mirror of
https://github.com/claunia/libexeinfo.git
synced 2025-12-16 19:14:24 +00:00
Decode RT_VERSION resource from PE executables.
This commit is contained in:
@@ -179,6 +179,58 @@ namespace exeinfo
|
||||
{
|
||||
recognized = true;
|
||||
Console.Write(peExe.Information);
|
||||
|
||||
if(((PE)peExe).Versions != null)
|
||||
foreach(PE.Version vers in ((PE)peExe).Versions)
|
||||
{
|
||||
Console.WriteLine("\tVersion resource {0}:", vers.Name);
|
||||
Console.WriteLine("\t\tFile version: {0}", vers.FileVersion);
|
||||
Console.WriteLine("\t\tProduct version: {0}", vers.ProductVersion);
|
||||
Console.WriteLine("\t\tFile type: {0}", PE.Version.TypeToString(vers.FileType));
|
||||
if(vers.FileType == PE.VersionFileType.VFT_DRV)
|
||||
Console.WriteLine("\t\tFile subtype: {0} driver",
|
||||
PE.Version.DriverToString(vers.FileSubtype));
|
||||
else if(vers.FileType == PE.VersionFileType.VFT_DRV)
|
||||
Console.WriteLine("\t\tFile subtype: {0} font", PE.Version.FontToString(vers.FileSubtype));
|
||||
else if(vers.FileSubtype > 0)
|
||||
Console.WriteLine("\t\tFile subtype: {0}", (uint)vers.FileSubtype);
|
||||
Console.WriteLine("\t\tFile flags: {0}", vers.FileFlags);
|
||||
Console.WriteLine("\t\tFile OS: {0}", PE.Version.OsToString(vers.FileOS));
|
||||
|
||||
foreach(KeyValuePair<string, Dictionary<string, string>> strByLang in vers.StringsByLanguage)
|
||||
{
|
||||
string cultureName;
|
||||
string encodingName;
|
||||
|
||||
try
|
||||
{
|
||||
cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16))
|
||||
.DisplayName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
cultureName =
|
||||
$"unsupported culture 0x{Convert.ToInt32(strByLang.Key.Substring(0, 4), 16):X4}";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
encodingName = Encoding
|
||||
.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16))
|
||||
.EncodingName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
encodingName =
|
||||
$"unsupported encoding 0x{Convert.ToInt32(strByLang.Key.Substring(4), 16):X4}";
|
||||
}
|
||||
|
||||
Console.WriteLine("\t\tStrings for {0} in codepage {1}:", cultureName, encodingName);
|
||||
foreach(KeyValuePair<string, string> strings in strByLang.Value)
|
||||
Console.WriteLine("\t\t\t{0}: {1}", strings.Key, strings.Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(peExe.Strings != null && peExe.Strings.Any())
|
||||
{
|
||||
|
||||
@@ -34,5 +34,13 @@ namespace libexeinfo
|
||||
const ushort SIGNATURE = 0x00004550;
|
||||
const ushort PE32 = COFF.ZMAGIC;
|
||||
internal const ushort PE32Plus = 0x20b;
|
||||
/// <summary>
|
||||
/// Signature for a <see cref="FixedFileInfo" />
|
||||
/// </summary>
|
||||
const string FIXED_FILE_INFO_SIG = "VS_VERSION_INFO";
|
||||
/// <summary>
|
||||
/// Signature for list of name=value strings inside a version resource
|
||||
/// </summary>
|
||||
const string STRING_FILE_INFO = "StringFileInfo";
|
||||
}
|
||||
}
|
||||
@@ -176,5 +176,92 @@ namespace libexeinfo
|
||||
/// </summary>
|
||||
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Version file flags.
|
||||
/// </summary>
|
||||
[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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Version file operating system.
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Version file subtype.
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Version file type.
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@ namespace libexeinfo
|
||||
COFF.SectionHeader[] sectionHeaders;
|
||||
public ResourceNode WindowsResourcesRoot;
|
||||
WindowsHeader64 winHeader;
|
||||
public Version[] Versions;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:libexeinfo.PE" /> class.
|
||||
@@ -387,9 +388,14 @@ namespace libexeinfo
|
||||
// TODO: Decode BeOS resource format
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowsResourcesRoot = GetResourceNode(BaseStream, rsrc.pointerToRawData,
|
||||
rsrc.virtualAddress,
|
||||
rsrc.pointerToRawData, 0, null, 0);
|
||||
Versions = GetVersions().ToArray();
|
||||
|
||||
strings.AddRange(from v in Versions from s in v.StringsByLanguage from k in s.Value select k.Value);
|
||||
}
|
||||
|
||||
sectionHeaders = newSectionHeaders.Values.OrderBy(s => s.pointerToRawData).ToArray();
|
||||
Segment[] segments = new Segment[sectionHeaders.Length];
|
||||
|
||||
@@ -459,5 +459,39 @@ namespace libexeinfo
|
||||
public byte[] data;
|
||||
public int level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Node in a version resource
|
||||
/// </summary>
|
||||
class VersionNode
|
||||
{
|
||||
public ushort wValueLength;
|
||||
public ushort wLength;
|
||||
public ushort wType;
|
||||
public VersionNode[] children;
|
||||
public byte[] rgbData;
|
||||
public string szName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixed file version info
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
331
libexeinfo/PE/Version.cs
Normal file
331
libexeinfo/PE/Version.cs
Normal file
@@ -0,0 +1,331 @@
|
||||
//
|
||||
// Version.cs
|
||||
//
|
||||
// Author:
|
||||
// Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Copyright (c) 2017-2018 Copyright © Claunia.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using libexeinfo.Windows;
|
||||
|
||||
namespace libexeinfo
|
||||
{
|
||||
public partial class PE
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all the version resources from this instance
|
||||
/// </summary>
|
||||
/// <returns>The decoded version resources.</returns>
|
||||
public List<Version> GetVersions()
|
||||
{
|
||||
return (from node in WindowsResourcesRoot.children
|
||||
where node.id == (uint)ResourceTypes.RT_VERSION
|
||||
from ids in node.children
|
||||
from lang in ids.children
|
||||
select new Version(lang.data, lang.name)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a version ("RT_VERSION") resource
|
||||
/// </summary>
|
||||
public class Version
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:libexeinfo.NE.Version" /> class.
|
||||
/// </summary>
|
||||
/// <param name="data">Resource data.</param>
|
||||
/// <param name="resourceName">Resource name.</param>
|
||||
public Version(byte[] data, string resourceName = null)
|
||||
{
|
||||
if(data == null || data.Length < 5) return;
|
||||
|
||||
Name = resourceName;
|
||||
|
||||
StringsByLanguage = new Dictionary<string, Dictionary<string, string>>();
|
||||
|
||||
VersionNode root = GetNode(data, 0, out int rootLength);
|
||||
DecodeNode(root, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This contains a list of all name=value strings pairs sorted by language
|
||||
/// </summary>
|
||||
/// <value>List of all name=value strings pairs sorted by language.</value>
|
||||
public Dictionary<string, Dictionary<string, string>> StringsByLanguage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// File version.
|
||||
/// </summary>
|
||||
/// <value>The file version.</value>
|
||||
public string FileVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Product version.
|
||||
/// </summary>
|
||||
/// <value>The product version.</value>
|
||||
public string ProductVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File flags.
|
||||
/// </summary>
|
||||
/// <value>The file flags.</value>
|
||||
public VersionFileFlags FileFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File operating system.
|
||||
/// </summary>
|
||||
/// <value>The file operating system.</value>
|
||||
public VersionFileOS FileOS { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File type.
|
||||
/// </summary>
|
||||
/// <value>The type of the file.</value>
|
||||
public VersionFileType FileType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File subtype.
|
||||
/// </summary>
|
||||
/// <value>The file subtype.</value>
|
||||
public VersionFileSubtype FileSubtype { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File date.
|
||||
/// </summary>
|
||||
/// <value>The file date.</value>
|
||||
public DateTime FileDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Resource name
|
||||
/// </summary>
|
||||
/// <value>The resource name.</value>
|
||||
public string Name { get; }
|
||||
|
||||
static VersionNode GetNode(byte[] data, int startPosition, out int nodeLength)
|
||||
{
|
||||
nodeLength = 0;
|
||||
|
||||
VersionNode node = new VersionNode
|
||||
{
|
||||
wLength = BitConverter.ToUInt16(data, startPosition + nodeLength),
|
||||
wValueLength = BitConverter.ToUInt16(data, startPosition + nodeLength + 2),
|
||||
wType = BitConverter.ToUInt16(data, startPosition + nodeLength + 4)
|
||||
};
|
||||
nodeLength += 6;
|
||||
|
||||
MemoryStream nameMs = new MemoryStream();
|
||||
while(true)
|
||||
{
|
||||
if(data[startPosition + nodeLength] == 0 && data[startPosition + nodeLength + 1] == 0)
|
||||
break;
|
||||
|
||||
nameMs.WriteByte(data[startPosition + nodeLength]);
|
||||
nameMs.WriteByte(data[startPosition + nodeLength + 1]);
|
||||
nodeLength+=2;
|
||||
}
|
||||
|
||||
node.szName = Encoding.Unicode.GetString(nameMs.ToArray());
|
||||
nodeLength+=2;
|
||||
|
||||
if(nodeLength % 4 > 0) nodeLength += 4 - nodeLength % 4;
|
||||
|
||||
int factor = node.wType == 1 ? 2 : 1;
|
||||
|
||||
node.rgbData = new byte[node.wValueLength * factor];
|
||||
Array.Copy(data, startPosition + nodeLength, node.rgbData, 0, node.rgbData.Length);
|
||||
nodeLength += node.rgbData.Length;
|
||||
if(nodeLength % 4 > 0) nodeLength += 4 - nodeLength % 4;
|
||||
|
||||
string foo = Encoding.Unicode.GetString(node.rgbData);
|
||||
|
||||
List<VersionNode> children = new List<VersionNode>();
|
||||
|
||||
while(nodeLength < node.wLength)
|
||||
{
|
||||
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 == FIXED_FILE_INFO_SIG)
|
||||
{
|
||||
IntPtr infoPtr = Marshal.AllocHGlobal(node.wValueLength);
|
||||
Marshal.Copy(node.rgbData, 0, infoPtr, node.wValueLength);
|
||||
FixedFileInfo info = (FixedFileInfo)Marshal.PtrToStructure(infoPtr, typeof(FixedFileInfo));
|
||||
Marshal.FreeHGlobal(infoPtr);
|
||||
|
||||
FileVersion =
|
||||
$"{(info.dwFileVersionMS & 0xFFFF0000) >> 16}.{info.dwFileVersionMS & 0xFFFF:D2}.{(info.dwFileVersionLS & 0xFFFF0000) >> 16}.{info.dwFileVersionLS & 0xFFFF}";
|
||||
ProductVersion =
|
||||
$"{(info.dwProductVersionMS & 0xFFFF0000) >> 16}.{info.dwProductVersionMS & 0xFFFF:D2}.{(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 == STRING_FILE_INFO)
|
||||
{
|
||||
Dictionary<string, string> strings = new Dictionary<string, string>();
|
||||
StringsByLanguage.Add(node.szName, strings);
|
||||
}
|
||||
|
||||
if(grandparent == STRING_FILE_INFO)
|
||||
if(StringsByLanguage.TryGetValue(parent, out Dictionary<string, string> strings))
|
||||
{
|
||||
strings.Add(node.szName, Encoding.Unicode.GetString(node.rgbData));
|
||||
}
|
||||
|
||||
if(node.children == null) return;
|
||||
|
||||
foreach(VersionNode n in node.children) DecodeNode(n, node.szName, parent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="VersionFileType" /> to string
|
||||
/// </summary>
|
||||
/// <returns>The string.</returns>
|
||||
/// <param name="type">
|
||||
/// <see cref="VersionFileType" />
|
||||
/// </param>
|
||||
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 $"Unknown type code {(uint)type}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="VersionFileSubtype" /> to string, considering file type to be a driver
|
||||
/// </summary>
|
||||
/// <returns>The string.</returns>
|
||||
/// <param name="subtype">
|
||||
/// <see cref="VersionFileSubtype" />
|
||||
/// </param>
|
||||
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 $"Unknown type code {(uint)subtype}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="VersionFileSubtype" /> to string, considering file type to be a font
|
||||
/// </summary>
|
||||
/// <returns>The string.</returns>
|
||||
/// <param name="subtype">
|
||||
/// <see cref="VersionFileSubtype" />
|
||||
/// </param>
|
||||
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 $"Unknown type code {(uint)subtype}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="VersionFileOS" /> to string
|
||||
/// </summary>
|
||||
/// <returns>The string.</returns>
|
||||
/// <param name="os">
|
||||
/// <see cref="VersionFileOS" />
|
||||
/// </param>
|
||||
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 $"Unknown OS code {(uint)os}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@
|
||||
<Compile Include="Os2\Enums.cs" />
|
||||
<Compile Include="Os2\Resources.cs" />
|
||||
<Compile Include="Os2\Structs.cs" />
|
||||
<Compile Include="PE\Version.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="MZ\Consts.cs" />
|
||||
<Compile Include="MZ\Info.cs" />
|
||||
|
||||
Reference in New Issue
Block a user