diff --git a/tools/launcher-generator/.idea/libraries/jdom.xml b/tools/launcher-generator/.idea/libraries/jdom.xml new file mode 100644 index 000000000000..b3d6748e1fdd --- /dev/null +++ b/tools/launcher-generator/.idea/libraries/jdom.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/tools/launcher-generator/.idea/modules.xml b/tools/launcher-generator/.idea/modules.xml index 36572af8a642..1927ae044a55 100644 --- a/tools/launcher-generator/.idea/modules.xml +++ b/tools/launcher-generator/.idea/modules.xml @@ -2,6 +2,7 @@ + diff --git a/tools/launcher-generator/launcher-generator.iml b/tools/launcher-generator/launcher-generator.iml index d5c074327501..0602a743d3f2 100644 --- a/tools/launcher-generator/launcher-generator.iml +++ b/tools/launcher-generator/launcher-generator.iml @@ -7,6 +7,8 @@ + + diff --git a/tools/launcher-generator/src/com/pme/exe/Bin.java b/tools/launcher-generator/src/com/pme/exe/Bin.java index f73bf529ea07..00f3bfb934fb 100644 --- a/tools/launcher-generator/src/com/pme/exe/Bin.java +++ b/tools/launcher-generator/src/com/pme/exe/Bin.java @@ -582,20 +582,20 @@ public abstract class Bin { } } - public static class ArrayOfBins extends Bin { + public static class ArrayOfBins extends Bin { private Bin[] myValues; private Bin.Value mySize; private Class myClass; private Bin.Value myCountHolder = null; - public ArrayOfBins(String name, Class cl, Bin.Value size) { + public ArrayOfBins(String name, Class cl, Bin.Value size) { super(name); myClass = cl; mySize = size; init(); } - public ArrayOfBins(String name, Class cl, int size) { + public ArrayOfBins(String name, Class cl, int size) { this(name, cl, new DWord("size").setValue(size)); } @@ -654,8 +654,9 @@ public abstract class Bin { return myValues; } - public Bin get(int index) { - return myValues[index]; + public T get(int index) { + //noinspection unchecked + return (T) myValues[index]; } public long sizeInBytes() { diff --git a/tools/launcher-generator/src/com/pme/exe/ImageOptionalHeader.java b/tools/launcher-generator/src/com/pme/exe/ImageOptionalHeader.java index bfb007766e0c..b8c152c52439 100644 --- a/tools/launcher-generator/src/com/pme/exe/ImageOptionalHeader.java +++ b/tools/launcher-generator/src/com/pme/exe/ImageOptionalHeader.java @@ -54,7 +54,7 @@ public class ImageOptionalHeader extends Bin.Structure { addMember( new DWord( "SizeOfHeapCommit" ) ); addMember( new DWord( "LoaderFlags" ) ); DWord numberOfRvaAndSizes = (DWord)addMember( new DWord( "NumberOfRvaAndSizes") ); - ArrayOfBins imageDataDirectories = new ArrayOfBins( "ImageDataDirectories", ImageDataDirectory.class, numberOfRvaAndSizes); + ArrayOfBins imageDataDirectories = new ArrayOfBins("ImageDataDirectories", ImageDataDirectory.class, numberOfRvaAndSizes); imageDataDirectories.setCountHolder( numberOfRvaAndSizes ); addMember( imageDataDirectories ); diff --git a/tools/launcher-generator/src/com/pme/exe/res/DirectoryEntry.java b/tools/launcher-generator/src/com/pme/exe/res/DirectoryEntry.java index 7b78a1773d11..b4c7ef03ec7d 100644 --- a/tools/launcher-generator/src/com/pme/exe/res/DirectoryEntry.java +++ b/tools/launcher-generator/src/com/pme/exe/res/DirectoryEntry.java @@ -27,14 +27,16 @@ import java.util.ArrayList; * Time: 11:22:12 PM */ public class DirectoryEntry extends LevelEntry { - private ArrayOfBins myNamedEntries; - private ArrayOfBins myIdEntries; + private ArrayOfBins myNamedEntries; + private ArrayOfBins myIdEntries; private ResourceSectionReader mySection; - private ArrayList mySubDirs = new ArrayList(); - private ArrayList myDatas = new ArrayList(); + private ArrayList mySubDirs = new ArrayList(); + private ArrayList myDatas = new ArrayList(); + private long myIdOrName; - public DirectoryEntry( ResourceSectionReader section, EntryDescription entry ) { + public DirectoryEntry(ResourceSectionReader section, EntryDescription entry, long idOrName) { super( createName( entry ) ); + myIdOrName = idOrName; addMember(new DWord("Characteristics")); addMember(new DWord("TimeDateStamp")); addMember(new Word("MajorVersion")); @@ -49,6 +51,10 @@ public class DirectoryEntry extends LevelEntry { } } + public long getIdOrName() { + return myIdOrName; + } + public ResourceSectionReader getSection(){ return mySection; } @@ -61,27 +67,23 @@ public class DirectoryEntry extends LevelEntry { return name; } + public ArrayList getSubDirs() { + return mySubDirs; + } + public DirectoryEntry findSubDir( String name ){ - for (int i = 0; i < mySubDirs.size(); i++) { - DirectoryEntry directoryEntry = (DirectoryEntry) mySubDirs.get(i); - if ( directoryEntry.getName().equals( name ) ){ + for (DirectoryEntry directoryEntry : mySubDirs) { + if (directoryEntry.getName().equals(name)) { return directoryEntry; } } return null; } - public ArrayList getSubDirs(){ - return mySubDirs; - } - - public RawResource getRawResource( int index ){ - DataEntry dataEntry = (DataEntry)myDatas.get(index); + public RawResource getRawResource(int index) { + DataEntry dataEntry = myDatas.get(index); return dataEntry.getRawResource(); } - public ArrayList getDatas() { - return myDatas; - } public long sizeInBytes() { return super.sizeInBytes(); @@ -106,10 +108,11 @@ public class DirectoryEntry extends LevelEntry { getLevel().addLevelEntry( dir ); mySubDirs.add( dir ); } + public void addIdEntry( EntryDescription entry ){ if ( myIdEntries == null ){ Word numberOfNamedEntries = (Word) getMember("NumberOfIdEntries"); - myIdEntries = new ArrayOfBins("Id entries", EntryDescription.class, 0); + myIdEntries = new ArrayOfBins("Id entries", EntryDescription.class, 0); addMember(myIdEntries); myIdEntries.setCountHolder(numberOfNamedEntries); } @@ -120,13 +123,13 @@ public class DirectoryEntry extends LevelEntry { super.read(stream); Word numberOfNamedEntries = (Word) getMember("NumberOfNamedEntries"); - myNamedEntries = new ArrayOfBins("Named entries", EntryDescription.class, numberOfNamedEntries); + myNamedEntries = new ArrayOfBins("Named entries", EntryDescription.class, numberOfNamedEntries); addMember(myNamedEntries); myNamedEntries.setCountHolder(numberOfNamedEntries); myNamedEntries.read(stream); Word numberOfIdEntries = (Word) getMember("NumberOfIdEntries"); - myIdEntries = new ArrayOfBins("Id entries", EntryDescription.class, numberOfIdEntries); + myIdEntries = new ArrayOfBins("Id entries", EntryDescription.class, numberOfIdEntries); addMember(myIdEntries); myIdEntries.setCountHolder(numberOfIdEntries); myIdEntries.read(stream); @@ -135,14 +138,15 @@ public class DirectoryEntry extends LevelEntry { processEntries(myIdEntries); } - private void processEntries(ArrayOfBins entries) { + private void processEntries(ArrayOfBins entries) { for (int i = 0; i < entries.size(); ++i) { - EntryDescription entry = (EntryDescription) entries.get(i); + EntryDescription entry = entries.get(i); Bin.Value offset = entry.getValueMember("OffsetToData"); + Bin.Value name = entry.getValueMember("Name"); if ((offset.getValue() & 0x80000000) != 0) { - addDirectoryEntry( new DirectoryEntry( mySection, entry ) ); + addDirectoryEntry( new DirectoryEntry( mySection, entry, name.getValue()) ); } else { - addDataEntry( new DataEntry( mySection, offset ) ); + addDataEntry( new DataEntry( mySection, offset) ); } } } diff --git a/tools/launcher-generator/src/com/pme/exe/res/ResourceSectionReader.java b/tools/launcher-generator/src/com/pme/exe/res/ResourceSectionReader.java index 7c50191c33cd..7b8476d05e8c 100644 --- a/tools/launcher-generator/src/com/pme/exe/res/ResourceSectionReader.java +++ b/tools/launcher-generator/src/com/pme/exe/res/ResourceSectionReader.java @@ -51,7 +51,7 @@ public class ResourceSectionReader extends Bin.Structure { addSizeHolder(mySize); addSizeHolder(virtualSize); addSizeHolder(size); - myRoot.addLevelEntry(new DirectoryEntry( this, null )); + myRoot.addLevelEntry(new DirectoryEntry( this, null, 0)); addMember(myRoot); } diff --git a/tools/launcher-generator/src/com/pme/exe/res/StringTableDirectory.java b/tools/launcher-generator/src/com/pme/exe/res/StringTableDirectory.java new file mode 100644 index 000000000000..b54a7201b72b --- /dev/null +++ b/tools/launcher-generator/src/com/pme/exe/res/StringTableDirectory.java @@ -0,0 +1,59 @@ +/* + * Copyright 2006 ProductiveMe Inc. + * Copyright 2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.pme.exe.res; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author yole + */ +public class StringTableDirectory { + private static class Entry { + int startID; + StringTable table; + RawResource resource; + } + + private final List myEntries = new ArrayList(); + + public StringTableDirectory(DirectoryEntry directoryEntry) throws IOException { + for (DirectoryEntry subDir : directoryEntry.getSubDirs()) { + Entry e = new Entry(); + e.startID = (int) subDir.getIdOrName(); + e.resource = subDir.getRawResource(0); + e.table = new StringTable(e.resource.getBytes().getBytes()); + myEntries.add(e); + } + } + + public void setString(int id, String value) { + for (Entry entry : myEntries) { + if (entry.startID == (id / 16)-1) { + entry.table.setString(id % 16, value); + } + } + } + + public void save() throws IOException { + for (Entry entry : myEntries) { + entry.resource.setBytes(entry.table.getBytes()); + } + } +} diff --git a/tools/launcher-generator/src/com/pme/exe/res/icon/IconResourceInjector.java b/tools/launcher-generator/src/com/pme/exe/res/icon/IconResourceInjector.java index 59dba368fc46..2366f8e757c3 100644 --- a/tools/launcher-generator/src/com/pme/exe/res/icon/IconResourceInjector.java +++ b/tools/launcher-generator/src/com/pme/exe/res/icon/IconResourceInjector.java @@ -73,7 +73,7 @@ public class IconResourceInjector { Bin.Value name = entryDescription.getValueMember("Name"); name.setValue(index + 1); - DirectoryEntry entryDirIcon2 = new DirectoryEntry(iconsDir.getSection(), entryDescription); + DirectoryEntry entryDirIcon2 = new DirectoryEntry(iconsDir.getSection(), entryDescription, name.getValue()); iconsDir.insertDirectoryEntry(index, entryDirIcon2); iconsDir.addIdEntry(entryDescription); diff --git a/tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java b/tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java index a5e1bda6b56e..7316ddce8f7f 100644 --- a/tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java +++ b/tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java @@ -20,10 +20,7 @@ package com.pme.launcher; import com.pme.exe.ExeReader; import com.pme.exe.SectionReader; import com.pme.exe.Bin; -import com.pme.exe.res.ResourceSectionReader; -import com.pme.exe.res.DirectoryEntry; -import com.pme.exe.res.RawResource; -import com.pme.exe.res.StringTable; +import com.pme.exe.res.*; import com.pme.exe.res.bmp.PictureResourceInjector; import com.pme.exe.res.icon.IconResourceInjector; import com.pme.exe.res.vi.VersionInfo; @@ -40,132 +37,58 @@ public class LauncherGenerator { private File myIcon; private File myBmp; private File myExePath; - private int mySplashTimeout = 3; - private String myJreBundlePath; - private String myVmParameters; - private String myStartJar; - private String myWorkDir; - private String myJavaVersion; - private boolean mySearchJdkOnly = false; + private StringTableDirectory myStringTableDirectory; + private DirectoryEntry myRoot; + private ExeReader myReader; public LauncherGenerator(File template, File exePath) { myTemplate = template; myExePath = exePath; } - public void setWorkDir(String workDir) { - myWorkDir = workDir; - } - public void setSplashTimeout(int splashTimeout) { - mySplashTimeout = splashTimeout; - } - - public void setJreBundlePath(String jreBundlePath) { - myJreBundlePath = jreBundlePath; - } - - public void setVmParameters(String vmParameters) { - myVmParameters = vmParameters; - } - - public void setStartJar(String startJar) { - myStartJar = startJar; - } - - public void setIcon(File icon) { - myIcon = icon; - } - - public void setBmp(File bmp) { - myBmp = bmp; + public void load() throws IOException { + myReader = new ExeReader(myTemplate.getName()); + RandomAccessFile stream = new RandomAccessFile(myTemplate, "r"); + myReader.read(stream); + stream.close(); + SectionReader sectionReader = myReader.getSectionReader(".rsrc"); + ResourceSectionReader resourceReader = (ResourceSectionReader) sectionReader.getMember(".rsrc"); + myRoot = resourceReader.getRoot(); + DirectoryEntry subDir = myRoot.findSubDir("IRD6"); + myStringTableDirectory = new StringTableDirectory(subDir); } public void generate() throws IOException { - ExeReader reader = new ExeReader(myTemplate.getName()); - RandomAccessFile stream = new RandomAccessFile(myTemplate, "r"); - reader.read(stream); - stream.close(); - SectionReader sectionReader = reader.getSectionReader(".rsrc"); - ResourceSectionReader resourceReader = (ResourceSectionReader) sectionReader.getMember(".rsrc"); - DirectoryEntry root = resourceReader.getRoot(); - DirectoryEntry subDir = root.findSubDir("IRD6"); - DirectoryEntry ird7 = subDir.findSubDir("IRD7"); - - RawResource rawResource = ird7.getRawResource(0); - Bin.Bytes bytes = rawResource.getBytes(); - StringTable srtingTable = new StringTable(bytes.getBytes()); - - if (myBmp != null) { - srtingTable.setString(0, "splash"); // show splash - } - srtingTable.setString(1, "alive"); // stay alive - srtingTable.setString(2, "" + mySplashTimeout); // splash timeout - if (myJreBundlePath != null) { - srtingTable.setString(3, myJreBundlePath); // jre bundled path - } - if (myVmParameters != null) { - srtingTable.setString(4, myVmParameters); // PROP_VM_PARAMETERS - } - if (myStartJar != null) { - srtingTable.setString(5, myStartJar); // PROP_START_JAR - } - srtingTable.setString(6, "waitForWindow"); // PROP_WAIT_FOR_WINDOW - - if (myWorkDir != null) { - srtingTable.setString(7, myWorkDir); // PROP_WORK_DIR - } - - if (myJavaVersion != null) { - StringBuffer buffer = new StringBuffer( myJavaVersion.length() ); - for( int i = 0; i < myJavaVersion.length(); ++i){ - char ch = myJavaVersion.charAt( i ); - if ( Character.isDigit( ch ) || ch == '.' ){ - buffer.append( ch ); - } - } - srtingTable.setString(8, buffer.toString()); // PROP_JAVA_VERSION - } - if (mySearchJdkOnly) { - srtingTable.setString(9, "SearchJdkOnly"); // PROP_SEARCH_JDK_ONLY - } - - byte[] a = srtingTable.getBytes(); - rawResource.setBytes(a); + myStringTableDirectory.save(); if (myIcon != null) { IconResourceInjector iconInjector = new IconResourceInjector(); - iconInjector.injectIcon(myIcon, root, "IRD101"); + iconInjector.injectIcon(myIcon, myRoot, "IRD101"); } if (myBmp != null) { PictureResourceInjector bmpInjector = new PictureResourceInjector(); - bmpInjector.inject(myBmp, root, "IRD104"); + bmpInjector.inject(myBmp, myRoot, "IRD104"); } - - - DirectoryEntry viDir = root.findSubDir("IRD16").findSubDir( "IRD1" ); + DirectoryEntry viDir = myRoot.findSubDir("IRD16").findSubDir( "IRD1" ); Bin.Bytes viBytes = viDir.getRawResource( 0 ).getBytes(); ByteArrayInputStream bytesStream = new ByteArrayInputStream(viBytes.getBytes()); VersionInfo viReader = new VersionInfo(); viReader.read(new OffsetTrackingInputStream(new DataInputStream(bytesStream))); - reader.resetOffsets(0); + myReader.resetOffsets(0); myExePath.getParentFile().mkdirs(); myExePath.createNewFile(); RandomAccessFile exeStream = new RandomAccessFile(myExePath, "rw"); - reader.write(exeStream); + myReader.write(exeStream); exeStream.close(); } - public void setJavaVersion(String javaVersion) { - myJavaVersion = javaVersion; - } - - public void setSearchJdkOnly(boolean searchJdkOnly) { - mySearchJdkOnly = searchJdkOnly; + public void setResourceString(int id, String value) { + myStringTableDirectory.setString(id, value); } } diff --git a/tools/launcher-generator/src/com/pme/launcher/LauncherGeneratorMain.java b/tools/launcher-generator/src/com/pme/launcher/LauncherGeneratorMain.java new file mode 100644 index 000000000000..73dbff498e68 --- /dev/null +++ b/tools/launcher-generator/src/com/pme/launcher/LauncherGeneratorMain.java @@ -0,0 +1,124 @@ +/* + * Copyright 2006 ProductiveMe Inc. + * Copyright 2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.pme.launcher; + +import org.jdom.Document; +import org.jdom.input.SAXBuilder; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author yole + */ +public class LauncherGeneratorMain { + public static void main(String[] args) { + if (args.length != 5) { + System.err.println("Usage: LauncherGeneratorMain