IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
VersionInfo.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2008 Jeroen Frijters
3
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.
7
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:
11
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.
19
20 Jeroen Frijters
21 jeroen@frijters.net
22
23*/
24using System;
25
27
29{
30
31 sealed class VersionInfo
32 {
33
34 AssemblyName name;
35 string fileName;
36 internal string copyright;
37 internal string trademark;
38 internal string product;
39 internal string company;
40 string description;
41 string title;
42 internal string informationalVersion;
43 string fileVersion;
44
45 internal void SetName(AssemblyName name)
46 {
47 this.name = name;
48 }
49
50 internal void SetFileName(string assemblyFileName)
51 {
52 this.fileName = System.IO.Path.GetFileName(assemblyFileName);
53 }
54
55 internal void SetAttribute(AssemblyBuilder asm, CustomAttributeBuilder cab)
56 {
57 var u = cab.Constructor.Module.Universe;
58 var type = cab.Constructor.DeclaringType;
59 if (copyright == null && type == u.System_Reflection_AssemblyCopyrightAttribute)
60 {
61 copyright = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
62 }
63 else if (trademark == null && type == u.System_Reflection_AssemblyTrademarkAttribute)
64 {
65 trademark = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
66 }
67 else if (product == null && type == u.System_Reflection_AssemblyProductAttribute)
68 {
69 product = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
70 }
71 else if (company == null && type == u.System_Reflection_AssemblyCompanyAttribute)
72 {
73 company = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
74 }
75 else if (description == null && type == u.System_Reflection_AssemblyDescriptionAttribute)
76 {
77 description = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
78 }
79 else if (title == null && type == u.System_Reflection_AssemblyTitleAttribute)
80 {
81 title = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
82 }
83 else if (informationalVersion == null && type == u.System_Reflection_AssemblyInformationalVersionAttribute)
84 {
85 informationalVersion = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
86 }
87 else if (fileVersion == null && type == u.System_Reflection_AssemblyFileVersionAttribute)
88 {
89 fileVersion = (string)cab.DecodeBlob(asm).GetConstructorArgument(0);
90 }
91 }
92
93 internal void Write(ByteBuffer bb)
94 {
95 if (fileVersion == null)
96 {
97 if (name.Version != null)
98 {
99 fileVersion = name.Version.ToString();
100 }
101 else
102 {
103 fileVersion = "0.0.0.0";
104 }
105 }
106
107 int codepage = 1200; // Unicode codepage
108
109 int lcid = 0x7f;
110 try
111 {
112 if (name.CultureInfo != null)
113 lcid = name.CultureInfo.LCID;
114 }
115 catch (ArgumentException)
116 {
117 // AssemblyName.CultureInfo throws an ArgumentException if AssemblyBuilder.__SetAssemblyCulture() was used to specify a non-existing culture
118 }
119
120 var filever = ParseVersionRobust(fileVersion);
121 var fileVersionMajor = filever.Major;
122 var fileVersionMinor = filever.Minor;
123 var fileVersionBuild = filever.Build;
124 var fileVersionRevision = filever.Revision;
125
126 var productVersionMajor = fileVersionMajor;
127 var productVersionMinor = fileVersionMinor;
128 var productVersionBuild = fileVersionBuild;
129 var productVersionRevision = fileVersionRevision;
130 if (informationalVersion != null)
131 {
132 Version productver = ParseVersionRobust(informationalVersion);
133 productVersionMajor = productver.Major;
134 productVersionMinor = productver.Minor;
135 productVersionBuild = productver.Build;
136 productVersionRevision = productver.Revision;
137 }
138
139 var stringTable = new ByteBuffer(512);
140 stringTable.Write((short)0); // wLength (placeholder)
141 stringTable.Write((short)0); // wValueLength
142 stringTable.Write((short)1); // wType
143 WriteUTF16Z(stringTable, string.Format("{0:x4}{1:x4}", lcid, codepage));
144 stringTable.Align(4);
145
146 WriteString(stringTable, "Comments", description);
147 WriteString(stringTable, "CompanyName", company);
148 WriteString(stringTable, "FileDescription", title);
149 WriteString(stringTable, "FileVersion", fileVersion);
150 WriteString(stringTable, "InternalName", name.Name);
151 WriteString(stringTable, "LegalCopyright", copyright);
152 WriteString(stringTable, "LegalTrademarks", trademark);
153 WriteString(stringTable, "OriginalFilename", fileName);
154 WriteString(stringTable, "ProductName", product);
155 WriteString(stringTable, "ProductVersion", informationalVersion);
156
157 stringTable.Position = 0;
158 stringTable.Write((short)stringTable.Length);
159
160 var stringFileInfo = new ByteBuffer(512);
161 stringFileInfo.Write((short)0); // wLength (placeholder)
162 stringFileInfo.Write((short)0); // wValueLength
163 stringFileInfo.Write((short)1); // wType
164 WriteUTF16Z(stringFileInfo, "StringFileInfo");
165 stringFileInfo.Align(4);
166 stringFileInfo.Write(stringTable);
167 stringFileInfo.Position = 0;
168 stringFileInfo.Write((short)stringFileInfo.Length);
169
170 var preamble1 = new byte[] {
171 // VS_VERSIONINFO (platform SDK)
172 0x34, 0x00, // wValueLength
173 0x00, 0x00, // wType
174 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"
175 0x00, 0x00, // Padding1 (32 bit alignment)
176 // VS_FIXEDFILEINFO starts
177 0xBD, 0x04, 0xEF, 0xFE, // dwSignature (0xFEEF04BD)
178 0x00, 0x00, 0x01, 0x00, // dwStrucVersion
179 };
180
181 byte[] preamble2 = new byte[] {
182 0x3F, 0x00, 0x00, 0x00, // dwFileFlagsMask (??)
183 0x00, 0x00, 0x00, 0x00, // dwFileFlags (??)
184 0x04, 0x00, 0x00, 0x00, // dwFileOS
185 0x02, 0x00, 0x00, 0x00, // dwFileType
186 0x00, 0x00, 0x00, 0x00, // dwFileSubtype
187 0x00, 0x00, 0x00, 0x00, // dwFileDateMS
188 0x00, 0x00, 0x00, 0x00, // dwFileDateLS
189 // Padding2 (32 bit alignment)
190 // VarFileInfo
191 0x44, 0x00, // wLength
192 0x00, 0x00, // wValueLength
193 0x01, 0x00, // wType
194 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"
195 0x00, 0x00, // Padding
196 // Var
197 0x24, 0x00, // wLength
198 0x04, 0x00, // wValueLength
199 0x00, 0x00, // wType
200 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"
201 0x00, 0x00, // Padding (32 bit alignment)
202 };
203
204 bb.Write((short)(2 + preamble1.Length + 8 + 8 + preamble2.Length + 4 + stringFileInfo.Length));
205 bb.Write(preamble1);
206 bb.Write((short)fileVersionMinor);
207 bb.Write((short)fileVersionMajor);
208 bb.Write((short)fileVersionRevision);
209 bb.Write((short)fileVersionBuild);
210 bb.Write((short)productVersionMinor);
211 bb.Write((short)productVersionMajor);
212 bb.Write((short)productVersionRevision);
213 bb.Write((short)productVersionBuild);
214 bb.Write(preamble2);
215 bb.Write((short)lcid);
216 bb.Write((short)codepage);
217 bb.Write(stringFileInfo);
218 }
219
220 static void WriteUTF16Z(ByteBuffer bb, string str)
221 {
222 foreach (char c in str)
223 bb.Write((short)c);
224
225 bb.Write((short)0);
226 }
227
228 static void WriteString(ByteBuffer bb, string name, string value)
229 {
230 value ??= " ";
231 var pos = bb.Position;
232 bb.Write((short)0); // wLength (placeholder)
233 bb.Write((short)(value.Length + 1));// wValueLength
234 bb.Write((short)1); // wType
235 WriteUTF16Z(bb, name);
236 bb.Align(4);
237 WriteUTF16Z(bb, value);
238 bb.Align(4);
239 var savedPos = bb.Position;
240 bb.Position = pos;
241 bb.Write((short)(savedPos - pos));
242 bb.Position = savedPos;
243 }
244
245 static Version ParseVersionRobust(string ver)
246 {
247 int index = 0;
248 var major = ParseVersionPart(ver, ref index);
249 var minor = ParseVersionPart(ver, ref index);
250 var build = ParseVersionPart(ver, ref index);
251 var revision = ParseVersionPart(ver, ref index);
252 return new Version(major, minor, build, revision);
253 }
254
255 static ushort ParseVersionPart(string str, ref int pos)
256 {
257 ushort value = 0;
258 while (pos < str.Length)
259 {
260 char c = str[pos];
261 if (c == '.')
262 {
263 pos++;
264 break;
265 }
266 else if (c >= '0' && c <= '9')
267 {
268 value *= 10;
269 value += (ushort)(c - '0');
270 pos++;
271 }
272 else
273 {
274 break;
275 }
276 }
277 return value;
278 }
279
280 }
281
282}