Refactor class names.

This commit is contained in:
2017-10-16 14:22:26 +01:00
parent b13a4a95d8
commit 5545471b79
9 changed files with 590 additions and 578 deletions

View File

@@ -33,10 +33,10 @@ namespace exeinfo
mzHdr = (libexeinfo.MZ.Header)Marshal.PtrToStructure(hdrPtr, typeof(libexeinfo.MZ.Header));
Marshal.FreeHGlobal(hdrPtr);
if(mzHdr.signature == libexeinfo.MZ.Consts.Signature)
if(mzHdr.signature == libexeinfo.MZ.Signature)
{
recognized = true;
libexeinfo.MZ.Info.PrintInfo(mzHdr);
libexeinfo.MZ.PrintInfo(mzHdr);
if (mzHdr.new_offset < exeFs.Length)
{
@@ -49,10 +49,10 @@ namespace exeinfo
neHdr = (libexeinfo.NE.Header)Marshal.PtrToStructure(hdrPtr, typeof(libexeinfo.NE.Header));
Marshal.FreeHGlobal(hdrPtr);
if (neHdr.signature == libexeinfo.NE.Consts.Signature)
if (neHdr.signature == libexeinfo.NE.Signature)
{
libexeinfo.NE.Info.PrintInfo(neHdr);
libexeinfo.NE.ResourceTable resources = libexeinfo.NE.Info.GetResources(exeFs, mzHdr.new_offset, neHdr.resource_table_offset);
libexeinfo.NE.PrintInfo(neHdr);
libexeinfo.NE.ResourceTable resources = libexeinfo.NE.GetResources(exeFs, mzHdr.new_offset, neHdr.resource_table_offset);
foreach(libexeinfo.NE.ResourceType type in resources.types)
{
if((type.id & 0x7FFF) == (int)libexeinfo.NE.ResourceTypes.RT_VERSION)

View File

@@ -1,7 +1,7 @@
using System;
namespace libexeinfo.MZ
namespace libexeinfo
{
public class Consts
public partial class MZ
{
public const ushort Signature = 0x5A4D;
}

View File

@@ -1,8 +1,8 @@
using System;
namespace libexeinfo.MZ
namespace libexeinfo
{
public class Info
{
public partial class MZ
{
public static void PrintInfo(Header header)
{
Console.WriteLine("DOS MZ executable:");

View File

@@ -1,37 +1,40 @@
using System.Runtime.InteropServices;
namespace libexeinfo.MZ
namespace libexeinfo
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Header
{
public ushort signature;
public ushort bytes_in_last_block;
public ushort blocks_in_file;
public ushort num_relocs;
public ushort header_paragraphs;
public ushort min_extra_paragraphs;
public ushort max_extra_paragraphs;
public ushort ss;
public ushort sp;
public ushort checksum;
public ushort ip;
public ushort cs;
public ushort reloc_table_offset;
public ushort overlay_number;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public ushort[] reserved;
public ushort oem_id;
public ushort oem_info;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public ushort[] reserved2;
public uint new_offset;
}
public partial class MZ
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Header
{
public ushort signature;
public ushort bytes_in_last_block;
public ushort blocks_in_file;
public ushort num_relocs;
public ushort header_paragraphs;
public ushort min_extra_paragraphs;
public ushort max_extra_paragraphs;
public ushort ss;
public ushort sp;
public ushort checksum;
public ushort ip;
public ushort cs;
public ushort reloc_table_offset;
public ushort overlay_number;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public ushort[] reserved;
public ushort oem_id;
public ushort oem_info;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public ushort[] reserved2;
public uint new_offset;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct RelocationTableEntry
{
public ushort offset;
public ushort segment;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct RelocationTableEntry
{
public ushort offset;
public ushort segment;
}
}
}

View File

@@ -1,11 +1,11 @@
using System;
using System.ComponentModel;
namespace libexeinfo.NE
namespace libexeinfo
{
public static class Consts
public partial class NE
{
public const ushort Signature = 0x454E;
public static readonly string FixedFileInfo = "VS_VERSION_INFO";
public static readonly string FixedFileInfoSig = "VS_VERSION_INFO";
public static readonly string StringFileInfo = "StringFileInfo";
public static string IdToName(ushort id)

View File

@@ -1,160 +1,163 @@
using System;
namespace libexeinfo.NE
namespace libexeinfo
{
[Flags]
public enum ProgramFlags : byte
public partial class NE
{
NoDGroup = 0,
SingleDGroup = 1,
MultipleDGroup = 2,
GlobalInit = 1 << 2,
ProtectedMode = 1 << 3,
i86 = 1 << 4,
i286 = 1 << 5,
i386 = 1 << 6,
i87 = 1 << 7
}
[Flags]
public enum ProgramFlags : byte
{
NoDGroup = 0,
SingleDGroup = 1,
MultipleDGroup = 2,
GlobalInit = 1 << 2,
ProtectedMode = 1 << 3,
i86 = 1 << 4,
i286 = 1 << 5,
i386 = 1 << 6,
i87 = 1 << 7
}
public enum TargetOS : byte
{
Unknown = 0,
OS2 = 1,
Windows = 2,
DOS = 3,
Win32 = 4,
Borland = 5
}
public enum TargetOS : byte
{
Unknown = 0,
OS2 = 1,
Windows = 2,
DOS = 3,
Win32 = 4,
Borland = 5
}
[Flags]
public enum ApplicationFlags : byte
{
FullScreen = 1,
GUICompatible = 2,
Errors = 1 << 5,
NonConforming = 1 << 6,
DLL = 1 << 7
}
[Flags]
public enum ApplicationFlags : byte
{
FullScreen = 1,
GUICompatible = 2,
Errors = 1 << 5,
NonConforming = 1 << 6,
DLL = 1 << 7
}
[Flags]
public enum OS2Flags : byte
{
LongFilename = 1 << 0,
ProtectedMode2 = 1 << 1,
ProportionalFonts = 1 << 2,
GangloadArea = 1 << 3,
}
[Flags]
public enum OS2Flags : byte
{
LongFilename = 1 << 0,
ProtectedMode2 = 1 << 1,
ProportionalFonts = 1 << 2,
GangloadArea = 1 << 3,
}
[Flags]
public enum ResourceFlags : ushort
{
Moveable = 0x10,
Pure = 0x20,
Preload = 0x40
}
[Flags]
public enum ResourceFlags : ushort
{
Moveable = 0x10,
Pure = 0x20,
Preload = 0x40
}
public enum ResourceTypes : ushort
{
RT_ACCELERATOR = 9,
RT_ANICURSOR = 21,
RT_ANIICON = 22,
RT_BITMAP = 2,
RT_CURSOR = 1,
RT_DIALOG = 5,
RT_DIALOGEX = 18,
RT_DLGINCLUDE = 17,
RT_DLGINIT = 240,
RT_FONT = 8,
RT_FONTDIR = 7,
RT_GROUP_CURSOR = 12,
RT_GROUP_ICON = 13,
RT_HTML = 23,
RT_ICON = 3,
RT_MANIFEST = 24,
RT_MENU = 4,
RT_MENUEX = 15,
RT_MESSAGETABLE = 11,
RT_NEWBITMAP = RT_NEW | RT_BITMAP,
RT_PLUGPLAY = 19,
RT_RCDATA = 10,
RT_STRING = 6,
RT_TOOLBAR = 241,
RT_VERSION = 16,
RT_VXD = 20,
RT_NEW = 0x2000,
}
public enum ResourceTypes : ushort
{
RT_ACCELERATOR = 9,
RT_ANICURSOR = 21,
RT_ANIICON = 22,
RT_BITMAP = 2,
RT_CURSOR = 1,
RT_DIALOG = 5,
RT_DIALOGEX = 18,
RT_DLGINCLUDE = 17,
RT_DLGINIT = 240,
RT_FONT = 8,
RT_FONTDIR = 7,
RT_GROUP_CURSOR = 12,
RT_GROUP_ICON = 13,
RT_HTML = 23,
RT_ICON = 3,
RT_MANIFEST = 24,
RT_MENU = 4,
RT_MENUEX = 15,
RT_MESSAGETABLE = 11,
RT_NEWBITMAP = RT_NEW | RT_BITMAP,
RT_PLUGPLAY = 19,
RT_RCDATA = 10,
RT_STRING = 6,
RT_TOOLBAR = 241,
RT_VERSION = 16,
RT_VXD = 20,
RT_NEW = 0x2000,
}
[Flags]
public enum VersionFileFlags : uint
{
VS_FF_DEBUG = 0x00000001,
VS_FF_INFOINFERRED = 0x00000010,
VS_FF_PATCHED = 0x00000004,
VS_FF_PRERELEASE = 0x00000002,
VS_FF_PRIVATEBUILD = 0x00000008,
VS_FF_SPECIALBUILD = 0x00000020,
}
[Flags]
public enum VersionFileFlags : uint
{
VS_FF_DEBUG = 0x00000001,
VS_FF_INFOINFERRED = 0x00000010,
VS_FF_PATCHED = 0x00000004,
VS_FF_PRERELEASE = 0x00000002,
VS_FF_PRIVATEBUILD = 0x00000008,
VS_FF_SPECIALBUILD = 0x00000020,
}
public enum VersionFileOS : uint
{
VOS_DOS = 0x00010000,
VOS_NT = 0x00040000,
VOS_WINDOWS16 = 0x00000001,
VOS_WINDOWS32 = 0x00000004,
VOS_OS216 = 0x00020000,
VOS_OS232 = 0x00030000,
VOS_PM16 = 0x00000002,
VOS_PM32 = 0x00000003,
VOS_UNKNOWN = 0x00000000,
public enum VersionFileOS : uint
{
VOS_DOS = 0x00010000,
VOS_NT = 0x00040000,
VOS_WINDOWS16 = 0x00000001,
VOS_WINDOWS32 = 0x00000004,
VOS_OS216 = 0x00020000,
VOS_OS232 = 0x00030000,
VOS_PM16 = 0x00000002,
VOS_PM32 = 0x00000003,
VOS_UNKNOWN = 0x00000000,
// Combinations, some have no sense
VOS_DOS_NT = 0x00050000,
VOS_DOS_WINDOWS16 = 0x00010001,
VOS_DOS_WINDOWS32 = 0x00010004,
VOS_DOS_PM16 = 0x00010002,
VOS_DOS_PM32 = 0x00010003,
VOS_NT_WINDOWS16 = 0x00040001,
VOS_NT_WINDOWS32 = 0x00040004,
VOS_NT_PM16 = 0x00040002,
VOS_NT_PM32 = 0x00040003,
VOS_OS216_WINDOWS16 = 0x00020001,
VOS_OS216_WINDOWS32 = 0x00020004,
VOS_OS216_PM16 = 0x00020002,
VOS_OS216_PM32 = 0x00020003,
VOS_OS232_WINDOWS16 = 0x00030001,
VOS_OS232_WINDOWS32 = 0x00030004,
VOS_OS232_PM16 = 0x00030002,
VOS_OS232_PM32 = 0x00030003,
}
// Combinations, some have no sense
VOS_DOS_NT = 0x00050000,
VOS_DOS_WINDOWS16 = 0x00010001,
VOS_DOS_WINDOWS32 = 0x00010004,
VOS_DOS_PM16 = 0x00010002,
VOS_DOS_PM32 = 0x00010003,
VOS_NT_WINDOWS16 = 0x00040001,
VOS_NT_WINDOWS32 = 0x00040004,
VOS_NT_PM16 = 0x00040002,
VOS_NT_PM32 = 0x00040003,
VOS_OS216_WINDOWS16 = 0x00020001,
VOS_OS216_WINDOWS32 = 0x00020004,
VOS_OS216_PM16 = 0x00020002,
VOS_OS216_PM32 = 0x00020003,
VOS_OS232_WINDOWS16 = 0x00030001,
VOS_OS232_WINDOWS32 = 0x00030004,
VOS_OS232_PM16 = 0x00030002,
VOS_OS232_PM32 = 0x00030003,
}
public enum VersionFileType : uint
{
VFT_APP = 0x00000001,
VFT_DLL = 0x00000002,
VFT_DRV = 0x00000003,
VFT_FONT = 0x00000004,
VFT_STATIC_LIB = 0x00000007,
VFT_UNKNOWN = 0x00000000,
VFT_VXD = 0x00000005,
}
public enum VersionFileType : uint
{
VFT_APP = 0x00000001,
VFT_DLL = 0x00000002,
VFT_DRV = 0x00000003,
VFT_FONT = 0x00000004,
VFT_STATIC_LIB = 0x00000007,
VFT_UNKNOWN = 0x00000000,
VFT_VXD = 0x00000005,
}
public enum VersionFileSubtype : uint
{
VFT2_UNKNOWN = 0x00000000,
// Drivers
VFT2_DRV_COMM = 0x0000000A,
VFT2_DRV_DISPLAY = 0x00000004,
VFT2_DRV_INSTALLABLE = 0x00000008,
VFT2_DRV_KEYBOARD = 0x00000002,
VFT2_DRV_LANGUAGE = 0x00000003,
VFT2_DRV_MOUSE = 0x00000005,
VFT2_DRV_NETWORK = 0x00000006,
VFT2_DRV_PRINTER = 0x00000001,
VFT2_DRV_SOUND = 0x00000009,
VFT2_DRV_SYSTEM = 0x00000007,
VFT2_DRV_VERSIONED_PRINTER = 0x0000000C,
// Fonts
VFT2_FONT_RASTER = 0x00000001,
VFT2_FONT_TRUETYPE = 0x00000003,
VFT2_FONT_VECTOR = 0x00000002,
public enum VersionFileSubtype : uint
{
VFT2_UNKNOWN = 0x00000000,
// Drivers
VFT2_DRV_COMM = 0x0000000A,
VFT2_DRV_DISPLAY = 0x00000004,
VFT2_DRV_INSTALLABLE = 0x00000008,
VFT2_DRV_KEYBOARD = 0x00000002,
VFT2_DRV_LANGUAGE = 0x00000003,
VFT2_DRV_MOUSE = 0x00000005,
VFT2_DRV_NETWORK = 0x00000006,
VFT2_DRV_PRINTER = 0x00000001,
VFT2_DRV_SOUND = 0x00000009,
VFT2_DRV_SYSTEM = 0x00000007,
VFT2_DRV_VERSIONED_PRINTER = 0x0000000C,
// Fonts
VFT2_FONT_RASTER = 0x00000001,
VFT2_FONT_TRUETYPE = 0x00000003,
VFT2_FONT_VECTOR = 0x00000002,
}
}
}
}

View File

@@ -3,10 +3,10 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
namespace libexeinfo.NE
namespace libexeinfo
{
public class Info
{
public partial class NE
{
public static void PrintInfo(Header header)
{
Console.WriteLine("New Executable (NE):");
@@ -190,7 +190,7 @@ namespace libexeinfo.NE
table.types[t].name = Encoding.ASCII.GetString(str);
}
else
table.types[t].name = Consts.IdToName(table.types[t].id);
table.types[t].name = IdToName(table.types[t].id);
for (int r = 0; r < table.types[t].resources.Length; r++)
{

View File

@@ -1,99 +1,102 @@
using System;
using System.Runtime.InteropServices;
namespace libexeinfo.NE
namespace libexeinfo
{
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)]
public struct Header
{
public ushort signature;
public byte linker_major;
public byte linker_minor;
public ushort entry_table_offset;
public ushort entry_table_length;
public uint crc;
public ProgramFlags program_flags;
public ApplicationFlags application_flags;
public byte auto_data_segment_index;
public ushort initial_heap;
public ushort initial_stack;
public uint entry_point;
public uint stack_pointer;
public ushort segment_count;
public ushort reference_count;
public ushort nonresident_table_size;
public ushort segment_table_offset;
public ushort resource_table_offset;
public ushort resident_names_offset;
public ushort module_reference_offset;
public ushort imported_names_offset;
public uint nonresident_names_offset;
public ushort movable_entries;
public ushort alignment_shift;
public ushort resource_entries;
public TargetOS target_os;
public OS2Flags os2_flags;
public ushort return_thunks_offset;
public ushort segment_reference_thunks;
public ushort minimum_swap_area;
public byte os_minor;
public byte os_major;
}
public struct ResourceTable
{
public ushort alignment_shift;
public ResourceType[] types;
}
public struct ResourceType
{
public ushort id;
public ushort count;
public uint reserved;
public Resource[] resources;
// Not sequentially stored
public string name;
}
public struct Resource
{
public ushort dataOffset;
public ushort length;
public ResourceFlags flags;
public ushort id;
public uint reserved;
// Not sequentially stored
public string name;
public byte[] data;
}
class VersionNode
{
public ushort cbNode;
public ushort cbData;
public string szName;
public byte[] rgbData;
public VersionNode[] children;
}
[StructLayout(LayoutKind.Sequential)]
public class FixedFileInfo
public partial class NE
{
public uint dwSignature;
public uint dwStrucVersion;
public uint dwFileVersionMS;
public uint dwFileVersionLS;
public uint dwProductVersionMS;
public uint dwProductVersionLS;
public uint dwFileFlagsMask;
public uint dwFileFlags;
public uint dwFileOS;
public uint dwFileType;
public uint dwFileSubtype;
public uint dwFileDateMS;
public uint dwFileDateLS;
}
}
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)]
public struct Header
{
public ushort signature;
public byte linker_major;
public byte linker_minor;
public ushort entry_table_offset;
public ushort entry_table_length;
public uint crc;
public ProgramFlags program_flags;
public ApplicationFlags application_flags;
public byte auto_data_segment_index;
public ushort initial_heap;
public ushort initial_stack;
public uint entry_point;
public uint stack_pointer;
public ushort segment_count;
public ushort reference_count;
public ushort nonresident_table_size;
public ushort segment_table_offset;
public ushort resource_table_offset;
public ushort resident_names_offset;
public ushort module_reference_offset;
public ushort imported_names_offset;
public uint nonresident_names_offset;
public ushort movable_entries;
public ushort alignment_shift;
public ushort resource_entries;
public TargetOS target_os;
public OS2Flags os2_flags;
public ushort return_thunks_offset;
public ushort segment_reference_thunks;
public ushort minimum_swap_area;
public byte os_minor;
public byte os_major;
}
public struct ResourceTable
{
public ushort alignment_shift;
public ResourceType[] types;
}
public struct ResourceType
{
public ushort id;
public ushort count;
public uint reserved;
public Resource[] resources;
// Not sequentially stored
public string name;
}
public struct Resource
{
public ushort dataOffset;
public ushort length;
public ResourceFlags flags;
public ushort id;
public uint reserved;
// Not sequentially stored
public string name;
public byte[] data;
}
class VersionNode
{
public ushort cbNode;
public ushort cbData;
public string szName;
public byte[] rgbData;
public VersionNode[] children;
}
[StructLayout(LayoutKind.Sequential)]
public class FixedFileInfo
{
public uint dwSignature;
public uint dwStrucVersion;
public uint dwFileVersionMS;
public uint dwFileVersionLS;
public uint dwProductVersionMS;
public uint dwProductVersionLS;
public uint dwFileFlagsMask;
public uint dwFileFlags;
public uint dwFileOS;
public uint dwFileType;
public uint dwFileSubtype;
public uint dwFileDateMS;
public uint dwFileDateLS;
}
}
}

View File

@@ -4,313 +4,316 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace libexeinfo.NE
namespace libexeinfo
{
public class Version
public partial class NE
{
public Dictionary<string, Dictionary<string, string>> StringsByLanguage { get; }
string fileVersion;
string productVersion;
VersionFileFlags fileFlags;
VersionFileOS fileOS;
VersionFileType fileType;
VersionFileSubtype fileSubtype;
DateTime fileDate;
public string FileVersion
public class Version
{
get
public Dictionary<string, Dictionary<string, string>> StringsByLanguage { get; }
string fileVersion;
string productVersion;
VersionFileFlags fileFlags;
VersionFileOS fileOS;
VersionFileType fileType;
VersionFileSubtype fileSubtype;
DateTime fileDate;
public string FileVersion
{
return fileVersion;
}
}
public string ProductVersion
{
get
{
return productVersion;
}
}
public VersionFileFlags FileFlags
{
get
{
return fileFlags;
}
}
public VersionFileOS FileOS
{
get
{
return fileOS;
}
}
public VersionFileType FileType
{
get
{
return fileType;
}
}
public VersionFileSubtype FileSubtype
{
get
{
return fileSubtype;
}
}
public DateTime FileDate
{
get
{
return fileDate;
}
}
public Version(byte[] data)
{
if (data == null || data.Length < 5)
return;
StringsByLanguage = new Dictionary<string, Dictionary<string, string>>();
VersionNode root = GetNode(data, 0, out int rootLength);
DecodeNode(root, null, null);
}
VersionNode GetNode(byte[] data, int startPosition, out int nodeLength)
{
nodeLength = 0;
VersionNode node = new VersionNode
{
cbNode = BitConverter.ToUInt16(data, startPosition + nodeLength),
cbData = BitConverter.ToUInt16(data, startPosition + nodeLength + 2)
};
nodeLength += 4;
MemoryStream nameMs = new MemoryStream();
while (data[startPosition + nodeLength] > 0)
{
nameMs.WriteByte(data[startPosition + nodeLength]);
nodeLength++;
}
node.szName = Encoding.ASCII.GetString(nameMs.ToArray());
nodeLength++;
if (nodeLength % 4 > 0)
nodeLength += 4 - (nodeLength % 4);
node.rgbData = new byte[node.cbData];
Array.Copy(data, startPosition + nodeLength, node.rgbData, 0, node.cbData);
nodeLength += node.cbData;
if (nodeLength % 4 > 0)
nodeLength += 4 - (nodeLength % 4);
List<VersionNode> children = new List<VersionNode>();
while (nodeLength < node.cbNode)
{
children.Add(GetNode(data, startPosition + nodeLength, out int childLength));
nodeLength += childLength;
}
if (children.Count > 0)
node.children = children.ToArray();
return node;
}
void DecodeNode(VersionNode node, string parent, string grandparent)
{
if (node.szName == Consts.FixedFileInfo)
{
IntPtr infoPtr = Marshal.AllocHGlobal(node.cbData);
Marshal.Copy(node.rgbData, 0, infoPtr, node.cbData);
FixedFileInfo info = (FixedFileInfo)Marshal.PtrToStructure(infoPtr, typeof(FixedFileInfo));
Marshal.FreeHGlobal(infoPtr);
fileVersion = string.Format("{0}.{1:D2}.{2}.{3}", (info.dwFileVersionMS & 0xFFFF0000) >> 16, info.dwFileVersionMS & 0xFFFF,
(info.dwFileVersionLS & 0xFFFF0000) >> 16, info.dwFileVersionLS & 0xFFFF);
productVersion = string.Format("{0}.{1:D2}.{2}.{3}", (info.dwProductVersionMS & 0xFFFF0000) >> 16, info.dwProductVersionMS & 0xFFFF,
(info.dwProductVersionLS & 0xFFFF0000) >> 16, info.dwProductVersionLS & 0xFFFF);
fileFlags = (VersionFileFlags)(info.dwFileFlags & info.dwFileFlagsMask);
fileOS = (VersionFileOS)info.dwFileOS;
fileType = (VersionFileType)info.dwFileType;
fileSubtype = (VersionFileSubtype)info.dwFileSubtype;
fileDate = DateTime.FromFileTime(info.dwFileDateMS * 0x100000000 + info.dwFileDateLS);
}
if (parent == Consts.StringFileInfo)
{
Dictionary<string, string> strings = new Dictionary<string, string>();
StringsByLanguage.Add(node.szName, strings);
}
if (grandparent == Consts.StringFileInfo)
{
if (StringsByLanguage.TryGetValue(parent, out Dictionary<string, string> strings))
get
{
Encoding encoding;
try
{
encoding = Encoding.GetEncoding(Convert.ToInt32(parent.Substring(4), 16));
}
catch
{
encoding = Encoding.ASCII;
}
strings.Add(node.szName, encoding.GetString(node.rgbData));
return fileVersion;
}
}
if (node.children != null)
public string ProductVersion
{
for (int i = 0; i < node.children.Length; i++)
DecodeNode(node.children[i], node.szName, parent);
get
{
return productVersion;
}
}
}
public static string TypeToString(VersionFileType type)
{
switch (type)
public VersionFileFlags FileFlags
{
case VersionFileType.VFT_APP:
return "Application";
case VersionFileType.VFT_DLL:
return "Dynamic-link library";
case VersionFileType.VFT_DRV:
return "Device driver";
case VersionFileType.VFT_FONT:
return "Font";
case VersionFileType.VFT_STATIC_LIB:
return "Static-link library";
case VersionFileType.VFT_UNKNOWN:
return "Unknown";
case VersionFileType.VFT_VXD:
return "Virtual device";
default:
return string.Format("Unknown type code {0}", (uint)type);
get
{
return fileFlags;
}
}
}
public static string DriverToString(VersionFileSubtype subtype)
{
switch (subtype)
public VersionFileOS FileOS
{
case VersionFileSubtype.VFT2_DRV_COMM:
return "Communications";
case VersionFileSubtype.VFT2_DRV_DISPLAY:
return "Display";
case VersionFileSubtype.VFT2_DRV_INSTALLABLE:
return "Installable";
case VersionFileSubtype.VFT2_DRV_KEYBOARD:
return "Keyboard";
case VersionFileSubtype.VFT2_DRV_LANGUAGE:
return "Language";
case VersionFileSubtype.VFT2_DRV_MOUSE:
return "Mouse";
case VersionFileSubtype.VFT2_DRV_NETWORK:
return "Network";
case VersionFileSubtype.VFT2_DRV_PRINTER:
return "Printer";
case VersionFileSubtype.VFT2_DRV_SOUND:
return "Sound";
case VersionFileSubtype.VFT2_DRV_SYSTEM:
return "System";
case VersionFileSubtype.VFT2_DRV_VERSIONED_PRINTER:
return "Versioned";
case VersionFileSubtype.VFT2_UNKNOWN:
return "Unknown";
default:
return string.Format("Unknown type code {0}", (uint)subtype);
get
{
return fileOS;
}
}
}
public static string FontToString(VersionFileSubtype subtype)
{
switch (subtype)
public VersionFileType FileType
{
case VersionFileSubtype.VFT2_FONT_RASTER:
return "Raster";
case VersionFileSubtype.VFT2_FONT_TRUETYPE:
return "TrueType";
case VersionFileSubtype.VFT2_FONT_VECTOR:
return "Vector";
case VersionFileSubtype.VFT2_UNKNOWN:
return "Unknown";
default:
return string.Format("Unknown type code {0}", (uint)subtype);
get
{
return fileType;
}
}
}
public static string OsToString(VersionFileOS os)
{
switch (os)
public VersionFileSubtype FileSubtype
{
case VersionFileOS.VOS_DOS:
return "DOS";
case VersionFileOS.VOS_NT:
return "Windows NT";
case VersionFileOS.VOS_WINDOWS16:
return "16-bit Windows";
case VersionFileOS.VOS_WINDOWS32:
return "32-bit Windows";
case VersionFileOS.VOS_OS216:
return "16-bit OS/2";
case VersionFileOS.VOS_OS232:
return "32-bit OS/2";
case VersionFileOS.VOS_PM16:
return "16-bit Presentation Manager";
case VersionFileOS.VOS_PM32:
return "32-bit Presentation Manager";
case VersionFileOS.VOS_UNKNOWN:
return "Unknown";
case VersionFileOS.VOS_DOS_NT:
return "DOS running under Windows NT";
case VersionFileOS.VOS_DOS_WINDOWS16:
return "16-bit Windows running under DOS";
case VersionFileOS.VOS_DOS_WINDOWS32:
return "32-bit Windows running under DOS";
case VersionFileOS.VOS_DOS_PM16:
return "16-bit Presentation Manager running under DOS";
case VersionFileOS.VOS_DOS_PM32:
return "32-bit Presentation Manager running under DOS";
case VersionFileOS.VOS_NT_WINDOWS16:
return "16-bit Windows running under Windows NT";
case VersionFileOS.VOS_NT_WINDOWS32:
return "32-bit Windows running under Windows NT";
case VersionFileOS.VOS_NT_PM16:
return "16-bit Presentation Manager running under Windows NT";
case VersionFileOS.VOS_NT_PM32:
return "32-bit Presentation Manager running under Windows NT";
case VersionFileOS.VOS_OS216_WINDOWS16:
return "16-bit Windows running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_WINDOWS32:
return "32-bit Windows running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_PM16:
return "16-bit Presentation Manager running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_PM32:
return "32-bit Presentation Manager running under 16-bit OS/2";
case VersionFileOS.VOS_OS232_WINDOWS16:
return "16-bit Windows running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_WINDOWS32:
return "32-bit Windows running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_PM16:
return "16-bit Presentation Manager running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_PM32:
return "32-bit Presentation Manager running under 32-bit OS/2";
default:
return string.Format("Unknown OS code {0}", (uint)os);
}
get
{
return fileSubtype;
}
}
public DateTime FileDate
{
get
{
return fileDate;
}
}
public Version(byte[] data)
{
if (data == null || data.Length < 5)
return;
StringsByLanguage = new Dictionary<string, Dictionary<string, string>>();
VersionNode root = GetNode(data, 0, out int rootLength);
DecodeNode(root, null, null);
}
VersionNode GetNode(byte[] data, int startPosition, out int nodeLength)
{
nodeLength = 0;
VersionNode node = new VersionNode
{
cbNode = BitConverter.ToUInt16(data, startPosition + nodeLength),
cbData = BitConverter.ToUInt16(data, startPosition + nodeLength + 2)
};
nodeLength += 4;
MemoryStream nameMs = new MemoryStream();
while (data[startPosition + nodeLength] > 0)
{
nameMs.WriteByte(data[startPosition + nodeLength]);
nodeLength++;
}
node.szName = Encoding.ASCII.GetString(nameMs.ToArray());
nodeLength++;
if (nodeLength % 4 > 0)
nodeLength += 4 - (nodeLength % 4);
node.rgbData = new byte[node.cbData];
Array.Copy(data, startPosition + nodeLength, node.rgbData, 0, node.cbData);
nodeLength += node.cbData;
if (nodeLength % 4 > 0)
nodeLength += 4 - (nodeLength % 4);
List<VersionNode> children = new List<VersionNode>();
while (nodeLength < node.cbNode)
{
children.Add(GetNode(data, startPosition + nodeLength, out int childLength));
nodeLength += childLength;
}
if (children.Count > 0)
node.children = children.ToArray();
return node;
}
void DecodeNode(VersionNode node, string parent, string grandparent)
{
if (node.szName == FixedFileInfoSig)
{
IntPtr infoPtr = Marshal.AllocHGlobal(node.cbData);
Marshal.Copy(node.rgbData, 0, infoPtr, node.cbData);
FixedFileInfo info = (FixedFileInfo)Marshal.PtrToStructure(infoPtr, typeof(FixedFileInfo));
Marshal.FreeHGlobal(infoPtr);
fileVersion = string.Format("{0}.{1:D2}.{2}.{3}", (info.dwFileVersionMS & 0xFFFF0000) >> 16, info.dwFileVersionMS & 0xFFFF,
(info.dwFileVersionLS & 0xFFFF0000) >> 16, info.dwFileVersionLS & 0xFFFF);
productVersion = string.Format("{0}.{1:D2}.{2}.{3}", (info.dwProductVersionMS & 0xFFFF0000) >> 16, info.dwProductVersionMS & 0xFFFF,
(info.dwProductVersionLS & 0xFFFF0000) >> 16, info.dwProductVersionLS & 0xFFFF);
fileFlags = (VersionFileFlags)(info.dwFileFlags & info.dwFileFlagsMask);
fileOS = (VersionFileOS)info.dwFileOS;
fileType = (VersionFileType)info.dwFileType;
fileSubtype = (VersionFileSubtype)info.dwFileSubtype;
fileDate = DateTime.FromFileTime(info.dwFileDateMS * 0x100000000 + info.dwFileDateLS);
}
if (parent == StringFileInfo)
{
Dictionary<string, string> strings = new Dictionary<string, string>();
StringsByLanguage.Add(node.szName, strings);
}
if (grandparent == StringFileInfo)
{
if (StringsByLanguage.TryGetValue(parent, out Dictionary<string, string> strings))
{
Encoding encoding;
try
{
encoding = Encoding.GetEncoding(Convert.ToInt32(parent.Substring(4), 16));
}
catch
{
encoding = Encoding.ASCII;
}
strings.Add(node.szName, encoding.GetString(node.rgbData));
}
}
if (node.children != null)
{
for (int i = 0; i < node.children.Length; i++)
DecodeNode(node.children[i], node.szName, parent);
}
}
public static string TypeToString(VersionFileType type)
{
switch (type)
{
case VersionFileType.VFT_APP:
return "Application";
case VersionFileType.VFT_DLL:
return "Dynamic-link library";
case VersionFileType.VFT_DRV:
return "Device driver";
case VersionFileType.VFT_FONT:
return "Font";
case VersionFileType.VFT_STATIC_LIB:
return "Static-link library";
case VersionFileType.VFT_UNKNOWN:
return "Unknown";
case VersionFileType.VFT_VXD:
return "Virtual device";
default:
return string.Format("Unknown type code {0}", (uint)type);
}
}
public static string DriverToString(VersionFileSubtype subtype)
{
switch (subtype)
{
case VersionFileSubtype.VFT2_DRV_COMM:
return "Communications";
case VersionFileSubtype.VFT2_DRV_DISPLAY:
return "Display";
case VersionFileSubtype.VFT2_DRV_INSTALLABLE:
return "Installable";
case VersionFileSubtype.VFT2_DRV_KEYBOARD:
return "Keyboard";
case VersionFileSubtype.VFT2_DRV_LANGUAGE:
return "Language";
case VersionFileSubtype.VFT2_DRV_MOUSE:
return "Mouse";
case VersionFileSubtype.VFT2_DRV_NETWORK:
return "Network";
case VersionFileSubtype.VFT2_DRV_PRINTER:
return "Printer";
case VersionFileSubtype.VFT2_DRV_SOUND:
return "Sound";
case VersionFileSubtype.VFT2_DRV_SYSTEM:
return "System";
case VersionFileSubtype.VFT2_DRV_VERSIONED_PRINTER:
return "Versioned";
case VersionFileSubtype.VFT2_UNKNOWN:
return "Unknown";
default:
return string.Format("Unknown type code {0}", (uint)subtype);
}
}
public static string FontToString(VersionFileSubtype subtype)
{
switch (subtype)
{
case VersionFileSubtype.VFT2_FONT_RASTER:
return "Raster";
case VersionFileSubtype.VFT2_FONT_TRUETYPE:
return "TrueType";
case VersionFileSubtype.VFT2_FONT_VECTOR:
return "Vector";
case VersionFileSubtype.VFT2_UNKNOWN:
return "Unknown";
default:
return string.Format("Unknown type code {0}", (uint)subtype);
}
}
public static string OsToString(VersionFileOS os)
{
switch (os)
{
case VersionFileOS.VOS_DOS:
return "DOS";
case VersionFileOS.VOS_NT:
return "Windows NT";
case VersionFileOS.VOS_WINDOWS16:
return "16-bit Windows";
case VersionFileOS.VOS_WINDOWS32:
return "32-bit Windows";
case VersionFileOS.VOS_OS216:
return "16-bit OS/2";
case VersionFileOS.VOS_OS232:
return "32-bit OS/2";
case VersionFileOS.VOS_PM16:
return "16-bit Presentation Manager";
case VersionFileOS.VOS_PM32:
return "32-bit Presentation Manager";
case VersionFileOS.VOS_UNKNOWN:
return "Unknown";
case VersionFileOS.VOS_DOS_NT:
return "DOS running under Windows NT";
case VersionFileOS.VOS_DOS_WINDOWS16:
return "16-bit Windows running under DOS";
case VersionFileOS.VOS_DOS_WINDOWS32:
return "32-bit Windows running under DOS";
case VersionFileOS.VOS_DOS_PM16:
return "16-bit Presentation Manager running under DOS";
case VersionFileOS.VOS_DOS_PM32:
return "32-bit Presentation Manager running under DOS";
case VersionFileOS.VOS_NT_WINDOWS16:
return "16-bit Windows running under Windows NT";
case VersionFileOS.VOS_NT_WINDOWS32:
return "32-bit Windows running under Windows NT";
case VersionFileOS.VOS_NT_PM16:
return "16-bit Presentation Manager running under Windows NT";
case VersionFileOS.VOS_NT_PM32:
return "32-bit Presentation Manager running under Windows NT";
case VersionFileOS.VOS_OS216_WINDOWS16:
return "16-bit Windows running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_WINDOWS32:
return "32-bit Windows running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_PM16:
return "16-bit Presentation Manager running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_PM32:
return "32-bit Presentation Manager running under 16-bit OS/2";
case VersionFileOS.VOS_OS232_WINDOWS16:
return "16-bit Windows running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_WINDOWS32:
return "32-bit Windows running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_PM16:
return "16-bit Presentation Manager running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_PM32:
return "32-bit Presentation Manager running under 32-bit OS/2";
default:
return string.Format("Unknown OS code {0}", (uint)os);
}
}
}
}
}
}