diff --git a/SabreTools.Serialization/Extensions/PortableExecutable.cs b/SabreTools.Serialization/Extensions/PortableExecutable.cs
index e2e6f34d..8f35f19e 100644
--- a/SabreTools.Serialization/Extensions/PortableExecutable.cs
+++ b/SabreTools.Serialization/Extensions/PortableExecutable.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using SabreTools.Data.Models.COFF;
using SabreTools.Data.Models.PortableExecutable;
using SabreTools.IO.Extensions;
@@ -148,38 +147,6 @@ namespace SabreTools.Data.Extensions
// 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 string table resource
- ///
- /// Resource data entry to parse into a string table resource
- /// A filled string table resource on success, null on error
- /// TODO: Create concrete type for this and inherit from ResourceDataType
- public static Dictionary? AsStringTable(this Models.PortableExecutable.Resource.DataEntry? entry)
- {
- // If we have an invalid entry, just skip
- if (entry?.Data is null)
- return null;
-
- // Initialize the iterators
- int offset = 0, stringIndex = 0;
-
- // Create the output table
- var stringTable = new Dictionary();
-
- // Loop through and add
- while (offset < entry.Data.Length)
- {
- string? stringValue = entry.Data.ReadPrefixedUnicodeString(ref offset);
- if (stringValue is not null)
- {
- stringValue = stringValue.Replace("\n", "\\n").Replace("\r", newValue: "\\r");
- stringTable[stringIndex++] = stringValue;
- }
- }
-
- return stringTable;
- }
-
///
/// Parse a byte array into a ResourceHeader
///
diff --git a/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/StringTableResource.cs b/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/StringTableResource.cs
new file mode 100644
index 00000000..9765c6b8
--- /dev/null
+++ b/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/StringTableResource.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace SabreTools.Data.Models.PortableExecutable.Resource.Entries
+{
+ ///
+ /// Represents a string table resource
+ ///
+ public sealed class StringTableResource : ResourceDataType
+ {
+ ///
+ /// Set of integer-keyed values
+ ///
+ public Dictionary Values { get; set; } = [];
+ }
+}
diff --git a/SabreTools.Serialization/Readers/PortableExecutable.cs b/SabreTools.Serialization/Readers/PortableExecutable.cs
index bd60f3af..be24fcaa 100644
--- a/SabreTools.Serialization/Readers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Readers/PortableExecutable.cs
@@ -122,7 +122,7 @@ namespace SabreTools.Serialization.Readers
// Set the symbol and string tables
pex.SymbolTable = ParseSymbolTable(data, fileHeader.NumberOfSymbols);
- pex.StringTable = ParseStringTable(data);
+ pex.StringTable = ParseCOFFStringTable(data);
}
#endregion
@@ -2739,7 +2739,7 @@ namespace SabreTools.Serialization.Readers
var stringFileInfoChildren = new List();
while ((offset - currentOffset) < obj.Length)
{
- var stringTable = ParseStringTableResource(data, ref offset, currentOffset);
+ var stringTable = ParseFileInfoStringTable(data, ref offset, currentOffset);
stringFileInfoChildren.Add(stringTable);
}
@@ -2781,11 +2781,11 @@ namespace SabreTools.Serialization.Readers
}
///
- /// Parse a Stream into a StringTable
+ /// Parse a Stream into a COFF StringTable
///
/// Stream to parse
/// Filled StringTable on success, null on error
- public static StringTable ParseStringTable(Stream data)
+ public static StringTable ParseCOFFStringTable(Stream data)
{
var obj = new StringTable();
@@ -2810,12 +2810,12 @@ namespace SabreTools.Serialization.Readers
}
///
- /// Read byte data as a StringTable resource
+ /// Read byte data as a FileInfo StringTable
///
/// Byte array to parse
/// Offset into the byte array
/// A filled StringTable resource on success, null on error
- public static Data.Models.PortableExecutable.Resource.Entries.StringTable ParseStringTableResource(byte[] data, ref int offset, int initialOffset)
+ public static Data.Models.PortableExecutable.Resource.Entries.StringTable ParseFileInfoStringTable(byte[] data, ref int offset, int initialOffset)
{
var obj = new Data.Models.PortableExecutable.Resource.Entries.StringTable();
@@ -2841,6 +2841,34 @@ namespace SabreTools.Serialization.Readers
return obj;
}
+ ///
+ /// Read byte data as a StringTableResource
+ ///
+ /// Byte array to parse
+ /// Offset into the byte array
+ /// A filled StringTableResource resource on success, null on error
+ public static Data.Models.PortableExecutable.Resource.Entries.StringTableResource? ParseStringTableResource(byte[] data)
+ {
+ // Initialize the iterators
+ int offset = 0, stringIndex = 0;
+
+ // Create the output table
+ var obj = new Data.Models.PortableExecutable.Resource.Entries.StringTableResource();
+
+ // Loop through and add
+ while (offset < data.Length)
+ {
+ string? stringValue = data.ReadPrefixedUnicodeString(ref offset);
+ if (stringValue is not null)
+ {
+ stringValue = stringValue.Replace("\n", "\\n").Replace("\r", newValue: "\\r");
+ obj.Values[stringIndex++] = stringValue;
+ }
+ }
+
+ return obj;
+ }
+
///
/// Parse a Stream into a symbol table
///
diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.Printing.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.Printing.cs
index dd1e41b1..f5bf979f 100644
--- a/SabreTools.Serialization/Wrappers/PortableExecutable.Printing.cs
+++ b/SabreTools.Serialization/Wrappers/PortableExecutable.Printing.cs
@@ -1284,8 +1284,8 @@ namespace SabreTools.Serialization.Wrappers
{
string padding = new(' ', (level + 1) * 2);
- Dictionary? stringTable = null;
- try { stringTable = entry.AsStringTable(); } catch { }
+ StringTableResource? stringTable = null;
+ try { stringTable = Readers.PortableExecutable.ParseStringTableResource(entry.Data); } catch { }
if (stringTable is null)
{
@@ -1293,7 +1293,7 @@ namespace SabreTools.Serialization.Wrappers
return;
}
- foreach (var kvp in stringTable)
+ foreach (var kvp in stringTable.Values)
{
int index = kvp.Key;
string? stringValue = kvp.Value;
diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
index 83b605c2..97d77549 100644
--- a/SabreTools.Serialization/Wrappers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
@@ -1894,7 +1894,7 @@ namespace SabreTools.Serialization.Wrappers
value = Readers.PortableExecutable.ParseDialogBoxResource(entry.Data);
break;
case ResourceType.RT_STRING:
- value = entry.AsStringTable();
+ value = Readers.PortableExecutable.ParseStringTableResource(entry.Data);
break;
case ResourceType.RT_FONTDIR:
value = entry.Data;