diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.Extraction.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.Extraction.cs
index 8dda12e9..fb642ead 100644
--- a/SabreTools.Serialization/Wrappers/PortableExecutable.Extraction.cs
+++ b/SabreTools.Serialization/Wrappers/PortableExecutable.Extraction.cs
@@ -397,9 +397,8 @@ namespace SabreTools.Serialization.Wrappers
return ExtractWiseOverlay(outputDirectory, includeDebug, source, offset);
// Try to find the section header
- var section = FindWiseSection();
- if (section != null)
- return ExtractWiseSection(outputDirectory, includeDebug, source, section);
+ if (WiseSection != null)
+ return ExtractWiseSection(outputDirectory, includeDebug, source);
// Everything else could not extract
return false;
@@ -527,23 +526,10 @@ namespace SabreTools.Serialization.Wrappers
/// Potentially multi-part stream to read
/// Wise section information
/// True if extraction succeeded, false otherwise
- private bool ExtractWiseSection(string outputDirectory, bool includeDebug, Stream source, Models.PortableExecutable.SectionHeader section)
+ private bool ExtractWiseSection(string outputDirectory, bool includeDebug, Stream source)
{
- // Get the offset
- long offset = section.VirtualAddress.ConvertVirtualAddress(SectionTable);
- if (offset < 0 || offset >= source.Length)
- return false;
-
- // Read the section into a local array
- int sectionLength = (int)section.VirtualSize;
- byte[]? sectionData;
- lock (source)
- {
- sectionData = source.ReadFrom(offset, sectionLength, retainPosition: true);
- }
-
- // Parse the section header
- var header = WiseSectionHeader.Create(sectionData, 0);
+ // Get the section header
+ var header = WiseSection;
if (header == null)
{
if (includeDebug) Console.Error.WriteLine("Could not parse the section header");
diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
index 6d88d434..709decd6 100644
--- a/SabreTools.Serialization/Wrappers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
@@ -491,6 +491,71 @@ namespace SabreTools.Serialization.Wrappers
}
}
+ ///
+ /// Wise section wrapper, if it exists
+ ///
+ public WiseSectionHeader? WiseSection
+ {
+ get
+ {
+ lock (_wiseSectionHeaderLock)
+ {
+ // If we already have cached data, just use that immediately
+ if (_wiseSectionHeader != null)
+ return _wiseSectionHeader;
+
+ // If the header will not be found due to missing section data
+ if (_wiseSectionHeaderMissing)
+ return null;
+
+ // If the section table is invalid
+ if (SectionTable == null)
+ {
+ _wiseSectionHeaderMissing = true;
+ return null;
+ }
+
+ // Find the .WISE section
+ SectionHeader? wiseSection = null;
+ foreach (var section in SectionTable)
+ {
+ string sectionName = Encoding.ASCII.GetString(section.Name ?? []).TrimEnd('\0');
+ if (sectionName != ".WISE")
+ continue;
+
+ wiseSection = section;
+ break;
+ }
+
+ // If the section cannot be found
+ if (wiseSection == null)
+ {
+ _wiseSectionHeaderMissing = true;
+ return null;
+ }
+
+ // Get the physical offset of the section
+ long offset = wiseSection.VirtualAddress.ConvertVirtualAddress(SectionTable);
+ if (offset < 0 || offset >= Length)
+ {
+ _wiseSectionHeaderMissing = true;
+ return null;
+ }
+
+ // Read the section into a local array
+ int sectionLength = (int)wiseSection.VirtualSize;
+ byte[]? sectionData = ReadRangeFromSource(offset, sectionLength);
+
+ // Parse the section header
+ _wiseSectionHeader = WiseSectionHeader.Create(sectionData, 0);
+ if (_wiseSectionHeader == null)
+ _wiseSectionHeaderMissing = true;
+
+ return _wiseSectionHeader;
+ }
+ }
+ }
+
#region Version Information
///
@@ -815,6 +880,21 @@ namespace SabreTools.Serialization.Wrappers
///
private readonly List?[] _tableStringData = new List?[16];
+ ///
+ /// Wise section wrapper, if it exists
+ ///
+ private WiseSectionHeader? _wiseSectionHeader = null;
+
+ ///
+ /// Lock object for
+ ///
+ private readonly object _wiseSectionHeaderLock = new();
+
+ ///
+ /// Indicates if cannot be found
+ ///
+ private bool _wiseSectionHeaderMissing = false;
+
#region Version Information
///
@@ -1446,30 +1526,6 @@ namespace SabreTools.Serialization.Wrappers
}
}
- ///
- /// Find the location of a Wise section, if it exists
- ///
- /// Wise section on success, null otherwise
- public SectionHeader? FindWiseSection()
- {
- // If the section table is invalid
- if (SectionTable == null)
- return null;
-
- // Find the .WISE section
- foreach (var section in SectionTable)
- {
- string sectionName = Encoding.ASCII.GetString(section.Name ?? []).TrimEnd('\0');
- if (sectionName != ".WISE")
- continue;
-
- return section;
- }
-
- // Otherwise, it could not be found
- return null;
- }
-
#endregion
#region Resource Parsing