diff --git a/BinaryObjectScanner/FileType/MicrosoftCAB.cs b/BinaryObjectScanner/FileType/MicrosoftCAB.cs
index d9a148b7..c5eb0da7 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, f);
+ var ms = DecompressBlocks(cabArchive, file, folder, f);
if (ms == null || ms.Length == 0)
continue;
@@ -121,10 +121,10 @@ namespace BinaryObjectScanner.FileType
///
/// Decompress all blocks for a folder
///
- private MemoryStream? DecompressBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, CFFOLDER? folder, int folderIndex)
+ private MemoryStream? DecompressBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, string file, CFFOLDER? folder, int folderIndex)
{
// Ensure data blocks
- var dataBlocks = GetDataBlocks(cabArchive, folder, folderIndex);
+ var dataBlocks = GetDataBlocks(cabArchive, file, folder, folderIndex);
if (dataBlocks == null || dataBlocks.Length == 0)
return null;
@@ -181,7 +181,12 @@ namespace BinaryObjectScanner.FileType
///
/// Get the set of data blocks for a folder
///
- private CFDATA[]? GetDataBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, CFFOLDER? folder, int folderIndex)
+ private CFDATA[]? GetDataBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive,
+ string file,
+ CFFOLDER? folder,
+ int folderIndex,
+ bool skipPrev = false,
+ bool skipNext = false)
{
// Skip invalid folders
if (folder?.DataBlocks == null || folder.DataBlocks.Length == 0)
@@ -193,19 +198,33 @@ namespace BinaryObjectScanner.FileType
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))
+ CFDATA[] prevBlocks = [];
+ if (!skipPrev && 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
+ var prev = OpenPrevious(cabArchive, file);
+ if (prev?.Model?.Header != null && prev.Model.Folders != null)
+ {
+ int prevFolderIndex = prev.Model.Header.FolderCount;
+ var prevFolder = prev.Model.Folders[prevFolderIndex - 1];
+ prevBlocks = GetDataBlocks(prev, file, prevFolder, folderIndex, skipNext: true) ?? [];
+ }
}
// Check if the folder spans forward
- if (Array.Exists(files, f => f.FolderIndex == FolderIndex.CONTINUED_TO_NEXT || f.FolderIndex == FolderIndex.CONTINUED_PREV_AND_NEXT))
+ CFDATA[] nextBlocks = [];
+ if (!skipNext && 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
+ var next = OpenNext(cabArchive, file);
+ if (next?.Model?.Header != null && next.Model.Folders != null)
+ {
+ int nextFolderIndex = next.Model.Header.FolderCount;
+ var nextFolder = next.Model.Folders[nextFolderIndex - 1];
+ nextBlocks = GetDataBlocks(next, file, nextFolder, folderIndex, skipPrev: true) ?? [];
+ }
}
- // Return all found blocks
- return [.. folder.DataBlocks];
+ // Return all found blocks in order
+ return [.. prevBlocks, .. folder.DataBlocks, .. nextBlocks];
}
///
@@ -245,15 +264,14 @@ namespace BinaryObjectScanner.FileType
///
/// Open the next archive, if possible
///
- private SabreTools.Serialization.Wrappers.MicrosoftCabinet? OpenNext(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, string? file)
+ private SabreTools.Serialization.Wrappers.MicrosoftCabinet? OpenNext(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, string file)
{
// Ignore invalid archives
if (cabArchive.Model.Header == null)
return null;
- // Normalize the filename, if one exists
- if (file != null)
- file = Path.GetFullPath(file);
+ // Normalize the filename
+ file = Path.GetFullPath(file);
// Get if the cabinet has a next part
string? next = cabArchive.Model.Header.CabinetNext;
@@ -276,15 +294,14 @@ namespace BinaryObjectScanner.FileType
///
/// Open the previous archive, if possible
///
- private SabreTools.Serialization.Wrappers.MicrosoftCabinet? OpenPrevious(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, string? file)
+ private SabreTools.Serialization.Wrappers.MicrosoftCabinet? OpenPrevious(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, string file)
{
// Ignore invalid archives
if (cabArchive.Model.Header == null)
return null;
- // Normalize the filename, if one exists
- if (file != null)
- file = Path.GetFullPath(file);
+ // Normalize the filename
+ file = Path.GetFullPath(file);
// Get if the cabinet has a previous part
string? prev = cabArchive.Model.Header.CabinetPrev;