diff --git a/SabreTools.Serialization/Wrappers/MicrosoftCabinet.cs b/SabreTools.Serialization/Wrappers/MicrosoftCabinet.cs
index 496eba64..c3633441 100644
--- a/SabreTools.Serialization/Wrappers/MicrosoftCabinet.cs
+++ b/SabreTools.Serialization/Wrappers/MicrosoftCabinet.cs
@@ -148,23 +148,23 @@ namespace SabreTools.Serialization.Wrappers
///
/// Extract a cabinet to an output directory, if possible
///
- /// Filename for one cabinet in the set
+ /// Filename for one cabinet in the set, if available
/// Path to the output directory
/// True to include debug data, false otherwise
/// Indicates if all files were able to be extracted
/// Will read spanned folders but won't attempt to extract unrelated folders
- public bool ExtractAll(string filename, string outDir, bool includeDebug)
+ public bool ExtractAll(string? filename, string outDir, bool includeDebug)
=> ExtractCabinet(filename, outDir, forwardOnly: false, includeDebug);
///
/// Extract a cabinet file to an output directory, if possible
///
- /// Filename for one cabinet in the set
+ /// Filename for one cabinet in the set, if available
/// Path to the output directory
/// True to include debug data, false otherwise
/// Indicates if decompression should be done forward-only
/// Indicates if all files were able to be extracted
- private bool ExtractCabinet(string filename, string outDir, bool forwardOnly, bool includeDebug)
+ private bool ExtractCabinet(string? filename, string outDir, bool forwardOnly, bool includeDebug)
{
// If the archive is invalid
if (Folders == null || Folders.Length == 0)
@@ -191,13 +191,13 @@ namespace SabreTools.Serialization.Wrappers
///
/// Extract the contents of a single folder
///
- /// Filename for one cabinet in the set
+ /// Filename for one cabinet in the set, if available
/// Path to the output directory
/// Folder containing the blocks to decompress
/// Index of the folder in the cabinet
/// Indicates if decompression should be done forward-only
/// True to include debug data, false otherwise
- private void ExtractFolder(string filename,
+ private void ExtractFolder(string? filename,
string outDir,
CFFOLDER? folder,
int folderIndex,
@@ -309,10 +309,10 @@ namespace SabreTools.Serialization.Wrappers
/// Open the next archive, if possible
///
/// Filename for one cabinet in the set
- private MicrosoftCabinet? OpenNext(string filename)
+ private MicrosoftCabinet? OpenNext(string? filename)
{
// Ignore invalid archives
- if (Header == null)
+ if (Header == null || string.IsNullOrEmpty(filename))
return null;
// Normalize the filename
@@ -337,10 +337,10 @@ namespace SabreTools.Serialization.Wrappers
/// Open the previous archive, if possible
///
/// Filename for one cabinet in the set
- private MicrosoftCabinet? OpenPrevious(string filename)
+ private MicrosoftCabinet? OpenPrevious(string? filename)
{
// Ignore invalid archives
- if (Header == null)
+ if (Header == null || string.IsNullOrEmpty(filename))
return null;
// Normalize the filename
@@ -462,12 +462,12 @@ namespace SabreTools.Serialization.Wrappers
///
/// Decompress all blocks for a folder
///
- /// Filename for one cabinet in the set
+ /// Filename for one cabinet in the set, if available
/// Folder containing the blocks to decompress
/// Index of the folder in the cabinet
/// Indicates if decompression should be done forward-only
/// Stream representing the decompressed data on success, null otherwise
- public Stream? DecompressBlocks(string filename, CFFOLDER? folder, int folderIndex, bool forwardOnly)
+ public Stream? DecompressBlocks(string? filename, CFFOLDER? folder, int folderIndex, bool forwardOnly)
{
// Ensure data blocks
var dataBlocks = forwardOnly
@@ -551,13 +551,13 @@ namespace SabreTools.Serialization.Wrappers
///
/// Get the set of data blocks for a folder
///
- /// Filename for one cabinet in the set
+ /// Filename for one cabinet in the set, if available
/// Folder containing the blocks to decompress
/// Index of the folder in the cabinet
/// Indicates if previous cabinets should be ignored
/// Indicates if next cabinets should be ignored
/// Array of data blocks on success, null otherwise
- private CFDATA[]? GetDataBlocks(string filename, CFFOLDER? folder, int folderIndex, bool skipPrev = false, bool skipNext = false)
+ private CFDATA[]? GetDataBlocks(string? filename, CFFOLDER? folder, int folderIndex, bool skipPrev = false, bool skipNext = false)
{
// Skip invalid folders
if (folder?.DataBlocks == null || folder.DataBlocks.Length == 0)
@@ -576,6 +576,11 @@ namespace SabreTools.Serialization.Wrappers
CFDATA[] prevBlocks = [];
if (!skipPrev && spanPrev)
{
+ // Try to get Prev if it doesn't exist
+ if (Prev?.Header == null)
+ Prev = OpenPrevious(filename);
+
+ // Get all blocks from Prev
if (Prev?.Header != null && Prev.Folders != null)
{
int prevFolderIndex = Prev.FolderCount;
@@ -588,6 +593,11 @@ namespace SabreTools.Serialization.Wrappers
CFDATA[] nextBlocks = [];
if (!skipNext && spanNext)
{
+ // Try to get Next if it doesn't exist
+ if (Next?.Header == null)
+ Next = OpenNext(filename);
+
+ // Get all blocks from Prev
if (Next?.Header != null && Next.Folders != null)
{
var nextFolder = Next.Folders[0];
@@ -602,11 +612,11 @@ namespace SabreTools.Serialization.Wrappers
///
/// Get the set of data blocks for a folder using forward reading only
///
- /// Filename for one cabinet in the set
+ /// Filename for one cabinet in the set, if available
/// Folder containing the blocks to decompress
/// Index of the folder in the cabinet
/// Array of data blocks on success, null otherwise
- private CFDATA[]? GetDataBlocksForward(string filename, CFFOLDER? folder, int folderIndex)
+ private CFDATA[]? GetDataBlocksForward(string? filename, CFFOLDER? folder, int folderIndex)
=> GetDataBlocks(filename, folder, folderIndex, skipPrev: true, skipNext: false);
///