diff --git a/SabreTools.Serialization/Deserializers/PortableExecutable.cs b/SabreTools.Serialization/Deserializers/PortableExecutable.cs
index a1aea612..4e93012e 100644
--- a/SabreTools.Serialization/Deserializers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Deserializers/PortableExecutable.cs
@@ -172,7 +172,54 @@ namespace SabreTools.Serialization.Deserializers
data.Seek(offset, SeekOrigin.Begin);
// Set the resource directory table
- pex.ResourceDirectoryTable = ParseResourceDirectoryTable(data, initialOffset, data.Position, pex.SectionTable, true);
+ long tableStart = data.Position;
+ pex.ResourceDirectoryTable = ParseResourceDirectoryTable(data, initialOffset, tableStart, pex.SectionTable);
+
+ // TODO: Revisit the logic for this
+ // - Don't check for signatures, just read anything that's there
+ // - If alignment is used, use the one from the optional header
+ #region Hidden Resources
+
+ // Get the section size
+ int tableSize = (int)optionalHeader.ResourceTable.Size;
+
+ // Align to the 512-byte boundary, we find the start of an MS-DOS header, or the end of the file
+ while (data.Position - tableStart < tableSize && data.Position % 0x200 != 0 && data.Position < data.Length - 1)
+ {
+ // If we find the start of an MS-DOS header
+ if (data.ReadUInt16LittleEndian() == Models.MSDOS.Constants.SignatureUInt16)
+ {
+ data.Seek(-2, origin: SeekOrigin.Current);
+ break;
+ }
+
+ // Otherwise
+ data.Seek(-1, origin: SeekOrigin.Current);
+ }
+
+ // If we have not used up the full size, parse the remaining chunk as a single resource
+ if (pex.ResourceDirectoryTable != null && data.Position - tableStart < tableSize)
+ {
+ var localEntries = pex.ResourceDirectoryTable.Entries ?? [];
+ Array.Resize(ref localEntries, localEntries.Length + 1);
+ pex.ResourceDirectoryTable.Entries = localEntries;
+ int length = (int)(tableSize - (data.Position - tableStart));
+
+ pex.ResourceDirectoryTable.Entries[localEntries.Length] = new ResourceDirectoryEntry
+ {
+ Name = new ResourceDirectoryString { UnicodeString = Encoding.Unicode.GetBytes("HIDDEN RESOURCE") },
+ IntegerID = uint.MaxValue,
+ DataEntryOffset = (uint)data.Position,
+ DataEntry = new ResourceDataEntry
+ {
+ Size = (uint)length,
+ Data = data.ReadBytes(length),
+ Codepage = (uint)Encoding.Unicode.CodePage,
+ },
+ };
+ }
+
+ #endregion
}
}
@@ -1496,9 +1543,11 @@ namespace SabreTools.Serialization.Deserializers
/// Initial offset to use in address comparisons
/// Table start address for relative reads
/// Section table to use for virtual address translation
- /// Indicates if this is the top level or not
/// Filled ResourceDirectoryTable on success, null on error
- public static ResourceDirectoryTable? ParseResourceDirectoryTable(Stream data, long initialOffset, long tableStart, SectionHeader[] sections, bool topLevel = false)
+ public static ResourceDirectoryTable? ParseResourceDirectoryTable(Stream data,
+ long initialOffset,
+ long tableStart,
+ SectionHeader[] sections)
{
var obj = new ResourceDirectoryTable();
@@ -1534,7 +1583,7 @@ namespace SabreTools.Serialization.Deserializers
if (offset > tableStart && offset < data.Length)
{
data.Seek(offset, SeekOrigin.Begin);
- entry.DataEntry = ParseResourceDataEntry(data, initialOffset, sections);;
+ entry.DataEntry = ParseResourceDataEntry(data, initialOffset, sections); ;
}
}
else if (entry.SubdirectoryOffset > 0)
@@ -1548,63 +1597,6 @@ namespace SabreTools.Serialization.Deserializers
}
}
- // If we are not at the top level
- if (!topLevel)
- return obj;
-
- // TODO: Revisit the logic for this
- // - Use the table boundaries not the section ones
- // - Don't check for signatures, just read anything that's there
- // - If alignment is used, use the one from the optional header
- // - Should this be moved out of this method entirely?
- #region Hidden Resources
-
- // If we're not aligned to a section
- var firstSection = Array.Find(sections, s => s != null && s.PointerToRawData == tableStart);
- if (firstSection == null)
- return obj;
-
- // Get the section size
- int size = (int)firstSection.SizeOfRawData;
-
- // Align to the 512-byte boundary, we find the start of an MS-DOS header, or the end of the file
- while (data.Position - tableStart < size && data.Position % 0x200 != 0 && data.Position < data.Length - 1)
- {
- // If we find the start of an MS-DOS header
- if (data.ReadUInt16LittleEndian() == Models.MSDOS.Constants.SignatureUInt16)
- {
- data.Seek(-2, origin: SeekOrigin.Current);
- break;
- }
-
- // Otherwise
- data.Seek(-1, origin: SeekOrigin.Current);
- }
-
- // If we have not used up the full size, parse the remaining chunk as a single resource
- if (data.Position - tableStart < size)
- {
- var localEntries = obj.Entries;
- Array.Resize(ref localEntries, totalEntryCount + 1);
- obj.Entries = localEntries;
- int length = (int)(size - (data.Position - tableStart));
-
- obj.Entries[totalEntryCount] = new ResourceDirectoryEntry
- {
- Name = new ResourceDirectoryString { UnicodeString = Encoding.Unicode.GetBytes("HIDDEN RESOURCE") },
- IntegerID = uint.MaxValue,
- DataEntryOffset = (uint)data.Position,
- DataEntry = new ResourceDataEntry
- {
- Size = (uint)length,
- Data = data.ReadBytes(length),
- Codepage = (uint)Encoding.Unicode.CodePage,
- },
- };
- }
-
- #endregion
-
return obj;
}