diff --git a/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/GenericResourceEntry.cs b/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/GenericResourceEntry.cs index 027627ee..73c22676 100644 --- a/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/GenericResourceEntry.cs +++ b/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/GenericResourceEntry.cs @@ -3,7 +3,7 @@ namespace SabreTools.Data.Models.PortableExecutable.Resource.Entries /// /// Generic or unparsed resource data /// - public abstract class GenericResourceEntry : ResourceDataType + public class GenericResourceEntry : ResourceDataType { /// /// Unparsed byte data from the resource diff --git a/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/StringTableResource.cs b/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/StringTableResource.cs index 9765c6b8..c2293180 100644 --- a/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/StringTableResource.cs +++ b/SabreTools.Serialization/Models/PortableExecutable/Resource/Entries/StringTableResource.cs @@ -10,6 +10,6 @@ namespace SabreTools.Data.Models.PortableExecutable.Resource.Entries /// /// Set of integer-keyed values /// - public Dictionary Values { get; set; } = []; + public Dictionary Data { get; set; } = []; } } diff --git a/SabreTools.Serialization/Readers/PortableExecutable.cs b/SabreTools.Serialization/Readers/PortableExecutable.cs index c082a72f..93c4edd3 100644 --- a/SabreTools.Serialization/Readers/PortableExecutable.cs +++ b/SabreTools.Serialization/Readers/PortableExecutable.cs @@ -1606,6 +1606,21 @@ namespace SabreTools.Serialization.Readers return obj; } + /// + /// Parse a byte array into a GenericResourceEntry + /// + /// Data to parse + /// Offset into the byte array + /// A filled GenericResourceEntry on success, null on error + public static Data.Models.PortableExecutable.Resource.Entries.GenericResourceEntry ParseGenericResourceEntry(byte[] data) + { + var obj = new Data.Models.PortableExecutable.Resource.Entries.GenericResourceEntry(); + + obj.Data = data; + + return obj; + } + /// /// Parse a Stream into a HintNameTable /// @@ -2930,7 +2945,7 @@ namespace SabreTools.Serialization.Readers if (stringValue is not null) { stringValue = stringValue.Replace("\n", "\\n").Replace("\r", newValue: "\\r"); - obj.Values[stringIndex++] = stringValue; + obj.Data[stringIndex++] = stringValue; } } diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.Extraction.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.Extraction.cs index d503478a..0e1e7a78 100644 --- a/SabreTools.Serialization/Wrappers/PortableExecutable.Extraction.cs +++ b/SabreTools.Serialization/Wrappers/PortableExecutable.Extraction.cs @@ -362,7 +362,7 @@ namespace SabreTools.Serialization.Wrappers string resourceKey = kvp.Key; var value = kvp.Value; - if (value is null || value is not byte[] ba || ba.Length == 0) + if (value is null || value is not Data.Models.PortableExecutable.Resource.Entries.GenericResourceEntry ba || ba.Data.Length == 0) continue; // Set the output variables @@ -370,10 +370,10 @@ namespace SabreTools.Serialization.Wrappers string extension = string.Empty; // Only process the resource if it a recognized signature - for (; resourceOffset < 0x400 && resourceOffset < ba.Length - 0x10; resourceOffset++) + for (; resourceOffset < 0x400 && resourceOffset < ba.Data.Length - 0x10; resourceOffset++) { int temp = resourceOffset; - byte[] resourceSample = ba.ReadBytes(ref temp, 0x10); + byte[] resourceSample = ba.Data.ReadBytes(ref temp, 0x10); if (resourceSample.StartsWith(Data.Models.SevenZip.Constants.SignatureBytes)) { @@ -506,7 +506,7 @@ namespace SabreTools.Serialization.Wrappers // Write the resource data to a temp file using var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); - tempStream.Write(ba, resourceOffset, ba.Length - resourceOffset); + tempStream.Write(ba.Data, resourceOffset, ba.Data.Length - resourceOffset); tempStream.Flush(); } catch (Exception ex) diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.Printing.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.Printing.cs index f5bf979f..9e79d194 100644 --- a/SabreTools.Serialization/Wrappers/PortableExecutable.Printing.cs +++ b/SabreTools.Serialization/Wrappers/PortableExecutable.Printing.cs @@ -1293,7 +1293,7 @@ namespace SabreTools.Serialization.Wrappers return; } - foreach (var kvp in stringTable.Values) + foreach (var kvp in stringTable.Data) { int index = kvp.Key; string? stringValue = kvp.Value; diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.cs index 29d49472..38e28963 100644 --- a/SabreTools.Serialization/Wrappers/PortableExecutable.cs +++ b/SabreTools.Serialization/Wrappers/PortableExecutable.cs @@ -595,7 +595,7 @@ namespace SabreTools.Serialization.Wrappers /// /// Dictionary of resource data /// - public Dictionary ResourceData + public Dictionary ResourceData { get { @@ -1122,7 +1122,7 @@ namespace SabreTools.Serialization.Wrappers /// /// Cached resource data /// - private readonly Dictionary _resourceData = []; + private readonly Dictionary _resourceData = []; /// /// Lock object for @@ -1588,22 +1588,22 @@ namespace SabreTools.Serialization.Wrappers /// /// String entry to check for /// List of matching resources - public List?> FindStringTableByEntry(string entry) + public List FindStringTableByEntry(string entry) { // Cache the resource data for easier reading var resourceData = ResourceData; if (resourceData.Count == 0) return []; - var stringTables = new List?>(); + var stringTables = new List(); foreach (var resource in resourceData.Values) { if (resource is null) continue; - if (resource is not Dictionary st || st is null) + if (resource is not StringTableResource st || st is null) continue; - foreach (string? s in st.Values) + foreach (string? s in st.Data.Values) { #if NETFRAMEWORK || NETSTANDARD if (s is null || !s.Contains(entry)) @@ -1637,10 +1637,10 @@ namespace SabreTools.Serialization.Wrappers { if (!kvp.Key.Contains(typeName)) continue; - if (kvp.Value is null || kvp.Value is not byte[] b || b is null) + if (kvp.Value is null || kvp.Value is not GenericResourceEntry b || b is null) continue; - resources.Add(b); + resources.Add(b.Data); } return resources; @@ -1663,15 +1663,15 @@ namespace SabreTools.Serialization.Wrappers { if (resource is null) continue; - if (resource is not byte[] b || b is null) + if (resource is not GenericResourceEntry b || b is null) continue; try { - string? arrayAsASCII = Encoding.ASCII.GetString(b!); + string? arrayAsASCII = Encoding.ASCII.GetString(b!.Data); if (arrayAsASCII.Contains(value)) { - resources.Add(b); + resources.Add(b.Data); continue; } } @@ -1679,10 +1679,10 @@ namespace SabreTools.Serialization.Wrappers try { - string? arrayAsUTF8 = Encoding.UTF8.GetString(b!); + string? arrayAsUTF8 = Encoding.UTF8.GetString(b!.Data); if (arrayAsUTF8.Contains(value)) { - resources.Add(b); + resources.Add(b.Data); continue; } } @@ -1690,10 +1690,10 @@ namespace SabreTools.Serialization.Wrappers try { - string? arrayAsUnicode = Encoding.Unicode.GetString(b!); + string? arrayAsUnicode = Encoding.Unicode.GetString(b!.Data); if (arrayAsUnicode.Contains(value)) { - resources.Add(b); + resources.Add(b.Data); continue; } } @@ -1770,9 +1770,9 @@ namespace SabreTools.Serialization.Wrappers bool exeResources = false; foreach (var kvp in resourceData) { - if (kvp.Value is null || kvp.Value is not byte[] ba) + if (kvp.Value is null || kvp.Value is not GenericResourceEntry ba) continue; - if (!ba.StartsWith(Data.Models.MSDOS.Constants.SignatureBytes)) + if (!ba.Data.StartsWith(Data.Models.MSDOS.Constants.SignatureBytes)) continue; exeResources = true; @@ -1866,7 +1866,7 @@ namespace SabreTools.Serialization.Wrappers // Create the key and value objects string key = string.Join(", ", Array.ConvertAll([.. types], t => t.ToString())); - object? value = entry.Data; + ResourceDataType? value = Readers.PortableExecutable.ParseGenericResourceEntry(entry.Data); // If we have a known resource type if (types.Count > 0 && types[0] is uint resourceType) @@ -1876,14 +1876,14 @@ namespace SabreTools.Serialization.Wrappers switch ((ResourceType)resourceType) { case ResourceType.RT_CURSOR: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_BITMAP: case ResourceType.RT_NEWBITMAP: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_ICON: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_MENU: case ResourceType.RT_NEWMENU: @@ -1897,47 +1897,47 @@ namespace SabreTools.Serialization.Wrappers value = Readers.PortableExecutable.ParseStringTableResource(entry.Data); break; case ResourceType.RT_FONTDIR: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_FONT: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_ACCELERATOR: value = Readers.PortableExecutable.ParseAcceleratorTable(entry.Data); break; case ResourceType.RT_RCDATA: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_MESSAGETABLE: value = Readers.PortableExecutable.ParseMessageResourceData(entry.Data); break; case ResourceType.RT_GROUP_CURSOR: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_GROUP_ICON: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_VERSION: _versionInfo = Readers.PortableExecutable.ParseVersionInfo(entry.Data); value = _versionInfo; break; case ResourceType.RT_DLGINCLUDE: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_PLUGPLAY: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_VXD: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_ANICURSOR: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_ANIICON: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_HTML: - value = entry.Data; + // TODO: Implement specific parsing break; case ResourceType.RT_MANIFEST: _assemblyManifest = Readers.PortableExecutable.ParseAssemblyManifest(entry.Data); @@ -1950,25 +1950,25 @@ namespace SabreTools.Serialization.Wrappers // Error state, ignore case ResourceType.RT_ERROR: - value = entry.Data; + // TODO: Implement specific parsing break; default: - value = entry.Data; + // TODO: Implement specific parsing break; } } catch { // Fall back on byte array data for malformed items - value = entry.Data; + value = Readers.PortableExecutable.ParseGenericResourceEntry(entry.Data); } } // If we have a custom resource type else if (types.Count > 0 && types[0] is string) { - value = entry.Data; + value = Readers.PortableExecutable.ParseGenericResourceEntry(entry.Data); } // Add the key and value to the cache