From 4953673caf97170724cd7e663c05d82b26a3588b Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 7 Jul 2022 11:37:53 -0700 Subject: [PATCH] Start writing CAB extraction --- BurnOutSharp/FileType/MicrosoftCAB.cs | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/BurnOutSharp/FileType/MicrosoftCAB.cs b/BurnOutSharp/FileType/MicrosoftCAB.cs index 9112e17e..32b0b0a1 100644 --- a/BurnOutSharp/FileType/MicrosoftCAB.cs +++ b/BurnOutSharp/FileType/MicrosoftCAB.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.IO; +using System.Text; using BurnOutSharp.Interfaces; using BurnOutSharp.Tools; using WixToolset.Dtf.Compression.Cab; @@ -262,6 +263,49 @@ namespace BurnOutSharp.FileType } #endregion + + #region Public Functionality + + /// + /// Extract a single file from the archive to + /// + public bool ExtractFile(string filePath, string outputDirectory, bool exact = false) + { + // Perform sanity checks + if (Header == null || Files == null || Files.Length == 0) + return false; + + // Check the file exists + int fileIndex = -1; + for (int i = 0; i < Files.Length; i++) + { + CFFILE tempFile = Files[i]; + if (tempFile == null) + continue; + + // Check for a match + if (exact ? tempFile.NameAsString == filePath : tempFile.NameAsString.EndsWith(filePath, StringComparison.OrdinalIgnoreCase)) + { + fileIndex = i; + break; + } + } + + // -1 is an invalid file index + if (fileIndex == -1) + return false; + + // Get the file to extract + CFFILE file = Files[fileIndex]; + string outputPath = Path.Combine(outputDirectory, file.NameAsString); + + // TODO: We don't check for other cabinets here yet + // TODO: Read and decompress data blocks + + return true; + } + + #endregion } /// @@ -745,6 +789,36 @@ namespace BurnOutSharp.FileType #endregion + #region Generated Properties + + /// + /// Name value as a string (not null-terminated) + /// + public string NameAsString + { + get + { + // Perform sanity checks + if (Name == null || Name.Length == 0) + return null; + + // Attempt to respect the attribute flag for UTF-8 + if (Attributes.HasFlag(FileAttributes.NAME_IS_UTF)) + { + try + { + return Encoding.UTF8.GetString(Name).TrimEnd('\0'); + } + catch { } + } + + // Default case uses local encoding + return Encoding.Default.GetString(Name).TrimEnd('\0'); + } + } + + #endregion + #region Serialization ///