Enable MS-CAB extraction on at least x86

This commit is contained in:
Matt Nadareski
2024-02-20 19:59:43 -05:00
parent 9d6c53f631
commit b7afad5a4a
6 changed files with 75 additions and 14 deletions

View File

@@ -24,8 +24,8 @@
</PropertyGroup>
<!-- Set a build flag for Windows specifically -->
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`win-`))">
<DefineConstants>WIN</DefineConstants>
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86' OR '$(RuntimeIdentifier)'=='win-x64'">
<DefineConstants>$(DefineConstants);WIN</DefineConstants>
</PropertyGroup>
<!-- Exclude certain parts of external modules for .NET Framework 4.5.2 and above -->
@@ -50,7 +50,7 @@
</PropertyGroup>
<!-- These are needed for dealing with native Windows DLLs -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net4`)) AND !$(TargetFramework.StartsWith(`net40`))">
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND $(RuntimeIdentifier.StartsWith(`win-`))">
<Content Include="*.dll">
<Pack>true</Pack>
<PackagePath>contentFiles;content</PackagePath>

View File

@@ -2,6 +2,9 @@
using System.Collections.Generic;
using System.IO;
using BinaryObjectScanner.Interfaces;
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
using LibMSPackN;
#endif
namespace BinaryObjectScanner.FileType
{
@@ -18,16 +21,50 @@ namespace BinaryObjectScanner.FileType
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return Extract(fs, file, includeDebug);
}
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, includeDebug);
}
/// <inheritdoc/>
public string? Extract(Stream? stream, string file, bool includeDebug)
{
#if NET20 || NET35 || NET40 || !WIN
// Not supported for old .NET due to feature requirements
// Not supported in non-Windows builds due to DLL requirements
return null;
#else
try
{
// Create a temp output directory
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
using (var cabArchive = new MSCabinet(file))
{
// Loop over each entry
foreach (var compressedFile in cabArchive.GetFiles())
{
try
{
string tempFile = Path.Combine(tempPath, compressedFile.Filename);
Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
compressedFile.ExtractTo(tempFile);
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
}
}
return tempPath;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return null;
}
#endif
}
}
}

View File

@@ -6,10 +6,12 @@ C# protection, packer, and archive scanning library. This currently compiles as
The following libraries (or ports thereof) are used for file handling:
- [LessIO](https://github.com/activescott/LessIO) - Used by libmspack4n for IO handling
- [libmspack4n](https://github.com/activescott/libmspack4n) MS-CAB extraction [Unused in .NET Frawework 2.0/3.5/4.0 and non-Windows builds due to Windows-specific libraries]
- [openmcdf](https://github.com/ironfede/openmcdf) - MSI extraction
- [SharpCompress](https://github.com/adamhathcock/sharpcompress) - Common archive format extraction
- [SharpZipLib](https://github.com/icsharpcode/SharpZipLib) - zlib-based extraction
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET 6, .NET 7, or .NET 8 builds due to Windows-specific libraries]
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET Frawework 2.0/3.5/4.0 and non-Windows builds due to Windows-specific libraries]
- [UnshieldSharp](https://github.com/mnadareski/UnshieldSharp) - InstallShield CAB extraction
- [WiseUnpacker](https://github.com/mnadareski/WiseUnpacker) - Wise Installer extraction

View File

@@ -408,6 +408,7 @@ namespace Test
#endif
}
#if ((NETFRAMEWORK && !NET20 && !NET35 && !NET40) || NETCOREAPP) && WIN
// Microsoft Cabinet archive
else if (ft == SupportedFileType.MicrosoftCAB)
{
@@ -415,7 +416,7 @@ namespace Test
Console.WriteLine("Extracting MS-CAB contents");
Console.WriteLine();
var cabinet = MicrosoftCabinet.Create(stream);
var cabinet = new LibMSPackN.MSCabinet(file);
if (cabinet == null)
{
Console.WriteLine("Something went wrong parsing MS-CAB archive");
@@ -425,7 +426,24 @@ namespace Test
try
{
Console.WriteLine("MS-CAB extraction is disabled");
// Extract the MS-CAB contents to the directory
foreach (var compressedFile in cabinet.GetFiles())
{
try
{
string tempFile = Path.Combine(outputDirectory, compressedFile.Filename);
string? directoryName = Path.GetDirectoryName(tempFile);
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
compressedFile.ExtractTo(tempFile);
}
catch (Exception ex)
{
Console.WriteLine($"Something went wrong extracting Microsoft Cabinet entry {compressedFile.Filename}: {ex}");
Console.WriteLine();
}
}
}
catch (Exception ex)
{
@@ -433,6 +451,7 @@ namespace Test
Console.WriteLine();
}
}
#endif
// Microsoft LZ / LZ32
else if (ft == SupportedFileType.MicrosoftLZ)
@@ -514,7 +533,10 @@ namespace Test
try
{
string tempFile = Path.Combine(outputDirectory, sub);
Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
string? directoryName = Path.GetDirectoryName(tempFile);
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
mpqArchive.ExtractFile(sub, tempFile);
}
catch (Exception ex)

View File

@@ -166,7 +166,7 @@ namespace Test
#if NET6_0_OR_GREATER
options.Json = true;
#else
Console.WriteLine("JSON output not available in .NET Framework 4.8");
Console.WriteLine("JSON output not available in .NET Framework");
#endif
break;

View File

@@ -12,8 +12,8 @@
</PropertyGroup>
<!-- Set a build flag for Windows specifically -->
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`win-`))">
<DefineConstants>WIN</DefineConstants>
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86' OR '$(RuntimeIdentifier)'=='win-x64'">
<DefineConstants>$(DefineConstants);WIN</DefineConstants>
</PropertyGroup>
<ItemGroup>