2
Copyright (C) 2008 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
25
using System.Globalization;
26
using IKVM.Reflection.Emit;
28
namespace IKVM.Reflection.Writer
30
sealed class VersionInfo
32
private AssemblyName name;
33
private string fileName;
34
internal string copyright;
35
internal string trademark;
36
internal string product;
37
internal string company;
38
private string description;
40
internal string informationalVersion;
41
private string fileVersion;
43
internal void SetName(AssemblyName name)
48
internal void SetFileName(string assemblyFileName)
50
this.fileName = assemblyFileName;
53
internal void SetAttribute(CustomAttributeBuilder cab)
55
Universe u = cab.Constructor.Module.universe;
56
Type type = cab.Constructor.DeclaringType;
57
if (copyright == null && type == u.System_Reflection_AssemblyCopyrightAttribute)
59
copyright = (string)cab.GetConstructorArgument(0);
61
else if (trademark == null && type == u.System_Reflection_AssemblyTrademarkAttribute)
63
trademark = (string)cab.GetConstructorArgument(0);
65
else if (product == null && type == u.System_Reflection_AssemblyProductAttribute)
67
product = (string)cab.GetConstructorArgument(0);
69
else if (company == null && type == u.System_Reflection_AssemblyCompanyAttribute)
71
company = (string)cab.GetConstructorArgument(0);
73
else if (description == null && type == u.System_Reflection_AssemblyDescriptionAttribute)
75
description = (string)cab.GetConstructorArgument(0);
77
else if (title == null && type == u.System_Reflection_AssemblyTitleAttribute)
79
title = (string)cab.GetConstructorArgument(0);
81
else if (informationalVersion == null && type == u.System_Reflection_AssemblyInformationalVersionAttribute)
83
informationalVersion = (string)cab.GetConstructorArgument(0);
85
else if (fileVersion == null && type == u.System_Reflection_AssemblyFileVersionAttribute)
87
fileVersion = (string)cab.GetConstructorArgument(0);
91
internal void Write(ByteBuffer bb)
93
if (fileVersion == null)
95
if (name.Version != null)
97
fileVersion = name.Version.ToString();
101
fileVersion = "0.0.0.0";
105
int codepage = 1200; // Unicode codepage
109
if (name.CultureInfo != null)
111
lcid = name.CultureInfo.LCID;
114
catch (ArgumentException)
116
// AssemblyName.CultureInfo throws an ArgumentException if AssemblyBuilder.__SetAssemblyCulture() was used to specify a non-existing culture
119
Version filever = ParseVersionRobust(fileVersion);
120
int fileVersionMajor = filever.Major;
121
int fileVersionMinor = filever.Minor;
122
int fileVersionBuild = filever.Build;
123
int fileVersionRevision = filever.Revision;
125
int productVersionMajor = fileVersionMajor;
126
int productVersionMinor = fileVersionMinor;
127
int productVersionBuild = fileVersionBuild;
128
int productVersionRevision = fileVersionRevision;
129
if (informationalVersion != null)
131
Version productver = ParseVersionRobust(informationalVersion);
132
productVersionMajor = productver.Major;
133
productVersionMinor = productver.Minor;
134
productVersionBuild = productver.Build;
135
productVersionRevision = productver.Revision;
138
ByteBuffer stringTable = new ByteBuffer(512);
139
stringTable.Write((short)0); // wLength (placeholder)
140
stringTable.Write((short)0); // wValueLength
141
stringTable.Write((short)1); // wType
142
WriteUTF16Z(stringTable, string.Format("{0:x4}{1:x4}", lcid, codepage));
143
stringTable.Align(4);
145
WriteString(stringTable, "Comments", description);
146
WriteString(stringTable, "CompanyName", company);
147
WriteString(stringTable, "FileDescription", title);
148
WriteString(stringTable, "FileVersion", fileVersion);
149
WriteString(stringTable, "InternalName", name.Name);
150
WriteString(stringTable, "LegalCopyright", copyright);
151
WriteString(stringTable, "LegalTrademarks", trademark);
152
WriteString(stringTable, "OriginalFilename", fileName);
153
WriteString(stringTable, "ProductName", product);
154
WriteString(stringTable, "ProductVersion", informationalVersion);
156
stringTable.Position = 0;
157
stringTable.Write((short)stringTable.Length);
159
ByteBuffer stringFileInfo = new ByteBuffer(512);
160
stringFileInfo.Write((short)0); // wLength (placeholder)
161
stringFileInfo.Write((short)0); // wValueLength
162
stringFileInfo.Write((short)1); // wType
163
WriteUTF16Z(stringFileInfo, "StringFileInfo");
164
stringFileInfo.Align(4);
165
stringFileInfo.Write(stringTable);
166
stringFileInfo.Position = 0;
167
stringFileInfo.Write((short)stringFileInfo.Length);
169
byte[] preamble1 = new byte[] {
170
// VS_VERSIONINFO (platform SDK)
171
0x34, 0x00, // wValueLength
173
0x56, 0x00, 0x53, 0x00, 0x5F, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4F, 0x00, 0x4E, 0x00, 0x5F, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x46, 0x00, 0x4F, 0x00, 0x00, 0x00, // "VS_VERSION_INFO\0"
174
0x00, 0x00, // Padding1 (32 bit alignment)
175
// VS_FIXEDFILEINFO starts
176
0xBD, 0x04, 0xEF, 0xFE, // dwSignature (0xFEEF04BD)
177
0x00, 0x00, 0x01, 0x00, // dwStrucVersion
179
byte[] preamble2 = new byte[] {
180
0x3F, 0x00, 0x00, 0x00, // dwFileFlagsMask (??)
181
0x00, 0x00, 0x00, 0x00, // dwFileFlags (??)
182
0x04, 0x00, 0x00, 0x00, // dwFileOS
183
0x02, 0x00, 0x00, 0x00, // dwFileType
184
0x00, 0x00, 0x00, 0x00, // dwFileSubtype
185
0x00, 0x00, 0x00, 0x00, // dwFileDateMS
186
0x00, 0x00, 0x00, 0x00, // dwFileDateLS
187
// Padding2 (32 bit alignment)
189
0x44, 0x00, // wLength
190
0x00, 0x00, // wValueLength
192
0x56, 0x00, 0x61, 0x00, 0x72, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x00, 0x00, // "VarFileInfo\0"
193
0x00, 0x00, // Padding
195
0x24, 0x00, // wLength
196
0x04, 0x00, // wValueLength
198
0x54, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x73, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, // "Translation\0"
199
0x00, 0x00, // Padding (32 bit alignment)
201
bb.Write((short)(2 + preamble1.Length + 8 + 8 + preamble2.Length + 4 + stringFileInfo.Length));
203
bb.Write((short)fileVersionMinor);
204
bb.Write((short)fileVersionMajor);
205
bb.Write((short)fileVersionRevision);
206
bb.Write((short)fileVersionBuild);
207
bb.Write((short)productVersionMinor);
208
bb.Write((short)productVersionMajor);
209
bb.Write((short)productVersionRevision);
210
bb.Write((short)productVersionBuild);
212
bb.Write((short)lcid);
213
bb.Write((short)codepage);
214
bb.Write(stringFileInfo);
217
private static void WriteUTF16Z(ByteBuffer bb, string str)
219
foreach (char c in str)
226
private static void WriteString(ByteBuffer bb, string name, string value)
228
value = value ?? " ";
229
int pos = bb.Position;
230
bb.Write((short)0); // wLength (placeholder)
231
bb.Write((short)(value.Length + 1));// wValueLength
232
bb.Write((short)1); // wType
233
WriteUTF16Z(bb, name);
235
WriteUTF16Z(bb, value);
237
int savedPos = bb.Position;
239
bb.Write((short)(savedPos - pos));
240
bb.Position = savedPos;
243
private static Version ParseVersionRobust(string ver)
246
ushort major = ParseVersionPart(ver, ref index);
247
ushort minor = ParseVersionPart(ver, ref index);
248
ushort build = ParseVersionPart(ver, ref index);
249
ushort revision = ParseVersionPart(ver, ref index);
250
return new Version(major, minor, build, revision);
253
private static ushort ParseVersionPart(string str, ref int pos)
256
while (pos < str.Length)
264
else if (c >= '0' && c <= '9')
267
value += (ushort)(c - '0');