In-depth cleanup with .NET 10 concepts

This commit is contained in:
Matt Nadareski
2025-11-14 14:06:43 -05:00
parent d63fcfcf7f
commit f6201e2c35
31 changed files with 405 additions and 191 deletions

View File

@@ -138,24 +138,15 @@ namespace SabreTools.Data.Extensions
/// <inheritdoc/>
public override long Length
{
get
{
return (_baseStream.Length / Constants.CDROMSectorSize) * _isoSectorSize;
}
}
=> (_baseStream.Length / Constants.CDROMSectorSize) * _isoSectorSize;
/// <inheritdoc/>
public override void SetLength(long value)
{
throw new NotSupportedException("Setting the length of this stream is not supported.");
}
=> throw new NotSupportedException("Setting the length of this stream is not supported.");
/// <inheritdoc/>
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException("Writing to this stream is not supported.");
}
=> throw new NotSupportedException("Writing to this stream is not supported.");
/// <inheritdoc/>
protected override void Dispose(bool disposing)

View File

@@ -18,10 +18,10 @@ namespace SabreTools.Data.Extensions
/// <param name="rva">Relative virtual address to convert</param>
/// <param name="sections">Array of sections to check against</param>
/// <returns>Physical address, 0 on error</returns>
public static uint ConvertVirtualAddress(this uint rva, SectionHeader[]? sections)
public static uint ConvertVirtualAddress(this uint rva, SectionHeader[] sections)
{
// If we have an invalid section table, we can't do anything
if (sections == null || sections.Length == 0)
if (sections.Length == 0)
return 0;
// If the RVA is 0, we just return 0 because it's invalid
@@ -69,7 +69,7 @@ namespace SabreTools.Data.Extensions
/// <param name="rva">Relative virtual address to convert</param>
/// <param name="sections">Array of sections to check against</param>
/// <returns>Section index, null on error</returns>
public static int ContainingSectionIndex(this uint rva, SectionHeader[]? sections)
public static int ContainingSectionIndex(this uint rva, SectionHeader[] sections)
{
// If we have an invalid section table, we can't do anything
if (sections == null || sections.Length == 0)
@@ -1282,10 +1282,10 @@ namespace SabreTools.Data.Extensions
/// <param name="data">Data to parse</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled ResourceHeader on success, null on error</returns>
public static Data.Models.PortableExecutable.Resource.ResourceHeader ParseResourceHeader(this byte[] data, ref int offset)
public static Models.PortableExecutable.Resource.ResourceHeader ParseResourceHeader(this byte[] data, ref int offset)
{
// Read in the table
var obj = new Data.Models.PortableExecutable.Resource.ResourceHeader();
var obj = new Models.PortableExecutable.Resource.ResourceHeader();
obj.DataSize = data.ReadUInt32LittleEndian(ref offset);
obj.HeaderSize = data.ReadUInt32LittleEndian(ref offset);

View File

@@ -13,7 +13,7 @@ namespace SabreTools.Data.Extensions
/// </summary>
/// <param name="paddingLevel">Padding level of the item when formatting</param>
/// <returns>String representing the TypeLengthValue, if possible</returns>
public static string Format(this Data.Models.ASN1.TypeLengthValue tlv, int paddingLevel = 0)
public static string Format(this Models.ASN1.TypeLengthValue tlv, int paddingLevel = 0)
{
// Create the left-padding string
string padding = new(' ', paddingLevel);
@@ -38,7 +38,7 @@ namespace SabreTools.Data.Extensions
if (tlv.Type.HasFlag(ASN1Type.V_ASN1_CONSTRUCTED))
#endif
{
if (tlv.Value is not SabreTools.Data.Models.ASN1.TypeLengthValue[] valueAsObjectArray)
if (tlv.Value is not Models.ASN1.TypeLengthValue[] valueAsObjectArray)
{
formatBuilder.Append(", Value: [INVALID DATA TYPE]");
return formatBuilder.ToString();

View File

@@ -65,9 +65,7 @@ namespace SabreTools.Serialization.Readers
private static Record? ParseRecord(Stream data)
{
// The first 4 bytes are the type and length
RecordType type = (RecordType)data.ReadByteValue();
uint recordLength = data.ReadUInt24LittleEndian();
data.SeekIfPossible(-4, SeekOrigin.Current);
RecordType type = (RecordType)data.PeekByteValue();
// Create a record based on the type
return type switch

View File

@@ -293,6 +293,7 @@ namespace SabreTools.Serialization.Readers
#endregion
// TODO: Pre-parse known resource types
#region Resource Directory Table
// Should also be in a '.rsrc' section

View File

@@ -2,7 +2,7 @@ using System;
using System.IO;
using System.Text;
using SabreTools.Data.Models.CFB;
#if NETFRAMEWORK || NETSTANDARD
#if NETFRAMEWORK || NETSTANDARD2_0
using SabreTools.IO.Extensions;
#endif

View File

@@ -37,7 +37,7 @@ namespace SabreTools.Serialization.Wrappers
Print(builder, v5);
break;
default:
builder.AppendLine("Unrecognized header type");
builder.AppendLine($"Unrecognized header type: {Model}");
builder.AppendLine();
break;
}

View File

@@ -3,6 +3,7 @@ namespace SabreTools.Serialization.Wrappers
/// <summary>
/// Represents an item that is extractable
/// </summary>
/// TODO: Investigate whether it's possible to do an ExtractToStream
public interface IExtractable
{
/// <summary>

View File

@@ -31,9 +31,9 @@ namespace SabreTools.Serialization.Wrappers
Print(builder, Model.DirectoryDescriptors, encoding);
}
protected static void Print(StringBuilder builder, byte[]? systemArea)
protected static void Print(StringBuilder builder, byte[] systemArea)
{
if (systemArea == null || systemArea.Length == 0)
if (systemArea.Length == 0)
builder.AppendLine(systemArea, " System Area");
else if (Array.TrueForAll(systemArea, b => b == 0))
builder.AppendLine("Zeroed", " System Area");

View File

@@ -94,8 +94,6 @@ namespace SabreTools.Serialization.Wrappers
return field;
}
private set;
} = null;
/// <summary>

View File

@@ -51,7 +51,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionsTable.Length == 0)
if (PartitionsTable.Length < 1)
return null;
return PartitionsTable[0];
@@ -65,7 +65,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionsTable.Length == 0)
if (PartitionsTable.Length < 2)
return null;
return PartitionsTable[1];
@@ -79,7 +79,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionsTable.Length == 0)
if (PartitionsTable.Length < 3)
return null;
return PartitionsTable[2];
@@ -93,7 +93,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionsTable.Length == 0)
if (PartitionsTable.Length < 7)
return null;
return PartitionsTable[6];
@@ -107,7 +107,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionsTable.Length == 0)
if (PartitionsTable.Length < 8)
return null;
return PartitionsTable[7];
@@ -131,7 +131,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionFlags.Length == 0)
if (PartitionFlags.Length < (int)NCSDFlags.BackupWriteWaitTime + 1)
return default;
return PartitionFlags[(int)NCSDFlags.BackupWriteWaitTime];
@@ -145,7 +145,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionFlags.Length == 0)
if (PartitionFlags.Length < (int)NCSDFlags.MediaCardDevice2X + 1)
return default;
return (MediaCardDeviceType)PartitionFlags[(int)NCSDFlags.MediaCardDevice2X];
@@ -159,7 +159,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionFlags.Length == 0)
if (PartitionFlags.Length < (int)NCSDFlags.MediaCardDevice3X + 1)
return default;
return (MediaCardDeviceType)PartitionFlags[(int)NCSDFlags.MediaCardDevice3X];
@@ -173,7 +173,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionFlags.Length == 0)
if (PartitionFlags.Length < (int)NCSDFlags.MediaPlatformIndex + 1)
return default;
return (MediaPlatformIndex)PartitionFlags[(int)NCSDFlags.MediaPlatformIndex];
@@ -187,7 +187,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
if (PartitionFlags.Length == 0)
if (PartitionFlags.Length < (int)NCSDFlags.MediaTypeIndex + 1)
return default;
return (MediaTypeIndex)PartitionFlags[(int)NCSDFlags.MediaTypeIndex];

View File

@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
using SharpCompress.Readers;
@@ -22,7 +22,7 @@ namespace SabreTools.Serialization.Wrappers
if (_dataSource == null || !_dataSource.CanRead)
return false;
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
try
{
var readerOptions = new ReaderOptions() { LookForHeader = lookForHeader };
@@ -74,17 +74,17 @@ namespace SabreTools.Serialization.Wrappers
entry.WriteToFile(filename);
}
catch (System.Exception ex)
catch (Exception ex)
{
if (includeDebug) System.Console.Error.WriteLine(ex);
if (includeDebug) Console.Error.WriteLine(ex);
}
}
return true;
}
catch (System.Exception ex)
catch (Exception ex)
{
if (includeDebug) System.Console.Error.WriteLine(ex);
if (includeDebug) Console.Error.WriteLine(ex);
return false;
}
#else

View File

@@ -259,7 +259,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, SectionHeader[]? entries)
private static void Print(StringBuilder builder, SectionHeader[] entries)
{
builder.AppendLine(" Section Table Information:");
builder.AppendLine(" -------------------------");
@@ -431,7 +431,7 @@ namespace SabreTools.Serialization.Wrappers
}
// Create the deserializer
var deserializer = new Serialization.Readers.AbstractSyntaxNotationOne();
var deserializer = new Readers.AbstractSyntaxNotationOne();
for (int i = 0; i < entries.Length; i++)
{
@@ -486,7 +486,7 @@ namespace SabreTools.Serialization.Wrappers
}
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.DelayLoad.DirectoryTable? table, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.DelayLoad.DirectoryTable? table, SectionHeader[] sections)
{
builder.AppendLine(" Delay-Load Directory Table Information:");
builder.AppendLine(" -------------------------");
@@ -513,7 +513,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.BaseRelocation.Block[]? entries, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.BaseRelocation.Block[]? entries, SectionHeader[] sections)
{
builder.AppendLine(" Base Relocation Table Information:");
builder.AppendLine(" -------------------------");
@@ -585,7 +585,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Export.DirectoryTable? table, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Export.DirectoryTable? table, SectionHeader[] sections)
{
builder.AppendLine(value: " Export Directory Table Information:");
builder.AppendLine(" -------------------------");
@@ -615,7 +615,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Export.AddressTableEntry[]? table, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Export.AddressTableEntry[]? table, SectionHeader[] sections)
{
builder.AppendLine(" Export Address Table Information:");
builder.AppendLine(" -------------------------");
@@ -704,7 +704,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Import.DirectoryTableEntry[]? table, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Import.DirectoryTableEntry[]? table, SectionHeader[] sections)
{
builder.AppendLine(" Import Directory Table Information:");
builder.AppendLine(" -------------------------");
@@ -734,7 +734,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, Dictionary<int, Data.Models.PortableExecutable.Import.LookupTableEntry[]?>? tables, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Dictionary<int, Data.Models.PortableExecutable.Import.LookupTableEntry[]?>? tables, SectionHeader[] sections)
{
builder.AppendLine(" Import Lookup Tables Information:");
builder.AppendLine(" -------------------------");
@@ -780,7 +780,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, Dictionary<int, Data.Models.PortableExecutable.Import.AddressTableEntry[]?>? tables, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Dictionary<int, Data.Models.PortableExecutable.Import.AddressTableEntry[]?>? tables, SectionHeader[] sections)
{
builder.AppendLine(" Import Address Tables Information:");
builder.AppendLine(" -------------------------");
@@ -849,7 +849,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Resource.DirectoryTable? table, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Resource.DirectoryTable? table, SectionHeader[] sections)
{
builder.AppendLine(" Resource Directory Table Information:");
builder.AppendLine(" -------------------------");
@@ -864,7 +864,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine();
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Resource.DirectoryTable table, int level, List<object> types, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Resource.DirectoryTable table, int level, List<object> types, SectionHeader[] sections)
{
string padding = new(' ', (level + 1) * 2);
@@ -901,7 +901,7 @@ namespace SabreTools.Serialization.Wrappers
}
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Resource.DirectoryEntry entry, int level, List<object> types, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Resource.DirectoryEntry entry, int level, List<object> types, SectionHeader[] sections)
{
string padding = new(' ', (level + 1) * 2);
@@ -922,7 +922,7 @@ namespace SabreTools.Serialization.Wrappers
Print(builder, entry.Subdirectory, level: level + 1, types, sections);
}
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Resource.DataEntry entry, int level, List<object> types, SectionHeader[]? sections)
private static void Print(StringBuilder builder, Data.Models.PortableExecutable.Resource.DataEntry entry, int level, List<object> types, SectionHeader[] sections)
{
string padding = new(' ', (level + 1) * 2);

View File

@@ -637,61 +637,171 @@ namespace SabreTools.Serialization.Wrappers
/// <summary>
/// "Build GUID"
/// </summary/>
public string? BuildGuid => GetVersionInfoString("BuildGuid");
public string? BuildGuid
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("BuildGuid");
return field;
}
} = null;
/// <summary>
/// "Build signature"
/// </summary/>
public string? BuildSignature => GetVersionInfoString("BuildSignature");
public string? BuildSignature
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("BuildSignature");
return field;
}
} = null;
/// <summary>
/// Additional information that should be displayed for diagnostic purposes.
/// </summary/>
public string? Comments => GetVersionInfoString("Comments");
public string? Comments
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("Comments");
return field;
}
} = null;
/// <summary>
/// Company that produced the file—for example, "Microsoft Corporation" or
/// "Standard Microsystems Corporation, Inc." This string is required.
/// </summary/>
public string? CompanyName => GetVersionInfoString("CompanyName");
public string? CompanyName
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("CompanyName");
return field;
}
} = null;
/// <summary>
/// "Debug version"
/// </summary/>
public string? DebugVersion => GetVersionInfoString("DebugVersion");
public string? DebugVersion
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("DebugVersion");
return field;
}
} = null;
/// <summary>
/// File description to be presented to users. This string may be displayed in a
/// list box when the user is choosing files to install—for example, "Keyboard
/// Driver for AT-Style Keyboards". This string is required.
/// </summary/>
public string? FileDescription => GetVersionInfoString("FileDescription");
public string? FileDescription
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("FileDescription");
return field;
}
} = null;
/// <summary>
/// Version number of the file—for example, "3.10" or "5.00.RC2". This string
/// is required.
/// </summary/>
public string? FileVersion => GetVersionInfoString("FileVersion");
public string? FileVersion
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("FileVersion");
return field;
}
} = null;
/// <summary>
/// Internal name of the file, if one exists—for example, a module name if the
/// file is a dynamic-link library. If the file has no internal name, this
/// string should be the original filename, without extension. This string is required.
/// </summary/>
public string? InternalName => GetVersionInfoString(key: "InternalName");
public string? InternalName
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("InternalName");
return field;
}
} = null;
/// <summary>
/// Copyright notices that apply to the file. This should include the full text of
/// all notices, legal symbols, copyright dates, and so on. This string is optional.
/// </summary/>
public string? LegalCopyright => GetVersionInfoString(key: "LegalCopyright");
public string? LegalCopyright
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("LegalCopyright");
return field;
}
} = null;
/// <summary>
/// Trademarks and registered trademarks that apply to the file. This should include
/// the full text of all notices, legal symbols, trademark numbers, and so on. This
/// string is optional.
/// </summary/>
public string? LegalTrademarks => GetVersionInfoString(key: "LegalTrademarks");
public string? LegalTrademarks
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("LegalTrademarks");
return field;
}
} = null;
/// <summary>
/// Original name of the file, not including a path. This information enables an
@@ -699,30 +809,85 @@ namespace SabreTools.Serialization.Wrappers
/// the name depends on the file system for which the file was created. This string
/// is required.
/// </summary/>
public string? OriginalFilename => GetVersionInfoString(key: "OriginalFilename");
public string? OriginalFilename
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("OriginalFilename");
return field;
}
} = null;
/// <summary>
/// Information about a private version of the file—for example, "Built by TESTER1 on
/// \TESTBED". This string should be present only if VS_FF_PRIVATEBUILD is specified in
/// the fileflags parameter of the root block.
/// </summary/>
public string? PrivateBuild => GetVersionInfoString(key: "PrivateBuild");
public string? PrivateBuild
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("PrivateBuild");
return field;
}
} = null;
/// <summary>
/// "Product GUID"
/// </summary/>
public string? ProductGuid => GetVersionInfoString("ProductGuid");
public string? ProductGuid
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("ProductGuid");
return field;
}
} = null;
/// <summary>
/// Name of the product with which the file is distributed. This string is required.
/// </summary/>
public string? ProductName => GetVersionInfoString(key: "ProductName");
public string? ProductName
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("ProductName");
return field;
}
} = null;
/// <summary>
/// Version of the product with which the file is distributed—for example, "3.10" or
/// "5.00.RC2". This string is required.
/// </summary/>
public string? ProductVersion => GetVersionInfoString(key: "ProductVersion");
public string? ProductVersion
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("ProductVersion");
return field;
}
} = null;
/// <summary>
/// Text that specifies how this version of the file differs from the standard
@@ -730,12 +895,34 @@ namespace SabreTools.Serialization.Wrappers
/// M250E computers". This string should be present only if VS_FF_SPECIALBUILD is
/// specified in the fileflags parameter of the root block.
/// </summary/>
public string? SpecialBuild => GetVersionInfoString(key: "SpecialBuild") ?? GetVersionInfoString(key: "Special Build");
public string? SpecialBuild
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("SpecialBuild") ?? GetVersionInfoString("Special Build");
return field;
}
} = null;
/// <summary>
/// "Trade name"
/// </summary/>
public string? TradeName => GetVersionInfoString(key: "TradeName");
public string? TradeName
{
get
{
// Use the cached data if possible
if (field != null)
return field;
field = GetVersionInfoString("TradeName");
return field;
}
} = null;
/// <summary>
/// Get the internal version as reported by the resources

View File

@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Common;
@@ -28,7 +28,7 @@ namespace SabreTools.Serialization.Wrappers
if (_dataSource == null || !_dataSource.CanRead)
return false;
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
try
{
var readerOptions = new ReaderOptions() { LookForHeader = lookForHeader };
@@ -96,9 +96,9 @@ namespace SabreTools.Serialization.Wrappers
return ExtractNonSolid(rarFile, outputDirectory, includeDebug);
}
catch (System.Exception ex)
catch (Exception ex)
{
if (includeDebug) System.Console.Error.WriteLine(ex);
if (includeDebug) Console.Error.WriteLine(ex);
return false;
}
#else
@@ -193,7 +193,7 @@ namespace SabreTools.Serialization.Wrappers
return parts;
}
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
/// <summary>
/// Extraction method for non-solid archives. This iterates over each entry in the archive to extract every
/// file individually, in order to extract all valid files from the archive.
@@ -231,9 +231,9 @@ namespace SabreTools.Serialization.Wrappers
entry.WriteToFile(filename);
}
catch (System.Exception ex)
catch (Exception ex)
{
if (includeDebug) System.Console.Error.WriteLine(ex);
if (includeDebug) Console.Error.WriteLine(ex);
}
}
return true;
@@ -257,9 +257,9 @@ namespace SabreTools.Serialization.Wrappers
});
}
catch (System.Exception ex)
catch (Exception ex)
{
if (includeDebug) System.Console.Error.WriteLine(ex);
if (includeDebug) Console.Error.WriteLine(ex);
}
return true;

View File

@@ -50,6 +50,10 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine(header6.FileDataOffset, " File data offset");
builder.AppendLine(header6.Dummy0, " Dummy 0");
break;
default:
builder.AppendLine($" Unrecognized header type");
break;
}
builder.AppendLine();

View File

@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;
using SharpCompress.Readers;
@@ -27,7 +27,7 @@ namespace SabreTools.Serialization.Wrappers
if (_dataSource == null || !_dataSource.CanRead)
return false;
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
try
{
var readerOptions = new ReaderOptions() { LookForHeader = lookForHeader };
@@ -95,9 +95,9 @@ namespace SabreTools.Serialization.Wrappers
return ExtractNonSolid(sevenZip, outputDirectory, includeDebug);
}
catch (System.Exception ex)
catch (Exception ex)
{
if (includeDebug) System.Console.Error.WriteLine(ex);
if (includeDebug) Console.Error.WriteLine(ex);
return false;
}
#else
@@ -161,7 +161,7 @@ namespace SabreTools.Serialization.Wrappers
return parts;
}
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
/// <summary>
/// Extraction method for non-solid archives. This iterates over each entry in the archive to extract every
/// file individually, in order to extract all valid files from the archive.
@@ -199,9 +199,9 @@ namespace SabreTools.Serialization.Wrappers
entry.WriteToFile(filename);
}
catch (System.Exception ex)
catch (Exception ex)
{
if (includeDebug) System.Console.Error.WriteLine(ex);
if (includeDebug) Console.Error.WriteLine(ex);
}
}
return true;
@@ -249,9 +249,9 @@ namespace SabreTools.Serialization.Wrappers
}
}
catch (System.Exception ex)
catch (Exception ex)
{
if (includeDebug) System.Console.Error.WriteLine(ex);
if (includeDebug) Console.Error.WriteLine(ex);
}
return true;

View File

@@ -21,11 +21,11 @@ namespace SabreTools.Serialization.Wrappers
Print(builder, Model.Entries);
}
private static void Print(StringBuilder builder, Entry[]? entries)
private static void Print(StringBuilder builder, Entry[] entries)
{
builder.AppendLine(" Entries Information:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Length == 0)
if (entries.Length == 0)
{
builder.AppendLine(" No entries");
builder.AppendLine();

View File

@@ -22,28 +22,21 @@ namespace SabreTools.Serialization.Wrappers
PrintLumps(builder, Model);
}
private static void Print(StringBuilder builder, VbspHeader? header)
private static void Print(StringBuilder builder, VbspHeader header)
{
builder.AppendLine(" Header Information:");
builder.AppendLine(" -------------------------");
if (header == null)
{
builder.AppendLine(" No header");
builder.AppendLine();
return;
}
builder.AppendLine(header.Signature, " Signature");
builder.AppendLine(header.Version, " Version");
builder.AppendLine(header.MapRevision, " Map revision");
builder.AppendLine();
}
private static void PrintLumps(StringBuilder builder, VbspFile? model)
private static void PrintLumps(StringBuilder builder, VbspFile model)
{
builder.AppendLine(" Lumps Information:");
builder.AppendLine(" -------------------------");
if (model?.Header?.Lumps == null || model.Header.Lumps.Length == 0)
if (model.Header.Lumps.Length == 0)
{
builder.AppendLine(" No lumps");
builder.AppendLine();

View File

@@ -18,7 +18,7 @@ namespace SabreTools.Serialization.Wrappers
/// <summary>
/// Array of archive filenames attached to the given VPK
/// </summary>
public string[]? ArchiveFilenames
public string[] ArchiveFilenames
{
get
{
@@ -28,7 +28,10 @@ namespace SabreTools.Serialization.Wrappers
// If we don't have a source filename
if (string.IsNullOrEmpty(Filename))
return null;
{
field = [];
return field;
}
// If the filename is not the right format
string extension = Path.GetExtension(Filename).TrimStart('.');
@@ -38,13 +41,19 @@ namespace SabreTools.Serialization.Wrappers
: Path.Combine(directoryName, Path.GetFileNameWithoutExtension(Filename));
if (fileName.Length < 3)
return null;
{
field = [];
return field;
}
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
else if (fileName[^3..] != "dir")
#else
else if (fileName.Substring(fileName.Length - 3) != "dir")
#endif
return null;
{
field = [];
return field;
}
// Get the archive count
ushort archiveCount = 0;

View File

@@ -22,53 +22,57 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
long offset = 0;
// Use the cached data if possible
if (field > -1)
return field;
offset += 1; // DllNameLen
field = 0;
field += 1; // DllNameLen
if (Model.DllNameLen > 0)
{
offset += Model.DllNameLen;
offset += 4; // DllSize
field += Model.DllNameLen;
field += 4; // DllSize
}
offset += 4; // Flags
offset += 12; // GraphicsData
offset += 4; // WiseScriptExitEventOffset
offset += 4; // WiseScriptCancelEventOffset
offset += 4; // WiseScriptInflatedSize
offset += 4; // WiseScriptDeflatedSize
offset += 4; // WiseDllDeflatedSize
offset += 4; // Ctl3d32DeflatedSize
offset += 4; // SomeData4DeflatedSize
offset += 4; // RegToolDeflatedSize
offset += 4; // ProgressDllDeflatedSize
offset += 4; // SomeData7DeflatedSize
offset += 4; // SomeData8DeflatedSize
offset += 4; // SomeData9DeflatedSize
offset += 4; // SomeData10DeflatedSize
offset += 4; // FinalFileDeflatedSize
offset += 4; // FinalFileInflatedSize
offset += 4; // EOF
field += 4; // Flags
field += 12; // GraphicsData
field += 4; // WiseScriptExitEventOffset
field += 4; // WiseScriptCancelEventOffset
field += 4; // WiseScriptInflatedSize
field += 4; // WiseScriptDeflatedSize
field += 4; // WiseDllDeflatedSize
field += 4; // Ctl3d32DeflatedSize
field += 4; // SomeData4DeflatedSize
field += 4; // RegToolDeflatedSize
field += 4; // ProgressDllDeflatedSize
field += 4; // SomeData7DeflatedSize
field += 4; // SomeData8DeflatedSize
field += 4; // SomeData9DeflatedSize
field += 4; // SomeData10DeflatedSize
field += 4; // FinalFileDeflatedSize
field += 4; // FinalFileInflatedSize
field += 4; // EOF
if (DibDeflatedSize == 0 && Model.Endianness == 0)
return offset;
return field;
offset += 4; // DibDeflatedSize
offset += 4; // DibInflatedSize
field += 4; // DibDeflatedSize
field += 4; // DibInflatedSize
if (Model.InstallScriptDeflatedSize != null)
offset += 4; // InstallScriptDeflatedSize
field += 4; // InstallScriptDeflatedSize
if (Model.CharacterSet != null)
offset += 4; // CharacterSet
field += 4; // CharacterSet
offset += 2; // Endianness
offset += 1; // InitTextLen
offset += Model.InitTextLen;
field += 2; // Endianness
field += 1; // InitTextLen
field += Model.InitTextLen;
return offset;
return field;
}
}
} = -1;
/// <summary>
/// Installer data offset

View File

@@ -4,7 +4,7 @@ using System.IO;
using System.Text;
using SabreTools.Data.Models.WiseInstaller;
using SabreTools.Data.Models.WiseInstaller.Actions;
#if NETFRAMEWORK || NETSTANDARD
#if NETFRAMEWORK || NETSTANDARD2_0
using SabreTools.IO.Extensions;
#endif

View File

@@ -89,13 +89,9 @@ namespace SabreTools.Serialization.Wrappers
var destination = new MemoryStream();
ExtractionStatus status;
if (!(Version != null && Version[1] == 0x01))
{
status = ExtractStreamWithChecksum(destination, entrySize, includeDebug);
}
else // hack for Codesited5.exe , very early and very strange.
{
status = ExtractStreamWithoutChecksum(destination, entrySize, includeDebug);
}
// If the extracted data is invalid
if (status != ExtractionStatus.GOOD || destination == null)

View File

@@ -43,7 +43,7 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine(Model.PreStringValues, "Pre-string values");
builder.AppendLine();
builder.AppendLine("Strings:");
if (Model.Strings == null || Model.Strings.Length == 0)
if (Model.Strings.Length == 0)
{
builder.AppendLine(" No strings");
}

View File

@@ -89,7 +89,7 @@ namespace SabreTools.Serialization.Wrappers
public byte[] PreStringValues => Model.PreStringValues;
/// <inheritdoc cref="SectionHeader.Strings"/>
public byte[][]? Strings => Model.Strings;
public byte[][] Strings => Model.Strings;
#endregion

View File

@@ -17,13 +17,13 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine("Xbox Media Identifier Information:");
builder.AppendLine("-------------------------");
builder.AppendLine(Model.PublisherIdentifier, "Publisher identifier");
if (!string.IsNullOrEmpty(Model.PublisherIdentifier) && Publishers.ContainsKey(Model.PublisherIdentifier ?? string.Empty))
builder.AppendLine(Publishers[Model.PublisherIdentifier ?? string.Empty], "Publisher");
if (Publishers.TryGetValue(Model.PublisherIdentifier, out var publisher))
builder.AppendLine(publisher, "Publisher");
builder.AppendLine(Model.GameID, "Game ID");
builder.AppendLine(Model.VersionNumber, "Version number");
builder.AppendLine(Model.RegionIdentifier, "Region identifier");
if (Regions.ContainsKey(Model.RegionIdentifier))
builder.AppendLine(Regions[Model.RegionIdentifier], "Region");
if (Regions.TryGetValue(Model.RegionIdentifier, out var region))
builder.AppendLine(region, "Region");
builder.AppendLine();
}
}

View File

@@ -22,16 +22,20 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
var publisherIdentifier = Model.PublisherIdentifier;
if (string.IsNullOrEmpty(publisherIdentifier))
return "Unknown";
// Use the cached data if possible
if (field != null)
return field;
if (Publishers.ContainsKey(publisherIdentifier!))
return Publishers[publisherIdentifier!];
if (Publishers.TryGetValue(Model.PublisherIdentifier, out var publisher))
{
field = publisher;
return field;
}
return $"Unknown ({publisherIdentifier})";
field = $"Unknown ({Model.PublisherIdentifier})";
return field;
}
}
} = null;
/// <summary>
/// Get the human-readable region string
@@ -40,13 +44,20 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
var regionIdentifier = Model.RegionIdentifier;
if (Regions.ContainsKey(regionIdentifier))
return Regions[regionIdentifier];
// Use the cached data if possible
if (field != null)
return field;
return $"Unknown ({regionIdentifier})";
if (Regions.TryGetValue(Model.RegionIdentifier, out var region))
{
field = region;
return field;
}
field = $"Unknown ({Model.RegionIdentifier})";
return field;
}
}
} = null;
/// <summary>
/// Get the human-readable serial string

View File

@@ -1,5 +1,5 @@
using System;
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
using System.IO;
using SharpCompress.Compressors.Xz;
#endif
@@ -19,7 +19,7 @@ namespace SabreTools.Serialization.Wrappers
if (_dataSource == null || !_dataSource.CanRead)
return false;
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
try
{
// Try opening the stream

View File

@@ -17,18 +17,18 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine("Xbox Media Identifier Information:");
builder.AppendLine("-------------------------");
builder.AppendLine(Model.PublisherIdentifier, "Publisher identifier");
if (!string.IsNullOrEmpty(Model.PublisherIdentifier) && Publishers.ContainsKey(Model.PublisherIdentifier ?? string.Empty))
builder.AppendLine(Publishers[Model.PublisherIdentifier ?? string.Empty], "Publisher");
if (Publishers.TryGetValue(Model.PublisherIdentifier, out var publisher))
builder.AppendLine(publisher, "Publisher");
builder.AppendLine(Model.PlatformIdentifier, "Platform identifier");
builder.AppendLine(Model.GameID, "Game ID");
builder.AppendLine(Model.SKU, "SKU");
builder.AppendLine(Model.RegionIdentifier, "Region identifier");
if (Regions.ContainsKey(Model.RegionIdentifier))
builder.AppendLine(Regions[Model.RegionIdentifier], "Region");
if (Regions.TryGetValue(Model.RegionIdentifier, out var region))
builder.AppendLine(region, "Region");
builder.AppendLine(Model.BaseVersion, "Base version");
builder.AppendLine(Model.MediaSubtypeIdentifier, "Media subtype identifier");
if (MediaSubtypes.ContainsKey(Model.MediaSubtypeIdentifier))
builder.AppendLine(MediaSubtypes[Model.MediaSubtypeIdentifier], "Media subtype");
if (MediaSubtypes.TryGetValue(Model.MediaSubtypeIdentifier, out var mediaSubtype))
builder.AppendLine(mediaSubtype, "Media subtype");
builder.AppendLine(Model.DiscNumberIdentifier, "Disc number identifier");
builder.AppendLine(Model.CertificationSubmissionIdentifier, "Certification submission identifier");
builder.AppendLine();

View File

@@ -22,13 +22,20 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
char mediaSubtype = Model.MediaSubtypeIdentifier;
if (MediaSubtypes.ContainsKey(mediaSubtype))
return MediaSubtypes[mediaSubtype];
// Use the cached data if possible
if (field != null)
return field;
return $"Unknown ({mediaSubtype})";
if (MediaSubtypes.TryGetValue(Model.MediaSubtypeIdentifier, out var mediaSubtype))
{
field = mediaSubtype;
return field;
}
field = $"Unknown ({Model.MediaSubtypeIdentifier})";
return field;
}
}
} = null;
/// <summary>
/// Get the human-readable publisher string
@@ -37,16 +44,20 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
var publisherIdentifier = Model.PublisherIdentifier;
if (string.IsNullOrEmpty(publisherIdentifier))
return "Unknown";
// Use the cached data if possible
if (field != null)
return field;
if (Publishers.ContainsKey(publisherIdentifier!))
return Publishers[publisherIdentifier!];
if (Publishers.TryGetValue(Model.PublisherIdentifier, out var publisher))
{
field = publisher;
return field;
}
return $"Unknown ({publisherIdentifier})";
field = $"Unknown ({Model.PublisherIdentifier})";
return field;
}
}
} = null;
/// <summary>
/// Get the human-readable region string
@@ -55,13 +66,20 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
var regionIdentifier = Model.RegionIdentifier;
if (Regions.ContainsKey(regionIdentifier))
return Regions[regionIdentifier];
// Use the cached data if possible
if (field != null)
return field;
return $"Unknown ({regionIdentifier})";
if (Regions.TryGetValue(Model.RegionIdentifier, out var region))
{
field = region;
return field;
}
field = $"Unknown ({Model.RegionIdentifier})";
return field;
}
}
} = null;
/// <summary>
/// Get the human-readable serial string

View File

@@ -1,6 +1,9 @@
using System;
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
using System.IO;
#if NET462_OR_GREATER || NETCOREAPP
#endif
using SabreTools.IO.Extensions;
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
using SharpCompress.Compressors.ZStandard;
#endif
@@ -17,13 +20,13 @@ namespace SabreTools.Serialization.Wrappers
public bool Extract(string outputDirectory, bool includeDebug)
{
// Ensure there is data to extract
if (Magic == null)
if (!Magic.EqualsExactly(Data.Models.ZSTD.Constants.SignatureBytes))
{
if (includeDebug) Console.Error.WriteLine("Invalid archive detected, skipping...");
return false;
}
#if NET462_OR_GREATER || NETCOREAPP
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
try
{
// Ensure directory separators are consistent