diff --git a/SabreTools.FileTypes/Aaru/AaruFormat.cs b/SabreTools.FileTypes/Aaru/AaruFormat.cs index df33909f..2755a928 100644 --- a/SabreTools.FileTypes/Aaru/AaruFormat.cs +++ b/SabreTools.FileTypes/Aaru/AaruFormat.cs @@ -12,6 +12,30 @@ namespace SabreTools.FileTypes.Aaru /// public class AaruFormat : BaseFile { + #region Fields + + /// + /// Internal MD5 hash of the file + /// + public byte[]? InternalMD5 { get; set; } + + /// + /// Internal SHA-1 hash of the file + /// + public byte[]? InternalSHA1 { get; set; } + + /// + /// Internal SHA-256 hash of the file + /// + public byte[]? InternalSHA256 { get; set; } + + /// + /// Internal SpamSum fuzzy hash of the file + /// + public byte[]? InternalSpamSum { get; set; } + + #endregion + #region Private instance variables #region Header @@ -113,102 +137,100 @@ namespace SabreTools.FileTypes.Aaru { try { - AaruFormat aif = new(); + var aif = new AaruFormat(); -#if NET20 || NET35 || NET40 - using (BinaryReader br = new(stream, Encoding.Default)) -#else - using (BinaryReader br = new(stream, Encoding.Default, true)) -#endif + aif.Identifier = stream.ReadUInt64(); + byte[] applicationBytes = stream.ReadBytes(64); + aif.Application = Encoding.Unicode.GetString(applicationBytes); + aif.ImageMajorVersion = stream.ReadByteValue(); + aif.ImageMinorVersion = stream.ReadByteValue(); + aif.ApplicationMajorVersion = stream.ReadByteValue(); + aif.ApplicationMinorVersion = stream.ReadByteValue(); + aif.MediaType = (AaruMediaType)stream.ReadUInt32(); + aif.IndexOffset = stream.ReadUInt64(); + aif.CreationTime = stream.ReadInt64(); + aif.LastWrittenTime = stream.ReadInt64(); + + // If the offset is bigger than the stream, we can't read it + if (aif.IndexOffset > (ulong)stream.Length) + return null; + + // Otherwise, we read in the index header + stream.Seek((long)aif.IndexOffset, SeekOrigin.Begin); + aif.IndexHeader = IndexHeader.Deserialize(stream); + if (aif.IndexHeader.entries == 0) + return null; + + // Get the list of entries + aif.IndexEntries = new IndexEntry[aif.IndexHeader.entries]; + for (ushort index = 0; index < aif.IndexHeader.entries; index++) { - aif.Identifier = br.ReadUInt64(); - aif.Application = Encoding.Unicode.GetString(br.ReadBytes(64), 0, 64); - aif.ImageMajorVersion = br.ReadByte(); - aif.ImageMinorVersion = br.ReadByte(); - aif.ApplicationMajorVersion = br.ReadByte(); - aif.ApplicationMinorVersion = br.ReadByte(); - aif.MediaType = (AaruMediaType)br.ReadUInt32(); - aif.IndexOffset = br.ReadUInt64(); - aif.CreationTime = br.ReadInt64(); - aif.LastWrittenTime = br.ReadInt64(); - - // If the offset is bigger than the stream, we can't read it - if (aif.IndexOffset > (ulong)stream.Length) - return null; - - // Otherwise, we read in the index header - stream.Seek((long)aif.IndexOffset, SeekOrigin.Begin); - aif.IndexHeader = IndexHeader.Deserialize(stream); - if (aif.IndexHeader.entries == 0) - return null; - - // Get the list of entries - aif.IndexEntries = new IndexEntry[aif.IndexHeader.entries]; - for (ushort index = 0; index < aif.IndexHeader.entries; index++) + aif.IndexEntries[index] = IndexEntry.Deserialize(stream); + switch (aif.IndexEntries[index].blockType) { - aif.IndexEntries[index] = IndexEntry.Deserialize(stream); - switch (aif.IndexEntries[index].blockType) - { - // We don't do anything with these block types currently - case AaruBlockType.DataBlock: - case AaruBlockType.DeDuplicationTable: - case AaruBlockType.Index: - case AaruBlockType.Index2: - case AaruBlockType.GeometryBlock: - case AaruBlockType.MetadataBlock: - case AaruBlockType.TracksBlock: - case AaruBlockType.CicmBlock: - case AaruBlockType.DataPositionMeasurementBlock: - case AaruBlockType.SnapshotBlock: - case AaruBlockType.ParentBlock: - case AaruBlockType.DumpHardwareBlock: - case AaruBlockType.TapeFileBlock: - case AaruBlockType.TapePartitionBlock: - case AaruBlockType.CompactDiscIndexesBlock: - // No-op - break; + // We don't do anything with these block types currently + case AaruBlockType.DataBlock: + case AaruBlockType.DeDuplicationTable: + case AaruBlockType.Index: + case AaruBlockType.Index2: + case AaruBlockType.GeometryBlock: + case AaruBlockType.MetadataBlock: + case AaruBlockType.TracksBlock: + case AaruBlockType.CicmBlock: + case AaruBlockType.DataPositionMeasurementBlock: + case AaruBlockType.SnapshotBlock: + case AaruBlockType.ParentBlock: + case AaruBlockType.DumpHardwareBlock: + case AaruBlockType.TapeFileBlock: + case AaruBlockType.TapePartitionBlock: + case AaruBlockType.CompactDiscIndexesBlock: + // No-op + break; - // Read in all available hashes - case AaruBlockType.ChecksumBlock: - // If the offset is bigger than the stream, we can't read it - if (aif.IndexEntries[index].offset > (ulong)stream.Length) - return null; + // Read in all available hashes + case AaruBlockType.ChecksumBlock: + // If the offset is bigger than the stream, we can't read it + if (aif.IndexEntries[index].offset > (ulong)stream.Length) + return null; - // Otherwise, we read in the block - stream.Seek((long)aif.IndexEntries[index].offset, SeekOrigin.Begin); - ChecksumHeader checksumHeader = ChecksumHeader.Deserialize(stream); - if (checksumHeader.entries == 0) - return null; + // Otherwise, we read in the block + stream.Seek((long)aif.IndexEntries[index].offset, SeekOrigin.Begin); + ChecksumHeader checksumHeader = ChecksumHeader.Deserialize(stream); + if (checksumHeader.entries == 0) + return null; - // Read through each and pick out the ones we care about - for (byte entry = 0; entry < checksumHeader.entries; entry++) + // Read through each and pick out the ones we care about + for (byte entry = 0; entry < checksumHeader.entries; entry++) + { + ChecksumEntry? checksumEntry = ChecksumEntry.Deserialize(stream); + if (checksumEntry == null) + continue; + + switch (checksumEntry.type) { - ChecksumEntry? checksumEntry = ChecksumEntry.Deserialize(stream); - if (checksumEntry == null) - continue; - - switch (checksumEntry.type) - { - case AaruChecksumAlgorithm.Invalid: - break; - case AaruChecksumAlgorithm.Md5: - aif.MD5 = checksumEntry.checksum; - break; - case AaruChecksumAlgorithm.Sha1: - aif.SHA1 = checksumEntry.checksum; - break; - case AaruChecksumAlgorithm.Sha256: - aif.SHA256 = checksumEntry.checksum; - break; - case AaruChecksumAlgorithm.SpamSum: - aif.SpamSum = checksumEntry.checksum; - break; - } + case AaruChecksumAlgorithm.Invalid: + break; + case AaruChecksumAlgorithm.Md5: + aif.MD5 = checksumEntry.checksum; + aif.InternalMD5 = checksumEntry.checksum; + break; + case AaruChecksumAlgorithm.Sha1: + aif.SHA1 = checksumEntry.checksum; + aif.InternalSHA1 = checksumEntry.checksum; + break; + case AaruChecksumAlgorithm.Sha256: + aif.SHA256 = checksumEntry.checksum; + aif.InternalSHA256 = checksumEntry.checksum; + break; + case AaruChecksumAlgorithm.SpamSum: + aif.SpamSum = checksumEntry.checksum; + aif.InternalSpamSum = checksumEntry.checksum; + break; } + } - // Once we got hashes, we return early - return aif; - } + // Once we got hashes, we return early + return aif; } } diff --git a/SabreTools.FileTypes/Aaru/ChecksumEntry.cs b/SabreTools.FileTypes/Aaru/ChecksumEntry.cs index 314f0d8b..fb164915 100644 --- a/SabreTools.FileTypes/Aaru/ChecksumEntry.cs +++ b/SabreTools.FileTypes/Aaru/ChecksumEntry.cs @@ -1,5 +1,5 @@ using System.IO; -using System.Text; +using SabreTools.IO.Extensions; namespace SabreTools.FileTypes.Aaru { @@ -25,19 +25,12 @@ namespace SabreTools.FileTypes.Aaru { var checksumEntry = new ChecksumEntry(); -#if NET20 || NET35 || NET40 - using (var br = new BinaryReader(stream, Encoding.Default)) -#else - using (var br = new BinaryReader(stream, Encoding.Default, true)) -#endif - { - checksumEntry.type = (AaruChecksumAlgorithm)br.ReadByte(); - checksumEntry.length = br.ReadUInt32(); - if (checksumEntry.length == 0) - return null; + checksumEntry.type = (AaruChecksumAlgorithm)stream.ReadByteValue(); + checksumEntry.length = stream.ReadUInt32(); + if (checksumEntry.length == 0) + return null; - checksumEntry.checksum = br.ReadBytes((int)checksumEntry.length); - } + checksumEntry.checksum = stream.ReadBytes((int)checksumEntry.length); return checksumEntry; } diff --git a/SabreTools.FileTypes/Aaru/ChecksumHeader.cs b/SabreTools.FileTypes/Aaru/ChecksumHeader.cs index 103c3892..16c6489f 100644 --- a/SabreTools.FileTypes/Aaru/ChecksumHeader.cs +++ b/SabreTools.FileTypes/Aaru/ChecksumHeader.cs @@ -1,5 +1,5 @@ using System.IO; -using System.Text; +using SabreTools.IO.Extensions; namespace SabreTools.FileTypes.Aaru { @@ -24,18 +24,11 @@ namespace SabreTools.FileTypes.Aaru /// Populated ChecksumHeader, null on failure public static ChecksumHeader Deserialize(Stream stream) { - ChecksumHeader checksumHeader = new ChecksumHeader(); + var checksumHeader = new ChecksumHeader(); -#if NET20 || NET35 || NET40 - using (var br = new BinaryReader(stream, Encoding.Default)) -#else - using (var br = new BinaryReader(stream, Encoding.Default, true)) -#endif - { - checksumHeader.identifier = (AaruBlockType)br.ReadUInt32(); - checksumHeader.length = br.ReadUInt32(); - checksumHeader.entries = br.ReadByte(); - } + checksumHeader.identifier = (AaruBlockType)stream.ReadUInt32(); + checksumHeader.length = stream.ReadUInt32(); + checksumHeader.entries = stream.ReadByteValue(); return checksumHeader; } diff --git a/SabreTools.FileTypes/Aaru/IndexEntry.cs b/SabreTools.FileTypes/Aaru/IndexEntry.cs index 06cc97db..126e9b5b 100644 --- a/SabreTools.FileTypes/Aaru/IndexEntry.cs +++ b/SabreTools.FileTypes/Aaru/IndexEntry.cs @@ -1,5 +1,5 @@ using System.IO; -using System.Text; +using SabreTools.IO.Extensions; namespace SabreTools.FileTypes.Aaru { @@ -23,18 +23,11 @@ namespace SabreTools.FileTypes.Aaru /// Populated IndexHeader, null on failure public static IndexEntry Deserialize(Stream stream) { - IndexEntry indexEntry = new IndexEntry(); + var indexEntry = new IndexEntry(); -#if NET20 || NET35 || NET40 - using (var br = new BinaryReader(stream, Encoding.Default)) -#else - using (var br = new BinaryReader(stream, Encoding.Default, true)) -#endif - { - indexEntry.blockType = (AaruBlockType)br.ReadUInt32(); - indexEntry.dataType = (AaruDataType)br.ReadUInt16(); - indexEntry.offset = br.ReadUInt64(); - } + indexEntry.blockType = (AaruBlockType)stream.ReadUInt32(); + indexEntry.dataType = (AaruDataType)stream.ReadUInt16(); + indexEntry.offset = stream.ReadUInt64(); return indexEntry; } diff --git a/SabreTools.FileTypes/Aaru/IndexHeader.cs b/SabreTools.FileTypes/Aaru/IndexHeader.cs index 0aa0e76a..7363bd08 100644 --- a/SabreTools.FileTypes/Aaru/IndexHeader.cs +++ b/SabreTools.FileTypes/Aaru/IndexHeader.cs @@ -1,5 +1,5 @@ using System.IO; -using System.Text; +using SabreTools.IO.Extensions; namespace SabreTools.FileTypes.Aaru { @@ -25,16 +25,9 @@ namespace SabreTools.FileTypes.Aaru { var indexHeader = new IndexHeader(); -#if NET20 || NET35 || NET40 - using (var br = new BinaryReader(stream, Encoding.Default)) -#else - using (var br = new BinaryReader(stream, Encoding.Default, true)) -#endif - { - indexHeader.identifier = (AaruBlockType)br.ReadUInt32(); - indexHeader.entries = br.ReadUInt16(); - indexHeader.crc64 = br.ReadUInt64(); - } + indexHeader.identifier = (AaruBlockType)stream.ReadUInt32(); + indexHeader.entries = stream.ReadUInt16(); + indexHeader.crc64 = stream.ReadUInt64(); return indexHeader; } diff --git a/SabreTools.FileTypes/CHD/CHDFile.cs b/SabreTools.FileTypes/CHD/CHDFile.cs index 7ac17ce9..50edba7a 100644 --- a/SabreTools.FileTypes/CHD/CHDFile.cs +++ b/SabreTools.FileTypes/CHD/CHDFile.cs @@ -5,6 +5,20 @@ namespace SabreTools.FileTypes.CHD { public class CHDFile : BaseFile { + #region Fields + + /// + /// Internal MD5 hash of the file + /// + public byte[]? InternalMD5 { get; set; } + + /// + /// Internal SHA-1 hash of the file + /// + public byte[]? InternalSHA1 { get; set; } + + #endregion + #region Private instance variables /// @@ -37,11 +51,38 @@ namespace SabreTools.FileTypes.CHD var header = Serialization.Deserializers.CHD.DeserializeStream(stream); return header switch { - HeaderV1 v1 => new CHDFile { _header = header, MD5 = v1.MD5 }, - HeaderV2 v2 => new CHDFile { _header = header, MD5 = v2.MD5 }, - HeaderV3 v3 => new CHDFile { _header = header, MD5 = v3.MD5, SHA1 = v3.SHA1 }, - HeaderV4 v4 => new CHDFile { _header = header, SHA1 = v4.SHA1 }, - HeaderV5 v5 => new CHDFile { _header = header, SHA1 = v5.SHA1 }, + HeaderV1 v1 => new CHDFile + { + _header = header, + MD5 = v1.MD5, + InternalMD5 = v1.MD5, + }, + HeaderV2 v2 => new CHDFile + { + _header = header, + MD5 = v2.MD5, + InternalMD5 = v2.MD5, + }, + HeaderV3 v3 => new CHDFile + { + _header = header, + MD5 = v3.MD5, + InternalMD5 = v3.MD5, + SHA1 = v3.SHA1, + InternalSHA1 = v3.SHA1, + }, + HeaderV4 v4 => new CHDFile + { + _header = header, + SHA1 = v4.SHA1, + InternalSHA1 = v4.SHA1, + }, + HeaderV5 v5 => new CHDFile + { + _header = header, + SHA1 = v5.SHA1, + InternalSHA1 = v5.SHA1, + }, _ => null, }; }