mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-02-04 05:36:12 +00:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9574232719 | ||
|
|
676bf584d6 | ||
|
|
0a4fd01ede | ||
|
|
6cb4023498 | ||
|
|
8f775dbb3b | ||
|
|
91785eab1f | ||
|
|
4f8751667a | ||
|
|
ad7508c464 | ||
|
|
97a9e141ae | ||
|
|
842a0c3daf | ||
|
|
b6acde9145 | ||
|
|
b97dbc2ac5 | ||
|
|
e03852bd7e | ||
|
|
0db5de204e | ||
|
|
5fe3f14419 | ||
|
|
ffe1d9a82d | ||
|
|
11d6560290 | ||
|
|
e29d8e6728 | ||
|
|
918e81a4cb | ||
|
|
ad0ddede38 | ||
|
|
e969b12884 | ||
|
|
7a5475255f | ||
|
|
0ffd436de8 | ||
|
|
4f685187e9 | ||
|
|
2b356b37b1 | ||
|
|
7c56268eb1 | ||
|
|
970a54e6e3 | ||
|
|
e35ddf0780 | ||
|
|
bf35b7c10b | ||
|
|
4026b8ca09 | ||
|
|
6d2e2d8c3b | ||
|
|
a2b08157cc | ||
|
|
0108ecf4c1 | ||
|
|
4921da0bb5 | ||
|
|
0c836bb3b1 | ||
|
|
a8e41c1505 | ||
|
|
f67e1c9d2b | ||
|
|
f0ce58a79e | ||
|
|
b7f782c1b7 | ||
|
|
5e39e169b2 | ||
|
|
104c5ccad4 |
@@ -10,7 +10,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.9.2</Version>
|
||||
<Version>1.9.6</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
@@ -66,8 +66,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.IO" Version="1.7.2" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.7.5" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.9" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Serialization;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace ExtractionTool
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.9.2</Version>
|
||||
<Version>1.9.6</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
@@ -32,7 +32,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.IO" Version="1.7.2" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.7.5" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -110,6 +110,9 @@ Below is a table of all namespaces within the library and what they represent
|
||||
| --- | --- |
|
||||
| `SabreTools.Serialization.CrossModel` | Convert between models; mainly used for metadata files converting to and from a common, `Dictionary`-based model |
|
||||
| `SabreTools.Serialization.Deserializers` | Convert from external sources to models |
|
||||
| `SabreTools.Serialization.Extensions` | Extension methods for both models and wrappers |
|
||||
| `SabreTools.Serialization.Interfaces` | Interfaces used commonly throughout the library |
|
||||
| `SabreTools.Serialization.ObjectIdentifier` | Object Identifier (OID) parsing |
|
||||
| `SabreTools.Serialization.Printers` | Export model information in a formatted manner |
|
||||
| `SabreTools.Serialization.Serializers` | Convert from models to external sources |
|
||||
| `SabreTools.Serialization.Wrappers` | Classes that wrap serialization and models to allow for including extension properties |
|
||||
|
||||
@@ -97,7 +97,11 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
Name = "XXXXXX",
|
||||
Size = "XXXXXX",
|
||||
CRC = "XXXXXX",
|
||||
MD2 = "XXXXXX",
|
||||
MD4 = "XXXXXX",
|
||||
MD5 = "XXXXXX",
|
||||
RIPEMD128 = "XXXXXX",
|
||||
RIPEMD160 = "XXXXXX",
|
||||
SHA1 = "XXXXXX",
|
||||
Merge = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
@@ -346,7 +350,11 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
Assert.Equal("XXXXXX", rom.Name);
|
||||
Assert.Equal("XXXXXX", rom.Size);
|
||||
Assert.Equal("XXXXXX", rom.CRC);
|
||||
Assert.Equal("XXXXXX", rom.MD2);
|
||||
Assert.Equal("XXXXXX", rom.MD4);
|
||||
Assert.Equal("XXXXXX", rom.MD5);
|
||||
Assert.Equal("XXXXXX", rom.RIPEMD128);
|
||||
Assert.Equal("XXXXXX", rom.RIPEMD160);
|
||||
Assert.Equal("XXXXXX", rom.SHA1);
|
||||
Assert.Equal("XXXXXX", rom.Merge);
|
||||
Assert.Equal("XXXXXX", rom.Status);
|
||||
|
||||
@@ -150,7 +150,11 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
Name = "XXXXXX",
|
||||
Size = "XXXXXX",
|
||||
CRC = "XXXXXX",
|
||||
MD2 = "XXXXXX",
|
||||
MD4 = "XXXXXX",
|
||||
MD5 = "XXXXXX",
|
||||
RIPEMD128 = "XXXXXX",
|
||||
RIPEMD160 = "XXXXXX",
|
||||
SHA1 = "XXXXXX",
|
||||
SHA256 = "XXXXXX",
|
||||
SHA384 = "XXXXXX",
|
||||
@@ -460,7 +464,11 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
Assert.Equal("XXXXXX", rom.Name);
|
||||
Assert.Equal("XXXXXX", rom.Size);
|
||||
Assert.Equal("XXXXXX", rom.CRC);
|
||||
Assert.Equal("XXXXXX", rom.MD2);
|
||||
Assert.Equal("XXXXXX", rom.MD4);
|
||||
Assert.Equal("XXXXXX", rom.MD5);
|
||||
Assert.Equal("XXXXXX", rom.RIPEMD128);
|
||||
Assert.Equal("XXXXXX", rom.RIPEMD160);
|
||||
Assert.Equal("XXXXXX", rom.SHA1);
|
||||
Assert.Equal("XXXXXX", rom.SHA256);
|
||||
Assert.Equal("XXXXXX", rom.SHA384);
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Models.ASN1;
|
||||
using SabreTools.Serialization.Deserializers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Deserializers
|
||||
{
|
||||
public class AbstractSyntaxNotationOneTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidMinimalStream_NotNull()
|
||||
{
|
||||
Stream data = new MemoryStream([0x00]);
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.NotNull(actual);
|
||||
|
||||
var actualSingle = Assert.Single(actual);
|
||||
Assert.Equal(ASN1Type.V_ASN1_EOC, actualSingle.Type);
|
||||
Assert.Equal(default, actualSingle.Length);
|
||||
Assert.Null(actualSingle.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidBoolean_NotNull()
|
||||
{
|
||||
Stream data = new MemoryStream([0x01, 0x01, 0x01]);
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.NotNull(actual);
|
||||
|
||||
var actualSingle = Assert.Single(actual);
|
||||
Assert.Equal(ASN1Type.V_ASN1_BOOLEAN, actualSingle.Type);
|
||||
Assert.Equal(1UL, actualSingle.Length);
|
||||
Assert.NotNull(actualSingle.Value);
|
||||
|
||||
byte[]? valueAsArray = actualSingle.Value as byte[];
|
||||
Assert.NotNull(valueAsArray);
|
||||
byte actualValue = Assert.Single(valueAsArray);
|
||||
Assert.Equal(0x01, actualValue);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 0x26, 0x81, 0x03, 0x01, 0x01, 0x01 })]
|
||||
[InlineData(new byte[] { 0x26, 0x82, 0x00, 0x03, 0x01, 0x01, 0x01 })]
|
||||
[InlineData(new byte[] { 0x26, 0x83, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
|
||||
[InlineData(new byte[] { 0x26, 0x84, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
|
||||
[InlineData(new byte[] { 0x26, 0x85, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
|
||||
[InlineData(new byte[] { 0x26, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
|
||||
[InlineData(new byte[] { 0x26, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
|
||||
[InlineData(new byte[] { 0x26, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
|
||||
public void ComplexValue_NotNull(byte[] arr)
|
||||
{
|
||||
Stream data = new MemoryStream(arr);
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.NotNull(actual);
|
||||
|
||||
var actualSingle = Assert.Single(actual);
|
||||
Assert.Equal(ASN1Type.V_ASN1_CONSTRUCTED | ASN1Type.V_ASN1_OBJECT, actualSingle.Type);
|
||||
Assert.Equal(3UL, actualSingle.Length);
|
||||
Assert.NotNull(actualSingle.Value);
|
||||
|
||||
TypeLengthValue[]? valueAsArray = actualSingle.Value as TypeLengthValue[];
|
||||
Assert.NotNull(valueAsArray);
|
||||
TypeLengthValue actualSub = Assert.Single(valueAsArray);
|
||||
|
||||
Assert.Equal(ASN1Type.V_ASN1_BOOLEAN, actualSub.Type);
|
||||
Assert.Equal(1UL, actualSub.Length);
|
||||
Assert.NotNull(actualSub.Value);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 0x26, 0x80 })]
|
||||
[InlineData(new byte[] { 0x26, 0x89 })]
|
||||
public void ComplexValueInvalidLength_Null(byte[] arr)
|
||||
{
|
||||
Stream data = new MemoryStream(arr);
|
||||
var deserializer = new AbstractSyntaxNotationOne();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +215,11 @@ namespace SabreTools.Serialization.Test.Deserializers
|
||||
Name = "XXXXXX",
|
||||
Size = "XXXXXX",
|
||||
CRC = "XXXXXX",
|
||||
MD2 = "XXXXXX",
|
||||
MD4 = "XXXXXX",
|
||||
MD5 = "XXXXXX",
|
||||
RIPEMD128 = "XXXXXX",
|
||||
RIPEMD160 = "XXXXXX",
|
||||
SHA1 = "XXXXXX",
|
||||
Merge = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
@@ -464,7 +468,11 @@ namespace SabreTools.Serialization.Test.Deserializers
|
||||
Assert.Equal("XXXXXX", rom.Name);
|
||||
Assert.Equal("XXXXXX", rom.Size);
|
||||
Assert.Equal("XXXXXX", rom.CRC);
|
||||
Assert.Equal("XXXXXX", rom.MD2);
|
||||
Assert.Equal("XXXXXX", rom.MD4);
|
||||
Assert.Equal("XXXXXX", rom.MD5);
|
||||
Assert.Equal("XXXXXX", rom.RIPEMD128);
|
||||
Assert.Equal("XXXXXX", rom.RIPEMD160);
|
||||
Assert.Equal("XXXXXX", rom.SHA1);
|
||||
Assert.Equal("XXXXXX", rom.Merge);
|
||||
Assert.Equal("XXXXXX", rom.Status);
|
||||
|
||||
@@ -217,7 +217,11 @@ namespace SabreTools.Serialization.Test.Deserializers
|
||||
Name = "XXXXXX",
|
||||
Size = "XXXXXX",
|
||||
CRC = "XXXXXX",
|
||||
MD2 = "XXXXXX",
|
||||
MD4 = "XXXXXX",
|
||||
MD5 = "XXXXXX",
|
||||
RIPEMD128 = "XXXXXX",
|
||||
RIPEMD160 = "XXXXXX",
|
||||
SHA1 = "XXXXXX",
|
||||
SHA256 = "XXXXXX",
|
||||
SHA384 = "XXXXXX",
|
||||
@@ -512,7 +516,11 @@ namespace SabreTools.Serialization.Test.Deserializers
|
||||
Assert.Equal("XXXXXX", rom.Name);
|
||||
Assert.Equal("XXXXXX", rom.Size);
|
||||
Assert.Equal("XXXXXX", rom.CRC);
|
||||
Assert.Equal("XXXXXX", rom.MD2);
|
||||
Assert.Equal("XXXXXX", rom.MD4);
|
||||
Assert.Equal("XXXXXX", rom.MD5);
|
||||
Assert.Equal("XXXXXX", rom.RIPEMD128);
|
||||
Assert.Equal("XXXXXX", rom.RIPEMD160);
|
||||
Assert.Equal("XXXXXX", rom.SHA1);
|
||||
Assert.Equal("XXXXXX", rom.SHA256);
|
||||
Assert.Equal("XXXXXX", rom.SHA384);
|
||||
|
||||
213
SabreTools.Serialization.Test/Extensions/TypeLengthValueTests.cs
Normal file
213
SabreTools.Serialization.Test/Extensions/TypeLengthValueTests.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using SabreTools.Models.ASN1;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Extensions
|
||||
{
|
||||
public class TypeLengthValueTests
|
||||
{
|
||||
#region Formatting
|
||||
|
||||
[Fact]
|
||||
public void Format_EOC()
|
||||
{
|
||||
string expected = "Type: V_ASN1_EOC";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_EOC, Length = 0, Value = null };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ZeroLength()
|
||||
{
|
||||
string expected = "Type: V_ASN1_NULL, Length: 0";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_NULL, Length = 0, Value = null };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_InvalidConstructed()
|
||||
{
|
||||
string expected = "Type: V_ASN1_OBJECT, V_ASN1_CONSTRUCTED, Length: 1, Value: [INVALID DATA TYPE]";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT | ASN1Type.V_ASN1_CONSTRUCTED, Length = 1, Value = (object?)false };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidConstructed()
|
||||
{
|
||||
string expected = "Type: V_ASN1_OBJECT, V_ASN1_CONSTRUCTED, Length: 3, Value:\n Type: V_ASN1_BOOLEAN, Length: 1, Value: True";
|
||||
var boolTlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BOOLEAN, Length = 1, Value = new byte[] { 0x01 } };
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT | ASN1Type.V_ASN1_CONSTRUCTED, Length = 3, Value = new Models.ASN1.TypeLengthValue[] { boolTlv } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_InvalidDataType()
|
||||
{
|
||||
string expected = "Type: V_ASN1_OBJECT, Length: 1, Value: [INVALID DATA TYPE]";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT, Length = 1, Value = (object?)false };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_InvalidLength()
|
||||
{
|
||||
string expected = "Type: V_ASN1_NULL, Length: 1, Value: [NO DATA]";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_NULL, Length = 1, Value = Array.Empty<byte>() };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_InvalidBooleanLength()
|
||||
{
|
||||
string expected = "Type: V_ASN1_BOOLEAN, Length: 2 [Expected length of 1], Value: True";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BOOLEAN, Length = 2, Value = new byte[] { 0x01 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_InvalidBooleanArrayLength()
|
||||
{
|
||||
string expected = "Type: V_ASN1_BOOLEAN, Length: 1 [Expected value length of 1], Value: True";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BOOLEAN, Length = 1, Value = new byte[] { 0x01, 0x00 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidBoolean()
|
||||
{
|
||||
string expected = "Type: V_ASN1_BOOLEAN, Length: 1, Value: True";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BOOLEAN, Length = 1, Value = new byte[] { 0x01 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidInteger()
|
||||
{
|
||||
string expected = "Type: V_ASN1_INTEGER, Length: 1, Value: 1";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_INTEGER, Length = 1, Value = new byte[] { 0x01 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidBitString_NoBits()
|
||||
{
|
||||
string expected = "Type: V_ASN1_BIT_STRING, Length: 1, Value with 0 unused bits";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BIT_STRING, Length = 1, Value = new byte[] { 0x00 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidBitString_Bits()
|
||||
{
|
||||
string expected = "Type: V_ASN1_BIT_STRING, Length: 1, Value with 1 unused bits: 01";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BIT_STRING, Length = 1, Value = new byte[] { 0x01, 0x01 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidOctetString()
|
||||
{
|
||||
string expected = "Type: V_ASN1_OCTET_STRING, Length: 1, Value: 01";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OCTET_STRING, Length = 1, Value = new byte[] { 0x01 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidObject()
|
||||
{
|
||||
string expected = "Type: V_ASN1_OBJECT, Length: 3, Value: 0.1.2.3 (/ITU-T/1/2/3)";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT, Length = 3, Value = new byte[] { 0x01, 0x02, 0x03 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidUTF8String()
|
||||
{
|
||||
string expected = "Type: V_ASN1_UTF8STRING, Length: 3, Value: ABC";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_UTF8STRING, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidPrintableString()
|
||||
{
|
||||
string expected = "Type: V_ASN1_PRINTABLESTRING, Length: 3, Value: ABC";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_PRINTABLESTRING, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidTeletexString()
|
||||
{
|
||||
string expected = "Type: V_ASN1_TELETEXSTRING, Length: 3, Value: ABC";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_TELETEXSTRING, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidIA5String()
|
||||
{
|
||||
string expected = "Type: V_ASN1_IA5STRING, Length: 3, Value: ABC";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_IA5STRING, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_InvalidUTCTime()
|
||||
{
|
||||
string expected = "Type: V_ASN1_UTCTIME, Length: 3, Value: ABC";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_UTCTIME, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidUTCTime()
|
||||
{
|
||||
string expected = "Type: V_ASN1_UTCTIME, Length: 3, Value: 1980-01-01 00:00:00";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_UTCTIME, Length = 3, Value = new byte[] { 0x31, 0x39, 0x38, 0x30, 0x2D, 0x30, 0x31, 0x2D, 0x30, 0x31, 0x20, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x3A, 0x30, 0x30 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidBmpString()
|
||||
{
|
||||
string expected = "Type: V_ASN1_BMPSTRING, Length: 6, Value: ABC";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BMPSTRING, Length = 6, Value = new byte[] { 0x41, 0x00, 0x42, 0x00, 0x43, 0x00 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Format_ValidUnformatted()
|
||||
{
|
||||
string expected = "Type: V_ASN1_OBJECT_DESCRIPTOR, Length: 1, Value: 01";
|
||||
var tlv = new Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT_DESCRIPTOR, Length = 1, Value = new byte[] { 0x01 } };
|
||||
string actual = tlv.Format();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
111
SabreTools.Serialization.Test/ObjectIdentifier/ParserTests.cs
Normal file
111
SabreTools.Serialization.Test/ObjectIdentifier/ParserTests.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using SabreTools.Serialization.ObjectIdentifier;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.ObjectIdentifier
|
||||
{
|
||||
// These tests are known to be incomplete due to the sheer number
|
||||
// of possible OIDs that exist. The tests below are a minimal
|
||||
// representation of functionality to guarantee proper behavior
|
||||
// not necessarily absolute outputs
|
||||
public class ParserTests
|
||||
{
|
||||
#region ASN.1
|
||||
|
||||
[Fact]
|
||||
public void ASN1Notation_AlwaysNull()
|
||||
{
|
||||
ulong[]? values = null;
|
||||
string? actual = Parser.ParseOIDToASN1Notation(values);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dot Notation
|
||||
|
||||
[Fact]
|
||||
public void DotNotation_NullValues_Null()
|
||||
{
|
||||
ulong[]? values = null;
|
||||
string? actual = Parser.ParseOIDToDotNotation(values);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DotNotation_EmptyValues_Null()
|
||||
{
|
||||
ulong[]? values = [];
|
||||
string? actual = Parser.ParseOIDToDotNotation(values);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DotNotation_Values_Formatted()
|
||||
{
|
||||
string expected = "0.1.2.3";
|
||||
ulong[]? values = [0, 1, 2, 3];
|
||||
string? actual = Parser.ParseOIDToDotNotation(values);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Modified OID-IRI
|
||||
|
||||
[Fact]
|
||||
public void ModifiedOIDIRI_NullValues_Null()
|
||||
{
|
||||
ulong[]? values = null;
|
||||
string? actual = Parser.ParseOIDToModifiedOIDIRI(values);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ModifiedOIDIRI_EmptyValues_Null()
|
||||
{
|
||||
ulong[]? values = [];
|
||||
string? actual = Parser.ParseOIDToModifiedOIDIRI(values);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ModifiedOIDIRI_Values_Formatted()
|
||||
{
|
||||
string expected = "/ITU-T/[question]/2/3";
|
||||
ulong[]? values = [0, 1, 2, 3];
|
||||
string? actual = Parser.ParseOIDToModifiedOIDIRI(values);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OID-IRI
|
||||
|
||||
[Fact]
|
||||
public void OIDIRI_NullValues_Null()
|
||||
{
|
||||
ulong[]? values = null;
|
||||
string? actual = Parser.ParseOIDToOIDIRINotation(values);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OIDIRI_EmptyValues_Null()
|
||||
{
|
||||
ulong[]? values = [];
|
||||
string? actual = Parser.ParseOIDToOIDIRINotation(values);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OIDIRI_Values_Formatted()
|
||||
{
|
||||
string expected = "/ITU-T/1/2/3";
|
||||
ulong[]? values = [0, 1, 2, 3];
|
||||
string? actual = Parser.ParseOIDToOIDIRINotation(values);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.5.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.7.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.7.2" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
61
SabreTools.Serialization.Test/Wrappers/LDSCRYPTTests.cs
Normal file
61
SabreTools.Serialization.Test/Wrappers/LDSCRYPTTests.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class LDSCRYPTTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = LDSCRYPT.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = LDSCRYPT.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = LDSCRYPT.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = LDSCRYPT.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = LDSCRYPT.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = LDSCRYPT.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class RealArcadeInstallerTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = RealArcadeInstaller.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = RealArcadeInstaller.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = RealArcadeInstaller.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = RealArcadeInstaller.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = RealArcadeInstaller.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = RealArcadeInstaller.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class RealArcadeMezzanineTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = RealArcadeMezzanine.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = RealArcadeMezzanine.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = RealArcadeMezzanine.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = RealArcadeMezzanine.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = RealArcadeMezzanine.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = RealArcadeMezzanine.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +275,11 @@ namespace SabreTools.Serialization.CrossModel
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
MD2 = item.ReadString(Models.Metadata.Rom.MD2Key),
|
||||
MD4 = item.ReadString(Models.Metadata.Rom.MD4Key),
|
||||
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
|
||||
RIPEMD128 = item.ReadString(Models.Metadata.Rom.RIPEMD128Key),
|
||||
RIPEMD160 = item.ReadString(Models.Metadata.Rom.RIPEMD160Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
|
||||
SHA384 = item.ReadString(Models.Metadata.Rom.SHA384Key),
|
||||
|
||||
@@ -291,7 +291,11 @@ namespace SabreTools.Serialization.CrossModel
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.MD2Key] = item.MD2,
|
||||
[Models.Metadata.Rom.MD4Key] = item.MD4,
|
||||
[Models.Metadata.Rom.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Rom.RIPEMD128Key] = item.RIPEMD128,
|
||||
[Models.Metadata.Rom.RIPEMD160Key] = item.RIPEMD160,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
|
||||
|
||||
@@ -28,6 +28,8 @@ namespace SabreTools.Serialization.CrossModel
|
||||
var md2s = new List<MD2>();
|
||||
var md4s = new List<MD4>();
|
||||
var md5s = new List<MD5>();
|
||||
var ripemd128s = new List<RIPEMD128>();
|
||||
var ripemd160s = new List<RIPEMD160>();
|
||||
var sha1s = new List<SHA1>();
|
||||
var sha256s = new List<SHA256>();
|
||||
var sha384s = new List<SHA384>();
|
||||
@@ -44,6 +46,10 @@ namespace SabreTools.Serialization.CrossModel
|
||||
md4s.AddRange(hashfile.MD4);
|
||||
if (hashfile.MD5 != null && hashfile.MD5.Length > 0)
|
||||
md5s.AddRange(hashfile.MD5);
|
||||
if (hashfile.RIPEMD128 != null && hashfile.RIPEMD128.Length > 0)
|
||||
ripemd128s.AddRange(hashfile.RIPEMD128);
|
||||
if (hashfile.RIPEMD160 != null && hashfile.RIPEMD160.Length > 0)
|
||||
ripemd160s.AddRange(hashfile.RIPEMD160);
|
||||
if (hashfile.SHA1 != null && hashfile.SHA1.Length > 0)
|
||||
sha1s.AddRange(hashfile.SHA1);
|
||||
if (hashfile.SHA256 != null && hashfile.SHA256.Length > 0)
|
||||
@@ -66,6 +72,10 @@ namespace SabreTools.Serialization.CrossModel
|
||||
hashfileItem.MD4 = [.. md4s];
|
||||
if (md5s.Count > 0)
|
||||
hashfileItem.MD5 = [.. md5s];
|
||||
if (ripemd128s.Count > 0)
|
||||
hashfileItem.RIPEMD128 = [.. ripemd128s];
|
||||
if (ripemd160s.Count > 0)
|
||||
hashfileItem.RIPEMD160 = [.. ripemd160s];
|
||||
if (sha1s.Count > 0)
|
||||
hashfileItem.SHA1 = [.. sha1s];
|
||||
if (sha256s.Count > 0)
|
||||
@@ -103,6 +113,12 @@ namespace SabreTools.Serialization.CrossModel
|
||||
MD5 = hash == HashType.MD5
|
||||
? Array.ConvertAll(roms, ConvertToMD5)
|
||||
: null,
|
||||
RIPEMD128 = hash == HashType.RIPEMD128
|
||||
? Array.ConvertAll(roms, ConvertToRIPEMD128)
|
||||
: null,
|
||||
RIPEMD160 = hash == HashType.RIPEMD160
|
||||
? Array.ConvertAll(roms, ConvertToRIPEMD160)
|
||||
: null,
|
||||
SHA1 = hash == HashType.SHA1
|
||||
? Array.ConvertAll(roms, ConvertToSHA1)
|
||||
: null,
|
||||
@@ -160,6 +176,32 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return md5;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Models.Hashfile.RIPEMD128"/>
|
||||
/// </summary>
|
||||
private static RIPEMD128 ConvertToRIPEMD128(Models.Metadata.Rom item)
|
||||
{
|
||||
var ripemd128 = new RIPEMD128
|
||||
{
|
||||
Hash = item.ReadString(Models.Metadata.Rom.RIPEMD128Key),
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
};
|
||||
return ripemd128;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Models.Hashfile.RIPEMD160"/>
|
||||
/// </summary>
|
||||
private static RIPEMD160 ConvertToRIPEMD160(Models.Metadata.Rom item)
|
||||
{
|
||||
var ripemd160 = new RIPEMD160
|
||||
{
|
||||
Hash = item.ReadString(Models.Metadata.Rom.RIPEMD160Key),
|
||||
File = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
};
|
||||
return ripemd160;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="Models.Hashfile.SFV"/>
|
||||
/// </summary>
|
||||
|
||||
@@ -50,6 +50,10 @@ namespace SabreTools.Serialization.CrossModel
|
||||
machine[Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD4, ConvertToInternalModel);
|
||||
else if (item.MD5 != null && item.MD5.Length > 0)
|
||||
machine[Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD5, ConvertToInternalModel);
|
||||
else if (item.RIPEMD128 != null && item.RIPEMD128.Length > 0)
|
||||
machine[Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.RIPEMD128, ConvertToInternalModel);
|
||||
else if (item.RIPEMD160 != null && item.RIPEMD160.Length > 0)
|
||||
machine[Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.RIPEMD160, ConvertToInternalModel);
|
||||
else if (item.SHA1 != null && item.SHA1.Length > 0)
|
||||
machine[Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA1, ConvertToInternalModel);
|
||||
else if (item.SHA256 != null && item.SHA256.Length > 0)
|
||||
@@ -103,6 +107,32 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Hashfile.RIPEMD128"/> to <see cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(RIPEMD128 item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.RIPEMD128Key] = item.Hash,
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Hashfile.RIPEMD160"/> to <see cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Rom ConvertToInternalModel(RIPEMD160 item)
|
||||
{
|
||||
var rom = new Models.Metadata.Rom
|
||||
{
|
||||
[Models.Metadata.Rom.RIPEMD160Key] = item.Hash,
|
||||
[Models.Metadata.Rom.NameKey] = item.File,
|
||||
};
|
||||
return rom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Hashfile.SFV"/> to <see cref="Models.Metadata.Rom"/>
|
||||
/// </summary>
|
||||
|
||||
@@ -302,7 +302,11 @@ namespace SabreTools.Serialization.CrossModel
|
||||
Name = item.ReadString(Models.Metadata.Rom.NameKey),
|
||||
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
|
||||
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
|
||||
MD2 = item.ReadString(Models.Metadata.Rom.MD2Key),
|
||||
MD4 = item.ReadString(Models.Metadata.Rom.MD4Key),
|
||||
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
|
||||
RIPEMD128 = item.ReadString(Models.Metadata.Rom.RIPEMD128Key),
|
||||
RIPEMD160 = item.ReadString(Models.Metadata.Rom.RIPEMD160Key),
|
||||
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
|
||||
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
|
||||
SHA384 = item.ReadString(Models.Metadata.Rom.SHA384Key),
|
||||
|
||||
@@ -298,7 +298,11 @@ namespace SabreTools.Serialization.CrossModel
|
||||
[Models.Metadata.Rom.NameKey] = item.Name,
|
||||
[Models.Metadata.Rom.SizeKey] = item.Size,
|
||||
[Models.Metadata.Rom.CRCKey] = item.CRC,
|
||||
[Models.Metadata.Rom.MD2Key] = item.MD2,
|
||||
[Models.Metadata.Rom.MD4Key] = item.MD4,
|
||||
[Models.Metadata.Rom.MD5Key] = item.MD5,
|
||||
[Models.Metadata.Rom.RIPEMD128Key] = item.RIPEMD128,
|
||||
[Models.Metadata.Rom.RIPEMD160Key] = item.RIPEMD160,
|
||||
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
|
||||
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
|
||||
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
|
||||
|
||||
@@ -70,25 +70,22 @@ namespace SabreTools.Serialization.Deserializers
|
||||
data.Seek(-4, SeekOrigin.Current);
|
||||
|
||||
// Create a record based on the type
|
||||
switch (type)
|
||||
return type switch
|
||||
{
|
||||
// Known record types
|
||||
case RecordType.EndOfMediaKeyBlock: return ParseEndOfMediaKeyBlockRecord(data);
|
||||
case RecordType.ExplicitSubsetDifference: return ParseExplicitSubsetDifferenceRecord(data);
|
||||
case RecordType.MediaKeyData: return ParseMediaKeyDataRecord(data);
|
||||
case RecordType.SubsetDifferenceIndex: return ParseSubsetDifferenceIndexRecord(data);
|
||||
case RecordType.TypeAndVersion: return ParseTypeAndVersionRecord(data);
|
||||
case RecordType.DriveRevocationList: return ParseDriveRevocationListRecord(data);
|
||||
case RecordType.HostRevocationList: return ParseHostRevocationListRecord(data);
|
||||
case RecordType.VerifyMediaKey: return ParseVerifyMediaKeyRecord(data);
|
||||
case RecordType.Copyright: return ParseCopyrightRecord(data);
|
||||
RecordType.EndOfMediaKeyBlock => ParseEndOfMediaKeyBlockRecord(data),
|
||||
RecordType.ExplicitSubsetDifference => ParseExplicitSubsetDifferenceRecord(data),
|
||||
RecordType.MediaKeyData => ParseMediaKeyDataRecord(data),
|
||||
RecordType.SubsetDifferenceIndex => ParseSubsetDifferenceIndexRecord(data),
|
||||
RecordType.TypeAndVersion => ParseTypeAndVersionRecord(data),
|
||||
RecordType.DriveRevocationList => ParseDriveRevocationListRecord(data),
|
||||
RecordType.HostRevocationList => ParseHostRevocationListRecord(data),
|
||||
RecordType.VerifyMediaKey => ParseVerifyMediaKeyRecord(data),
|
||||
RecordType.Copyright => ParseCopyrightRecord(data),
|
||||
|
||||
// Unknown record type
|
||||
default:
|
||||
if (recordLength > 4)
|
||||
_ = data.ReadBytes((int)recordLength - 4);
|
||||
return null;
|
||||
}
|
||||
_ => ParseGenericRecord(data),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -235,6 +232,22 @@ namespace SabreTools.Serialization.Deserializers
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into a GenericRecord
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <returns>Filled GenericRecord on success, null on error</returns>
|
||||
public static GenericRecord ParseGenericRecord(Stream data)
|
||||
{
|
||||
var obj = new GenericRecord();
|
||||
|
||||
obj.RecordType = (RecordType)data.ReadByteValue();
|
||||
obj.RecordLength = data.ReadUInt24LittleEndian();
|
||||
obj.Data = data.ReadBytes(0x10);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into a HostRevocationListEntry
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.ASN1;
|
||||
|
||||
namespace SabreTools.Serialization.Deserializers
|
||||
{
|
||||
public class AbstractSyntaxNotationOne : BaseBinaryDeserializer<TypeLengthValue[]>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TypeLengthValue[]? Deserialize(Stream? data)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
// Cache the current offset
|
||||
long initialOffset = data.Position;
|
||||
|
||||
// Loop through the data and return all top-level values
|
||||
var topLevelValues = new List<TypeLengthValue>();
|
||||
while (data.Position < data.Length)
|
||||
{
|
||||
var topLevelValue = ParseTypeLengthValue(data);
|
||||
if (topLevelValue == null)
|
||||
break;
|
||||
|
||||
topLevelValues.Add(topLevelValue);
|
||||
}
|
||||
|
||||
// Return null instead of empty
|
||||
if (topLevelValues.Count == 0)
|
||||
return null;
|
||||
|
||||
// Return the top-level values
|
||||
return [.. topLevelValues];
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore the actual error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into a TypeLengthValue
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <returns>Filled TypeLengthValue on success, null on error</returns>
|
||||
public TypeLengthValue? ParseTypeLengthValue(Stream data)
|
||||
{
|
||||
var obj = new TypeLengthValue();
|
||||
|
||||
// Get the type and modifiers
|
||||
obj.Type = (ASN1Type)data.ReadByteValue();
|
||||
|
||||
// If we have an end indicator, we just return
|
||||
if (obj.Type == ASN1Type.V_ASN1_EOC)
|
||||
return obj;
|
||||
|
||||
// Get the length of the value
|
||||
ulong? length = ReadLength(data);
|
||||
if (length == null)
|
||||
return null;
|
||||
|
||||
// Set the length
|
||||
obj.Length = length.Value;
|
||||
|
||||
// Read the value
|
||||
#if NET20 || NET35
|
||||
if ((obj.Type & ASN1Type.V_ASN1_CONSTRUCTED) != 0)
|
||||
#else
|
||||
if (obj.Type.HasFlag(ASN1Type.V_ASN1_CONSTRUCTED))
|
||||
#endif
|
||||
{
|
||||
var valueList = new List<TypeLengthValue>();
|
||||
|
||||
long currentIndex = data.Position;
|
||||
while (data.Position < currentIndex + (long)obj.Length)
|
||||
{
|
||||
var value = ParseTypeLengthValue(data);
|
||||
valueList.Add(value);
|
||||
}
|
||||
|
||||
obj.Value = valueList.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Get more granular based on type
|
||||
obj.Value = data.ReadBytes((int)obj.Length);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the length field for a type
|
||||
/// </summary>
|
||||
/// <param name="data">Stream representing data to read</param>
|
||||
/// <returns>The length value read from the array</returns>
|
||||
private static ulong? ReadLength(Stream data)
|
||||
{
|
||||
// Read the first byte, assuming it's the length
|
||||
byte length = data.ReadByteValue();
|
||||
|
||||
// If the bit 7 is not set, then use the value as it is
|
||||
if ((length & 0x80) == 0)
|
||||
return length;
|
||||
|
||||
// Otherwise, use the value as the number of remaining bytes to read
|
||||
int bytesToRead = length & ~0x80;
|
||||
|
||||
// Assemble the length based on byte count
|
||||
ulong fullLength = 0;
|
||||
switch (bytesToRead)
|
||||
{
|
||||
case 8:
|
||||
fullLength |= data.ReadByteValue();
|
||||
fullLength <<= 8;
|
||||
goto case 7;
|
||||
case 7:
|
||||
fullLength |= data.ReadByteValue();
|
||||
fullLength <<= 8;
|
||||
goto case 6;
|
||||
case 6:
|
||||
fullLength |= data.ReadByteValue();
|
||||
fullLength <<= 8;
|
||||
goto case 5;
|
||||
case 5:
|
||||
fullLength |= data.ReadByteValue();
|
||||
fullLength <<= 8;
|
||||
goto case 4;
|
||||
case 4:
|
||||
fullLength |= data.ReadByteValue();
|
||||
fullLength <<= 8;
|
||||
goto case 3;
|
||||
case 3:
|
||||
fullLength |= data.ReadByteValue();
|
||||
fullLength <<= 8;
|
||||
goto case 2;
|
||||
case 2:
|
||||
fullLength |= data.ReadByteValue();
|
||||
fullLength <<= 8;
|
||||
goto case 1;
|
||||
case 1:
|
||||
fullLength |= data.ReadByteValue();
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return fullLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc/>
|
||||
public override MetadataFile? Deserialize(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return default;
|
||||
|
||||
|
||||
@@ -41,8 +41,21 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc/>
|
||||
public virtual TModel? Deserialize(string? path)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream);
|
||||
try
|
||||
{
|
||||
// If we don't have a file
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||||
return default;
|
||||
|
||||
// Open the file for deserialization
|
||||
using var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Deserialize(stream);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.CFB;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
using static SabreTools.Models.CFB.Constants;
|
||||
|
||||
namespace SabreTools.Serialization.Deserializers
|
||||
|
||||
@@ -42,8 +42,21 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(string?)"/>
|
||||
public MetadataFile? Deserialize(string? path, bool quotes)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream, quotes);
|
||||
try
|
||||
{
|
||||
// If we don't have a file
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||||
return default;
|
||||
|
||||
// Open the file for deserialization
|
||||
using var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Deserialize(stream, quotes);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -57,7 +70,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public MetadataFile? Deserialize(Stream? data, bool quotes)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -460,9 +473,21 @@ namespace SabreTools.Serialization.Deserializers
|
||||
case "crc":
|
||||
rom.CRC = kvp.Value;
|
||||
break;
|
||||
case "md2":
|
||||
rom.MD2 = kvp.Value;
|
||||
break;
|
||||
case "md4":
|
||||
rom.MD4 = kvp.Value;
|
||||
break;
|
||||
case "md5":
|
||||
rom.MD5 = kvp.Value;
|
||||
break;
|
||||
case "ripemd128":
|
||||
rom.RIPEMD128 = kvp.Value;
|
||||
break;
|
||||
case "ripemd160":
|
||||
rom.RIPEMD160 = kvp.Value;
|
||||
break;
|
||||
case "sha1":
|
||||
rom.SHA1 = kvp.Value;
|
||||
break;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc/>
|
||||
public override MetadataFile? Deserialize(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -41,8 +41,21 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(string?)"/>
|
||||
public Models.Hashfile.Hashfile? Deserialize(string? path, HashType hash)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream, hash);
|
||||
try
|
||||
{
|
||||
// If we don't have a file
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||||
return default;
|
||||
|
||||
// Open the file for deserialization
|
||||
using var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Deserialize(stream, hash);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -61,6 +74,8 @@ namespace SabreTools.Serialization.Deserializers
|
||||
HashType.MD2 => DeserializeMD2(data),
|
||||
HashType.MD4 => DeserializeMD4(data),
|
||||
HashType.MD5 => DeserializeMD5(data),
|
||||
HashType.RIPEMD128 => DeserializeRIPEMD128(data),
|
||||
HashType.RIPEMD160 => DeserializeRIPEMD160(data),
|
||||
HashType.SHA1 => DeserializeSHA1(data),
|
||||
HashType.SHA256 => DeserializeSHA256(data),
|
||||
HashType.SHA384 => DeserializeSHA384(data),
|
||||
@@ -74,7 +89,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeSFV(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -117,7 +132,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeMD2(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -161,7 +176,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeMD4(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -205,7 +220,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeMD5(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -238,10 +253,82 @@ namespace SabreTools.Serialization.Deserializers
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeRIPEMD128(Stream? data)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new StreamReader(data);
|
||||
var ripemd128List = new List<RIPEMD128>();
|
||||
|
||||
// Loop through the rows and parse out values
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// Read and split the line
|
||||
string? line = reader.ReadLine();
|
||||
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
||||
if (lineParts == null || lineParts.Length < 2)
|
||||
continue;
|
||||
|
||||
// Parse the line into a hash
|
||||
var ripemd128 = new RIPEMD128
|
||||
{
|
||||
Hash = lineParts[0],
|
||||
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
||||
};
|
||||
ripemd128List.Add(ripemd128);
|
||||
}
|
||||
|
||||
// Assign the hashes to the hashfile and return
|
||||
if (ripemd128List.Count > 0)
|
||||
return new Models.Hashfile.Hashfile { RIPEMD128 = [.. ripemd128List] };
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeRIPEMD160(Stream? data)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new StreamReader(data);
|
||||
var ripemd160List = new List<RIPEMD160>();
|
||||
|
||||
// Loop through the rows and parse out values
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// Read and split the line
|
||||
string? line = reader.ReadLine();
|
||||
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
||||
if (lineParts == null || lineParts.Length < 2)
|
||||
continue;
|
||||
|
||||
// Parse the line into a hash
|
||||
var ripemd160 = new RIPEMD160
|
||||
{
|
||||
Hash = lineParts[0],
|
||||
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
||||
};
|
||||
ripemd160List.Add(ripemd160);
|
||||
}
|
||||
|
||||
// Assign the hashes to the hashfile and return
|
||||
if (ripemd160List.Count > 0)
|
||||
return new Models.Hashfile.Hashfile { RIPEMD160 = [.. ripemd160List] };
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeSHA1(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -285,7 +372,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeSHA256(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -329,7 +416,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeSHA384(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -373,7 +460,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeSHA512(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
@@ -417,7 +504,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public Models.Hashfile.Hashfile? DeserializeSpamSum(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return default;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.InstallShieldCabinet;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
using static SabreTools.Models.InstallShieldCabinet.Constants;
|
||||
|
||||
namespace SabreTools.Serialization.Deserializers
|
||||
|
||||
@@ -56,8 +56,21 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <returns>Filled object on success, null on error</returns>
|
||||
public T? Deserialize(string? path, Encoding encoding)
|
||||
{
|
||||
using var data = PathProcessor.OpenStream(path);
|
||||
return Deserialize(data, encoding);
|
||||
try
|
||||
{
|
||||
// If we don't have a file
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||||
return default;
|
||||
|
||||
// Open the file for deserialization
|
||||
using var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Deserialize(stream, encoding);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.NewExecutable;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
using static SabreTools.Models.NewExecutable.Constants;
|
||||
|
||||
namespace SabreTools.Serialization.Deserializers
|
||||
@@ -420,7 +421,14 @@ namespace SabreTools.Serialization.Deserializers
|
||||
obj.RelocationRecords = new RelocationRecord[obj.RelocationRecordCount];
|
||||
for (int i = 0; i < obj.RelocationRecords.Length; i++)
|
||||
{
|
||||
obj.RelocationRecords[i] = ParseRelocationRecord(data);
|
||||
if (data.Position >= data.Length)
|
||||
break;
|
||||
|
||||
var record = ParseRelocationRecord(data);
|
||||
if (record == null)
|
||||
break;
|
||||
|
||||
obj.RelocationRecords[i] = record;
|
||||
}
|
||||
|
||||
return obj;
|
||||
@@ -433,12 +441,20 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <returns>Filled RelocationRecord on success, null on error</returns>
|
||||
public static RelocationRecord ParseRelocationRecord(Stream data)
|
||||
{
|
||||
// Handle partial relocation sections
|
||||
if (data.Position > data.Length - 4)
|
||||
return null;
|
||||
|
||||
var obj = new RelocationRecord();
|
||||
|
||||
obj.SourceType = (RelocationRecordSourceType)data.ReadByteValue();
|
||||
obj.Flags = (RelocationRecordFlag)data.ReadByteValue();
|
||||
obj.Offset = data.ReadUInt16LittleEndian();
|
||||
|
||||
// Handle incomplete entries
|
||||
if (data.Position > data.Length - 4)
|
||||
return obj;
|
||||
|
||||
switch (obj.Flags & RelocationRecordFlag.TARGET_MASK)
|
||||
{
|
||||
case RelocationRecordFlag.INTERNALREF:
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Models.PKZIP;
|
||||
using static SabreTools.Models.PKZIP.Constants;
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace SabreTools.Serialization.Deserializers
|
||||
{
|
||||
internal class PathProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens a path as a stream in a safe manner, decompressing if needed
|
||||
/// </summary>
|
||||
/// <param name="path">Path to open as a stream</param>
|
||||
/// <returns>Stream representing the file, null on error</returns>
|
||||
public static Stream? OpenStream(string? path)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If we don't have a file
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||||
return null;
|
||||
|
||||
// Open the file for deserialization
|
||||
return File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc/>
|
||||
public override MetadataFile? Deserialize(Stream? data)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.PortableExecutable;
|
||||
using SabreTools.Models.SecuROM;
|
||||
|
||||
namespace SabreTools.Serialization.Deserializers
|
||||
{
|
||||
public class SecuROMAddD : BaseBinaryDeserializer<Models.PortableExecutable.SecuROMAddD>
|
||||
public class SecuROMAddD : BaseBinaryDeserializer<AddD>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override Models.PortableExecutable.SecuROMAddD? Deserialize(Stream? data)
|
||||
public override AddD? Deserialize(Stream? data)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
@@ -37,9 +37,9 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <returns>Filled SecuROMAddD on success, null on error</returns>
|
||||
private static Models.PortableExecutable.SecuROMAddD ParseSecuROMAddD(Stream data)
|
||||
private static AddD ParseSecuROMAddD(Stream data)
|
||||
{
|
||||
var obj = new Models.PortableExecutable.SecuROMAddD();
|
||||
var obj = new AddD();
|
||||
|
||||
obj.Signature = data.ReadUInt32LittleEndian();
|
||||
obj.EntryCount = data.ReadUInt32LittleEndian();
|
||||
@@ -49,7 +49,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
obj.Build = buildStr.ToCharArray();
|
||||
obj.Unknown14h = data.ReadBytes(1); // TODO: Figure out how to determine how many bytes are here consistently
|
||||
|
||||
obj.Entries = new SecuROMAddDEntry[obj.EntryCount];
|
||||
obj.Entries = new AddDEntry[obj.EntryCount];
|
||||
for (int i = 0; i < obj.Entries.Length; i++)
|
||||
{
|
||||
var entry = ParseSecuROMAddDEntry(data);
|
||||
@@ -64,9 +64,9 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <returns>Filled SecuROMAddDEntry on success, null on error</returns>
|
||||
private static SecuROMAddDEntry ParseSecuROMAddDEntry(Stream data)
|
||||
private static AddDEntry ParseSecuROMAddDEntry(Stream data)
|
||||
{
|
||||
var obj = new SecuROMAddDEntry();
|
||||
var obj = new AddDEntry();
|
||||
|
||||
obj.PhysicalOffset = data.ReadUInt32LittleEndian();
|
||||
obj.Length = data.ReadUInt32LittleEndian();
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Models.SecuROM;
|
||||
using static SabreTools.Models.SecuROM.Constants;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Models.SecuROM;
|
||||
using static SabreTools.Models.SecuROM.Constants;
|
||||
|
||||
namespace SabreTools.Serialization.Deserializers
|
||||
{
|
||||
// TODO: Cache data blocks during parse
|
||||
public class SecuROMMatroschkaPackage : BaseBinaryDeserializer<MatroshkaPackage>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
@@ -96,7 +96,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
data.Seek(data.Position + 256, SeekOrigin.Begin);
|
||||
var tempValue = data.ReadUInt32LittleEndian();
|
||||
data.Seek(tempPosition, SeekOrigin.Begin);
|
||||
int gapSize = tempValue == 0 ? 512 : 256;
|
||||
int pathSize = tempValue == 0 ? 512 : 256;
|
||||
|
||||
// Set default value for unknown value checking
|
||||
bool? hasUnknown = null;
|
||||
@@ -106,7 +106,8 @@ namespace SabreTools.Serialization.Deserializers
|
||||
{
|
||||
var entry = new MatroshkaEntry();
|
||||
|
||||
entry.Path = data.ReadBytes(gapSize);
|
||||
byte[] pathBytes = data.ReadBytes(pathSize);
|
||||
entry.Path = Encoding.ASCII.GetString(pathBytes);
|
||||
entry.EntryType = (MatroshkaEntryType)data.ReadUInt32LittleEndian();
|
||||
entry.Size = data.ReadUInt32LittleEndian();
|
||||
entry.Offset = data.ReadUInt32LittleEndian();
|
||||
|
||||
@@ -49,8 +49,21 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(string?)"/>
|
||||
public MetadataFile? Deserialize(string? path, char delim)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream, delim);
|
||||
try
|
||||
{
|
||||
// If we don't have a file
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||||
return default;
|
||||
|
||||
// Open the file for deserialization
|
||||
using var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
return Deserialize(stream, delim);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -64,7 +77,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc cref="Deserialize(Stream)"/>
|
||||
public MetadataFile? Deserialize(Stream? data, char delim)
|
||||
{
|
||||
// If tthe data is invalid
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Models.WiseInstaller;
|
||||
using static SabreTools.Models.WiseInstaller.Constants;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Text;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
namespace SabreTools.Serialization.Extensions
|
||||
{
|
||||
public static partial class Extensions
|
||||
public static class CFB
|
||||
{
|
||||
/// <summary>
|
||||
/// Decode a MIME-encoded stream name stored as a byte array
|
||||
@@ -1,8 +1,8 @@
|
||||
using SabreTools.Models.InstallShieldCabinet;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
namespace SabreTools.Serialization.Extensions
|
||||
{
|
||||
public static partial class Extensions
|
||||
public static class InstallShieldCabinet
|
||||
{
|
||||
#region File Descriptors
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using SabreTools.Models.NewExecutable;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
namespace SabreTools.Serialization.Extensions
|
||||
{
|
||||
public static partial class Extensions
|
||||
public static class NewExecutable
|
||||
{
|
||||
/// <summary>
|
||||
/// Determine if a resource type information entry is an integer or offset
|
||||
@@ -4,12 +4,14 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.COFF;
|
||||
using SabreTools.Models.PortableExecutable;
|
||||
using SabreTools.Models.PortableExecutable.ResourceEntries;
|
||||
using SabreTools.Models.PortableExecutable.Resource.Entries;
|
||||
using SabreTools.Models.SecuROM;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
namespace SabreTools.Serialization.Extensions
|
||||
{
|
||||
public static partial class Extensions
|
||||
public static class PortableExecutable
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert a relative virtual address to a physical one
|
||||
@@ -108,9 +110,9 @@ namespace SabreTools.Serialization
|
||||
/// <param name="data">Data to parse</param>
|
||||
/// <param name="offset">Offset into the byte array</param>
|
||||
/// <returns>A filled NB10ProgramDatabase on success, null on error</returns>
|
||||
public static NB10ProgramDatabase? ParseNB10ProgramDatabase(this byte[] data, ref int offset)
|
||||
public static Models.PortableExecutable.DebugData.NB10ProgramDatabase? ParseNB10ProgramDatabase(this byte[] data, ref int offset)
|
||||
{
|
||||
var obj = new NB10ProgramDatabase();
|
||||
var obj = new Models.PortableExecutable.DebugData.NB10ProgramDatabase();
|
||||
|
||||
obj.Signature = data.ReadUInt32LittleEndian(ref offset);
|
||||
if (obj.Signature != 0x3031424E)
|
||||
@@ -130,9 +132,9 @@ namespace SabreTools.Serialization
|
||||
/// <param name="data">Data to parse</param>
|
||||
/// <param name="offset">Offset into the byte array</param>
|
||||
/// <returns>A filled RSDSProgramDatabase on success, null on error</returns>
|
||||
public static RSDSProgramDatabase? ParseRSDSProgramDatabase(this byte[] data, ref int offset)
|
||||
public static Models.PortableExecutable.DebugData.RSDSProgramDatabase? ParseRSDSProgramDatabase(this byte[] data, ref int offset)
|
||||
{
|
||||
var obj = new RSDSProgramDatabase();
|
||||
var obj = new Models.PortableExecutable.DebugData.RSDSProgramDatabase();
|
||||
|
||||
obj.Signature = data.ReadUInt32LittleEndian(ref offset);
|
||||
if (obj.Signature != 0x53445352)
|
||||
@@ -155,10 +157,10 @@ namespace SabreTools.Serialization
|
||||
/// <param name="data">Data to parse into overlay data</param>
|
||||
/// <param name="offset">Offset into the byte array</param>
|
||||
/// <returns>A filled SecuROMAddD on success, null on error</returns>
|
||||
public static SecuROMAddD? ParseSecuROMAddD(this byte[] data, ref int offset)
|
||||
public static AddD? ParseSecuROMAddD(this byte[] data, ref int offset)
|
||||
{
|
||||
// Read in the table
|
||||
var obj = new SecuROMAddD();
|
||||
var obj = new AddD();
|
||||
|
||||
obj.Signature = data.ReadUInt32LittleEndian(ref offset);
|
||||
if (obj.Signature != 0x44646441)
|
||||
@@ -186,7 +188,7 @@ namespace SabreTools.Serialization
|
||||
|
||||
obj.Unknown14h = data.ReadBytes(ref offset, bytesToRead);
|
||||
|
||||
obj.Entries = new SecuROMAddDEntry[obj.EntryCount];
|
||||
obj.Entries = new AddDEntry[obj.EntryCount];
|
||||
for (int i = 0; i < obj.EntryCount; i++)
|
||||
{
|
||||
obj.Entries[i] = ParseSecuROMAddDEntry(data, ref offset);
|
||||
@@ -201,9 +203,9 @@ namespace SabreTools.Serialization
|
||||
/// <param name="data">Data to parse</param>
|
||||
/// <param name="offset">Offset into the byte array</param>
|
||||
/// <returns>Filled SecuROMAddDEntry on success, null on error</returns>
|
||||
public static SecuROMAddDEntry ParseSecuROMAddDEntry(this byte[] data, ref int offset)
|
||||
public static AddDEntry ParseSecuROMAddDEntry(this byte[] data, ref int offset)
|
||||
{
|
||||
var obj = new SecuROMAddDEntry();
|
||||
var obj = new AddDEntry();
|
||||
|
||||
obj.PhysicalOffset = data.ReadUInt32LittleEndian(ref offset);
|
||||
obj.Length = data.ReadUInt32LittleEndian(ref offset);
|
||||
@@ -229,7 +231,7 @@ namespace SabreTools.Serialization
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into an accelerator table resource</param>
|
||||
/// <returns>A filled accelerator table resource on success, null on error</returns>
|
||||
public static AcceleratorTableEntry[]? AsAcceleratorTableResource(this ResourceDataEntry? entry)
|
||||
public static AcceleratorTableEntry[]? AsAcceleratorTableResource(this Models.PortableExecutable.Resource.DataEntry? entry)
|
||||
{
|
||||
// If we have data that's invalid for this resource type, we can't do anything
|
||||
if (entry?.Data == null || entry.Data.Length % 8 != 0)
|
||||
@@ -258,7 +260,7 @@ namespace SabreTools.Serialization
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into a side-by-side assembly manifest</param>
|
||||
/// <returns>A filled side-by-side assembly manifest on success, null on error</returns>
|
||||
public static AssemblyManifest? AsAssemblyManifest(this ResourceDataEntry? entry)
|
||||
public static AssemblyManifest? AsAssemblyManifest(this Models.PortableExecutable.Resource.DataEntry? entry)
|
||||
{
|
||||
// If we have an invalid entry, just skip
|
||||
if (entry?.Data == null)
|
||||
@@ -280,7 +282,7 @@ namespace SabreTools.Serialization
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into a dialog box</param>
|
||||
/// <returns>A filled dialog box on success, null on error</returns>
|
||||
public static DialogBoxResource? AsDialogBox(this ResourceDataEntry? entry)
|
||||
public static DialogBoxResource? AsDialogBox(this Models.PortableExecutable.Resource.DataEntry? entry)
|
||||
{
|
||||
// If we have an invalid entry, just skip
|
||||
if (entry?.Data == null)
|
||||
@@ -729,7 +731,7 @@ namespace SabreTools.Serialization
|
||||
#region Creation data
|
||||
|
||||
dialogItemTemplate.CreationDataSize = entry.Data.ReadUInt16LittleEndian(ref offset);
|
||||
if (dialogItemTemplate.CreationDataSize != 0)
|
||||
if (dialogItemTemplate.CreationDataSize != 0 && dialogItemTemplate.CreationDataSize + offset < entry.Data.Length)
|
||||
dialogItemTemplate.CreationData = entry.Data.ReadBytes(ref offset, dialogItemTemplate.CreationDataSize);
|
||||
|
||||
#endregion
|
||||
@@ -757,7 +759,7 @@ namespace SabreTools.Serialization
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into a font group</param>
|
||||
/// <returns>A filled font group on success, null on error</returns>
|
||||
public static FontGroupHeader? AsFontGroup(this ResourceDataEntry? entry)
|
||||
public static FontGroupHeader? AsFontGroup(this Models.PortableExecutable.Resource.DataEntry? entry)
|
||||
{
|
||||
// If we have an invalid entry, just skip
|
||||
if (entry?.Data == null)
|
||||
@@ -826,7 +828,7 @@ namespace SabreTools.Serialization
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into a menu</param>
|
||||
/// <returns>A filled menu on success, null on error</returns>
|
||||
public static MenuResource? AsMenu(this ResourceDataEntry? entry)
|
||||
public static MenuResource? AsMenu(this Models.PortableExecutable.Resource.DataEntry? entry)
|
||||
{
|
||||
// If we have an invalid entry, just skip
|
||||
if (entry?.Data == null)
|
||||
@@ -922,7 +924,7 @@ namespace SabreTools.Serialization
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into a message table resource</param>
|
||||
/// <returns>A filled message table resource on success, null on error</returns>
|
||||
public static MessageResourceData? AsMessageResourceData(this ResourceDataEntry? entry)
|
||||
public static MessageResourceData? AsMessageResourceData(this Models.PortableExecutable.Resource.DataEntry? entry)
|
||||
{
|
||||
// If we have an invalid entry, just skip
|
||||
if (entry?.Data == null)
|
||||
@@ -1010,10 +1012,10 @@ namespace SabreTools.Serialization
|
||||
// Align to the DWORD boundary if we're not at the end
|
||||
data.AlignToBoundary(ref offset, 4);
|
||||
|
||||
var stringFileInfoChildren = new List<StringTable>();
|
||||
var stringFileInfoChildren = new List<Models.PortableExecutable.Resource.Entries.StringTable>();
|
||||
while ((offset - currentOffset) < stringFileInfo.Length)
|
||||
{
|
||||
var stringTable = new StringTable();
|
||||
var stringTable = new Models.PortableExecutable.Resource.Entries.StringTable();
|
||||
|
||||
stringTable.Length = data.ReadUInt16LittleEndian(ref offset);
|
||||
stringTable.ValueLength = data.ReadUInt16LittleEndian(ref offset);
|
||||
@@ -1067,7 +1069,7 @@ namespace SabreTools.Serialization
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into a string table resource</param>
|
||||
/// <returns>A filled string table resource on success, null on error</returns>
|
||||
public static Dictionary<int, string?>? AsStringTable(this ResourceDataEntry? entry)
|
||||
public static Dictionary<int, string?>? AsStringTable(this Models.PortableExecutable.Resource.DataEntry? entry)
|
||||
{
|
||||
// If we have an invalid entry, just skip
|
||||
if (entry?.Data == null)
|
||||
@@ -1159,7 +1161,7 @@ namespace SabreTools.Serialization
|
||||
/// </summary>
|
||||
/// <param name="entry">Resource data entry to parse into a version info resource</param>
|
||||
/// <returns>A filled version info resource on success, null on error</returns>
|
||||
public static VersionInfo? AsVersionInfo(this ResourceDataEntry? entry)
|
||||
public static VersionInfo? AsVersionInfo(this Models.PortableExecutable.Resource.DataEntry? entry)
|
||||
{
|
||||
// If we have an invalid entry, just skip
|
||||
if (entry?.Data == null)
|
||||
@@ -1356,10 +1358,10 @@ namespace SabreTools.Serialization
|
||||
/// <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 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 ResourceHeader();
|
||||
var obj = new Models.PortableExecutable.Resource.ResourceHeader();
|
||||
|
||||
obj.DataSize = data.ReadUInt32LittleEndian(ref offset);
|
||||
obj.HeaderSize = data.ReadUInt32LittleEndian(ref offset);
|
||||
160
SabreTools.Serialization/Extensions/TypeLengthValue.cs
Normal file
160
SabreTools.Serialization/Extensions/TypeLengthValue.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using SabreTools.Models.ASN1;
|
||||
using SabreTools.Serialization.ObjectIdentifier;
|
||||
|
||||
namespace SabreTools.Serialization.Extensions
|
||||
{
|
||||
public static class TypeLengthValue
|
||||
{
|
||||
/// <summary>
|
||||
/// Format a TypeLengthValue as a string
|
||||
/// </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 Models.ASN1.TypeLengthValue tlv, int paddingLevel = 0)
|
||||
{
|
||||
// Create the left-padding string
|
||||
string padding = new(' ', paddingLevel);
|
||||
|
||||
// Create the string builder
|
||||
var formatBuilder = new StringBuilder();
|
||||
|
||||
// Append the type
|
||||
formatBuilder.Append($"{padding}Type: {tlv.Type}");
|
||||
if (tlv.Type == ASN1Type.V_ASN1_EOC)
|
||||
return formatBuilder.ToString();
|
||||
|
||||
// Append the length
|
||||
formatBuilder.Append($", Length: {tlv.Length}");
|
||||
if (tlv.Length == 0)
|
||||
return formatBuilder.ToString();
|
||||
|
||||
// If we have a constructed type
|
||||
#if NET20 || NET35
|
||||
if ((tlv.Type & ASN1Type.V_ASN1_CONSTRUCTED) != 0)
|
||||
#else
|
||||
if (tlv.Type.HasFlag(ASN1Type.V_ASN1_CONSTRUCTED))
|
||||
#endif
|
||||
{
|
||||
if (tlv.Value is not Models.ASN1.TypeLengthValue[] valueAsObjectArray)
|
||||
{
|
||||
formatBuilder.Append(", Value: [INVALID DATA TYPE]");
|
||||
return formatBuilder.ToString();
|
||||
}
|
||||
|
||||
formatBuilder.Append(", Value:\n");
|
||||
for (int i = 0; i < valueAsObjectArray.Length; i++)
|
||||
{
|
||||
var child = valueAsObjectArray[i];
|
||||
string childString = child.Format(paddingLevel + 1);
|
||||
formatBuilder.Append($"{childString}\n");
|
||||
}
|
||||
|
||||
return formatBuilder.ToString().TrimEnd('\n');
|
||||
}
|
||||
|
||||
// Get the value as a byte array
|
||||
if (tlv.Value is not byte[] valueAsByteArray)
|
||||
{
|
||||
formatBuilder.Append(", Value: [INVALID DATA TYPE]");
|
||||
return formatBuilder.ToString();
|
||||
}
|
||||
else if (valueAsByteArray.Length == 0)
|
||||
{
|
||||
formatBuilder.Append(", Value: [NO DATA]");
|
||||
return formatBuilder.ToString();
|
||||
}
|
||||
|
||||
// If we have a primitive type
|
||||
switch (tlv.Type)
|
||||
{
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-boolean"/>
|
||||
case ASN1Type.V_ASN1_BOOLEAN:
|
||||
if (tlv.Length > 1)
|
||||
formatBuilder.Append($" [Expected length of 1]");
|
||||
else if (valueAsByteArray.Length > 1)
|
||||
formatBuilder.Append($" [Expected value length of 1]");
|
||||
|
||||
bool booleanValue = valueAsByteArray[0] != 0x00;
|
||||
formatBuilder.Append($", Value: {booleanValue}");
|
||||
break;
|
||||
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-integer"/>
|
||||
case ASN1Type.V_ASN1_INTEGER:
|
||||
Array.Reverse(valueAsByteArray);
|
||||
var integerValue = new BigInteger(valueAsByteArray);
|
||||
formatBuilder.Append($", Value: {integerValue}");
|
||||
break;
|
||||
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-bit-string"/>
|
||||
case ASN1Type.V_ASN1_BIT_STRING:
|
||||
// TODO: Read into a BitArray and print that out instead?
|
||||
int unusedBits = valueAsByteArray[0];
|
||||
if (unusedBits == 0)
|
||||
formatBuilder.Append($", Value with {unusedBits} unused bits");
|
||||
else
|
||||
formatBuilder.Append($", Value with {unusedBits} unused bits: {BitConverter.ToString(valueAsByteArray, 1).Replace('-', ' ')}");
|
||||
break;
|
||||
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-octet-string"/>
|
||||
case ASN1Type.V_ASN1_OCTET_STRING:
|
||||
formatBuilder.Append($", Value: {BitConverter.ToString(valueAsByteArray).Replace('-', ' ')}");
|
||||
break;
|
||||
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier"/>
|
||||
/// <see cref="http://snmpsharpnet.com/index.php/2009/03/02/ber-encoding-and-decoding-oid-values/"/>
|
||||
case ASN1Type.V_ASN1_OBJECT:
|
||||
// Derive array of values
|
||||
ulong[] objectNodes = Parser.ParseDERIntoArray(valueAsByteArray, tlv.Length);
|
||||
|
||||
// Append the dot and modified OID-IRI notations
|
||||
string? dotNotationString = Parser.ParseOIDToDotNotation(objectNodes);
|
||||
string? oidIriString = Parser.ParseOIDToOIDIRINotation(objectNodes);
|
||||
formatBuilder.Append($", Value: {dotNotationString} ({oidIriString})");
|
||||
break;
|
||||
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-utf8string"/>
|
||||
case ASN1Type.V_ASN1_UTF8STRING:
|
||||
formatBuilder.Append($", Value: {Encoding.UTF8.GetString(valueAsByteArray)}");
|
||||
break;
|
||||
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-printablestring"/>
|
||||
case ASN1Type.V_ASN1_PRINTABLESTRING:
|
||||
formatBuilder.Append($", Value: {Encoding.ASCII.GetString(valueAsByteArray)}");
|
||||
break;
|
||||
|
||||
//case ASN1Type.V_ASN1_T61STRING:
|
||||
case ASN1Type.V_ASN1_TELETEXSTRING:
|
||||
formatBuilder.Append($", Value: {Encoding.ASCII.GetString(valueAsByteArray)}");
|
||||
break;
|
||||
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-ia5string"/>
|
||||
case ASN1Type.V_ASN1_IA5STRING:
|
||||
formatBuilder.Append($", Value: {Encoding.ASCII.GetString(valueAsByteArray)}");
|
||||
break;
|
||||
|
||||
case ASN1Type.V_ASN1_UTCTIME:
|
||||
string utctimeString = Encoding.ASCII.GetString(valueAsByteArray);
|
||||
if (DateTime.TryParse(utctimeString, out DateTime utctimeDateTime))
|
||||
formatBuilder.Append($", Value: {utctimeDateTime:yyyy-MM-dd HH:mm:ss}");
|
||||
else
|
||||
formatBuilder.Append($", Value: {utctimeString}");
|
||||
break;
|
||||
|
||||
/// <see href="https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-bmpstring"/>
|
||||
case ASN1Type.V_ASN1_BMPSTRING:
|
||||
formatBuilder.Append($", Value: {Encoding.Unicode.GetString(valueAsByteArray)}");
|
||||
break;
|
||||
|
||||
default:
|
||||
formatBuilder.Append($", Value: {BitConverter.ToString(valueAsByteArray).Replace('-', ' ')}");
|
||||
break;
|
||||
}
|
||||
|
||||
// Return the formatted string
|
||||
return formatBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
namespace SabreTools.Serialization.Extensions
|
||||
{
|
||||
public static partial class Extensions
|
||||
public static class WiseScript
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert a Wise function ID to the formal action name
|
||||
@@ -5,39 +5,39 @@
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
public delegate TResult Func<out TResult>();
|
||||
internal delegate TResult Func<out TResult>();
|
||||
|
||||
public delegate TResult Func<in T, out TResult>(T arg);
|
||||
internal delegate TResult Func<in T, out TResult>(T arg);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
|
||||
internal delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15);
|
||||
|
||||
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
|
||||
internal delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
20
SabreTools.Serialization/ObjectIdentifier/Parser.ASN1.cs
Normal file
20
SabreTools.Serialization/ObjectIdentifier/Parser.ASN1.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace SabreTools.Serialization.ObjectIdentifier
|
||||
{
|
||||
/// <summary>
|
||||
/// Methods related to Object Identifiers (OID) and ASN.1 notation
|
||||
/// </summary>
|
||||
public static partial class Parser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse an OID in separated-value notation into ASN.1 notation
|
||||
/// </summary>
|
||||
/// <param name="values">List of values to check against</param>
|
||||
/// <returns>ASN.1 formatted string, if possible</returns>
|
||||
/// <remarks>
|
||||
public static string? ParseOIDToASN1Notation(ulong[]? values)
|
||||
{
|
||||
// TODO: Once the modified OID-IRI formatting is done, make an ASN.1 notation version
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
18058
SabreTools.Serialization/ObjectIdentifier/Parser.ModifiedOIDIRI.cs
Normal file
18058
SabreTools.Serialization/ObjectIdentifier/Parser.ModifiedOIDIRI.cs
Normal file
File diff suppressed because it is too large
Load Diff
907
SabreTools.Serialization/ObjectIdentifier/Parser.OIDIRI.cs
Normal file
907
SabreTools.Serialization/ObjectIdentifier/Parser.OIDIRI.cs
Normal file
@@ -0,0 +1,907 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace SabreTools.Serialization.ObjectIdentifier
|
||||
{
|
||||
/// <summary>
|
||||
/// Methods related to Object Identifiers (OID) and OID-IRI formatting
|
||||
/// </summary>
|
||||
public static partial class Parser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse an OID in separated-value notation into OID-IRI notation
|
||||
/// </summary>
|
||||
/// <param name="values">List of values to check against</param>
|
||||
/// <param name="index">Current index into the list</param>
|
||||
/// <returns>OID-IRI formatted string, if possible</returns>
|
||||
/// <see href="https://oid-base.com/"/>
|
||||
public static string? ParseOIDToOIDIRINotation(ulong[]? values)
|
||||
{
|
||||
// If we have an invalid set of values, we can't do anything
|
||||
if (values == null || values.Length == 0)
|
||||
return null;
|
||||
|
||||
// Set the initial index
|
||||
int index = 0;
|
||||
|
||||
// Get a string builder for the path
|
||||
var nameBuilder = new StringBuilder();
|
||||
|
||||
// Try to parse the standard value
|
||||
string? standard = ParseOIDToOIDIRINotation(values, ref index);
|
||||
if (standard == null)
|
||||
return null;
|
||||
|
||||
// Add the standard value to the output
|
||||
nameBuilder.Append(standard);
|
||||
|
||||
// If we have no more items
|
||||
if (index == values.Length)
|
||||
return nameBuilder.ToString();
|
||||
|
||||
// Add trailing items as just values
|
||||
nameBuilder.Append("/");
|
||||
|
||||
// Get the remaining values in a new array
|
||||
var remainingValues = new ulong[values.Length - index];
|
||||
Array.Copy(values, index, remainingValues, 0, remainingValues.Length);
|
||||
|
||||
// Convert the values and append to the builder
|
||||
var stringValues = Array.ConvertAll(remainingValues, v => v.ToString());
|
||||
nameBuilder.Append(string.Join("/", stringValues));
|
||||
|
||||
// Create and return the string
|
||||
return nameBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an OID in separated-value notation into OID-IRI notation
|
||||
/// </summary>
|
||||
/// <param name="values">List of values to check against</param>
|
||||
/// <param name="index">Current index into the list</param>
|
||||
/// <returns>OID-IRI formatted string, if possible</returns>
|
||||
/// <see href="https://oid-base.com/"/>
|
||||
private static string? ParseOIDToOIDIRINotation(ulong[]? values, ref int index)
|
||||
{
|
||||
// If we have an invalid set of values, we can't do anything
|
||||
if (values == null || values.Length == 0)
|
||||
return null;
|
||||
|
||||
// If we have an invalid index, we can't do anything
|
||||
if (index < 0 || index >= values.Length)
|
||||
return null;
|
||||
|
||||
#region Start
|
||||
|
||||
var oidPath = string.Empty;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_0;
|
||||
case 1: goto oid_1;
|
||||
case 2: goto oid_2;
|
||||
default: return oidPath;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// itu-t, ccitt, itu-r
|
||||
#region 0.*
|
||||
|
||||
oid_0:
|
||||
|
||||
oidPath += "/ITU-T";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_0_0;
|
||||
case 2: return $"{oidPath}/Administration";
|
||||
case 3: return $"{oidPath}/Network-Operator";
|
||||
case 4: return $"{oidPath}/Identified-Organization";
|
||||
case 5: return "/ITU-R/R-Recommendation";
|
||||
case 9: return $"{oidPath}/Data";
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
;
|
||||
|
||||
// recommendation
|
||||
#region 0.0.*
|
||||
|
||||
oid_0_0:
|
||||
|
||||
oidPath += "/Recommendation";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/A",
|
||||
2 => $"{oidPath}/B",
|
||||
3 => $"{oidPath}/C",
|
||||
4 => $"{oidPath}/D",
|
||||
5 => $"{oidPath}/E",
|
||||
6 => $"{oidPath}/F",
|
||||
7 => $"{oidPath}/G",
|
||||
8 => $"{oidPath}/H",
|
||||
9 => $"{oidPath}/I",
|
||||
10 => $"{oidPath}/J",
|
||||
11 => $"{oidPath}/K",
|
||||
12 => $"{oidPath}/L",
|
||||
13 => $"{oidPath}/M",
|
||||
14 => $"{oidPath}/N",
|
||||
15 => $"{oidPath}/O",
|
||||
16 => $"{oidPath}/P",
|
||||
17 => $"{oidPath}/Q",
|
||||
18 => $"{oidPath}/R",
|
||||
19 => $"{oidPath}/S",
|
||||
20 => $"{oidPath}/T",
|
||||
21 => $"{oidPath}/U",
|
||||
22 => $"{oidPath}/V",
|
||||
24 => $"{oidPath}/X",
|
||||
25 => $"{oidPath}/Y",
|
||||
26 => $"{oidPath}/Z",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// iso
|
||||
#region 1.*
|
||||
|
||||
oid_1:
|
||||
|
||||
oidPath += "/ISO";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: return $"{oidPath}/Standard";
|
||||
case 1: return $"{oidPath}/Registration-Authority";
|
||||
case 2: goto oid_1_2;
|
||||
case 3: return $"{oidPath}/Identified-Organization";
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// member-body
|
||||
#region 1.2.*
|
||||
|
||||
oid_1_2:
|
||||
|
||||
oidPath += "/Member-Body";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
36 => $"{oidPath}/AU",
|
||||
40 => $"{oidPath}/AT",
|
||||
56 => $"{oidPath}/BE",
|
||||
124 => $"{oidPath}/CA",
|
||||
156 => $"{oidPath}/CN",
|
||||
203 => $"{oidPath}/CZ",
|
||||
208 => $"{oidPath}/DK",
|
||||
246 => $"{oidPath}/FI",
|
||||
250 => $"{oidPath}/FR",
|
||||
276 => $"{oidPath}/DE",
|
||||
300 => $"{oidPath}/GR",
|
||||
344 => $"{oidPath}/HK",
|
||||
372 => $"{oidPath}/IE",
|
||||
392 => $"{oidPath}/JP",
|
||||
398 => $"{oidPath}/KZ",
|
||||
410 => $"{oidPath}/KR",
|
||||
498 => $"{oidPath}/MD",
|
||||
528 => $"{oidPath}/NL",
|
||||
566 => $"{oidPath}/NG",
|
||||
578 => $"{oidPath}/NO",
|
||||
616 => $"{oidPath}/PL",
|
||||
643 => $"{oidPath}/RU",
|
||||
702 => $"{oidPath}/SG",
|
||||
752 => $"{oidPath}/SE",
|
||||
804 => $"{oidPath}/UA",
|
||||
826 => $"{oidPath}/GB",
|
||||
840 => $"{oidPath}/US",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// joint-iso-itu-t, joint-iso-ccitt
|
||||
#region 2.*
|
||||
|
||||
oid_2:
|
||||
|
||||
oidPath += "/Joint-ISO-ITU-T";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 1: return "/ASN.1";
|
||||
case 16: oidPath = string.Empty; goto oid_2_16;
|
||||
case 17: return $"{oidPath}/Registration-Procedures";
|
||||
case 23: return $"{oidPath}/International-Organizations";
|
||||
case 25: goto oid_2_25;
|
||||
case 27: return "/Tag-Based";
|
||||
case 28: return $"{oidPath}/ITS";
|
||||
case 41: return "/BIP";
|
||||
case 42: oidPath = string.Empty; goto oid_2_42;
|
||||
case 48: oidPath = string.Empty; goto oid_2_48;
|
||||
case 49: oidPath = string.Empty; goto oid_2_49;
|
||||
case 50: return "/OIDResolutionSystem";
|
||||
case 51: return "/GS1";
|
||||
case 52: return $"{oidPath}/UAV";
|
||||
case 999: return $"{oidPath}/Example";
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// country
|
||||
#region 2.16.*
|
||||
|
||||
oid_2_16:
|
||||
|
||||
oidPath += "/Country";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
4 => $"{oidPath}AF",
|
||||
8 => $"{oidPath}AL",
|
||||
12 => $"{oidPath}DZ",
|
||||
20 => $"{oidPath}AD",
|
||||
24 => $"{oidPath}AO",
|
||||
28 => $"{oidPath}AG",
|
||||
31 => $"{oidPath}AZ",
|
||||
32 => $"{oidPath}AR",
|
||||
36 => $"{oidPath}AU",
|
||||
40 => $"{oidPath}AT",
|
||||
44 => $"{oidPath}BS",
|
||||
48 => $"{oidPath}BH",
|
||||
50 => $"{oidPath}BD",
|
||||
51 => $"{oidPath}AM",
|
||||
52 => $"{oidPath}BB",
|
||||
56 => $"{oidPath}BE",
|
||||
60 => $"{oidPath}BM",
|
||||
64 => $"{oidPath}BT",
|
||||
68 => $"{oidPath}BO",
|
||||
70 => $"{oidPath}BA",
|
||||
72 => $"{oidPath}BW",
|
||||
76 => $"{oidPath}BR",
|
||||
84 => $"{oidPath}BZ",
|
||||
90 => $"{oidPath}SB",
|
||||
96 => $"{oidPath}BN",
|
||||
100 => $"{oidPath}BG",
|
||||
104 => $"{oidPath}MM",
|
||||
108 => $"{oidPath}BI",
|
||||
112 => $"{oidPath}BY",
|
||||
116 => $"{oidPath}KH",
|
||||
120 => $"{oidPath}CM",
|
||||
124 => $"{oidPath}CA",
|
||||
132 => $"{oidPath}CV",
|
||||
140 => $"{oidPath}CF",
|
||||
144 => $"{oidPath}LK",
|
||||
148 => $"{oidPath}TD",
|
||||
152 => $"{oidPath}CL",
|
||||
156 => $"{oidPath}CN",
|
||||
158 => $"{oidPath}TW",
|
||||
170 => $"{oidPath}CO",
|
||||
174 => $"{oidPath}KM",
|
||||
178 => $"{oidPath}CG",
|
||||
180 => $"{oidPath}CD",
|
||||
188 => $"{oidPath}CR",
|
||||
191 => $"{oidPath}HR",
|
||||
192 => $"{oidPath}CU",
|
||||
196 => $"{oidPath}CY",
|
||||
203 => $"{oidPath}CZ",
|
||||
204 => $"{oidPath}BJ",
|
||||
208 => $"{oidPath}DK",
|
||||
212 => $"{oidPath}DM",
|
||||
214 => $"{oidPath}DO",
|
||||
218 => $"{oidPath}EC",
|
||||
222 => $"{oidPath}SV",
|
||||
226 => $"{oidPath}GQ",
|
||||
231 => $"{oidPath}ET",
|
||||
232 => $"{oidPath}ER",
|
||||
233 => $"{oidPath}EE",
|
||||
242 => $"{oidPath}FJ",
|
||||
246 => $"{oidPath}FI",
|
||||
250 => $"{oidPath}FR",
|
||||
262 => $"{oidPath}DJ",
|
||||
266 => $"{oidPath}GA",
|
||||
268 => $"{oidPath}GE",
|
||||
270 => $"{oidPath}GM",
|
||||
275 => $"{oidPath}PS",
|
||||
276 => $"{oidPath}DE",
|
||||
288 => $"{oidPath}GH",
|
||||
296 => $"{oidPath}KI",
|
||||
300 => $"{oidPath}GR",
|
||||
308 => $"{oidPath}GD",
|
||||
320 => $"{oidPath}GT",
|
||||
324 => $"{oidPath}GN",
|
||||
328 => $"{oidPath}GY",
|
||||
332 => $"{oidPath}HT",
|
||||
336 => $"{oidPath}VA",
|
||||
340 => $"{oidPath}HN",
|
||||
344 => $"{oidPath}HK",
|
||||
348 => $"{oidPath}HU",
|
||||
352 => $"{oidPath}IS",
|
||||
356 => $"{oidPath}IN",
|
||||
360 => $"{oidPath}ID",
|
||||
364 => $"{oidPath}IR",
|
||||
368 => $"{oidPath}IQ",
|
||||
372 => $"{oidPath}IE",
|
||||
376 => $"{oidPath}IL",
|
||||
380 => $"{oidPath}IT",
|
||||
384 => $"{oidPath}CI",
|
||||
388 => $"{oidPath}JM",
|
||||
392 => $"{oidPath}JP",
|
||||
398 => $"{oidPath}KZ",
|
||||
400 => $"{oidPath}JO",
|
||||
404 => $"{oidPath}KE",
|
||||
408 => $"{oidPath}KP",
|
||||
410 => $"{oidPath}KR",
|
||||
414 => $"{oidPath}KW",
|
||||
417 => $"{oidPath}KG",
|
||||
418 => $"{oidPath}LA",
|
||||
422 => $"{oidPath}LB",
|
||||
426 => $"{oidPath}LS",
|
||||
428 => $"{oidPath}LV",
|
||||
430 => $"{oidPath}LR",
|
||||
434 => $"{oidPath}LY",
|
||||
438 => $"{oidPath}LI",
|
||||
440 => $"{oidPath}LT",
|
||||
442 => $"{oidPath}LU",
|
||||
450 => $"{oidPath}MG",
|
||||
454 => $"{oidPath}MW",
|
||||
458 => $"{oidPath}MY",
|
||||
462 => $"{oidPath}MV",
|
||||
466 => $"{oidPath}ML",
|
||||
470 => $"{oidPath}MT",
|
||||
478 => $"{oidPath}MR",
|
||||
480 => $"{oidPath}MU",
|
||||
484 => $"{oidPath}MX",
|
||||
492 => $"{oidPath}MC",
|
||||
496 => $"{oidPath}MN",
|
||||
498 => $"{oidPath}MD",
|
||||
499 => $"{oidPath}ME",
|
||||
504 => $"{oidPath}MA",
|
||||
508 => $"{oidPath}MZ",
|
||||
512 => $"{oidPath}OM",
|
||||
516 => $"{oidPath}NA",
|
||||
520 => $"{oidPath}NR",
|
||||
524 => $"{oidPath}NP",
|
||||
528 => $"{oidPath}NL",
|
||||
530 => $"{oidPath}AN",
|
||||
548 => $"{oidPath}VU",
|
||||
554 => $"{oidPath}NZ",
|
||||
558 => $"{oidPath}NI",
|
||||
562 => $"{oidPath}NE",
|
||||
566 => $"{oidPath}NG",
|
||||
578 => $"{oidPath}NO",
|
||||
583 => $"{oidPath}FM",
|
||||
584 => $"{oidPath}MH",
|
||||
585 => $"{oidPath}PW",
|
||||
586 => $"{oidPath}PK",
|
||||
591 => $"{oidPath}PA",
|
||||
598 => $"{oidPath}PG",
|
||||
600 => $"{oidPath}PY",
|
||||
604 => $"{oidPath}PE",
|
||||
608 => $"{oidPath}PH",
|
||||
616 => $"{oidPath}PL",
|
||||
620 => $"{oidPath}PT",
|
||||
624 => $"{oidPath}GW",
|
||||
626 => $"{oidPath}TL",
|
||||
634 => $"{oidPath}QA",
|
||||
642 => $"{oidPath}RO",
|
||||
643 => $"{oidPath}RU",
|
||||
646 => $"{oidPath}RW",
|
||||
659 => $"{oidPath}KN",
|
||||
662 => $"{oidPath}LC",
|
||||
670 => $"{oidPath}VC",
|
||||
674 => $"{oidPath}SM",
|
||||
678 => $"{oidPath}ST",
|
||||
682 => $"{oidPath}SA",
|
||||
686 => $"{oidPath}SN",
|
||||
688 => $"{oidPath}RS",
|
||||
690 => $"{oidPath}SC",
|
||||
694 => $"{oidPath}SL",
|
||||
702 => $"{oidPath}SG",
|
||||
703 => $"{oidPath}SK",
|
||||
704 => $"{oidPath}VN",
|
||||
705 => $"{oidPath}SI",
|
||||
706 => $"{oidPath}SO",
|
||||
710 => $"{oidPath}ZA",
|
||||
716 => $"{oidPath}ZW",
|
||||
724 => $"{oidPath}ES",
|
||||
728 => $"{oidPath}SS",
|
||||
729 => $"{oidPath}SD",
|
||||
740 => $"{oidPath}SR",
|
||||
748 => $"{oidPath}SZ",
|
||||
752 => $"{oidPath}SE",
|
||||
756 => $"{oidPath}CH",
|
||||
760 => $"{oidPath}SY",
|
||||
762 => $"{oidPath}TJ",
|
||||
764 => $"{oidPath}TH",
|
||||
768 => $"{oidPath}TG",
|
||||
776 => $"{oidPath}TO",
|
||||
780 => $"{oidPath}TT",
|
||||
784 => $"{oidPath}AE",
|
||||
788 => $"{oidPath}TN",
|
||||
792 => $"{oidPath}TR",
|
||||
795 => $"{oidPath}TM",
|
||||
798 => $"{oidPath}TV",
|
||||
800 => $"{oidPath}UG",
|
||||
804 => $"{oidPath}UA",
|
||||
807 => $"{oidPath}MK",
|
||||
818 => $"{oidPath}EG",
|
||||
826 => $"{oidPath}GB",
|
||||
834 => $"{oidPath}TZ",
|
||||
840 => $"{oidPath}US",
|
||||
854 => $"{oidPath}BF",
|
||||
858 => $"{oidPath}UY",
|
||||
860 => $"{oidPath}UZ",
|
||||
862 => $"{oidPath}VE",
|
||||
882 => $"{oidPath}WS",
|
||||
887 => $"{oidPath}YE",
|
||||
894 => $"{oidPath}ZM",
|
||||
_ => $"{oidPath}{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// uuid [TODO: Requires 128-bit values]
|
||||
#region 2.25.*
|
||||
|
||||
oid_2_25:
|
||||
|
||||
oidPath += "/UUID";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
0 => $"{oidPath}/00000000-0000-0000-0000-000000000000",
|
||||
//case 288786655511405443130567505384701230: return $"{oidPath}/00379e48-0a2b-1085-b288-0002a5d5fd2e";
|
||||
//case 987895962269883002155146617097157934: return $"{oidPath}/00be4308-0c89-1085-8ea0-0002a5d5fd2e";
|
||||
//case 1858228783942312576083372383319475483: return $"{oidPath}/0165e1c0-a655-11e0-95b8-0002a5d5c51b";
|
||||
//case 2474299330026746002885628159579243803: return $"{oidPath}/01dc8860-25fb-11da-82b2-0002a5d5c51b";
|
||||
//case 3263645701162998421821186056373271854: return $"{oidPath}/02748e28-08c4-1085-b21d-0002a5d5fd2e";
|
||||
//case 3325839809379844461264382260940242222: return $"{oidPath}/02808890-0ad8-1085-9bdf-0002a5d5fd2e";
|
||||
// TODO: Left off at http://www.oid-info.com/get/2.25.3664154270495270126161055518190585115
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// telebiometrics
|
||||
#region 2.42.*
|
||||
|
||||
oid_2_42:
|
||||
|
||||
oidPath += "/Telebiometrics";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_2_42_0;
|
||||
case 1: goto oid_2_42_1;
|
||||
case 2: goto oid_2_42_2;
|
||||
case 3: goto oid_2_42_3;
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// modules
|
||||
#region 2.42.0.*
|
||||
|
||||
oid_2_42_0:
|
||||
|
||||
oidPath += "/Modules";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_2_42_0_0;
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// main
|
||||
#region 2.42.0.0.*
|
||||
|
||||
oid_2_42_0_0:
|
||||
|
||||
oidPath += "/Main_Module";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Version1",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// tmm
|
||||
#region 2.42.1.*
|
||||
|
||||
oid_2_42_1:
|
||||
|
||||
oidPath += "/TMM";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_2_42_1_0;
|
||||
case 1: goto oid_2_42_1_1;
|
||||
case 2: goto oid_2_42_1_2;
|
||||
case 3: goto oid_2_42_1_3;
|
||||
case 4: return $"{oidPath}/Practitioners";
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// modules
|
||||
#region 2.42.1.0.*
|
||||
|
||||
oid_2_42_1_0:
|
||||
|
||||
oidPath += "/Modules";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_2_42_1_0_0;
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// main
|
||||
#region 2.42.1.0.0.*
|
||||
|
||||
oid_2_42_1_0_0:
|
||||
|
||||
oidPath += "/Main";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
0 => $"{oidPath}/First_Version",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// measures, metric
|
||||
#region 2.42.1.1.*
|
||||
|
||||
oid_2_42_1_1:
|
||||
|
||||
oidPath += "/Measures";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 1: goto oid_2_42_1_1_1;
|
||||
case 2: return $"{oidPath}/Units";
|
||||
case 3: return $"{oidPath}";
|
||||
case 4: return $"{oidPath}/Conditions";
|
||||
case 5: goto oid_2_42_1_1_5;
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// quantities
|
||||
#region 2.42.1.1.1.*
|
||||
|
||||
oid_2_42_1_1_1:
|
||||
|
||||
oidPath += "/Quantities";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Physics",
|
||||
2 => $"{oidPath}/Chemistry",
|
||||
3 => $"{oidPath}/Biology",
|
||||
4 => $"{oidPath}/Culturology",
|
||||
5 => $"{oidPath}/Psychology",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// methods
|
||||
#region 2.42.1.1.5.*
|
||||
|
||||
oid_2_42_1_1_5:
|
||||
|
||||
oidPath += "/Methods";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Physics",
|
||||
2 => $"{oidPath}/Chemistry",
|
||||
3 => $"{oidPath}/Biology",
|
||||
4 => $"{oidPath}/Culturology",
|
||||
5 => $"{oidPath}/Psychology",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// fields-of-study, scientific
|
||||
#region 2.42.1.2.*
|
||||
|
||||
oid_2_42_1_2:
|
||||
|
||||
oidPath += "/Fields_of_Study";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Physics",
|
||||
2 => $"{oidPath}/Chemistry",
|
||||
3 => $"{oidPath}/Biology",
|
||||
4 => $"{oidPath}/Culturology",
|
||||
5 => $"{oidPath}/Psychology",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// modalities, sensory
|
||||
#region 2.42.1.3.*
|
||||
|
||||
oid_2_42_1_3:
|
||||
|
||||
oidPath += "/Modalities";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Tango",
|
||||
2 => $"{oidPath}/Video",
|
||||
3 => $"{oidPath}/Audio",
|
||||
4 => $"{oidPath}/Chemo",
|
||||
5 => $"{oidPath}/Radio",
|
||||
6 => $"{oidPath}/Calor",
|
||||
7 => $"{oidPath}/Electro",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// human-physiology
|
||||
#region 2.42.2.*
|
||||
|
||||
oid_2_42_2:
|
||||
|
||||
oidPath += "/Human_Physiology";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_2_42_2_0;
|
||||
case 1: goto oid_2_42_2_1;
|
||||
case 2: return $"{oidPath}/Symbol_Combinations";
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// modules
|
||||
#region 2.42.2.0.*
|
||||
|
||||
oid_2_42_2_0:
|
||||
|
||||
oidPath += "/Modules";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_2_42_2_0_0;
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// main
|
||||
#region 2.42.2.0.0.*
|
||||
|
||||
oid_2_42_2_0_0:
|
||||
|
||||
oidPath += "/Main_Module";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
0 => $"{oidPath}/First_Version",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// symbols
|
||||
#region 2.42.2.1.*
|
||||
|
||||
oid_2_42_2_1:
|
||||
|
||||
oidPath += "/Symbols";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Tango_in",
|
||||
2 => $"{oidPath}/Video_in",
|
||||
3 => $"{oidPath}/Audio_in",
|
||||
4 => $"{oidPath}/Chemo_in",
|
||||
5 => $"{oidPath}/Radio_in",
|
||||
6 => $"{oidPath}/Calor_in",
|
||||
7 => $"{oidPath}/Tango_out",
|
||||
8 => $"{oidPath}/Video_out",
|
||||
9 => $"{oidPath}/Audio_out",
|
||||
10 => $"{oidPath}/Chemo_out",
|
||||
11 => $"{oidPath}/Radio_out",
|
||||
12 => $"{oidPath}/Calor_out",
|
||||
13 => $"{oidPath}/Safe",
|
||||
14 => $"{oidPath}/Threshold",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// obj-cat, telehealth, e-health-protocol, th
|
||||
#region 2.42.3.*
|
||||
|
||||
oid_2_42_3:
|
||||
|
||||
oidPath += "/E_Health_Protocol";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_2_42_3_0;
|
||||
case 1: return $"{oidPath}/[Patient schemes]";
|
||||
case 2: return $"{oidPath}/[Medical staff schemes]";
|
||||
case 3: return $"{oidPath}/[Observer schemes]";
|
||||
case 4: return $"{oidPath}/[Pharmaceutical schemes]";
|
||||
case 5: return $"{oidPath}/[Laboratory schemes]";
|
||||
case 6: return $"{oidPath}/[Drug manufacturer schemes]";
|
||||
case 7: return $"{oidPath}/[Medical device schemes]";
|
||||
case 8: return $"{oidPath}/[Medical software schemes]";
|
||||
case 9: return $"{oidPath}/[Medical insurance schemes]";
|
||||
case 10: return $"{oidPath}/[Medical record schemes]";
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// obj-cat, telehealth, e-health-protocol, th
|
||||
#region 2.42.3.0.*
|
||||
|
||||
oid_2_42_3_0:
|
||||
|
||||
oidPath += "/Modules";
|
||||
if (index == values.Length) return oidPath;
|
||||
switch (values[index++])
|
||||
{
|
||||
case 0: goto oid_2_42_3_0_0;
|
||||
case 1: goto oid_2_42_3_0_1;
|
||||
case 2: goto oid_2_42_3_0_2;
|
||||
case 3: goto oid_2_42_3_0_3;
|
||||
case 4: goto oid_2_42_3_0_4;
|
||||
case 5: goto oid_2_42_3_0_5;
|
||||
default: return $"{oidPath}/{values[index - 1]}";
|
||||
}
|
||||
|
||||
// identification
|
||||
#region 2.42.3.0.0.*
|
||||
|
||||
oid_2_42_3_0_0:
|
||||
|
||||
oidPath += "/Identification";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Version1",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// set-up
|
||||
#region 2.42.3.0.1.*
|
||||
|
||||
oid_2_42_3_0_1:
|
||||
|
||||
oidPath += "/Setup";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Version1",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// send-and-ack
|
||||
#region 2.42.3.0.2.*
|
||||
|
||||
oid_2_42_3_0_2:
|
||||
|
||||
oidPath += "/Send-and-ack";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Version1",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// command-response
|
||||
#region 2.42.3.0.3.*
|
||||
|
||||
oid_2_42_3_0_3:
|
||||
|
||||
oidPath += "/Command-response";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Version1",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// quantity-and-units
|
||||
#region 2.42.3.0.4.*
|
||||
|
||||
oid_2_42_3_0_4:
|
||||
|
||||
oidPath += "/Quantities_And_Units";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Version1",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// examples
|
||||
#region 2.42.3.0.5.*
|
||||
|
||||
oid_2_42_3_0_5:
|
||||
|
||||
oidPath += "/Examples";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
0 => $"{oidPath}/Command_Response",
|
||||
1 => $"{oidPath}/Data_Message",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
// cybersecurity
|
||||
#region 2.48.*
|
||||
|
||||
oid_2_48:
|
||||
|
||||
oidPath += "/Cybersecurity";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
1 => $"{oidPath}/Country",
|
||||
2 => $"{oidPath}/International-Org",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
// alerting
|
||||
#region 2.49.*
|
||||
|
||||
oid_2_49:
|
||||
|
||||
oidPath += "/Alerting";
|
||||
if (index == values.Length) return oidPath;
|
||||
return values[index++] switch
|
||||
{
|
||||
0 => $"{oidPath}/WMO",
|
||||
_ => $"{oidPath}/{values[index - 1]}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
71
SabreTools.Serialization/ObjectIdentifier/Parser.cs
Normal file
71
SabreTools.Serialization/ObjectIdentifier/Parser.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SabreTools.Serialization.ObjectIdentifier
|
||||
{
|
||||
/// <summary>
|
||||
/// Methods related to Object Identifiers (OID)
|
||||
/// </summary>
|
||||
public static partial class Parser
|
||||
{
|
||||
// TODO: ulong[] isn't going to work. If we can use .NET 7, we can use UInt128
|
||||
// We might want to look into storing all values as GUID? I don't remember if
|
||||
// you can do value comparisions between an integral value and a GUID, though.
|
||||
|
||||
/// <summary>
|
||||
/// Parse an OID in DER-encoded byte notation into a list of values
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array representing the data to read</param>
|
||||
/// <param name="length">Total length of the data according to the DER TLV</param>
|
||||
/// <returns>Array of values representing the OID</returns>
|
||||
public static ulong[] ParseDERIntoArray(byte[] data, ulong length)
|
||||
{
|
||||
// The first byte contains nodes 1 and 2
|
||||
int firstNode = Math.DivRem(data[0], 40, out int secondNode);
|
||||
|
||||
// Create a list for all nodes
|
||||
List<ulong> nodes = [(ulong)firstNode, (ulong)secondNode];
|
||||
|
||||
// All other nodes are encoded uniquely
|
||||
int offset = 1;
|
||||
while (offset < (long)length)
|
||||
{
|
||||
// If bit 7 is not set
|
||||
if ((data[offset] & 0x80) == 0)
|
||||
{
|
||||
nodes.Add(data[offset]);
|
||||
offset++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, read the encoded value in a loop
|
||||
ulong dotValue = 0;
|
||||
bool doneProcessing = false;
|
||||
|
||||
do
|
||||
{
|
||||
// Shift the current encoded value
|
||||
dotValue <<= 7;
|
||||
|
||||
// If we have a leading zero byte, we're at the end
|
||||
if ((data[offset] & 0x80) == 0)
|
||||
doneProcessing = true;
|
||||
|
||||
// Clear the top byte
|
||||
unchecked { data[offset] &= (byte)~0x80; }
|
||||
|
||||
// Add the new value to the result
|
||||
dotValue |= data[offset];
|
||||
|
||||
// Increment the offset
|
||||
offset++;
|
||||
} while (offset < data.Length && !doneProcessing);
|
||||
|
||||
// Add the parsed value to the output
|
||||
nodes.Add(dotValue);
|
||||
}
|
||||
|
||||
return [.. nodes];
|
||||
}
|
||||
}
|
||||
}
|
||||
25
SabreTools.Serialization/ObjectIdentifier/Parser.dot.cs
Normal file
25
SabreTools.Serialization/ObjectIdentifier/Parser.dot.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace SabreTools.Serialization.ObjectIdentifier
|
||||
{
|
||||
/// <summary>
|
||||
/// Methods related to Object Identifiers (OID) and dot notation
|
||||
/// </summary>
|
||||
public static partial class Parser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse an OID in separated-value notation into dot notation
|
||||
/// </summary>
|
||||
/// <param name="values">List of values to check against</param>
|
||||
/// <returns>List of values representing the dot notation</returns>
|
||||
public static string? ParseOIDToDotNotation(ulong[]? values)
|
||||
{
|
||||
// If we have an invalid set of values, we can't do anything
|
||||
if (values == null || values.Length == 0)
|
||||
return null;
|
||||
|
||||
var stringValues = Array.ConvertAll(values, v => v.ToString());
|
||||
return string.Join(".", [.. stringValues]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Text;
|
||||
using SabreTools.Models.BSP;
|
||||
using SabreTools.Models.TAR;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Printers
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using SabreTools.Models.NewExecutable;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Printers
|
||||
|
||||
@@ -2,12 +2,12 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using SabreTools.ASN1;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Models.COFF;
|
||||
using SabreTools.Models.COFF.SymbolTableEntries;
|
||||
using SabreTools.Models.PortableExecutable;
|
||||
using SabreTools.Models.PortableExecutable.COFFSymbolTableEntries;
|
||||
using SabreTools.Models.PortableExecutable.ResourceEntries;
|
||||
using SabreTools.Models.PortableExecutable.Resource.Entries;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Printers
|
||||
@@ -28,22 +28,36 @@ namespace SabreTools.Serialization.Printers
|
||||
Print(builder, executable.Stub?.Header);
|
||||
|
||||
// Header
|
||||
Print(builder, executable.Signature, executable.COFFFileHeader);
|
||||
Print(builder, executable.Signature, executable.FileHeader);
|
||||
Print(builder, executable.OptionalHeader, executable.SectionTable);
|
||||
|
||||
// Tables
|
||||
// COFF Tables
|
||||
Print(builder, executable.SectionTable);
|
||||
Print(builder, executable.COFFSymbolTable);
|
||||
Print(builder, executable.COFFStringTable);
|
||||
Print(builder, executable.SymbolTable);
|
||||
Print(builder, executable.StringTable);
|
||||
|
||||
// Export Table
|
||||
Print(builder, executable.ExportDirectoryTable, executable.SectionTable);
|
||||
Print(builder, executable.ExportAddressTable, executable.SectionTable);
|
||||
Print(builder, executable.NamePointerTable);
|
||||
Print(builder, executable.OrdinalTable);
|
||||
Print(builder, executable.ExportNameTable);
|
||||
|
||||
// Import Table
|
||||
Print(builder, executable.ImportDirectoryTable, executable.SectionTable);
|
||||
Print(builder, executable.ImportLookupTables, executable.SectionTable);
|
||||
Print(builder, executable.ImportAddressTables, executable.SectionTable);
|
||||
Print(builder, executable.HintNameTable);
|
||||
|
||||
// Resource Table
|
||||
Print(builder, executable.ResourceDirectoryTable, executable.SectionTable);
|
||||
|
||||
Print(builder, executable.AttributeCertificateTable);
|
||||
Print(builder, executable.DelayLoadDirectoryTable);
|
||||
Print(builder, executable.DelayLoadDirectoryTable, executable.SectionTable);
|
||||
|
||||
// Named Sections
|
||||
Print(builder, executable.BaseRelocationTable, executable.SectionTable);
|
||||
Print(builder, executable.DebugTable);
|
||||
Print(builder, executable.ExportTable);
|
||||
Print(builder, executable.ImportTable, executable.SectionTable);
|
||||
Print(builder, executable.ResourceDirectoryTable);
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, Models.MSDOS.ExecutableHeader? header)
|
||||
@@ -83,13 +97,13 @@ namespace SabreTools.Serialization.Printers
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, string? signature, COFFFileHeader? header)
|
||||
private static void Print(StringBuilder builder, string? signature, FileHeader? header)
|
||||
{
|
||||
builder.AppendLine(" COFF File Header Information:");
|
||||
builder.AppendLine(" File Header Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (header == null)
|
||||
{
|
||||
builder.AppendLine(" No COFF file header");
|
||||
builder.AppendLine(" No file header");
|
||||
builder.AppendLine();
|
||||
return;
|
||||
}
|
||||
@@ -105,7 +119,7 @@ namespace SabreTools.Serialization.Printers
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, OptionalHeader? header, SectionHeader[]? table)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.OptionalHeader? header, SectionHeader[]? table)
|
||||
{
|
||||
builder.AppendLine(" Optional Header Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
@@ -127,10 +141,7 @@ namespace SabreTools.Serialization.Printers
|
||||
if (header.Magic == OptionalHeaderMagicNumber.PE32)
|
||||
builder.AppendLine(header.BaseOfData, " Base of data");
|
||||
|
||||
if (header.Magic == OptionalHeaderMagicNumber.PE32)
|
||||
builder.AppendLine(header.ImageBase_PE32, " Image base");
|
||||
else
|
||||
builder.AppendLine(header.ImageBase_PE32Plus, " Image base");
|
||||
builder.AppendLine(header.ImageBase, " Image base");
|
||||
builder.AppendLine(header.SectionAlignment, " Section alignment");
|
||||
builder.AppendLine(header.FileAlignment, " File alignment");
|
||||
builder.AppendLine(header.MajorOperatingSystemVersion, " Major operating system version");
|
||||
@@ -145,20 +156,10 @@ namespace SabreTools.Serialization.Printers
|
||||
builder.AppendLine(header.CheckSum, " Checksum");
|
||||
builder.AppendLine($" Subsystem: {header.Subsystem} (0x{header.Subsystem:X})");
|
||||
builder.AppendLine($" DLL characteristics: {header.DllCharacteristics} (0x{header.DllCharacteristics:X})");
|
||||
if (header.Magic == OptionalHeaderMagicNumber.PE32)
|
||||
{
|
||||
builder.AppendLine(header.SizeOfStackReserve_PE32, " Size of stack reserve");
|
||||
builder.AppendLine(header.SizeOfStackCommit_PE32, " Size of stack commit");
|
||||
builder.AppendLine(header.SizeOfHeapReserve_PE32, " Size of heap reserve");
|
||||
builder.AppendLine(header.SizeOfHeapCommit_PE32, " Size of heap commit");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine(header.SizeOfStackReserve_PE32Plus, " Size of stack reserve");
|
||||
builder.AppendLine(header.SizeOfStackCommit_PE32Plus, " Size of stack commit");
|
||||
builder.AppendLine(header.SizeOfHeapReserve_PE32Plus, " Size of heap reserve");
|
||||
builder.AppendLine(header.SizeOfHeapCommit_PE32Plus, " Size of heap commit");
|
||||
}
|
||||
builder.AppendLine(header.SizeOfStackReserve, " Size of stack reserve");
|
||||
builder.AppendLine(header.SizeOfStackCommit, " Size of stack commit");
|
||||
builder.AppendLine(header.SizeOfHeapReserve, " Size of heap reserve");
|
||||
builder.AppendLine(header.SizeOfHeapCommit, " Size of heap commit");
|
||||
builder.AppendLine(header.LoaderFlags, " Loader flags");
|
||||
builder.AppendLine(header.NumberOfRvaAndSizes, " Number of data-directory entries");
|
||||
|
||||
@@ -314,11 +315,11 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
private static void Print(StringBuilder builder, BaseEntry[]? entries)
|
||||
{
|
||||
builder.AppendLine(" COFF Symbol Table Information:");
|
||||
builder.AppendLine(" Symbol Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (entries == null || entries.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No COFF symbol table items");
|
||||
builder.AppendLine(" No symbol table items");
|
||||
builder.AppendLine();
|
||||
return;
|
||||
}
|
||||
@@ -344,7 +345,7 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
private static void Print(StringBuilder builder, StandardRecord entry, int i)
|
||||
{
|
||||
builder.AppendLine($" COFF Symbol Table Entry {i} (Standard Record)");
|
||||
builder.AppendLine($" Symbol Table Entry {i} (Standard Record)");
|
||||
if (entry.ShortName != null)
|
||||
{
|
||||
builder.AppendLine(entry.ShortName, " Short name", Encoding.ASCII);
|
||||
@@ -355,7 +356,7 @@ namespace SabreTools.Serialization.Printers
|
||||
builder.AppendLine(entry.Offset, " Offset");
|
||||
}
|
||||
builder.AppendLine(entry.Value, " Value");
|
||||
builder.AppendLine(entry.SectionNumber, " Section number");
|
||||
builder.AppendLine($" Section number: {entry.SectionNumber} (0x{entry.SectionNumber:X})");
|
||||
builder.AppendLine($" Symbol type: {entry.SymbolType} (0x{entry.SymbolType:X})");
|
||||
builder.AppendLine($" Storage class: {entry.StorageClass} (0x{entry.StorageClass:X})");
|
||||
builder.AppendLine(entry.NumberOfAuxSymbols, " Number of aux symbols");
|
||||
@@ -363,7 +364,7 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
private static void Print(StringBuilder builder, FunctionDefinition entry, int i)
|
||||
{
|
||||
builder.AppendLine($" COFF Symbol Table Entry {i} (Function Definition)");
|
||||
builder.AppendLine($" Symbol Table Entry {i} (Function Definition)");
|
||||
builder.AppendLine(entry.TagIndex, " Tag index");
|
||||
builder.AppendLine(entry.TotalSize, " Total size");
|
||||
builder.AppendLine(entry.PointerToLinenumber, " Pointer to linenumber");
|
||||
@@ -373,7 +374,7 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
private static void Print(StringBuilder builder, Descriptor entry, int i)
|
||||
{
|
||||
builder.AppendLine($" COFF Symbol Table Entry {i} (.bf and .ef Symbol)");
|
||||
builder.AppendLine($" Symbol Table Entry {i} (.bf and .ef Symbol)");
|
||||
builder.AppendLine(entry.Unused1, " Unused");
|
||||
builder.AppendLine(entry.Linenumber, " Linenumber");
|
||||
builder.AppendLine(entry.Unused2, " Unused");
|
||||
@@ -383,7 +384,7 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
private static void Print(StringBuilder builder, WeakExternal entry, int i)
|
||||
{
|
||||
builder.AppendLine($" COFF Symbol Table Entry {i} (Weak External)");
|
||||
builder.AppendLine($" Symbol Table Entry {i} (Weak External)");
|
||||
builder.AppendLine(entry.TagIndex, " Tag index");
|
||||
builder.AppendLine(entry.Characteristics, " Characteristics");
|
||||
builder.AppendLine(entry.Unused, " Unused");
|
||||
@@ -391,13 +392,13 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
private static void Print(StringBuilder builder, FileRecord entry, int i)
|
||||
{
|
||||
builder.AppendLine($" COFF Symbol Table Entry {i} (File)");
|
||||
builder.AppendLine($" Symbol Table Entry {i} (File)");
|
||||
builder.AppendLine(entry.FileName, " File name", Encoding.ASCII);
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, SectionDefinition entry, int i)
|
||||
{
|
||||
builder.AppendLine($" COFF Symbol Table Entry {i} (Section Defintion)");
|
||||
builder.AppendLine($" Symbol Table Entry {i} (Section Defintion)");
|
||||
builder.AppendLine(entry.Length, " Length");
|
||||
builder.AppendLine(entry.NumberOfRelocations, " Number of relocations");
|
||||
builder.AppendLine(entry.NumberOfLinenumbers, " Number of linenumbers");
|
||||
@@ -409,20 +410,20 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
private static void Print(StringBuilder builder, CLRTokenDefinition entry, int i)
|
||||
{
|
||||
builder.AppendLine($" COFF Symbol Table Entry {i} (CLR Token Defintion)");
|
||||
builder.AppendLine($" Symbol Table Entry {i} (CLR Token Defintion)");
|
||||
builder.AppendLine(entry.AuxType, " Aux type");
|
||||
builder.AppendLine(entry.Reserved1, " Reserved");
|
||||
builder.AppendLine(entry.SymbolTableIndex, " Symbol table index");
|
||||
builder.AppendLine(entry.Reserved2, " Reserved");
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, COFFStringTable? stringTable)
|
||||
private static void Print(StringBuilder builder, Models.COFF.StringTable? stringTable)
|
||||
{
|
||||
builder.AppendLine(" COFF String Table Information:");
|
||||
builder.AppendLine(" String Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (stringTable?.Strings == null || stringTable.Strings.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No COFF string table items");
|
||||
builder.AppendLine(" No string table items");
|
||||
builder.AppendLine();
|
||||
return;
|
||||
}
|
||||
@@ -431,14 +432,14 @@ namespace SabreTools.Serialization.Printers
|
||||
for (int i = 0; i < stringTable.Strings.Length; i++)
|
||||
{
|
||||
string? entry = stringTable.Strings[i];
|
||||
builder.AppendLine($" COFF String Table Entry {i})");
|
||||
builder.AppendLine($" String Table Entry {i})");
|
||||
builder.AppendLine(entry, " Value");
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, AttributeCertificateTableEntry[]? entries)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.AttributeCertificate.Entry[]? entries)
|
||||
{
|
||||
builder.AppendLine(" Attribute Certificate Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
@@ -449,6 +450,9 @@ namespace SabreTools.Serialization.Printers
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the deserializer
|
||||
var deserializer = new Deserializers.AbstractSyntaxNotationOne();
|
||||
|
||||
for (int i = 0; i < entries.Length; i++)
|
||||
{
|
||||
var entry = entries[i];
|
||||
@@ -468,7 +472,7 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
else
|
||||
{
|
||||
var topLevelValues = AbstractSyntaxNotationOne.Parse(entry.Certificate, 0);
|
||||
var topLevelValues = deserializer.Deserialize(entry.Certificate, 0);
|
||||
if (topLevelValues == null)
|
||||
{
|
||||
builder.AppendLine(" INVALID DATA FOUND");
|
||||
@@ -476,7 +480,7 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (TypeLengthValue tlv in topLevelValues)
|
||||
foreach (Models.ASN1.TypeLengthValue tlv in topLevelValues)
|
||||
{
|
||||
string tlvString = tlv.Format(paddingLevel: 4);
|
||||
builder.AppendLine(tlvString);
|
||||
@@ -502,7 +506,7 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, DelayLoadDirectoryTable? table)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.DelayLoad.DirectoryTable? table, SectionHeader[]? sections)
|
||||
{
|
||||
builder.AppendLine(" Delay-Load Directory Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
@@ -514,17 +518,22 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
|
||||
builder.AppendLine(table.Attributes, " Attributes");
|
||||
builder.AppendLine(table.Name, " Name RVA");
|
||||
builder.AppendLine(table.NameRVA, " Name RVA");
|
||||
builder.AppendLine(table.NameRVA.ConvertVirtualAddress(sections), " Name physical address");
|
||||
builder.AppendLine(table.ModuleHandle, " Module handle");
|
||||
builder.AppendLine(table.DelayImportAddressTable, " Delay import address table RVA");
|
||||
builder.AppendLine(table.DelayImportAddressTable.ConvertVirtualAddress(sections), " Delay import address table physical address");
|
||||
builder.AppendLine(table.DelayImportNameTable, " Delay import name table RVA");
|
||||
builder.AppendLine(table.DelayImportNameTable.ConvertVirtualAddress(sections), " Delay import name table physical address");
|
||||
builder.AppendLine(table.BoundDelayImportTable, " Bound delay import table RVA");
|
||||
builder.AppendLine(table.BoundDelayImportTable.ConvertVirtualAddress(sections), " Bound delay import table physical address");
|
||||
builder.AppendLine(table.UnloadDelayImportTable, " Unload delay import table RVA");
|
||||
builder.AppendLine(table.UnloadDelayImportTable.ConvertVirtualAddress(sections), " Unload delay import table physical address");
|
||||
builder.AppendLine(table.TimeStamp, " Timestamp");
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, BaseRelocationBlock[]? entries, SectionHeader[]? table)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.BaseRelocation.Block[]? entries, SectionHeader[]? sections)
|
||||
{
|
||||
builder.AppendLine(" Base Relocation Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
@@ -541,7 +550,7 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
builder.AppendLine($" Base Relocation Table Entry {i}");
|
||||
builder.AppendLine(baseRelocationTableEntry.PageRVA, " Page RVA");
|
||||
builder.AppendLine(baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(table), " Page physical address");
|
||||
builder.AppendLine(baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(sections), " Page physical address");
|
||||
builder.AppendLine(baseRelocationTableEntry.BlockSize, " Block size");
|
||||
builder.AppendLine();
|
||||
|
||||
@@ -567,7 +576,7 @@ namespace SabreTools.Serialization.Printers
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, DebugTable? table)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.DebugData.Table? table)
|
||||
{
|
||||
builder.AppendLine(" Debug Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
@@ -578,7 +587,6 @@ namespace SabreTools.Serialization.Printers
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: If more sections added, model this after the Export Table
|
||||
for (int i = 0; i < table.DebugDirectoryTable.Length; i++)
|
||||
{
|
||||
var entry = table.DebugDirectoryTable[i];
|
||||
@@ -597,174 +605,176 @@ namespace SabreTools.Serialization.Printers
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, ExportTable? table)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Export.DirectoryTable? table, SectionHeader[]? sections)
|
||||
{
|
||||
builder.AppendLine(" Export Table Information:");
|
||||
builder.AppendLine(value: " Export Directory Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table == null)
|
||||
{
|
||||
builder.AppendLine(" No export table");
|
||||
builder.AppendLine();
|
||||
return;
|
||||
}
|
||||
|
||||
builder.AppendLine(" Export Directory Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.ExportDirectoryTable == null)
|
||||
{
|
||||
builder.AppendLine(" No export directory table");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine(table.ExportDirectoryTable.ExportFlags, " Export flags");
|
||||
builder.AppendLine(table.ExportDirectoryTable.TimeDateStamp, " Time/Date stamp");
|
||||
builder.AppendLine(table.ExportDirectoryTable.MajorVersion, " Major version");
|
||||
builder.AppendLine(table.ExportDirectoryTable.MinorVersion, " Minor version");
|
||||
builder.AppendLine(table.ExportDirectoryTable.NameRVA, " Name RVA");
|
||||
builder.AppendLine(table.ExportDirectoryTable.Name, " Name");
|
||||
builder.AppendLine(table.ExportDirectoryTable.OrdinalBase, " Ordinal base");
|
||||
builder.AppendLine(table.ExportDirectoryTable.AddressTableEntries, " Address table entries");
|
||||
builder.AppendLine(table.ExportDirectoryTable.NumberOfNamePointers, " Number of name pointers");
|
||||
builder.AppendLine(table.ExportDirectoryTable.ExportAddressTableRVA, " Export address table RVA");
|
||||
builder.AppendLine(table.ExportDirectoryTable.NamePointerRVA, " Name pointer table RVA");
|
||||
builder.AppendLine(table.ExportDirectoryTable.OrdinalTableRVA, " Ordinal table RVA");
|
||||
builder.AppendLine(table.ExportFlags, " Export flags");
|
||||
builder.AppendLine(table.TimeDateStamp, " Time/Date stamp");
|
||||
builder.AppendLine(table.MajorVersion, " Major version");
|
||||
builder.AppendLine(table.MinorVersion, " Minor version");
|
||||
builder.AppendLine(table.NameRVA, " Name RVA");
|
||||
builder.AppendLine(table.NameRVA.ConvertVirtualAddress(sections), " Name physical address");
|
||||
builder.AppendLine(table.Name, " Name");
|
||||
builder.AppendLine(table.OrdinalBase, " Ordinal base");
|
||||
builder.AppendLine(table.AddressTableEntries, " Address table entries");
|
||||
builder.AppendLine(table.NumberOfNamePointers, " Number of name pointers");
|
||||
builder.AppendLine(table.ExportAddressTableRVA, " Export address table RVA");
|
||||
builder.AppendLine(table.ExportAddressTableRVA.ConvertVirtualAddress(sections), " Export address table physical address");
|
||||
builder.AppendLine(table.NamePointerRVA, " Name pointer table RVA");
|
||||
builder.AppendLine(table.NamePointerRVA.ConvertVirtualAddress(sections), " Name pointer table physical address");
|
||||
builder.AppendLine(table.OrdinalTableRVA, " Ordinal table RVA");
|
||||
builder.AppendLine(table.OrdinalTableRVA.ConvertVirtualAddress(sections), " Ordinal table physical address");
|
||||
}
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
builder.AppendLine(" Export Address Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.ExportAddressTable == null || table.ExportAddressTable.Length == 0)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Export.AddressTableEntry[]? table, SectionHeader[]? sections)
|
||||
{
|
||||
builder.AppendLine(" Export Address Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table == null || table.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No export address table items");
|
||||
builder.AppendLine(" No export address table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < table.ExportAddressTable.Length; i++)
|
||||
for (int i = 0; i < table.Length; i++)
|
||||
{
|
||||
var entry = table.ExportAddressTable[i];
|
||||
var entry = table[i];
|
||||
|
||||
builder.AppendLine($" Export Address Table Entry {i}");
|
||||
builder.AppendLine(entry.ExportRVA, " Export RVA / Forwarder RVA");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
|
||||
builder.AppendLine(" Name Pointer Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.NamePointerTable?.Pointers == null || table.NamePointerTable.Pointers.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No name pointer table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < table.NamePointerTable.Pointers.Length; i++)
|
||||
{
|
||||
var entry = table.NamePointerTable.Pointers[i];
|
||||
|
||||
builder.AppendLine($" Name Pointer Table Entry {i}");
|
||||
builder.AppendLine(entry, " Pointer");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
|
||||
builder.AppendLine(" Ordinal Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.OrdinalTable?.Indexes == null || table.OrdinalTable.Indexes.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No ordinal table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < table.OrdinalTable.Indexes.Length; i++)
|
||||
{
|
||||
var entry = table.OrdinalTable.Indexes[i];
|
||||
|
||||
builder.AppendLine($" Ordinal Table Entry {i}");
|
||||
builder.AppendLine(entry, " Index");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
|
||||
builder.AppendLine(" Export Name Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.ExportNameTable?.Strings == null || table.ExportNameTable.Strings.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No export name table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < table.ExportNameTable.Strings.Length; i++)
|
||||
{
|
||||
var entry = table.ExportNameTable.Strings[i];
|
||||
|
||||
builder.AppendLine($" Export Name Table Entry {i}");
|
||||
builder.AppendLine(entry, " String");
|
||||
builder.AppendLine($" Export Address Table Entry {i}");
|
||||
builder.AppendLine(entry.ExportRVA, " Export / Forwarder RVA");
|
||||
builder.AppendLine(entry.ExportRVA.ConvertVirtualAddress(sections), " Export / Forwarder physical address");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, ImportTable? table, SectionHeader[]? sectionTable)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Export.NamePointerTable? table)
|
||||
{
|
||||
builder.AppendLine(" Import Table Information:");
|
||||
builder.AppendLine(" Export Name Pointer Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table == null)
|
||||
if (table?.Pointers == null || table.Pointers.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No import table");
|
||||
builder.AppendLine();
|
||||
return;
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
builder.AppendLine(" Import Directory Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.ImportDirectoryTable == null || table.ImportDirectoryTable.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No import directory table items");
|
||||
builder.AppendLine(" No export name pointer table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < table.ImportDirectoryTable.Length; i++)
|
||||
for (int i = 0; i < table.Pointers.Length; i++)
|
||||
{
|
||||
var entry = table.ImportDirectoryTable[i];
|
||||
var entry = table.Pointers[i];
|
||||
|
||||
builder.AppendLine($" Import Directory Table Entry {i}");
|
||||
builder.AppendLine(entry.ImportLookupTableRVA, " Import lookup table RVA");
|
||||
builder.AppendLine(entry.ImportLookupTableRVA.ConvertVirtualAddress(sectionTable), " Import lookup table Physical Address");
|
||||
builder.AppendLine(entry.TimeDateStamp, " Time/Date stamp");
|
||||
builder.AppendLine(entry.ForwarderChain, " Forwarder chain");
|
||||
builder.AppendLine(entry.NameRVA, " Name RVA");
|
||||
builder.AppendLine(entry.Name, " Name");
|
||||
builder.AppendLine(entry.ImportAddressTableRVA, " Import address table RVA");
|
||||
builder.AppendLine(entry.ImportAddressTableRVA.ConvertVirtualAddress(sectionTable), " Import address table Physical Address");
|
||||
builder.AppendLine($" Export Name Pointer Table Entry {i}");
|
||||
builder.AppendLine(entry, " Pointer");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
builder.AppendLine(" Import Lookup Tables Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.ImportLookupTables == null || table.ImportLookupTables.Count == 0)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Export.OrdinalTable? table)
|
||||
{
|
||||
builder.AppendLine(" Export Ordinal Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table?.Indexes == null || table.Indexes.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No import lookup tables");
|
||||
builder.AppendLine(" No export ordinal table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var kvp in table.ImportLookupTables)
|
||||
for (int i = 0; i < table.Indexes.Length; i++)
|
||||
{
|
||||
var entry = table.Indexes[i];
|
||||
|
||||
builder.AppendLine($" Export Ordinal Table Entry {i}");
|
||||
builder.AppendLine(entry, " Index");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Export.NameTable? table)
|
||||
{
|
||||
builder.AppendLine(" Export Name Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table?.Strings == null || table.Strings.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No export name table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < table.Strings.Length; i++)
|
||||
{
|
||||
var entry = table.Strings[i];
|
||||
|
||||
builder.AppendLine($" Export Name Table Entry {i}");
|
||||
builder.AppendLine(entry, " String");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Import.DirectoryTableEntry[]? table, SectionHeader[]? sections)
|
||||
{
|
||||
builder.AppendLine(" Import Directory Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table == null || table.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No import directory table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < table.Length; i++)
|
||||
{
|
||||
var entry = table[i];
|
||||
|
||||
builder.AppendLine($" Import Directory Table Entry {i}");
|
||||
builder.AppendLine(entry.ImportLookupTableRVA, " Import lookup table RVA");
|
||||
builder.AppendLine(entry.ImportLookupTableRVA.ConvertVirtualAddress(sections), " Import lookup table physical address");
|
||||
builder.AppendLine(entry.TimeDateStamp, " Time/Date stamp");
|
||||
builder.AppendLine(entry.ForwarderChain, " Forwarder chain");
|
||||
builder.AppendLine(entry.NameRVA, " Name RVA");
|
||||
builder.AppendLine(entry.NameRVA.ConvertVirtualAddress(sections), " Name physical address");
|
||||
builder.AppendLine(entry.Name, " Name");
|
||||
builder.AppendLine(entry.ImportAddressTableRVA, " Import address table RVA");
|
||||
builder.AppendLine(entry.ImportAddressTableRVA.ConvertVirtualAddress(sections), " Import address table physical address");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, Dictionary<int, Models.PortableExecutable.Import.LookupTableEntry[]?>? tables, SectionHeader[]? sections)
|
||||
{
|
||||
builder.AppendLine(" Import Lookup Tables Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (tables == null || tables.Count == 0)
|
||||
{
|
||||
builder.AppendLine(" No import lookup tables");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var kvp in tables)
|
||||
{
|
||||
int index = kvp.Key;
|
||||
var importLookupTable = kvp.Value;
|
||||
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" Import Lookup Table {index} Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
builder.AppendLine($" Import Lookup Table {index} Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (importLookupTable == null || importLookupTable.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No import lookup table items");
|
||||
builder.AppendLine(" No import lookup table items");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -772,42 +782,45 @@ namespace SabreTools.Serialization.Printers
|
||||
{
|
||||
var entry = importLookupTable[i];
|
||||
|
||||
builder.AppendLine($" Import Lookup Table {index} Entry {i}");
|
||||
builder.AppendLine(entry.OrdinalNameFlag, " Ordinal/Name flag");
|
||||
builder.AppendLine($" Import Lookup Table {index} Entry {i}");
|
||||
builder.AppendLine(entry.OrdinalNameFlag, " Ordinal/Name flag");
|
||||
if (entry.OrdinalNameFlag)
|
||||
{
|
||||
builder.AppendLine(entry.OrdinalNumber, " Ordinal number");
|
||||
builder.AppendLine(entry.OrdinalNumber, " Ordinal number");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine(entry.HintNameTableRVA, " Hint/Name table RVA");
|
||||
builder.AppendLine(entry.HintNameTableRVA.ConvertVirtualAddress(sectionTable), " Hint/Name table Physical Address");
|
||||
builder.AppendLine(entry.HintNameTableRVA, " Hint/Name table RVA");
|
||||
builder.AppendLine(entry.HintNameTableRVA.ConvertVirtualAddress(sections), " Hint/Name table physical address");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
builder.AppendLine(" Import Address Tables Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.ImportAddressTables == null || table.ImportAddressTables.Count == 0)
|
||||
private static void Print(StringBuilder builder, Dictionary<int, Models.PortableExecutable.Import.AddressTableEntry[]?>? tables, SectionHeader[]? sections)
|
||||
{
|
||||
builder.AppendLine(" Import Address Tables Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (tables == null || tables.Count == 0)
|
||||
{
|
||||
builder.AppendLine(" No import address tables");
|
||||
builder.AppendLine(" No import address tables");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var kvp in table.ImportAddressTables)
|
||||
foreach (var kvp in tables)
|
||||
{
|
||||
int index = kvp.Key;
|
||||
var importAddressTable = kvp.Value;
|
||||
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" Import Address Table {index} Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
builder.AppendLine($" Import Address Table {index} Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (importAddressTable == null || importAddressTable.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No import address table items");
|
||||
builder.AppendLine(" No import address table items");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -815,45 +828,48 @@ namespace SabreTools.Serialization.Printers
|
||||
{
|
||||
var entry = importAddressTable[i];
|
||||
|
||||
builder.AppendLine($" Import Address Table {index} Entry {i}");
|
||||
builder.AppendLine(entry.OrdinalNameFlag, " Ordinal/Name flag");
|
||||
builder.AppendLine($" Import Address Table {index} Entry {i}");
|
||||
builder.AppendLine(entry.OrdinalNameFlag, " Ordinal/Name flag");
|
||||
if (entry.OrdinalNameFlag)
|
||||
{
|
||||
builder.AppendLine(entry.OrdinalNumber, " Ordinal number");
|
||||
builder.AppendLine(entry.OrdinalNumber, " Ordinal number");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine(entry.HintNameTableRVA, " Hint/Name table RVA");
|
||||
builder.AppendLine(entry.HintNameTableRVA.ConvertVirtualAddress(sectionTable), " Hint/Name table Physical Address");
|
||||
builder.AppendLine(entry.HintNameTableRVA, " Hint/Name table RVA");
|
||||
builder.AppendLine(entry.HintNameTableRVA.ConvertVirtualAddress(sections), " Hint/Name table physical address");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
builder.AppendLine(" Hint/Name Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table.HintNameTable == null || table.HintNameTable.Length == 0)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Import.HintNameTableEntry[]? table)
|
||||
{
|
||||
builder.AppendLine(" Import Hint/Name Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
if (table == null || table.Length == 0)
|
||||
{
|
||||
builder.AppendLine(" No hint/name table items");
|
||||
builder.AppendLine(" No import hint/name table items");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < table.HintNameTable.Length; i++)
|
||||
for (int i = 0; i < table.Length; i++)
|
||||
{
|
||||
var entry = table.HintNameTable[i];
|
||||
var entry = table[i];
|
||||
|
||||
builder.AppendLine($" Hint/Name Table Entry {i}");
|
||||
builder.AppendLine(entry.Hint, " Hint");
|
||||
builder.AppendLine(entry.Name, " Name");
|
||||
builder.AppendLine($" Hint/Name Table Entry {i}");
|
||||
builder.AppendLine(entry.Hint, " Hint");
|
||||
builder.AppendLine(entry.Name, " Name");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(StringBuilder builder, ResourceDirectoryTable? table)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Resource.DirectoryTable? table, SectionHeader[]? sections)
|
||||
{
|
||||
builder.AppendLine(" Resource Directory Table Information:");
|
||||
builder.AppendLine(" -------------------------");
|
||||
@@ -864,11 +880,11 @@ namespace SabreTools.Serialization.Printers
|
||||
return;
|
||||
}
|
||||
|
||||
Print(table, level: 0, types: [], builder);
|
||||
Print(builder, table, level: 0, types: [], sections);
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void Print(ResourceDirectoryTable table, int level, List<object> types, StringBuilder builder)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Resource.DirectoryTable table, int level, List<object> types, SectionHeader[]? sections)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -903,12 +919,12 @@ namespace SabreTools.Serialization.Printers
|
||||
else
|
||||
newTypes.Add(entry.IntegerID);
|
||||
|
||||
PrintResourceDirectoryEntry(entry, level + 1, newTypes, builder);
|
||||
Print(builder, entry, level + 1, newTypes, sections);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceDirectoryEntry(ResourceDirectoryEntry entry, int level, List<object> types, StringBuilder builder)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Resource.DirectoryEntry entry, int level, List<object> types, SectionHeader[]? sections)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -924,12 +940,12 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
|
||||
if (entry.DataEntry != null)
|
||||
PrintResourceDataEntry(entry.DataEntry, level: level + 1, types, builder);
|
||||
Print(builder, entry.DataEntry, level: level + 1, types, sections);
|
||||
else if (entry.Subdirectory != null)
|
||||
Print(entry.Subdirectory, level: level + 1, types, builder);
|
||||
Print(builder, entry.Subdirectory, level: level + 1, types, sections);
|
||||
}
|
||||
|
||||
private static void PrintResourceDataEntry(ResourceDataEntry entry, int level, List<object> types, StringBuilder builder)
|
||||
private static void Print(StringBuilder builder, Models.PortableExecutable.Resource.DataEntry entry, int level, List<object> types, SectionHeader[]? sections)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -939,6 +955,7 @@ namespace SabreTools.Serialization.Printers
|
||||
|
||||
builder.AppendLine(level, $"{padding}Entry level");
|
||||
builder.AppendLine(entry.DataRVA, $"{padding}Data RVA");
|
||||
builder.AppendLine(entry.DataRVA.ConvertVirtualAddress(sections), $"{padding}Data physical address");
|
||||
builder.AppendLine(entry.Size, $"{padding}Size");
|
||||
builder.AppendLine(entry.Codepage, $"{padding}Codepage");
|
||||
builder.AppendLine(entry.Reserved, $"{padding}Reserved");
|
||||
@@ -1024,25 +1041,25 @@ namespace SabreTools.Serialization.Printers
|
||||
builder.AppendLine();
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_CURSOR(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_CURSOR(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Hardware-dependent cursor resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_BITMAP(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_BITMAP(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Bitmap resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_ICON(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_ICON(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Hardware-dependent icon resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_MENU(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_MENU(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -1120,7 +1137,7 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_DIALOG(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_DIALOG(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -1255,7 +1272,7 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_STRING(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_STRING(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -1275,19 +1292,19 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_FONTDIR(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_FONTDIR(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Font directory resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_FONT(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_FONT(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Font resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_ACCELERATOR(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_ACCELERATOR(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -1310,7 +1327,7 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_RCDATA(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_RCDATA(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Application-defined resource found, not parsed yet");
|
||||
@@ -1369,7 +1386,7 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_MESSAGETABLE(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_MESSAGETABLE(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -1436,19 +1453,19 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_GROUP_CURSOR(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_GROUP_CURSOR(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Hardware-independent cursor resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_GROUP_ICON(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_GROUP_ICON(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Hardware-independent icon resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_VERSION(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_VERSION(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -1569,37 +1586,37 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_DLGINCLUDE(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_DLGINCLUDE(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}External header resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_PLUGPLAY(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_PLUGPLAY(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Plug and Play resource found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_VXD(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_VXD(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}VXD found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_ANICURSOR(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_ANICURSOR(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Animated cursor found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_ANIICON(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_ANIICON(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}Animated icon found, not parsed yet");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_HTML(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_HTML(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
builder.AppendLine($"{padding}HTML resource found, not parsed yet");
|
||||
@@ -1612,7 +1629,7 @@ namespace SabreTools.Serialization.Printers
|
||||
// builder.AppendLine(Encoding.Unicode.GetString(entry.Data), $"{padding}Value (Unicode)");
|
||||
}
|
||||
|
||||
private static void PrintResourceRT_MANIFEST(ResourceDataEntry entry, int level, StringBuilder builder)
|
||||
private static void PrintResourceRT_MANIFEST(Models.PortableExecutable.Resource.DataEntry entry, int level, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
@@ -1789,7 +1806,7 @@ namespace SabreTools.Serialization.Printers
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintResourceUNKNOWN(ResourceDataEntry entry, int level, object resourceType, StringBuilder builder)
|
||||
private static void PrintResourceUNKNOWN(Models.PortableExecutable.Resource.DataEntry entry, int level, object resourceType, StringBuilder builder)
|
||||
{
|
||||
string padding = new(' ', (level + 1) * 2);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Text;
|
||||
using SabreTools.Models.WiseInstaller;
|
||||
using SabreTools.Models.WiseInstaller.Actions;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Printers
|
||||
|
||||
58
SabreTools.Serialization/SabreTools.Models.ASN1/ASN1Type.cs
Normal file
58
SabreTools.Serialization/SabreTools.Models.ASN1/ASN1Type.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
|
||||
namespace SabreTools.Models.ASN1
|
||||
{
|
||||
/// <summary>
|
||||
/// ASN.1 type indicators
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ASN1Type : byte
|
||||
{
|
||||
#region Types
|
||||
|
||||
V_ASN1_EOC = 0x00,
|
||||
V_ASN1_BOOLEAN = 0x01,
|
||||
V_ASN1_INTEGER = 0x02,
|
||||
V_ASN1_BIT_STRING = 0x03,
|
||||
V_ASN1_OCTET_STRING = 0x04,
|
||||
V_ASN1_NULL = 0x05,
|
||||
V_ASN1_OBJECT = 0x06,
|
||||
V_ASN1_OBJECT_DESCRIPTOR = 0x07,
|
||||
V_ASN1_EXTERNAL = 0x08,
|
||||
V_ASN1_REAL = 0x09,
|
||||
V_ASN1_ENUMERATED = 0x0A,
|
||||
V_ASN1_UTF8STRING = 0x0C,
|
||||
V_ASN1_SEQUENCE = 0x10,
|
||||
V_ASN1_SET = 0x11,
|
||||
V_ASN1_NUMERICSTRING = 0x12,
|
||||
V_ASN1_PRINTABLESTRING = 0x13,
|
||||
V_ASN1_T61STRING = 0x14,
|
||||
V_ASN1_TELETEXSTRING = 0x14,
|
||||
V_ASN1_VIDEOTEXSTRING = 0x15,
|
||||
V_ASN1_IA5STRING = 0x16,
|
||||
V_ASN1_UTCTIME = 0x17,
|
||||
V_ASN1_GENERALIZEDTIME = 0x18,
|
||||
V_ASN1_GRAPHICSTRING = 0x19,
|
||||
V_ASN1_ISO64STRING = 0x1A,
|
||||
V_ASN1_VISIBLESTRING = 0x1A,
|
||||
V_ASN1_GENERALSTRING = 0x1B,
|
||||
V_ASN1_UNIVERSALSTRING = 0x1C,
|
||||
V_ASN1_BMPSTRING = 0x1E,
|
||||
|
||||
#endregion
|
||||
|
||||
#region Modifiers
|
||||
|
||||
// Commented out because it is the default
|
||||
// and can interfere with V_ASN1_EOC
|
||||
// V_ASN1_UNIVERSAL = 0x00,
|
||||
|
||||
V_ASN1_PRIMITIVE_TAG = 0x1F,
|
||||
V_ASN1_CONSTRUCTED = 0x20,
|
||||
V_ASN1_APPLICATION = 0x40,
|
||||
V_ASN1_CONTEXT_SPECIFIC = 0x80,
|
||||
V_ASN1_PRIVATE = 0xC0,
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace SabreTools.Models.ASN1
|
||||
{
|
||||
/// <summary>
|
||||
/// ASN.1 type/length/value class that all types are based on
|
||||
/// </summary>
|
||||
public class TypeLengthValue
|
||||
{
|
||||
/// <summary>
|
||||
/// The ASN.1 type
|
||||
/// </summary>
|
||||
public ASN1Type Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Length of the value
|
||||
/// </summary>
|
||||
public ulong Length { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Generic value associated with <see cref="Type"/>
|
||||
/// </summary>
|
||||
public object? Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,13 @@
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<!-- Added due to StormLibSharp -->
|
||||
<NoWarn>CS8600;CS8601;CS8603;CS8604;CS8618;CS8625;CS8634;IL3000</NoWarn>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.9.2</Version>
|
||||
<Version>1.9.6</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
@@ -26,6 +28,28 @@
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
|
||||
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set a build flag for Windows specifically -->
|
||||
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
|
||||
<DefineConstants>$(DefineConstants);WINX86</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x64'">
|
||||
<DefineConstants>$(DefineConstants);WINX64</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Exclude certain parts of external modules for by default -->
|
||||
<PropertyGroup>
|
||||
<DefaultItemExcludes>
|
||||
@@ -36,9 +60,8 @@
|
||||
</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Exclude all external modules for .NET Framework 2.0, .NET Framework 3.5, or non-Windows
|
||||
builds -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR !$(RuntimeIdentifier.StartsWith(`win-x86`))">
|
||||
<!-- Exclude all external modules for .NET Framework 2.0, .NET Framework 3.5, or non-Windows builds -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR !($(RuntimeIdentifier.StartsWith(`win-x86`)) OR $(RuntimeIdentifier.StartsWith(`win-x64`)))">
|
||||
<DefaultItemExcludes>
|
||||
$(DefaultItemExcludes);
|
||||
_EXTERNAL\**
|
||||
@@ -62,12 +85,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SabreTools.ASN1" Version="1.6.2" />
|
||||
<PackageReference Include="NetLegacySupport.Numerics" Version="1.0.1" Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.5.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.7.2" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.7.1" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.6.0" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.7.5" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.7.2" />
|
||||
<PackageReference Include="SharpCompress" Version="0.40.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -112,8 +112,10 @@ namespace SabreTools.Serialization.Serializers
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
using var fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
stream.CopyTo(fs);
|
||||
fs.Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,10 @@ namespace SabreTools.Serialization.Serializers
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
using var fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
stream.CopyTo(fs);
|
||||
fs.Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,10 @@ namespace SabreTools.Serialization.Serializers
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
using var fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
stream.CopyTo(fs);
|
||||
fs.Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -270,7 +272,11 @@ namespace SabreTools.Serialization.Serializers
|
||||
writer.WriteRequiredAttributeString("name", rom.Name, throwOnError: true);
|
||||
writer.WriteRequiredAttributeString("size", rom.Size, throwOnError: true);
|
||||
writer.WriteOptionalAttributeString("crc", rom.CRC);
|
||||
writer.WriteOptionalAttributeString("md2", rom.MD2);
|
||||
writer.WriteOptionalAttributeString("md4", rom.MD4);
|
||||
writer.WriteOptionalAttributeString("md5", rom.MD5);
|
||||
writer.WriteOptionalAttributeString("ripemd128", rom.RIPEMD128);
|
||||
writer.WriteOptionalAttributeString("ripemd160", rom.RIPEMD160);
|
||||
writer.WriteOptionalAttributeString("sha1", rom.SHA1);
|
||||
writer.WriteOptionalAttributeString("sha256", rom.SHA256);
|
||||
writer.WriteOptionalAttributeString("sha384", rom.SHA384);
|
||||
|
||||
@@ -59,8 +59,10 @@ namespace SabreTools.Serialization.Serializers
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = System.IO.File.OpenWrite(path);
|
||||
using var fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
stream.CopyTo(fs);
|
||||
fs.Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -110,6 +112,12 @@ namespace SabreTools.Serialization.Serializers
|
||||
case HashType.MD5:
|
||||
WriteMD5(obj.MD5, writer);
|
||||
break;
|
||||
case HashType.RIPEMD128:
|
||||
WriteRIPEMD128(obj.RIPEMD128, writer);
|
||||
break;
|
||||
case HashType.RIPEMD160:
|
||||
WriteRIPEMD160(obj.RIPEMD160, writer);
|
||||
break;
|
||||
case HashType.SHA1:
|
||||
WriteSHA1(obj.SHA1, writer);
|
||||
break;
|
||||
@@ -222,6 +230,50 @@ namespace SabreTools.Serialization.Serializers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write RIPEMD128 information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="ripemd128s">Array of RIPEMD128 objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteRIPEMD128(RIPEMD128[]? ripemd128s, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (ripemd128s == null || ripemd128s.Length == 0)
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var ripemd128 in ripemd128s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ripemd128.Hash) || string.IsNullOrEmpty(ripemd128.File))
|
||||
continue;
|
||||
|
||||
writer.WriteValues([ripemd128.Hash!, ripemd128.File!]);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write RIPEMD160 information to the current writer
|
||||
/// </summary>
|
||||
/// <param name="ripemd160s">Array of RIPEMD160 objects representing the files</param>
|
||||
/// <param name="writer">SeparatedValueWriter representing the output</param>
|
||||
private static void WriteRIPEMD160(RIPEMD160[]? ripemd160s, SeparatedValueWriter writer)
|
||||
{
|
||||
// If the item information is missing, we can't do anything
|
||||
if (ripemd160s == null || ripemd160s.Length == 0)
|
||||
return;
|
||||
|
||||
// Loop through and write out the items
|
||||
foreach (var ripemd160 in ripemd160s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ripemd160.Hash) || string.IsNullOrEmpty(ripemd160.File))
|
||||
continue;
|
||||
|
||||
writer.WriteValues([ripemd160.Hash!, ripemd160.File!]);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write SHA1 information to the current writer
|
||||
/// </summary>
|
||||
|
||||
@@ -59,8 +59,9 @@ namespace SabreTools.Serialization.Serializers
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
using var fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
stream.CopyTo(fs);
|
||||
fs.Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -100,8 +100,10 @@ namespace SabreTools.Serialization.Serializers
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
using var fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
stream.CopyTo(fs);
|
||||
fs.Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,8 +64,9 @@ namespace SabreTools.Serialization.Serializers
|
||||
if (stream == null)
|
||||
return false;
|
||||
|
||||
using var fs = File.OpenWrite(path);
|
||||
using var fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
stream.CopyTo(fs);
|
||||
fs.Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
using static SabreTools.Matching.Extensions;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
public static class WrapperFactory
|
||||
{
|
||||
@@ -30,7 +29,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
WrapperType.IniFile => null,// TODO: Implement wrapper
|
||||
WrapperType.InstallShieldArchiveV3 => InstallShieldArchiveV3.Create(data),
|
||||
WrapperType.InstallShieldCAB => InstallShieldCabinet.Create(data),
|
||||
WrapperType.LDSCRYPT => null,// TODO: Implement wrapper
|
||||
WrapperType.LDSCRYPT => LDSCRYPT.Create(data),
|
||||
WrapperType.LZKWAJ => LZKWAJ.Create(data),
|
||||
WrapperType.LZQBasic => LZQBasic.Create(data),
|
||||
WrapperType.LZSZDD => LZSZDD.Create(data),
|
||||
@@ -47,11 +46,11 @@ namespace SabreTools.Serialization.Wrappers
|
||||
WrapperType.PlayJPlaylist => PlayJPlaylist.Create(data),
|
||||
WrapperType.Quantum => Quantum.Create(data),
|
||||
WrapperType.RAR => RAR.Create(data),
|
||||
WrapperType.RealArcadeInstaller => null,// TODO: Implement wrapper
|
||||
WrapperType.RealArcadeMezzanine => null,// TODO: Implement wrapper
|
||||
WrapperType.RealArcadeInstaller => RealArcadeInstaller.Create(data),
|
||||
WrapperType.RealArcadeMezzanine => RealArcadeMezzanine.Create(data),
|
||||
WrapperType.SecuROMDFA => SecuROMDFA.Create(data),
|
||||
WrapperType.SevenZip => SevenZip.Create(data),
|
||||
WrapperType.SFFS => null,// TODO: Implement wrapper
|
||||
WrapperType.SFFS => SFFS.Create(data),
|
||||
WrapperType.SGA => SGA.Create(data),
|
||||
WrapperType.TapeArchive => TapeArchive.Create(data),
|
||||
WrapperType.Textfile => null,// TODO: Implement wrapper
|
||||
@@ -158,10 +157,9 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region BDPlusSVM
|
||||
|
||||
if (magic.StartsWith([0x42, 0x44, 0x53, 0x56, 0x4D, 0x5F, 0x43, 0x43]))
|
||||
if (magic.StartsWith(Models.BDPlus.Constants.SignatureBytes))
|
||||
return WrapperType.BDPlusSVM;
|
||||
|
||||
if (extension.Equals("svm", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -191,10 +189,9 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region BZip2
|
||||
|
||||
if (magic.StartsWith([0x42, 0x52, 0x68]))
|
||||
if (magic.StartsWith(Models.BZip2.Constants.SignatureBytes))
|
||||
return WrapperType.BZip2;
|
||||
|
||||
if (extension.Equals("bz2", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -229,10 +226,9 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region CHD
|
||||
|
||||
if (magic.StartsWith([0x4D, 0x43, 0x6F, 0x6D, 0x70, 0x72, 0x48, 0x44]))
|
||||
if (magic.StartsWith(Models.CHD.Constants.SignatureBytes))
|
||||
return WrapperType.CHD;
|
||||
|
||||
#endregion
|
||||
@@ -315,10 +311,9 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region InstallShieldArchiveV3
|
||||
|
||||
if (magic.StartsWith([0x13, 0x5D, 0x65, 0x8C]))
|
||||
if (magic.StartsWith(Models.InstallShieldArchiveV3.Constants.HeaderSignatureBytes))
|
||||
return WrapperType.InstallShieldArchiveV3;
|
||||
|
||||
if (extension.Equals("z", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -335,10 +330,9 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region LDSCRYPT
|
||||
|
||||
if (magic.StartsWith([0x4C, 0x44, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54]))
|
||||
if (magic.StartsWith(Models.LDSCRYPT.Constants.SignatureBytes))
|
||||
return WrapperType.LDSCRYPT;
|
||||
|
||||
#endregion
|
||||
@@ -438,6 +432,10 @@ namespace SabreTools.Serialization.Wrappers
|
||||
// TODO: Use constants from Models here
|
||||
#region PFF
|
||||
|
||||
// Version 0
|
||||
if (magic.StartsWith([0x14, 0x00, 0x00, 0x00, 0x50, 0x46, 0x46, 0x30]))
|
||||
return WrapperType.PFF;
|
||||
|
||||
// Version 2
|
||||
if (magic.StartsWith([0x14, 0x00, 0x00, 0x00, 0x50, 0x46, 0x46, 0x32]))
|
||||
return WrapperType.PFF;
|
||||
@@ -588,15 +586,14 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region RAR
|
||||
|
||||
// RAR archive version 1.50 onwards
|
||||
if (magic.StartsWith([0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00]))
|
||||
if (magic.StartsWith(Models.RAR.Constants.OldSignatureBytes))
|
||||
return WrapperType.RAR;
|
||||
|
||||
// RAR archive version 5.0 onwards
|
||||
if (magic.StartsWith([0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00]))
|
||||
if (magic.StartsWith(Models.RAR.Constants.NewSignatureBytes))
|
||||
return WrapperType.RAR;
|
||||
|
||||
if (extension.Equals("rar", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -604,17 +601,16 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region RealArcade
|
||||
|
||||
// RASGI2.0
|
||||
// Found in the ".rgs files in IA item "Nova_RealArcadeCD_USA".
|
||||
if (magic.StartsWith([0x52, 0x41, 0x53, 0x47, 0x49, 0x32, 0x2E, 0x30]))
|
||||
if (magic.StartsWith(Models.RealArcades.Constants.RgsSignatureBytes))
|
||||
return WrapperType.RealArcadeInstaller;
|
||||
|
||||
// XZip2.0
|
||||
// Found in the ".mez" files in IA item "Nova_RealArcadeCD_USA".
|
||||
if (magic.StartsWith([0x58, 0x5A, 0x69, 0x70, 0x32, 0x2E, 0x30]))
|
||||
if (magic.StartsWith(Models.RealArcades.Constants.MezzanineSignatureBytes))
|
||||
return WrapperType.RealArcadeMezzanine;
|
||||
|
||||
#endregion
|
||||
@@ -626,10 +622,9 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region SevenZip
|
||||
|
||||
if (magic.StartsWith([0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c]))
|
||||
if (magic.StartsWith(Models.SevenZip.Constants.SignatureBytes))
|
||||
return WrapperType.SevenZip;
|
||||
|
||||
if (extension.Equals("7z", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -640,7 +635,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
#region SFFS
|
||||
|
||||
// Found in Redump entry 81756, confirmed to be "StarForce Filesystem" by PiD.
|
||||
if (magic.StartsWith(Models.SFFS.Constants.SignatureBytes))
|
||||
if (magic.StartsWith(Models.StarForce.Constants.SignatureBytes))
|
||||
return WrapperType.SFFS;
|
||||
|
||||
#endregion
|
||||
@@ -703,6 +698,14 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (magic.StartsWith([0x3C, 0x3F, 0x78, 0x6D, 0x6C]))
|
||||
return WrapperType.Textfile;
|
||||
|
||||
// "<?xml" in UTF-16 encoding
|
||||
if (magic.StartsWith([0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00]))
|
||||
return WrapperType.Textfile;
|
||||
|
||||
// "<?xml" in UTF-16 encoding with byte order marks
|
||||
if (magic.StartsWith([0xFF, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00]))
|
||||
return WrapperType.Textfile;
|
||||
|
||||
// "Description in Zip"
|
||||
if (extension.Equals("diz", StringComparison.OrdinalIgnoreCase))
|
||||
return WrapperType.Textfile;
|
||||
@@ -784,10 +787,9 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Use constants from Models here
|
||||
#region XZ
|
||||
|
||||
if (magic.StartsWith([0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00]))
|
||||
if (magic.StartsWith(Models.XZ.Constants.SignatureBytes))
|
||||
return WrapperType.XZ;
|
||||
|
||||
if (extension.Equals("xz", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -78,7 +78,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using FileStream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
|
||||
// Read the data block
|
||||
var data = ReadRangeFromSource(offset, compressedSize);
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data, 0, data.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
// Extract the file
|
||||
using FileStream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
bz2File.CopyTo(fs);
|
||||
fs.Flush();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using SabreTools.Models.BZip2;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
@@ -7,7 +8,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// any actual parsing. It is used as a placeholder for
|
||||
/// types that typically do not have models.
|
||||
/// </summary>
|
||||
public partial class BZip2 : WrapperBase
|
||||
public partial class BZip2 : WrapperBase<Archive>
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -19,22 +20,22 @@ namespace SabreTools.Serialization.Wrappers
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BZip2(byte[] data) : base(data) { }
|
||||
public BZip2(Archive model, byte[] data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BZip2(byte[] data, int offset) : base(data, offset) { }
|
||||
public BZip2(Archive model, byte[] data, int offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BZip2(byte[] data, int offset, int length) : base(data, offset, length) { }
|
||||
public BZip2(Archive model, byte[] data, int offset, int length) : base(model, data, offset, length) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BZip2(Stream data) : base(data) { }
|
||||
public BZip2(Archive model, Stream data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BZip2(Stream data, long offset) : base(data, offset) { }
|
||||
public BZip2(Archive model, Stream data, long offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public BZip2(Stream data, long offset, long length) : base(data, offset, length) { }
|
||||
public BZip2(Archive model, Stream data, long offset, long length) : base(model, data, offset, length) { }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
return new BZip2(data);
|
||||
return new BZip2(new Archive(), data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using FileStream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
|
||||
// Now read the data sequentially and write out while we have data left
|
||||
long fileSize = file.Size;
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = System.IO.File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data, 0, data.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (directoryName != null && !Directory.Exists(directoryName))
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
cabinet.FileSave(i, filename);
|
||||
cabinet.FileSave(i, filename, includeDebug);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -269,7 +269,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <summary>
|
||||
/// Save the file at the given index to the filename specified
|
||||
/// </summary>
|
||||
public bool FileSave(int index, string filename, bool useOld = false)
|
||||
public bool FileSave(int index, string filename, bool includeDebug, bool useOld = false)
|
||||
{
|
||||
// Get the file descriptor
|
||||
if (!TryGetFileDescriptor(index, out var fileDescriptor) || fileDescriptor == null)
|
||||
@@ -277,7 +277,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
// If the file is split
|
||||
if (fileDescriptor.LinkFlags == LinkFlags.LINK_PREV)
|
||||
return FileSave((int)fileDescriptor.LinkPrevious, filename, useOld);
|
||||
return FileSave((int)fileDescriptor.LinkPrevious, filename, includeDebug, useOld);
|
||||
|
||||
// Get the reader at the index
|
||||
var reader = Reader.Create(this, index, fileDescriptor);
|
||||
@@ -285,7 +285,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
return false;
|
||||
|
||||
// Create the output file and hasher
|
||||
FileStream output = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
var md5 = new HashWrapper(HashType.MD5);
|
||||
|
||||
long readBytesLeft = (long)GetReadableBytes(fileDescriptor);
|
||||
@@ -313,7 +313,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
Console.Error.WriteLine($"Failed to read {lengthArr.Length} bytes of file {index} ({GetFileName(index)}) from input cabinet file {fileDescriptor.Volume}");
|
||||
reader.Dispose();
|
||||
output?.Close();
|
||||
fs?.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
Console.Error.WriteLine($"Failed to read {lengthArr.Length} bytes of file {index} ({GetFileName(index)}) from input cabinet file {fileDescriptor.Volume}");
|
||||
reader.Dispose();
|
||||
output?.Close();
|
||||
fs?.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
Console.Error.WriteLine($"Decompression failed with code {result.ToZlibConstName()}. bytes_to_read={bytesToRead}, volume={fileDescriptor.Volume}, read_bytes={readBytes}");
|
||||
reader.Dispose();
|
||||
output?.Close();
|
||||
fs?.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
Console.Error.WriteLine($"Failed to write {bytesToWrite} bytes from input cabinet file {fileDescriptor.Volume}");
|
||||
reader.Dispose();
|
||||
output?.Close();
|
||||
fs?.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
// Hash and write the next block
|
||||
bytesToWrite = Math.Min(bytesToWrite, writeBytesLeft);
|
||||
md5.Process(outputBuffer, 0, (int)bytesToWrite);
|
||||
output?.Write(outputBuffer, 0, (int)bytesToWrite);
|
||||
fs?.Write(outputBuffer, 0, (int)bytesToWrite);
|
||||
|
||||
totalWritten += bytesToWrite;
|
||||
writeBytesLeft -= bytesToWrite;
|
||||
@@ -379,12 +379,12 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
// Validate the number of bytes written
|
||||
if ((long)fileDescriptor.ExpandedSize != totalWritten)
|
||||
Console.WriteLine($"Expanded size of file {index} ({GetFileName(index)}) expected to be {fileDescriptor.ExpandedSize}, but was {totalWritten}");
|
||||
if (includeDebug) Console.WriteLine($"Expanded size of file {index} ({GetFileName(index)}) expected to be {fileDescriptor.ExpandedSize}, but was {totalWritten}");
|
||||
|
||||
// Finalize output values
|
||||
md5.Terminate();
|
||||
reader?.Dispose();
|
||||
output?.Close();
|
||||
fs?.Close();
|
||||
|
||||
// Validate the data written, if required
|
||||
if (MajorVersion >= 6)
|
||||
@@ -422,7 +422,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
return false;
|
||||
|
||||
// Create the output file
|
||||
FileStream output = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
|
||||
ulong bytesLeft = GetReadableBytes(fileDescriptor);
|
||||
byte[] outputBuffer = new byte[BUFFER_SIZE];
|
||||
@@ -435,7 +435,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
Console.Error.WriteLine($"Failed to read {bytesToWrite} bytes from input cabinet file {fileDescriptor.Volume}");
|
||||
reader.Dispose();
|
||||
output?.Close();
|
||||
fs?.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -443,12 +443,12 @@ namespace SabreTools.Serialization.Wrappers
|
||||
bytesLeft -= (uint)bytesToWrite;
|
||||
|
||||
// Write the next block
|
||||
output.Write(outputBuffer, 0, (int)bytesToWrite);
|
||||
fs.Write(outputBuffer, 0, (int)bytesToWrite);
|
||||
}
|
||||
|
||||
// Finalize output values
|
||||
reader.Dispose();
|
||||
output?.Close();
|
||||
fs?.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Models.InstallShieldCabinet;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
|
||||
91
SabreTools.Serialization/Wrappers/LDSCRYPT.cs
Normal file
91
SabreTools.Serialization/Wrappers/LDSCRYPT.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System.IO;
|
||||
using SabreTools.Models.LDSCRYPT;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a shell wrapper; one that does not contain
|
||||
/// any actual parsing. It is used as a placeholder for
|
||||
/// types that typically do not have models.
|
||||
/// </summary>
|
||||
public class LDSCRYPT : WrapperBase<EncryptedFile>
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string DescriptionString => "Link Data Security encrypted file";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc/>
|
||||
public LDSCRYPT(EncryptedFile model, byte[] data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public LDSCRYPT(EncryptedFile model, byte[] data, int offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public LDSCRYPT(EncryptedFile model, byte[] data, int offset, int length) : base(model, data, offset, length) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public LDSCRYPT(EncryptedFile model, Stream data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public LDSCRYPT(EncryptedFile model, Stream data, long offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public LDSCRYPT(EncryptedFile model, Stream data, long offset, long length) : base(model, data, offset, length) { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Create a LDSCRYPT file from a byte array and offset
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array representing the archive</param>
|
||||
/// <param name="offset">Offset within the array to parse</param>
|
||||
/// <returns>A LDSCRYPT wrapper on success, null on failure</returns>
|
||||
public static LDSCRYPT? Create(byte[]? data, int offset)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || data.Length == 0)
|
||||
return null;
|
||||
|
||||
// If the offset is out of bounds
|
||||
if (offset < 0 || offset >= data.Length)
|
||||
return null;
|
||||
|
||||
// Create a memory stream and use that
|
||||
var dataStream = new MemoryStream(data, offset, data.Length - offset);
|
||||
return Create(dataStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a LDSCRYPT file from a Stream
|
||||
/// </summary>
|
||||
/// <param name="data">Stream representing the archive</param>
|
||||
/// <returns>A LDSCRYPT wrapper on success, null on failure</returns>
|
||||
public static LDSCRYPT? Create(Stream? data)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
return new LDSCRYPT(new EncryptedFile(), data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region JSON Export
|
||||
|
||||
#if NETCOREAPP
|
||||
/// <inheritdoc/>
|
||||
public override string ExportJSON() => throw new System.NotImplementedException();
|
||||
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
return false;
|
||||
|
||||
// Get the decompressor
|
||||
var decompressor = Decompressor.CreateKWAJ(contents, CompressionType);
|
||||
var decompressor = Decompressor.CreateKWAJ(contents, (ushort)CompressionType);
|
||||
if (decompressor == null)
|
||||
return false;
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
decompressor.CopyTo(fs);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
decompressor.CopyTo(fs);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
decompressor.CopyTo(fs);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -144,8 +144,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Display warning
|
||||
Console.WriteLine("WARNING: LZX and Quantum compression schemes are not supported so some files may be skipped!");
|
||||
// Display warning in debug runs
|
||||
if (includeDebug) Console.WriteLine("WARNING: LZX and Quantum compression schemes are not supported so some files may be skipped!");
|
||||
|
||||
// Open the full set if possible
|
||||
var cabinet = this;
|
||||
@@ -236,7 +236,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
// Open the output file for writing
|
||||
using var fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(fileData, 0, fileData.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
#if (NET452_OR_GREATER || NETCOREAPP) && (WINX86 || WINX64)
|
||||
using System.IO;
|
||||
using StormLibSharp;
|
||||
#endif
|
||||
|
||||
@@ -11,11 +12,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
#if NET20 || NET35 || !(WINX86 || WINX64)
|
||||
Console.WriteLine("Extraction is not supported for this framework!");
|
||||
Console.WriteLine();
|
||||
return false;
|
||||
#else
|
||||
#if (NET452_OR_GREATER || NETCOREAPP) && (WINX86 || WINX64)
|
||||
try
|
||||
{
|
||||
if (Filename == null || !File.Exists(Filename))
|
||||
@@ -42,7 +39,6 @@ namespace SabreTools.Serialization.Wrappers
|
||||
// Loop over each entry
|
||||
foreach (string sub in listfileLines)
|
||||
{
|
||||
// Ensure directory separators are consistent
|
||||
string filename = sub;
|
||||
if (Path.DirectorySeparatorChar == '\\')
|
||||
filename = filename.Replace('/', '\\');
|
||||
@@ -50,7 +46,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
filename = filename.Replace('\\', '/');
|
||||
|
||||
// Ensure the full output directory exists
|
||||
filename = Path.Combine(outDir, filename);
|
||||
filename = Path.Combine(outputDirectory, filename);
|
||||
var directoryName = Path.GetDirectoryName(filename);
|
||||
if (directoryName != null && !Directory.Exists(directoryName))
|
||||
Directory.CreateDirectory(directoryName);
|
||||
@@ -73,6 +69,10 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (includeDebug) System.Console.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
Console.WriteLine("Extraction is not supported for this framework!");
|
||||
Console.WriteLine();
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
@@ -42,7 +41,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
string extension = string.Empty;
|
||||
|
||||
// Only process the overlay if it is recognized
|
||||
for (; overlayOffset < 0x400 && overlayOffset < overlayData.Length; overlayOffset++)
|
||||
for (; overlayOffset < 0x400 && overlayOffset < overlayData.Length - 0x10; overlayOffset++)
|
||||
{
|
||||
int temp = overlayOffset;
|
||||
byte[] overlaySample = overlayData.ReadBytes(ref temp, 0x10);
|
||||
@@ -113,6 +112,21 @@ namespace SabreTools.Serialization.Wrappers
|
||||
extension = "uha";
|
||||
break;
|
||||
}
|
||||
else if (overlaySample.StartsWith([0x3C, 0x3F, 0x78, 0x6D, 0x6C]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (overlaySample.StartsWith([0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (overlaySample.StartsWith([0xFF, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (overlaySample.StartsWith([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00]))
|
||||
{
|
||||
extension = "xz";
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = System.IO.File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data, 0, data.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
Directory.CreateDirectory(directoryName);
|
||||
|
||||
// Create the output file
|
||||
using FileStream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
|
||||
// Read the data block
|
||||
var data = ReadRangeFromSource(offset, size);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.IO;
|
||||
using SabreTools.IO.Compression.zlib;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
@@ -174,6 +173,21 @@ namespace SabreTools.Serialization.Wrappers
|
||||
extension = "uha";
|
||||
break;
|
||||
}
|
||||
else if (overlaySample.StartsWith([0x3C, 0x3F, 0x78, 0x6D, 0x6C]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (overlaySample.StartsWith([0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (overlaySample.StartsWith([0xFF, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (overlaySample.StartsWith([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00]))
|
||||
{
|
||||
extension = "xz";
|
||||
@@ -329,6 +343,21 @@ namespace SabreTools.Serialization.Wrappers
|
||||
extension = "uha";
|
||||
break;
|
||||
}
|
||||
else if (resourceSample.StartsWith([0x3C, 0x3F, 0x78, 0x6D, 0x6C]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (resourceSample.StartsWith([0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (resourceSample.StartsWith([0xFF, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00]))
|
||||
{
|
||||
extension = "xml";
|
||||
break;
|
||||
}
|
||||
else if (resourceSample.StartsWith([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00]))
|
||||
{
|
||||
extension = "xz";
|
||||
@@ -375,7 +404,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Extract data from a SecuROM Matroschka Package
|
||||
/// </summary>
|
||||
|
||||
@@ -3,9 +3,10 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Models.COFF;
|
||||
using SabreTools.Models.PortableExecutable;
|
||||
using SabreTools.Models.PortableExecutable.ResourceEntries;
|
||||
using SabreTools.Models.PortableExecutable.Resource.Entries;
|
||||
using SabreTools.Serialization.Extensions;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
@@ -20,8 +21,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extension Properties
|
||||
|
||||
/// <inheritdoc cref="Executable.COFFFileHeader"/>
|
||||
public COFFFileHeader? COFFFileHeader => Model.COFFFileHeader;
|
||||
/// <inheritdoc cref="Executable.FileHeader"/>
|
||||
public FileHeader? COFFFileHeader => Model.FileHeader;
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of debug data
|
||||
@@ -47,8 +48,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="DebugTable.DebugDirectoryTable"/>
|
||||
public DebugDirectoryEntry[]? DebugDirectoryTable
|
||||
/// <inheritdoc cref="Models.PortableExecutable.DebugData.Table.Table"/>
|
||||
public Models.PortableExecutable.DebugData.Entry[]? DebugDirectoryTable
|
||||
=> Model.DebugTable?.DebugDirectoryTable;
|
||||
|
||||
/// <summary>
|
||||
@@ -101,8 +102,20 @@ namespace SabreTools.Serialization.Wrappers
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Executable.ExportTable"/>
|
||||
public ExportTable? ExportTable => Model.ExportTable;
|
||||
/// <inheritdoc cref="Executable.ExportAddressTable"/>
|
||||
public Models.PortableExecutable.Export.AddressTableEntry[]? ExportTable => Model.ExportAddressTable;
|
||||
|
||||
/// <inheritdoc cref="Executable.ExportDirectoryTable"/>
|
||||
public Models.PortableExecutable.Export.DirectoryTable? ExportDirectoryTable => Model.ExportDirectoryTable;
|
||||
|
||||
/// <inheritdoc cref="Executable.NamePointerTable"/>
|
||||
public Models.PortableExecutable.Export.NamePointerTable? ExportNamePointerTable => Model.NamePointerTable;
|
||||
|
||||
/// <inheritdoc cref="Executable.ExportNameTable"/>
|
||||
public Models.PortableExecutable.Export.NameTable? ExportNameTable => Model.ExportNameTable;
|
||||
|
||||
/// <inheritdoc cref="Executable.OrdinalTable"/>
|
||||
public Models.PortableExecutable.Export.OrdinalTable? ExportOrdinalTable => Model.OrdinalTable;
|
||||
|
||||
/// <summary>
|
||||
/// Header padding data, if it exists
|
||||
@@ -182,8 +195,17 @@ namespace SabreTools.Serialization.Wrappers
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Executable.ImportTable"/>
|
||||
public ImportTable? ImportTable => Model.ImportTable;
|
||||
/// <inheritdoc cref="Executable.ImportAddressTables"/>
|
||||
public Dictionary<int, Models.PortableExecutable.Import.AddressTableEntry[]?>? ImportAddressTables => Model.ImportAddressTables;
|
||||
|
||||
/// <inheritdoc cref="Executable.ImportDirectoryTable"/>
|
||||
public Models.PortableExecutable.Import.DirectoryTableEntry[]? ImportDirectoryTable => Model.ImportDirectoryTable;
|
||||
|
||||
/// <inheritdoc cref="Executable.HintNameTable"/>
|
||||
public Models.PortableExecutable.Import.HintNameTableEntry[]? ImportHintNameTable => Model.HintNameTable;
|
||||
|
||||
/// <inheritdoc cref="Executable.ImportLookupTables"/>
|
||||
public Dictionary<int, Models.PortableExecutable.Import.LookupTableEntry[]?>? ImportLookupTables => Model.ImportLookupTables;
|
||||
|
||||
/// <summary>
|
||||
/// SecuROM Matroschka package wrapper, if it exists
|
||||
@@ -264,7 +286,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Executable.OptionalHeader"/>
|
||||
public OptionalHeader? OptionalHeader => Model.OptionalHeader;
|
||||
public Models.PortableExecutable.OptionalHeader? OptionalHeader => Model.OptionalHeader;
|
||||
|
||||
/// <summary>
|
||||
/// Address of the overlay, if it exists
|
||||
@@ -420,7 +442,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Executable.ResourceDirectoryTable"/>
|
||||
public ResourceDirectoryTable? ResourceDirectoryTable => Model.ResourceDirectoryTable;
|
||||
public Models.PortableExecutable.Resource.DirectoryTable? ResourceDirectoryTable => Model.ResourceDirectoryTable;
|
||||
|
||||
/// <summary>
|
||||
/// Sanitized section names
|
||||
@@ -493,7 +515,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
// Get the offset from the end of the section table
|
||||
long endOfSectionTable = Stub.Header.NewExeHeaderAddr
|
||||
+ 24 // Signature size + COFF file header size
|
||||
+ 24 // Signature size + file header size
|
||||
+ COFFFileHeader.SizeOfOptionalHeader
|
||||
+ (COFFFileHeader.NumberOfSections * 40); // Size of a section header
|
||||
|
||||
@@ -1174,14 +1196,14 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (data == null)
|
||||
continue;
|
||||
|
||||
if (data is NB10ProgramDatabase n)
|
||||
if (data is Models.PortableExecutable.DebugData.NB10ProgramDatabase n)
|
||||
{
|
||||
if (n.PdbFileName == null || !n.PdbFileName.Contains(path))
|
||||
continue;
|
||||
|
||||
debugFound.Add(n);
|
||||
}
|
||||
else if (data is RSDSProgramDatabase r)
|
||||
else if (data is Models.PortableExecutable.DebugData.RSDSProgramDatabase r)
|
||||
{
|
||||
if (r.PathAndFileName == null || !r.PathAndFileName.Contains(path))
|
||||
continue;
|
||||
@@ -1635,7 +1657,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <summary>
|
||||
/// Parse the resource directory table information
|
||||
/// </summary>
|
||||
private void ParseResourceDirectoryTable(ResourceDirectoryTable table, List<object> types)
|
||||
private void ParseResourceDirectoryTable(Models.PortableExecutable.Resource.DirectoryTable table, List<object> types)
|
||||
{
|
||||
if (table?.Entries == null)
|
||||
return;
|
||||
@@ -1657,7 +1679,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <summary>
|
||||
/// Parse the name resource directory entry information
|
||||
/// </summary>
|
||||
private void ParseResourceDirectoryEntry(ResourceDirectoryEntry entry, List<object> types)
|
||||
private void ParseResourceDirectoryEntry(Models.PortableExecutable.Resource.DirectoryEntry entry, List<object> types)
|
||||
{
|
||||
if (entry.DataEntry != null)
|
||||
ParseResourceDataEntry(entry.DataEntry, types);
|
||||
@@ -1673,7 +1695,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// of those resources in the entire exectuable. This means that only the last found version or manifest will
|
||||
/// ever be cached.
|
||||
/// </remarks>
|
||||
private void ParseResourceDataEntry(ResourceDataEntry entry, List<object> types)
|
||||
private void ParseResourceDataEntry(Models.PortableExecutable.Resource.DataEntry entry, List<object> types)
|
||||
{
|
||||
// Create the key and value objects
|
||||
string key = types == null
|
||||
@@ -2029,22 +2051,19 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <returns>Section strings on success, null on error</returns>
|
||||
public List<string>? GetSectionStrings(int index)
|
||||
{
|
||||
// If we have no sections
|
||||
if (SectionNames.Length == 0 || SectionTable == null || SectionTable.Length == 0)
|
||||
return null;
|
||||
|
||||
// If the section doesn't exist
|
||||
if (index < 0 || index >= SectionTable.Length)
|
||||
return null;
|
||||
|
||||
lock (_sectionStringDataLock)
|
||||
{
|
||||
// If we have no sections
|
||||
if (SectionNames.Length == 0 || SectionTable == null || SectionTable.Length == 0)
|
||||
{
|
||||
_sectionStringData = [];
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create the section string array if we have to
|
||||
_sectionStringData ??= new List<string>?[SectionNames.Length];
|
||||
|
||||
// If the section doesn't exist
|
||||
if (index < 0 || index >= SectionTable.Length)
|
||||
return null;
|
||||
|
||||
// If we already have cached data, just use that immediately
|
||||
if (_sectionStringData[index] != null)
|
||||
return _sectionStringData[index];
|
||||
|
||||
@@ -100,10 +100,9 @@ namespace SabreTools.Serialization.Wrappers
|
||||
// try
|
||||
// {
|
||||
// // Open the output file for writing
|
||||
// using (Stream fs = File.OpenWrite(filename))
|
||||
// {
|
||||
// fs.Write(data, 0, data.Length);
|
||||
// }
|
||||
// using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
// fs.Write(data, 0, data.Length);
|
||||
// fs.Flush();
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using SabreTools.Models.RAR;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
@@ -7,7 +8,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// any actual parsing. It is used as a placeholder for
|
||||
/// types that typically do not have models.
|
||||
/// </summary>
|
||||
public partial class RAR : WrapperBase
|
||||
public partial class RAR : WrapperBase<Archive>
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -19,22 +20,22 @@ namespace SabreTools.Serialization.Wrappers
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RAR(byte[] data) : base(data) { }
|
||||
public RAR(Archive model, byte[] data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RAR(byte[] data, int offset) : base(data, offset) { }
|
||||
public RAR(Archive model, byte[] data, int offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RAR(byte[] data, int offset, int length) : base(data, offset, length) { }
|
||||
public RAR(Archive model, byte[] data, int offset, int length) : base(model, data, offset, length) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RAR(Stream data) : base(data) { }
|
||||
public RAR(Archive model, Stream data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RAR(Stream data, long offset) : base(data, offset) { }
|
||||
public RAR(Archive model, Stream data, long offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RAR(Stream data, long offset, long length) : base(data, offset, length) { }
|
||||
public RAR(Archive model, Stream data, long offset, long length) : base(model, data, offset, length) { }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
return new RAR(data);
|
||||
return new RAR(new Archive(), data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
90
SabreTools.Serialization/Wrappers/RealArcadeInstaller.cs
Normal file
90
SabreTools.Serialization/Wrappers/RealArcadeInstaller.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.IO;
|
||||
using SabreTools.Models.RealArcade;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a shell wrapper; one that does not contain
|
||||
/// any actual parsing. It is used as a placeholder for
|
||||
/// types that typically do not have models.
|
||||
/// </summary>
|
||||
public class RealArcadeInstaller : WrapperBase<RgsFile>
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string DescriptionString => "RealArcade Installer RGS File";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeInstaller(RgsFile model, byte[] data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeInstaller(RgsFile model, byte[] data, int offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeInstaller(RgsFile model, byte[] data, int offset, int length) : base(model, data, offset, length) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeInstaller(RgsFile model, Stream data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeInstaller(RgsFile model, Stream data, long offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeInstaller(RgsFile model, Stream data, long offset, long length) : base(model, data, offset, length) { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Create a RealArcade installer RGS file from a byte array and offset
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array representing the archive</param>
|
||||
/// <param name="offset">Offset within the array to parse</param>
|
||||
/// <returns>A RealArcade installer RGS file wrapper on success, null on failure</returns>
|
||||
public static RealArcadeInstaller? Create(byte[]? data, int offset)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || data.Length == 0)
|
||||
return null;
|
||||
|
||||
// If the offset is out of bounds
|
||||
if (offset < 0 || offset >= data.Length)
|
||||
return null;
|
||||
|
||||
// Create a memory stream and use that
|
||||
var dataStream = new MemoryStream(data, offset, data.Length - offset);
|
||||
return Create(dataStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a RealArcade installer RGS file from a Stream
|
||||
/// </summary>
|
||||
/// <param name="data">Stream representing the archive</param>
|
||||
/// <returns>A RealArcade installer RGS file wrapper on success, null on failure</returns>
|
||||
public static RealArcadeInstaller? Create(Stream? data)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
return new RealArcadeInstaller(new RgsFile(), data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region JSON Export
|
||||
|
||||
#if NETCOREAPP
|
||||
/// <inheritdoc/>
|
||||
public override string ExportJSON() => throw new System.NotImplementedException();
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
90
SabreTools.Serialization/Wrappers/RealArcadeMezzanine.cs
Normal file
90
SabreTools.Serialization/Wrappers/RealArcadeMezzanine.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.IO;
|
||||
using SabreTools.Models.RealArcade;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a shell wrapper; one that does not contain
|
||||
/// any actual parsing. It is used as a placeholder for
|
||||
/// types that typically do not have models.
|
||||
/// </summary>
|
||||
public class RealArcadeMezzanine : WrapperBase<Mezzanine>
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string DescriptionString => "RealArcade Mezzanine";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeMezzanine(Mezzanine model, byte[] data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeMezzanine(Mezzanine model, byte[] data, int offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeMezzanine(Mezzanine model, byte[] data, int offset, int length) : base(model, data, offset, length) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeMezzanine(Mezzanine model, Stream data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeMezzanine(Mezzanine model, Stream data, long offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RealArcadeMezzanine(Mezzanine model, Stream data, long offset, long length) : base(model, data, offset, length) { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Create a RealArcade mezzanine from a byte array and offset
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array representing the archive</param>
|
||||
/// <param name="offset">Offset within the array to parse</param>
|
||||
/// <returns>A RealArcade mezzanine wrapper on success, null on failure</returns>
|
||||
public static RealArcadeMezzanine? Create(byte[]? data, int offset)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || data.Length == 0)
|
||||
return null;
|
||||
|
||||
// If the offset is out of bounds
|
||||
if (offset < 0 || offset >= data.Length)
|
||||
return null;
|
||||
|
||||
// Create a memory stream and use that
|
||||
var dataStream = new MemoryStream(data, offset, data.Length - offset);
|
||||
return Create(dataStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a RealArcade mezzanine from a Stream
|
||||
/// </summary>
|
||||
/// <param name="data">Stream representing the archive</param>
|
||||
/// <returns>A RealArcade mezzanine wrapper on success, null on failure</returns>
|
||||
public static RealArcadeMezzanine? Create(Stream? data)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
return new RealArcadeMezzanine(new Mezzanine(), data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region JSON Export
|
||||
|
||||
#if NETCOREAPP
|
||||
/// <inheritdoc/>
|
||||
public override string ExportJSON() => throw new System.NotImplementedException();
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
91
SabreTools.Serialization/Wrappers/SFFS.cs
Normal file
91
SabreTools.Serialization/Wrappers/SFFS.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System.IO;
|
||||
using SabreTools.Models.StarForce;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a shell wrapper; one that does not contain
|
||||
/// any actual parsing. It is used as a placeholder for
|
||||
/// types that typically do not have models.
|
||||
/// </summary>
|
||||
/// TODO: Hook up the models to a proper deserializer
|
||||
public class SFFS : WrapperBase<FileSystem>
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string DescriptionString => "StarForce File System";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SFFS(FileSystem model, byte[] data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SFFS(FileSystem model, byte[] data, int offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SFFS(FileSystem model, byte[] data, int offset, int length) : base(model, data, offset, length) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SFFS(FileSystem model, Stream data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SFFS(FileSystem model, Stream data, long offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SFFS(FileSystem model, Stream data, long offset, long length) : base(model, data, offset, length) { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Create a SFFS file from a byte array and offset
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array representing the archive</param>
|
||||
/// <param name="offset">Offset within the array to parse</param>
|
||||
/// <returns>A SFFS wrapper on success, null on failure</returns>
|
||||
public static SFFS? Create(byte[]? data, int offset)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || data.Length == 0)
|
||||
return null;
|
||||
|
||||
// If the offset is out of bounds
|
||||
if (offset < 0 || offset >= data.Length)
|
||||
return null;
|
||||
|
||||
// Create a memory stream and use that
|
||||
var dataStream = new MemoryStream(data, offset, data.Length - offset);
|
||||
return Create(dataStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a SFFS file (or derived format) from a Stream
|
||||
/// </summary>
|
||||
/// <param name="data">Stream representing the archive</param>
|
||||
/// <returns>A SFFS wrapper on success, null on failure</returns>
|
||||
public static SFFS? Create(Stream? data)
|
||||
{
|
||||
// If the data is invalid
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
return new SFFS(new FileSystem(), data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region JSON Export
|
||||
|
||||
#if NETCOREAPP
|
||||
/// <inheritdoc/>
|
||||
public override string ExportJSON() => throw new System.NotImplementedException();
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = System.IO.File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data, 0, data.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
return false;
|
||||
|
||||
// Ensure directory separators are consistent
|
||||
string filename = Encoding.ASCII.GetString(entry.Path).TrimEnd('\0');
|
||||
string filename = entry.Path.TrimEnd('\0');
|
||||
if (Path.DirectorySeparatorChar == '\\')
|
||||
filename = filename.Replace('/', '\\');
|
||||
else if (Path.DirectorySeparatorChar == '/')
|
||||
@@ -72,7 +72,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data, 0, data.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
@@ -122,7 +122,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
// Do not return on a hash mismatch
|
||||
if (actualMd5 != expectedMd5)
|
||||
{
|
||||
string filename = Encoding.ASCII.GetString(entry.Path).TrimEnd('\0');
|
||||
string filename = entry.Path.TrimEnd('\0');
|
||||
if (includeDebug) Console.Error.WriteLine($"MD5 checksum failure for file {filename})");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ using SabreTools.Serialization.Interfaces;
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.SevenZip;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Readers;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using SabreTools.Models.SevenZip;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
@@ -7,7 +8,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// any actual parsing. It is used as a placeholder for
|
||||
/// types that typically do not have models.
|
||||
/// </summary>
|
||||
public partial class SevenZip : WrapperBase
|
||||
public partial class SevenZip : WrapperBase<Archive>
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -19,22 +20,22 @@ namespace SabreTools.Serialization.Wrappers
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SevenZip(byte[] data) : base(data) { }
|
||||
public SevenZip(Archive model, byte[] data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SevenZip(byte[] data, int offset) : base(data, offset) { }
|
||||
public SevenZip(Archive model, byte[] data, int offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SevenZip(byte[] data, int offset, int length) : base(data, offset, length) { }
|
||||
public SevenZip(Archive model, byte[] data, int offset, int length) : base(model, data, offset, length) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SevenZip(Stream data) : base(data) { }
|
||||
public SevenZip(Archive model, Stream data) : base(model, data) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SevenZip(Stream data, long offset) : base(data, offset) { }
|
||||
public SevenZip(Archive model, Stream data, long offset) : base(model, data, offset) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SevenZip(Stream data, long offset, long length) : base(data, offset, length) { }
|
||||
public SevenZip(Archive model, Stream data, long offset, long length) : base(model, data, offset, length) { }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (data == null || !data.CanRead)
|
||||
return null;
|
||||
|
||||
return new SevenZip(data);
|
||||
return new SevenZip(new Archive(), data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data, 0, data.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data, 0, data.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
try
|
||||
{
|
||||
// Open the output file for writing
|
||||
using Stream fs = File.OpenWrite(filename);
|
||||
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
fs.Write(data, 0, data.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user