diff --git a/SabreTools.Serialization/Extensions.PortableExecutable.cs b/SabreTools.Serialization/Extensions.PortableExecutable.cs
index 696b843a..c7ad7a7b 100644
--- a/SabreTools.Serialization/Extensions.PortableExecutable.cs
+++ b/SabreTools.Serialization/Extensions.PortableExecutable.cs
@@ -6,7 +6,6 @@ using System.Xml.Serialization;
using SabreTools.IO.Extensions;
using SabreTools.Models.PortableExecutable;
-// TODO: Finish replacing ReadType
namespace SabreTools.Serialization
{
public static partial class Extensions
@@ -95,42 +94,46 @@ namespace SabreTools.Serialization
#region Debug
///
- /// Read debug data as an NB10 Program Database
+ /// Parse a byte array into a NB10ProgramDatabase
///
- /// Data to parse into a database
+ /// Data to parse
/// Offset into the byte array
- /// A filled NB10 Program Database on success, null on error
- public static NB10ProgramDatabase? AsNB10ProgramDatabase(this byte[] data, ref int offset)
+ /// A filled NB10ProgramDatabase on success, null on error
+ public static NB10ProgramDatabase? ParseNB10ProgramDatabase(this byte[] data, ref int offset)
{
- var nb10ProgramDatabase = data.ReadType(ref offset);
- if (nb10ProgramDatabase?.Signature != 0x3031424E)
+ var obj = new NB10ProgramDatabase();
+
+ obj.Signature = data.ReadUInt32LittleEndian(ref offset);
+ if (obj.Signature != 0x3031424E)
return null;
- return nb10ProgramDatabase;
+ obj.Offset = data.ReadUInt32LittleEndian(ref offset);
+ obj.Timestamp = data.ReadUInt32LittleEndian(ref offset);
+ obj.Age = data.ReadUInt32LittleEndian(ref offset);
+ obj.PdbFileName = data.ReadNullTerminatedAnsiString(ref offset);
+
+ return obj;
}
///
- /// Read debug data as an RSDS Program Database
+ /// Parse a byte array into a RSDSProgramDatabase
///
- /// Data to parse into a database
+ /// Data to parse
/// Offset into the byte array
- /// A filled RSDS Program Database on success, null on error
- public static RSDSProgramDatabase? AsRSDSProgramDatabase(this byte[] data, ref int offset)
+ /// A filled RSDSProgramDatabase on success, null on error
+ public static RSDSProgramDatabase? ParseRSDSProgramDatabase(this byte[] data, ref int offset)
{
- var rsdsProgramDatabase = data.ReadType(ref offset);
- if (rsdsProgramDatabase?.Signature != 0x53445352)
+ var obj = new RSDSProgramDatabase();
+
+ obj.Signature = data.ReadUInt32LittleEndian(ref offset);
+ if (obj.Signature != 0x53445352)
return null;
-#if NET20 || NET35 || NET40 || NET452 || NET462
- // Convert ASCII string to UTF-8
- if (rsdsProgramDatabase.PathAndFileName != null)
- {
- byte[] bytes = Encoding.ASCII.GetBytes(rsdsProgramDatabase.PathAndFileName);
- rsdsProgramDatabase.PathAndFileName = Encoding.UTF8.GetString(bytes);
- }
-#endif
+ obj.GUID = data.ReadGuid(ref offset);
+ obj.Age = data.ReadUInt32LittleEndian(ref offset);
+ obj.PathAndFileName = data.ReadNullTerminatedUTF8String(ref offset);
- return rsdsProgramDatabase;
+ return obj;
}
#endregion
@@ -138,53 +141,73 @@ namespace SabreTools.Serialization
#region Overlay
///
- /// Read overlay data as a SecuROM AddD overlay data
+ /// Parse a byte array into a SecuROMAddD
///
/// Data to parse into overlay data
/// Offset into the byte array
- /// A filled SecuROM AddD overlay data on success, null on error
- public static SecuROMAddD? AsSecuROMAddD(this byte[] data, ref int offset)
+ /// A filled SecuROMAddD on success, null on error
+ public static SecuROMAddD? ParseSecuROMAddD(this byte[] data, ref int offset)
{
// Read in the table
- var addD = new SecuROMAddD();
+ var obj = new SecuROMAddD();
- addD.Signature = data.ReadUInt32(ref offset);
- if (addD.Signature != 0x44646441)
+ obj.Signature = data.ReadUInt32LittleEndian(ref offset);
+ if (obj.Signature != 0x44646441)
return null;
int originalOffset = offset;
- addD.EntryCount = data.ReadUInt32(ref offset);
- addD.Version = data.ReadNullTerminatedAnsiString(ref offset);
- if (string.IsNullOrEmpty(addD.Version))
+ obj.EntryCount = data.ReadUInt32LittleEndian(ref offset);
+ obj.Version = data.ReadNullTerminatedAnsiString(ref offset);
+ if (string.IsNullOrEmpty(obj.Version))
offset = originalOffset + 0x10;
var buildBytes = data.ReadBytes(ref offset, 4);
var buildChars = Array.ConvertAll(buildBytes, b => (char)b);
- addD.Build = buildChars;
+ obj.Build = buildChars;
// Distinguish between v1 and v2
int bytesToRead = 112; // v2
- if (string.IsNullOrEmpty(addD.Version)
- || addD.Version!.StartsWith("3")
- || addD.Version.StartsWith("4.47"))
+ if (string.IsNullOrEmpty(obj.Version)
+ || obj.Version!.StartsWith("3")
+ || obj.Version.StartsWith("4.47"))
{
bytesToRead = 44;
}
- addD.Unknown14h = data.ReadBytes(ref offset, bytesToRead);
+ obj.Unknown14h = data.ReadBytes(ref offset, bytesToRead);
- addD.Entries = new SecuROMAddDEntry[addD.EntryCount];
- for (int i = 0; i < addD.EntryCount; i++)
+ obj.Entries = new SecuROMAddDEntry[obj.EntryCount];
+ for (int i = 0; i < obj.EntryCount; i++)
{
- var addDEntry = data.ReadType(ref offset);
- if (addDEntry == null)
- return null;
-
- addD.Entries[i] = addDEntry;
+ obj.Entries[i] = ParseSecuROMAddDEntry(data, ref offset);
}
- return addD;
+ return obj;
+ }
+
+ ///
+ /// Parse a byte array into a SecuROMAddDEntry
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// Filled SecuROMAddDEntry on success, null on error
+ public static SecuROMAddDEntry ParseSecuROMAddDEntry(this byte[] data, ref int offset)
+ {
+ var obj = new SecuROMAddDEntry();
+
+ obj.PhysicalOffset = data.ReadUInt32LittleEndian(ref offset);
+ obj.Length = data.ReadUInt32LittleEndian(ref offset);
+ obj.Unknown08h = data.ReadUInt32LittleEndian(ref offset);
+ obj.Unknown0Ch = data.ReadUInt32LittleEndian(ref offset);
+ obj.Unknown10h = data.ReadUInt32LittleEndian(ref offset);
+ obj.Unknown14h = data.ReadUInt32LittleEndian(ref offset);
+ obj.Unknown18h = data.ReadUInt32LittleEndian(ref offset);
+ obj.Unknown1Ch = data.ReadUInt32LittleEndian(ref offset);
+ obj.FileName = data.ReadNullTerminatedAnsiString(ref offset);
+ obj.Unknown2Ch = data.ReadUInt32LittleEndian(ref offset);
+
+ return obj;
}
#endregion
@@ -192,34 +215,6 @@ namespace SabreTools.Serialization
// TODO: Implement other resource types from https://learn.microsoft.com/en-us/windows/win32/menurc/resource-file-formats
#region Resources
- ///
- /// Read resource data as a resource header
- ///
- /// Data to parse into a resource header
- /// Offset into the byte array
- /// A filled resource header on success, null on error
- public static ResourceHeader? AsResourceHeader(this byte[] data, ref int offset)
- {
- // If we have data that's invalid, we can't do anything
- if (data == null)
- return null;
-
- // Read in the table
- var header = new ResourceHeader();
-
- header.DataSize = data.ReadUInt32(ref offset);
- header.HeaderSize = data.ReadUInt32(ref offset);
- header.ResourceType = (ResourceType)data.ReadUInt32(ref offset); // TODO: Could be a string too
- header.Name = data.ReadUInt32(ref offset); // TODO: Could be a string too
- header.DataVersion = data.ReadUInt32(ref offset);
- header.MemoryFlags = (MemoryFlags)data.ReadUInt16(ref offset);
- header.LanguageId = data.ReadUInt16(ref offset);
- header.Version = data.ReadUInt32(ref offset);
- header.Characteristics = data.ReadUInt32(ref offset);
-
- return header;
- }
-
///
/// Read resource data as an accelerator table resource
///
@@ -243,11 +238,7 @@ namespace SabreTools.Serialization
// Read in the table
for (int i = 0; i < count; i++)
{
- var acceleratorTableEntry = entry.Data.ReadType(ref offset);
- if (acceleratorTableEntry == null)
- return null;
-
- table[i] = acceleratorTableEntry;
+ table[i] = ParseAcceleratorTableEntry(entry.Data, ref offset);
}
return table;
@@ -294,19 +285,19 @@ namespace SabreTools.Serialization
// Try to read the signature for an extended dialog box template
int signatureOffset = sizeof(ushort);
- int possibleSignature = entry.Data.ReadUInt16(ref signatureOffset);
+ int possibleSignature = entry.Data.ReadUInt16LittleEndian(ref signatureOffset);
if (possibleSignature == 0xFFFF)
{
#region Extended dialog template
var dialogTemplateExtended = new DialogTemplateExtended();
- dialogTemplateExtended.Version = entry.Data.ReadUInt16(ref offset);
- dialogTemplateExtended.Signature = entry.Data.ReadUInt16(ref offset);
- dialogTemplateExtended.HelpID = entry.Data.ReadUInt32(ref offset);
- dialogTemplateExtended.ExtendedStyle = (ExtendedWindowStyles)entry.Data.ReadUInt32(ref offset);
- dialogTemplateExtended.Style = (WindowStyles)entry.Data.ReadUInt32(ref offset);
- dialogTemplateExtended.DialogItems = entry.Data.ReadUInt16(ref offset);
+ dialogTemplateExtended.Version = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dialogTemplateExtended.Signature = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dialogTemplateExtended.HelpID = entry.Data.ReadUInt32LittleEndian(ref offset);
+ dialogTemplateExtended.ExtendedStyle = (ExtendedWindowStyles)entry.Data.ReadUInt32LittleEndian(ref offset);
+ dialogTemplateExtended.Style = (WindowStyles)entry.Data.ReadUInt32LittleEndian(ref offset);
+ dialogTemplateExtended.DialogItems = entry.Data.ReadUInt16LittleEndian(ref offset);
dialogTemplateExtended.PositionX = entry.Data.ReadInt16(ref offset);
dialogTemplateExtended.PositionY = entry.Data.ReadInt16(ref offset);
dialogTemplateExtended.WidthX = entry.Data.ReadInt16(ref offset);
@@ -315,7 +306,7 @@ namespace SabreTools.Serialization
#region Menu resource
int currentOffset = offset;
- ushort menuResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ ushort menuResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0x0000 means no elements
@@ -343,7 +334,7 @@ namespace SabreTools.Serialization
// Read the ordinal if we have the flag set
if (menuResourceHasOrdinal)
- dialogTemplateExtended.MenuResourceOrdinal = entry.Data.ReadUInt16(ref offset);
+ dialogTemplateExtended.MenuResourceOrdinal = entry.Data.ReadUInt16LittleEndian(ref offset);
}
#endregion
@@ -351,7 +342,7 @@ namespace SabreTools.Serialization
#region Class resource
currentOffset = offset;
- ushort classResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ ushort classResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0x0000 means no elements
@@ -379,7 +370,7 @@ namespace SabreTools.Serialization
// Read the ordinal if we have the flag set
if (classResourcehasOrdinal)
- dialogTemplateExtended.ClassResourceOrdinal = entry.Data.ReadUInt16(ref offset);
+ dialogTemplateExtended.ClassResourceOrdinal = entry.Data.ReadUInt16LittleEndian(ref offset);
}
#endregion
@@ -387,7 +378,7 @@ namespace SabreTools.Serialization
#region Title resource
currentOffset = offset;
- ushort titleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ ushort titleResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0x0000 means no elements
@@ -420,8 +411,8 @@ namespace SabreTools.Serialization
if (dialogTemplateExtended.Style.HasFlag(WindowStyles.DS_SETFONT))
#endif
{
- dialogTemplateExtended.PointSize = entry.Data.ReadUInt16(ref offset);
- dialogTemplateExtended.Weight = entry.Data.ReadUInt16(ref offset);
+ dialogTemplateExtended.PointSize = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dialogTemplateExtended.Weight = entry.Data.ReadUInt16LittleEndian(ref offset);
dialogTemplateExtended.Italic = entry.Data.ReadByte(ref offset);
dialogTemplateExtended.CharSet = entry.Data.ReadByte(ref offset);
dialogTemplateExtended.Typeface = entry.Data.ReadNullTerminatedUnicodeString(ref offset);
@@ -448,29 +439,29 @@ namespace SabreTools.Serialization
{
var dialogItemTemplate = new DialogItemTemplateExtended();
- dialogItemTemplate.HelpID = entry.Data.ReadUInt32(ref offset);
- dialogItemTemplate.ExtendedStyle = (ExtendedWindowStyles)entry.Data.ReadUInt32(ref offset);
- dialogItemTemplate.Style = (WindowStyles)entry.Data.ReadUInt32(ref offset);
+ dialogItemTemplate.HelpID = entry.Data.ReadUInt32LittleEndian(ref offset);
+ dialogItemTemplate.ExtendedStyle = (ExtendedWindowStyles)entry.Data.ReadUInt32LittleEndian(ref offset);
+ dialogItemTemplate.Style = (WindowStyles)entry.Data.ReadUInt32LittleEndian(ref offset);
dialogItemTemplate.PositionX = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.PositionY = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.WidthX = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.HeightY = entry.Data.ReadInt16(ref offset);
- dialogItemTemplate.ID = entry.Data.ReadUInt32(ref offset);
+ dialogItemTemplate.ID = entry.Data.ReadUInt32LittleEndian(ref offset);
#region Class resource
currentOffset = offset;
- ushort itemClassResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ ushort itemClassResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0xFFFF means ordinal only
if (itemClassResourceIdentifier == 0xFFFF)
{
// Increment the pointer
- _ = entry.Data.ReadUInt16(ref offset);
+ _ = entry.Data.ReadUInt16LittleEndian(ref offset);
// Read the ordinal
- dialogItemTemplate.ClassResourceOrdinal = (DialogItemTemplateOrdinal)entry.Data.ReadUInt16(ref offset);
+ dialogItemTemplate.ClassResourceOrdinal = (DialogItemTemplateOrdinal)entry.Data.ReadUInt16LittleEndian(ref offset);
}
else
{
@@ -495,17 +486,17 @@ namespace SabreTools.Serialization
#region Title resource
currentOffset = offset;
- ushort itemTitleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ ushort itemTitleResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0xFFFF means ordinal only
if (itemTitleResourceIdentifier == 0xFFFF)
{
// Increment the pointer
- _ = entry.Data.ReadUInt16(ref offset);
+ _ = entry.Data.ReadUInt16LittleEndian(ref offset);
// Read the ordinal
- dialogItemTemplate.TitleResourceOrdinal = entry.Data.ReadUInt16(ref offset);
+ dialogItemTemplate.TitleResourceOrdinal = entry.Data.ReadUInt16LittleEndian(ref offset);
}
else
{
@@ -524,7 +515,7 @@ namespace SabreTools.Serialization
#region Creation data
- dialogItemTemplate.CreationDataSize = entry.Data.ReadUInt16(ref offset);
+ dialogItemTemplate.CreationDataSize = entry.Data.ReadUInt16LittleEndian(ref offset);
if (dialogItemTemplate.CreationDataSize != 0)
dialogItemTemplate.CreationData = entry.Data.ReadBytes(ref offset, dialogItemTemplate.CreationDataSize);
@@ -554,9 +545,9 @@ namespace SabreTools.Serialization
var dialogTemplate = new DialogTemplate();
- dialogTemplate.Style = (WindowStyles)entry.Data.ReadUInt32(ref offset);
- dialogTemplate.ExtendedStyle = (ExtendedWindowStyles)entry.Data.ReadUInt32(ref offset);
- dialogTemplate.ItemCount = entry.Data.ReadUInt16(ref offset);
+ dialogTemplate.Style = (WindowStyles)entry.Data.ReadUInt32LittleEndian(ref offset);
+ dialogTemplate.ExtendedStyle = (ExtendedWindowStyles)entry.Data.ReadUInt32LittleEndian(ref offset);
+ dialogTemplate.ItemCount = entry.Data.ReadUInt16LittleEndian(ref offset);
dialogTemplate.PositionX = entry.Data.ReadInt16(ref offset);
dialogTemplate.PositionY = entry.Data.ReadInt16(ref offset);
dialogTemplate.WidthX = entry.Data.ReadInt16(ref offset);
@@ -565,7 +556,7 @@ namespace SabreTools.Serialization
#region Menu resource
int currentOffset = offset;
- ushort menuResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ ushort menuResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0x0000 means no elements
@@ -593,7 +584,7 @@ namespace SabreTools.Serialization
// Read the ordinal if we have the flag set
if (menuResourceHasOrdinal)
- dialogTemplate.MenuResourceOrdinal = entry.Data.ReadUInt16(ref offset);
+ dialogTemplate.MenuResourceOrdinal = entry.Data.ReadUInt16LittleEndian(ref offset);
}
#endregion
@@ -605,7 +596,7 @@ namespace SabreTools.Serialization
if (offset >= entry.Data.Length)
classResourceIdentifier = 0x0000;
else
- classResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ classResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0x0000 means no elements
@@ -633,7 +624,7 @@ namespace SabreTools.Serialization
// Read the ordinal if we have the flag set
if (classResourcehasOrdinal)
- dialogTemplate.ClassResourceOrdinal = entry.Data.ReadUInt16(ref offset);
+ dialogTemplate.ClassResourceOrdinal = entry.Data.ReadUInt16LittleEndian(ref offset);
}
#endregion
@@ -645,7 +636,7 @@ namespace SabreTools.Serialization
if (offset >= entry.Data.Length)
titleResourceIdentifier = 0x0000;
else
- titleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ titleResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0x0000 means no elements
@@ -678,7 +669,7 @@ namespace SabreTools.Serialization
if (dialogTemplate.Style.HasFlag(WindowStyles.DS_SETFONT))
#endif
{
- dialogTemplate.PointSizeValue = entry.Data.ReadUInt16(ref offset);
+ dialogTemplate.PointSizeValue = entry.Data.ReadUInt16LittleEndian(ref offset);
// Read the font name as a string
dialogTemplate.Typeface = entry.Data.ReadNullTerminatedUnicodeString(ref offset);
@@ -705,28 +696,28 @@ namespace SabreTools.Serialization
{
var dialogItemTemplate = new DialogItemTemplate();
- dialogItemTemplate.Style = (WindowStyles)entry.Data.ReadUInt32(ref offset);
- dialogItemTemplate.ExtendedStyle = (ExtendedWindowStyles)entry.Data.ReadUInt32(ref offset);
+ dialogItemTemplate.Style = (WindowStyles)entry.Data.ReadUInt32LittleEndian(ref offset);
+ dialogItemTemplate.ExtendedStyle = (ExtendedWindowStyles)entry.Data.ReadUInt32LittleEndian(ref offset);
dialogItemTemplate.PositionX = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.PositionY = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.WidthX = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.HeightY = entry.Data.ReadInt16(ref offset);
- dialogItemTemplate.ID = entry.Data.ReadUInt16(ref offset);
+ dialogItemTemplate.ID = entry.Data.ReadUInt16LittleEndian(ref offset);
#region Class resource
currentOffset = offset;
- ushort itemClassResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ ushort itemClassResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0xFFFF means ordinal only
if (itemClassResourceIdentifier == 0xFFFF)
{
// Increment the pointer
- _ = entry.Data.ReadUInt16(ref offset);
+ _ = entry.Data.ReadUInt16LittleEndian(ref offset);
// Read the ordinal
- dialogItemTemplate.ClassResourceOrdinal = (DialogItemTemplateOrdinal)entry.Data.ReadUInt16(ref offset);
+ dialogItemTemplate.ClassResourceOrdinal = (DialogItemTemplateOrdinal)entry.Data.ReadUInt16LittleEndian(ref offset);
}
else
{
@@ -751,17 +742,17 @@ namespace SabreTools.Serialization
#region Title resource
currentOffset = offset;
- ushort itemTitleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
+ ushort itemTitleResourceIdentifier = entry.Data.ReadUInt16LittleEndian(ref offset);
offset = currentOffset;
// 0xFFFF means ordinal only
if (itemTitleResourceIdentifier == 0xFFFF)
{
// Increment the pointer
- _ = entry.Data.ReadUInt16(ref offset);
+ _ = entry.Data.ReadUInt16LittleEndian(ref offset);
// Read the ordinal
- dialogItemTemplate.TitleResourceOrdinal = entry.Data.ReadUInt16(ref offset);
+ dialogItemTemplate.TitleResourceOrdinal = entry.Data.ReadUInt16LittleEndian(ref offset);
}
else
{
@@ -780,7 +771,7 @@ namespace SabreTools.Serialization
#region Creation data
- dialogItemTemplate.CreationDataSize = entry.Data.ReadUInt16(ref offset);
+ dialogItemTemplate.CreationDataSize = entry.Data.ReadUInt16LittleEndian(ref offset);
if (dialogItemTemplate.CreationDataSize != 0)
dialogItemTemplate.CreationData = entry.Data.ReadBytes(ref offset, dialogItemTemplate.CreationDataSize);
@@ -825,7 +816,7 @@ namespace SabreTools.Serialization
// Create the output object
var fontGroupHeader = new FontGroupHeader();
- fontGroupHeader.NumberOfFonts = entry.Data.ReadUInt16(ref offset);
+ fontGroupHeader.NumberOfFonts = entry.Data.ReadUInt16LittleEndian(ref offset);
if (fontGroupHeader.NumberOfFonts > 0)
{
fontGroupHeader.DE = new DirEntry[fontGroupHeader.NumberOfFonts];
@@ -833,37 +824,37 @@ namespace SabreTools.Serialization
{
var dirEntry = new DirEntry();
- dirEntry.FontOrdinal = entry.Data.ReadUInt16(ref offset);
+ dirEntry.FontOrdinal = entry.Data.ReadUInt16LittleEndian(ref offset);
dirEntry.Entry = new FontDirEntry();
- dirEntry.Entry.Version = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.Size = entry.Data.ReadUInt32(ref offset);
+ dirEntry.Entry.Version = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.Size = entry.Data.ReadUInt32LittleEndian(ref offset);
dirEntry.Entry.Copyright = entry.Data.ReadBytes(ref offset, 60);
- dirEntry.Entry.Type = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.Points = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.VertRes = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.HorizRes = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.Ascent = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.InternalLeading = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.ExternalLeading = entry.Data.ReadUInt16(ref offset);
+ dirEntry.Entry.Type = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.Points = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.VertRes = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.HorizRes = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.Ascent = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.InternalLeading = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.ExternalLeading = entry.Data.ReadUInt16LittleEndian(ref offset);
dirEntry.Entry.Italic = entry.Data.ReadByte(ref offset);
dirEntry.Entry.Underline = entry.Data.ReadByte(ref offset);
dirEntry.Entry.StrikeOut = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.Weight = entry.Data.ReadUInt16(ref offset);
+ dirEntry.Entry.Weight = entry.Data.ReadUInt16LittleEndian(ref offset);
dirEntry.Entry.CharSet = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.PixWidth = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.PixHeight = entry.Data.ReadUInt16(ref offset);
+ dirEntry.Entry.PixWidth = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.PixHeight = entry.Data.ReadUInt16LittleEndian(ref offset);
dirEntry.Entry.PitchAndFamily = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.AvgWidth = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.MaxWidth = entry.Data.ReadUInt16(ref offset);
+ dirEntry.Entry.AvgWidth = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.MaxWidth = entry.Data.ReadUInt16LittleEndian(ref offset);
dirEntry.Entry.FirstChar = entry.Data.ReadByte(ref offset);
dirEntry.Entry.LastChar = entry.Data.ReadByte(ref offset);
dirEntry.Entry.DefaultChar = entry.Data.ReadByte(ref offset);
dirEntry.Entry.BreakChar = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.WidthBytes = entry.Data.ReadUInt16(ref offset);
- dirEntry.Entry.Device = entry.Data.ReadUInt32(ref offset);
- dirEntry.Entry.Face = entry.Data.ReadUInt32(ref offset);
- dirEntry.Entry.Reserved = entry.Data.ReadUInt32(ref offset);
+ dirEntry.Entry.WidthBytes = entry.Data.ReadUInt16LittleEndian(ref offset);
+ dirEntry.Entry.Device = entry.Data.ReadUInt32LittleEndian(ref offset);
+ dirEntry.Entry.Face = entry.Data.ReadUInt32LittleEndian(ref offset);
+ dirEntry.Entry.Reserved = entry.Data.ReadUInt32LittleEndian(ref offset);
// TODO: Determine how to read these two? Immediately after?
dirEntry.Entry.DeviceName = entry.Data.ReadNullTerminatedAnsiString(ref offset);
@@ -896,15 +887,12 @@ namespace SabreTools.Serialization
// Try to read the version for an extended header
int versionOffset = 0;
- int possibleVersion = entry.Data.ReadUInt16(ref versionOffset);
+ int possibleVersion = entry.Data.ReadUInt16LittleEndian(ref versionOffset);
if (possibleVersion == 0x0001)
{
#region Extended menu header
- var menuHeaderExtended = entry.Data.ReadType(ref offset);
- if (menuHeaderExtended == null)
- return null;
-
+ var menuHeaderExtended = ParseMenuHeaderExtended(entry.Data, ref offset);
menuResource.MenuHeader = menuHeaderExtended;
#endregion
@@ -919,9 +907,8 @@ namespace SabreTools.Serialization
while (offset < entry.Data.Length)
{
- var extendedMenuItem = entry.Data.ReadType(ref offset);
- if (extendedMenuItem == null)
- return null;
+ var extendedMenuItem = ParseMenuItemExtended(entry.Data, ref offset);
+ extendedMenuItems.Add(extendedMenuItem);
// Align to the DWORD boundary if we're not at the end
if (offset < entry.Data.Length)
@@ -929,8 +916,6 @@ namespace SabreTools.Serialization
while (offset < entry.Data.Length && (offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
}
-
- extendedMenuItems.Add(extendedMenuItem);
}
}
@@ -942,11 +927,7 @@ namespace SabreTools.Serialization
{
#region Menu header
- var menuHeader = entry.Data.ReadType(ref offset);
- if (menuHeader == null)
- return null;
-
- menuResource.MenuHeader = menuHeader;
+ menuResource.MenuHeader = ParseNormalMenuHeader(entry.Data, ref offset);
#endregion
@@ -958,7 +939,7 @@ namespace SabreTools.Serialization
{
// Determine if this is a popup
int flagsOffset = offset;
- var initialFlags = (MenuFlags)entry.Data.ReadUInt16(ref flagsOffset);
+ var initialFlags = (MenuFlags)entry.Data.ReadUInt16LittleEndian(ref flagsOffset);
MenuItem? menuItem;
#if NET20 || NET35
@@ -966,9 +947,9 @@ namespace SabreTools.Serialization
#else
if (initialFlags.HasFlag(MenuFlags.MF_POPUP))
#endif
- menuItem = entry.Data.ReadType(ref offset);
+ menuItem = ParsePopupMenuItem(entry.Data, ref offset);
else
- menuItem = entry.Data.ReadType(ref offset);
+ menuItem = ParseNormalMenuItem(entry.Data, ref offset);
// Align to the DWORD boundary if we're not at the end
if (offset < entry.Data.Length)
@@ -1009,17 +990,14 @@ namespace SabreTools.Serialization
var messageResourceData = new MessageResourceData();
// Message resource blocks
- messageResourceData.NumberOfBlocks = entry.Data.ReadUInt32(ref offset);
+ messageResourceData.NumberOfBlocks = entry.Data.ReadUInt32LittleEndian(ref offset);
if (messageResourceData.NumberOfBlocks > 0)
{
var messageResourceBlocks = new List();
for (int i = 0; i < messageResourceData.NumberOfBlocks; i++)
{
- var messageResourceBlock = entry.Data.ReadType(ref offset);
- if (messageResourceBlock == null)
- return null;
-
+ var messageResourceBlock = ParseMessageResourceBlock(entry.Data, ref offset);
messageResourceBlocks.Add(messageResourceBlock);
}
@@ -1043,8 +1021,8 @@ namespace SabreTools.Serialization
{
var messageResourceEntry = new MessageResourceEntry();
- messageResourceEntry.Length = entry.Data.ReadUInt16(ref offset);
- messageResourceEntry.Flags = entry.Data.ReadUInt16(ref offset);
+ messageResourceEntry.Length = entry.Data.ReadUInt16LittleEndian(ref offset);
+ messageResourceEntry.Flags = entry.Data.ReadUInt16LittleEndian(ref offset);
Encoding textEncoding = messageResourceEntry.Flags == 0x0001 ? Encoding.Unicode : Encoding.ASCII;
byte[]? textArray = entry.Data.ReadBytes(ref offset, messageResourceEntry.Length - 4);
@@ -1061,6 +1039,100 @@ namespace SabreTools.Serialization
return messageResourceData;
}
+ ///
+ /// Read byte data as a string file info resource
+ ///
+ /// Data to parse into a string file info
+ /// Offset into the byte array
+ /// A filled string file info resource on success, null on error
+ public static StringFileInfo? AsStringFileInfo(byte[] data, ref int offset)
+ {
+ var stringFileInfo = new StringFileInfo();
+
+ // Cache the initial offset
+ int currentOffset = offset;
+
+ stringFileInfo.Length = data.ReadUInt16LittleEndian(ref offset);
+ stringFileInfo.ValueLength = data.ReadUInt16LittleEndian(ref offset);
+ stringFileInfo.ResourceType = (VersionResourceType)data.ReadUInt16LittleEndian(ref offset);
+ stringFileInfo.Key = data.ReadNullTerminatedUnicodeString(ref offset);
+ if (stringFileInfo.Key != "StringFileInfo")
+ {
+ offset -= 6 + ((stringFileInfo.Key?.Length ?? 0 + 1) * 2);
+ return null;
+ }
+
+ // Align to the DWORD boundary if we're not at the end
+ if (offset < data.Length)
+ {
+ while (offset < data.Length && (offset % 4) != 0)
+ stringFileInfo.Padding = data.ReadByte(ref offset);
+ }
+
+ var stringFileInfoChildren = new List();
+ while ((offset - currentOffset) < stringFileInfo.Length)
+ {
+ var stringTable = new StringTable();
+
+ stringTable.Length = data.ReadUInt16LittleEndian(ref offset);
+ stringTable.ValueLength = data.ReadUInt16LittleEndian(ref offset);
+ stringTable.ResourceType = (VersionResourceType)data.ReadUInt16LittleEndian(ref offset);
+ stringTable.Key = data.ReadNullTerminatedUnicodeString(ref offset);
+
+ // Align to the DWORD boundary if we're not at the end
+ if (offset < data.Length)
+ {
+ while (offset < data.Length && (offset % 4) != 0)
+ stringTable.Padding = data.ReadByte(ref offset);
+ }
+
+ var stringTableChildren = new List();
+ while ((offset - currentOffset) < stringTable.Length)
+ {
+ var stringData = new StringData();
+
+ int dataStartOffset = offset;
+ stringData.Length = data.ReadUInt16LittleEndian(ref offset);
+ stringData.ValueLength = data.ReadUInt16LittleEndian(ref offset);
+ stringData.ResourceType = (VersionResourceType)data.ReadUInt16LittleEndian(ref offset);
+ stringData.Key = data.ReadNullTerminatedUnicodeString(ref offset);
+
+ // Align to the DWORD boundary if we're not at the end
+ if (offset < data.Length)
+ {
+ while (offset < data.Length && (offset % 4) != 0)
+ stringData.Padding = data.ReadByte(ref offset);
+ }
+
+ if (stringData.ValueLength > 0)
+ {
+ int bytesReadable = Math.Min(stringData.ValueLength * sizeof(ushort), stringData.Length - (offset - dataStartOffset));
+ byte[] valueBytes = data.ReadBytes(ref offset, bytesReadable);
+ stringData.Value = Encoding.Unicode.GetString(valueBytes);
+ }
+
+ // Align to the DWORD boundary if we're not at the end
+ if (offset < data.Length)
+ {
+ while (offset < data.Length && (offset % 4) != 0)
+ _ = data.ReadByte(ref offset);
+ }
+
+ stringTableChildren.Add(stringData);
+ if (stringData.Length == 0 && stringData.ValueLength == 0)
+ break;
+ }
+
+ stringTable.Children = [.. stringTableChildren];
+
+ stringFileInfoChildren.Add(stringTable);
+ }
+
+ stringFileInfo.Children = [.. stringFileInfoChildren];
+
+ return stringFileInfo;
+ }
+
///
/// Read resource data as a string table resource
///
@@ -1092,6 +1164,75 @@ namespace SabreTools.Serialization
return stringTable;
}
+ ///
+ /// Read byte data as a var file info resource
+ ///
+ /// Data to parse into a var file info
+ /// Offset into the byte array
+ /// A filled var file info resource on success, null on error
+ public static VarFileInfo? AsVarFileInfo(byte[] data, ref int offset)
+ {
+ var varFileInfo = new VarFileInfo();
+
+ // Cache the initial offset
+ int initialOffset = offset;
+
+ varFileInfo.Length = data.ReadUInt16LittleEndian(ref offset);
+ varFileInfo.ValueLength = data.ReadUInt16LittleEndian(ref offset);
+ varFileInfo.ResourceType = (VersionResourceType)data.ReadUInt16LittleEndian(ref offset);
+ varFileInfo.Key = data.ReadNullTerminatedUnicodeString(ref offset);
+ if (varFileInfo.Key != "VarFileInfo")
+ return null;
+
+ // Align to the DWORD boundary if we're not at the end
+ if (offset < data.Length)
+ {
+ while (offset < data.Length && (offset % 4) != 0)
+ varFileInfo.Padding = data.ReadByte(ref offset);
+ }
+
+ var varFileInfoChildren = new List();
+ while ((offset - initialOffset) < varFileInfo.Length)
+ {
+ var varData = new VarData();
+
+ varData.Length = data.ReadUInt16LittleEndian(ref offset);
+ varData.ValueLength = data.ReadUInt16LittleEndian(ref offset);
+ varData.ResourceType = (VersionResourceType)data.ReadUInt16LittleEndian(ref offset);
+ varData.Key = data.ReadNullTerminatedUnicodeString(ref offset);
+ if (varData.Key != "Translation")
+ {
+ offset -= 6 + ((varData.Key?.Length ?? 0 + 1) * 2);
+ return null;
+ }
+
+ // Align to the DWORD boundary if we're not at the end
+ if (offset < data.Length)
+ {
+ while (offset < data.Length && (offset % 4) != 0)
+ varData.Padding = data.ReadByte(ref offset);
+ }
+
+ // Cache the current offset
+ int currentOffset = offset;
+
+ var varDataValue = new List();
+ while ((offset - currentOffset) < varData.ValueLength)
+ {
+ uint languageAndCodeIdentifierPair = data.ReadUInt32LittleEndian(ref offset);
+ varDataValue.Add(languageAndCodeIdentifierPair);
+ }
+
+ varData.Value = [.. varDataValue];
+
+ varFileInfoChildren.Add(varData);
+ }
+
+ varFileInfo.Children = [.. varFileInfoChildren];
+
+ return varFileInfo;
+ }
+
///
/// Read resource data as a version info resource
///
@@ -1109,20 +1250,20 @@ namespace SabreTools.Serialization
// Create the output object
var versionInfo = new VersionInfo();
- versionInfo.Length = entry.Data.ReadUInt16(ref offset);
- versionInfo.ValueLength = entry.Data.ReadUInt16(ref offset);
- versionInfo.ResourceType = (VersionResourceType)entry.Data.ReadUInt16(ref offset);
+ versionInfo.Length = entry.Data.ReadUInt16LittleEndian(ref offset);
+ versionInfo.ValueLength = entry.Data.ReadUInt16LittleEndian(ref offset);
+ versionInfo.ResourceType = (VersionResourceType)entry.Data.ReadUInt16LittleEndian(ref offset);
versionInfo.Key = entry.Data.ReadNullTerminatedUnicodeString(ref offset);
if (versionInfo.Key != "VS_VERSION_INFO")
return null;
while (offset < entry.Data.Length && (offset % 4) != 0)
- versionInfo.Padding1 = entry.Data.ReadUInt16(ref offset);
+ versionInfo.Padding1 = entry.Data.ReadUInt16LittleEndian(ref offset);
// Read fixed file info
if (versionInfo.ValueLength > 0 && offset + versionInfo.ValueLength <= entry.Data.Length)
{
- var fixedFileInfo = entry.Data.ReadType(ref offset);
+ var fixedFileInfo = ParseFixedFileInfo(entry.Data, ref offset);
if (fixedFileInfo?.Signature != 0xFEEF04BD)
return null;
@@ -1130,7 +1271,7 @@ namespace SabreTools.Serialization
}
while (offset < entry.Data.Length && (offset % 4) != 0)
- versionInfo.Padding2 = entry.Data.ReadUInt16(ref offset);
+ versionInfo.Padding2 = entry.Data.ReadUInt16LittleEndian(ref offset);
// TODO: Make the following block a private helper method
@@ -1182,166 +1323,176 @@ namespace SabreTools.Serialization
}
///
- /// Read byte data as a string file info resource
+ /// Parse a byte array into a AcceleratorTableEntry
///
- /// Data to parse into a string file info
+ /// Data to parse
/// Offset into the byte array
- /// A filled string file info resource on success, null on error
- public static StringFileInfo? AsStringFileInfo(byte[] data, ref int offset)
+ /// A filled AcceleratorTableEntry on success, null on error
+ public static AcceleratorTableEntry ParseAcceleratorTableEntry(this byte[] data, ref int offset)
{
- var stringFileInfo = new StringFileInfo();
+ var obj = new AcceleratorTableEntry();
- // Cache the initial offset
- int currentOffset = offset;
+ obj.Flags = (AcceleratorTableFlags)data.ReadUInt16LittleEndian(ref offset);
+ obj.Ansi = data.ReadUInt16LittleEndian(ref offset);
+ obj.Id = data.ReadUInt16LittleEndian(ref offset);
+ obj.Padding = data.ReadUInt16LittleEndian(ref offset);
- stringFileInfo.Length = data.ReadUInt16(ref offset);
- stringFileInfo.ValueLength = data.ReadUInt16(ref offset);
- stringFileInfo.ResourceType = (VersionResourceType)data.ReadUInt16(ref offset);
- stringFileInfo.Key = data.ReadNullTerminatedUnicodeString(ref offset);
- if (stringFileInfo.Key != "StringFileInfo")
- {
- offset -= 6 + ((stringFileInfo.Key?.Length ?? 0 + 1) * 2);
- return null;
- }
-
- // Align to the DWORD boundary if we're not at the end
- if (offset < data.Length)
- {
- while (offset < data.Length && (offset % 4) != 0)
- stringFileInfo.Padding = data.ReadByte(ref offset);
- }
-
- var stringFileInfoChildren = new List();
- while ((offset - currentOffset) < stringFileInfo.Length)
- {
- var stringTable = new StringTable();
-
- stringTable.Length = data.ReadUInt16(ref offset);
- stringTable.ValueLength = data.ReadUInt16(ref offset);
- stringTable.ResourceType = (VersionResourceType)data.ReadUInt16(ref offset);
- stringTable.Key = data.ReadNullTerminatedUnicodeString(ref offset);
-
- // Align to the DWORD boundary if we're not at the end
- if (offset < data.Length)
- {
- while (offset < data.Length && (offset % 4) != 0)
- stringTable.Padding = data.ReadByte(ref offset);
- }
-
- var stringTableChildren = new List();
- while ((offset - currentOffset) < stringTable.Length)
- {
- var stringData = new StringData();
-
- int dataStartOffset = offset;
- stringData.Length = data.ReadUInt16(ref offset);
- stringData.ValueLength = data.ReadUInt16(ref offset);
- stringData.ResourceType = (VersionResourceType)data.ReadUInt16(ref offset);
- stringData.Key = data.ReadNullTerminatedUnicodeString(ref offset);
-
- // Align to the DWORD boundary if we're not at the end
- if (offset < data.Length)
- {
- while (offset < data.Length && (offset % 4) != 0)
- stringData.Padding = data.ReadByte(ref offset);
- }
-
- if (stringData.ValueLength > 0)
- {
- int bytesReadable = Math.Min(stringData.ValueLength * sizeof(ushort), stringData.Length - (offset - dataStartOffset));
- byte[] valueBytes = data.ReadBytes(ref offset, bytesReadable);
- stringData.Value = Encoding.Unicode.GetString(valueBytes);
- }
-
- // Align to the DWORD boundary if we're not at the end
- if (offset < data.Length)
- {
- while (offset < data.Length && (offset % 4) != 0)
- _ = data.ReadByte(ref offset);
- }
-
- stringTableChildren.Add(stringData);
- if (stringData.Length == 0 && stringData.ValueLength == 0)
- break;
- }
-
- stringTable.Children = [.. stringTableChildren];
-
- stringFileInfoChildren.Add(stringTable);
- }
-
- stringFileInfo.Children = [.. stringFileInfoChildren];
-
- return stringFileInfo;
+ return obj;
}
///
- /// Read byte data as a var file info resource
+ /// Parse a byte array into a FixedFileInfo
///
- /// Data to parse into a var file info
+ /// Data to parse
/// Offset into the byte array
- /// A filled var file info resource on success, null on error
- public static VarFileInfo? AsVarFileInfo(byte[] data, ref int offset)
+ /// A filled FixedFileInfo on success, null on error
+ public static FixedFileInfo ParseFixedFileInfo(this byte[] data, ref int offset)
{
- var varFileInfo = new VarFileInfo();
+ var obj = new FixedFileInfo();
- // Cache the initial offset
- int initialOffset = offset;
+ obj.Signature = data.ReadUInt32LittleEndian(ref offset);
+ obj.StrucVersion = data.ReadUInt32LittleEndian(ref offset);
+ obj.FileVersionMS = data.ReadUInt32LittleEndian(ref offset);
+ obj.FileVersionLS = data.ReadUInt32LittleEndian(ref offset);
+ obj.ProductVersionMS = data.ReadUInt32LittleEndian(ref offset);
+ obj.ProductVersionLS = data.ReadUInt32LittleEndian(ref offset);
+ obj.FileFlagsMask = data.ReadUInt32LittleEndian(ref offset);
+ obj.FileFlags = (FixedFileInfoFlags)data.ReadUInt32LittleEndian(ref offset);
+ obj.FileOS = (FixedFileInfoOS)data.ReadUInt32LittleEndian(ref offset);
+ obj.FileType = (FixedFileInfoFileType)data.ReadUInt32LittleEndian(ref offset);
+ obj.FileSubtype = (FixedFileInfoFileSubtype)data.ReadUInt32LittleEndian(ref offset);
+ obj.FileDateMS = data.ReadUInt32LittleEndian(ref offset);
+ obj.FileDateLS = data.ReadUInt32LittleEndian(ref offset);
- varFileInfo.Length = data.ReadUInt16(ref offset);
- varFileInfo.ValueLength = data.ReadUInt16(ref offset);
- varFileInfo.ResourceType = (VersionResourceType)data.ReadUInt16(ref offset);
- varFileInfo.Key = data.ReadNullTerminatedUnicodeString(ref offset);
- if (varFileInfo.Key != "VarFileInfo")
- return null;
+ return obj;
+ }
- // Align to the DWORD boundary if we're not at the end
- if (offset < data.Length)
- {
- while (offset < data.Length && (offset % 4) != 0)
- varFileInfo.Padding = data.ReadByte(ref offset);
- }
+ ///
+ /// Parse a byte array into a MenuHeaderExtended
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled MenuHeaderExtended on success, null on error
+ public static MenuHeaderExtended ParseMenuHeaderExtended(this byte[] data, ref int offset)
+ {
+ var obj = new MenuHeaderExtended();
- var varFileInfoChildren = new List();
- while ((offset - initialOffset) < varFileInfo.Length)
- {
- var varData = new VarData();
+ obj.Version = data.ReadUInt16LittleEndian(ref offset);
+ obj.Offset = data.ReadUInt16LittleEndian(ref offset);
+ obj.HelpID = data.ReadUInt32LittleEndian(ref offset);
- varData.Length = data.ReadUInt16(ref offset);
- varData.ValueLength = data.ReadUInt16(ref offset);
- varData.ResourceType = (VersionResourceType)data.ReadUInt16(ref offset);
- varData.Key = data.ReadNullTerminatedUnicodeString(ref offset);
- if (varData.Key != "Translation")
- {
- offset -= 6 + ((varData.Key?.Length ?? 0 + 1) * 2);
- return null;
- }
+ return obj;
+ }
- // Align to the DWORD boundary if we're not at the end
- if (offset < data.Length)
- {
- while (offset < data.Length && (offset % 4) != 0)
- varData.Padding = data.ReadByte(ref offset);
- }
+ ///
+ /// Parse a byte array into a MenuItemExtended
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled MenuItemExtended on success, null on error
+ public static MenuItemExtended ParseMenuItemExtended(this byte[] data, ref int offset)
+ {
+ var obj = new MenuItemExtended();
- // Cache the current offset
- int currentOffset = offset;
+ obj.ItemType = (MenuFlags)data.ReadUInt32LittleEndian(ref offset);
+ obj.State = (MenuFlags)data.ReadUInt32LittleEndian(ref offset);
+ obj.ID = data.ReadUInt32LittleEndian(ref offset);
+ obj.Flags = (MenuFlags)data.ReadUInt32LittleEndian(ref offset);
+ obj.MenuText = data.ReadNullTerminatedUnicodeString(ref offset);
- var varDataValue = new List();
- while ((offset - currentOffset) < varData.ValueLength)
- {
- uint languageAndCodeIdentifierPair = data.ReadUInt32(ref offset);
- varDataValue.Add(languageAndCodeIdentifierPair);
- }
+ return obj;
+ }
- varData.Value = [.. varDataValue];
+ ///
+ /// Parse a byte array into a MessageResourceBlock
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled MessageResourceBlock on success, null on error
+ public static MessageResourceBlock ParseMessageResourceBlock(this byte[] data, ref int offset)
+ {
+ var obj = new MessageResourceBlock();
- varFileInfoChildren.Add(varData);
- }
+ obj.LowId = data.ReadUInt32LittleEndian(ref offset);
+ obj.HighId = data.ReadUInt32LittleEndian(ref offset);
+ obj.OffsetToEntries = data.ReadUInt32LittleEndian(ref offset);
- varFileInfo.Children = [.. varFileInfoChildren];
+ return obj;
+ }
- return varFileInfo;
+ ///
+ /// Parse a byte array into a NormalMenuHeader
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled NormalMenuHeader on success, null on error
+ public static NormalMenuHeader ParseNormalMenuHeader(this byte[] data, ref int offset)
+ {
+ var obj = new NormalMenuHeader();
+
+ obj.Version = data.ReadUInt16LittleEndian(ref offset);
+ obj.HeaderSize = data.ReadUInt16LittleEndian(ref offset);
+
+ return obj;
+ }
+
+ ///
+ /// Parse a byte array into a NormalMenuItem
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled NormalMenuItem on success, null on error
+ public static NormalMenuItem ParseNormalMenuItem(this byte[] data, ref int offset)
+ {
+ var obj = new NormalMenuItem();
+
+ obj.NormalResInfo = (MenuFlags)data.ReadUInt32LittleEndian(ref offset);
+ obj.NormalMenuText = data.ReadNullTerminatedUnicodeString(ref offset);
+
+ return obj;
+ }
+
+ ///
+ /// Parse a byte array into a PopupMenuItem
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled PopupMenuItem on success, null on error
+ public static PopupMenuItem ParsePopupMenuItem(this byte[] data, ref int offset)
+ {
+ var obj = new PopupMenuItem();
+
+ obj.PopupItemType = (MenuFlags)data.ReadUInt32LittleEndian(ref offset);
+ obj.PopupState = (MenuFlags)data.ReadUInt32LittleEndian(ref offset);
+ obj.PopupID = data.ReadUInt32LittleEndian(ref offset);
+ obj.PopupResInfo = (MenuFlags)data.ReadUInt32LittleEndian(ref offset);
+ obj.PopupMenuText = data.ReadNullTerminatedUnicodeString(ref offset);
+
+ return obj;
+ }
+
+ ///
+ /// Parse a byte array into a ResourceHeader
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled ResourceHeader on success, null on error
+ public static ResourceHeader ParseResourceHeader(this byte[] data, ref int offset)
+ {
+ // Read in the table
+ var obj = new ResourceHeader();
+
+ obj.DataSize = data.ReadUInt32LittleEndian(ref offset);
+ obj.HeaderSize = data.ReadUInt32LittleEndian(ref offset);
+ obj.ResourceType = (ResourceType)data.ReadUInt32LittleEndian(ref offset); // TODO: Could be a string too
+ obj.Name = data.ReadUInt32LittleEndian(ref offset); // TODO: Could be a string too
+ obj.DataVersion = data.ReadUInt32LittleEndian(ref offset);
+ obj.MemoryFlags = (MemoryFlags)data.ReadUInt16LittleEndian(ref offset);
+ obj.LanguageId = data.ReadUInt16LittleEndian(ref offset);
+ obj.Version = data.ReadUInt32LittleEndian(ref offset);
+ obj.Characteristics = data.ReadUInt32LittleEndian(ref offset);
+
+ return obj;
}
#endregion
diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
index aa4597a8..534d5d03 100644
--- a/SabreTools.Serialization/Wrappers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
@@ -1036,7 +1036,7 @@ namespace SabreTools.Serialization.Wrappers
// NB10
if (signature == 0x3031424E)
{
- var nb10ProgramDatabase = entryData.AsNB10ProgramDatabase(ref offset);
+ var nb10ProgramDatabase = entryData.ParseNB10ProgramDatabase(ref offset);
if (nb10ProgramDatabase != null)
{
_debugData[i] = nb10ProgramDatabase;
@@ -1047,7 +1047,7 @@ namespace SabreTools.Serialization.Wrappers
// RSDS
else if (signature == 0x53445352)
{
- var rsdsProgramDatabase = entryData.AsRSDSProgramDatabase(ref offset);
+ var rsdsProgramDatabase = entryData.ParseRSDSProgramDatabase(ref offset);
if (rsdsProgramDatabase != null)
{
_debugData[i] = rsdsProgramDatabase;