BuildDesk launcher generator

This commit is contained in:
Dmitry Jemerov
2013-02-20 20:14:07 +01:00
parent 2d158d2653
commit ee3f3e5e0e
56 changed files with 3736 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
out
+1
View File
@@ -0,0 +1 @@
launcher-generator
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AntConfiguration">
<defaultAnt bundledAnt="true" />
</component>
</project>
+231
View File
@@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</value>
</option>
<option name="FIELD_NAME_PREFIX" value="my" />
<codeStyleSettings language="JAVA">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
<arrangement>
<groups>
<group>
<type>GETTERS_AND_SETTERS</type>
<order>KEEP</order>
</group>
</groups>
<rules>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PUBLIC</MODIFIER>
<MODIFIER>STATIC</MODIFIER>
<MODIFIER>FINAL</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PROTECTED</MODIFIER>
<MODIFIER>STATIC</MODIFIER>
<MODIFIER>FINAL</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PACKAGE_PRIVATE</MODIFIER>
<MODIFIER>STATIC</MODIFIER>
<MODIFIER>FINAL</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PRIVATE</MODIFIER>
<MODIFIER>STATIC</MODIFIER>
<MODIFIER>FINAL</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PUBLIC</MODIFIER>
<MODIFIER>STATIC</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PROTECTED</MODIFIER>
<MODIFIER>STATIC</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PACKAGE_PRIVATE</MODIFIER>
<MODIFIER>STATIC</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PRIVATE</MODIFIER>
<MODIFIER>STATIC</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PUBLIC</MODIFIER>
<MODIFIER>FINAL</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PROTECTED</MODIFIER>
<MODIFIER>FINAL</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PACKAGE_PRIVATE</MODIFIER>
<MODIFIER>FINAL</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PRIVATE</MODIFIER>
<MODIFIER>FINAL</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PUBLIC</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PROTECTED</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PACKAGE_PRIVATE</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>FIELD</TYPE>
<MODIFIER>PRIVATE</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<TYPE>FIELD</TYPE>
</match>
</rule>
<rule>
<match>
<TYPE>CONSTRUCTOR</TYPE>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>METHOD</TYPE>
<MODIFIER>STATIC</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<TYPE>METHOD</TYPE>
</match>
</rule>
<rule>
<match>
<TYPE>ENUM</TYPE>
</match>
</rule>
<rule>
<match>
<TYPE>INTERFACE</TYPE>
</match>
</rule>
<rule>
<match>
<AND>
<TYPE>CLASS</TYPE>
<MODIFIER>STATIC</MODIFIER>
</AND>
</match>
</rule>
<rule>
<match>
<TYPE>CLASS</TYPE>
</match>
</rule>
</rules>
</arrangement>
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
</project>
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="?*.properties" />
<entry name="?*.xml" />
<entry name="?*.gif" />
<entry name="?*.png" />
<entry name="?*.jpeg" />
<entry name="?*.jpg" />
<entry name="?*.html" />
<entry name="?*.dtd" />
<entry name="?*.tld" />
<entry name="?*.ftl" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>
@@ -0,0 +1,9 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright 2006 ProductiveMe Inc.&#10;#if(&amp;#36;{today.year} == 2013)&#10;Copyright &amp;#36;{today.year} JetBrains s.r.o.&#10;#else&#10;Copyright 2013-&amp;#36;{today.year} JetBrains s.r.o.&#10;#end&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
<option name="keyword" value="Copyright" />
<option name="allowReplaceKeyword" value="" />
<option name="myName" value="apache 2 productiveme" />
<option name="myLocal" value="true" />
</copyright>
</component>
@@ -0,0 +1,5 @@
<component name="CopyrightManager">
<settings default="apache 2 productiveme">
<module2copyright />
</settings>
</component>
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/launcher-generator.iml" filepath="$PROJECT_DIR$/launcher-generator.iml" />
</modules>
</component>
</project>
@@ -0,0 +1,5 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>
+125
View File
@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
@@ -0,0 +1,631 @@
/*
* 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;
import com.pme.util.BitsUtil;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.lang.reflect.Array;
/**
* Date: Mar 31, 2006
* Time: 6:17:24 PM
*/
public abstract class Bin {
private String myName;
private String myDescription;
private long myOffset = 0;
ArrayList<Bin.Value> myOffsetHolders = new ArrayList<Bin.Value>(0);
ArrayList<Bin.Value> mySizeHolders = new ArrayList<Bin.Value>(0);
public Bin(String name) {
myName = name;
}
public String getName() {
return myName;
}
public void setName(String name) {
myName = name;
}
public String getDescription() {
if (myDescription != null) {
return myDescription;
}
return myName;
}
public long getOffset() {
return myOffset;
}
public void resetOffsets(long offset) {
myOffset = offset;
for (Value holder : myOffsetHolders) {
holder.setValue(offset);
}
for (Value holder : mySizeHolders) {
holder.setValue(sizeInBytes());
}
}
public void copyFrom(Bin value) {
}
public void addOffsetHolder(Value offsetHolder) {
myOffsetHolders.add( offsetHolder );
}
public void addSizeHolder(Value sizeHolder) {
mySizeHolders.add( sizeHolder );
}
public abstract long sizeInBytes();
public void setDescription(String description) {
myDescription = description;
}
public abstract void read(DataInput stream) throws IOException;
public abstract void write(DataOutput stream) throws IOException;
public abstract void report(OutputStreamWriter writer) throws IOException;
public static class Comment extends Bin {
public Comment(String comment) {
super(comment);
}
public long sizeInBytes() {
return 0;
}
public void read(DataInput stream) throws IOException {
}
public void write(DataOutput stream) throws IOException {
}
public void report(OutputStreamWriter writer) throws IOException {
_report(writer, getName());
}
}
public static class Structure extends Bin {
private ArrayList<Bin> myMembers = new ArrayList<Bin>(1);
private HashMap<String, Bin> myMembersMap = new HashMap<String, Bin>(1);
public Structure(String name) {
super(name);
}
public void resetOffsets(long newOffset) {
super.resetOffsets(newOffset);
long offset = getOffset();
for (Bin bin : myMembers) {
bin.resetOffsets(offset);
offset = offset + bin.sizeInBytes();
}
}
public void copyFrom(Bin binStructure) {
Bin.Structure structure = (Bin.Structure)binStructure;
ArrayList<Bin> members = structure.getMembers();
for (Bin bin : members) {
Bin valueMember = getMember(bin.getName());
if (valueMember != null) {
valueMember.copyFrom(bin);
}
}
}
public long sizeInBytes() {
long size = 0;
for (Bin bin : myMembers) {
size += bin.sizeInBytes();
}
return size;
}
public ArrayList<Bin> getMembers() {
return myMembers;
}
public void addMember(Bin bin, String description) {
bin.setDescription(description);
addMember(bin);
}
public void addComment(String message) {
myMembers.add(new Comment(message));
}
public Bin insertMember(int index, Bin bin) {
ArrayList<Bin> list = new ArrayList<Bin>( myMembers.size() + 1 );
for ( int i = 0; i < index; ++i ){
list.add( myMembers.get( i ) );
}
list.add( bin );
for ( int i = index; i < myMembers.size(); ++i ){
list.add( myMembers.get( i ) );
}
myMembers = list;
addMemberToMapOnly(bin);
return bin;
}
public Bin addMember(Bin bin) {
myMembers.add(bin);
addMemberToMapOnly(bin);
return bin;
}
//such members are not read by framework
//it is read by parent in 'read' overrided method
public void addMemberToMapOnly(Bin bin) {
myMembersMap.put(bin.getName(), bin);
}
public Bin getMember(String name) {
return (Bin) myMembersMap.get(name);
}
public Bin.Value getValueMember(String name) {
return (Bin.Value) myMembersMap.get(name);
}
public Bin.Structure getStructureMember(String name) {
return (Bin.Structure) myMembersMap.get(name);
}
public long getValue(String name) {
return ((Bin.Value) myMembersMap.get(name)).getValue();
}
public void read(DataInput stream) throws IOException {
for (Bin bin : myMembers) {
bin.read(stream);
}
}
public void write(DataOutput stream) throws IOException {
for (Bin bin : myMembers) {
bin.write(stream);
}
}
public void report(OutputStreamWriter writer) throws IOException {
_report(writer, "--- '" + getName() + "' Structure --- size = " + sizeInBytes());
_report(writer, "{Offset = " + Long.toHexString(getOffset()) + "}");
for (Bin bin : myMembers) {
bin.report(writer);
}
_report(writer, "--- End Of '" + getName() + "' Structure ---");
}
}
public abstract static class Value extends Bin {
private long myValue;
public Value(String name) {
super(name);
}
public abstract long getValue();
public abstract Value setValue(long value);
public void copyFrom(Bin value) {
setValue(((Value)value).getValue());
}
public long getRawValue() {
return myValue;
}
public Value setRawValue(long value) {
myValue = value;
return this;
}
public Value setValue(short value) {
myValue = BitsUtil.revertBytesOfShort(value);
return this;
}
}
public static class Byte extends Value {
public Byte(String name) {
super(name);
}
public long sizeInBytes() {
return 1;
}
public long getValue() {
return getRawValue();
}
public Value setValue(long value) {
setRawValue(value);
return this;
}
public void read(DataInput stream) throws IOException {
setRawValue(stream.readByte());
}
public void write(DataOutput stream) throws IOException {
stream.writeByte((byte) getRawValue());
}
public void report(OutputStreamWriter writer) throws IOException {
_report(writer, getDescription(), (byte) getValue());
}
}
public static class Word extends Value {
public Word() {
super("");
}
public Word(String name) {
super(name);
}
public long sizeInBytes() {
return 2;
}
public long getValue() {
return BitsUtil.revertBytesOfShort((short) super.getRawValue());
}
public Value setValue(long value) {
setRawValue(BitsUtil.revertBytesOfShort((short) value));
return this;
}
public void read(DataInput stream) throws IOException {
setRawValue(stream.readShort());
}
public void write(DataOutput stream) throws IOException {
stream.writeShort((short) getRawValue());
}
public void report(OutputStreamWriter writer) throws IOException {
short sh = (short) getValue();
_report(writer, getDescription(), sh);
}
public String toString() {
return BitsUtil.shortToHexString( (int)getValue() );
}
}
public static class DWord extends Value {
public DWord(String name) {
super(name);
}
public long sizeInBytes() {
return 4;
}
public Value setValue(long value) {
setRawValue(BitsUtil.revertBytesOfInt((int) value));
return this;
}
public long getValue() {
return BitsUtil.revertBytesOfInt((int) super.getRawValue());
}
public void read(DataInput stream) throws IOException {
setRawValue(stream.readInt());
}
public void write(DataOutput stream) throws IOException {
stream.writeInt((int) getRawValue());
}
public void report(OutputStreamWriter writer) throws IOException {
_report(writer, getDescription(), (int) getValue());
}
public String toString() {
return BitsUtil.intToHexString( (int)getValue() );
}
}
public static class Txt extends Bin {
private StringBuffer myBuffer = new StringBuffer();
private Bin.Value mySize;
private byte[] myBytes;
public Txt(String name, byte[] bytes) {
super(name);
myBytes = bytes;
mySize = new DWord("").setValue(bytes.length);
setValue();
}
public Txt(String name, String string) {
super(name);
myBytes = new byte[string.length() * 2];
byte[] bytes = string.getBytes();
for (int i = 0; i < bytes.length; ++i) {
myBytes[i * 2] = bytes[i];
myBytes[i * 2 + 1] = 0;
}
mySize = new DWord("").setValue(myBytes.length);
setValue();
}
public Txt(String name, Bin.Value size) {
super(name);
mySize = size;
}
public Txt(String name, int size) {
this(name, new DWord("size").setValue(size));
}
public String getText() {
return myBuffer.toString();
}
public long sizeInBytes() {
return mySize.getValue();
}
private void setValue(){
for (int i = 0; i < mySize.getValue(); ++i) {
int b = BitsUtil.unsignedByte(myBytes[i]);
if (b != 0) {
myBuffer.append((char) b);
}
}
}
public void read(DataInput stream) throws IOException {
myBuffer.setLength(0);
myBytes = new byte[(int) mySize.getValue()];
for (int i = 0; i < mySize.getValue(); ++i) {
myBytes[i] = stream.readByte();
}
setValue();
}
public void write(DataOutput stream) throws IOException {
stream.write(myBytes);
}
public void report(OutputStreamWriter writer) throws IOException {
_report(writer, myBuffer.toString());
}
}
public static class Bytes extends Bin {
private byte[] myBytes;
private Value myStartOffset;
private Value mySize;
private int myBytesInRow = 16;
public Bytes(String name, Bin.Value size) {
super(name);
mySize = size;
}
public Bytes(String name, long size) {
super(name);
mySize = new DWord("size").setValue(size);
}
public Bytes(String name, Bin.Value startOffset, Bin.Value size) {
super(name);
reset(startOffset, size);
}
public void reset(int startOffset, int size) {
reset(new DWord("startOffset").setValue(startOffset), new DWord("size").setValue(size));
}
public void reset(Bin.Value startOffset, Bin.Value size) {
myStartOffset = startOffset;
mySize = size;
}
public byte[] getBytes() {
return myBytes;
}
public void setBytes(byte[] bytes) {
setBytes(bytes, bytes.length);
}
public void setBytes(byte[] bytes, int size) {
if (bytes.length < size) {
throw new RuntimeException("bytes.length < size");
}
myBytes = bytes;
mySize.setValue(size);
}
public long sizeInBytes() {
return mySize.getValue();
}
public void read(DataInput stream) throws IOException {
if (myStartOffset != null) {
RandomAccessFile file = (RandomAccessFile) stream;
file.seek(myStartOffset.getValue());
}
myBytes = new byte[(int) mySize.getValue()];
stream.readFully(myBytes);
}
public void write(DataOutput stream) throws IOException {
stream.write(myBytes, 0, (int) sizeInBytes());
}
private StringBuffer myBuffer = new StringBuffer();
public void report(OutputStreamWriter writer) throws IOException {
_report(writer, getName());
_report(writer, "Number of bytes: " + mySize.getValue());
int rowCount = (myBytes.length / myBytesInRow);
if (myBytes.length % myBytesInRow != 0) {
rowCount++;
}
int byteCount = 0;
for (int i = 0; i < rowCount; i++) {
myBuffer.setLength(0);
myBuffer.append("\n");
for (int j = 0; j < myBytesInRow && byteCount < myBytes.length; j++) {
byte aByte = myBytes[byteCount++];
myBuffer.append(" ").append(BitsUtil.byteToHexString(aByte));
}
writer.write(myBuffer.toString());
}
}
}
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) {
super(name);
myClass = cl;
mySize = size;
init();
}
public ArrayOfBins(String name, Class cl, int size) {
this(name, cl, new DWord("size").setValue(size));
}
public void addBin( Bin bin ){
Bin[] newArray = new Bin[myValues.length+1];
System.arraycopy( myValues, 0, newArray, 0, myValues.length );
newArray[myValues.length] = bin;
myValues = newArray;
mySize.setValue( mySize.getValue() + 1 );
}
public void copyFrom(Bin bin) {
ArrayOfBins value = (ArrayOfBins)bin;
for (int i = 0; i < myValues.length; i++) {
myValues[i].copyFrom( value.get(i) );
}
}
public void setCountHolder(Value countHolder) {
myCountHolder = countHolder;
}
private void init() {
myValues = (Bin[]) Array.newInstance(myClass, (int) mySize.getValue());
for (int i = 0; i < myValues.length; i++) {
try {
Bin bin = (Bin) myClass.newInstance();
bin.setName("[" + i + "]");
myValues[i] = bin;
} catch (InstantiationException e) {
throw new RuntimeException(e.getMessage());
} catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage());
}
}
}
public void resetOffsets(long newOffset) {
super.resetOffsets(newOffset);
long offset = getOffset();
if (myCountHolder != null) {
myCountHolder.setValue(myValues.length);
}
for (Bin bin : myValues) {
bin.resetOffsets(offset);
offset = offset + bin.sizeInBytes();
}
}
public int size() {
return myValues.length;
}
public Bin[] getArray() {
return myValues;
}
public Bin get(int index) {
return myValues[index];
}
public long sizeInBytes() {
int size = 0;
for (Bin value : myValues) {
size += value.sizeInBytes();
}
return size;
}
public void read(DataInput stream) throws IOException {
init();
for (Bin value : myValues) {
value.read(stream);
}
}
public void write(DataOutput stream) throws IOException {
for (Bin value : myValues) {
value.write(stream);
}
}
public void report(OutputStreamWriter writer) throws IOException {
writer.write("\n" + "Array size: " + myValues.length);
for (Bin value : myValues) {
value.report(writer);
}
}
}
protected void _report(OutputStreamWriter buffer, String name, int value) throws IOException {
buffer.write("\n" + name + " : " + BitsUtil.intToHexString(value));
}
protected void _report(OutputStreamWriter buffer, String name, short value) throws IOException {
buffer.write("\n" + name + " : " + BitsUtil.shortToHexString(value));
}
protected void _report(OutputStreamWriter buffer, String name, byte value) throws IOException {
buffer.write("\n" + name + " : " + BitsUtil.byteToHexString(value));
}
protected void _report(OutputStreamWriter buffer, String message) throws IOException {
buffer.write("\n" + message);
}
}
@@ -0,0 +1,157 @@
/*
* 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;
import com.pme.exe.res.ValuesAdd;
import java.io.*;
/**
* Date: Mar 30, 2006
* Time: 4:14:38 PM
*/
public class ExeReader extends Bin.Structure{
private ArrayOfBins mySectionHeaders;
private SectionReader[] mySections;
private PeHeaderReader myPeHeader;
private ImageOptionalHeader myImageOptionalHeader;
private Bin.Bytes myBytes;
private Bin.Bytes myMsDosStub;
private MsDosHeader myMsDosHeader;
public ExeReader(String name) {
super(name);
myMsDosHeader = new MsDosHeader();
addMember( myMsDosHeader );
Bin.Value member = myMsDosHeader.getValueMember("lfanew");
ValuesAdd size = new ValuesAdd( member, new DWord("").setValue( myMsDosHeader.sizeInBytes() ) );
myMsDosStub = new Bytes( "MsDos stub program", size );
addMember( myMsDosStub );
myPeHeader = new PeHeaderReader( member );
addMember( myPeHeader );
myImageOptionalHeader = (ImageOptionalHeader) myPeHeader.getMember("Image Optional Header");
mySectionHeaders = (ArrayOfBins)myPeHeader.getMember( "ImageSectionHeaders" );
addSizeHolder( myImageOptionalHeader.getValueMember( "SizeOfImage" ) ); //b164
}
public long sizeOfHeaders(){
return myPeHeader.sizeInBytes() + myMsDosStub.sizeInBytes() + myMsDosHeader.sizeInBytes();
}
public long sizeInBytes() {
long result = 0;
long va = 0;
for ( int i = 0; i < mySectionHeaders.size(); ++i){
ImageSectionHeader header = (ImageSectionHeader)mySectionHeaders.get(i);
Value virtualAddress = header.getValueMember("VirtualAddress");
if ( va < virtualAddress.getValue() ){
result = mySections[i].sizeInBytes() + virtualAddress.getValue();
}
}
long div = result / 0x1000;
long r = result % 0x1000;
if ( r != 0 ){
div++;
}
result = div * 0x1000;
return result;
}
public SectionReader[] getSections(){
return mySections;
}
public ArrayOfBins getSectionHeaders(){
return mySectionHeaders;
}
public SectionReader getSectionReader( String sectionName ){
for (int i = 0; i < mySections.length; i++) {
SectionReader section = mySections[i];
if ( sectionName.equals( section.getSectionName() )){
return section;
}
}
return null;
}
public void read(DataInput stream) throws IOException {
super.read(stream);
long filePointer = getOffset() + sizeOfHeaders();
Bin.Value mainSectionsOffset;
mySections = new SectionReader[mySectionHeaders.size()];
for ( int i = 0; i < mySectionHeaders.size(); ++i ){
ImageSectionHeader sectionHeader = (ImageSectionHeader)mySectionHeaders.get(i);
Bin.Value startOffset = sectionHeader.getValueMember( "PointerToRawData" );
Bin.Value rva = sectionHeader.getValueMember( "VirtualAddress" );
if ( i == 0 ){
long size = startOffset.getValue() - filePointer;
if ( myBytes == null ){
myBytes = new Bytes( "Aligment", size );
addMemberToMapOnly( myBytes );
} else {
myBytes = (Bytes)getMember( "Aligment" );
myBytes.reset( (int)filePointer, (int)size );
}
myBytes.read( stream );
}
mainSectionsOffset = new ValuesAdd( rva, startOffset );
mySections[i] = new SectionReader( sectionHeader, startOffset, mainSectionsOffset, myImageOptionalHeader );
mySections[i].read( stream );
}
resetOffsets( 0 );
}
public void resetOffsets(long newOffset) {
super.resetOffsets(newOffset);
long mainOffset = myPeHeader.getOffset() + myPeHeader.sizeInBytes() + myBytes.sizeInBytes();
long offset = 0;
for (int i = 0; i < mySections.length; i++) {
Bin section = mySections[i];
section.resetOffsets( mainOffset + offset );
offset += section.sizeInBytes();
}
}
public void write(DataOutput stream) throws IOException {
super.write(stream);
myBytes.write( stream );
for (int i = 0; i < mySections.length; i++) {
mySections[i].write( stream );
}
}
public void report(OutputStreamWriter writer) throws IOException {
super.report(writer);
myBytes.report( writer );
mySectionHeaders.report( writer );
for ( int i = 0; i < mySections.length; ++i ){
mySections[i].report( writer );
}
}
public static void main(String[] args) throws Throwable {
ExeReader reader = new ExeReader( "SeaShell.exe" );
File file = new File( "C:\\work\\SeaShell.exe" );
RandomAccessFile stream = new RandomAccessFile( file, "r" );
reader.read( stream );
stream.close();
}
}
@@ -0,0 +1,33 @@
/*
* 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;
/**
* Date: Mar 31, 2006
* Time: 10:40:56 PM
*/
public class ImageDataDirectory extends Bin.Structure {
public ImageDataDirectory(String name) {
super(name);
addMember( new DWord( "VirtualAddress" ) );
addMember( new DWord( "Size" ) );
}
public ImageDataDirectory( ){
this("");
}
}
@@ -0,0 +1,57 @@
/*
* 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;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* Date: Mar 31, 2006
* Time: 5:17:01 PM
*/
public class ImageFileHeader extends Bin.Structure {
public ImageFileHeader() {
super("Image File Header");
addMember( new Machine( ) );
addMember( new Word( "NumberOfSections" ) );
addMember( new DWord( "TimeDateStamp" ) );
addMember( new DWord( "PointerToSymbolTable" ) );
addMember( new DWord( "NumberOfSymbols" ) );
addMember( new Word( "SizeOfOptionalHeader" ) );
addMember( new Word( "Characteristics" ) );
}
class Machine extends Bin.Word{
public Machine() {
super("Machine");
}
public void report( OutputStreamWriter writer ) throws IOException {
super.report( writer );
long machine = getValue();
if ( machine == 0x014c ){
_report(writer ,"Machine: Intel 386" );
} else if ( machine == 0x0002 ) {
_report( writer, "Machine: Intel 64" );
} else {
_report( writer, "Machine: Unknown" );
}
}
}
}
@@ -0,0 +1,62 @@
/*
* 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;
/**
* Date: Mar 31, 2006
* Time: 6:01:16 PM
*/
public class ImageOptionalHeader extends Bin.Structure {
public ImageOptionalHeader() {
super("Image Optional Header");
addMember( new Word( "Magic" ) );
addMember( new Byte( "MajorLinkerVersion"));
addMember( new Byte( "MinorLinkerVersion"));
addMember( new DWord( "SizeOfCode" ) );
addMember( new DWord( "SizeOfInitializedData" ) );
addMember( new DWord( "SizeOfUninitializedData" ) );
addMember( new DWord( "AddressOfEntryPoint" ) );
addMember( new DWord( "BaseOfCode" ) );
addMember( new DWord( "BaseOfData" ) );
addMember( new DWord( "ImageBase" ) );
addMember( new DWord( "SectionAlignment" ) );
addMember( new DWord( "FileAlignment" ) );
addMember( new Word( "MajorOperatingSystemVersion" ) );
addMember( new Word( "MinorOperatingSystemVersion" ) );
addMember( new Word( "MajorImageVersion" ) );
addMember( new Word( "MinorImageVersion" ) );
addMember( new Word( "MajorSubsystemVersion" ) );
addMember( new Word( "MinorSubsystemVersion" ) );
addMember( new DWord( "Win32VersionValue" ) );
addMember( new DWord( "SizeOfImage" ) );
addMember( new DWord( "SizeOfHeaders" ) );
addMember( new DWord( "CheckSum" ) );
addMember( new Word( "Subsystem" ) );
addMember( new Word( "DllCharacteristics" ) );
addMember( new DWord( "SizeOfStackReserve" ) );
addMember( new DWord( "SizeOfStackCommit" ) );
addMember( new DWord( "SizeOfHeapReserve" ) );
addMember( new DWord( "SizeOfHeapCommit" ) );
addMember( new DWord( "LoaderFlags" ) );
DWord numberOfRvaAndSizes = (DWord)addMember( new DWord( "NumberOfRvaAndSizes") );
ArrayOfBins imageDataDirectories = new ArrayOfBins( "ImageDataDirectories", ImageDataDirectory.class, numberOfRvaAndSizes);
imageDataDirectories.setCountHolder( numberOfRvaAndSizes );
addMember( imageDataDirectories );
}
}
@@ -0,0 +1,38 @@
/*
* 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;
/**
* Date: Apr 1, 2006
* Time: 1:54:57 PM
*/
public class ImageSectionHeader extends Bin.Structure{
public ImageSectionHeader() {
super("Image section header");
addMember( new Txt( "Name", 8 ));
addMember( new DWord( "VirtualSize"));
addMember( new DWord( "VirtualAddress"));
addMember( new DWord( "SizeOfRawData"));
addMember( new DWord( "PointerToRawData"));
addMember( new DWord( "PointerToRelocations"));
addMember( new DWord( "PointerToLinenumbers"));
addMember( new Word( "NumberOfRelocations"));
addMember( new Word( "NumberOfLinenumbers"));
addMember( new DWord( "Characteristics"));
}
}
@@ -0,0 +1,33 @@
/*
* 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;
import java.io.IOException;
/**
* Date: Mar 31, 2006
* Time: 2:09:25 PM
*/
public class InvalidMsDosHeaderException extends IOException {
public InvalidMsDosHeaderException() {
}
public InvalidMsDosHeaderException(String s) {
super(s);
}
}
@@ -0,0 +1,58 @@
/*
* 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;
import java.io.IOException;
import java.io.DataInput;
/**
* Date: Mar 31, 2006
* Time: 2:10:01 PM
*/
public class MsDosHeader extends Bin.Structure {
public MsDosHeader() {
super("MSDOS Header");
addMember( new Word( "magic" ), "Magic number" );
addMember( new Word( "cblp" ), "Bytes on last page of file" );
addMember( new Word( "cp" ), "Pages in file" );
addMember( new Word( "crlc" ), "Relocations" );
addMember( new Word( "cparhdr" ), "Size of header in paragraphs" );
addMember( new Word( "minalloc" ), "Minimum extra paragraphs needed" );
addMember( new Word( "maxalloc" ), "Maximum extra paragraphs needed" );
addMember( new Word( "ss" ), "Initial (relative) SS value" );
addMember( new Word( "sp" ), "Initial SP value" );
addMember( new Word( "csum" ), "Checksum" );
addMember( new Word( "ip" ), "Initial IP value" );
addMember( new Word( "cs" ), "Initial (relative) CS value" );
addMember( new Word( "lfarlc" ), "File address of relocation table" );
addMember( new Word( "ovno" ), "Overlay number" );
addMember( new ArrayOfBins( "res", Word.class,4 ), "Reserved words" );
addMember( new Word( "oemid" ), "OEM identifier (for e_oeminfo)" );
addMember( new Word( "oeminfo" ), "OEM information; e_oemid specific" );
addMember( new ArrayOfBins( "res2", Word.class, 10 ), "Reserved words" );
addMember( new DWord( "lfanew" ), "File address of new exe header" );
}
public void read(DataInput stream) throws IOException {
super.read( stream );
long magic = getValue( "magic" );
if (magic != 0x5a4d) {
throw new InvalidMsDosHeaderException("First two chars in exe file must be 'MZ'");
}
}
}
@@ -0,0 +1,46 @@
/*
* 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;
import java.io.IOException;
import java.io.DataInput;
/**
* Date: Mar 31, 2006
* Time: 5:00:49 PM
*/
public class PeHeaderReader extends Bin.Structure{
private Bin.Value myStartOffset;
public PeHeaderReader( Bin.Value startOffset ){
super( "PE Header" );
myStartOffset = startOffset;
addOffsetHolder( myStartOffset );
addMember( new DWord( "Signature" ) );
ImageFileHeader imageFileHeader = new ImageFileHeader();
addMember( imageFileHeader );
addMember( new ImageOptionalHeader() );
Bin.Value numberOfSections = imageFileHeader.getValueMember( "NumberOfSections" );
ArrayOfBins imageSectionHeaders = new ArrayOfBins( "ImageSectionHeaders", ImageSectionHeader.class, numberOfSections );
imageSectionHeaders.setCountHolder( numberOfSections );
addMember( imageSectionHeaders );
}
public void read(DataInput stream) throws IOException {
super.read( stream );
}
}
@@ -0,0 +1,63 @@
/*
* 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;
import com.pme.exe.res.ResourceSectionReader;
import java.io.OutputStreamWriter;
import java.io.IOException;
/**
* Date: Apr 5, 2006
* Time: 9:48:35 AM
*/
public class SectionReader extends Bin.Structure{
private Bin.Txt myName;
public SectionReader( ImageSectionHeader sectionHeader, Bin.Value startOffset, Bin.Value mainSectionsOffset, ImageOptionalHeader imageOptionalHeader ) {
super("Section");
myName = (Bin.Txt)sectionHeader.getMember("Name");
String sectionName = myName.getText();
if ( ".rsrc".equals(sectionName) ){
addMember( new ResourceSectionReader( sectionHeader, startOffset, mainSectionsOffset, imageOptionalHeader ) );
} else {
Bin.Value size = sectionHeader.getValueMember( "SizeOfRawData" );
addMember( new Simple( sectionName, startOffset, size ) );
}
}
public String getSectionName(){
return myName.getText();
}
public void report(OutputStreamWriter writer) throws IOException {
_report( writer, "Section name: " + myName.getText() );
super.report(writer);
}
public static class Simple extends Bin.Structure{
public Simple(String name, Bin.Value startOffset, Bin.Value size) {
super(name);
addOffsetHolder( startOffset );
addSizeHolder( size );
addMember( new Bin.Bytes( "Raw data", size ) );
}
}
}
@@ -0,0 +1,64 @@
/*
* 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 com.pme.exe.Bin;
import java.io.IOException;
import java.io.DataInput;
import java.io.DataOutput;
/**
* Date: Apr 20, 2006
* Time: 3:58:05 PM
*/
public class DataEntry extends LevelEntry {
private ResourceSectionReader mySection;
private RawResource myRawResource = null;
public DataEntry( ResourceSectionReader section, Bin.Value offsetHolder ) {
super("DataEntry");
addMember(new DWord("RVA"));
addMember(new DWord("Size"));
addMember(new DWord("Code Page"));
addMember(new DWord("Reserved"));
mySection = section;
addOffsetHolder( new ValuesSub( offsetHolder, mySection.getStartOffset() ) );
}
public RawResource getRawResource() {
return myRawResource;
}
public void initRawData(){
myRawResource = new RawResource( mySection, (DWord) getValueMember("RVA"), (DWord) getValueMember("Size"));
getLevel().addLevelEntry( myRawResource );
}
public void insertRawData( int index ){
myRawResource = new RawResource( mySection, (DWord) getValueMember("RVA"), (DWord) getValueMember("Size"));
getLevel().insertLevelEntry( index, myRawResource );
}
public void read(DataInput stream) throws IOException {
super.read(stream);
initRawData();
}
public void write(DataOutput stream) throws IOException {
super.write(stream);
}
}
@@ -0,0 +1,158 @@
/*
* 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 com.pme.exe.Bin;
import java.io.*;
import java.util.ArrayList;
/**
* Date: Apr 6, 2006
* Time: 11:22:12 PM
*/
public class DirectoryEntry extends LevelEntry {
private ArrayOfBins myNamedEntries;
private ArrayOfBins myIdEntries;
private ResourceSectionReader mySection;
private ArrayList mySubDirs = new ArrayList();
private ArrayList myDatas = new ArrayList();
public DirectoryEntry( ResourceSectionReader section, EntryDescription entry ) {
super( createName( entry ) );
addMember(new DWord("Characteristics"));
addMember(new DWord("TimeDateStamp"));
addMember(new Word("MajorVersion"));
addMember(new Word("MinorVersion"));
addMember(new Word("NumberOfNamedEntries"));
addMember(new Word("NumberOfIdEntries"));
mySection = section;
if ( entry != null ){
Value flagValue = new DWord( "flag" ).setValue( 0x80000000 );
Bin.Value offset = entry.getValueMember("OffsetToData");
addOffsetHolder( new ValuesSub( offset, new ValuesAdd( mySection.getStartOffset(), flagValue ) ));
}
}
public ResourceSectionReader getSection(){
return mySection;
}
public static String createName( EntryDescription entry ){
String name = "IRD";
if ( entry != null ){
name += entry.getValueMember( "Name" ).getValue();
}
return name;
}
public DirectoryEntry findSubDir( String name ){
for (int i = 0; i < mySubDirs.size(); i++) {
DirectoryEntry directoryEntry = (DirectoryEntry) mySubDirs.get(i);
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);
return dataEntry.getRawResource();
}
public ArrayList getDatas() {
return myDatas;
}
public long sizeInBytes() {
return super.sizeInBytes();
}
public void insertDataEntry( int index, DataEntry dataEntry ){
myDatas.add( dataEntry );
getLevel().insertLevelEntry( index, dataEntry );
}
public void addDataEntry( DataEntry dataEntry ){
myDatas.add( dataEntry );
getLevel().addLevelEntry( dataEntry );
}
public void insertDirectoryEntry( int index, DirectoryEntry dir ){
getLevel().insertLevelEntry( index, dir );
mySubDirs.add( dir );
}
public void addDirectoryEntry( DirectoryEntry dir ){
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);
addMember(myIdEntries);
myIdEntries.setCountHolder(numberOfNamedEntries);
}
myIdEntries.addBin( entry );
}
public void read(DataInput stream) throws IOException {
super.read(stream);
Word numberOfNamedEntries = (Word) getMember("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);
addMember(myIdEntries);
myIdEntries.setCountHolder(numberOfIdEntries);
myIdEntries.read(stream);
processEntries(myNamedEntries);
processEntries(myIdEntries);
}
private void processEntries(ArrayOfBins entries) {
for (int i = 0; i < entries.size(); ++i) {
EntryDescription entry = (EntryDescription) entries.get(i);
Bin.Value offset = entry.getValueMember("OffsetToData");
if ((offset.getValue() & 0x80000000) != 0) {
addDirectoryEntry( new DirectoryEntry( mySection, entry ) );
} else {
addDataEntry( new DataEntry( mySection, offset ) );
}
}
}
public void report(OutputStreamWriter writer) throws IOException {
super.report(writer);
}
public void write(DataOutput stream) throws IOException {
super.write(stream);
}
}
@@ -0,0 +1,32 @@
/*
* 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 com.pme.exe.Bin;
/**
* Date: Apr 20, 2006
* Time: 3:59:15 PM
*/
public class EntryDescription extends Bin.Structure {
public EntryDescription() {
super("Entry");
addMember(new DWord("Name"));
addMember(new DWord("OffsetToData"));
}
}
@@ -0,0 +1,92 @@
/*
* 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 com.pme.exe.Bin;
import java.io.*;
/**
* Date: Apr 20, 2006
* Time: 3:56:31 PM
*/
public class Level extends Bin.Structure {
private Level mySubLevel = null;
public Level() {
super("Level");
}
public void addLevelEntry(LevelEntry dir) {
if (mySubLevel == null) {
mySubLevel = new Level();
}
dir.setLevel(mySubLevel);
addMember(dir);
}
public void insertLevelEntry(int index, LevelEntry dir) {
if (mySubLevel == null) {
mySubLevel = new Level();
}
dir.setLevel(mySubLevel);
insertMember(index,dir);
}
public long sizeInBytes() {
if (mySubLevel != null) {
return super.sizeInBytes() + mySubLevel.sizeInBytes();
}
return super.sizeInBytes();
}
public void resetOffsets(long newOffset) {
super.resetOffsets(newOffset);
if (mySubLevel != null) {
mySubLevel.resetOffsets(getOffset() + super.sizeInBytes());
}
}
/*
public void copyFrom(Bin structure) {
super.copyFrom(structure);
if (mySubLevel != null) {
mySubLevel.copyFrom(((Level)structure).mySubLevel);
}
}
*/
public void read(DataInput stream) throws IOException {
super.read(stream);
if (mySubLevel != null) {
mySubLevel.read(stream);
}
}
public void write(DataOutput stream) throws IOException {
super.write(stream);
if (mySubLevel != null) {
mySubLevel.write(stream);
}
}
public void report(OutputStreamWriter writer) throws IOException {
super.report(writer);
if (mySubLevel != null) {
mySubLevel.report(writer);
}
}
}
@@ -0,0 +1,41 @@
/*
* 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 com.pme.exe.Bin;
/**
* Date: Apr 17, 2006
* Time: 11:02:21 PM
*/
public abstract class LevelEntry extends Bin.Structure {
private Level myLevel = null;
public LevelEntry(String name) {
super(name);
}
public void setLevel(Level level) {
myLevel = level;
}
public Level getLevel() {
return myLevel;
}
}
@@ -0,0 +1,41 @@
/*
* 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;
/**
* Date: Apr 25, 2006
* Time: 3:12:58 PM
*/
public class RawResource extends LevelEntry {
public RawResource(ResourceSectionReader section, DWord rva, DWord size) {
super("Raw Resource");
Value offsetHolder = new ValuesAdd(rva, section.getMainSectionsOffset());
Bytes bytes = new Bytes("Raw Resource", offsetHolder, size);
bytes.addOffsetHolder(offsetHolder);
bytes.addSizeHolder(size);
addMember(bytes);
}
public Bytes getBytes(){
return (Bytes)getMember( "Raw Resource" );
}
public void setBytes( byte[] bytes ){
Bytes mem = (Bytes) getMember("Raw Resource");
mem.setBytes( bytes );
}
}
@@ -0,0 +1,93 @@
/*
* 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 com.pme.exe.Bin;
import com.pme.exe.ImageSectionHeader;
import com.pme.exe.ImageOptionalHeader;
import com.pme.exe.ImageDataDirectory;
import java.io.*;
/**
* Date: Apr 6, 2006
* Time: 7:10:09 PM
*/
public class ResourceSectionReader extends Bin.Structure {
private Level myRoot = new Level();
private Bin.Value myStartOffset;
private Bin.Value myMainSectionsOffset;
private Bin.Value mySize;
private Bin.Bytes myBytes;
public ResourceSectionReader( ImageSectionHeader sectionHeader, Bin.Value startOffset, Bin.Value mainSectionsOffset, ImageOptionalHeader imageOptionalHeader) {
super(((Bin.Txt)sectionHeader.getMember("Name")).getText());
myStartOffset = startOffset;
mySize = sectionHeader.getValueMember( "SizeOfRawData" );
Bin.Value virtualSize = sectionHeader.getValueMember( "VirtualSize" );
myMainSectionsOffset = mainSectionsOffset;
addOffsetHolder(startOffset);
ArrayOfBins imageDataDirs = (ArrayOfBins)imageOptionalHeader.getMember( "ImageDataDirectories" );
Bin[] bins = imageDataDirs.getArray();
ImageDataDirectory imageDataDirectory = (ImageDataDirectory)bins[2];
Value size = imageDataDirectory.getValueMember("Size");
addSizeHolder(mySize);
addSizeHolder(virtualSize);
addSizeHolder(size);
myRoot.addLevelEntry(new DirectoryEntry( this, null ));
addMember(myRoot);
}
public DirectoryEntry getRoot(){
return (DirectoryEntry)myRoot.getMember( "IRD" );
}
public Value getStartOffset() {
return myStartOffset;
}
public Value getMainSectionsOffset() {
return myMainSectionsOffset;
}
public long sizeInBytes() {
return super.sizeInBytes() + myBytes.sizeInBytes();
}
public void read(DataInput stream) throws IOException {
super.read(stream);
DWord size = new DWord("size");
size.setValue((mySize.getValue() - myRoot.sizeInBytes()));
DWord startOffset = new DWord("startOffset");
startOffset.setValue((myStartOffset.getValue() + myRoot.sizeInBytes()));
myBytes = new Bin.Bytes("Raw data", startOffset, size);
myBytes.read(stream);
}
public void write(DataOutput stream) throws IOException {
super.write(stream);
myBytes.write(stream);
}
public void report(OutputStreamWriter writer) throws IOException {
super.report(writer);
myBytes.report(writer);
}
}
@@ -0,0 +1,67 @@
/*
* 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 com.pme.exe.Bin;
import java.io.*;
/**
* Date: Apr 27, 2006
* Time: 12:43:28 PM
*/
public class StringTable {
String[] strings = new String[16];
public StringTable(byte[] bytes) throws IOException {
ByteArrayInputStream bytesStream = new ByteArrayInputStream(bytes);
DataInputStream stream = new DataInputStream(bytesStream);
Bin.Word count = new Bin.Word();
for (int i = 0; i < 16; ++i) {
count.read(stream);
if ( count.getValue() != 0 ){
Bin.Txt txt = new Bin.Txt("", (int)(count.getValue() * 2));
txt.read( stream );
strings[i] = txt.getText();
} else {
strings[i] = "";
}
}
}
public void setString( int index, String string ){
strings[index] = string;
}
public byte[] getBytes() throws IOException {
int size = 0;
for ( int i = 0; i < strings.length; ++i){
size += 2 + strings[i].length() * 2;
}
ByteArrayOutputStream bytesStream = new ByteArrayOutputStream(size);
DataOutputStream stream = new DataOutputStream(bytesStream);
for ( int i = 0; i < strings.length; ++i){
int count = strings[i].length();
new Bin.Word().setValue( count ).write( stream );
if ( count != 0 ){
new Bin.Txt( "", strings[i] ).write( stream );
}
}
return bytesStream.toByteArray();
}
}
@@ -0,0 +1,43 @@
/*
* 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 com.pme.exe.Bin;
/**
* Date: Apr 20, 2006
* Time: 4:32:29 PM
*/
public class ValuesAdd extends Bin.DWord {
private Bin.Value myActual;
private Bin.Value myMinus;
public ValuesAdd(Bin.Value actual, Bin.Value minusConst) {
super(actual.getName());
myActual = actual;
myMinus = minusConst;
}
public Value setValue(long value) {
return myActual.setValue(value + myMinus.getValue());
}
public long getValue() {
return myActual.getValue() - myMinus.getValue();
}
}
@@ -0,0 +1,43 @@
/*
* 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 com.pme.exe.Bin;
/**
* Date: Apr 20, 2006
* Time: 4:18:29 PM
*/
public class ValuesSub extends Bin.DWord {
private Bin.Value myActual;
private Bin.Value myMinus;
public ValuesSub(Bin.Value actual, Bin.Value minusConst) {
super(actual.getName());
myActual = actual;
myMinus = minusConst;
}
public Value setValue(long value) {
return myActual.setValue(value - myMinus.getValue());
}
public long getValue() {
return myActual.getValue() + myMinus.getValue();
}
}
@@ -0,0 +1,35 @@
/*
* 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.bmp;
import com.pme.exe.Bin;
/**
* Date: May 3, 2006
* Time: 12:34:47 PM
*/
public class BitmapFileHeader extends Bin.Structure{
public BitmapFileHeader() {
super("Bitmap File Header");
addMember( new Word( "bfType" ) );
addMember( new DWord( "bfSize" ) );
addMember( new Word( "bfReserved1" ) );
addMember( new Word( "bfReserved2" ) );
addMember( new DWord( "bfOffBits" ) );
}
}
@@ -0,0 +1,61 @@
/*
* 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.bmp;
import com.pme.exe.Bin;
import java.io.File;
import java.io.DataInput;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* Date: May 3, 2006
* Time: 12:33:01 PM
*/
public class BmpFile extends Bin.Structure {
private File myFile;
private BitmapFileHeader myHeader = new BitmapFileHeader();
public BmpFile(File file) {
super(file.getName());
myFile = file;
addMember( myHeader );
}
public void read() throws IOException {
RandomAccessFile stream = null;
try {
stream = new RandomAccessFile(myFile, "r");
read(stream);
} finally {
if (stream != null) {
stream.close();
}
}
}
public void read(DataInput stream) throws IOException {
super.read(stream);
Value bfSize = myHeader.getValueMember("bfSize");
long size = bfSize.getValue() - sizeInBytes();
Bytes bytes = new Bytes( "Data", size );
bytes.read( stream );
addMember( bytes );
}
}
@@ -0,0 +1,58 @@
/*
* 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.bmp;
import com.pme.exe.res.DirectoryEntry;
import com.pme.exe.res.RawResource;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* Date: May 3, 2006
* Time: 1:00:08 PM
*/
public class PictureResourceInjector {
public class PictureWrongFormat extends IOException {
public PictureWrongFormat(File file) {
super("Picture file is not found: " + file.getPath());
}
}
public void inject(File file, DirectoryEntry root, String resourceId) throws IOException {
byte[] bytes = new byte[(int) file.length()];
RandomAccessFile stream = null;
try {
stream = new RandomAccessFile(file, "r");
stream.read(bytes);
}
catch (IOException exception) {
throw new PictureWrongFormat(file);
}
finally {
if (stream != null) {
stream.close();
}
}
DirectoryEntry subDirBmp = root.findSubDir("IRD2").findSubDir(resourceId);
RawResource bmpRes = subDirBmp.getRawResource(0);
bmpRes.setBytes(bytes);
}
}
@@ -0,0 +1,42 @@
/*
* 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.icon;
import com.pme.exe.Bin;
import com.pme.exe.res.LevelEntry;
import com.pme.exe.res.Level;
/**
* Date: Apr 28, 2006
* Time: 11:35:48 AM
*/
public class GroupIconResource extends Bin.Structure {
public GroupIconResource( Bin.Value idCount ) {
super("GroupIcon");
addMember(new IconHeader());
Level level = new Level();
ArrayOfBins arrayOfBins = new ArrayOfBins("Icon directories", GroupIconResourceDirectory.class, idCount);
addMember(level);
Bin[] array = arrayOfBins.getArray();
for (Bin bin : array) {
level.addLevelEntry((LevelEntry) bin);
}
}
}
@@ -0,0 +1,38 @@
/*
* 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.icon;
import com.pme.exe.res.LevelEntry;
/**
* Date: Apr 28, 2006
* Time: 11:38:20 AM
*/
public class GroupIconResourceDirectory extends LevelEntry {
public GroupIconResourceDirectory() {
super("Icon Directory");
addMember( new Byte( "bWidth" ) );
addMember( new Byte( "bHeight" ) );
addMember( new Byte( "bColorCount" ) );
addMember( new Byte( "bReserved" ) );
addMember( new Word( "wPlanes" ) );
addMember( new Word( "wBitCount" ) );
addMember( new DWord( "dwBytesInRes" ) );
addMember( new Word( "dwId" ) );
}
}
@@ -0,0 +1,55 @@
/*
* 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.icon;
import com.pme.exe.res.LevelEntry;
import java.io.DataInput;
import java.io.IOException;
/**
* Date: Apr 27, 2006
* Time: 1:13:15 PM
*/
public class IconDirectory extends LevelEntry {
private RawBytes myRawBytes;
public IconDirectory() {
super("Icon Directory");
addMember( new Byte( "bWidth" ) );
addMember( new Byte( "bHeight" ) );
addMember( new Byte( "bColorCount" ) );
addMember( new Byte( "bReserved" ) );
addMember( new Word( "wPlanes" ) );
addMember( new Word( "wBitCount" ) );
addMember( new DWord( "dwBytesInRes" ) );
addMember( new DWord( "dwImageOffset" ) );
}
public byte[] getRawBytes(){
Bytes bytes = (Bytes)myRawBytes.getMember( "Raw Bytes" );
return bytes.getBytes();
}
public void read(DataInput stream) throws IOException {
super.read(stream);
RawBytes bytes = new RawBytes( getValueMember( "dwImageOffset" ),
getValueMember( "dwBytesInRes" ));
myRawBytes = bytes;
getLevel().addLevelEntry( bytes );
}
}
@@ -0,0 +1,79 @@
/*
* 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.icon;
import com.pme.exe.Bin;
import com.pme.exe.res.Level;
import com.pme.exe.res.LevelEntry;
import java.io.DataInput;
import java.io.IOException;
import java.io.File;
import java.io.RandomAccessFile;
/**
* Date: Apr 27, 2006
* Time: 12:52:09 PM
*/
public class IconFile extends Bin.Structure {
private Level myImages = new Level();
private File myFile;
public class IconWrongFormat extends IOException {
public IconWrongFormat( File file ) {
super("Icon file has wrong format:" + file.getPath());
}
}
public IconFile(File file) {
super(file.getName());
myFile = file;
addMember(new IconHeader());
}
public void read() throws IOException {
RandomAccessFile stream = null;
try {
stream = new RandomAccessFile(myFile, "r");
read(stream);
} finally {
if (stream != null) {
stream.close();
}
}
}
public void read(DataInput stream) throws IOException {
try {
super.read(stream);
Word idCount = (Word) ((Bin.Structure) getMember("Header")).getMember("idCount");
ArrayOfBins iconDirs = new ArrayOfBins("Icon directories", IconDirectory.class, idCount);
iconDirs.setCountHolder(idCount);
addMember(myImages);
Bin[] array = iconDirs.getArray();
for (int i = 0; i < array.length; i++) {
Bin bin = array[i];
myImages.addLevelEntry((LevelEntry) bin);
}
myImages.read(stream);
}
catch (IOException exception) {
throw new IconWrongFormat( myFile );
}
}
}
@@ -0,0 +1,33 @@
/*
* 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.icon;
import com.pme.exe.Bin;
/**
* Date: Apr 28, 2006
* Time: 11:30:10 AM
*/
public class IconHeader extends Bin.Structure{
public IconHeader() {
super("Header");
addMember(new Word("idReserved"));
addMember(new Word("idType"));
addMember(new Word("idCount"));
}
}
@@ -0,0 +1,94 @@
/*
* 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.icon;
import com.pme.exe.res.*;
import com.pme.exe.Bin;
import java.io.File;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
/**
* Date: Apr 28, 2006
* Time: 10:56:55 AM
*/
public class IconResourceInjector {
public void injectIcon(File file, DirectoryEntry root, String iconId) throws IOException {
IconFile iconFile = new IconFile(file);
iconFile.read();
DirectoryEntry subDirGroupIcon = root.findSubDir("IRD14").findSubDir(iconId);
RawResource groupIcon = subDirGroupIcon.getRawResource(0);
Bin.Value idCount = iconFile.getStructureMember("Header").getValueMember("idCount");
GroupIconResource groupIconResource = new GroupIconResource(idCount);
groupIconResource.copyFrom(iconFile);
Level level = (Level) groupIconResource.getMember("Level");
ArrayList directories = level.getMembers();
for (int i = 0; i < directories.size(); ++i) {
GroupIconResourceDirectory grpDir = (GroupIconResourceDirectory) directories.get(i);
grpDir.getValueMember("dwId").setValue(i + 1);
}
long size = groupIconResource.sizeInBytes();
ByteArrayOutputStream bytesStream = new ByteArrayOutputStream((int) size);
DataOutputStream stream = new DataOutputStream(bytesStream);
groupIconResource.write(stream);
groupIcon.getBytes().setBytes(bytesStream.toByteArray());
DirectoryEntry iconsDir = root.findSubDir("IRD3");
DirectoryEntry subDirIcon = iconsDir.findSubDir("IRD1");
RawResource rawResource = subDirIcon.getRawResource(0);
Level iconFileLevel = (Level) iconFile.getMember("Level");
IconDirectory iconDirectory = (IconDirectory) iconFileLevel.getMembers().get(0);
rawResource.setBytes(iconDirectory.getRawBytes());
ArrayList icons = iconFileLevel.getMembers();
for (int i = 1; i < icons.size(); i++) {
insertIcon(iconsDir, (IconDirectory) icons.get(i), i);
}
}
private void insertIcon(DirectoryEntry iconsDir, IconDirectory iconDirectory, int index) {
EntryDescription entryDescription = new EntryDescription();
Bin.Value name = entryDescription.getValueMember("Name");
name.setValue(index + 1);
DirectoryEntry entryDirIcon2 = new DirectoryEntry(iconsDir.getSection(), entryDescription);
iconsDir.insertDirectoryEntry(index, entryDirIcon2);
iconsDir.addIdEntry(entryDescription);
EntryDescription entry409 = new EntryDescription();
Bin.Value name409 = entry409.getValueMember("Name");
name409.setValue(0x409);
entryDirIcon2.addIdEntry(entry409);
Bin.Value offset = entry409.getValueMember("OffsetToData");
DataEntry dataEntry = new DataEntry(entryDirIcon2.getSection(), offset);
entryDirIcon2.insertDataEntry(index, dataEntry);
dataEntry.insertRawData(index);
RawResource rawRes = dataEntry.getRawResource();
rawRes.setBytes(iconDirectory.getRawBytes());
}
}
@@ -0,0 +1,35 @@
/*
* 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.icon;
import com.pme.exe.res.LevelEntry;
import com.pme.exe.Bin;
/**
* Date: Apr 27, 2006
* Time: 1:44:11 PM
*/
public class RawBytes extends LevelEntry {
public RawBytes( Bin.Value offsetHolder, Bin.Value size ) {
super("Raw Bytes");
Bytes bytes = new Bytes("Raw Bytes", offsetHolder, size);
bytes.addOffsetHolder( offsetHolder );
bytes.addSizeHolder( size );
addMember( bytes );
}
}
@@ -0,0 +1,43 @@
/*
* 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.vi;
import com.pme.exe.Bin;
/**
* Date: May 10, 2006
* Time: 1:35:49 PM
*/
public class FixedFileInfo extends Bin.Structure {
public FixedFileInfo() {
super("FixedFileInfo");
addMember( new DWord( "dwSignature" ) );
addMember( new DWord( "dwStrucVersion" ) );
addMember( new DWord( "dwFileVersionMS" ) );
addMember( new DWord( "dwFileVersionLS" ) );
addMember( new DWord( "dwProductVersionMS" ) );
addMember( new DWord( "dwProductVersionLS" ) );
addMember( new DWord( "dwFileFlagsMask" ) );
addMember( new DWord( "dwFileFlags" ) );
addMember( new DWord( "dwFileOS" ) );
addMember( new DWord( "dwFileType" ) );
addMember( new DWord( "dwFileSubtype" ) );
addMember( new DWord( "dwFileDateMS" ) );
addMember( new DWord( "dwFileDateLS" ) );
}
}
@@ -0,0 +1,43 @@
/*
* 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.vi;
import com.pme.exe.Bin;
import java.io.DataInput;
import java.io.IOException;
/**
* Date: May 10, 2006
* Time: 8:01:15 PM
*/
public class StringFileInfo extends Bin.Structure {
public StringFileInfo() {
super("StringFileInfo");
addMember( new Word( "wLength" ) );
addMember( new Word( "wValueLength" ) );
addMember( new Word( "wType" ) );
addMember( new Bytes( "Bytes", 30 ) );
}
public void readWithPadding( DataInput stream, long offset ) throws IOException {
read( stream );
StringTableReader stringTableReader = new StringTableReader();
stringTableReader.readWithPadding( stream, offset + sizeInBytes() );
addMember( stringTableReader );
}
}
@@ -0,0 +1,75 @@
/*
* 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.vi;
import com.pme.exe.Bin;
import java.io.*;
import java.util.ArrayList;
/**
* Date: May 10, 2006
* Time: 8:26:03 PM
*/
public class StringTableEntry extends Bin.Structure {
public StringTableEntry(String key) {
super(key);
addMember(new Word("wLength"));
addMember(new Word("wValueLength"));
addMember(new Word("wType"));
addMember(new Bytes("key", key.length() * 2));
}
public void readWithPadding(DataInput stream, long offset) throws IOException {
read(stream);
long off = offset + sizeInBytes();
Bytes padding = new Bytes("Padding", off % 8);
padding.read(stream);
addMember(padding);
ArrayList list = new ArrayList();
for(int i = 0;;++i){
Word word = new Word( "" + i );
word.read( stream );
list.add( word );
if ( word.getValue() == 0 ) break;
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(list.size() * 2);
DataOutputStream bytesStream = new DataOutputStream( byteArrayOutputStream );
for (int i = 0; i < list.size(); ++i) {
Word word = (Word)list.get(i);
word.write( bytesStream );
}
bytesStream.close();
Txt txt = new Txt("Value", byteArrayOutputStream.toByteArray());
System.out.println( txt.getText() );
addMember( txt );
offset += sizeInBytes();
System.out.println( "" + offset % 8 );
System.out.println( "" + offset % 4 );
System.out.println( "" + offset % 16 );
long r = offset % 8;
if ( r > 0 ){
Bytes padding2 = new Bytes( "Padding2", r );
padding2.read( stream );
addMember( padding2 );
}
}
}
@@ -0,0 +1,57 @@
/*
* 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.vi;
import com.pme.exe.Bin;
import java.io.DataInput;
import java.io.IOException;
/**
* Date: May 10, 2006
* Time: 8:09:42 PM
*/
public class StringTableReader extends Bin.Structure{
public StringTableReader() {
super("StringTable");
addMember( new Word( "wLength" ) );
addMember( new Word( "wValueLength" ) );
addMember( new Word( "wType" ) );
addMember( new Bytes( "Bytes", 18 ) );
}
public void readWithPadding( DataInput stream, long offset ) throws IOException {
read(stream);
StringTableEntry stringTableEntry = new StringTableEntry("CompanyName");
stringTableEntry.readWithPadding( stream, offset + sizeInBytes() );
addMember( stringTableEntry );
StringTableEntry desc = new StringTableEntry("FileDescription");
desc.readWithPadding( stream, offset + sizeInBytes() + stringTableEntry.sizeInBytes() );
addMember( desc );
StringTableEntry fileVersion = new StringTableEntry("FileVersion");
fileVersion.readWithPadding( stream, offset + sizeInBytes() + stringTableEntry.sizeInBytes() + desc.sizeInBytes() );
addMember( fileVersion );
StringTableEntry internalName = new StringTableEntry("InternalName");
internalName.readWithPadding( stream, offset + sizeInBytes() + stringTableEntry.sizeInBytes() + desc.sizeInBytes() + fileVersion.sizeInBytes() );
addMember( internalName );
}
}
@@ -0,0 +1,43 @@
/*
* 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.vi;
import com.pme.exe.Bin;
import java.io.DataInput;
import java.io.IOException;
/**
* Date: May 10, 2006
* Time: 1:33:34 PM
*/
public class VersionInfoReader extends Bin.Structure {
public VersionInfoReader() {
super("VersionInfo");
addMember( new Word("wLength") );
addMember( new Bytes( "Bytes", 38 ) );
addMember( new FixedFileInfo() );
}
public void read(DataInput stream) throws IOException {
super.read(stream);
StringFileInfo stringFileInfo = new StringFileInfo();
stringFileInfo.readWithPadding( stream, sizeInBytes() );
addMember( stringFileInfo );
}
}
@@ -0,0 +1,170 @@
/*
* 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 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.bmp.PictureResourceInjector;
import com.pme.exe.res.icon.IconResourceInjector;
import com.pme.exe.res.vi.VersionInfoReader;
import java.io.*;
/**
* Date: May 6, 2006
* Time: 10:43:01 AM
*/
public class LauncherGenerator {
private File myTemplate;
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;
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 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);
if (myIcon != null) {
IconResourceInjector iconInjector = new IconResourceInjector();
iconInjector.injectIcon(myIcon, root, "IRD101");
}
if (myBmp != null) {
PictureResourceInjector bmpInjector = new PictureResourceInjector();
bmpInjector.inject(myBmp, root, "IRD104");
}
DirectoryEntry viDir = root.findSubDir("IRD16").findSubDir( "IRD1" );
Bin.Bytes viBytes = viDir.getRawResource( 0 ).getBytes();
ByteArrayInputStream bytesStream = new ByteArrayInputStream(viBytes.getBytes());
VersionInfoReader viReader = new VersionInfoReader();
viReader.read(new DataInputStream(bytesStream));
reader.resetOffsets(0);
myExePath.getParentFile().mkdirs();
myExePath.createNewFile();
RandomAccessFile exeStream = new RandomAccessFile(myExePath, "rw");
reader.write(exeStream);
exeStream.close();
}
public void setJavaVersion(String javaVersion) {
myJavaVersion = javaVersion;
}
public void setSearchJdkOnly(boolean searchJdkOnly) {
mySearchJdkOnly = searchJdkOnly;
}
}
@@ -0,0 +1,45 @@
/*
* 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.util;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InvalidClassException;
public class AttributeInfo {
private ConstantPoolInfo myName;
private byte myData[];
public ConstantPoolInfo getName() {
return myName;
}
public byte[] getData() {
return myData;
}
public void read(DataInputStream stream, ConstantPoolInfo pool[]) throws IOException {
myName = pool[stream.readShort()];
int len = stream.readInt();
myData = new byte[len];
len = stream.read(myData);
if (len != myData.length){
throw new InvalidClassException( "Cannot read content for attribute: " + myName.getStrValue() );
}
}
}
@@ -0,0 +1,63 @@
/*
* 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.util;
/**
* Date: Mar 30, 2006
* Time: 7:10:10 PM
*/
public class BitsUtil {
public static int revertBytesOfShort( short shortValue ){
return ((shortValue << 8) & 0xff00) + ((shortValue >> 8) & 0xff);
}
public static long revertBytesOfInt( int intValue ){
long result = (intValue & 0x000000ff);
result <<= 24;
result += ((intValue & 0x0000ff00) << 8) + ((intValue & 0x00ff0000) >> 8) + ((intValue >> 24) & 0xff);
return result;
}
public static int unsignedByte( byte byteValue ){
int result = byteValue;
return (result & 0xff);
}
private static String toHexString( long value, int size ){
String strValue = Long.toHexString( value );
if ( strValue.length() > size ){
strValue = strValue.substring( strValue.length() - size );
}
StringBuffer buffer = new StringBuffer( strValue.length() + 1 + size );
buffer.append( "0x" );
int dif = size - strValue.length();
for ( int i = 0; i < dif; ++i ){
buffer.append( "0" );
}
buffer.append( strValue );
return buffer.toString();
}
public static String intToHexString( long value ){
return toHexString( value, 8 );
}
public static String shortToHexString( int value ){
return toHexString( value, 4 );
}
public static String byteToHexString( int value ){
return toHexString( value, 2 );
}
}
@@ -0,0 +1,141 @@
/*
* 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.util;
import java.io.*;
public class ClassFile {
private int myMagic;
private short myMajorVersion;
private short myMinorVersion;
private ConstantPoolInfo myConstantPool[];
private short myAccessFlags;
private ConstantPoolInfo myThisClass;
private ConstantPoolInfo mySuperClass;
private ConstantPoolInfo myInterfaces[];
private FieldInfo myFields[];
private MethodInfo myMethods[];
private AttributeInfo myAttributes[];
private void readConstantPool(DataInputStream stream) throws IOException {
myConstantPool = new ConstantPoolInfo[stream.readShort()];
myConstantPool[0] = new ConstantPoolInfo();
for (int i = 1; i < myConstantPool.length; i++) {
myConstantPool[i] = new ConstantPoolInfo();
myConstantPool[i].read(stream);
// These two types take up "two" spots in the table
if ((myConstantPool[i].getType() == ConstantPoolInfo.LONG) ||
(myConstantPool[i].getType() == ConstantPoolInfo.DOUBLE))
i++;
}
}
private void readInterfaces(DataInputStream stream) throws IOException {
int count = stream.readShort();
if (count != 0) {
myInterfaces = new ConstantPoolInfo[count];
for (int i = 0; i < count; i++) {
int index = stream.readShort();
if ((index < 1) || (index > myConstantPool.length - 1))
throw new InvalidClassException("Wrong count for constant pool");
myInterfaces[i] = myConstantPool[index];
}
}
}
private void readFields(DataInputStream stream) throws IOException {
int count = stream.readShort();
if (count != 0) {
myFields = new FieldInfo[count];
for (int i = 0; i < count; i++) {
myFields[i] = new FieldInfo();
myFields[i].read(stream, myConstantPool);
}
}
}
private void readMethods(DataInputStream stream) throws IOException {
int count = stream.readShort();
if (count != 0) {
myMethods = new MethodInfo[count];
for (int i = 0; i < count; i++) {
myMethods[i] = new MethodInfo();
myMethods[i].read(stream, myConstantPool);
}
}
}
private void readAttributes(DataInputStream stream) throws IOException {
int count = stream.readShort();
if (count != 0) {
myAttributes = new AttributeInfo[count];
for (int i = 0; i < count; i++) {
myAttributes[i] = new AttributeInfo();
myAttributes[i].read(stream, myConstantPool);
}
}
}
public static String readClassName(File file) throws IOException {
FileInputStream stream = new FileInputStream(file);
ClassFile classFile = new ClassFile();
try {
classFile.read(stream);
return classFile.getSourceName();
} finally{
stream.close();
}
}
public void read(InputStream in) throws IOException {
DataInputStream stream = new DataInputStream(in);
myMagic = stream.readInt();
if (myMagic != 0xCAFEBABE) {
throw new InvalidClassException("There is no magic number");
}
myMajorVersion = stream.readShort();
myMinorVersion = stream.readShort();
readConstantPool(stream);
myAccessFlags = stream.readShort();
myThisClass = myConstantPool[stream.readShort()];
mySuperClass = myConstantPool[stream.readShort()];
readInterfaces(stream);
readFields(stream);
readMethods(stream);
readAttributes(stream);
}
public String getSourceName() {
if (myAttributes != null) {
for (int i = 0; i < myAttributes.length; i++) {
String attrName = myAttributes[i].getName().getStrValue();
if ("SourceFile".compareTo(attrName) == 0) {
try {
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(myAttributes[i].getData()));
ConstantPoolInfo cpi = myConstantPool[dis.readShort()];
return cpi.getStrValue();
} catch (IOException e) {
}
}
}
}
return null;
}
}
@@ -0,0 +1,105 @@
/*
* 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.util;
import java.io.DataInputStream;
import java.io.IOException;
public class ConstantPoolInfo {
private int myType = -1;
private short myIindex1 = -1;
private short myIndex2 = -1;
private String myStrValue;
private int myIntValue;
private long myLongValue;
private float myFloatValue;
private double myDoubleValue;
public static final int CLASS = 7;
public static final int FIELDREF = 9;
public static final int METHODREF = 10;
public static final int STRING = 8;
public static final int INTEGER = 3;
public static final int FLOAT = 4;
public static final int LONG = 5;
public static final int DOUBLE = 6;
public static final int INTERFACE = 11;
public static final int NAMEANDTYPE = 12;
public static final int ASCIZ = 1;
public static final int UNICODE = 2;
public String getStrValue() {
return myStrValue;
}
public int getType() {
return myType;
}
public void read(DataInputStream stream)throws IOException {
myType = stream.readByte();
switch (myType) {
case CLASS:
myIindex1 = stream.readShort();
break;
case FIELDREF:
myIindex1 = stream.readShort();
myIndex2 = stream.readShort();
break;
case METHODREF:
myIindex1 = stream.readShort();
myIndex2 = stream.readShort();
break;
case INTERFACE:
myIindex1 = stream.readShort();
myIndex2 = stream.readShort();
break;
case NAMEANDTYPE:
myIindex1 = stream.readShort();
myIndex2 = stream.readShort();
break;
case STRING:
myIindex1 = stream.readShort();
break;
case INTEGER:
myIntValue = stream.readInt();
break;
case FLOAT:
myFloatValue = stream.readFloat();
break;
case LONG:
myLongValue = stream.readLong();
break;
case DOUBLE:
myDoubleValue = stream.readDouble();
break;
case ASCIZ:
case UNICODE:
StringBuffer buff = new StringBuffer();
int len = stream.readShort();
while (len > 0) {
char c = (char) (stream.readByte());
buff.append(c);
len--;
}
myStrValue = buff.toString();
break;
}
}
}
@@ -0,0 +1,58 @@
/*
* 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.util;
import java.io.DataInputStream;
import java.io.IOException;
public class FieldInfo {
private short myAccessFlags;
private ConstantPoolInfo myName;
private ConstantPoolInfo mySignature;
private AttributeInfo myAttributes[];
public short getAccessFlags() {
return myAccessFlags;
}
public ConstantPoolInfo getName() {
return myName;
}
public ConstantPoolInfo getSignature() {
return mySignature;
}
public AttributeInfo[] getAttributes() {
return myAttributes;
}
public void read(DataInputStream stream, ConstantPoolInfo pool[]) throws IOException {
myAccessFlags = stream.readShort();
myName = pool[stream.readShort()];
mySignature = pool[stream.readShort()];
int count = stream.readShort();
if (count != 0) {
myAttributes = new AttributeInfo[count];
for (int i = 0; i < count; i++) {
myAttributes[i] = new AttributeInfo();
myAttributes[i].read(stream, pool);
}
}
}
}
@@ -0,0 +1,58 @@
/*
* 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.util;
import java.io.DataInputStream;
import java.io.IOException;
public class MethodInfo {
private short myAccessFlags;
private ConstantPoolInfo myName;
private ConstantPoolInfo mySignature;
private AttributeInfo myAttributes[];
public short getAccessFlags() {
return myAccessFlags;
}
public ConstantPoolInfo getName() {
return myName;
}
public ConstantPoolInfo getSignature() {
return mySignature;
}
public AttributeInfo[] getAttributes() {
return myAttributes;
}
public void read(DataInputStream stream, ConstantPoolInfo pool[]) throws IOException {
myAccessFlags = stream.readShort();
myName = pool[stream.readShort()];
mySignature = pool[stream.readShort()];
int count = stream.readShort();
if (count != 0) {
myAttributes = new AttributeInfo[count];
for (int i = 0; i < count; i++) {
myAttributes[i] = new AttributeInfo(); // "code"
myAttributes[i].read(stream, pool);
}
}
}
}