diff --git a/BinaryObjectScanner/FileType/MicrosoftCAB.cs b/BinaryObjectScanner/FileType/MicrosoftCAB.cs
index e81b04ba..d9a148b7 100644
--- a/BinaryObjectScanner/FileType/MicrosoftCAB.cs
+++ b/BinaryObjectScanner/FileType/MicrosoftCAB.cs
@@ -43,7 +43,7 @@ namespace BinaryObjectScanner.FileType
{
// Decompress the blocks, if possible
var folder = cabArchive.Model.Folders[f];
- var ms = DecompressBlocks(cabArchive, folder);
+ var ms = DecompressBlocks(cabArchive, folder, f);
if (ms == null || ms.Length == 0)
continue;
@@ -121,19 +121,20 @@ namespace BinaryObjectScanner.FileType
///
/// Decompress all blocks for a folder
///
- private MemoryStream? DecompressBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, CFFOLDER? folder)
+ private MemoryStream? DecompressBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, CFFOLDER? folder, int folderIndex)
{
// Ensure data blocks
- if (folder?.DataBlocks == null || folder.DataBlocks.Length == 0)
+ var dataBlocks = GetDataBlocks(cabArchive, folder, folderIndex);
+ if (dataBlocks == null || dataBlocks.Length == 0)
return null;
// Setup decompressors
var mszip = SabreTools.Compression.MSZIP.Decompressor.Create();
- uint quantumWindowBits = (uint)(((ushort)folder.CompressionType >> 8) & 0x1f);
+ uint quantumWindowBits = (uint)(((ushort)folder!.CompressionType >> 8) & 0x1f);
// Loop through the data blocks
var ms = new MemoryStream();
- foreach (var db in folder.DataBlocks)
+ foreach (var db in dataBlocks)
{
if (db?.CompressedData == null)
continue;
@@ -177,6 +178,36 @@ namespace BinaryObjectScanner.FileType
return ms;
}
+ ///
+ /// Get the set of data blocks for a folder
+ ///
+ private CFDATA[]? GetDataBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, CFFOLDER? folder, int folderIndex)
+ {
+ // Skip invalid folders
+ if (folder?.DataBlocks == null || folder.DataBlocks.Length == 0)
+ return null;
+
+ // Get all files for the folder
+ var files = GetFiles(cabArchive, folderIndex);
+ if (files.Length == 0)
+ return folder.DataBlocks;
+
+ // Check if the folder spans backward
+ if (Array.Exists(files, f => f.FolderIndex == FolderIndex.CONTINUED_FROM_PREV || f.FolderIndex == FolderIndex.CONTINUED_PREV_AND_NEXT))
+ {
+ // TODO: Get the list of blocks from the last folder in the previous cabinet
+ }
+
+ // Check if the folder spans forward
+ if (Array.Exists(files, f => f.FolderIndex == FolderIndex.CONTINUED_TO_NEXT || f.FolderIndex == FolderIndex.CONTINUED_PREV_AND_NEXT))
+ {
+ // TODO: Get the list of blocks from the first folder in the next cabinet
+ }
+
+ // Return all found blocks
+ return [.. folder.DataBlocks];
+ }
+
///
/// Get all files for the current folder index
///