Fix null sessions in HttpContextWrapper.Session
[mono.git] / mcs / class / IKVM.Reflection / Writer / VersionInfo.cs
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 */
24 using System;
25 using System.Globalization;
26 using IKVM.Reflection.Emit;
27
28 namespace IKVM.Reflection.Writer
29 {
30         sealed class VersionInfo
31         {
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;
39                 private string title;
40                 internal string informationalVersion;
41                 private string fileVersion;
42
43                 internal void SetName(AssemblyName name)
44                 {
45                         this.name = name;
46                 }
47
48                 internal void SetFileName(string assemblyFileName)
49                 {
50                         this.fileName = assemblyFileName;
51                 }
52
53                 internal void SetAttribute(CustomAttributeBuilder cab)
54                 {
55                         Universe u = cab.Constructor.Module.universe;
56                         Type type = cab.Constructor.DeclaringType;
57                         if (copyright == null && type == u.System_Reflection_AssemblyCopyrightAttribute)
58                         {
59                                 copyright = (string)cab.GetConstructorArgument(0);
60                         }
61                         else if (trademark == null && type == u.System_Reflection_AssemblyTrademarkAttribute)
62                         {
63                                 trademark = (string)cab.GetConstructorArgument(0);
64                         }
65                         else if (product == null && type == u.System_Reflection_AssemblyProductAttribute)
66                         {
67                                 product = (string)cab.GetConstructorArgument(0);
68                         }
69                         else if (company == null && type == u.System_Reflection_AssemblyCompanyAttribute)
70                         {
71                                 company = (string)cab.GetConstructorArgument(0);
72                         }
73                         else if (description == null && type == u.System_Reflection_AssemblyDescriptionAttribute)
74                         {
75                                 description = (string)cab.GetConstructorArgument(0);
76                         }
77                         else if (title == null && type == u.System_Reflection_AssemblyTitleAttribute)
78                         {
79                                 title = (string)cab.GetConstructorArgument(0);
80                         }
81                         else if (informationalVersion == null && type == u.System_Reflection_AssemblyInformationalVersionAttribute)
82                         {
83                                 informationalVersion = (string)cab.GetConstructorArgument(0);
84                         }
85                         else if (fileVersion == null && type == u.System_Reflection_AssemblyFileVersionAttribute)
86                         {
87                                 fileVersion = (string)cab.GetConstructorArgument(0);
88                         }
89                 }
90
91                 internal void Write(ByteBuffer bb)
92                 {
93                         if (fileVersion == null)
94                         {
95                                 if (name.Version != null)
96                                 {
97                                         fileVersion = name.Version.ToString();
98                                 }
99                                 else
100                                 {
101                                         fileVersion = "0.0.0.0";
102                                 }
103                         }
104
105                         int codepage = 1200;    // Unicode codepage
106                         int lcid = 0x7f;
107                         try
108                         {
109                                 if (name.CultureInfo != null)
110                                 {
111                                         lcid = name.CultureInfo.LCID;
112                                 }
113                         }
114                         catch (ArgumentException)
115                         {
116                                 // AssemblyName.CultureInfo throws an ArgumentException if AssemblyBuilder.__SetAssemblyCulture() was used to specify a non-existing culture
117                         }
118
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;
124
125                         int productVersionMajor = fileVersionMajor;
126                         int productVersionMinor = fileVersionMinor;
127                         int productVersionBuild = fileVersionBuild;
128                         int productVersionRevision = fileVersionRevision;
129                         if (informationalVersion != null)
130                         {
131                                 Version productver = ParseVersionRobust(informationalVersion);
132                                 productVersionMajor = productver.Major;
133                                 productVersionMinor = productver.Minor;
134                                 productVersionBuild = productver.Build;
135                                 productVersionRevision = productver.Revision;
136                         }
137
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);
144
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);
155
156                         stringTable.Position = 0;
157                         stringTable.Write((short)stringTable.Length);
158
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);
168
169                         byte[] preamble1 = new byte[] {
170                           // VS_VERSIONINFO (platform SDK)
171                           0x34, 0x00,                           // wValueLength
172                           0x00, 0x00,                           // wType
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
178                         };
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)
188                           // VarFileInfo
189                           0x44, 0x00,                           // wLength
190                           0x00, 0x00,                           // wValueLength
191                           0x01, 0x00,                           // wType
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
194                           // Var
195                           0x24, 0x00,                           // wLength
196                           0x04, 0x00,                           // wValueLength
197                           0x00, 0x00,                           // wType
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)
200                         };
201                         bb.Write((short)(2 + preamble1.Length + 8 + 8 + preamble2.Length + 4 + stringFileInfo.Length));
202                         bb.Write(preamble1);
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);
211                         bb.Write(preamble2);
212                         bb.Write((short)lcid);
213                         bb.Write((short)codepage);
214                         bb.Write(stringFileInfo);
215                 }
216
217                 private static void WriteUTF16Z(ByteBuffer bb, string str)
218                 {
219                         foreach (char c in str)
220                         {
221                                 bb.Write((short)c);
222                         }
223                         bb.Write((short)0);
224                 }
225
226                 private static void WriteString(ByteBuffer bb, string name, string value)
227                 {
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);
234                         bb.Align(4);
235                         WriteUTF16Z(bb, value);
236                         bb.Align(4);
237                         int savedPos = bb.Position;
238                         bb.Position = pos;
239                         bb.Write((short)(savedPos - pos));
240                         bb.Position = savedPos;
241                 }
242
243                 private static Version ParseVersionRobust(string ver)
244                 {
245                         int index = 0;
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);
251                 }
252
253                 private static ushort ParseVersionPart(string str, ref int pos)
254                 {
255                         ushort value = 0;
256                         while (pos < str.Length)
257                         {
258                                 char c = str[pos];
259                                 if (c == '.')
260                                 {
261                                         pos++;
262                                         break;
263                                 }
264                                 else if (c >= '0' && c <= '9')
265                                 {
266                                         value *= 10;
267                                         value += (ushort)(c - '0');
268                                         pos++;
269                                 }
270                                 else
271                                 {
272                                         break;
273                                 }
274                         }
275                         return value;
276                 }
277         }
278 }