fixes in version info writing; API for updating version info

This commit is contained in:
Dmitry Jemerov
2013-03-27 21:18:28 +01:00
parent 16775c5d7c
commit b4905d5bbf
7 changed files with 85 additions and 10 deletions
@@ -61,8 +61,12 @@ public abstract class Bin {
public void resetOffsets(long offset) {
myOffset = offset;
updateSizeOffsetHolders();
}
protected void updateSizeOffsetHolders() {
for (Value holder : myOffsetHolders) {
holder.setValue(offset);
holder.setValue(myOffset);
}
for (Value holder : mySizeHolders) {
holder.setValue(sizeInBytes());
@@ -127,6 +131,7 @@ public abstract class Bin {
bin.resetOffsets(offset);
offset = offset + bin.sizeInBytes();
}
updateSizeOffsetHolders();
}
public void copyFrom(Bin binStructure) {
@@ -187,7 +192,7 @@ public abstract class Bin {
}
public Bin getMember(String name) {
return (Bin) myMembersMap.get(name);
return myMembersMap.get(name);
}
public Bin.Value getValueMember(String name) {
@@ -389,6 +394,10 @@ public abstract class Bin {
@Override
public void write(DataOutput stream) throws IOException {
int skip = bytesToSkip(getOffset());
for (int i = 0; i < skip; i++) {
stream.writeByte(0);
}
}
@Override
@@ -503,6 +512,10 @@ public abstract class Bin {
public String getValue() {
return myValue;
}
public void setValue(String value) {
myValue = value;
}
}
public static class Bytes extends Bin {
@@ -26,4 +26,8 @@ public class StringFileInfo extends VersionInfoBin {
}
});
}
public StringTable getFirstStringTable() {
return (StringTable) getMember("StringTable0");
}
}
@@ -17,6 +17,8 @@
package com.pme.exe.res.vi;
import com.pme.exe.Bin;
public class StringTable extends VersionInfoBin {
public StringTable(String name) {
@@ -27,4 +29,15 @@ public class StringTable extends VersionInfoBin {
}
});
}
public void setStringValue(String key, String value) {
for (Bin bin : getMembers()) {
if (bin.getName().equals(key)) {
StringTableEntry entry = (StringTableEntry) bin;
((WChar) entry.getMember("Value")).setValue(value);
return;
}
}
assert false: "Could not find string with key " + key;
}
}
@@ -23,11 +23,14 @@ import java.io.DataInput;
import java.io.IOException;
public class VersionInfo extends VersionInfoBin {
private final StringFileInfo myStringFileInfo;
public VersionInfo() {
super("VersionInfo", "VS_VERSION_INFO");
addMember(new FixedFileInfo());
addMember(new Padding(4));
addMember(new StringFileInfo());
myStringFileInfo = new StringFileInfo();
addMember(myStringFileInfo);
addMember(new VarFileInfo());
}
@@ -45,4 +48,8 @@ public class VersionInfo extends VersionInfoBin {
") does not match actual version info length (" + (offset - startOffset) + ")";
}
}
public StringFileInfo getStringFileInfo() {
return myStringFileInfo;
}
}
@@ -4,7 +4,9 @@ import com.pme.exe.Bin;
import com.pme.util.OffsetTrackingInputStream;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* @author yole
@@ -54,4 +56,21 @@ public class VersionInfoBin extends Bin.Structure {
}
}
}
@Override
public void write(DataOutput stream) throws IOException {
long startOffset = -1;
if (stream instanceof RandomAccessFile) {
startOffset = ((RandomAccessFile) stream).getFilePointer();
assert startOffset % 4 == 0;
}
super.write(stream);
if (stream instanceof RandomAccessFile) {
long offset = ((RandomAccessFile) stream).getFilePointer();
long realLength = offset - startOffset;
long expectedLength = getValue("wLength");
assert realLength == expectedLength: "Actual length does not match calculated length for " + getName() +
": expected " + expectedLength + ", actual " + realLength + ", sizeInBytes() " + sizeInBytes();
}
}
}
@@ -27,6 +27,7 @@ import com.pme.exe.res.RawResource;
import com.pme.exe.res.ResourceSectionReader;
import com.pme.exe.res.StringTableDirectory;
import com.pme.exe.res.icon.IconResourceInjector;
import com.pme.exe.res.vi.StringTable;
import com.pme.exe.res.vi.VersionInfo;
import com.pme.util.OffsetTrackingInputStream;
@@ -49,7 +50,6 @@ public class LauncherGenerator {
myExePath = exePath;
}
public void load() throws IOException {
myReader = new ExeReader(myTemplate.getName());
RandomAccessFile stream = new RandomAccessFile(myTemplate, "r");
@@ -80,15 +80,31 @@ public class LauncherGenerator {
myReader.write(exeStream);
exeStream.close();
RandomAccessFile versionInfoStream = new RandomAccessFile(myExePath + ".version", "rw");
myVersionInfo.resetOffsets(0);
myVersionInfo.write(versionInfoStream);
String versionInfoPath = myExePath + ".version";
RandomAccessFile versionInfoStream = new RandomAccessFile(versionInfoPath, "rw");
try {
myVersionInfo.resetOffsets(0);
myVersionInfo.write(versionInfoStream);
}
finally {
versionInfoStream.close();
}
VersionInfo copy = new VersionInfo();
copy.read(new OffsetTrackingInputStream(new DataInputStream(new FileInputStream(versionInfoPath))));
}
public void setResourceString(int id, String value) {
myStringTableDirectory.setString(id, value);
}
public void setVersionInfoString(String key, String value) {
StringTable stringTable = myVersionInfo.getStringFileInfo().getFirstStringTable();
if (stringTable != null) {
stringTable.setStringValue(key, value);
}
}
public void injectBitmap(int id, byte[] bitmapData) {
DirectoryEntry subDirBmp = myRoot.findSubDir("IRD2").findSubDir("IRD" + id);
RawResource bmpRes = subDirBmp.getRawResource(0);
@@ -25,9 +25,7 @@ import org.jdom.input.SAXBuilder;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -117,6 +115,9 @@ public class LauncherGeneratorMain {
System.exit(8);
}
String companyName = appInfo.getRootElement().getChild("company").getAttributeValue("name");
int year = new GregorianCalendar().get(Calendar.YEAR);
LauncherGenerator generator = new LauncherGenerator(template, new File(args[4]));
try {
generator.load();
@@ -134,6 +135,8 @@ public class LauncherGeneratorMain {
generator.injectBitmap(resourceIDs.get("IDB_SPLASH"), splashBmpStream.toByteArray());
generator.injectIcon(resourceIDs.get("IDI_WINLAUNCHER"), iconStream);
generator.setVersionInfoString("LegalCopyright", "Copyright (C) 2000-" + year + " " + companyName);
generator.generate();
} catch (IOException e) {
e.printStackTrace();