mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-09-22 14:55:11 +00:00
Do the same for string table resource
This commit is contained in:
@@ -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
|
||||
|
||||
/// <summary>
|
||||
/// Read resource data as a string table resource
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into a string table resource</param>
|
||||
/// <returns>A filled string table resource on success, null on error</returns>
|
||||
/// TODO: Create concrete type for this and inherit from ResourceDataType
|
||||
public static Dictionary<int, string?>? 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<int, string?>();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a byte array into a ResourceHeader
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SabreTools.Data.Models.PortableExecutable.Resource.Entries
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a string table resource
|
||||
/// </summary>
|
||||
public sealed class StringTableResource : ResourceDataType
|
||||
{
|
||||
/// <summary>
|
||||
/// Set of integer-keyed values
|
||||
/// </summary>
|
||||
public Dictionary<int, string?> Values { get; set; } = [];
|
||||
}
|
||||
}
|
||||
@@ -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<Data.Models.PortableExecutable.Resource.Entries.StringTable>();
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into a StringTable
|
||||
/// Parse a Stream into a COFF StringTable
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <returns>Filled StringTable on success, null on error</returns>
|
||||
public static StringTable ParseStringTable(Stream data)
|
||||
public static StringTable ParseCOFFStringTable(Stream data)
|
||||
{
|
||||
var obj = new StringTable();
|
||||
|
||||
@@ -2810,12 +2810,12 @@ namespace SabreTools.Serialization.Readers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read byte data as a StringTable resource
|
||||
/// Read byte data as a FileInfo StringTable
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array to parse</param>
|
||||
/// <param name="offset">Offset into the byte array</param>
|
||||
/// <returns>A filled StringTable resource on success, null on error</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read byte data as a StringTableResource
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array to parse</param>
|
||||
/// <param name="offset">Offset into the byte array</param>
|
||||
/// <returns>A filled StringTableResource resource on success, null on error</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into a symbol table
|
||||
/// </summary>
|
||||
|
||||
@@ -1284,8 +1284,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
Dictionary<int, string?>? 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user