Update packages

This commit is contained in:
Matt Nadareski
2024-12-13 11:56:31 -05:00
parent 69f8d8cfdd
commit f9b4e262f2
18 changed files with 265 additions and 295 deletions

View File

@@ -17,7 +17,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="SabreTools.Serialization" Version="1.8.2" />
<PackageReference Include="SabreTools.Serialization" Version="1.8.3" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -68,8 +68,10 @@ namespace BinaryObjectScanner.Test
WrapperType.GZIP,
WrapperType.InstallShieldArchiveV3,
WrapperType.InstallShieldCAB,
WrapperType.LZKWAJ,
WrapperType.LZQBasic,
WrapperType.LZSZDD,
WrapperType.MicrosoftCAB,
WrapperType.MicrosoftLZ,
WrapperType.MoPaQ,
//WrapperType.N3DS,
//WrapperType.NCF,

View File

@@ -4,14 +4,14 @@ using Xunit;
namespace BinaryObjectScanner.Test.FileType
{
public class MicrosoftLZTests
public class LZKWAJTests
{
[Fact]
public void ExtractFile_EmptyString_False()
{
string file = string.Empty;
string outDir = string.Empty;
var extractable = new MicrosoftLZ();
var extractable = new LZKWAJ();
bool actual = extractable.Extract(file, outDir, includeDebug: false);
Assert.False(actual);
@@ -23,7 +23,7 @@ namespace BinaryObjectScanner.Test.FileType
Stream? stream = null;
string file = string.Empty;
string outDir = string.Empty;
var extractable = new MicrosoftLZ();
var extractable = new LZKWAJ();
bool actual = extractable.Extract(stream, file, outDir, includeDebug: false);
Assert.False(actual);
@@ -35,7 +35,7 @@ namespace BinaryObjectScanner.Test.FileType
Stream? stream = new MemoryStream();
string file = string.Empty;
string outDir = string.Empty;
var extractable = new MicrosoftLZ();
var extractable = new LZKWAJ();
bool actual = extractable.Extract(stream, file, outDir, includeDebug: false);
Assert.False(actual);

View File

@@ -0,0 +1,44 @@
using System.IO;
using BinaryObjectScanner.FileType;
using Xunit;
namespace BinaryObjectScanner.Test.FileType
{
public class LZQBasicTests
{
[Fact]
public void ExtractFile_EmptyString_False()
{
string file = string.Empty;
string outDir = string.Empty;
var extractable = new LZQBasic();
bool actual = extractable.Extract(file, outDir, includeDebug: false);
Assert.False(actual);
}
[Fact]
public void ExtractStream_Null_False()
{
Stream? stream = null;
string file = string.Empty;
string outDir = string.Empty;
var extractable = new LZQBasic();
bool actual = extractable.Extract(stream, file, outDir, includeDebug: false);
Assert.False(actual);
}
[Fact]
public void ExtractStream_Empty_False()
{
Stream? stream = new MemoryStream();
string file = string.Empty;
string outDir = string.Empty;
var extractable = new LZQBasic();
bool actual = extractable.Extract(stream, file, outDir, includeDebug: false);
Assert.False(actual);
}
}
}

View File

@@ -0,0 +1,44 @@
using System.IO;
using BinaryObjectScanner.FileType;
using Xunit;
namespace BinaryObjectScanner.Test.FileType
{
public class LZSZDDTests
{
[Fact]
public void ExtractFile_EmptyString_False()
{
string file = string.Empty;
string outDir = string.Empty;
var extractable = new LZSZDD();
bool actual = extractable.Extract(file, outDir, includeDebug: false);
Assert.False(actual);
}
[Fact]
public void ExtractStream_Null_False()
{
Stream? stream = null;
string file = string.Empty;
string outDir = string.Empty;
var extractable = new LZSZDD();
bool actual = extractable.Extract(stream, file, outDir, includeDebug: false);
Assert.False(actual);
}
[Fact]
public void ExtractStream_Empty_False()
{
Stream? stream = new MemoryStream();
string file = string.Empty;
string outDir = string.Empty;
var extractable = new LZSZDD();
bool actual = extractable.Extract(stream, file, outDir, includeDebug: false);
Assert.False(actual);
}
}
}

View File

@@ -40,29 +40,5 @@ namespace BinaryObjectScanner.Test.FileType
bool actual = extractable.Extract(stream, file, outDir, includeDebug: false);
Assert.False(actual);
}
[Fact]
public void ExtractAll_EmptyModel_False()
{
var model = new SabreTools.Models.SGA.Archive();
var data = new MemoryStream();
var item = new SabreTools.Serialization.Wrappers.SGA(model, data);
string outputDirectory = string.Empty;
bool actual = SGA.ExtractAll(item, outputDirectory);
Assert.False(actual);
}
[Fact]
public void ExtractFile_EmptyModel_False()
{
var model = new SabreTools.Models.SGA.Archive();
var data = new MemoryStream();
var item = new SabreTools.Serialization.Wrappers.SGA(model, data);
string outputDirectory = string.Empty;
bool actual = SGA.ExtractFile(item, 0, outputDirectory);
Assert.False(actual);
}
}
}

View File

@@ -87,14 +87,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.Compression" Version="0.6.1" />
<PackageReference Include="SabreTools.Compression" Version="0.6.2" />
<PackageReference Include="SabreTools.Hashing" Version="1.4.0" />
<PackageReference Include="SabreTools.IO" Version="1.6.1" />
<PackageReference Include="SabreTools.Matching" Version="1.5.0" />
<PackageReference Include="SabreTools.Models" Version="1.5.6" />
<PackageReference Include="SabreTools.Serialization" Version="1.8.2" />
<PackageReference Include="UnshieldSharp" Version="1.9.2" />
<PackageReference Include="WiseUnpacker" Version="1.5.4" />
<PackageReference Include="SabreTools.Models" Version="1.5.7" />
<PackageReference Include="SabreTools.Serialization" Version="1.8.3" />
<PackageReference Include="UnshieldSharp" Version="1.9.3" />
<PackageReference Include="WiseUnpacker" Version="1.5.5" />
</ItemGroup>
</Project>

View File

@@ -44,8 +44,10 @@ namespace BinaryObjectScanner
WrapperType.GZIP => new FileType.GZIP(),
WrapperType.InstallShieldArchiveV3 => new FileType.InstallShieldArchiveV3(),
WrapperType.InstallShieldCAB => new FileType.InstallShieldCAB(),
WrapperType.LZKWAJ => new FileType.LZKWAJ(),
WrapperType.LZQBasic => new FileType.LZQBasic(),
WrapperType.LZSZDD => new FileType.LZSZDD(),
WrapperType.MicrosoftCAB => new FileType.MicrosoftCAB(),
WrapperType.MicrosoftLZ => new FileType.MicrosoftLZ(),
WrapperType.MoPaQ => new FileType.MPQ(),
//WrapperType.N3DS => new FileType.N3DS(),
//WrapperType.NCF => new FileType.NCF(),

View File

@@ -1,7 +1,5 @@
using System;
using System.IO;
using System.IO;
using BinaryObjectScanner.Interfaces;
using ISv3 = UnshieldSharp.Archive.InstallShieldArchiveV3;
namespace BinaryObjectScanner.FileType
{
@@ -23,41 +21,16 @@ namespace BinaryObjectScanner.FileType
/// <inheritdoc/>
public bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
{
try
{
if (!File.Exists(file))
return false;
var archive = new ISv3(file);
foreach (var cfile in archive.Files)
{
try
{
string tempFile = Path.Combine(outDir, cfile.Key);
var directoryName = Path.GetDirectoryName(tempFile);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
byte[]? fileContents = archive.Extract(cfile.Key, out string? error);
if (fileContents == null || !string.IsNullOrEmpty(error))
continue;
using FileStream fs = File.OpenWrite(tempFile);
fs.Write(fileContents, 0, fileContents.Length);
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
}
}
return true;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
// Create the wrapper
var isv3 = SabreTools.Serialization.Wrappers.InstallShieldArchiveV3.Create(stream);
if (isv3 == null)
return false;
}
// Loop through and extract all files
Directory.CreateDirectory(outDir);
isv3.ExtractAll(outDir);
return true;
}
}
}

View File

@@ -2,7 +2,7 @@
using System.IO;
using System.Text.RegularExpressions;
using BinaryObjectScanner.Interfaces;
using UnshieldSharp.Cabinet;
using UnshieldSharp;
namespace BinaryObjectScanner.FileType
{

View File

@@ -0,0 +1,36 @@
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// LZ-compressed file, KWAJ variant
/// </summary>
public class LZKWAJ : IExtractable
{
/// <inheritdoc/>
public bool Extract(string file, string outDir, bool includeDebug)
{
if (!File.Exists(file))
return false;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, outDir, includeDebug);
}
/// <inheritdoc/>
public bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
{
// Create the wrapper
var kwaj = SabreTools.Serialization.Wrappers.LZKWAJ.Create(stream);
if (kwaj == null)
return false;
// Loop through and extract all files
Directory.CreateDirectory(outDir);
kwaj.Extract(outDir);
return true;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// LZ-compressed file, QBasic variant
/// </summary>
public class LZQBasic : IExtractable
{
/// <inheritdoc/>
public bool Extract(string file, string outDir, bool includeDebug)
{
if (!File.Exists(file))
return false;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, outDir, includeDebug);
}
/// <inheritdoc/>
public bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
{
// Create the wrapper
var qbasic = SabreTools.Serialization.Wrappers.LZQBasic.Create(stream);
if (qbasic == null)
return false;
// Loop through and extract all files
Directory.CreateDirectory(outDir);
qbasic.Extract(outDir);
return true;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.IO;
using BinaryObjectScanner.Interfaces;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// LZ-compressed file, SZDD variant
/// </summary>
public class LZSZDD : IExtractable
{
/// <inheritdoc/>
public bool Extract(string file, string outDir, bool includeDebug)
{
if (!File.Exists(file))
return false;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, outDir, includeDebug);
}
/// <inheritdoc/>
public bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
{
// Create the wrapper
var szdd = SabreTools.Serialization.Wrappers.LZSZDD.Create(stream);
if (szdd == null)
return false;
// Loop through and extract all files
Directory.CreateDirectory(outDir);
szdd.Extract(Path.GetFileName(file), outDir);
return true;
}
}
}

View File

@@ -1,66 +0,0 @@
using System;
using System.IO;
using BinaryObjectScanner.Interfaces;
using SabreTools.Compression.LZ;
namespace BinaryObjectScanner.FileType
{
/// <summary>
/// Microsoft LZ-compressed Files (LZ32)
/// </summary>
/// <remarks>This is treated like an archive type due to the packing style</remarks>
public class MicrosoftLZ : IExtractable
{
/// <inheritdoc/>
public bool Extract(string file, string outDir, bool includeDebug)
{
if (!File.Exists(file))
return false;
using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Extract(fs, file, outDir, includeDebug);
}
/// <inheritdoc/>
public bool Extract(Stream? stream, string file, string outDir, bool includeDebug)
{
if (stream == null || !stream.CanRead)
return false;
try
{
var data = Decompressor.Decompress(stream);
if (data == null)
return false;
// Create the temp filename
string tempFile = "temp.bin";
if (!string.IsNullOrEmpty(file))
{
var expandedFilePath = Decompressor.GetExpandedName(file, out _);
if (expandedFilePath != null)
tempFile = Path.GetFileName(expandedFilePath).TrimEnd('\0');
if (tempFile.EndsWith(".ex"))
tempFile += "e";
else if (tempFile.EndsWith(".dl"))
tempFile += "l";
}
tempFile = Path.Combine(outDir, tempFile);
var directoryName = Path.GetDirectoryName(tempFile);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
using Stream tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
tempStream.Write(data, 0, data.Length);
return true;
}
catch (Exception ex)
{
if (includeDebug) Console.WriteLine(ex);
return false;
}
}
}
}

View File

@@ -1,7 +1,5 @@
using System.Collections.Generic;
using System.IO;
using BinaryObjectScanner.Interfaces;
using SabreTools.Compression.zlib;
namespace BinaryObjectScanner.FileType
{
@@ -30,147 +28,9 @@ namespace BinaryObjectScanner.FileType
// Loop through and extract all files
Directory.CreateDirectory(outDir);
ExtractAll(sga, outDir);
sga.ExtractAll(outDir);
return true;
}
/// <summary>
/// Extract all files from the SGA to an output directory
/// </summary>
/// <param name="outputDirectory">Output directory to write to</param>
/// <returns>True if all files extracted, false otherwise</returns>
public static bool ExtractAll(SabreTools.Serialization.Wrappers.SGA item, string outputDirectory)
{
// Get the file count
int fileCount = item.FileCount;
if (fileCount == 0)
return false;
// Loop through and extract all files to the output
bool allExtracted = true;
for (int i = 0; i < fileCount; i++)
{
allExtracted &= ExtractFile(item, i, outputDirectory);
}
return allExtracted;
}
/// <summary>
/// Extract a file from the SGA to an output directory by index
/// </summary>
/// <param name="index">File index to extract</param>
/// <param name="outputDirectory">Output directory to write to</param>
/// <returns>True if the file extracted, false otherwise</returns>
public static bool ExtractFile(SabreTools.Serialization.Wrappers.SGA item, int index, string outputDirectory)
{
// Get the file count
int fileCount = item.FileCount;
if (fileCount == 0)
return false;
// If the files index is invalid
if (index < 0 || index >= fileCount)
return false;
// Create the filename
var filename = item.GetFileName(index);
if (filename == null)
return false;
// Loop through and get all parent directories
var parentNames = new List<string> { filename };
// Get the parent directory
string? folderName = item.GetParentName(index);
if (folderName != null)
parentNames.Add(folderName);
// TODO: Should the section name/alias be used in the path as well?
// Reverse and assemble the filename
parentNames.Reverse();
#if NET20 || NET35
filename = parentNames[0];
for (int i = 1; i < parentNames.Count; i++)
{
filename = Path.Combine(filename, parentNames[i]);
}
#else
filename = Path.Combine([.. parentNames]);
#endif
// Get and adjust the file offset
long fileOffset = item.GetFileOffset(index);
fileOffset += item.FileDataOffset;
if (fileOffset < 0)
return false;
// Get the file sizes
long fileSize = item.GetCompressedSize(index);
long outputFileSize = item.GetUncompressedSize(index);
// Read the compressed data directly
var compressedData = item.ReadFromDataSource((int)fileOffset, (int)fileSize);
if (compressedData == null)
return false;
// If the compressed and uncompressed sizes match
byte[] data;
if (fileSize == outputFileSize)
{
data = compressedData;
}
else
{
// Inflate the data into the buffer
var zstream = new ZLib.z_stream_s();
data = new byte[outputFileSize];
unsafe
{
fixed (byte* payloadPtr = compressedData)
fixed (byte* dataPtr = data)
{
zstream.next_in = payloadPtr;
zstream.avail_in = (uint)compressedData.Length;
zstream.total_in = (uint)compressedData.Length;
zstream.next_out = dataPtr;
zstream.avail_out = (uint)data.Length;
zstream.total_out = 0;
ZLib.inflateInit_(zstream, ZLib.zlibVersion(), compressedData.Length);
int zret = ZLib.inflate(zstream, 1);
ZLib.inflateEnd(zstream);
}
}
}
// If we have an invalid output directory
if (string.IsNullOrEmpty(outputDirectory))
return false;
// Create the full output path
filename = Path.Combine(outputDirectory, filename);
// Ensure the output directory is created
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null)
Directory.CreateDirectory(directoryName);
// Try to write the data
try
{
// Open the output file for writing
using Stream fs = File.OpenWrite(filename);
fs.Write(data, 0, data.Length);
}
catch
{
return false;
}
return false;
}
}
}

View File

@@ -110,7 +110,10 @@ namespace BinaryObjectScanner.Packer
{
try
{
data = SabreTools.Compression.LZ.Decompressor.Decompress(payload);
var decompressor = SabreTools.Compression.SZDD.Decompressor.CreateSZDD(payload);
var dataStream = new MemoryStream();
decompressor.CopyTo(dataStream);
data = dataStream.ToArray();
}
catch
{

View File

@@ -37,7 +37,7 @@
<ItemGroup>
<PackageReference Include="SabreTools.IO" Version="1.6.1" />
<PackageReference Include="SabreTools.Serialization" Version="1.8.2" />
<PackageReference Include="SabreTools.Serialization" Version="1.8.3" />
</ItemGroup>
</Project>

View File

@@ -269,6 +269,42 @@ namespace ExtractionTool
iscab.Extract(stream, file, outputDirectory, includeDebug: true);
}
// LZ-compressed file, KWAJ variant
else if (ft == WrapperType.LZKWAJ)
{
// Build the KWAJ
Console.WriteLine("Extracting LZ-compressed file, KWAJ variant contents");
Console.WriteLine();
// Extract using the FileType
var lz = new LZKWAJ();
lz.Extract(stream, file, outputDirectory, includeDebug: true);
}
// LZ-compressed file, QBasic variant
else if (ft == WrapperType.LZQBasic)
{
// Build the QBasic
Console.WriteLine("Extracting LZ-compressed file, QBasic variant contents");
Console.WriteLine();
// Extract using the FileType
var lz = new LZQBasic();
lz.Extract(stream, file, outputDirectory, includeDebug: true);
}
// LZ-compressed file, SZDD variant
else if (ft == WrapperType.LZSZDD)
{
// Build the SZDD
Console.WriteLine("Extracting LZ-compressed file, SZDD variant contents");
Console.WriteLine();
// Extract using the FileType
var lz = new LZSZDD();
lz.Extract(stream, file, outputDirectory, includeDebug: true);
}
// Microsoft Cabinet archive
else if (ft == WrapperType.MicrosoftCAB)
{
@@ -286,18 +322,6 @@ namespace ExtractionTool
#endif
}
// Microsoft LZ / LZ32
else if (ft == WrapperType.MicrosoftLZ)
{
// Build the Microsoft LZ / LZ32 information
Console.WriteLine("Extracting Microsoft LZ / LZ32 contents");
Console.WriteLine();
// Extract using the FileType
var lz = new MicrosoftLZ();
lz.Extract(stream, file, outputDirectory, includeDebug: true);
}
// MoPaQ (MPQ) archive
else if (ft == WrapperType.MoPaQ)
{