diff --git a/Aaru.Images/A2R/A2R.cs b/Aaru.Images/A2R/A2R.cs index e936f3259..820ba41bc 100644 --- a/Aaru.Images/A2R/A2R.cs +++ b/Aaru.Images/A2R/A2R.cs @@ -45,25 +45,25 @@ namespace Aaru.DiscImages; /// Implements reading A2R flux images public sealed partial class A2R : IFluxImage, IMediaImage, IWritableImage, IWritableFluxImage { - ImageInfo _imageInfo; - Stream _a2rStream; - IFilter _a2rFilter; - FileStream _writingStream; - A2rHeader Header; - Dictionary Meta; - InfoChunkV2 _infoChunkV2; - InfoChunkV3 _infoChunkV3; - List _a2rCaptures; - uint _currentResolution; + const string MODULE_NAME = "A2R plugin"; + List _a2rCaptures; + IFilter _a2rFilter; + Stream _a2rStream; // Offset from the start of the current RWCP to the next capture uint _currentCaptureOffset = 16; + uint _currentResolution; // 53 = A2R header, INFO header, INFO data - long _currentRwcpStart = 53; + long _currentRwcpStart = 53; + ImageInfo _imageInfo; + InfoChunkV2 _infoChunkV2; + InfoChunkV3 _infoChunkV3; + FileStream _writingStream; + A2rHeader Header; + Dictionary Meta; - public A2R() - { + public A2R() => _imageInfo = new ImageInfo { ReadableSectorTags = new List(), @@ -87,7 +87,4 @@ public sealed partial class A2R : IFluxImage, IMediaImage, IWritableImage, IWrit DriveSerialNumber = null, DriveFirmwareRevision = null }; - } - - const string MODULE_NAME = "A2R plugin"; } \ No newline at end of file diff --git a/Aaru.Images/A2R/Constants.cs b/Aaru.Images/A2R/Constants.cs index 5b7da91db..ba174c019 100644 --- a/Aaru.Images/A2R/Constants.cs +++ b/Aaru.Images/A2R/Constants.cs @@ -49,6 +49,11 @@ public sealed partial class A2R 0x49, 0x4E, 0x46, 0x4F // INFO }; + readonly byte[] _metaChunkSignature = + { + 0x4D, 0x45, 0x54, 0x41 // META + }; + readonly byte[] _rwcpChunkSignature = { 0x52, 0x57, 0x43, 0x50 // RWCP @@ -59,11 +64,6 @@ public sealed partial class A2R 0x53, 0x4C, 0x56, 0x44 // SLVD }; - readonly byte[] _metaChunkSignature = - { - 0x4D, 0x45, 0x54, 0x41 // META - }; - readonly byte[] _strmChunkSignature = { 0x53, 0x54, 0x52, 0x4D // STRM diff --git a/Aaru.Images/A2R/Enums.cs b/Aaru.Images/A2R/Enums.cs index cfc85ac87..7b3e7e617 100644 --- a/Aaru.Images/A2R/Enums.cs +++ b/Aaru.Images/A2R/Enums.cs @@ -36,15 +36,28 @@ namespace Aaru.DiscImages; public sealed partial class A2R { - [SuppressMessage("ReSharper", "InconsistentNaming")] - public enum A2rDriveType : byte - { - SS_525_40trk_quarterStep = 0x1, DS_35_80trk_appleCLV = 0x2, DS_525_80trk = 0x3, - DS_525_40trk = 0x4, DS_35_80trk = 0x5, DS_8 = 0x6 - } +#region A2rDiskType enum public enum A2rDiskType : byte { - _525 = 0x01, _35 = 0x2, + _525 = 0x01, + _35 = 0x2 } + +#endregion + +#region A2rDriveType enum + + [SuppressMessage("ReSharper", "InconsistentNaming")] + public enum A2rDriveType : byte + { + SS_525_40trk_quarterStep = 0x1, + DS_35_80trk_appleCLV = 0x2, + DS_525_80trk = 0x3, + DS_525_40trk = 0x4, + DS_35_80trk = 0x5, + DS_8 = 0x6 + } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/A2R/Helpers.cs b/Aaru.Images/A2R/Helpers.cs index 786e8a4fc..5e6f7da9d 100644 --- a/Aaru.Images/A2R/Helpers.cs +++ b/Aaru.Images/A2R/Helpers.cs @@ -40,8 +40,8 @@ namespace Aaru.DiscImages; public sealed partial class A2R { /// - /// Takes a Head, Track and Sub-Track representation, as well as the MediaType, - /// and converts it to the Track representation used by A2R. + /// Takes a Head, Track and Sub-Track representation, as well as the MediaType, + /// and converts it to the Track representation used by A2R. /// /// The head number /// The track number @@ -51,14 +51,14 @@ public sealed partial class A2R static long HeadTrackSubToA2rLocation(uint head, ushort track, byte subTrack, MediaType mediaType) { if(mediaType == MediaType.Apple32SS) - return head + (track * 4) + subTrack; + return head + track * 4 + subTrack; - return head + (track * 2); + return head + track * 2; } /// - /// Takes a Head, Track and Sub-Track representation, as well as the A2rDriveType, - /// and converts it to the Track representation used by A2R. + /// Takes a Head, Track and Sub-Track representation, as well as the A2rDriveType, + /// and converts it to the Track representation used by A2R. /// /// The head number /// The track number @@ -68,22 +68,22 @@ public sealed partial class A2R static long HeadTrackSubToA2rLocation(uint head, ushort track, byte subTrack, A2rDriveType driveType) { if(driveType == A2rDriveType.SS_525_40trk_quarterStep) - return head + (track * 4) + subTrack; + return head + track * 4 + subTrack; - return head + (track * 2); + return head + track * 2; } /// - /// Takes an A2R location and a MediaType, and converts it to a Head, Track and Sub-Track representation - /// used by the internal representation. The MediaType is needed because the track location is different - /// for different types of media sources. + /// Takes an A2R location and a MediaType, and converts it to a Head, Track and Sub-Track representation + /// used by the internal representation. The MediaType is needed because the track location is different + /// for different types of media sources. /// /// A2R format location /// /// The head number /// The track number /// The sub-track number - static void A2rLocationToHeadTrackSub(uint location, MediaType mediaType, out uint head, out ushort track, + static void A2rLocationToHeadTrackSub(uint location, MediaType mediaType, out uint head, out ushort track, out byte subTrack) { if(mediaType == MediaType.Apple32SS) @@ -101,8 +101,8 @@ public sealed partial class A2R } /// - /// Takes a single number flux (uint length) and converts it to a flux in the - /// internal representation format (byte length) + /// Takes a single number flux (uint length) and converts it to a flux in the + /// internal representation format (byte length) /// /// The uint flux representation /// The byte[] flux representation @@ -111,12 +111,11 @@ public sealed partial class A2R uint over = ticks / 255; if(over == 0) - return new[] - { - (byte)ticks - }; + { + return new[] { (byte)ticks }; + } - byte[] expanded = new byte[over + 1]; + var expanded = new byte[over + 1]; Array.Fill(expanded, (byte)255, 0, (int)over); expanded[^1] = (byte)(ticks % 255); @@ -125,8 +124,8 @@ public sealed partial class A2R } /// - /// Takes a flux representation in the internal format (byte length) and converts it to - /// an array of single number fluxes (uint length) + /// Takes a flux representation in the internal format (byte length) and converts it to + /// an array of single number fluxes (uint length) /// /// The byte[] flux representation /// The uint flux representation @@ -151,9 +150,9 @@ public sealed partial class A2R } /// - /// A2R has two types of flux capture types; "timing" and "xtiming". The only difference is the length of the - /// capture, with "timing" being about 1¼ revolutions. This function returns true if the flux buffer is "timing" - /// and false otherwise. + /// A2R has two types of flux capture types; "timing" and "xtiming". The only difference is the length of the + /// capture, with "timing" being about 1¼ revolutions. This function returns true if the flux buffer is "timing" + /// and false otherwise. /// /// The resolution of the flux capture /// The flux data diff --git a/Aaru.Images/A2R/Identify.cs b/Aaru.Images/A2R/Identify.cs index f31d559ae..57f2501a3 100644 --- a/Aaru.Images/A2R/Identify.cs +++ b/Aaru.Images/A2R/Identify.cs @@ -39,6 +39,8 @@ namespace Aaru.DiscImages; public sealed partial class A2R { +#region IFluxImage Members + /// public bool Identify(IFilter imageFilter) { @@ -48,10 +50,12 @@ public sealed partial class A2R if(stream.Length < 8) return false; - byte[] hdr = new byte[4]; + var hdr = new byte[4]; stream.EnsureRead(hdr, 0, 4); return _a2rV2Signature.SequenceEqual(hdr) || _a2rV3Signature.SequenceEqual(hdr); } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/A2R/Properties.cs b/Aaru.Images/A2R/Properties.cs index 0ade183b7..ec36a8ad6 100644 --- a/Aaru.Images/A2R/Properties.cs +++ b/Aaru.Images/A2R/Properties.cs @@ -41,44 +41,61 @@ namespace Aaru.DiscImages; public sealed partial class A2R { + bool IsWritingRwcps { get; set; } + +#region IFluxImage Members + /// public ImageInfo Info => _imageInfo; + /// public string Name => Localization.A2R_Name; + /// public Guid Id => new("7497c26a-fe44-4b50-a2e6-de50a9f3c13f"); + /// public string Author => Authors.RebeccaWallander; + /// public string Format => "A2R"; + /// public List DumpHardware => null; + /// public Metadata AaruMetadata => null; + +#endregion + +#region IWritableImage Members + /// - public IEnumerable KnownExtensions => new[] - { - ".a2r" - }; + public IEnumerable KnownExtensions => new[] { ".a2r" }; + /// public IEnumerable SupportedMediaTags => null; + /// public IEnumerable SupportedMediaTypes => new[] { // TODO: A2R supports a lot more formats, please add more whence tested. MediaType.DOS_35_DS_DD_9, MediaType.DOS_35_HD, MediaType.DOS_525_DS_DD_9, MediaType.DOS_525_HD, - MediaType.Apple32SS, - MediaType.Unknown + MediaType.Apple32SS, MediaType.Unknown }; + /// public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions => Array.Empty<(string name, Type type, string description, object @default)>(); + /// public IEnumerable SupportedSectorTags => Array.Empty(); + /// public bool IsWriting { get; private set; } + /// public string ErrorMessage { get; private set; } - - bool IsWritingRwcps { get; set; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/A2R/Read.cs b/Aaru.Images/A2R/Read.cs index c8956bac0..e7de15c4b 100644 --- a/Aaru.Images/A2R/Read.cs +++ b/Aaru.Images/A2R/Read.cs @@ -45,6 +45,8 @@ namespace Aaru.DiscImages; public sealed partial class A2R { +#region IFluxImage Members + /// public ErrorNumber Open(IFilter imageFilter) { @@ -53,7 +55,7 @@ public sealed partial class A2R _a2rFilter = imageFilter; - byte[] hdr = new byte[Marshal.SizeOf()]; + var hdr = new byte[Marshal.SizeOf()]; _a2rStream.EnsureRead(hdr, 0, Marshal.SizeOf()); Header = Marshal.ByteArrayToStructureLittleEndian(hdr); @@ -61,13 +63,13 @@ public sealed partial class A2R AaruConsole.DebugWriteLine(MODULE_NAME, "header.signature = \"{0}\"", StringHandlers.CToString(Header.signature)); - AaruConsole.DebugWriteLine(MODULE_NAME, "header.version = {0}", Header.version); + AaruConsole.DebugWriteLine(MODULE_NAME, "header.version = {0}", Header.version); AaruConsole.DebugWriteLine(MODULE_NAME, "header.highBitTest = {0:X2}", Header.highBitTest); AaruConsole.DebugWriteLine(MODULE_NAME, "header.lineTest = {0:X2} {1:X2} {2:X2}", Header.lineTest[0], Header.lineTest[1], Header.lineTest[2]); - byte[] infoMagic = new byte[4]; + var infoMagic = new byte[4]; _a2rStream.EnsureRead(infoMagic, 0, 4); // There must be an INFO chunk after the header (at byte 16) @@ -80,7 +82,7 @@ public sealed partial class A2R { case 0x32: { - byte[] infoChnk = new byte[Marshal.SizeOf()]; + var infoChnk = new byte[Marshal.SizeOf()]; _a2rStream.EnsureRead(infoChnk, 0, Marshal.SizeOf()); _infoChunkV2 = Marshal.ByteArrayToStructureLittleEndian(infoChnk); @@ -118,14 +120,15 @@ public sealed partial class A2R _imageInfo.MediaType = MediaType.Apple32SS; break; - default: return ErrorNumber.OutOfRange; + default: + return ErrorNumber.OutOfRange; } break; } case 0x33: { - byte[] infoChk = new byte[Marshal.SizeOf()]; + var infoChk = new byte[Marshal.SizeOf()]; _a2rStream.EnsureRead(infoChk, 0, Marshal.SizeOf()); _infoChunkV3 = Marshal.ByteArrayToStructureLittleEndian(infoChk); @@ -191,7 +194,8 @@ public sealed partial class A2R _imageInfo.Cylinders = 40; break; - default: return ErrorNumber.OutOfRange; + default: + return ErrorNumber.OutOfRange; } break; @@ -202,7 +206,7 @@ public sealed partial class A2R while(_a2rStream.Position < _a2rStream.Length) { - byte[] chunkHdr = new byte[Marshal.SizeOf()]; + var chunkHdr = new byte[Marshal.SizeOf()]; _a2rStream.EnsureRead(chunkHdr, 0, Marshal.SizeOf()); ChunkHeader chunkHeader = Marshal.ByteArrayToStructureLittleEndian(chunkHdr); _a2rStream.Seek(-Marshal.SizeOf(), SeekOrigin.Current); @@ -210,7 +214,7 @@ public sealed partial class A2R switch(chunkHeader.chunkId) { case var rwcp when rwcp.SequenceEqual(_rwcpChunkSignature): - byte[] rwcpBuffer = new byte[Marshal.SizeOf()]; + var rwcpBuffer = new byte[Marshal.SizeOf()]; _a2rStream.EnsureRead(rwcpBuffer, 0, Marshal.SizeOf()); RwcpChunkHeader rwcpChunk = Marshal.ByteArrayToStructureLittleEndian(rwcpBuffer); @@ -222,11 +226,11 @@ public sealed partial class A2R captureType = (byte)_a2rStream.ReadByte() }; - byte[] location = new byte[2]; + var location = new byte[2]; _a2rStream.EnsureRead(location, 0, 2); capture.location = BitConverter.ToUInt16(location); - A2rLocationToHeadTrackSub(capture.location, _imageInfo.MediaType, out capture.head, + A2rLocationToHeadTrackSub(capture.location, _imageInfo.MediaType, out capture.head, out capture.track, out capture.subTrack); if(capture.head + 1 > _imageInfo.Heads) @@ -238,14 +242,14 @@ public sealed partial class A2R capture.numberOfIndexSignals = (byte)_a2rStream.ReadByte(); capture.indexSignals = new uint[capture.numberOfIndexSignals]; - for(int i = 0; capture.numberOfIndexSignals > i; i++) + for(var i = 0; capture.numberOfIndexSignals > i; i++) { - byte[] index = new byte[4]; + var index = new byte[4]; _a2rStream.EnsureRead(index, 0, 4); capture.indexSignals[i] = BitConverter.ToUInt32(index); } - byte[] dataSize = new byte[4]; + var dataSize = new byte[4]; _a2rStream.EnsureRead(dataSize, 0, 4); capture.captureDataSize = BitConverter.ToUInt32(dataSize); @@ -264,7 +268,7 @@ public sealed partial class A2R _a2rStream.Seek(Marshal.SizeOf(), SeekOrigin.Current); - byte[] metadataBuffer = new byte[chunkHeader.chunkSize]; + var metadataBuffer = new byte[chunkHeader.chunkSize]; _a2rStream.EnsureRead(metadataBuffer, 0, (int)chunkHeader.chunkSize); string metaData = Encoding.UTF8.GetString(metadataBuffer); @@ -286,9 +290,10 @@ public sealed partial class A2R _imageInfo.MediaTitle = title; break; - case var slvd when slvd.SequenceEqual(_slvdChunkSignature): return ErrorNumber.NotImplemented; + case var slvd when slvd.SequenceEqual(_slvdChunkSignature): + return ErrorNumber.NotImplemented; case var strm when strm.SequenceEqual(_strmChunkSignature): - byte[] strmBuffer = new byte[Marshal.SizeOf()]; + var strmBuffer = new byte[Marshal.SizeOf()]; _a2rStream.EnsureRead(strmBuffer, 0, Marshal.SizeOf()); ChunkHeader strmChunk = Marshal.ByteArrayToStructureLittleEndian(strmBuffer); @@ -305,7 +310,7 @@ public sealed partial class A2R numberOfIndexSignals = 1 }; - A2rLocationToHeadTrackSub(capture.location, _imageInfo.MediaType, out capture.head, + A2rLocationToHeadTrackSub(capture.location, _imageInfo.MediaType, out capture.head, out capture.track, out capture.subTrack); if(capture.head + 1 > _imageInfo.Heads) @@ -314,11 +319,11 @@ public sealed partial class A2R if(capture.track + 1 > _imageInfo.Cylinders) _imageInfo.Cylinders = (uint)(capture.track + 1); - byte[] dataSize = new byte[4]; + var dataSize = new byte[4]; _a2rStream.EnsureRead(dataSize, 0, 4); capture.captureDataSize = BitConverter.ToUInt32(dataSize); - byte[] index = new byte[4]; + var index = new byte[4]; _a2rStream.EnsureRead(index, 0, 4); capture.indexSignals[0] = BitConverter.ToUInt32(index); @@ -349,7 +354,7 @@ public sealed partial class A2R } /// - public ErrorNumber ReadFluxIndexResolution(uint head, ushort track, byte subTrack, uint captureIndex, + public ErrorNumber ReadFluxIndexResolution(uint head, ushort track, byte subTrack, uint captureIndex, out ulong resolution) { resolution = StreamCaptureAtIndex(head, track, subTrack, captureIndex).resolution; @@ -358,7 +363,7 @@ public sealed partial class A2R } /// - public ErrorNumber ReadFluxDataResolution(uint head, ushort track, byte subTrack, uint captureIndex, + public ErrorNumber ReadFluxDataResolution(uint head, ushort track, byte subTrack, uint captureIndex, out ulong resolution) { resolution = StreamCaptureAtIndex(head, track, subTrack, captureIndex).resolution; @@ -367,7 +372,7 @@ public sealed partial class A2R } /// - public ErrorNumber ReadFluxResolution(uint head, ushort track, byte subTrack, uint captureIndex, + public ErrorNumber ReadFluxResolution(uint head, ushort track, byte subTrack, uint captureIndex, out ulong indexResolution, out ulong dataResolution) { indexResolution = dataResolution = StreamCaptureAtIndex(head, track, subTrack, captureIndex).resolution; @@ -376,8 +381,8 @@ public sealed partial class A2R } /// - public ErrorNumber ReadFluxCapture(uint head, ushort track, byte subTrack, uint captureIndex, - out ulong indexResolution, out ulong dataResolution, out byte[] indexBuffer, + public ErrorNumber ReadFluxCapture(uint head, ushort track, byte subTrack, uint captureIndex, + out ulong indexResolution, out ulong dataResolution, out byte[] indexBuffer, out byte[] dataBuffer) { dataBuffer = indexBuffer = null; @@ -399,7 +404,7 @@ public sealed partial class A2R } /// - public ErrorNumber ReadFluxIndexCapture(uint head, ushort track, byte subTrack, uint captureIndex, + public ErrorNumber ReadFluxIndexCapture(uint head, ushort track, byte subTrack, uint captureIndex, out byte[] buffer) { buffer = null; @@ -414,7 +419,7 @@ public sealed partial class A2R uint previousTicks = 0; - for(int i = 0; i < capture.numberOfIndexSignals; i++) + for(var i = 0; i < capture.numberOfIndexSignals; i++) { uint ticks = capture.indexSignals[i] - previousTicks; tmpBuffer.AddRange(UInt32ToFluxRepresentation(ticks)); @@ -461,6 +466,10 @@ public sealed partial class A2R return ErrorNumber.NoError; } +#endregion + +#region IMediaImage Members + /// public ErrorNumber ReadMediaTag(MediaTagType tag, out byte[] buffer) => throw new NotImplementedException(); @@ -486,6 +495,8 @@ public sealed partial class A2R public ErrorNumber ReadSectorTag(ulong sectorAddress, SectorTagType tag, out byte[] buffer) => throw new NotImplementedException(); +#endregion + StreamCapture StreamCaptureAtIndex(uint head, ushort track, byte subTrack, uint captureIndex) { long index = HeadTrackSubToA2rLocation(head, track, subTrack, _imageInfo.MediaType); diff --git a/Aaru.Images/A2R/Structs.cs b/Aaru.Images/A2R/Structs.cs index d8eb8f81c..fcb53c60b 100644 --- a/Aaru.Images/A2R/Structs.cs +++ b/Aaru.Images/A2R/Structs.cs @@ -36,6 +36,8 @@ namespace Aaru.DiscImages; public sealed partial class A2R { +#region Nested type: A2rHeader + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct A2rHeader { @@ -47,6 +49,10 @@ public sealed partial class A2R public byte[] lineTest; // Should always be 0x0A 0x0D 0x0A } +#endregion + +#region Nested type: ChunkHeader + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ChunkHeader { @@ -55,6 +61,10 @@ public sealed partial class A2R public uint chunkSize; } +#endregion + +#region Nested type: InfoChunkV2 + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct InfoChunkV2 { @@ -67,6 +77,10 @@ public sealed partial class A2R public byte synchronized; } +#endregion + +#region Nested type: InfoChunkV3 + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct InfoChunkV3 { @@ -80,6 +94,10 @@ public sealed partial class A2R public byte hardSectorCount; } +#endregion + +#region Nested type: RwcpChunkHeader + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct RwcpChunkHeader { @@ -90,6 +108,24 @@ public sealed partial class A2R public byte[] reserved; } +#endregion + +#region Nested type: SlvdChunkHeader + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct SlvdChunkHeader + { + public ChunkHeader header; + public byte version; + public uint resolution; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] + public byte[] reserved; + } + +#endregion + +#region Nested type: StreamCapture + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct StreamCapture { @@ -106,15 +142,9 @@ public sealed partial class A2R public byte subTrack; } - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct SlvdChunkHeader - { - public ChunkHeader header; - public byte version; - public uint resolution; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] - public byte[] reserved; - } +#endregion + +#region Nested type: TrackHeader [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct TrackHeader @@ -129,4 +159,6 @@ public sealed partial class A2R public uint[] indexSignals; public uint fluxDataSize; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/A2R/Write.cs b/Aaru.Images/A2R/Write.cs index fdcdeff78..32ee5c6eb 100644 --- a/Aaru.Images/A2R/Write.cs +++ b/Aaru.Images/A2R/Write.cs @@ -45,9 +45,88 @@ namespace Aaru.DiscImages; public sealed partial class A2R { +#region IWritableFluxImage Members + + /// + public ErrorNumber WriteFluxCapture(ulong indexResolution, ulong dataResolution, byte[] indexBuffer, + byte[] dataBuffer, uint head, ushort track, byte subTrack, uint captureIndex) + { + if(!IsWriting) + { + ErrorMessage = Localization.Tried_to_write_on_a_non_writable_image; + + return ErrorNumber.WriteError; + } + + // An RWCP chunk can only have one capture resolution. If the resolution changes we need to create a new chunk. + if(_currentResolution != dataResolution) + { + if(IsWritingRwcps) + { + CloseRwcpChunk(); + + _writingStream.Seek(_currentRwcpStart, SeekOrigin.Begin); + WriteRwcpHeader(); + + _currentRwcpStart = _writingStream.Length; + _currentCaptureOffset = 16; + } + + IsWritingRwcps = true; + + _currentResolution = (uint)dataResolution; + } + + _writingStream.Seek(_currentRwcpStart + _currentCaptureOffset + Marshal.SizeOf(), + SeekOrigin.Begin); + + _writingStream.WriteByte(0x43); + + _writingStream.WriteByte(IsCaptureTypeTiming(dataResolution, dataBuffer) ? (byte)1 : (byte)3); + + _writingStream. + Write( + BitConverter.GetBytes((ushort)HeadTrackSubToA2rLocation(head, track, subTrack, _infoChunkV3.driveType)), + 0, 2); + + List a2rIndices = FluxRepresentationsToUInt32List(indexBuffer); + + if(a2rIndices[0] == 0) + a2rIndices.RemoveAt(0); + + _writingStream.WriteByte((byte)a2rIndices.Count); + + long previousIndex = 0; + + foreach(uint index in a2rIndices) + { + _writingStream.Write(BitConverter.GetBytes(index + previousIndex), 0, 4); + previousIndex += index; + } + + _writingStream.Write(BitConverter.GetBytes(dataBuffer.Length), 0, 4); + _writingStream.Write(dataBuffer, 0, dataBuffer.Length); + + _currentCaptureOffset += (uint)(9 + a2rIndices.Count * 4 + dataBuffer.Length); + + return ErrorNumber.NoError; + } + + /// + public ErrorNumber WriteFluxIndexCapture(ulong resolution, byte[] index, uint head, ushort track, byte subTrack, + uint captureIndex) => ErrorNumber.NoError; + + /// + public ErrorNumber WriteFluxDataCapture(ulong resolution, byte[] data, uint head, ushort track, byte subTrack, + uint captureIndex) => ErrorNumber.NoError; + +#endregion + +#region IWritableImage Members + /// public bool Create(string path, MediaType mediaType, Dictionary options, ulong sectors, - uint sectorSize) + uint sectorSize) { try { @@ -69,12 +148,12 @@ public sealed partial class A2R Header.lineTest = "\n\r\n"u8.ToArray(); _infoChunkV3.driveType = mediaType switch - { - MediaType.DOS_525_DS_DD_9 => A2rDriveType.DS_525_40trk, - MediaType.Apple32SS => A2rDriveType.SS_525_40trk_quarterStep, - MediaType.Unknown => A2rDriveType.DS_35_80trk, - _ => _infoChunkV3.driveType - }; + { + MediaType.DOS_525_DS_DD_9 => A2rDriveType.DS_525_40trk, + MediaType.Apple32SS => A2rDriveType.SS_525_40trk_quarterStep, + MediaType.Unknown => A2rDriveType.DS_35_80trk, + _ => _infoChunkV3.driveType + }; return true; } @@ -134,7 +213,7 @@ public sealed partial class A2R _infoChunkV3.hardSectorCount = 0; Meta.Add("image_date", DateTime.Now.ToString("O")); - Meta.Add("title", imageInfo.MediaTitle); + Meta.Add("title", imageInfo.MediaTitle); return true; } @@ -169,80 +248,10 @@ public sealed partial class A2R /// public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length) => throw new NotImplementedException(); - /// - public ErrorNumber WriteFluxCapture(ulong indexResolution, ulong dataResolution, byte[] indexBuffer, - byte[] dataBuffer, uint head, ushort track, byte subTrack, uint captureIndex) - { - if(!IsWriting) - { - ErrorMessage = Localization.Tried_to_write_on_a_non_writable_image; - - return ErrorNumber.WriteError; - } - - // An RWCP chunk can only have one capture resolution. If the resolution changes we need to create a new chunk. - if(_currentResolution != dataResolution) - { - if(IsWritingRwcps) - { - CloseRwcpChunk(); - - _writingStream.Seek(_currentRwcpStart, SeekOrigin.Begin); - WriteRwcpHeader(); - - _currentRwcpStart = _writingStream.Length; - _currentCaptureOffset = 16; - } - - IsWritingRwcps = true; - - _currentResolution = (uint)dataResolution; - } - - _writingStream.Seek(_currentRwcpStart + _currentCaptureOffset + Marshal.SizeOf(), - SeekOrigin.Begin); - - _writingStream.WriteByte(0x43); - - _writingStream.WriteByte(IsCaptureTypeTiming(dataResolution, dataBuffer) ? (byte)1 : (byte)3); - - _writingStream. - Write(BitConverter.GetBytes((ushort)HeadTrackSubToA2rLocation(head, track, subTrack, _infoChunkV3.driveType)), - 0, 2); - - List a2rIndices = FluxRepresentationsToUInt32List(indexBuffer); - - if(a2rIndices[0] == 0) - a2rIndices.RemoveAt(0); - - _writingStream.WriteByte((byte)a2rIndices.Count); - - long previousIndex = 0; - - foreach(uint index in a2rIndices) - { - _writingStream.Write(BitConverter.GetBytes(index + previousIndex), 0, 4); - previousIndex += index; - } - - _writingStream.Write(BitConverter.GetBytes(dataBuffer.Length), 0, 4); - _writingStream.Write(dataBuffer, 0, dataBuffer.Length); - - _currentCaptureOffset += (uint)(9 + (a2rIndices.Count * 4) + dataBuffer.Length); - - return ErrorNumber.NoError; - } - - /// - public ErrorNumber WriteFluxIndexCapture(ulong resolution, byte[] index, uint head, ushort track, byte subTrack, - uint captureIndex) => ErrorNumber.NoError; - - /// - public ErrorNumber WriteFluxDataCapture(ulong resolution, byte[] data, uint head, ushort track, byte subTrack, - uint captureIndex) => ErrorNumber.NoError; +#endregion /// - /// writes the header to an RWCP chunk, up to and including the reserved bytes, to stream. + /// writes the header to an RWCP chunk, up to and including the reserved bytes, to stream. /// /// ErrorNumber WriteRwcpHeader() @@ -254,15 +263,12 @@ public sealed partial class A2R return ErrorNumber.WriteError; } - _writingStream.Write(_rwcpChunkSignature, 0, 4); + _writingStream.Write(_rwcpChunkSignature, 0, 4); _writingStream.Write(BitConverter.GetBytes(_currentCaptureOffset + 1), 0, 4); _writingStream.WriteByte(1); _writingStream.Write(BitConverter.GetBytes(_currentResolution), 0, 4); - byte[] reserved = - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; + byte[] reserved = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; _writingStream.Write(reserved, 0, 11); @@ -270,7 +276,7 @@ public sealed partial class A2R } /// - /// Writes the entire INFO chunk to stream. + /// Writes the entire INFO chunk to stream. /// /// ErrorNumber WriteInfoChunk() @@ -282,7 +288,7 @@ public sealed partial class A2R return ErrorNumber.WriteError; } - _writingStream.Write(_infoChunkV3.header.chunkId, 0, 4); + _writingStream.Write(_infoChunkV3.header.chunkId, 0, 4); _writingStream.Write(BitConverter.GetBytes(_infoChunkV3.header.chunkSize), 0, 4); _writingStream.WriteByte(_infoChunkV3.version); _writingStream.Write(_infoChunkV3.creator, 0, 32); @@ -295,7 +301,7 @@ public sealed partial class A2R } /// - /// Writes the entire META chunk to stream. + /// Writes the entire META chunk to stream. /// /// ErrorNumber WriteMetaChunk() @@ -313,13 +319,13 @@ public sealed partial class A2R Aggregate(static (concat, str) => $"{concat}\n{str}") + '\n'); _writingStream.Write(BitConverter.GetBytes((uint)metaString.Length), 0, 4); - _writingStream.Write(metaString, 0, metaString.Length); + _writingStream.Write(metaString, 0, metaString.Length); return ErrorNumber.NoError; } /// - /// Writes the closing byte to an RWCP chunk signaling its end, to stream. + /// Writes the closing byte to an RWCP chunk signaling its end, to stream. /// /// ErrorNumber CloseRwcpChunk() diff --git a/Aaru.Images/Aaru.Images.csproj b/Aaru.Images/Aaru.Images.csproj index ea2c1daf1..7e71dc21b 100644 --- a/Aaru.Images/Aaru.Images.csproj +++ b/Aaru.Images/Aaru.Images.csproj @@ -35,8 +35,8 @@ CS1591;CS1574 - - + + $(Version)+{chash:8} @@ -44,25 +44,25 @@ true - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + + @@ -74,6 +74,6 @@ - + diff --git a/Aaru.Images/Aaru.Images.csproj.DotSettings b/Aaru.Images/Aaru.Images.csproj.DotSettings index 4db06027b..e639e22d9 100644 --- a/Aaru.Images/Aaru.Images.csproj.DotSettings +++ b/Aaru.Images/Aaru.Images.csproj.DotSettings @@ -2,92 +2,92 @@ xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml:space="preserve"> True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True \ No newline at end of file + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/AaruFormat.cs b/Aaru.Images/AaruFormat/AaruFormat.cs index a1d197ada..99bc00dec 100644 --- a/Aaru.Images/AaruFormat/AaruFormat.cs +++ b/Aaru.Images/AaruFormat/AaruFormat.cs @@ -83,7 +83,8 @@ namespace Aaru.DiscImages; /// Implements reading and writing AaruFormat media images public sealed partial class AaruFormat : IWritableOpticalImage, IVerifiableImage, IWritableTapeImage { - bool _alreadyWrittenZero; + const string MODULE_NAME = "Aaru Format plugin"; + bool _alreadyWrittenZero; /// Cache of uncompressed blocks. Dictionary _blockCache; /// Cache of block headers. @@ -129,10 +130,10 @@ public sealed partial class AaruFormat : IWritableOpticalImage, IVerifiableImage long _outMemoryDdtPosition; bool _rewinded; byte[] _sectorCprMai; - byte[] _sectorIed; - byte[] _sectorId; - byte[] _sectorEdc; byte[] _sectorDecryptedTitleKey; + byte[] _sectorEdc; + byte[] _sectorId; + byte[] _sectorIed; /// Cache for data that prefixes the user data on a sector (e.g. sync). byte[] _sectorPrefix; uint[] _sectorPrefixDdt; @@ -187,6 +188,4 @@ public sealed partial class AaruFormat : IWritableOpticalImage, IVerifiableImage DriveSerialNumber = null, DriveFirmwareRevision = null }; - - const string MODULE_NAME = "Aaru Format plugin"; } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/CdEcc.cs b/Aaru.Images/AaruFormat/CdEcc.cs index 02f9b96c5..84f42ac53 100644 --- a/Aaru.Images/AaruFormat/CdEcc.cs +++ b/Aaru.Images/AaruFormat/CdEcc.cs @@ -55,12 +55,12 @@ public sealed partial class AaruFormat for(uint i = 0; i < 256; i++) { uint edc = i; - uint j = (uint)((i << 1) ^ ((i & 0x80) == 0x80 ? 0x11D : 0)); + var j = (uint)(i << 1 ^ ((i & 0x80) == 0x80 ? 0x11D : 0)); _eccFTable[i] = (byte)j; _eccBTable[i ^ j] = (byte)i; for(j = 0; j < 8; j++) - edc = (edc >> 1) ^ ((edc & 1) > 0 ? 0xD8018001 : 0); + edc = edc >> 1 ^ ((edc & 1) > 0 ? 0xD8018001 : 0); _edcTable[i] = edc; } @@ -93,13 +93,13 @@ public sealed partial class AaruFormat if(!correctEccQ) return false; - uint storedEdc = BitConverter.ToUInt32(sector, 0x810); + var storedEdc = BitConverter.ToUInt32(sector, 0x810); uint edc = 0; - int size = 0x810; - int pos = 0; + var size = 0x810; + var pos = 0; for(; size > 0; size--) - edc = (edc >> 8) ^ _edcTable[(edc ^ sector[pos++]) & 0xFF]; + edc = edc >> 8 ^ _edcTable[(edc ^ sector[pos++]) & 0xFF]; uint calculatedEdc = edc; @@ -111,7 +111,7 @@ public sealed partial class AaruFormat if(!_initedEdc) EccInit(); - byte[] zeroAddress = new byte[4]; + var zeroAddress = new byte[4]; bool correctEccP = CheckEcc(zeroAddress, sector, 86, 24, 2, 86, sector, 0, 0x10, 0x81C); @@ -123,28 +123,28 @@ public sealed partial class AaruFormat if(!correctEccQ) return false; - uint storedEdc = BitConverter.ToUInt32(sector, 0x818); + var storedEdc = BitConverter.ToUInt32(sector, 0x818); uint edc = 0; - int size = 0x808; - int pos = 0x10; + var size = 0x808; + var pos = 0x10; for(; size > 0; size--) - edc = (edc >> 8) ^ _edcTable[(edc ^ sector[pos++]) & 0xFF]; + edc = edc >> 8 ^ _edcTable[(edc ^ sector[pos++]) & 0xFF]; uint calculatedEdc = edc; return calculatedEdc == storedEdc; } - bool CheckEcc(byte[] address, byte[] data, uint majorCount, uint minorCount, uint majorMult, uint minorInc, - byte[] ecc, int addressOffset, int dataOffset, int eccOffset) + bool CheckEcc(byte[] address, byte[] data, uint majorCount, uint minorCount, uint majorMult, uint minorInc, + byte[] ecc, int addressOffset, int dataOffset, int eccOffset) { uint size = majorCount * minorCount; uint major; for(major = 0; major < majorCount; major++) { - uint idx = ((major >> 1) * majorMult) + (major & 1); + uint idx = (major >> 1) * majorMult + (major & 1); byte eccA = 0; byte eccB = 0; uint minor; @@ -172,15 +172,15 @@ public sealed partial class AaruFormat return true; } - void WriteEcc(byte[] address, byte[] data, uint majorCount, uint minorCount, uint majorMult, uint minorInc, - ref byte[] ecc, int addressOffset, int dataOffset, int eccOffset) + void WriteEcc(byte[] address, byte[] data, uint majorCount, uint minorCount, uint majorMult, uint minorInc, + ref byte[] ecc, int addressOffset, int dataOffset, int eccOffset) { uint size = majorCount * minorCount; uint major; for(major = 0; major < majorCount; major++) { - uint idx = ((major >> 1) * majorMult) + (major & 1); + uint idx = (major >> 1) * majorMult + (major & 1); byte eccA = 0; byte eccB = 0; uint minor; @@ -206,7 +206,7 @@ public sealed partial class AaruFormat void EccWriteSector(byte[] address, byte[] data, ref byte[] ecc, int addressOffset, int dataOffset, int eccOffset) { - WriteEcc(address, data, 86, 24, 2, 86, ref ecc, addressOffset, dataOffset, eccOffset); // P + WriteEcc(address, data, 86, 24, 2, 86, ref ecc, addressOffset, dataOffset, eccOffset); // P WriteEcc(address, data, 52, 43, 86, 88, ref ecc, addressOffset, dataOffset, eccOffset + 0xAC); // Q } @@ -214,7 +214,7 @@ public sealed partial class AaruFormat ((byte)((pos + 150) / 75 / 60), (byte)((pos + 150) / 75 % 60), (byte)((pos + 150) % 75)); static void ReconstructPrefix(ref byte[] sector, // must point to a full 2352-byte sector - TrackType type, long lba) + TrackType type, long lba) { // // Sync @@ -234,9 +234,9 @@ public sealed partial class AaruFormat (byte minute, byte second, byte frame) msf = LbaToMsf(lba); - sector[0x00C] = (byte)(((msf.minute / 10) << 4) + (msf.minute % 10)); - sector[0x00D] = (byte)(((msf.second / 10) << 4) + (msf.second % 10)); - sector[0x00E] = (byte)(((msf.frame / 10) << 4) + (msf.frame % 10)); + sector[0x00C] = (byte)((msf.minute / 10 << 4) + msf.minute % 10); + sector[0x00D] = (byte)((msf.second / 10 << 4) + msf.second % 10); + sector[0x00E] = (byte)((msf.frame / 10 << 4) + msf.frame % 10); switch(type) { @@ -264,12 +264,13 @@ public sealed partial class AaruFormat sector[0x013] = sector[0x017]; break; - default: return; + default: + return; } } void ReconstructEcc(ref byte[] sector, // must point to a full 2352-byte sector - TrackType type) + TrackType type) { byte[] computedEdc; @@ -305,10 +306,11 @@ public sealed partial class AaruFormat sector[0x92F] = computedEdc[3]; break; - default: return; + default: + return; } - byte[] zeroAddress = new byte[4]; + var zeroAddress = new byte[4]; switch(type) { @@ -334,7 +336,8 @@ public sealed partial class AaruFormat EccWriteSector(zeroAddress, sector, ref sector, 0, 0x10, 0x81C); break; - default: return; + default: + return; } // @@ -350,7 +353,7 @@ public sealed partial class AaruFormat int pos = srcOffset; for(; size > 0; size--) - edc = (edc >> 8) ^ _edcTable[(edc ^ src[pos++]) & 0xFF]; + edc = edc >> 8 ^ _edcTable[(edc ^ src[pos++]) & 0xFF]; return edc; } diff --git a/Aaru.Images/AaruFormat/ClauniaSubchannelTransform.cs b/Aaru.Images/AaruFormat/ClauniaSubchannelTransform.cs index c187c3e73..a5c814861 100644 --- a/Aaru.Images/AaruFormat/ClauniaSubchannelTransform.cs +++ b/Aaru.Images/AaruFormat/ClauniaSubchannelTransform.cs @@ -43,19 +43,19 @@ public sealed partial class AaruFormat if(interleaved == null) return null; - int[] p = new int[interleaved.Length / 8]; - int[] q = new int[interleaved.Length / 8]; - int[] r = new int[interleaved.Length / 8]; - int[] s = new int[interleaved.Length / 8]; - int[] t = new int[interleaved.Length / 8]; - int[] u = new int[interleaved.Length / 8]; - int[] v = new int[interleaved.Length / 8]; - int[] w = new int[interleaved.Length / 8]; + var p = new int[interleaved.Length / 8]; + var q = new int[interleaved.Length / 8]; + var r = new int[interleaved.Length / 8]; + var s = new int[interleaved.Length / 8]; + var t = new int[interleaved.Length / 8]; + var u = new int[interleaved.Length / 8]; + var v = new int[interleaved.Length / 8]; + var w = new int[interleaved.Length / 8]; var stopwatch = new Stopwatch(); stopwatch.Start(); - for(int i = 0; i < interleaved.Length; i += 8) + for(var i = 0; i < interleaved.Length; i += 8) { p[i / 8] = interleaved[i] & 0x80; p[i / 8] += (interleaved[i + 1] & 0x80) >> 1; @@ -133,7 +133,7 @@ public sealed partial class AaruFormat stopwatch.Stop(); TimeSpan deinterleave = stopwatch.Elapsed; - byte[] sequential = new byte[interleaved.Length]; + var sequential = new byte[interleaved.Length]; stopwatch.Restart(); int qStart = p.Length * 1; @@ -144,7 +144,7 @@ public sealed partial class AaruFormat int vStart = p.Length * 6; int wStart = p.Length * 7; - for(int i = 0; i < p.Length; i++) + for(var i = 0; i < p.Length; i++) { sequential[i] = (byte)p[i]; sequential[qStart + i] = (byte)q[i]; @@ -176,14 +176,14 @@ public sealed partial class AaruFormat if(sequential == null) return null; - int[] p = new int[sequential.Length / 8]; - int[] q = new int[sequential.Length / 8]; - int[] r = new int[sequential.Length / 8]; - int[] s = new int[sequential.Length / 8]; - int[] t = new int[sequential.Length / 8]; - int[] u = new int[sequential.Length / 8]; - int[] v = new int[sequential.Length / 8]; - int[] w = new int[sequential.Length / 8]; + var p = new int[sequential.Length / 8]; + var q = new int[sequential.Length / 8]; + var r = new int[sequential.Length / 8]; + var s = new int[sequential.Length / 8]; + var t = new int[sequential.Length / 8]; + var u = new int[sequential.Length / 8]; + var v = new int[sequential.Length / 8]; + var w = new int[sequential.Length / 8]; int qStart = p.Length * 1; int rStart = p.Length * 2; @@ -196,7 +196,7 @@ public sealed partial class AaruFormat var stopwatch = new Stopwatch(); stopwatch.Start(); - for(int i = 0; i < p.Length; i++) + for(var i = 0; i < p.Length; i++) { p[i] = sequential[i]; q[i] = sequential[qStart + i]; @@ -211,10 +211,10 @@ public sealed partial class AaruFormat stopwatch.Stop(); TimeSpan desequentialize = stopwatch.Elapsed; - byte[] interleaved = new byte[sequential.Length]; + var interleaved = new byte[sequential.Length]; stopwatch.Restart(); - for(int i = 0; i < interleaved.Length; i += 8) + for(var i = 0; i < interleaved.Length; i += 8) { interleaved[i] = (byte)((p[i / 8] & 0x80) == 0x80 ? 0x80 : 0); interleaved[i + 1] += (byte)((p[i / 8] & 0x40) == 0x40 ? 0x80 : 0); diff --git a/Aaru.Images/AaruFormat/Enums.cs b/Aaru.Images/AaruFormat/Enums.cs index 936100ee8..5fdecfbf8 100644 --- a/Aaru.Images/AaruFormat/Enums.cs +++ b/Aaru.Images/AaruFormat/Enums.cs @@ -36,6 +36,77 @@ namespace Aaru.DiscImages; public sealed partial class AaruFormat { +#region Nested type: BlockType + + /// List of known blocks types + enum BlockType : uint + { + /// Block containing data + DataBlock = 0x4B4C4244, + /// Block containing a deduplication table + DeDuplicationTable = 0x2A544444, + /// Block containing the index + Index = 0x58444E49, + /// Block containing the index + Index2 = 0x32584449, + /// Block containing logical geometry + GeometryBlock = 0x4D4F4547, + /// Block containing metadata + MetadataBlock = 0x4154454D, + /// Block containing optical disc tracks + TracksBlock = 0x534B5254, + /// Block containing CICM XML metadata + CicmBlock = 0x4D434943, + /// Block containing contents checksums + ChecksumBlock = 0x4D534B43, + /// TODO: Block containing data position measurements + DataPositionMeasurementBlock = 0x2A4D5044, + /// TODO: Block containing a snapshot index + SnapshotBlock = 0x50414E53, + /// TODO: Block containing how to locate the parent image + ParentBlock = 0x544E5250, + /// Block containing an array of hardware used to create the image + DumpHardwareBlock = 0x2A504D44, + /// Block containing list of files for a tape image + TapeFileBlock = 0x454C4654, + /// Block containing list of partitions for a tape image + TapePartitionBlock = 0x54425054, + /// Block containing list of indexes for Compact Disc tracks + CompactDiscIndexesBlock = 0x58494443, + /// Block containing JSON version of Aaru Metadata + AaruMetadataJsonBlock = 0x444D534A + } + +#endregion + +#region Nested type: CdFixFlags + + enum CdFixFlags : uint + { + NotDumped = 0x10000000, + Correct = 0x20000000, + Mode2Form1Ok = 0x30000000, + Mode2Form2Ok = 0x40000000, + Mode2Form2NoCrc = 0x50000000 + } + +#endregion + +#region Nested type: ChecksumAlgorithm + + enum ChecksumAlgorithm : byte + { + Invalid = 0, + Md5 = 1, + Sha1 = 2, + Sha256 = 3, + SpamSum = 4 + } + +#endregion + +#region Nested type: CompressionType + /// List of known compression types enum CompressionType : ushort { @@ -49,6 +120,10 @@ public sealed partial class AaruFormat LzmaClauniaSubchannelTransform = 3 } +#endregion + +#region Nested type: DataType + /// List of known data types enum DataType : ushort { @@ -226,54 +301,5 @@ public sealed partial class AaruFormat DvdSectorEdc = 85 } - /// List of known blocks types - enum BlockType : uint - { - /// Block containing data - DataBlock = 0x4B4C4244, - /// Block containing a deduplication table - DeDuplicationTable = 0x2A544444, - /// Block containing the index - Index = 0x58444E49, - /// Block containing the index - Index2 = 0x32584449, - /// Block containing logical geometry - GeometryBlock = 0x4D4F4547, - /// Block containing metadata - MetadataBlock = 0x4154454D, - /// Block containing optical disc tracks - TracksBlock = 0x534B5254, - /// Block containing CICM XML metadata - CicmBlock = 0x4D434943, - /// Block containing contents checksums - ChecksumBlock = 0x4D534B43, - /// TODO: Block containing data position measurements - DataPositionMeasurementBlock = 0x2A4D5044, - /// TODO: Block containing a snapshot index - SnapshotBlock = 0x50414E53, - /// TODO: Block containing how to locate the parent image - ParentBlock = 0x544E5250, - /// Block containing an array of hardware used to create the image - DumpHardwareBlock = 0x2A504D44, - /// Block containing list of files for a tape image - TapeFileBlock = 0x454C4654, - /// Block containing list of partitions for a tape image - TapePartitionBlock = 0x54425054, - /// Block containing list of indexes for Compact Disc tracks - CompactDiscIndexesBlock = 0x58494443, - /// Block containing JSON version of Aaru Metadata - AaruMetadataJsonBlock = 0x444D534A - } - - enum ChecksumAlgorithm : byte - { - Invalid = 0, Md5 = 1, Sha1 = 2, - Sha256 = 3, SpamSum = 4 - } - - enum CdFixFlags : uint - { - NotDumped = 0x10000000, Correct = 0x20000000, Mode2Form1Ok = 0x30000000, - Mode2Form2Ok = 0x40000000, Mode2Form2NoCrc = 0x50000000 - } +#endregion } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/Helpers.cs b/Aaru.Images/AaruFormat/Helpers.cs index 28caf1975..d8589ec36 100644 --- a/Aaru.Images/AaruFormat/Helpers.cs +++ b/Aaru.Images/AaruFormat/Helpers.cs @@ -57,8 +57,10 @@ public sealed partial class AaruFormat _imageInfo.DriveModel = decoded.ProductName; if(string.IsNullOrWhiteSpace(_imageInfo.DriveFirmwareRevision)) + { _imageInfo.DriveFirmwareRevision = $"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}"; + } if(string.IsNullOrWhiteSpace(_imageInfo.DriveSerialNumber)) _imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}"; @@ -76,8 +78,10 @@ public sealed partial class AaruFormat _imageInfo.DriveModel = decoded.ProductName; if(string.IsNullOrWhiteSpace(_imageInfo.DriveFirmwareRevision)) + { _imageInfo.DriveFirmwareRevision = $"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}"; + } if(string.IsNullOrWhiteSpace(_imageInfo.DriveSerialNumber)) _imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}"; @@ -104,7 +108,7 @@ public sealed partial class AaruFormat } // Search for ATA or ATAPI IDENTIFY - if(!_mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out byte[] ataIdentify) && + if(!_mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out byte[] ataIdentify) && !_mediaTags.TryGetValue(MediaTagType.ATAPI_IDENTIFY, out ataIdentify)) return; @@ -118,6 +122,7 @@ public sealed partial class AaruFormat string[] separated = identify.Model.Split(' '); if(separated.Length == 1) + { if(string.IsNullOrWhiteSpace(_imageInfo.DriveModel)) _imageInfo.DriveModel = separated[0]; else @@ -128,6 +133,7 @@ public sealed partial class AaruFormat if(string.IsNullOrWhiteSpace(_imageInfo.DriveModel)) _imageInfo.DriveModel = separated[^1]; } + } if(string.IsNullOrWhiteSpace(_imageInfo.DriveFirmwareRevision)) _imageInfo.DriveFirmwareRevision = identify.FirmwareRevision; @@ -235,8 +241,10 @@ public sealed partial class AaruFormat case MediaType.VideoNow: case MediaType.VideoNowColor: case MediaType.VideoNowXp: - case MediaType.CVD: return MetadataMediaType.OpticalDisc; - default: return MetadataMediaType.BlockMedia; + case MediaType.CVD: + return MetadataMediaType.OpticalDisc; + default: + return MetadataMediaType.BlockMedia; } } @@ -252,7 +260,7 @@ public sealed partial class AaruFormat long oldPosition = _imageStream.Position; _imageStream.Position = _outMemoryDdtPosition + Marshal.SizeOf(); _imageStream.Position += (long)(sectorAddress * sizeof(ulong)); - byte[] temp = new byte[sizeof(ulong)]; + var temp = new byte[sizeof(ulong)]; _imageStream.EnsureRead(temp, 0, sizeof(ulong)); _imageStream.Position = oldPosition; entry = BitConverter.ToUInt64(temp, 0); @@ -287,153 +295,246 @@ public sealed partial class AaruFormat // Converts between image data type and Aaru media tag type static MediaTagType GetMediaTagTypeForDataType(DataType type) => type switch - { - DataType.CompactDiscPartialToc => MediaTagType.CD_TOC, - DataType.CompactDiscSessionInfo => MediaTagType.CD_SessionInfo, - DataType.CompactDiscToc => MediaTagType.CD_FullTOC, - DataType.CompactDiscPma => MediaTagType.CD_PMA, - DataType.CompactDiscAtip => MediaTagType.CD_ATIP, - DataType.CompactDiscLeadInCdText => MediaTagType.CD_TEXT, - DataType.DvdPfi => MediaTagType.DVD_PFI, - DataType.DvdLeadInCmi => MediaTagType.DVD_CMI, - DataType.DvdDiscKey => MediaTagType.DVD_DiscKey, - DataType.DvdBca => MediaTagType.DVD_BCA, - DataType.DvdDmi => MediaTagType.DVD_DMI, - DataType.DvdMediaIdentifier => MediaTagType.DVD_MediaIdentifier, - DataType.DvdMediaKeyBlock => MediaTagType.DVD_MKB, - DataType.DvdRamDds => MediaTagType.DVDRAM_DDS, - DataType.DvdRamMediumStatus => MediaTagType.DVDRAM_MediumStatus, - DataType.DvdRamSpareArea => MediaTagType.DVDRAM_SpareArea, - DataType.DvdRRmd => MediaTagType.DVDR_RMD, - DataType.DvdRPrerecordedInfo => MediaTagType.DVDR_PreRecordedInfo, - DataType.DvdRMediaIdentifier => MediaTagType.DVDR_MediaIdentifier, - DataType.DvdRPfi => MediaTagType.DVDR_PFI, - DataType.DvdAdip => MediaTagType.DVD_ADIP, - DataType.HdDvdCpi => MediaTagType.HDDVD_CPI, - DataType.HdDvdMediumStatus => MediaTagType.HDDVD_MediumStatus, - DataType.DvdDlLayerCapacity => MediaTagType.DVDDL_LayerCapacity, - DataType.DvdDlMiddleZoneAddress => MediaTagType.DVDDL_MiddleZoneAddress, - DataType.DvdDlJumpIntervalSize => MediaTagType.DVDDL_JumpIntervalSize, - DataType.DvdDlManualLayerJumpLba => MediaTagType.DVDDL_ManualLayerJumpLBA, - DataType.BlurayDi => MediaTagType.BD_DI, - DataType.BlurayBca => MediaTagType.BD_BCA, - DataType.BlurayDds => MediaTagType.BD_DDS, - DataType.BlurayCartridgeStatus => MediaTagType.BD_CartridgeStatus, - DataType.BluraySpareArea => MediaTagType.BD_SpareArea, - DataType.AacsVolumeIdentifier => MediaTagType.AACS_VolumeIdentifier, - DataType.AacsSerialNumber => MediaTagType.AACS_SerialNumber, - DataType.AacsMediaIdentifier => MediaTagType.AACS_MediaIdentifier, - DataType.AacsMediaKeyBlock => MediaTagType.AACS_MKB, - DataType.AacsDataKeys => MediaTagType.AACS_DataKeys, - DataType.AacsLbaExtents => MediaTagType.AACS_LBAExtents, - DataType.CprmMediaKeyBlock => MediaTagType.AACS_CPRM_MKB, - DataType.HybridRecognizedLayers => MediaTagType.Hybrid_RecognizedLayers, - DataType.ScsiMmcWriteProtection => MediaTagType.MMC_WriteProtection, - DataType.ScsiMmcDiscInformation => MediaTagType.MMC_DiscInformation, - DataType.ScsiMmcTrackResourcesInformation => MediaTagType.MMC_TrackResourcesInformation, - DataType.ScsiMmcPowResourcesInformation => MediaTagType.MMC_POWResourcesInformation, - DataType.ScsiInquiry => MediaTagType.SCSI_INQUIRY, - DataType.ScsiModePage2A => MediaTagType.SCSI_MODEPAGE_2A, - DataType.AtaIdentify => MediaTagType.ATA_IDENTIFY, - DataType.AtapiIdentify => MediaTagType.ATAPI_IDENTIFY, - DataType.PcmciaCis => MediaTagType.PCMCIA_CIS, - DataType.SecureDigitalCid => MediaTagType.SD_CID, - DataType.SecureDigitalCsd => MediaTagType.SD_CSD, - DataType.SecureDigitalScr => MediaTagType.SD_SCR, - DataType.SecureDigitalOcr => MediaTagType.SD_OCR, - DataType.MultiMediaCardCid => MediaTagType.MMC_CID, - DataType.MultiMediaCardCsd => MediaTagType.MMC_CSD, - DataType.MultiMediaCardOcr => MediaTagType.MMC_OCR, - DataType.MultiMediaCardExtendedCsd => MediaTagType.MMC_ExtendedCSD, - DataType.XboxSecuritySector => MediaTagType.Xbox_SecuritySector, - DataType.FloppyLeadOut => MediaTagType.Floppy_LeadOut, - DataType.DvdDiscControlBlock => MediaTagType.DCB, - DataType.CompactDiscFirstTrackPregap => MediaTagType.CD_FirstTrackPregap, - DataType.CompactDiscLeadOut => MediaTagType.CD_LeadOut, - DataType.ScsiModeSense6 => MediaTagType.SCSI_MODESENSE_6, - DataType.ScsiModeSense10 => MediaTagType.SCSI_MODESENSE_10, - DataType.UsbDescriptors => MediaTagType.USB_Descriptors, - DataType.XboxDmi => MediaTagType.Xbox_DMI, - DataType.XboxPfi => MediaTagType.Xbox_PFI, - DataType.CompactDiscMediaCatalogueNumber => MediaTagType.CD_MCN, - DataType.CompactDiscLeadIn => MediaTagType.CD_LeadIn, - DataType.DvdDiscKeyDecrypted => MediaTagType.DVD_DiscKey_Decrypted, - _ => throw new ArgumentOutOfRangeException() - }; + { + DataType.CompactDiscPartialToc => MediaTagType. + CD_TOC, + DataType.CompactDiscSessionInfo => + MediaTagType.CD_SessionInfo, + DataType.CompactDiscToc => MediaTagType. + CD_FullTOC, + DataType.CompactDiscPma => MediaTagType.CD_PMA, + DataType.CompactDiscAtip => MediaTagType. + CD_ATIP, + DataType.CompactDiscLeadInCdText => + MediaTagType.CD_TEXT, + DataType.DvdPfi => MediaTagType.DVD_PFI, + DataType.DvdLeadInCmi => MediaTagType.DVD_CMI, + DataType.DvdDiscKey => + MediaTagType.DVD_DiscKey, + DataType.DvdBca => MediaTagType.DVD_BCA, + DataType.DvdDmi => MediaTagType.DVD_DMI, + DataType.DvdMediaIdentifier => MediaTagType. + DVD_MediaIdentifier, + DataType.DvdMediaKeyBlock => MediaTagType. + DVD_MKB, + DataType.DvdRamDds => MediaTagType.DVDRAM_DDS, + DataType.DvdRamMediumStatus => MediaTagType. + DVDRAM_MediumStatus, + DataType.DvdRamSpareArea => MediaTagType. + DVDRAM_SpareArea, + DataType.DvdRRmd => MediaTagType.DVDR_RMD, + DataType.DvdRPrerecordedInfo => MediaTagType. + DVDR_PreRecordedInfo, + DataType.DvdRMediaIdentifier => MediaTagType. + DVDR_MediaIdentifier, + DataType.DvdRPfi => MediaTagType.DVDR_PFI, + DataType.DvdAdip => MediaTagType.DVD_ADIP, + DataType.HdDvdCpi => MediaTagType.HDDVD_CPI, + DataType.HdDvdMediumStatus => MediaTagType. + HDDVD_MediumStatus, + DataType.DvdDlLayerCapacity => MediaTagType. + DVDDL_LayerCapacity, + DataType.DvdDlMiddleZoneAddress => + MediaTagType.DVDDL_MiddleZoneAddress, + DataType.DvdDlJumpIntervalSize => MediaTagType. + DVDDL_JumpIntervalSize, + DataType.DvdDlManualLayerJumpLba => + MediaTagType.DVDDL_ManualLayerJumpLBA, + DataType.BlurayDi => MediaTagType.BD_DI, + DataType.BlurayBca => MediaTagType.BD_BCA, + DataType.BlurayDds => MediaTagType.BD_DDS, + DataType.BlurayCartridgeStatus => MediaTagType. + BD_CartridgeStatus, + DataType.BluraySpareArea => MediaTagType. + BD_SpareArea, + DataType.AacsVolumeIdentifier => MediaTagType. + AACS_VolumeIdentifier, + DataType.AacsSerialNumber => MediaTagType. + AACS_SerialNumber, + DataType.AacsMediaIdentifier => MediaTagType. + AACS_MediaIdentifier, + DataType.AacsMediaKeyBlock => MediaTagType. + AACS_MKB, + DataType.AacsDataKeys => MediaTagType. + AACS_DataKeys, + DataType.AacsLbaExtents => MediaTagType. + AACS_LBAExtents, + DataType.CprmMediaKeyBlock => MediaTagType. + AACS_CPRM_MKB, + DataType.HybridRecognizedLayers => + MediaTagType.Hybrid_RecognizedLayers, + DataType.ScsiMmcWriteProtection => + MediaTagType.MMC_WriteProtection, + DataType.ScsiMmcDiscInformation => + MediaTagType.MMC_DiscInformation, + DataType.ScsiMmcTrackResourcesInformation => + MediaTagType.MMC_TrackResourcesInformation, + DataType.ScsiMmcPowResourcesInformation => + MediaTagType.MMC_POWResourcesInformation, + DataType.ScsiInquiry => MediaTagType. + SCSI_INQUIRY, + DataType.ScsiModePage2A => MediaTagType. + SCSI_MODEPAGE_2A, + DataType.AtaIdentify => MediaTagType. + ATA_IDENTIFY, + DataType.AtapiIdentify => MediaTagType. + ATAPI_IDENTIFY, + DataType.PcmciaCis => MediaTagType.PCMCIA_CIS, + DataType.SecureDigitalCid => MediaTagType. + SD_CID, + DataType.SecureDigitalCsd => MediaTagType. + SD_CSD, + DataType.SecureDigitalScr => MediaTagType. + SD_SCR, + DataType.SecureDigitalOcr => MediaTagType. + SD_OCR, + DataType.MultiMediaCardCid => MediaTagType. + MMC_CID, + DataType.MultiMediaCardCsd => MediaTagType. + MMC_CSD, + DataType.MultiMediaCardOcr => MediaTagType. + MMC_OCR, + DataType.MultiMediaCardExtendedCsd => + MediaTagType.MMC_ExtendedCSD, + DataType.XboxSecuritySector => MediaTagType. + Xbox_SecuritySector, + DataType.FloppyLeadOut => MediaTagType. + Floppy_LeadOut, + DataType.DvdDiscControlBlock => MediaTagType. + DCB, + DataType.CompactDiscFirstTrackPregap => + MediaTagType.CD_FirstTrackPregap, + DataType.CompactDiscLeadOut => MediaTagType. + CD_LeadOut, + DataType.ScsiModeSense6 => MediaTagType. + SCSI_MODESENSE_6, + DataType.ScsiModeSense10 => MediaTagType. + SCSI_MODESENSE_10, + DataType.UsbDescriptors => MediaTagType. + USB_Descriptors, + DataType.XboxDmi => MediaTagType.Xbox_DMI, + DataType.XboxPfi => MediaTagType.Xbox_PFI, + DataType.CompactDiscMediaCatalogueNumber => + MediaTagType.CD_MCN, + DataType.CompactDiscLeadIn => MediaTagType. + CD_LeadIn, + DataType.DvdDiscKeyDecrypted => MediaTagType. + DVD_DiscKey_Decrypted, + _ => throw new ArgumentOutOfRangeException() + }; // Converts between Aaru media tag type and image data type static DataType GetDataTypeForMediaTag(MediaTagType tag) => tag switch - { - MediaTagType.CD_TOC => DataType.CompactDiscPartialToc, - MediaTagType.CD_SessionInfo => DataType.CompactDiscSessionInfo, - MediaTagType.CD_FullTOC => DataType.CompactDiscToc, - MediaTagType.CD_PMA => DataType.CompactDiscPma, - MediaTagType.CD_ATIP => DataType.CompactDiscAtip, - MediaTagType.CD_TEXT => DataType.CompactDiscLeadInCdText, - MediaTagType.DVD_PFI => DataType.DvdPfi, - MediaTagType.DVD_CMI => DataType.DvdLeadInCmi, - MediaTagType.DVD_DiscKey => DataType.DvdDiscKey, - MediaTagType.DVD_BCA => DataType.DvdBca, - MediaTagType.DVD_DMI => DataType.DvdDmi, - MediaTagType.DVD_MediaIdentifier => DataType.DvdMediaIdentifier, - MediaTagType.DVD_MKB => DataType.DvdMediaKeyBlock, - MediaTagType.DVDRAM_DDS => DataType.DvdRamDds, - MediaTagType.DVDRAM_MediumStatus => DataType.DvdRamMediumStatus, - MediaTagType.DVDRAM_SpareArea => DataType.DvdRamSpareArea, - MediaTagType.DVDR_RMD => DataType.DvdRRmd, - MediaTagType.DVDR_PreRecordedInfo => DataType.DvdRPrerecordedInfo, - MediaTagType.DVDR_MediaIdentifier => DataType.DvdRMediaIdentifier, - MediaTagType.DVDR_PFI => DataType.DvdRPfi, - MediaTagType.DVD_ADIP => DataType.DvdAdip, - MediaTagType.HDDVD_CPI => DataType.HdDvdCpi, - MediaTagType.HDDVD_MediumStatus => DataType.HdDvdMediumStatus, - MediaTagType.DVDDL_LayerCapacity => DataType.DvdDlLayerCapacity, - MediaTagType.DVDDL_MiddleZoneAddress => DataType.DvdDlMiddleZoneAddress, - MediaTagType.DVDDL_JumpIntervalSize => DataType.DvdDlJumpIntervalSize, - MediaTagType.DVDDL_ManualLayerJumpLBA => DataType.DvdDlManualLayerJumpLba, - MediaTagType.BD_DI => DataType.BlurayDi, - MediaTagType.BD_BCA => DataType.BlurayBca, - MediaTagType.BD_DDS => DataType.BlurayDds, - MediaTagType.BD_CartridgeStatus => DataType.BlurayCartridgeStatus, - MediaTagType.BD_SpareArea => DataType.BluraySpareArea, - MediaTagType.AACS_VolumeIdentifier => DataType.AacsVolumeIdentifier, - MediaTagType.AACS_SerialNumber => DataType.AacsSerialNumber, - MediaTagType.AACS_MediaIdentifier => DataType.AacsMediaIdentifier, - MediaTagType.AACS_MKB => DataType.AacsMediaKeyBlock, - MediaTagType.AACS_DataKeys => DataType.AacsDataKeys, - MediaTagType.AACS_LBAExtents => DataType.AacsLbaExtents, - MediaTagType.AACS_CPRM_MKB => DataType.CprmMediaKeyBlock, - MediaTagType.Hybrid_RecognizedLayers => DataType.HybridRecognizedLayers, - MediaTagType.MMC_WriteProtection => DataType.ScsiMmcWriteProtection, - MediaTagType.MMC_DiscInformation => DataType.ScsiMmcDiscInformation, - MediaTagType.MMC_TrackResourcesInformation => DataType.ScsiMmcTrackResourcesInformation, - MediaTagType.MMC_POWResourcesInformation => DataType.ScsiMmcPowResourcesInformation, - MediaTagType.SCSI_INQUIRY => DataType.ScsiInquiry, - MediaTagType.SCSI_MODEPAGE_2A => DataType.ScsiModePage2A, - MediaTagType.ATA_IDENTIFY => DataType.AtaIdentify, - MediaTagType.ATAPI_IDENTIFY => DataType.AtapiIdentify, - MediaTagType.PCMCIA_CIS => DataType.PcmciaCis, - MediaTagType.SD_CID => DataType.SecureDigitalCid, - MediaTagType.SD_CSD => DataType.SecureDigitalCsd, - MediaTagType.SD_SCR => DataType.SecureDigitalScr, - MediaTagType.SD_OCR => DataType.SecureDigitalOcr, - MediaTagType.MMC_CID => DataType.MultiMediaCardCid, - MediaTagType.MMC_CSD => DataType.MultiMediaCardCsd, - MediaTagType.MMC_OCR => DataType.MultiMediaCardOcr, - MediaTagType.MMC_ExtendedCSD => DataType.MultiMediaCardExtendedCsd, - MediaTagType.Xbox_SecuritySector => DataType.XboxSecuritySector, - MediaTagType.Floppy_LeadOut => DataType.FloppyLeadOut, - MediaTagType.DCB => DataType.DvdDiscControlBlock, - MediaTagType.CD_FirstTrackPregap => DataType.CompactDiscFirstTrackPregap, - MediaTagType.CD_LeadOut => DataType.CompactDiscLeadOut, - MediaTagType.SCSI_MODESENSE_6 => DataType.ScsiModeSense6, - MediaTagType.SCSI_MODESENSE_10 => DataType.ScsiModeSense10, - MediaTagType.USB_Descriptors => DataType.UsbDescriptors, - MediaTagType.Xbox_DMI => DataType.XboxDmi, - MediaTagType.Xbox_PFI => DataType.XboxPfi, - MediaTagType.CD_MCN => DataType.CompactDiscMediaCatalogueNumber, - MediaTagType.CD_LeadIn => DataType.CompactDiscLeadIn, - MediaTagType.DVD_DiscKey_Decrypted => DataType.DvdDiscKeyDecrypted, - _ => throw new ArgumentOutOfRangeException(nameof(tag), tag, null) - }; + { + MediaTagType.CD_TOC => DataType. + CompactDiscPartialToc, + MediaTagType.CD_SessionInfo => DataType. + CompactDiscSessionInfo, + MediaTagType.CD_FullTOC => DataType.CompactDiscToc, + MediaTagType.CD_PMA => DataType.CompactDiscPma, + MediaTagType.CD_ATIP => DataType.CompactDiscAtip, + MediaTagType.CD_TEXT => DataType. + CompactDiscLeadInCdText, + MediaTagType.DVD_PFI => DataType.DvdPfi, + MediaTagType.DVD_CMI => DataType.DvdLeadInCmi, + MediaTagType.DVD_DiscKey => DataType.DvdDiscKey, + MediaTagType.DVD_BCA => DataType.DvdBca, + MediaTagType.DVD_DMI => DataType.DvdDmi, + MediaTagType.DVD_MediaIdentifier => DataType. + DvdMediaIdentifier, + MediaTagType.DVD_MKB => DataType.DvdMediaKeyBlock, + MediaTagType.DVDRAM_DDS => DataType.DvdRamDds, + MediaTagType.DVDRAM_MediumStatus => DataType. + DvdRamMediumStatus, + MediaTagType.DVDRAM_SpareArea => DataType. + DvdRamSpareArea, + MediaTagType.DVDR_RMD => DataType.DvdRRmd, + MediaTagType.DVDR_PreRecordedInfo => DataType. + DvdRPrerecordedInfo, + MediaTagType.DVDR_MediaIdentifier => DataType. + DvdRMediaIdentifier, + MediaTagType.DVDR_PFI => DataType.DvdRPfi, + MediaTagType.DVD_ADIP => DataType.DvdAdip, + MediaTagType.HDDVD_CPI => DataType.HdDvdCpi, + MediaTagType.HDDVD_MediumStatus => DataType. + HdDvdMediumStatus, + MediaTagType.DVDDL_LayerCapacity => DataType. + DvdDlLayerCapacity, + MediaTagType.DVDDL_MiddleZoneAddress => DataType. + DvdDlMiddleZoneAddress, + MediaTagType.DVDDL_JumpIntervalSize => DataType. + DvdDlJumpIntervalSize, + MediaTagType.DVDDL_ManualLayerJumpLBA => DataType. + DvdDlManualLayerJumpLba, + MediaTagType.BD_DI => DataType.BlurayDi, + MediaTagType.BD_BCA => DataType.BlurayBca, + MediaTagType.BD_DDS => DataType.BlurayDds, + MediaTagType.BD_CartridgeStatus => DataType. + BlurayCartridgeStatus, + MediaTagType.BD_SpareArea => DataType. + BluraySpareArea, + MediaTagType.AACS_VolumeIdentifier => DataType. + AacsVolumeIdentifier, + MediaTagType.AACS_SerialNumber => DataType. + AacsSerialNumber, + MediaTagType.AACS_MediaIdentifier => DataType. + AacsMediaIdentifier, + MediaTagType.AACS_MKB => DataType.AacsMediaKeyBlock, + MediaTagType.AACS_DataKeys => DataType.AacsDataKeys, + MediaTagType.AACS_LBAExtents => DataType. + AacsLbaExtents, + MediaTagType.AACS_CPRM_MKB => DataType. + CprmMediaKeyBlock, + MediaTagType.Hybrid_RecognizedLayers => DataType. + HybridRecognizedLayers, + MediaTagType.MMC_WriteProtection => DataType. + ScsiMmcWriteProtection, + MediaTagType.MMC_DiscInformation => DataType. + ScsiMmcDiscInformation, + MediaTagType.MMC_TrackResourcesInformation => + DataType.ScsiMmcTrackResourcesInformation, + MediaTagType.MMC_POWResourcesInformation => + DataType.ScsiMmcPowResourcesInformation, + MediaTagType.SCSI_INQUIRY => DataType.ScsiInquiry, + MediaTagType.SCSI_MODEPAGE_2A => DataType. + ScsiModePage2A, + MediaTagType.ATA_IDENTIFY => DataType.AtaIdentify, + MediaTagType.ATAPI_IDENTIFY => DataType. + AtapiIdentify, + MediaTagType.PCMCIA_CIS => DataType.PcmciaCis, + MediaTagType.SD_CID => DataType.SecureDigitalCid, + MediaTagType.SD_CSD => DataType.SecureDigitalCsd, + MediaTagType.SD_SCR => DataType.SecureDigitalScr, + MediaTagType.SD_OCR => DataType.SecureDigitalOcr, + MediaTagType.MMC_CID => DataType.MultiMediaCardCid, + MediaTagType.MMC_CSD => DataType.MultiMediaCardCsd, + MediaTagType.MMC_OCR => DataType.MultiMediaCardOcr, + MediaTagType.MMC_ExtendedCSD => DataType. + MultiMediaCardExtendedCsd, + MediaTagType.Xbox_SecuritySector => DataType. + XboxSecuritySector, + MediaTagType.Floppy_LeadOut => DataType. + FloppyLeadOut, + MediaTagType.DCB => DataType.DvdDiscControlBlock, + MediaTagType.CD_FirstTrackPregap => DataType. + CompactDiscFirstTrackPregap, + MediaTagType.CD_LeadOut => DataType. + CompactDiscLeadOut, + MediaTagType.SCSI_MODESENSE_6 => DataType. + ScsiModeSense6, + MediaTagType.SCSI_MODESENSE_10 => DataType. + ScsiModeSense10, + MediaTagType.USB_Descriptors => DataType. + UsbDescriptors, + MediaTagType.Xbox_DMI => DataType.XboxDmi, + MediaTagType.Xbox_PFI => DataType.XboxPfi, + MediaTagType.CD_MCN => DataType. + CompactDiscMediaCatalogueNumber, + MediaTagType.CD_LeadIn => + DataType.CompactDiscLeadIn, + MediaTagType.DVD_DiscKey_Decrypted => DataType. + DvdDiscKeyDecrypted, + _ => throw new ArgumentOutOfRangeException( + nameof(tag), tag, null) + }; } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/Identify.cs b/Aaru.Images/AaruFormat/Identify.cs index f63270bfe..4c7301a17 100644 --- a/Aaru.Images/AaruFormat/Identify.cs +++ b/Aaru.Images/AaruFormat/Identify.cs @@ -38,6 +38,8 @@ namespace Aaru.DiscImages; public sealed partial class AaruFormat { +#region IWritableOpticalImage Members + /// public bool Identify(IFilter imageFilter) { @@ -53,4 +55,6 @@ public sealed partial class AaruFormat return _header.identifier is DIC_MAGIC or AARU_MAGIC && _header.imageMajorVersion <= AARUFMT_VERSION; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/Properties.cs b/Aaru.Images/AaruFormat/Properties.cs index c6d1121bd..036f41a53 100644 --- a/Aaru.Images/AaruFormat/Properties.cs +++ b/Aaru.Images/AaruFormat/Properties.cs @@ -44,6 +44,8 @@ namespace Aaru.DiscImages; public sealed partial class AaruFormat { +#region IWritableOpticalImage Members + /// public OpticalImageCapabilities OpticalCapabilities => OpticalImageCapabilities.CanStoreAudioTracks | OpticalImageCapabilities.CanStoreDataTracks | @@ -60,33 +62,47 @@ public sealed partial class AaruFormat OpticalImageCapabilities.CanStoreNotCdTracks | OpticalImageCapabilities.CanStoreIndexes | OpticalImageCapabilities.CanStoreHiddenTracks; + /// public ImageInfo Info => _imageInfo; + /// public string Name => Localization.AaruFormat_Name; + /// public Guid Id => new("49360069-1784-4A2F-B723-0C844D610B0A"); + /// public string Format => "Aaru"; + /// public string Author => Authors.NataliaPortillo; + /// public List Partitions { get; private set; } + /// public List Tracks { get; private set; } + /// public List Sessions { get; private set; } + /// public List DumpHardware { get; private set; } + /// public Metadata AaruMetadata { get; private set; } + /// public IEnumerable SupportedMediaTags => Enum.GetValues(typeof(MediaTagType)).Cast(); + /// public IEnumerable SupportedSectorTags => Enum.GetValues(typeof(SectorTagType)).Cast(); + /// public IEnumerable SupportedMediaTypes => Enum.GetValues(typeof(MediaType)).Cast(); + /// public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions => new[] { @@ -98,20 +114,23 @@ public sealed partial class AaruFormat ("md5", typeof(bool), Localization.Calculate_and_store_MD5_of_image_user_data, false), ("sha1", typeof(bool), Localization.Calculate_and_store_SHA1_of_image_user_data, false), ("sha256", typeof(bool), Localization.Calculate_and_store_SHA256_of_image_user_data, false), - ("spamsum", typeof(bool), Localization.Calculate_and_store_SpamSum_of_image_user_data, false), - ("deduplicate", typeof(bool), - Localization.Store_only_unique_sectors_This_consumes_more_memory_and_is_slower_but_its_enabled_by_default, - true), + ("spamsum", typeof(bool), Localization.Calculate_and_store_SpamSum_of_image_user_data, false), ("deduplicate", + typeof(bool), + Localization. + Store_only_unique_sectors_This_consumes_more_memory_and_is_slower_but_its_enabled_by_default, + true), ("compress", typeof(bool), Localization.Compress_user_data_blocks_Other_blocks_will_always_be_compressed, (object)true) }; + /// - public IEnumerable KnownExtensions => new[] - { - ".dicf", ".aaru", ".aaruformat", ".aaruf", ".aif" - }; + public IEnumerable KnownExtensions => new[] { ".dicf", ".aaru", ".aaruformat", ".aaruf", ".aif" }; + /// public bool IsWriting { get; private set; } + /// public string ErrorMessage { get; private set; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/Read.cs b/Aaru.Images/AaruFormat/Read.cs index 810baf688..f8f871290 100644 --- a/Aaru.Images/AaruFormat/Read.cs +++ b/Aaru.Images/AaruFormat/Read.cs @@ -63,6 +63,8 @@ namespace Aaru.DiscImages; public sealed partial class AaruFormat { +#region IWritableOpticalImage Members + /// public ErrorNumber Open(IFilter imageFilter) { @@ -168,7 +170,7 @@ public sealed partial class AaruFormat _imageInfo.ImageSize = 0; - bool foundUserDataDdt = false; + var foundUserDataDdt = false; _mediaTags = new Dictionary(); List compactDiscIndexes = null; @@ -228,7 +230,7 @@ public sealed partial class AaruFormat // Decompress media tag if(blockHeader.compression is CompressionType.Lzma - or CompressionType.LzmaClauniaSubchannelTransform) + or CompressionType.LzmaClauniaSubchannelTransform) { if(blockHeader.compression == CompressionType.LzmaClauniaSubchannelTransform && entry.dataType != DataType.CdSectorSubchannel) @@ -243,10 +245,10 @@ public sealed partial class AaruFormat var decompressStopwatch = new Stopwatch(); decompressStopwatch.Start(); - byte[] compressedTag = new byte[blockHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; - byte[] lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; + var compressedTag = new byte[blockHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; + var lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; _imageStream.EnsureRead(lzmaProperties, 0, LZMA_PROPERTIES_LENGTH); - _imageStream.EnsureRead(compressedTag, 0, compressedTag.Length); + _imageStream.EnsureRead(compressedTag, 0, compressedTag.Length); data = new byte[blockHeader.length]; int decompressedLength = LZMA.DecodeBuffer(compressedTag, data, lzmaProperties); @@ -487,13 +489,13 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Decompressing_DDT); var ddtStopwatch = new Stopwatch(); ddtStopwatch.Start(); - byte[] compressedDdt = new byte[ddtHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; - byte[] lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; + var compressedDdt = new byte[ddtHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; + var lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; _imageStream.EnsureRead(lzmaProperties, 0, LZMA_PROPERTIES_LENGTH); - _imageStream.EnsureRead(compressedDdt, 0, compressedDdt.Length); - byte[] decompressedDdt = new byte[ddtHeader.length]; + _imageStream.EnsureRead(compressedDdt, 0, compressedDdt.Length); + var decompressedDdt = new byte[ddtHeader.length]; - ulong decompressedLength = + var decompressedLength = (ulong)LZMA.DecodeBuffer(compressedDdt, decompressedDdt, lzmaProperties); if(decompressedLength != ddtHeader.length) @@ -531,8 +533,9 @@ public sealed partial class AaruFormat default: AaruConsole. ErrorWriteLine(string. - Format(Localization.Found_unsupported_compression_algorithm_0, - (ushort)ddtHeader.compression)); + Format( + Localization.Found_unsupported_compression_algorithm_0, + (ushort)ddtHeader.compression)); return ErrorNumber.NotSupported; } @@ -543,7 +546,7 @@ public sealed partial class AaruFormat case DataType.CdSectorPrefixCorrected: case DataType.CdSectorSuffixCorrected: { - byte[] decompressedDdt = new byte[ddtHeader.length]; + var decompressedDdt = new byte[ddtHeader.length]; AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Memory_snapshot_0_bytes, GC.GetTotalMemory(false)); @@ -555,12 +558,12 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Decompressing_DDT); var ddtStopwatch = new Stopwatch(); ddtStopwatch.Start(); - byte[] compressedDdt = new byte[ddtHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; - byte[] lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; + var compressedDdt = new byte[ddtHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; + var lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; _imageStream.EnsureRead(lzmaProperties, 0, LZMA_PROPERTIES_LENGTH); - _imageStream.EnsureRead(compressedDdt, 0, compressedDdt.Length); + _imageStream.EnsureRead(compressedDdt, 0, compressedDdt.Length); - ulong decompressedLength = + var decompressedLength = (ulong)LZMA.DecodeBuffer(compressedDdt, decompressedDdt, lzmaProperties); ddtStopwatch.Stop(); @@ -595,8 +598,9 @@ public sealed partial class AaruFormat default: AaruConsole. ErrorWriteLine(string. - Format(Localization.Found_unsupported_compression_algorithm_0, - (ushort)ddtHeader.compression)); + Format( + Localization.Found_unsupported_compression_algorithm_0, + (ushort)ddtHeader.compression)); return ErrorNumber.NotSupported; } @@ -668,7 +672,7 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Found_metadata_block_at_position_0, entry.offset); - byte[] metadata = new byte[metadataBlock.blockSize]; + var metadata = new byte[metadataBlock.blockSize]; _imageStream.Position = (long)entry.offset; _imageStream.EnsureRead(metadata, 0, metadata.Length); @@ -917,23 +921,23 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Memory_snapshot_0_bytes, GC.GetTotalMemory(false)); - byte[] cicmBytes = new byte[cicmBlock.length]; + var cicmBytes = new byte[cicmBlock.length]; _imageStream.EnsureRead(cicmBytes, 0, cicmBytes.Length); var cicmMs = new MemoryStream(cicmBytes); // The converter to AaruMetadata basically overcomes this (should?) - #pragma warning disable IL2026 + #pragma warning disable IL2026 var cicmXs = new XmlSerializer(typeof(CICMMetadataType)); - #pragma warning restore IL2026 + #pragma warning restore IL2026 try { var sr = new StreamReader(cicmMs); // The converter to AaruMetadata basically overcomes this (should?) - #pragma warning disable IL2026 + #pragma warning disable IL2026 AaruMetadata = (CICMMetadataType)cicmXs.Deserialize(sr); - #pragma warning restore IL2026 + #pragma warning restore IL2026 sr.Close(); } catch(XmlException ex) @@ -967,7 +971,7 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Memory_snapshot_0_bytes, GC.GetTotalMemory(false)); - byte[] jsonBytes = new byte[aaruMetadataBlock.length]; + var jsonBytes = new byte[aaruMetadataBlock.length]; _imageStream.EnsureRead(jsonBytes, 0, jsonBytes.Length); try @@ -1145,7 +1149,7 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Found_tape_partition_block_at_position_0, entry.offset); - byte[] tapePartitionBytes = new byte[partitionHeader.length]; + var tapePartitionBytes = new byte[partitionHeader.length]; _imageStream.EnsureRead(tapePartitionBytes, 0, tapePartitionBytes.Length); Span tapePartitions = @@ -1154,12 +1158,14 @@ public sealed partial class AaruFormat TapePartitions = new List(); foreach(TapePartitionEntry tapePartition in tapePartitions) + { TapePartitions.Add(new TapePartition { FirstBlock = tapePartition.FirstBlock, LastBlock = tapePartition.LastBlock, Number = tapePartition.Number }); + } IsTape = true; @@ -1178,12 +1184,13 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Found_tape_file_block_at_position_0, entry.offset); - byte[] tapeFileBytes = new byte[fileHeader.length]; + var tapeFileBytes = new byte[fileHeader.length]; _imageStream.EnsureRead(tapeFileBytes, 0, tapeFileBytes.Length); Span tapeFiles = MemoryMarshal.Cast(tapeFileBytes); Files = new List(); foreach(TapeFileEntry file in tapeFiles) + { Files.Add(new TapeFile { FirstBlock = file.FirstBlock, @@ -1191,6 +1198,7 @@ public sealed partial class AaruFormat Partition = file.Partition, File = file.File }); + } IsTape = true; @@ -1298,12 +1306,12 @@ public sealed partial class AaruFormat { if(Tracks != null) { - bool leadOutFixed = false; - bool sessionPregapFixed = false; + var leadOutFixed = false; + var sessionPregapFixed = false; if(_mediaTags.TryGetValue(MediaTagType.CD_FullTOC, out byte[] fullToc)) { - byte[] tmp = new byte[fullToc.Length + 2]; + var tmp = new byte[fullToc.Length + 2]; Array.Copy(fullToc, 0, tmp, 2, fullToc.Length); tmp[0] = (byte)(fullToc.Length >> 8); tmp[1] = (byte)(fullToc.Length & 0xFF); @@ -1354,8 +1362,8 @@ public sealed partial class AaruFormat phour = trk.PHOUR; } - int lastSector = (phour * 3600 * 75) + (pmin * 60 * 75) + (psec * 75) + pframe - 150; - leadOutStarts?.Add(trk.SessionNumber, lastSector + 1); + int lastSector = phour * 3600 * 75 + pmin * 60 * 75 + psec * 75 + pframe - 150; + leadOutStarts?.Add(trk.SessionNumber, lastSector + 1); } foreach(KeyValuePair leadOuts in leadOutStarts) @@ -1377,6 +1385,7 @@ public sealed partial class AaruFormat } if(_header.imageMajorVersion <= 1) + { foreach(Track track in Tracks) { if(track.Sequence <= 1) @@ -1398,13 +1407,16 @@ public sealed partial class AaruFormat sessionPregapFixed = true; } + } if(leadOutFixed) AaruConsole.ErrorWriteLine(Localization.This_image_has_a_corrupted_track_list_convert_will_fix_it); if(sessionPregapFixed) + { AaruConsole.ErrorWriteLine(Localization. This_image_has_a_corrupted_track_list_a_best_effort_has_been_tried_but_may_require_manual_editing_or_redump); + } } AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Memory_snapshot_0_bytes, @@ -1431,9 +1443,7 @@ public sealed partial class AaruFormat _trackFlags = new Dictionary { - { - 1, (byte)CdFlags.DataTrack - } + { 1, (byte)CdFlags.DataTrack } }; _trackIsrcs = new Dictionary(); @@ -1444,7 +1454,8 @@ public sealed partial class AaruFormat Sessions = new List(); - for(int i = 1; i <= Tracks.Max(t => t.Session); i++) + for(var i = 1; i <= Tracks.Max(t => t.Session); i++) + { Sessions.Add(new Session { Sequence = (ushort)i, @@ -1453,6 +1464,7 @@ public sealed partial class AaruFormat StartSector = Tracks.Where(t => t.Session == i).Min(t => t.StartSector), EndSector = Tracks.Where(t => t.Session == i).Max(t => t.EndSector) }); + } AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Memory_snapshot_0_bytes, GC.GetTotalMemory(false)); @@ -1519,8 +1531,10 @@ public sealed partial class AaruFormat trk.BytesPerSector = sector.Length; trk.RawBytesPerSector = - (_sectorPrefix != null && _sectorSuffix != null) || - (_sectorPrefixDdt != null && _sectorSuffixDdt != null) ? 2352 : sector.Length; + _sectorPrefix != null && _sectorSuffix != null || + _sectorPrefixDdt != null && _sectorSuffixDdt != null + ? 2352 + : sector.Length; if(_sectorSubchannel == null) continue; @@ -1539,6 +1553,7 @@ public sealed partial class AaruFormat GC.GetTotalMemory(false)); if(compactDiscIndexes != null) + { foreach(CompactDiscIndexEntry compactDiscIndex in compactDiscIndexes.OrderBy(i => i.Track). ThenBy(i => i.Index)) { @@ -1549,6 +1564,7 @@ public sealed partial class AaruFormat track.Indexes[compactDiscIndex.Index] = compactDiscIndex.Lba; } + } } else { @@ -1569,13 +1585,20 @@ public sealed partial class AaruFormat return ErrorNumber.NoError; if(_imageInfo.MediaType is MediaType.CD or MediaType.CDDA or MediaType.CDG or MediaType.CDEG or MediaType.CDI - or MediaType.CDROM or MediaType.CDROMXA or MediaType.CDPLUS or MediaType.CDMO or MediaType.CDR - or MediaType.CDRW or MediaType.CDMRW or MediaType.VCD or MediaType.SVCD or MediaType.PCD or MediaType.DTSCD - or MediaType.CDMIDI or MediaType.CDV or MediaType.CDIREADY or MediaType.FMTOWNS or MediaType.PS1CD - or MediaType.PS2CD or MediaType.MEGACD or MediaType.SATURNCD or MediaType.GDROM or MediaType.GDR - or MediaType.MilCD or MediaType.SuperCDROM2 or MediaType.JaguarCD or MediaType.ThreeDO or MediaType.PCFX - or MediaType.NeoGeoCD or MediaType.CDTV or MediaType.CD32 or MediaType.Playdia or MediaType.Pippin - or MediaType.VideoNow or MediaType.VideoNowColor or MediaType.VideoNowXp or MediaType.CVD) + or MediaType.CDROM or MediaType.CDROMXA or MediaType.CDPLUS or MediaType.CDMO + or MediaType.CDR + or MediaType.CDRW or MediaType.CDMRW or MediaType.VCD or MediaType.SVCD or MediaType.PCD + or MediaType.DTSCD + or MediaType.CDMIDI or MediaType.CDV or MediaType.CDIREADY or MediaType.FMTOWNS + or MediaType.PS1CD + or MediaType.PS2CD or MediaType.MEGACD or MediaType.SATURNCD or MediaType.GDROM + or MediaType.GDR + or MediaType.MilCD or MediaType.SuperCDROM2 or MediaType.JaguarCD or MediaType.ThreeDO + or MediaType.PCFX + or MediaType.NeoGeoCD or MediaType.CDTV or MediaType.CD32 or MediaType.Playdia + or MediaType.Pippin + or MediaType.VideoNow or MediaType.VideoNowColor or MediaType.VideoNowXp + or MediaType.CVD) return ErrorNumber.NoError; { @@ -1606,7 +1629,7 @@ public sealed partial class AaruFormat return ErrorNumber.OutOfRange; ulong ddtEntry = GetDdtEntry(sectorAddress); - uint offsetMask = (uint)((1 << _shift) - 1); + var offsetMask = (uint)((1 << _shift) - 1); ulong offset = ddtEntry & offsetMask; ulong blockOffset = ddtEntry >> _shift; @@ -1651,9 +1674,9 @@ public sealed partial class AaruFormat break; case CompressionType.Lzma: - byte[] compressedBlock = new byte[blockHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; - byte[] lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; - _imageStream.EnsureRead(lzmaProperties, 0, LZMA_PROPERTIES_LENGTH); + var compressedBlock = new byte[blockHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; + var lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; + _imageStream.EnsureRead(lzmaProperties, 0, LZMA_PROPERTIES_LENGTH); _imageStream.EnsureRead(compressedBlock, 0, compressedBlock.Length); block = new byte[blockHeader.length]; decompressedLength = (ulong)LZMA.DecodeBuffer(compressedBlock, block, lzmaProperties); @@ -1672,7 +1695,7 @@ public sealed partial class AaruFormat break; case CompressionType.Flac: - byte[] flacBlock = new byte[blockHeader.cmpLength]; + var flacBlock = new byte[blockHeader.cmpLength]; _imageStream.EnsureRead(flacBlock, 0, flacBlock.Length); block = new byte[blockHeader.length]; decompressedLength = (ulong)FLAC.DecodeBuffer(flacBlock, block); @@ -1690,7 +1713,8 @@ public sealed partial class AaruFormat GC.GetTotalMemory(false)); break; - default: return ErrorNumber.NotSupported; + default: + return ErrorNumber.NotSupported; } // Check if cache needs to be emptied @@ -1729,7 +1753,8 @@ public sealed partial class AaruFormat Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); - return trk?.Sequence != track ? ErrorNumber.SectorNotFound + return trk?.Sequence != track + ? ErrorNumber.SectorNotFound : ReadSector(trk.StartSector + sectorAddress, out buffer); } @@ -1743,7 +1768,8 @@ public sealed partial class AaruFormat Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); - return trk?.Sequence != track ? ErrorNumber.SectorNotFound + return trk?.Sequence != track + ? ErrorNumber.SectorNotFound : ReadSectorTag(trk.StartSector + sectorAddress, tag, out buffer); } @@ -1812,15 +1838,13 @@ public sealed partial class AaruFormat case SectorTagType.DvdSectorNumber: case SectorTagType.DvdSectorIed: case SectorTagType.DvdSectorEdc: - case SectorTagType.DvdTitleKeyDecrypted: break; + case SectorTagType.DvdTitleKeyDecrypted: + break; case SectorTagType.CdTrackFlags: if(!_trackFlags.TryGetValue((byte)sectorAddress, out byte flags)) return ErrorNumber.NoData; - buffer = new[] - { - flags - }; + buffer = new[] { flags }; return ErrorNumber.NoError; case SectorTagType.CdTrackIsrc: @@ -1830,7 +1854,8 @@ public sealed partial class AaruFormat buffer = Encoding.UTF8.GetBytes(isrc); return ErrorNumber.NoError; - default: return ErrorNumber.NotSupported; + default: + return ErrorNumber.NotSupported; } switch(trk.Type) @@ -1858,7 +1883,8 @@ public sealed partial class AaruFormat break; } - case SectorTagType.CdSectorSubHeader: return ErrorNumber.NotSupported; + case SectorTagType.CdSectorSubHeader: + return ErrorNumber.NotSupported; case SectorTagType.CdSectorEcc: { sectorOffset = 12; @@ -1909,7 +1935,8 @@ public sealed partial class AaruFormat break; } - default: return ErrorNumber.NotSupported; + default: + return ErrorNumber.NotSupported; } break; @@ -1953,7 +1980,8 @@ public sealed partial class AaruFormat case SectorTagType.CdSectorEcc: case SectorTagType.CdSectorEccP: case SectorTagType.CdSectorEccQ: - case SectorTagType.CdSectorEdc: return ErrorNumber.NotSupported; + case SectorTagType.CdSectorEdc: + return ErrorNumber.NotSupported; case SectorTagType.CdSectorSubchannel: { sectorOffset = 0; @@ -1964,7 +1992,8 @@ public sealed partial class AaruFormat break; } - default: return ErrorNumber.NotSupported; + default: + return ErrorNumber.NotSupported; } break; @@ -1984,7 +2013,8 @@ public sealed partial class AaruFormat break; } - default: return ErrorNumber.NotSupported; + default: + return ErrorNumber.NotSupported; } break; @@ -1993,6 +2023,7 @@ public sealed partial class AaruFormat case TrackType.Data: { if(_imageInfo.MediaType == MediaType.DVDROM) + { switch(tag) { case SectorTagType.DvdSectorCmi: @@ -2058,15 +2089,18 @@ public sealed partial class AaruFormat break; } - default: return ErrorNumber.NotSupported; + default: + return ErrorNumber.NotSupported; } + } else return ErrorNumber.NotSupported; break; } - default: return ErrorNumber.NotSupported; + default: + return ErrorNumber.NotSupported; } } else @@ -2085,9 +2119,11 @@ public sealed partial class AaruFormat return ErrorNumber.NoError; } - for(int i = 0; i < length; i++) - Array.Copy(dataSource, (long)((sectorAddress * (sectorOffset + sectorSize + sectorSkip)) + sectorOffset), + for(var i = 0; i < length; i++) + { + Array.Copy(dataSource, (long)(sectorAddress * (sectorOffset + sectorSize + sectorSkip) + sectorOffset), buffer, i * sectorSize, sectorSize); + } return ErrorNumber.NoError; } @@ -2105,12 +2141,13 @@ public sealed partial class AaruFormat if(trk?.Sequence != track) return ErrorNumber.SectorNotFound; - return trk.StartSector + sectorAddress + length > trk.EndSector + 1 ? ErrorNumber.OutOfRange + return trk.StartSector + sectorAddress + length > trk.EndSector + 1 + ? ErrorNumber.OutOfRange : ReadSectors(trk.StartSector + sectorAddress, length, out buffer); } /// - public ErrorNumber ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag, + public ErrorNumber ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag, out byte[] buffer) { buffer = null; @@ -2306,7 +2343,7 @@ public sealed partial class AaruFormat else if(_mode2Subheaders != null) { Array.Copy(_mode2Subheaders, (int)sectorAddress * 8, buffer, 16, 8); - Array.Copy(data, 0, buffer, 24, 2328); + Array.Copy(data, 0, buffer, 24, 2328); } else Array.Copy(data, 0, buffer, 16, 2336); @@ -2323,7 +2360,8 @@ public sealed partial class AaruFormat case MediaType.AppleSonySS: case MediaType.AppleSonyDS: case MediaType.AppleWidget: - case MediaType.PriamDataTower: return ReadSectorsLong(sectorAddress, 1, out buffer); + case MediaType.PriamDataTower: + return ReadSectorsLong(sectorAddress, 1, out buffer); } break; @@ -2342,7 +2380,8 @@ public sealed partial class AaruFormat Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); - return trk?.Sequence != track ? ErrorNumber.SectorNotFound + return trk?.Sequence != track + ? ErrorNumber.SectorNotFound : ReadSectorLong(trk.StartSector + sectorAddress, out buffer); } @@ -2373,7 +2412,8 @@ public sealed partial class AaruFormat { // These types only contain user data case TrackType.Audio: - case TrackType.Data: return ReadSectors(sectorAddress, length, out buffer); + case TrackType.Data: + return ReadSectors(sectorAddress, length, out buffer); // Join prefix (sync, header) with user data with suffix (edc, ecc p, ecc q) case TrackType.CdMode1: @@ -2505,7 +2545,7 @@ public sealed partial class AaruFormat for(uint i = 0; i < length; i++) { Array.Copy(_sectorSubchannel, (int)((sectorAddress + i) * tagSize), buffer, - (int)((i * sectorSize) + 512), tagSize); + (int)(i * sectorSize + 512), tagSize); Array.Copy(data, (int)((sectorAddress + i) * 512), buffer, (int)(i * 512), 512); } @@ -2541,4 +2581,6 @@ public sealed partial class AaruFormat /// public List GetSessionTracks(ushort session) => Tracks.Where(t => t.Sequence == session).ToList(); + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/Structs.cs b/Aaru.Images/AaruFormat/Structs.cs index 5bf972d95..fd5ceae3a 100644 --- a/Aaru.Images/AaruFormat/Structs.cs +++ b/Aaru.Images/AaruFormat/Structs.cs @@ -38,6 +38,8 @@ namespace Aaru.DiscImages; public sealed partial class AaruFormat { +#region Nested type: AaruHeader + /// Header, at start of file [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)] struct AaruHeader @@ -65,6 +67,131 @@ public sealed partial class AaruFormat public long lastWrittenTime; } +#endregion + +#region Nested type: AaruMetadataJsonBlock + + /// Aaru Metadata JSON block + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AaruMetadataJsonBlock + { + /// Identifier, + public BlockType identifier; + public uint length; + } + +#endregion + +#region Nested type: BlockHeader + + /// Block header, precedes block data + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct BlockHeader + { + /// Identifier, + public BlockType identifier; + /// Type of data contained by this block + public DataType type; + /// Compression algorithm used to compress the block + public CompressionType compression; + /// Size in bytes of each sector contained in this block + public uint sectorSize; + /// Compressed length for the block + public uint cmpLength; + /// Uncompressed length for the block + public uint length; + /// CRC64-ECMA of the compressed block + public ulong cmpCrc64; + /// CRC64-ECMA of the uncompressed block + public ulong crc64; + } + +#endregion + +#region Nested type: ChecksumEntry + + /// Checksum entry, followed by checksum data itself + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct ChecksumEntry + { + /// Checksum algorithm + public ChecksumAlgorithm type; + /// Length in bytes of checksum that follows this structure + public uint length; + } + +#endregion + +#region Nested type: ChecksumHeader + + /// + /// Checksum block, contains a checksum of all user data sectors (except for optical discs that is 2352 bytes raw + /// sector if available + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct ChecksumHeader + { + /// Identifier, + public BlockType identifier; + /// Length in bytes of the block + public uint length; + /// How many checksums follow + public byte entries; + } + +#endregion + +#region Nested type: CicmMetadataBlock + + /// CICM Metadata XML block + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CicmMetadataBlock + { + /// Identifier, + public readonly BlockType identifier; + public readonly uint length; + } + +#endregion + +#region Nested type: CompactDiscIndexEntry + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CompactDiscIndexEntry + { + /// How many entries follow this header + public ushort Track; + /// Size of the whole block, not including this header, in bytes + public ushort Index; + /// CRC64-ECMA of the block + public int Lba; + } + +#endregion + +#region Nested type: CompactDiscIndexesHeader + + /// + /// Compact Disc track indexes block, contains a cache of all Compact Disc indexes to not need to interpret + /// subchannel + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CompactDiscIndexesHeader + { + /// Identifier, + public BlockType identifier; + /// How many entries follow this header + public ushort entries; + /// Size of the whole block, not including this header, in bytes + public readonly ulong length; + /// CRC64-ECMA of the block + public ulong crc64; + } + +#endregion + +#region Nested type: DdtHeader + /// Header for a deduplication table. Table follows it [StructLayout(LayoutKind.Sequential, Pack = 1)] struct DdtHeader @@ -89,30 +216,71 @@ public sealed partial class AaruFormat public readonly ulong crc64; } - /// Header for the index, followed by entries +#endregion + +#region Nested type: DumpHardwareEntry + + /// Dump hardware entry, contains length of strings that follow, in the same order as the length, this structure [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct IndexHeader + struct DumpHardwareEntry { - /// Identifier, + /// Length of UTF-8 manufacturer string + public uint manufacturerLength; + /// Length of UTF-8 model string + public uint modelLength; + /// Length of UTF-8 revision string + public uint revisionLength; + /// Length of UTF-8 firmware version string + public uint firmwareLength; + /// Length of UTF-8 serial string + public uint serialLength; + /// Length of UTF-8 software name string + public uint softwareNameLength; + /// Length of UTF-8 software version string + public uint softwareVersionLength; + /// Length of UTF-8 software operating system string + public uint softwareOperatingSystemLength; + /// How many extents are after the strings + public uint extents; + } + +#endregion + +#region Nested type: DumpHardwareHeader + + /// Dump hardware block, contains a list of hardware used to dump the media on this image + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct DumpHardwareHeader + { + /// Identifier, public BlockType identifier; /// How many entries follow this header public ushort entries; - /// CRC64-ECMA of the index + /// Size of the whole block, not including this header, in bytes + public uint length; + /// CRC64-ECMA of the block public ulong crc64; } - /// Header for the index, followed by entries +#endregion + +#region Nested type: GeometryBlock + + /// Geometry block, contains physical geometry information [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct IndexHeader2 + struct GeometryBlock { - /// Identifier, + /// Identifier, public BlockType identifier; - /// How many entries follow this header - public ulong entries; - /// CRC64-ECMA of the index - public ulong crc64; + public uint cylinders; + public uint heads; + public uint sectorsPerTrack; } +#endregion + +#region Nested type: IndexEntry + /// Index entry [StructLayout(LayoutKind.Sequential, Pack = 1)] struct IndexEntry @@ -125,39 +293,42 @@ public sealed partial class AaruFormat public ulong offset; } - /// Block header, precedes block data +#endregion + +#region Nested type: IndexHeader + + /// Header for the index, followed by entries [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct BlockHeader + struct IndexHeader { - /// Identifier, + /// Identifier, public BlockType identifier; - /// Type of data contained by this block - public DataType type; - /// Compression algorithm used to compress the block - public CompressionType compression; - /// Size in bytes of each sector contained in this block - public uint sectorSize; - /// Compressed length for the block - public uint cmpLength; - /// Uncompressed length for the block - public uint length; - /// CRC64-ECMA of the compressed block - public ulong cmpCrc64; - /// CRC64-ECMA of the uncompressed block + /// How many entries follow this header + public ushort entries; + /// CRC64-ECMA of the index public ulong crc64; } - /// Geometry block, contains physical geometry information +#endregion + +#region Nested type: IndexHeader2 + + /// Header for the index, followed by entries [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct GeometryBlock + struct IndexHeader2 { - /// Identifier, + /// Identifier, public BlockType identifier; - public uint cylinders; - public uint heads; - public uint sectorsPerTrack; + /// How many entries follow this header + public ulong entries; + /// CRC64-ECMA of the index + public ulong crc64; } +#endregion + +#region Nested type: MetadataBlock + /// Metadata block, contains metadata [StructLayout(LayoutKind.Sequential, Pack = 1)] struct MetadataBlock @@ -220,18 +391,80 @@ public sealed partial class AaruFormat public uint driveFirmwareRevisionLength; } - /// Contains list of optical disc tracks +#endregion + +#region Nested type: TapeFileEntry + + /// Tape file entry [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct TracksHeader + struct TapeFileEntry { - /// Identifier, + /// File number + public uint File; + /// Partition number + public readonly byte Partition; + /// First block, inclusive, of the file + public ulong FirstBlock; + /// Last block, inclusive, of the file + public ulong LastBlock; + } + +#endregion + +#region Nested type: TapeFileHeader + + /// Tape file block, contains a list of all files in a tape + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct TapeFileHeader + { + /// Identifier, public BlockType identifier; /// How many entries follow this header - public ushort entries; + public uint entries; + /// Size of the whole block, not including this header, in bytes + public ulong length; /// CRC64-ECMA of the block public ulong crc64; } +#endregion + +#region Nested type: TapePartitionEntry + + /// Tape partition entry + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct TapePartitionEntry + { + /// Partition number + public byte Number; + /// First block, inclusive, of the partition + public ulong FirstBlock; + /// Last block, inclusive, of the partition + public ulong LastBlock; + } + +#endregion + +#region Nested type: TapePartitionHeader + + /// Tape partition block, contains a list of all partitions in a tape + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct TapePartitionHeader + { + /// Identifier, + public BlockType identifier; + /// How many entries follow this header + public byte entries; + /// Size of the whole block, not including this header, in bytes + public ulong length; + /// CRC64-ECMA of the block + public ulong crc64; + } + +#endregion + +#region Nested type: TrackEntry + /// Optical disc track [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] struct TrackEntry @@ -255,166 +488,21 @@ public sealed partial class AaruFormat public byte flags; } - /// CICM Metadata XML block - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct CicmMetadataBlock - { - /// Identifier, - public readonly BlockType identifier; - public readonly uint length; - } +#endregion - /// Aaru Metadata JSON block - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AaruMetadataJsonBlock - { - /// Identifier, - public BlockType identifier; - public uint length; - } +#region Nested type: TracksHeader - /// Dump hardware block, contains a list of hardware used to dump the media on this image + /// Contains list of optical disc tracks [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct DumpHardwareHeader + struct TracksHeader { - /// Identifier, + /// Identifier, public BlockType identifier; /// How many entries follow this header public ushort entries; - /// Size of the whole block, not including this header, in bytes - public uint length; /// CRC64-ECMA of the block public ulong crc64; } - /// Dump hardware entry, contains length of strings that follow, in the same order as the length, this structure - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct DumpHardwareEntry - { - /// Length of UTF-8 manufacturer string - public uint manufacturerLength; - /// Length of UTF-8 model string - public uint modelLength; - /// Length of UTF-8 revision string - public uint revisionLength; - /// Length of UTF-8 firmware version string - public uint firmwareLength; - /// Length of UTF-8 serial string - public uint serialLength; - /// Length of UTF-8 software name string - public uint softwareNameLength; - /// Length of UTF-8 software version string - public uint softwareVersionLength; - /// Length of UTF-8 software operating system string - public uint softwareOperatingSystemLength; - /// How many extents are after the strings - public uint extents; - } - - /// - /// Checksum block, contains a checksum of all user data sectors (except for optical discs that is 2352 bytes raw - /// sector if available - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct ChecksumHeader - { - /// Identifier, - public BlockType identifier; - /// Length in bytes of the block - public uint length; - /// How many checksums follow - public byte entries; - } - - /// Checksum entry, followed by checksum data itself - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct ChecksumEntry - { - /// Checksum algorithm - public ChecksumAlgorithm type; - /// Length in bytes of checksum that follows this structure - public uint length; - } - - /// Tape file block, contains a list of all files in a tape - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct TapeFileHeader - { - /// Identifier, - public BlockType identifier; - /// How many entries follow this header - public uint entries; - /// Size of the whole block, not including this header, in bytes - public ulong length; - /// CRC64-ECMA of the block - public ulong crc64; - } - - /// Tape file entry - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct TapeFileEntry - { - /// File number - public uint File; - /// Partition number - public readonly byte Partition; - /// First block, inclusive, of the file - public ulong FirstBlock; - /// Last block, inclusive, of the file - public ulong LastBlock; - } - - /// Tape partition block, contains a list of all partitions in a tape - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct TapePartitionHeader - { - /// Identifier, - public BlockType identifier; - /// How many entries follow this header - public byte entries; - /// Size of the whole block, not including this header, in bytes - public ulong length; - /// CRC64-ECMA of the block - public ulong crc64; - } - - /// Tape partition entry - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct TapePartitionEntry - { - /// Partition number - public byte Number; - /// First block, inclusive, of the partition - public ulong FirstBlock; - /// Last block, inclusive, of the partition - public ulong LastBlock; - } - - /// - /// Compact Disc track indexes block, contains a cache of all Compact Disc indexes to not need to interpret - /// subchannel - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct CompactDiscIndexesHeader - { - /// Identifier, - public BlockType identifier; - /// How many entries follow this header - public ushort entries; - /// Size of the whole block, not including this header, in bytes - public readonly ulong length; - /// CRC64-ECMA of the block - public ulong crc64; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct CompactDiscIndexEntry - { - /// How many entries follow this header - public ushort Track; - /// Size of the whole block, not including this header, in bytes - public ushort Index; - /// CRC64-ECMA of the block - public int Lba; - } +#endregion } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/Tape.cs b/Aaru.Images/AaruFormat/Tape.cs index 776a62398..503248d7d 100644 --- a/Aaru.Images/AaruFormat/Tape.cs +++ b/Aaru.Images/AaruFormat/Tape.cs @@ -38,10 +38,14 @@ namespace Aaru.DiscImages; public sealed partial class AaruFormat { +#region IWritableTapeImage Members + /// public List Files { get; private set; } + /// public List TapePartitions { get; private set; } + /// public bool IsTape { get; private set; } @@ -81,4 +85,6 @@ public sealed partial class AaruFormat return IsTape = true; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/Verify.cs b/Aaru.Images/AaruFormat/Verify.cs index 151e1d016..901ccb494 100644 --- a/Aaru.Images/AaruFormat/Verify.cs +++ b/Aaru.Images/AaruFormat/Verify.cs @@ -41,6 +41,8 @@ namespace Aaru.DiscImages; public sealed partial class AaruFormat { +#region IVerifiableImage Members + /// public bool? VerifyMediaImage() { @@ -209,6 +211,10 @@ public sealed partial class AaruFormat return true; } +#endregion + +#region IWritableOpticalImage Members + /// public bool? VerifySector(ulong sectorAddress) { @@ -221,7 +227,7 @@ public sealed partial class AaruFormat } /// - public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, + public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, out List unknownLbas) { failingLbas = new List(); @@ -241,12 +247,12 @@ public sealed partial class AaruFormat if(errno != ErrorNumber.NoError) return null; - int bps = (int)(buffer.Length / length); - byte[] sector = new byte[bps]; + var bps = (int)(buffer.Length / length); + var sector = new byte[bps]; failingLbas = new List(); unknownLbas = new List(); - for(int i = 0; i < length; i++) + for(var i = 0; i < length; i++) { Array.Copy(buffer, i * bps, sector, 0, bps); bool? sectorStatus = CdChecksums.CheckCdSector(sector); @@ -271,7 +277,7 @@ public sealed partial class AaruFormat } /// - public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, + public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, out List unknownLbas) { // Right now only CompactDisc sectors are verifiable @@ -294,10 +300,10 @@ public sealed partial class AaruFormat if(errno != ErrorNumber.NoError) return null; - int bps = (int)(buffer.Length / length); - byte[] sector = new byte[bps]; + var bps = (int)(buffer.Length / length); + var sector = new byte[bps]; - for(int i = 0; i < length; i++) + for(var i = 0; i < length; i++) { Array.Copy(buffer, i * bps, sector, 0, bps); bool? sectorStatus = CdChecksums.CheckCdSector(sector); @@ -320,4 +326,6 @@ public sealed partial class AaruFormat return failingLbas.Count <= 0; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/AaruFormat/Write.cs b/Aaru.Images/AaruFormat/Write.cs index 5c34a6a19..4dff02758 100644 --- a/Aaru.Images/AaruFormat/Write.cs +++ b/Aaru.Images/AaruFormat/Write.cs @@ -65,9 +65,11 @@ namespace Aaru.DiscImages; public sealed partial class AaruFormat { +#region IWritableOpticalImage Members + /// public bool Create(string path, MediaType mediaType, Dictionary options, ulong sectors, - uint sectorSize) + uint sectorSize) { uint sectorsPerBlock; uint maxDdtSize; @@ -346,7 +348,7 @@ public sealed partial class AaruFormat // Invalidate previous checksum block _index.RemoveAll(t => t is { blockType: BlockType.ChecksumBlock, dataType: DataType.NoData }); - bool foundUserDataDdt = false; + var foundUserDataDdt = false; foreach(IndexEntry entry in _index) { @@ -400,7 +402,7 @@ public sealed partial class AaruFormat // Decompress media tag if(blockHeader.compression is CompressionType.Lzma - or CompressionType.LzmaClauniaSubchannelTransform) + or CompressionType.LzmaClauniaSubchannelTransform) { if(blockHeader.compression == CompressionType.LzmaClauniaSubchannelTransform && entry.dataType != DataType.CdSectorSubchannel) @@ -415,10 +417,10 @@ public sealed partial class AaruFormat var decompressStopwatch = new Stopwatch(); decompressStopwatch.Restart(); - byte[] compressedTag = new byte[blockHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; - byte[] lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; + var compressedTag = new byte[blockHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; + var lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; _imageStream.EnsureRead(lzmaProperties, 0, LZMA_PROPERTIES_LENGTH); - _imageStream.EnsureRead(compressedTag, 0, compressedTag.Length); + _imageStream.EnsureRead(compressedTag, 0, compressedTag.Length); data = new byte[blockHeader.length]; int decompressedLength = LZMA.DecodeBuffer(compressedTag, data, lzmaProperties); @@ -618,8 +620,10 @@ public sealed partial class AaruFormat { ErrorMessage = string. - Format(Localization.Trying_to_write_a_media_with_0_sectors_to_an_image_with_1_sectors_not_continuing, - _imageInfo.Sectors, ddtHeader.entries); + Format( + Localization. + Trying_to_write_a_media_with_0_sectors_to_an_image_with_1_sectors_not_continuing, + _imageInfo.Sectors, ddtHeader.entries); return false; } @@ -634,22 +638,24 @@ public sealed partial class AaruFormat var ddtStopwatch = new Stopwatch(); ddtStopwatch.Start(); - byte[] compressedDdt = new byte[ddtHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; + var compressedDdt = new byte[ddtHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; - byte[] lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; + var lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; _imageStream.EnsureRead(lzmaProperties, 0, LZMA_PROPERTIES_LENGTH); - _imageStream.EnsureRead(compressedDdt, 0, compressedDdt.Length); - byte[] decompressedDdt = new byte[ddtHeader.length]; + _imageStream.EnsureRead(compressedDdt, 0, compressedDdt.Length); + var decompressedDdt = new byte[ddtHeader.length]; - ulong decompressedLength = + var decompressedLength = (ulong)LZMA.DecodeBuffer(compressedDdt, decompressedDdt, lzmaProperties); if(decompressedLength != ddtHeader.length) { ErrorMessage = string. - Format(Localization.Error_decompressing_DDT_should_be_0_bytes_but_got_1_bytes, - ddtHeader.length, decompressedLength); + Format( + Localization. + Error_decompressing_DDT_should_be_0_bytes_but_got_1_bytes, + ddtHeader.length, decompressedLength); return false; } @@ -701,13 +707,15 @@ public sealed partial class AaruFormat { ErrorMessage = string. - Format(Localization.Trying_to_write_a_media_with_0_sectors_to_an_image_with_1_sectors_not_continuing, - _imageInfo.Sectors, ddtHeader.entries); + Format( + Localization. + Trying_to_write_a_media_with_0_sectors_to_an_image_with_1_sectors_not_continuing, + _imageInfo.Sectors, ddtHeader.entries); return false; } - byte[] decompressedDdt = new byte[ddtHeader.length]; + var decompressedDdt = new byte[ddtHeader.length]; switch(ddtHeader.compression) { @@ -717,21 +725,23 @@ public sealed partial class AaruFormat var ddtStopwatch = new Stopwatch(); ddtStopwatch.Start(); - byte[] compressedDdt = new byte[ddtHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; + var compressedDdt = new byte[ddtHeader.cmpLength - LZMA_PROPERTIES_LENGTH]; - byte[] lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; + var lzmaProperties = new byte[LZMA_PROPERTIES_LENGTH]; _imageStream.EnsureRead(lzmaProperties, 0, LZMA_PROPERTIES_LENGTH); - _imageStream.EnsureRead(compressedDdt, 0, compressedDdt.Length); + _imageStream.EnsureRead(compressedDdt, 0, compressedDdt.Length); - ulong decompressedLength = + var decompressedLength = (ulong)LZMA.DecodeBuffer(compressedDdt, decompressedDdt, lzmaProperties); if(decompressedLength != ddtHeader.length) { ErrorMessage = string. - Format(Localization.Error_decompressing_DDT_should_be_0_bytes_but_got_1_bytes, - ddtHeader.length, decompressedLength); + Format( + Localization. + Error_decompressing_DDT_should_be_0_bytes_but_got_1_bytes, + ddtHeader.length, decompressedLength); return false; } @@ -815,7 +825,7 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Found_metadata_block_at_position_0, entry.offset); - byte[] metadata = new byte[metadataBlock.blockSize]; + var metadata = new byte[metadataBlock.blockSize]; _imageStream.Position = (long)entry.offset; _imageStream.EnsureRead(metadata, 0, metadata.Length); @@ -1070,23 +1080,23 @@ public sealed partial class AaruFormat Localization.Found_CICM_XML_metadata_block_at_position_0, entry.offset); - byte[] cicmBytes = new byte[cicmBlock.length]; + var cicmBytes = new byte[cicmBlock.length]; _imageStream.EnsureRead(cicmBytes, 0, cicmBytes.Length); var cicmMs = new MemoryStream(cicmBytes); // The converter to AaruMetadata basically overcomes this (should?) - #pragma warning disable IL2026 + #pragma warning disable IL2026 var cicmXs = new XmlSerializer(typeof(CICMMetadataType)); - #pragma warning restore IL2026 + #pragma warning restore IL2026 try { var sr = new StreamReader(cicmMs); // The converter to AaruMetadata basically overcomes this (should?) - #pragma warning disable IL2026 + #pragma warning disable IL2026 AaruMetadata = (CICMMetadataType)cicmXs.Deserialize(sr); - #pragma warning restore IL2026 + #pragma warning restore IL2026 sr.Close(); } catch(XmlException ex) @@ -1117,7 +1127,7 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Memory_snapshot_0_bytes, GC.GetTotalMemory(false)); - byte[] jsonBytes = new byte[aaruMetadataBlock.length]; + var jsonBytes = new byte[aaruMetadataBlock.length]; _imageStream.EnsureRead(jsonBytes, 0, jsonBytes.Length); try @@ -1290,7 +1300,7 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Found_tape_partition_block_at_position_0, entry.offset); - byte[] tapePartitionBytes = new byte[partitionHeader.length]; + var tapePartitionBytes = new byte[partitionHeader.length]; _imageStream.EnsureRead(tapePartitionBytes, 0, tapePartitionBytes.Length); Span tapePartitions = @@ -1299,12 +1309,14 @@ public sealed partial class AaruFormat TapePartitions = new List(); foreach(TapePartitionEntry tapePartition in tapePartitions) + { TapePartitions.Add(new TapePartition { FirstBlock = tapePartition.FirstBlock, LastBlock = tapePartition.LastBlock, Number = tapePartition.Number }); + } IsTape = true; @@ -1324,12 +1336,13 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Found_tape_file_block_at_position_0, entry.offset); - byte[] tapeFileBytes = new byte[fileHeader.length]; + var tapeFileBytes = new byte[fileHeader.length]; _imageStream.EnsureRead(tapeFileBytes, 0, tapeFileBytes.Length); Span tapeFiles = MemoryMarshal.Cast(tapeFileBytes); Files = new List(); foreach(TapeFileEntry file in tapeFiles) + { Files.Add(new TapeFile { FirstBlock = file.FirstBlock, @@ -1337,6 +1350,7 @@ public sealed partial class AaruFormat Partition = file.Partition, File = file.File }); + } IsTape = true; @@ -1426,7 +1440,7 @@ public sealed partial class AaruFormat if(Tracks != null && _mediaTags.TryGetValue(MediaTagType.CD_FullTOC, out byte[] fullToc)) { - byte[] tmp = new byte[fullToc.Length + 2]; + var tmp = new byte[fullToc.Length + 2]; Array.Copy(fullToc, 0, tmp, 2, fullToc.Length); tmp[0] = (byte)(fullToc.Length >> 8); tmp[1] = (byte)(fullToc.Length & 0xFF); @@ -1477,8 +1491,8 @@ public sealed partial class AaruFormat phour = trk.PHOUR; } - int lastSector = (phour * 3600 * 75) + (pmin * 60 * 75) + (psec * 75) + pframe - 150; - leadOutStarts?.Add(trk.SessionNumber, lastSector + 1); + int lastSector = phour * 3600 * 75 + pmin * 60 * 75 + psec * 75 + pframe - 150; + leadOutStarts?.Add(trk.SessionNumber, lastSector + 1); } foreach(KeyValuePair leadOuts in leadOutStarts) @@ -1520,9 +1534,7 @@ public sealed partial class AaruFormat _trackFlags = new Dictionary { - { - 1, (byte)CdFlags.DataTrack - } + { 1, (byte)CdFlags.DataTrack } }; _trackIsrcs = new Dictionary(); @@ -1533,7 +1545,8 @@ public sealed partial class AaruFormat Sessions = new List(); - for(int i = 1; i <= Tracks.Max(t => t.Session); i++) + for(var i = 1; i <= Tracks.Max(t => t.Session); i++) + { Sessions.Add(new Session { Sequence = (ushort)i, @@ -1542,6 +1555,7 @@ public sealed partial class AaruFormat StartSector = Tracks.Where(t => t.Session == i).Min(t => t.StartSector), EndSector = Tracks.Where(t => t.Session == i).Max(t => t.EndSector) }); + } AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Memory_snapshot_0_bytes, GC.GetTotalMemory(false)); @@ -1601,8 +1615,10 @@ public sealed partial class AaruFormat trk.BytesPerSector = sector.Length; trk.RawBytesPerSector = - (_sectorPrefix != null && _sectorSuffix != null) || - (_sectorPrefixDdt != null && _sectorSuffixDdt != null) ? 2352 : sector.Length; + _sectorPrefix != null && _sectorSuffix != null || + _sectorPrefixDdt != null && _sectorSuffixDdt != null + ? 2352 + : sector.Length; if(_sectorSubchannel == null) continue; @@ -1621,6 +1637,7 @@ public sealed partial class AaruFormat GC.GetTotalMemory(false)); if(compactDiscIndexes != null) + { foreach(CompactDiscIndexEntry compactDiscIndex in compactDiscIndexes.OrderBy(i => i.Track). ThenBy(i => i.Index)) { @@ -1631,6 +1648,7 @@ public sealed partial class AaruFormat track.Indexes[compactDiscIndex.Index] = compactDiscIndex.Lba; } + } } else { @@ -1822,7 +1840,7 @@ public sealed partial class AaruFormat _currentBlockOffset == 1 << _shift || // When we change to/from CompactDisc audio - (_currentBlockHeader.compression == CompressionType.Flac && trk.Type != TrackType.Audio))) + _currentBlockHeader.compression == CompressionType.Flac && trk.Type != TrackType.Audio)) { _currentBlockHeader.length = _currentBlockOffset * _currentBlockHeader.sectorSize; _currentBlockHeader.crc64 = BitConverter.ToUInt64(_crc64.Final(), 0); @@ -1830,7 +1848,7 @@ public sealed partial class AaruFormat var cmpCrc64Context = new Crc64Context(); byte[] lzmaProperties = Array.Empty(); - int compressedLength = 0; + var compressedLength = 0; switch(_currentBlockHeader.compression) { @@ -1849,8 +1867,10 @@ public sealed partial class AaruFormat // Fill FLAC block if(remaining != 0) - for(int r = 0; r < remaining * 4; r++) + { + for(var r = 0; r < remaining * 4; r++) _writingBuffer[_writingBufferPosition + r] = 0; + } compressedLength = FLAC.EncodeBuffer(_writingBuffer, _compressedBuffer, flacBlockSize, true, false, "hamming", 12, 15, true, false, 0, 8, "Aaru"); @@ -1872,8 +1892,10 @@ public sealed partial class AaruFormat break; } - case CompressionType.None: break; // Do nothing - default: throw new ArgumentOutOfRangeException(); + case CompressionType.None: + break; // Do nothing + default: + throw new ArgumentOutOfRangeException(); } if(_currentBlockHeader.compression == CompressionType.None) @@ -1934,14 +1956,14 @@ public sealed partial class AaruFormat // JaguarCD stores data in audio tracks. FLAC is too inefficient, use LZMA there. // VideoNow stores video in audio tracks, and LZMA works better too. - if(((_imageInfo.MediaType == MediaType.JaguarCD && trk.Session > 1) || + if((_imageInfo.MediaType == MediaType.JaguarCD && trk.Session > 1 || _imageInfo.MediaType is MediaType.VideoNow or MediaType.VideoNowColor or MediaType.VideoNowXp) && trk.Type == TrackType.Audio && _compress && _currentBlockHeader.compression == CompressionType.Flac) _currentBlockHeader.compression = CompressionType.Lzma; - int maxBufferSize = ((1 << _shift) * data.Length) + (MAX_FLAKE_BLOCK * 4); + int maxBufferSize = (1 << _shift) * data.Length + MAX_FLAKE_BLOCK * 4; if(_writingBuffer == null || _writingBuffer.Length < maxBufferSize) @@ -1954,7 +1976,7 @@ public sealed partial class AaruFormat _crc64 = new Crc64Context(); } - ulong ddtEntry = (ulong)((_imageStream.Position << _shift) + _currentBlockOffset); + var ddtEntry = (ulong)((_imageStream.Position << _shift) + _currentBlockOffset); if(hash != null) _deduplicationTable.Add(hashString, ddtEntry); @@ -1988,11 +2010,11 @@ public sealed partial class AaruFormat return false; } - uint sectorSize = (uint)(data.Length / length); + var sectorSize = (uint)(data.Length / length); for(uint i = 0; i < length; i++) { - byte[] tmp = new byte[sectorSize]; + var tmp = new byte[sectorSize]; Array.Copy(data, i * sectorSize, tmp, 0, sectorSize); if(!WriteSector(tmp, sectorAddress + i)) @@ -2043,15 +2065,15 @@ public sealed partial class AaruFormat _sectorCprMai ??= new byte[_imageInfo.Sectors * 6]; _sectorEdc ??= new byte[_imageInfo.Sectors * 4]; - Array.Copy(data, 0, _sectorId, (int)sectorAddress * 4, 4); - Array.Copy(data, 4, _sectorIed, (int)sectorAddress * 2, 2); - Array.Copy(data, 6, _sectorCprMai, (int)sectorAddress * 6, 6); - Array.Copy(data, 12, sector, 0, 2048); - Array.Copy(data, 2060, _sectorEdc, (int)sectorAddress * 4, 4); + Array.Copy(data, 0, _sectorId, (int)sectorAddress * 4, 4); + Array.Copy(data, 4, _sectorIed, (int)sectorAddress * 2, 2); + Array.Copy(data, 6, _sectorCprMai, (int)sectorAddress * 6, 6); + Array.Copy(data, 12, sector, 0, 2048); + Array.Copy(data, 2060, _sectorEdc, (int)sectorAddress * 4, 4); return WriteSector(sector, sectorAddress); } - + if(data.Length != 2352) { ErrorMessage = Localization.Incorrect_data_size; @@ -2089,14 +2111,15 @@ public sealed partial class AaruFormat switch(track.Type) { case TrackType.Audio: - case TrackType.Data: return WriteSector(data, sectorAddress); + case TrackType.Data: + return WriteSector(data, sectorAddress); case TrackType.CdMode1: if(_sectorPrefix != null && _sectorSuffix != null) { sector = new byte[2048]; - Array.Copy(data, 0, _sectorPrefix, (int)sectorAddress * 16, 16); - Array.Copy(data, 16, sector, 0, 2048); + Array.Copy(data, 0, _sectorPrefix, (int)sectorAddress * 16, 16); + Array.Copy(data, 16, sector, 0, 2048); Array.Copy(data, 2064, _sectorSuffix, (int)sectorAddress * 288, 288); return WriteSector(sector, sectorAddress); @@ -2143,10 +2166,10 @@ public sealed partial class AaruFormat if(prefixCorrect) { - minute = ((data[0x0C] >> 4) * 10) + (data[0x0C] & 0x0F); - second = ((data[0x0D] >> 4) * 10) + (data[0x0D] & 0x0F); - frame = ((data[0x0E] >> 4) * 10) + (data[0x0E] & 0x0F); - storedLba = (minute * 60 * 75) + (second * 75) + frame - 150; + minute = (data[0x0C] >> 4) * 10 + (data[0x0C] & 0x0F); + second = (data[0x0D] >> 4) * 10 + (data[0x0D] & 0x0F); + frame = (data[0x0E] >> 4) * 10 + (data[0x0E] & 0x0F); + storedLba = minute * 60 * 75 + second * 75 + frame - 150; prefixCorrect = storedLba == (int)sectorAddress; } @@ -2159,7 +2182,7 @@ public sealed partial class AaruFormat else _sectorPrefixMs.Seek(0, SeekOrigin.End); - _sectorPrefixDdt[sectorAddress] = (uint)((_sectorPrefixMs.Position / 16) + 1); + _sectorPrefixDdt[sectorAddress] = (uint)(_sectorPrefixMs.Position / 16 + 1); _sectorPrefixMs.Write(data, 0, 16); } @@ -2174,7 +2197,7 @@ public sealed partial class AaruFormat else _sectorSuffixMs.Seek(0, SeekOrigin.End); - _sectorSuffixDdt[sectorAddress] = (uint)((_sectorSuffixMs.Position / 288) + 1); + _sectorSuffixDdt[sectorAddress] = (uint)(_sectorSuffixMs.Position / 288 + 1); _sectorSuffixMs.Write(data, 2064, 288); } @@ -2189,8 +2212,8 @@ public sealed partial class AaruFormat _sectorSuffix != null) { sector = new byte[2336]; - Array.Copy(data, 0, _sectorPrefix, (int)sectorAddress * 16, 16); - Array.Copy(data, 16, sector, 0, 2336); + Array.Copy(data, 0, _sectorPrefix, (int)sectorAddress * 16, 16); + Array.Copy(data, 16, sector, 0, 2336); return WriteSector(sector, sectorAddress); } @@ -2235,10 +2258,10 @@ public sealed partial class AaruFormat if(prefixCorrect) { - minute = ((data[0x0C] >> 4) * 10) + (data[0x0C] & 0x0F); - second = ((data[0x0D] >> 4) * 10) + (data[0x0D] & 0x0F); - frame = ((data[0x0E] >> 4) * 10) + (data[0x0E] & 0x0F); - storedLba = (minute * 60 * 75) + (second * 75) + frame - 150; + minute = (data[0x0C] >> 4) * 10 + (data[0x0C] & 0x0F); + second = (data[0x0D] >> 4) * 10 + (data[0x0D] & 0x0F); + frame = (data[0x0E] >> 4) * 10 + (data[0x0E] & 0x0F); + storedLba = minute * 60 * 75 + second * 75 + frame - 150; prefixCorrect = storedLba == (int)sectorAddress; } @@ -2251,7 +2274,7 @@ public sealed partial class AaruFormat else _sectorPrefixMs.Seek(0, SeekOrigin.End); - _sectorPrefixDdt[sectorAddress] = (uint)((_sectorPrefixMs.Position / 16) + 1); + _sectorPrefixDdt[sectorAddress] = (uint)(_sectorPrefixMs.Position / 16 + 1); _sectorPrefixMs.Write(data, 0, 16); } @@ -2263,7 +2286,7 @@ public sealed partial class AaruFormat if(form2) { uint computedEdc = ComputeEdc(0, data, 0x91C, 0x10); - uint edc = BitConverter.ToUInt32(data, 0x92C); + var edc = BitConverter.ToUInt32(data, 0x92C); bool correctEdc = computedEdc == edc; sector = new byte[2324]; @@ -2279,12 +2302,14 @@ public sealed partial class AaruFormat else { if((_sectorSuffixDdt[sectorAddress] & CD_DFIX_MASK) > 0) + { _sectorSuffixMs.Position = ((_sectorSuffixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 288; + } else _sectorSuffixMs.Seek(0, SeekOrigin.End); - _sectorSuffixDdt[sectorAddress] = (uint)((_sectorSuffixMs.Position / 288) + 1); + _sectorSuffixDdt[sectorAddress] = (uint)(_sectorSuffixMs.Position / 288 + 1); _sectorSuffixMs.Write(data, 2348, 4); } @@ -2294,7 +2319,7 @@ public sealed partial class AaruFormat bool correctEcc = SuffixIsCorrectMode2(data); uint computedEdc = ComputeEdc(0, data, 0x808, 0x10); - uint edc = BitConverter.ToUInt32(data, 0x818); + var edc = BitConverter.ToUInt32(data, 0x818); bool correctEdc = computedEdc == edc; sector = new byte[2048]; @@ -2309,12 +2334,14 @@ public sealed partial class AaruFormat else { if((_sectorSuffixDdt[sectorAddress] & CD_DFIX_MASK) > 0) + { _sectorSuffixMs.Position = ((_sectorSuffixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 288; + } else _sectorSuffixMs.Seek(0, SeekOrigin.End); - _sectorSuffixDdt[sectorAddress] = (uint)((_sectorSuffixMs.Position / 288) + 1); + _sectorSuffixDdt[sectorAddress] = (uint)(_sectorSuffixMs.Position / 288 + 1); _sectorSuffixMs.Write(data, 2072, 280); } @@ -2471,7 +2498,7 @@ public sealed partial class AaruFormat ErrorMessage = ""; return true; - + default: if(data.Length % 2352 != 0) { @@ -2494,7 +2521,7 @@ public sealed partial class AaruFormat return true; } - + case MetadataMediaType.BlockMedia: switch(_imageInfo.MediaType) { @@ -2504,7 +2531,7 @@ public sealed partial class AaruFormat case MediaType.AppleSonySS: case MediaType.AppleWidget: case MediaType.PriamDataTower: - int sectorSize = 0; + var sectorSize = 0; if(data.Length % 524 == 0) sectorSize = 524; @@ -2585,7 +2612,7 @@ public sealed partial class AaruFormat var cmpCrc64Context = new Crc64Context(); byte[] lzmaProperties = Array.Empty(); - int compressedLength = 0; + var compressedLength = 0; switch(_currentBlockHeader.compression) { @@ -2604,8 +2631,10 @@ public sealed partial class AaruFormat // Fill FLAC block if(remaining != 0) - for(int r = 0; r < remaining * 4; r++) + { + for(var r = 0; r < remaining * 4; r++) _writingBuffer[_writingBufferPosition + r] = 0; + } compressedLength = FLAC.EncodeBuffer(_writingBuffer, _compressedBuffer, flacBlockSize, true, false, "hamming", 12, 15, true, false, 0, 8, "Aaru"); @@ -2627,8 +2656,10 @@ public sealed partial class AaruFormat break; } - case CompressionType.None: break; // Do nothing - default: throw new ArgumentOutOfRangeException(); + case CompressionType.None: + break; // Do nothing + default: + throw new ArgumentOutOfRangeException(); } if(_currentBlockHeader.compression == CompressionType.None) @@ -2670,9 +2701,11 @@ public sealed partial class AaruFormat } if(_deduplicate) + { AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Of_0_sectors_written_1_are_unique_2, _writtenSectors, _deduplicationTable.Count, (double)_deduplicationTable.Count / _writtenSectors); + } IndexEntry idxEntry; @@ -2711,10 +2744,10 @@ public sealed partial class AaruFormat crc64 = BitConverter.ToUInt64(tagCrc, 0) }; - byte[] cmpBuffer = new byte[mediaTag.Value.Length + 262144]; + var cmpBuffer = new byte[mediaTag.Value.Length + 262144]; byte[] lzmaProperties = null; - bool doNotCompress = false; + var doNotCompress = false; switch(_compressionAlgorithm) { @@ -2730,7 +2763,8 @@ public sealed partial class AaruFormat doNotCompress = true; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } byte[] tagData; @@ -2905,7 +2939,7 @@ public sealed partial class AaruFormat foreach(Extent extent in dump.Extents) { dumpMs.Write(BitConverter.GetBytes(extent.Start), 0, sizeof(ulong)); - dumpMs.Write(BitConverter.GetBytes(extent.End), 0, sizeof(ulong)); + dumpMs.Write(BitConverter.GetBytes(extent.End), 0, sizeof(ulong)); } } @@ -2931,7 +2965,7 @@ public sealed partial class AaruFormat _structureBytes = new byte[Marshal.SizeOf()]; MemoryMarshal.Write(_structureBytes, in dumpBlock); - _imageStream.Write(_structureBytes, 0, _structureBytes.Length); + _imageStream.Write(_structureBytes, 0, _structureBytes.Length); _imageStream.Write(dumpMs.ToArray(), 0, (int)dumpMs.Length); _index.RemoveAll(t => t is { blockType: BlockType.DumpHardwareBlock, dataType: DataType.NoData }); @@ -2967,7 +3001,7 @@ public sealed partial class AaruFormat _structureBytes = new byte[Marshal.SizeOf()]; MemoryMarshal.Write(_structureBytes, in jsonBlock); - _imageStream.Write(_structureBytes, 0, _structureBytes.Length); + _imageStream.Write(_structureBytes, 0, _structureBytes.Length); _imageStream.Write(jsonMs.ToArray(), 0, (int)jsonMs.Length); // Ensure no CICM XML block is recorded altogether @@ -3003,7 +3037,7 @@ public sealed partial class AaruFormat _structureBytes = new byte[Marshal.SizeOf()]; MemoryMarshal.Write(_structureBytes, in md5Entry); chkMs.Write(_structureBytes, 0, _structureBytes.Length); - chkMs.Write(md5, 0, md5.Length); + chkMs.Write(md5, 0, md5.Length); chkHeader.entries++; } @@ -3020,7 +3054,7 @@ public sealed partial class AaruFormat _structureBytes = new byte[Marshal.SizeOf()]; MemoryMarshal.Write(_structureBytes, in sha1Entry); chkMs.Write(_structureBytes, 0, _structureBytes.Length); - chkMs.Write(sha1, 0, sha1.Length); + chkMs.Write(sha1, 0, sha1.Length); chkHeader.entries++; } @@ -3037,7 +3071,7 @@ public sealed partial class AaruFormat _structureBytes = new byte[Marshal.SizeOf()]; MemoryMarshal.Write(_structureBytes, in sha256Entry); chkMs.Write(_structureBytes, 0, _structureBytes.Length); - chkMs.Write(sha256, 0, sha256.Length); + chkMs.Write(sha256, 0, sha256.Length); chkHeader.entries++; } @@ -3054,7 +3088,7 @@ public sealed partial class AaruFormat _structureBytes = new byte[Marshal.SizeOf()]; MemoryMarshal.Write(_structureBytes, in spamsumEntry); chkMs.Write(_structureBytes, 0, _structureBytes.Length); - chkMs.Write(spamsum, 0, spamsum.Length); + chkMs.Write(spamsum, 0, spamsum.Length); chkHeader.entries++; } @@ -3105,15 +3139,17 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Writing_tape_partitions_to_position_0, idxEntry.offset); - TapePartitionEntry[] tapePartitionEntries = new TapePartitionEntry[TapePartitions.Count]; + var tapePartitionEntries = new TapePartitionEntry[TapePartitions.Count]; - for(int t = 0; t < TapePartitions.Count; t++) + for(var t = 0; t < TapePartitions.Count; t++) + { tapePartitionEntries[t] = new TapePartitionEntry { Number = TapePartitions[t].Number, FirstBlock = TapePartitions[t].FirstBlock, LastBlock = TapePartitions[t].LastBlock }; + } byte[] tapePartitionEntriesData = MemoryMarshal.Cast(tapePartitionEntries).ToArray(); @@ -3148,15 +3184,17 @@ public sealed partial class AaruFormat AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Writing_tape_files_to_position_0, idxEntry.offset); - TapeFileEntry[] tapeFileEntries = new TapeFileEntry[Files.Count]; + var tapeFileEntries = new TapeFileEntry[Files.Count]; - for(int t = 0; t < Files.Count; t++) + for(var t = 0; t < Files.Count; t++) + { tapeFileEntries[t] = new TapeFileEntry { File = Files[t].File, FirstBlock = Files[t].FirstBlock, LastBlock = Files[t].LastBlock }; + } byte[] tapeFileEntriesData = MemoryMarshal.Cast(tapeFileEntries).ToArray(); @@ -3209,7 +3247,7 @@ public sealed partial class AaruFormat byte[] ddtEntries = MemoryMarshal.Cast(_userDataDdt).ToArray(); _crc64.Update(ddtEntries); - byte[] cmpBuffer = new byte[ddtEntries.Length + 262144]; + var cmpBuffer = new byte[ddtEntries.Length + 262144]; int cmpLen; byte[] lzmaProperties = null; @@ -3226,7 +3264,8 @@ public sealed partial class AaruFormat 273); break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -3307,7 +3346,7 @@ public sealed partial class AaruFormat { compressStopwatch.Restart(); - byte[] cmpBuffer = new byte[_sectorPrefix.Length + 262144]; + var cmpBuffer = new byte[_sectorPrefix.Length + 262144]; int cmpLen; @@ -3323,7 +3362,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -3396,7 +3436,7 @@ public sealed partial class AaruFormat { compressStopwatch.Restart(); - byte[] cmpBuffer = new byte[_sectorSuffix.Length + 262144]; + var cmpBuffer = new byte[_sectorSuffix.Length + 262144]; int cmpLen; @@ -3412,7 +3452,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -3469,6 +3510,7 @@ public sealed partial class AaruFormat uint emptyMode2Form1 = 0; for(long i = 0; i < _sectorPrefixDdt.LongLength; i++) + { switch(_sectorPrefixDdt[i] & CD_XFIX_MASK) { case (uint)CdFixFlags.NotDumped: @@ -3487,8 +3529,10 @@ public sealed partial class AaruFormat break; } } + } for(long i = 0; i < _sectorPrefixDdt.LongLength; i++) + { switch(_sectorSuffixDdt[i] & CD_XFIX_MASK) { case (uint)CdFixFlags.NotDumped: @@ -3519,6 +3563,7 @@ public sealed partial class AaruFormat break; } } + } AaruConsole.DebugWriteLine(MODULE_NAME, Localization. @@ -3566,7 +3611,7 @@ public sealed partial class AaruFormat byte[] ddtEntries = MemoryMarshal.Cast(_sectorPrefixDdt).ToArray(); _crc64.Update(ddtEntries); - byte[] cmpBuffer = new byte[ddtEntries.Length + 262144]; + var cmpBuffer = new byte[ddtEntries.Length + 262144]; int cmpLen; byte[] lzmaProperties = Array.Empty(); @@ -3583,7 +3628,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -3613,10 +3659,10 @@ public sealed partial class AaruFormat blockStream.Close(); _index.RemoveAll(t => t is - { - blockType: BlockType.DeDuplicationTable, - dataType : DataType.CdSectorPrefixCorrected - }); + { + blockType: BlockType.DeDuplicationTable, + dataType : DataType.CdSectorPrefixCorrected + }); _index.Add(idxEntry); @@ -3658,7 +3704,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -3688,10 +3735,10 @@ public sealed partial class AaruFormat blockStream.Close(); _index.RemoveAll(t => t is - { - blockType: BlockType.DeDuplicationTable, - dataType : DataType.CdSectorSuffixCorrected - }); + { + blockType: BlockType.DeDuplicationTable, + dataType : DataType.CdSectorSuffixCorrected + }); _index.Add(idxEntry); @@ -3745,7 +3792,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -3782,10 +3830,10 @@ public sealed partial class AaruFormat blockStream.Close(); _index.RemoveAll(t => t is - { - blockType: BlockType.DataBlock, - dataType : DataType.CdSectorPrefixCorrected - }); + { + blockType: BlockType.DataBlock, + dataType : DataType.CdSectorPrefixCorrected + }); _index.Add(idxEntry); @@ -3839,7 +3887,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -3876,10 +3925,10 @@ public sealed partial class AaruFormat blockStream.Close(); _index.RemoveAll(t => t is - { - blockType: BlockType.DataBlock, - dataType : DataType.CdSectorSuffixCorrected - }); + { + blockType: BlockType.DataBlock, + dataType : DataType.CdSectorSuffixCorrected + }); _index.Add(idxEntry); } @@ -3921,7 +3970,7 @@ public sealed partial class AaruFormat { compressStopwatch.Restart(); - byte[] cmpBuffer = new byte[_mode2Subheaders.Length + 262144]; + var cmpBuffer = new byte[_mode2Subheaders.Length + 262144]; int cmpLen; @@ -3937,7 +3986,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -3974,10 +4024,10 @@ public sealed partial class AaruFormat _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); _index.RemoveAll(t => t is - { - blockType: BlockType.DataBlock, - dataType : DataType.CompactDiscMode2Subheader - }); + { + blockType: BlockType.DataBlock, + dataType : DataType.CompactDiscMode2Subheader + }); _index.Add(idxEntry); blockStream.Close(); @@ -4020,7 +4070,7 @@ public sealed partial class AaruFormat compressStopwatch.Restart(); byte[] transformedSubchannel = ClauniaSubchannelTransform(_sectorSubchannel); - byte[] cmpBuffer = new byte[transformedSubchannel.Length + 262144]; + var cmpBuffer = new byte[transformedSubchannel.Length + 262144]; int cmpLen; @@ -4036,7 +4086,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -4071,15 +4122,13 @@ public sealed partial class AaruFormat _imageStream.Write(_structureBytes, 0, _structureBytes.Length); if(subchannelBlock.compression is CompressionType.Lzma - or CompressionType.LzmaClauniaSubchannelTransform) + or CompressionType.LzmaClauniaSubchannelTransform) _imageStream.Write(lzmaProperties, 0, lzmaProperties.Length); _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); - _index.RemoveAll(t => t is - { - blockType: BlockType.DataBlock, dataType: DataType.CdSectorSubchannel - }); + _index.RemoveAll( + t => t is { blockType: BlockType.DataBlock, dataType: DataType.CdSectorSubchannel }); _index.Add(idxEntry); blockStream.Close(); @@ -4121,7 +4170,7 @@ public sealed partial class AaruFormat { compressStopwatch.Restart(); - byte[] cmpBuffer = new byte[_sectorCprMai.Length + 262144]; + var cmpBuffer = new byte[_sectorCprMai.Length + 262144]; int cmpLen; @@ -4137,7 +4186,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -4169,7 +4219,7 @@ public sealed partial class AaruFormat _imageStream.Write(_structureBytes, 0, _structureBytes.Length); if(cprMaiBlock.compression is CompressionType.Lzma - or CompressionType.LzmaClauniaSubchannelTransform) + or CompressionType.LzmaClauniaSubchannelTransform) _imageStream.Write(lzmaProperties, 0, lzmaProperties.Length); _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); @@ -4179,7 +4229,7 @@ public sealed partial class AaruFormat _index.Add(idxEntry); blockStream.Close(); } - + if(_sectorId != null) { idxEntry = new IndexEntry @@ -4216,7 +4266,7 @@ public sealed partial class AaruFormat { compressStopwatch.Restart(); - byte[] cmpBuffer = new byte[_sectorId.Length + 262144]; + var cmpBuffer = new byte[_sectorId.Length + 262144]; int cmpLen; @@ -4232,7 +4282,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -4264,7 +4315,7 @@ public sealed partial class AaruFormat _imageStream.Write(_structureBytes, 0, _structureBytes.Length); if(idBlock.compression is CompressionType.Lzma - or CompressionType.LzmaClauniaSubchannelTransform) + or CompressionType.LzmaClauniaSubchannelTransform) _imageStream.Write(lzmaProperties, 0, lzmaProperties.Length); _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); @@ -4274,7 +4325,7 @@ public sealed partial class AaruFormat _index.Add(idxEntry); blockStream.Close(); } - + if(_sectorIed != null) { idxEntry = new IndexEntry @@ -4311,7 +4362,7 @@ public sealed partial class AaruFormat { compressStopwatch.Restart(); - byte[] cmpBuffer = new byte[_sectorIed.Length + 262144]; + var cmpBuffer = new byte[_sectorIed.Length + 262144]; int cmpLen; @@ -4327,7 +4378,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -4359,7 +4411,7 @@ public sealed partial class AaruFormat _imageStream.Write(_structureBytes, 0, _structureBytes.Length); if(iedBlock.compression is CompressionType.Lzma - or CompressionType.LzmaClauniaSubchannelTransform) + or CompressionType.LzmaClauniaSubchannelTransform) _imageStream.Write(lzmaProperties, 0, lzmaProperties.Length); _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); @@ -4369,7 +4421,7 @@ public sealed partial class AaruFormat _index.Add(idxEntry); blockStream.Close(); } - + if(_sectorEdc != null) { idxEntry = new IndexEntry @@ -4406,7 +4458,7 @@ public sealed partial class AaruFormat { compressStopwatch.Restart(); - byte[] cmpBuffer = new byte[_sectorEdc.Length + 262144]; + var cmpBuffer = new byte[_sectorEdc.Length + 262144]; int cmpLen; @@ -4422,7 +4474,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -4454,7 +4507,7 @@ public sealed partial class AaruFormat _imageStream.Write(_structureBytes, 0, _structureBytes.Length); if(edcBlock.compression is CompressionType.Lzma - or CompressionType.LzmaClauniaSubchannelTransform) + or CompressionType.LzmaClauniaSubchannelTransform) _imageStream.Write(lzmaProperties, 0, lzmaProperties.Length); _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); @@ -4502,7 +4555,7 @@ public sealed partial class AaruFormat { compressStopwatch.Restart(); - byte[] cmpBuffer = new byte[_sectorDecryptedTitleKey.Length + 262144]; + var cmpBuffer = new byte[_sectorDecryptedTitleKey.Length + 262144]; int cmpLen; @@ -4518,7 +4571,8 @@ public sealed partial class AaruFormat cmpLen = cmpBuffer.Length; break; - default: throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); } blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -4550,16 +4604,16 @@ public sealed partial class AaruFormat _imageStream.Write(_structureBytes, 0, _structureBytes.Length); if(titleKeyBlock.compression is CompressionType.Lzma - or CompressionType.LzmaClauniaSubchannelTransform) + or CompressionType.LzmaClauniaSubchannelTransform) _imageStream.Write(lzmaProperties, 0, lzmaProperties.Length); _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); _index.RemoveAll(t => t is - { - blockType: BlockType.DataBlock, - dataType : DataType.DvdSectorTitleKeyDecrypted - }); + { + blockType: BlockType.DataBlock, + dataType : DataType.DvdSectorTitleKeyDecrypted + }); _index.Add(idxEntry); blockStream.Close(); @@ -4653,7 +4707,7 @@ public sealed partial class AaruFormat _structureBytes = new byte[Marshal.SizeOf()]; MemoryMarshal.Write(_structureBytes, in trkHeader); - _imageStream.Write(_structureBytes, 0, _structureBytes.Length); + _imageStream.Write(_structureBytes, 0, _structureBytes.Length); _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); blockStream.Close(); } @@ -4693,10 +4747,10 @@ public sealed partial class AaruFormat _imageStream.Position); _index.RemoveAll(t => t is - { - blockType: BlockType.CompactDiscIndexesBlock, - dataType : DataType.NoData - }); + { + blockType: BlockType.CompactDiscIndexesBlock, + dataType : DataType.NoData + }); _index.Add(new IndexEntry { @@ -4707,7 +4761,7 @@ public sealed partial class AaruFormat _structureBytes = new byte[Marshal.SizeOf()]; MemoryMarshal.Write(_structureBytes, in cdixHeader); - _imageStream.Write(_structureBytes, 0, _structureBytes.Length); + _imageStream.Write(_structureBytes, 0, _structureBytes.Length); _imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); blockStream.Close(); } @@ -4716,7 +4770,7 @@ public sealed partial class AaruFormat case MetadataMediaType.BlockMedia: if(_sectorSubchannel != null && _imageInfo.MediaType is MediaType.AppleFileWare or MediaType.AppleSonySS or MediaType.AppleSonyDS - or MediaType.AppleProfile or MediaType.AppleWidget or MediaType.PriamDataTower) + or MediaType.AppleProfile or MediaType.AppleWidget or MediaType.PriamDataTower) { DataType tagType = DataType.NoData; @@ -4790,14 +4844,15 @@ public sealed partial class AaruFormat } else { - byte[] cmpBuffer = new byte[_sectorSubchannel.Length + 262144]; + var cmpBuffer = new byte[_sectorSubchannel.Length + 262144]; int cmpLen = _compressionAlgorithm switch - { - CompressionType.Lzma => LZMA.EncodeBuffer(_sectorSubchannel, cmpBuffer, out lzmaProperties, - 9, _dictionarySize, 4, 0, 2, 273), - _ => throw new ArgumentOutOfRangeException() - }; + { + CompressionType.Lzma => LZMA.EncodeBuffer( + _sectorSubchannel, cmpBuffer, out lzmaProperties, + 9, _dictionarySize, 4, 0, 2, 273), + _ => throw new ArgumentOutOfRangeException() + }; blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); @@ -4857,10 +4912,7 @@ public sealed partial class AaruFormat metadataBlock.creatorLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.Comments)) @@ -4871,10 +4923,7 @@ public sealed partial class AaruFormat metadataBlock.commentsLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.MediaTitle)) @@ -4885,10 +4934,7 @@ public sealed partial class AaruFormat metadataBlock.mediaTitleLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.MediaManufacturer)) @@ -4899,10 +4945,7 @@ public sealed partial class AaruFormat metadataBlock.mediaManufacturerLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.MediaModel)) @@ -4913,10 +4956,7 @@ public sealed partial class AaruFormat metadataBlock.mediaModelLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.MediaSerialNumber)) @@ -4927,10 +4967,7 @@ public sealed partial class AaruFormat metadataBlock.mediaSerialNumberLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.MediaBarcode)) @@ -4941,10 +4978,7 @@ public sealed partial class AaruFormat metadataBlock.mediaBarcodeLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.MediaPartNumber)) @@ -4955,10 +4989,7 @@ public sealed partial class AaruFormat metadataBlock.mediaPartNumberLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.DriveManufacturer)) @@ -4969,10 +5000,7 @@ public sealed partial class AaruFormat metadataBlock.driveManufacturerLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.DriveModel)) @@ -4983,10 +5011,7 @@ public sealed partial class AaruFormat metadataBlock.driveModelLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.DriveSerialNumber)) @@ -4997,10 +5022,7 @@ public sealed partial class AaruFormat metadataBlock.driveSerialNumberLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } if(!string.IsNullOrWhiteSpace(_imageInfo.DriveFirmwareRevision)) @@ -5011,10 +5033,7 @@ public sealed partial class AaruFormat metadataBlock.driveFirmwareRevisionLength = (uint)(tmpUtf16Le.Length + 2); blockStream.Write(tmpUtf16Le, 0, tmpUtf16Le.Length); - blockStream.Write(new byte[] - { - 0, 0 - }, 0, 2); + blockStream.Write(new byte[] { 0, 0 }, 0, 2); } // Check if we set up any metadata earlier, then write its block @@ -5197,7 +5216,7 @@ public sealed partial class AaruFormat track = Tracks.FirstOrDefault(trk => sectorAddress == trk.Sequence); if(track is null || - (track.Sequence == 0 && track.StartSector == 0 && track.EndSector == 0)) + track.Sequence == 0 && track.StartSector == 0 && track.EndSector == 0) { ErrorMessage = string.Format(Localization.Cant_find_track_0, sectorAddress); @@ -5277,7 +5296,7 @@ public sealed partial class AaruFormat return true; } - + case SectorTagType.DvdSectorTitleKey: { if(data.Length != 5) @@ -5289,11 +5308,11 @@ public sealed partial class AaruFormat _sectorCprMai ??= new byte[_imageInfo.Sectors * 6]; - Array.Copy(data, 0, _sectorCprMai, (int)(1 + (6 * sectorAddress)), 5); + Array.Copy(data, 0, _sectorCprMai, (int)(1 + 6 * sectorAddress), 5); return true; } - + case SectorTagType.DvdSectorInformation: { if(data.Length != 1) @@ -5309,7 +5328,7 @@ public sealed partial class AaruFormat return true; } - + case SectorTagType.DvdSectorNumber: { if(data.Length != 3) @@ -5321,11 +5340,11 @@ public sealed partial class AaruFormat _sectorId ??= new byte[_imageInfo.Sectors * 4]; - Array.Copy(data, 0, _sectorId, (int)(1 + (4 * sectorAddress)), 3); + Array.Copy(data, 0, _sectorId, (int)(1 + 4 * sectorAddress), 3); return true; } - + case SectorTagType.DvdSectorIed: { if(data.Length != 2) @@ -5341,7 +5360,7 @@ public sealed partial class AaruFormat return true; } - + case SectorTagType.DvdSectorEdc: { if(data.Length != 4) @@ -5357,7 +5376,7 @@ public sealed partial class AaruFormat return true; } - + case SectorTagType.DvdTitleKeyDecrypted: { if(data.Length != 5) @@ -5401,7 +5420,8 @@ public sealed partial class AaruFormat switch(tag) { case SectorTagType.CdTrackFlags: - case SectorTagType.CdTrackIsrc: return WriteSectorTag(data, sectorAddress, tag); + case SectorTagType.CdTrackIsrc: + return WriteSectorTag(data, sectorAddress, tag); case SectorTagType.CdSectorSubchannel: { if(data.Length % 96 != 0) @@ -5413,7 +5433,7 @@ public sealed partial class AaruFormat _sectorSubchannel ??= new byte[_imageInfo.Sectors * 96]; - if((sectorAddress * 96) + (length * 96) > (ulong)_sectorSubchannel.LongLength) + if(sectorAddress * 96 + length * 96 > (ulong)_sectorSubchannel.LongLength) { ErrorMessage = Localization.Tried_to_write_more_data_than_possible; @@ -5447,4 +5467,6 @@ public sealed partial class AaruFormat return true; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/Alcohol120/Alcohol120.cs b/Aaru.Images/Alcohol120/Alcohol120.cs index 5ee2463f4..20871fac8 100644 --- a/Aaru.Images/Alcohol120/Alcohol120.cs +++ b/Aaru.Images/Alcohol120/Alcohol120.cs @@ -42,6 +42,7 @@ namespace Aaru.DiscImages; /// Implements reading and writing Alcohol 120% disk images public sealed partial class Alcohol120 : IWritableOpticalImage { + const string MODULE_NAME = "Alcohol 120% plugin"; Footer _alcFooter; IFilter _alcImage; Dictionary _alcSessions; @@ -84,6 +85,4 @@ public sealed partial class Alcohol120 : IWritableOpticalImage DriveSerialNumber = null, DriveFirmwareRevision = null }; - - const string MODULE_NAME = "Alcohol 120% plugin"; } \ No newline at end of file diff --git a/Aaru.Images/Alcohol120/Enums.cs b/Aaru.Images/Alcohol120/Enums.cs index cb771888f..5a46fd6bf 100644 --- a/Aaru.Images/Alcohol120/Enums.cs +++ b/Aaru.Images/Alcohol120/Enums.cs @@ -36,24 +36,47 @@ namespace Aaru.DiscImages; public sealed partial class Alcohol120 { +#region Nested type: MediumType + [SuppressMessage("ReSharper", "InconsistentNaming")] enum MediumType : ushort { - CD = 0x00, CDR = 0x01, CDRW = 0x02, - DVD = 0x10, DVDR = 0x12 + CD = 0x00, + CDR = 0x01, + CDRW = 0x02, + DVD = 0x10, + DVDR = 0x12 } +#endregion + +#region Nested type: SubchannelMode + + enum SubchannelMode : byte + { + None = 0x00, + Interleaved = 0x08 + } + +#endregion + +#region Nested type: TrackMode + [SuppressMessage("ReSharper", "InconsistentNaming")] enum TrackMode : byte { - NoData = 0x00, DVD = 0x02, Audio = 0xA9, - AudioAlt = 0xE9, Mode1 = 0xAA, Mode1Alt = 0xEA, - Mode2 = 0xAB, Mode2F1 = 0xEC, Mode2F2 = 0xED, - Mode2F1Alt = 0xAC, Mode2F2Alt = 0xAD + NoData = 0x00, + DVD = 0x02, + Audio = 0xA9, + AudioAlt = 0xE9, + Mode1 = 0xAA, + Mode1Alt = 0xEA, + Mode2 = 0xAB, + Mode2F1 = 0xEC, + Mode2F2 = 0xED, + Mode2F1Alt = 0xAC, + Mode2F2Alt = 0xAD } - enum SubchannelMode : byte - { - None = 0x00, Interleaved = 0x08 - } +#endregion } \ No newline at end of file diff --git a/Aaru.Images/Alcohol120/Helpers.cs b/Aaru.Images/Alcohol120/Helpers.cs index 0b2b03d93..dd37e6e7d 100644 --- a/Aaru.Images/Alcohol120/Helpers.cs +++ b/Aaru.Images/Alcohol120/Helpers.cs @@ -44,14 +44,20 @@ public sealed partial class Alcohol120 case TrackMode.Mode1: case TrackMode.Mode1Alt: case TrackMode.Mode2F1: - case TrackMode.Mode2F1Alt: return 2048; + case TrackMode.Mode2F1Alt: + return 2048; case TrackMode.Mode2F2: - case TrackMode.Mode2F2Alt: return 2324; - case TrackMode.Mode2: return 2336; + case TrackMode.Mode2F2Alt: + return 2324; + case TrackMode.Mode2: + return 2336; case TrackMode.Audio: - case TrackMode.AudioAlt: return 2352; - case TrackMode.DVD: return 2048; - default: return 0; + case TrackMode.AudioAlt: + return 2352; + case TrackMode.DVD: + return 2048; + default: + return 0; } } @@ -60,27 +66,33 @@ public sealed partial class Alcohol120 switch(trackType) { case TrackMode.Mode1: - case TrackMode.Mode1Alt: return TrackType.CdMode1; + case TrackMode.Mode1Alt: + return TrackType.CdMode1; case TrackMode.Mode2F1: - case TrackMode.Mode2F1Alt: return TrackType.CdMode2Form1; + case TrackMode.Mode2F1Alt: + return TrackType.CdMode2Form1; case TrackMode.Mode2F2: - case TrackMode.Mode2F2Alt: return TrackType.CdMode2Form2; - case TrackMode.Mode2: return TrackType.CdMode2Formless; + case TrackMode.Mode2F2Alt: + return TrackType.CdMode2Form2; + case TrackMode.Mode2: + return TrackType.CdMode2Formless; case TrackMode.Audio: - case TrackMode.AudioAlt: return TrackType.Audio; - default: return TrackType.Data; + case TrackMode.AudioAlt: + return TrackType.Audio; + default: + return TrackType.Data; } } static MediaType MediumTypeToMediaType(MediumType discType) => discType switch - { - MediumType.CD => MediaType.CD, - MediumType.CDR => MediaType.CDR, - MediumType.CDRW => MediaType.CDRW, - MediumType.DVD => MediaType.DVDROM, - MediumType.DVDR => MediaType.DVDR, - _ => MediaType.Unknown - }; + { + MediumType.CD => MediaType.CD, + MediumType.CDR => MediaType.CDR, + MediumType.CDRW => MediaType.CDRW, + MediumType.DVD => MediaType.DVDROM, + MediumType.DVDR => MediaType.DVDR, + _ => MediaType.Unknown + }; static MediumType MediaTypeToMediumType(MediaType type) { @@ -119,30 +131,35 @@ public sealed partial class Alcohol120 case MediaType.VideoNow: case MediaType.VideoNowColor: case MediaType.VideoNowXp: - case MediaType.CVD: return MediumType.CD; - case MediaType.CDR: return MediumType.CDR; + case MediaType.CVD: + return MediumType.CD; + case MediaType.CDR: + return MediumType.CDR; case MediaType.CDRW: - case MediaType.CDMRW: return MediumType.CDRW; + case MediaType.CDMRW: + return MediumType.CDRW; case MediaType.DVDR: case MediaType.DVDRW: case MediaType.DVDPR: case MediaType.DVDRDL: case MediaType.DVDRWDL: case MediaType.DVDPRDL: - case MediaType.DVDPRWDL: return MediumType.DVDR; - default: return MediumType.DVD; + case MediaType.DVDPRWDL: + return MediumType.DVDR; + default: + return MediumType.DVD; } } static TrackMode TrackTypeToTrackMode(TrackType type) => type switch - { - TrackType.Audio => TrackMode.Audio, - TrackType.CdMode1 => TrackMode.Mode1, - TrackType.CdMode2Formless => TrackMode.Mode2, - TrackType.CdMode2Form1 => TrackMode.Mode2F1, - TrackType.CdMode2Form2 => TrackMode.Mode2F2, - _ => TrackMode.DVD - }; + { + TrackType.Audio => TrackMode.Audio, + TrackType.CdMode1 => TrackMode.Mode1, + TrackType.CdMode2Formless => TrackMode.Mode2, + TrackType.CdMode2Form1 => TrackMode.Mode2F1, + TrackType.CdMode2Form2 => TrackMode.Mode2F2, + _ => TrackMode.DVD + }; static (byte minute, byte second, byte frame) LbaToMsf(ulong sector) => ((byte)((sector + 150) / 75 / 60), (byte)((sector + 150) / 75 % 60), (byte)((sector + 150) % 75)); diff --git a/Aaru.Images/Alcohol120/Identify.cs b/Aaru.Images/Alcohol120/Identify.cs index 63bd56267..3bce2ae63 100644 --- a/Aaru.Images/Alcohol120/Identify.cs +++ b/Aaru.Images/Alcohol120/Identify.cs @@ -39,6 +39,8 @@ namespace Aaru.DiscImages; public sealed partial class Alcohol120 { +#region IWritableOpticalImage Members + /// public bool Identify(IFilter imageFilter) { @@ -48,10 +50,12 @@ public sealed partial class Alcohol120 if(stream.Length < 88) return false; - byte[] hdr = new byte[88]; + var hdr = new byte[88]; stream.EnsureRead(hdr, 0, 88); Header header = Marshal.ByteArrayToStructureLittleEndian
(hdr); return header.signature.SequenceEqual(_alcoholSignature) && header.version[0] <= MAXIMUM_SUPPORTED_VERSION; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/Alcohol120/Properties.cs b/Aaru.Images/Alcohol120/Properties.cs index e7f6f6d60..b1098c09d 100644 --- a/Aaru.Images/Alcohol120/Properties.cs +++ b/Aaru.Images/Alcohol120/Properties.cs @@ -43,6 +43,8 @@ namespace Aaru.DiscImages; public sealed partial class Alcohol120 { +#region IWritableOpticalImage Members + /// public OpticalImageCapabilities OpticalCapabilities => OpticalImageCapabilities.CanStoreAudioTracks | OpticalImageCapabilities.CanStoreDataTracks | @@ -56,12 +58,16 @@ public sealed partial class Alcohol120 OpticalImageCapabilities.CanStoreRawData | OpticalImageCapabilities.CanStoreCookedData | OpticalImageCapabilities.CanStoreMultipleTracks; + /// public ImageInfo Info => _imageInfo; + /// public string Name => Localization.Alcohol120_Name; + /// public Guid Id => new("A78FBEBA-0307-4915-BDE3-B8A3B57F843F"); + /// public string Author => Authors.NataliaPortillo; @@ -153,6 +159,7 @@ public sealed partial class Alcohol120 /// public List DumpHardware => null; + /// public Metadata AaruMetadata => null; @@ -161,40 +168,46 @@ public sealed partial class Alcohol120 { MediaTagType.CD_FullTOC, MediaTagType.DVD_BCA, MediaTagType.DVD_DMI, MediaTagType.DVD_PFI }; + /// public IEnumerable SupportedSectorTags => new[] { - SectorTagType.CdSectorEcc, SectorTagType.CdSectorEccP, SectorTagType.CdSectorEccQ, SectorTagType.CdSectorEdc, - SectorTagType.CdSectorHeader, SectorTagType.CdSectorSubHeader, SectorTagType.CdSectorSync, - SectorTagType.CdTrackFlags, SectorTagType.CdSectorSubchannel + SectorTagType.CdSectorEcc, SectorTagType.CdSectorEccP, SectorTagType.CdSectorEccQ, + SectorTagType.CdSectorEdc, SectorTagType.CdSectorHeader, SectorTagType.CdSectorSubHeader, + SectorTagType.CdSectorSync, SectorTagType.CdTrackFlags, SectorTagType.CdSectorSubchannel }; + /// public IEnumerable SupportedMediaTypes => new[] { MediaType.BDR, MediaType.BDRE, MediaType.BDREXL, MediaType.BDROM, MediaType.UHDBD, MediaType.BDRXL, - MediaType.CBHD, MediaType.CD, MediaType.CDDA, MediaType.CDEG, MediaType.CDG, MediaType.CDI, MediaType.CDMIDI, - MediaType.CDMRW, MediaType.CDPLUS, MediaType.CDR, MediaType.CDROM, MediaType.CDROMXA, MediaType.CDRW, - MediaType.CDV, MediaType.DVDDownload, MediaType.DVDPR, MediaType.DVDPRDL, MediaType.DVDPRW, MediaType.DVDPRWDL, - MediaType.DVDR, MediaType.DVDRAM, MediaType.DVDRDL, MediaType.DVDROM, MediaType.DVDRW, MediaType.DVDRWDL, - MediaType.EVD, MediaType.FDDVD, MediaType.DTSCD, MediaType.FVD, MediaType.HDDVDR, MediaType.HDDVDRAM, - MediaType.HDDVDRDL, MediaType.HDDVDROM, MediaType.HDDVDRW, MediaType.HDDVDRWDL, MediaType.HDVMD, MediaType.HVD, - MediaType.JaguarCD, MediaType.MEGACD, MediaType.PS1CD, MediaType.PS2CD, MediaType.PS2DVD, MediaType.PS3BD, - MediaType.PS3DVD, MediaType.PS4BD, MediaType.PS5BD, MediaType.SuperCDROM2, MediaType.SVCD, MediaType.SVOD, - MediaType.SATURNCD, MediaType.ThreeDO, MediaType.UDO, MediaType.UDO2, MediaType.UDO2_WORM, MediaType.UMD, - MediaType.VCD, MediaType.VCDHD, MediaType.NeoGeoCD, MediaType.PCFX, MediaType.CDTV, MediaType.CD32, - MediaType.Nuon, MediaType.Playdia, MediaType.Pippin, MediaType.FMTOWNS, MediaType.MilCD, MediaType.VideoNow, - MediaType.VideoNowColor, MediaType.VideoNowXp, MediaType.CVD, MediaType.PCD + MediaType.CBHD, MediaType.CD, MediaType.CDDA, MediaType.CDEG, MediaType.CDG, MediaType.CDI, + MediaType.CDMIDI, MediaType.CDMRW, MediaType.CDPLUS, MediaType.CDR, MediaType.CDROM, MediaType.CDROMXA, + MediaType.CDRW, MediaType.CDV, MediaType.DVDDownload, MediaType.DVDPR, MediaType.DVDPRDL, MediaType.DVDPRW, + MediaType.DVDPRWDL, MediaType.DVDR, MediaType.DVDRAM, MediaType.DVDRDL, MediaType.DVDROM, MediaType.DVDRW, + MediaType.DVDRWDL, MediaType.EVD, MediaType.FDDVD, MediaType.DTSCD, MediaType.FVD, MediaType.HDDVDR, + MediaType.HDDVDRAM, MediaType.HDDVDRDL, MediaType.HDDVDROM, MediaType.HDDVDRW, MediaType.HDDVDRWDL, + MediaType.HDVMD, MediaType.HVD, MediaType.JaguarCD, MediaType.MEGACD, MediaType.PS1CD, MediaType.PS2CD, + MediaType.PS2DVD, MediaType.PS3BD, MediaType.PS3DVD, MediaType.PS4BD, MediaType.PS5BD, + MediaType.SuperCDROM2, MediaType.SVCD, MediaType.SVOD, MediaType.SATURNCD, MediaType.ThreeDO, MediaType.UDO, + MediaType.UDO2, MediaType.UDO2_WORM, MediaType.UMD, MediaType.VCD, MediaType.VCDHD, MediaType.NeoGeoCD, + MediaType.PCFX, MediaType.CDTV, MediaType.CD32, MediaType.Nuon, MediaType.Playdia, MediaType.Pippin, + MediaType.FMTOWNS, MediaType.MilCD, MediaType.VideoNow, MediaType.VideoNowColor, MediaType.VideoNowXp, + MediaType.CVD, MediaType.PCD }; + /// public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions => Array.Empty<(string name, Type type, string description, object @default)>(); + /// - public IEnumerable KnownExtensions => new[] - { - ".mds" - }; + public IEnumerable KnownExtensions => new[] { ".mds" }; + /// public bool IsWriting { get; private set; } + /// public string ErrorMessage { get; private set; } + +#endregion } \ No newline at end of file diff --git a/Aaru.Images/Alcohol120/Read.cs b/Aaru.Images/Alcohol120/Read.cs index 03a0b84f1..7ad34c82d 100644 --- a/Aaru.Images/Alcohol120/Read.cs +++ b/Aaru.Images/Alcohol120/Read.cs @@ -48,6 +48,8 @@ namespace Aaru.DiscImages; public sealed partial class Alcohol120 { +#region IWritableOpticalImage Members + /// public ErrorNumber Open(IFilter imageFilter) { @@ -58,7 +60,7 @@ public sealed partial class Alcohol120 return ErrorNumber.InvalidArgument; _isDvd = false; - byte[] hdr = new byte[88]; + var hdr = new byte[88]; stream.EnsureRead(hdr, 0, 88); _header = Marshal.ByteArrayToStructureLittleEndian
(hdr); @@ -68,33 +70,41 @@ public sealed partial class Alcohol120 AaruConsole.DebugWriteLine(MODULE_NAME, "header.version = {0}.{1}", _header.version[0], _header.version[1]); - AaruConsole.DebugWriteLine(MODULE_NAME, "header.type = {0}", _header.type); + AaruConsole.DebugWriteLine(MODULE_NAME, "header.type = {0}", _header.type); AaruConsole.DebugWriteLine(MODULE_NAME, "header.sessions = {0}", _header.sessions); - for(int i = 0; i < _header.unknown1.Length; i++) + for(var i = 0; i < _header.unknown1.Length; i++) + { AaruConsole.DebugWriteLine(MODULE_NAME, "header.unknown1[{1}] = 0x{0:X4}", _header.unknown1[i], i); + } AaruConsole.DebugWriteLine(MODULE_NAME, "header.bcaLength = {0}", _header.bcaLength); - for(int i = 0; i < _header.unknown2.Length; i++) + for(var i = 0; i < _header.unknown2.Length; i++) + { AaruConsole.DebugWriteLine(MODULE_NAME, "header.unknown2[{1}] = 0x{0:X8}", _header.unknown2[i], i); + } AaruConsole.DebugWriteLine(MODULE_NAME, "header.bcaOffset = {0}", _header.bcaOffset); - for(int i = 0; i < _header.unknown3.Length; i++) + for(var i = 0; i < _header.unknown3.Length; i++) + { AaruConsole.DebugWriteLine(MODULE_NAME, "header.unknown3[{1}] = 0x{0:X8}", _header.unknown3[i], i); + } AaruConsole.DebugWriteLine(MODULE_NAME, "header.structuresOffset = {0}", _header.structuresOffset); - for(int i = 0; i < _header.unknown4.Length; i++) + for(var i = 0; i < _header.unknown4.Length; i++) + { AaruConsole.DebugWriteLine(MODULE_NAME, "header.unknown4[{1}] = 0x{0:X8}", _header.unknown4[i], i); + } AaruConsole.DebugWriteLine(MODULE_NAME, "header.sessionOffset = {0}", _header.sessionOffset); - AaruConsole.DebugWriteLine(MODULE_NAME, "header.dpmOffset = {0}", _header.dpmOffset); + AaruConsole.DebugWriteLine(MODULE_NAME, "header.dpmOffset = {0}", _header.dpmOffset); if(_header.version[0] > MAXIMUM_SUPPORTED_VERSION) return ErrorNumber.NotSupported; @@ -102,9 +112,9 @@ public sealed partial class Alcohol120 stream.Seek(_header.sessionOffset, SeekOrigin.Begin); _alcSessions = new Dictionary(); - for(int i = 0; i < _header.sessions; i++) + for(var i = 0; i < _header.sessions; i++) { - byte[] sesHdr = new byte[24]; + var sesHdr = new byte[24]; stream.EnsureRead(sesHdr, 0, 24); Session session = Marshal.SpanToStructureLittleEndian(sesHdr); @@ -133,7 +143,7 @@ public sealed partial class Alcohol120 } long footerOff = 0; - bool oldIncorrectImage = false; + var oldIncorrectImage = false; _alcTracks = new Dictionary(); _alcToc = new Dictionary>(); @@ -144,9 +154,9 @@ public sealed partial class Alcohol120 stream.Seek(session.trackOffset, SeekOrigin.Begin); Dictionary sesToc = new(); - for(int i = 0; i < session.allBlocks; i++) + for(var i = 0; i < session.allBlocks; i++) { - byte[] trkHdr = new byte[80]; + var trkHdr = new byte[80]; stream.EnsureRead(trkHdr, 0, 80); Track track = Marshal.ByteArrayToStructureLittleEndian(trkHdr); @@ -250,10 +260,11 @@ public sealed partial class Alcohol120 _alcTrackExtras = new Dictionary(); foreach(Track track in _alcTracks.Values) + { if(track.extraOffset > 0 && !_isDvd) { - byte[] extHdr = new byte[8]; + var extHdr = new byte[8]; stream.Seek(track.extraOffset, SeekOrigin.Begin); stream.EnsureRead(extHdr, 0, 8); TrackExtra extra = Marshal.SpanToStructureLittleEndian(extHdr); @@ -281,33 +292,36 @@ public sealed partial class Alcohol120 _alcTrackExtras.Add(track.point, extra); } + } if(footerOff > 0) { - byte[] footer = new byte[16]; + var footer = new byte[16]; stream.Seek(footerOff, SeekOrigin.Begin); stream.EnsureRead(footer, 0, 16); _alcFooter = Marshal.SpanToStructureLittleEndian