ikvm-fork/refemit/Writer/VersionInfo.cs

245 строки
7.8 KiB
C#

/*
Copyright (C) 2008 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
using System;
using System.Reflection;
using System.Globalization;
namespace IKVM.Reflection.Emit.Writer
{
sealed class VersionInfo
{
private AssemblyName name;
private string fileName;
private string copyright;
private string trademark;
private string product;
private string company;
private string description;
private string title;
private string informationalVersion;
private string culture;
private string fileVersion;
internal void SetName(AssemblyName name)
{
this.name = name;
}
internal void SetFileName(string assemblyFileName)
{
this.fileName = assemblyFileName;
}
internal void SetAttribute(CustomAttributeBuilder cab)
{
Type type = cab.Constructor.DeclaringType;
if (type == typeof(AssemblyCopyrightAttribute))
{
copyright = (string)cab.GetConstructorArgument(0);
}
else if (type == typeof(AssemblyTrademarkAttribute))
{
trademark = (string)cab.GetConstructorArgument(0);
}
else if (type == typeof(AssemblyProductAttribute))
{
product = (string)cab.GetConstructorArgument(0);
}
else if (type == typeof(AssemblyCompanyAttribute))
{
company = (string)cab.GetConstructorArgument(0);
}
else if (type == typeof(AssemblyDescriptionAttribute))
{
description = (string)cab.GetConstructorArgument(0);
}
else if (type == typeof(AssemblyTitleAttribute))
{
title = (string)cab.GetConstructorArgument(0);
}
else if (type == typeof(AssemblyInformationalVersionAttribute))
{
informationalVersion = (string)cab.GetConstructorArgument(0);
}
else if (type == typeof(AssemblyCultureAttribute))
{
culture = (string)cab.GetConstructorArgument(0);
}
else if (type == typeof(AssemblyFileVersionAttribute))
{
fileVersion = (string)cab.GetConstructorArgument(0);
}
}
internal void Write(ByteBuffer bb)
{
if (fileVersion == null)
{
if (name.Version != null)
{
fileVersion = name.Version.ToString();
}
else
{
fileVersion = "0.0.0.0";
}
}
int codepage = 1200; // Unicode codepage
int lcid = 0x7f;
if (name.CultureInfo != null)
{
lcid = name.CultureInfo.LCID;
}
if (culture != null)
{
lcid = new CultureInfo(culture).LCID;
}
Version filever = new Version(fileVersion);
int fileVersionMajor = filever.Major;
int fileVersionMinor = filever.Minor;
int fileVersionBuild = filever.Build;
int fileVersionRevision = filever.Revision;
int productVersionMajor = 0;
int productVersionMinor = 0;
int productVersionBuild = 0;
int productVersionRevision = 0;
if (informationalVersion != null)
{
Version productver = new Version(informationalVersion);
productVersionMajor = productver.Major;
productVersionMinor = productver.Minor;
productVersionBuild = productver.Build;
productVersionRevision = productver.Revision;
}
ByteBuffer stringTable = new ByteBuffer(512);
stringTable.Write((short)0); // wLength (placeholder)
stringTable.Write((short)0); // wValueLength
stringTable.Write((short)1); // wType
WriteUTF16Z(stringTable, string.Format("{0:x4}{1:x4}", lcid, codepage));
stringTable.Align(4);
WriteString(stringTable, "Comments", description);
WriteString(stringTable, "CompanyName", company);
WriteString(stringTable, "FileDescription", title);
WriteString(stringTable, "FileVersion", fileVersion);
WriteString(stringTable, "InternalName", name.Name);
WriteString(stringTable, "LegalCopyright", copyright);
WriteString(stringTable, "LegalTrademarks", trademark);
WriteString(stringTable, "OriginalFilename", fileName);
WriteString(stringTable, "ProductName", product);
WriteString(stringTable, "ProductVersion", informationalVersion);
stringTable.Position = 0;
stringTable.Write((short)stringTable.Length);
ByteBuffer stringFileInfo = new ByteBuffer(512);
stringFileInfo.Write((short)0); // wLength (placeholder)
stringFileInfo.Write((short)0); // wValueLength
stringFileInfo.Write((short)1); // wType
WriteUTF16Z(stringFileInfo, "StringFileInfo");
stringFileInfo.Align(4);
stringFileInfo.Write(stringTable);
stringFileInfo.Position = 0;
stringFileInfo.Write((short)stringFileInfo.Length);
byte[] preamble1 = new byte[] {
// VS_VERSIONINFO (platform SDK)
0x34, 0x00, // wValueLength
0x00, 0x00, // wType
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"
0x00, 0x00, // Padding1 (32 bit alignment)
// VS_FIXEDFILEINFO starts
0xBD, 0x04, 0xEF, 0xFE, // dwSignature (0xFEEF04BD)
0x00, 0x00, 0x01, 0x00, // dwStrucVersion
};
byte[] preamble2 = new byte[] {
0x3F, 0x00, 0x00, 0x00, // dwFileFlagsMask (??)
0x00, 0x00, 0x00, 0x00, // dwFileFlags (??)
0x04, 0x00, 0x00, 0x00, // dwFileOS
0x02, 0x00, 0x00, 0x00, // dwFileType
0x00, 0x00, 0x00, 0x00, // dwFileSubtype
0x00, 0x00, 0x00, 0x00, // dwFileDateMS
0x00, 0x00, 0x00, 0x00, // dwFileDateLS
// Padding2 (32 bit alignment)
// VarFileInfo
0x44, 0x00, // wLength
0x00, 0x00, // wValueLength
0x01, 0x00, // wType
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"
0x00, 0x00, // Padding
// Var
0x24, 0x00, // wLength
0x04, 0x00, // wValueLength
0x00, 0x00, // wType
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"
0x00, 0x00, // Padding (32 bit alignment)
};
bb.Write((short)(2 + preamble1.Length + 8 + 8 + preamble2.Length + 4 + stringFileInfo.Length));
bb.Write(preamble1);
bb.Write((short)fileVersionMinor);
bb.Write((short)fileVersionMajor);
bb.Write((short)fileVersionRevision);
bb.Write((short)fileVersionBuild);
bb.Write((short)productVersionMinor);
bb.Write((short)productVersionMajor);
bb.Write((short)productVersionRevision);
bb.Write((short)productVersionBuild);
bb.Write(preamble2);
bb.Write((short)lcid);
bb.Write((short)codepage);
bb.Write(stringFileInfo);
}
private void WriteUTF16Z(ByteBuffer bb, string str)
{
foreach (char c in str)
{
bb.Write((short)c);
}
bb.Write((short)0);
}
private void WriteString(ByteBuffer bb, string name, string value)
{
value = value ?? " ";
int pos = bb.Position;
bb.Write((short)0); // wLength (placeholder)
bb.Write((short)(value.Length + 1));// wValueLength
bb.Write((short)1); // wType
WriteUTF16Z(bb, name);
bb.Align(4);
WriteUTF16Z(bb, value);
bb.Align(4);
int savedPos = bb.Position;
bb.Position = pos;
bb.Write((short)(savedPos - pos));
bb.Position = savedPos;
}
}
}