Fix resource table issues with NE

This commit is contained in:
Matt Nadareski
2024-05-12 11:46:05 -04:00
parent d41a0045cb
commit 66da74e00a
3 changed files with 24 additions and 25 deletions

View File

@@ -76,7 +76,7 @@ namespace SabreTools.Serialization.Deserializers
// If the offset for the segment table doesn't exist
tableAddress = initialOffset
+ (int)stub.Header.NewExeHeaderAddr
+ executableHeader.SegmentTableOffset;
+ executableHeader.ResourceTableOffset;
if (tableAddress >= data.Length)
return executable;
@@ -262,7 +262,7 @@ namespace SabreTools.Serialization.Deserializers
/// <param name="data">Stream to parse</param>
/// <param name="count">Number of resource table entries to read</param>
/// <returns>Filled resource table on success, null on error</returns>
public static ResourceTable? ParseResourceTable(Stream data, int count)
public static ResourceTable? ParseResourceTable(Stream data, ushort count)
{
long initialOffset = data.Position;
@@ -270,13 +270,23 @@ namespace SabreTools.Serialization.Deserializers
var resourceTable = new ResourceTable();
resourceTable.AlignmentShiftCount = data.ReadUInt16();
resourceTable.ResourceTypes = new ResourceTypeInformationEntry[count];
for (int i = 0; i < resourceTable.ResourceTypes.Length; i++)
var resourceTypes = new List<ResourceTypeInformationEntry>();
for (int i = 0; i < count; i++)
{
var entry = new ResourceTypeInformationEntry();
entry.TypeID = data.ReadUInt16();
entry.ResourceCount = data.ReadUInt16();
entry.Reserved = data.ReadUInt32();
// A zero type ID marks the end of the resource type information blocks.
if (entry.TypeID == 0)
{
resourceTypes.Add(entry);
break;
}
entry.Resources = new ResourceTypeResourceEntry[entry.ResourceCount];
for (int j = 0; j < entry.ResourceCount; j++)
{
@@ -287,20 +297,23 @@ namespace SabreTools.Serialization.Deserializers
entry.Resources[j] = resource;
}
resourceTable.ResourceTypes[i] = entry;
resourceTypes.Add(entry);
}
resourceTable.ResourceTypes = [.. resourceTypes];
// Get the full list of unique string offsets
var stringOffsets = resourceTable.ResourceTypes
.Where(rt => rt != null)
.Where(rt => rt!.IsIntegerType() == false)
.Where(rt => !rt!.IsIntegerType() && rt!.TypeID != 0)
.Select(rt => rt!.TypeID)
.Union(resourceTable.ResourceTypes
.Where(rt => rt != null)
.Where(rt => rt != null && rt!.TypeID != 0)
.SelectMany(rt => rt!.Resources ?? [])
.Where(r => r!.IsIntegerType() == false)
.Where(r => !r!.IsIntegerType())
.Select(r => r!.ResourceID))
.Distinct()
.Where(o => o != 0)
.OrderBy(o => o)
.ToList();

View File

@@ -9,13 +9,8 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource type information entry to check</param>
/// <returns>True if the entry is an integer type, false if an offset, null on error</returns>
public static bool? IsIntegerType(this ResourceTypeInformationEntry entry)
public static bool IsIntegerType(this ResourceTypeInformationEntry entry)
{
// We can't do anything with an invalid entry
if (entry == null)
return null;
// If the highest order bit is set, it's an integer type
return (entry.TypeID & 0x8000) != 0;
}
@@ -24,13 +19,8 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource type resource entry to check</param>
/// <returns>True if the entry is an integer type, false if an offset, null on error</returns>
public static bool? IsIntegerType(this ResourceTypeResourceEntry entry)
public static bool IsIntegerType(this ResourceTypeResourceEntry entry)
{
// We can't do anything with an invalid entry
if (entry == null)
return null;
// If the highest order bit is set, it's an integer type
return (entry.ResourceID & 0x8000) != 0;
}
@@ -41,10 +31,6 @@ namespace SabreTools.Serialization
/// <returns>SegmentEntryType corresponding to the type</returns>
public static SegmentEntryType GetEntryType(this EntryTableBundle entry)
{
// We can't do anything with an invalid entry
if (entry == null)
return SegmentEntryType.Unused;
// Determine the entry type based on segment indicator
if (entry.SegmentIndicator == 0x00)
return SegmentEntryType.Unused;

View File

@@ -188,7 +188,7 @@ namespace SabreTools.Serialization.Printers
{
// TODO: If not integer type, print out name
var resource = entry.Resources[j];
builder.AppendLine($" Resource Entry {i}");
builder.AppendLine($" Resource Entry {j}");
if (resource == null)
{
builder.AppendLine(" [NULL]");