diff --git a/BinaryObjectScanner/FileType/MicrosoftCAB.cs b/BinaryObjectScanner/FileType/MicrosoftCAB.cs index 75d75b61..2ae79561 100644 --- a/BinaryObjectScanner/FileType/MicrosoftCAB.cs +++ b/BinaryObjectScanner/FileType/MicrosoftCAB.cs @@ -35,211 +35,7 @@ namespace BinaryObjectScanner.FileType public string? Extract(Stream stream, string file, bool includeDebug) #endif { - try - { - // TODO: Fix/re-enable/do ANYTHING to get this working again - return null; - - // Open the cab file - var cabFile = SabreTools.Serialization.Wrappers.MicrosoftCabinet.Create(stream); - if (cabFile == null) - return null; - - // Create a temp output directory - string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - Directory.CreateDirectory(tempPath); - - // If entry extraction fails - bool success = ExtractAll(cabFile, tempPath); - if (!success) - return null; - - return tempPath; - } - catch (Exception ex) - { - if (includeDebug) Console.WriteLine(ex); - return null; - } + return null; } - - #region Folders - - /// - /// Get the uncompressed data associated with a folder - /// - /// Folder index to check - /// Byte array representing the data, null on error - /// All but uncompressed are unimplemented -#if NET48 - public static byte[] GetUncompressedData(SabreTools.Serialization.Wrappers.MicrosoftCabinet item, int folderIndex) -#else - public static byte[]? GetUncompressedData(SabreTools.Serialization.Wrappers.MicrosoftCabinet item, int folderIndex) -#endif - { - // If we have an invalid folder index - if (folderIndex < 0 || item.Model.Folders == null || folderIndex >= item.Model.Folders.Length) - return null; - - // Get the folder header - var folder = item.Model.Folders[folderIndex]; - if (folder == null) - return null; - - // If we have invalid data blocks - if (folder.DataBlocks == null || folder.DataBlocks.Length == 0) - return null; - - // Setup LZX decompression - var lzx = new Compression.LZX.State(); - Compression.LZX.Decompressor.Init(((ushort)folder.CompressionType >> 8) & 0x1f, lzx); - - // Setup MS-ZIP decompression - Compression.MSZIP.State mszip = new Compression.MSZIP.State(); - - // Setup Quantum decompression - var qtm = new Compression.Quantum.State(); - Compression.Quantum.Decompressor.InitState(qtm, folder); - - List data = new List(); - foreach (var dataBlock in folder.DataBlocks) - { - if (dataBlock == null) - continue; - - var decompressed = new byte[dataBlock.UncompressedSize]; - switch (folder.CompressionType & SabreTools.Models.MicrosoftCabinet.CompressionType.MASK_TYPE) - { - case SabreTools.Models.MicrosoftCabinet.CompressionType.TYPE_NONE: - decompressed = dataBlock.CompressedData; - break; - case SabreTools.Models.MicrosoftCabinet.CompressionType.TYPE_MSZIP: - decompressed = new byte[SabreTools.Models.Compression.MSZIP.Constants.ZIPWSIZE]; - Compression.MSZIP.Decompressor.Decompress(mszip, dataBlock.CompressedSize, dataBlock.CompressedData, dataBlock.UncompressedSize, decompressed); - Array.Resize(ref decompressed, dataBlock.UncompressedSize); - break; - case SabreTools.Models.MicrosoftCabinet.CompressionType.TYPE_QUANTUM: - Compression.Quantum.Decompressor.Decompress(qtm, dataBlock.CompressedSize, dataBlock.CompressedData, dataBlock.UncompressedSize, decompressed); - break; - case SabreTools.Models.MicrosoftCabinet.CompressionType.TYPE_LZX: - Compression.LZX.Decompressor.Decompress(state: lzx, dataBlock.CompressedSize, dataBlock.CompressedData, dataBlock.UncompressedSize, decompressed); - break; - default: - return null; - } - - if (decompressed != null) - data.AddRange(decompressed); - } - - return data.ToArray(); - } - - #endregion - - #region Files - - /// - /// Extract all files from the MS-CAB to an output directory - /// - /// Output directory to write to - /// True if all filez extracted, false otherwise - public static bool ExtractAll(SabreTools.Serialization.Wrappers.MicrosoftCabinet item, string outputDirectory) - { - // If we have no files - if (item.Model.Files == null || item.Model.Files.Length == 0) - return false; - - // Loop through and extract all files to the output - bool allExtracted = true; - for (int i = 0; i < item.Model.Files.Length; i++) - { - allExtracted &= ExtractFile(item, i, outputDirectory); - } - - return allExtracted; - } - - /// - /// Extract a file from the MS-CAB to an output directory by index - /// - /// File index to extract - /// Output directory to write to - /// True if the file extracted, false otherwise - public static bool ExtractFile(SabreTools.Serialization.Wrappers.MicrosoftCabinet item, int index, string outputDirectory) - { - // If we have an invalid file index - if (index < 0 || item.Model.Files == null || index >= item.Model.Files.Length) - return false; - - // If we have an invalid output directory - if (string.IsNullOrWhiteSpace(outputDirectory)) - return false; - - // Ensure the directory exists - Directory.CreateDirectory(outputDirectory); - - // Get the file header - var file = item.Model.Files[index]; - if (file == null || file.FileSize == 0) - return false; - - // Create the output filename - string fileName = Path.Combine(outputDirectory, file.Name ?? $"file{index}"); - - // Get the file data, if possible - var fileData = GetFileData(item, index); - if (fileData == null) - return false; - - // Write the file data - using (FileStream fs = File.OpenWrite(fileName)) - { - fs.Write(fileData, 0, fileData.Length); - } - - return true; - } - - /// - /// Get the uncompressed data associated with a file - /// - /// File index to check - /// Byte array representing the data, null on error -#if NET48 - public static byte[] GetFileData(SabreTools.Serialization.Wrappers.MicrosoftCabinet item, int fileIndex) -#else - public static byte[]? GetFileData(SabreTools.Serialization.Wrappers.MicrosoftCabinet item, int fileIndex) -#endif - { - // If we have an invalid file index - if (fileIndex < 0 || item.Model.Files == null || fileIndex >= item.Model.Files.Length) - return null; - - // Get the file header - var file = item.Model.Files[fileIndex]; - if (file == null || file.FileSize == 0) - return null; - - // Get the parent folder data -#if NET48 - byte[] folderData = GetUncompressedData(item, (int)file.FolderIndex); -#else - byte[]? folderData = GetUncompressedData(item, (int)file.FolderIndex); -#endif - if (folderData == null || folderData.Length == 0) - return null; - - // Create the output file data - byte[] fileData = new byte[file.FileSize]; - if (folderData.Length < file.FolderStartOffset + file.FileSize) - return null; - - // Get the segment that represents this file - Array.Copy(folderData, file.FolderStartOffset, fileData, 0, file.FileSize); - return fileData; - } - - #endregion } }