From ebf893e2780acdfb3fe5e2a383a60e40f49d4cc8 Mon Sep 17 00:00:00 2001 From: Rebecca Wallander Date: Tue, 22 Aug 2023 16:27:52 +0200 Subject: [PATCH] Add reader for DiscImageCreator DVD Raw dumps (#817) --- Aaru.CommonTypes | 2 +- Aaru.Core/Devices/Dumping/Sbc/Data.cs | 10 +- Aaru.Core/Devices/Dumping/Sbc/Error.cs | 6 +- Aaru.Core/Media/Detection/MMC.cs | 1 + Aaru.Decoders | 2 +- Aaru.Devices/Device/ScsiCommands/SBC.cs | 2 +- Aaru.Images/AaruFormat/AaruFormat.cs | 5 +- Aaru.Images/AaruFormat/Enums.cs | 12 +- Aaru.Images/AaruFormat/Read.cs | 97 +++- Aaru.Images/AaruFormat/Write.cs | 498 ++++++++++++++++-- Aaru.Images/Alcohol120/Read.cs | 1 + Aaru.Images/BlindWrite5/Read.cs | 1 + .../Localization/Localization.Designer.cs | 68 ++- Aaru.Images/Localization/Localization.resx | 38 +- Aaru.Images/ZZZRawImage/Helpers.cs | 6 + Aaru.Images/ZZZRawImage/Identify.cs | 1 + Aaru.Images/ZZZRawImage/Read.cs | 130 ++++- Aaru.Images/ZZZRawImage/ZZZRawImage.cs | 3 + Aaru/Commands/Image/Convert.cs | 10 +- 19 files changed, 798 insertions(+), 95 deletions(-) diff --git a/Aaru.CommonTypes b/Aaru.CommonTypes index d007f1ac9..1d4add328 160000 --- a/Aaru.CommonTypes +++ b/Aaru.CommonTypes @@ -1 +1 @@ -Subproject commit d007f1ac9ac2a85c885c1be960107bd42fba5542 +Subproject commit 1d4add3282b517bdd599dba49c18850b151e0991 diff --git a/Aaru.Core/Devices/Dumping/Sbc/Data.cs b/Aaru.Core/Devices/Dumping/Sbc/Data.cs index 278124666..a0b5ae166 100644 --- a/Aaru.Core/Devices/Dumping/Sbc/Data.cs +++ b/Aaru.Core/Devices/Dumping/Sbc/Data.cs @@ -136,7 +136,7 @@ partial class Dump outputFormat.WriteSectorTag(new[] { titleKey.Value.CMI - }, i + j, SectorTagType.DvdCmi); + }, i + j, SectorTagType.DvdSectorCmi); else continue; @@ -147,7 +147,7 @@ partial class Dump outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 - }, i + j, SectorTagType.DvdTitleKey); + }, i + j, SectorTagType.DvdSectorTitleKey); outputFormat.WriteSectorTag(new byte[] { @@ -166,7 +166,7 @@ partial class Dump outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 - }, i + j, SectorTagType.DvdTitleKey); + }, i + j, SectorTagType.DvdSectorTitleKey); outputFormat.WriteSectorTag(new byte[] { @@ -178,7 +178,7 @@ partial class Dump continue; } - outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey); + outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdSectorTitleKey); _resume.MissingTitleKeys.Remove(i + j); CSS.DecryptTitleKey(discKey, titleKey.Value.Key, out tmpBuf); @@ -190,7 +190,7 @@ partial class Dump // Todo: Flag in the outputFormat that a sector has been decrypted { ErrorNumber errno = - outputFormat.ReadSectorsTag(i, blocksToRead, SectorTagType.DvdCmi, out byte[] cmi); + outputFormat.ReadSectorsTag(i, blocksToRead, SectorTagType.DvdSectorCmi, out byte[] cmi); if(errno != ErrorNumber.NoError) ErrorMessage?.Invoke(string.Format(Localization.Core.Error_retrieving_CMI_for_sector_0, i)); diff --git a/Aaru.Core/Devices/Dumping/Sbc/Error.cs b/Aaru.Core/Devices/Dumping/Sbc/Error.cs index 7b5db44c5..387997765 100644 --- a/Aaru.Core/Devices/Dumping/Sbc/Error.cs +++ b/Aaru.Core/Devices/Dumping/Sbc/Error.cs @@ -378,7 +378,7 @@ partial class Dump outputFormat.WriteSectorTag(new[] { titleKey.Value.CMI - }, missingKey, SectorTagType.DvdCmi); + }, missingKey, SectorTagType.DvdSectorCmi); // If the CMI bit is 1, the sector is using copy protection, else it is not // If the decoded title key is zeroed, there should be no copy protection @@ -388,7 +388,7 @@ partial class Dump outputFormat.WriteSectorTag(new byte[] { 0, 0, 0, 0, 0 - }, missingKey, SectorTagType.DvdTitleKey); + }, missingKey, SectorTagType.DvdSectorTitleKey); outputFormat.WriteSectorTag(new byte[] { @@ -404,7 +404,7 @@ partial class Dump } else { - outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdTitleKey); + outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdSectorTitleKey); _resume.MissingTitleKeys.Remove(missingKey); if(discKey != null) diff --git a/Aaru.Core/Media/Detection/MMC.cs b/Aaru.Core/Media/Detection/MMC.cs index 984b051a7..fee5cb8da 100644 --- a/Aaru.Core/Media/Detection/MMC.cs +++ b/Aaru.Core/Media/Detection/MMC.cs @@ -48,6 +48,7 @@ using Aaru.Decoders.Sega; using Aaru.Devices; using Aaru.Helpers; using DMI = Aaru.Decoders.Xbox.DMI; +using Sector = Aaru.Decoders.CD.Sector; namespace Aaru.Core.Media.Detection; diff --git a/Aaru.Decoders b/Aaru.Decoders index 66c6b4b7f..6e0e9405a 160000 --- a/Aaru.Decoders +++ b/Aaru.Decoders @@ -1 +1 @@ -Subproject commit 66c6b4b7f9dcff452ec1092510cf0151bbf7c5c6 +Subproject commit 6e0e9405ae2b5c63f0d71fac3f1ca50bf5aa20ad diff --git a/Aaru.Devices/Device/ScsiCommands/SBC.cs b/Aaru.Devices/Device/ScsiCommands/SBC.cs index 409cf5e8a..a33396979 100644 --- a/Aaru.Devices/Device/ScsiCommands/SBC.cs +++ b/Aaru.Devices/Device/ScsiCommands/SBC.cs @@ -93,7 +93,7 @@ public partial class Device /// If set to true requested blocks shall be assigned the lowest retention priority on cache /// fetch/retain. /// - /// If set to true requested blocks MUST bu read from medium and not the cache. + /// If set to true requested blocks MUST be read from medium and not the cache. /// /// If set to true requested blocks will be returned from non-volatile cache. If they're not /// present they shall be stored there. diff --git a/Aaru.Images/AaruFormat/AaruFormat.cs b/Aaru.Images/AaruFormat/AaruFormat.cs index c5b4ec697..4e3848768 100644 --- a/Aaru.Images/AaruFormat/AaruFormat.cs +++ b/Aaru.Images/AaruFormat/AaruFormat.cs @@ -128,7 +128,10 @@ public sealed partial class AaruFormat : IWritableOpticalImage, IVerifiableImage /// If DDT is on-disk, this is the image stream offset at which it starts. long _outMemoryDdtPosition; bool _rewinded; - byte[] _sectorCpiMai; + byte[] _sectorCprMai; + byte[] _sectorIed; + byte[] _sectorId; + byte[] _sectorEdc; byte[] _sectorDecryptedTitleKey; /// Cache for data that prefixes the user data on a sector (e.g. sync). byte[] _sectorPrefix; diff --git a/Aaru.Images/AaruFormat/Enums.cs b/Aaru.Images/AaruFormat/Enums.cs index feff4d98e..936100ee8 100644 --- a/Aaru.Images/AaruFormat/Enums.cs +++ b/Aaru.Images/AaruFormat/Enums.cs @@ -214,10 +214,16 @@ public sealed partial class AaruFormat CompactDiscLeadIn = 79, /// Decrypted DVD Disc Key DvdDiscKeyDecrypted = 80, - /// DVD CPI_MAI - DvdSectorCpiMai = 81, + /// DVD Copyright Management Information (CPR_MAI) + DvdSectorCprMai = 81, /// Decrypted DVD Title Key - DvdSectorTitleKeyDecrypted = 82 + DvdSectorTitleKeyDecrypted = 82, + /// DVD Identification Data (ID) + DvdSectorId = 83, + /// DVD ID Error Detection Code (IED) + DvdSectorIed = 84, + /// DVD Error Detection Code (EDC) + DvdSectorEdc = 85 } /// List of known blocks types diff --git a/Aaru.Images/AaruFormat/Read.cs b/Aaru.Images/AaruFormat/Read.cs index 93b4e6f33..ac9139b00 100644 --- a/Aaru.Images/AaruFormat/Read.cs +++ b/Aaru.Images/AaruFormat/Read.cs @@ -382,14 +382,47 @@ public sealed partial class AaruFormat GC.GetTotalMemory(false)); break; - case DataType.DvdSectorCpiMai: - _sectorCpiMai = data; + case DataType.DvdSectorCprMai: + _sectorCprMai = data; - if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdCmi)) - _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdCmi); + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorCmi)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorCmi); - if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdTitleKey)) - _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdTitleKey); + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorTitleKey)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorTitleKey); + + AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes, + GC.GetTotalMemory(false)); + + break; + case DataType.DvdSectorId: + _sectorId = data; + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorInformation)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorInformation); + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorNumber)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorNumber); + + AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes, + GC.GetTotalMemory(false)); + + break; + case DataType.DvdSectorIed: + _sectorDecryptedTitleKey = data; + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorIed)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorIed); + + AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes, + GC.GetTotalMemory(false)); + + break; + case DataType.DvdSectorEdc: + _sectorDecryptedTitleKey = data; + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorEdc)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorEdc); AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes, GC.GetTotalMemory(false)); @@ -1769,8 +1802,12 @@ public sealed partial class AaruFormat case SectorTagType.CdSectorSubchannel: case SectorTagType.CdSectorSubHeader: case SectorTagType.CdSectorSync: - case SectorTagType.DvdCmi: - case SectorTagType.DvdTitleKey: + case SectorTagType.DvdSectorCmi: + case SectorTagType.DvdSectorTitleKey: + case SectorTagType.DvdSectorInformation: + case SectorTagType.DvdSectorNumber: + case SectorTagType.DvdSectorIed: + case SectorTagType.DvdSectorEdc: case SectorTagType.DvdTitleKeyDecrypted: break; case SectorTagType.CdTrackFlags: if(!_trackFlags.TryGetValue((byte)sectorAddress, out byte flags)) @@ -1954,21 +1991,57 @@ public sealed partial class AaruFormat if(_imageInfo.MediaType == MediaType.DVDROM) switch(tag) { - case SectorTagType.DvdCmi: + case SectorTagType.DvdSectorCmi: { sectorOffset = 0; sectorSize = 1; sectorSkip = 5; - dataSource = _sectorCpiMai; + dataSource = _sectorCprMai; break; } - case SectorTagType.DvdTitleKey: + case SectorTagType.DvdSectorTitleKey: { sectorOffset = 1; sectorSize = 5; sectorSkip = 0; - dataSource = _sectorCpiMai; + dataSource = _sectorCprMai; + + break; + } + case SectorTagType.DvdSectorInformation: + { + sectorOffset = 0; + sectorSize = 1; + sectorSkip = 3; + dataSource = _sectorId; + + break; + } + case SectorTagType.DvdSectorNumber: + { + sectorOffset = 1; + sectorSize = 3; + sectorSkip = 0; + dataSource = _sectorId; + + break; + } + case SectorTagType.DvdSectorIed: + { + sectorOffset = 0; + sectorSize = 2; + sectorSkip = 0; + dataSource = _sectorIed; + + break; + } + case SectorTagType.DvdSectorEdc: + { + sectorOffset = 0; + sectorSize = 4; + sectorSkip = 0; + dataSource = _sectorEdc; break; } diff --git a/Aaru.Images/AaruFormat/Write.cs b/Aaru.Images/AaruFormat/Write.cs index 06e093b55..97ae49558 100644 --- a/Aaru.Images/AaruFormat/Write.cs +++ b/Aaru.Images/AaruFormat/Write.cs @@ -554,14 +554,14 @@ public sealed partial class AaruFormat GC.GetTotalMemory(false)); break; - case DataType.DvdSectorCpiMai: - _sectorCpiMai = data; + case DataType.DvdSectorCprMai: + _sectorCprMai = data; - if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdCmi)) - _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdCmi); + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorCmi)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorCmi); - if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdTitleKey)) - _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdTitleKey); + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorTitleKey)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorTitleKey); AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes, GC.GetTotalMemory(false)); @@ -2030,6 +2030,24 @@ public sealed partial class AaruFormat track.EndSector == 0) track.Type = TrackType.Data; + if(data.Length == 2064 && + _imageInfo.MediaType == MediaType.DVDROM) + { + sector = new byte[2048]; + _sectorId ??= new byte[_imageInfo.Sectors * 4]; + _sectorIed ??= new byte[_imageInfo.Sectors * 2]; + _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); + + return WriteSector(sector, sectorAddress); + } + if(data.Length != 2352) { ErrorMessage = Localization.Incorrect_data_size; @@ -2426,26 +2444,53 @@ public sealed partial class AaruFormat switch(_imageInfo.MetadataMediaType) { case MetadataMediaType.OpticalDisc: - if(data.Length % 2352 != 0) + switch(_imageInfo.MediaType) { - ErrorMessage = Localization.Incorrect_data_size; + case MediaType.DVDROM: + if(data.Length % 2064 != 0) + { + ErrorMessage = Localization.Incorrect_data_size; - return false; + return false; + } + + sector = new byte[2064]; + + for(uint i = 0; i < length; i++) + { + Array.Copy(data, 2064 * i, sector, 0, 2064); + + if(!WriteSectorLong(sector, sectorAddress + i)) + return false; + } + + ErrorMessage = ""; + + return true; + + default: + if(data.Length % 2352 != 0) + { + ErrorMessage = Localization.Incorrect_data_size; + + return false; + } + + sector = new byte[2352]; + + for(uint i = 0; i < length; i++) + { + Array.Copy(data, 2352 * i, sector, 0, 2352); + + if(!WriteSectorLong(sector, sectorAddress + i)) + return false; + } + + ErrorMessage = ""; + + return true; } - - sector = new byte[2352]; - - for(uint i = 0; i < length; i++) - { - Array.Copy(data, 2352 * i, sector, 0, 2352); - - if(!WriteSectorLong(sector, sectorAddress + i)) - return false; - } - - ErrorMessage = ""; - - return true; + case MetadataMediaType.BlockMedia: switch(_imageInfo.MediaType) { @@ -4037,25 +4082,25 @@ public sealed partial class AaruFormat blockStream.Close(); } - if(_sectorCpiMai != null) + if(_sectorCprMai != null) { idxEntry = new IndexEntry { blockType = BlockType.DataBlock, - dataType = DataType.DvdSectorCpiMai, + dataType = DataType.DvdSectorCprMai, offset = (ulong)_imageStream.Position }; AaruConsole.DebugWriteLine("Aaru Format plugin", - Localization.Writing_DVD_CPI_MAI_block_to_position_0, idxEntry.offset); + Localization.Writing_DVD_CPR_MAI_block_to_position_0, idxEntry.offset); - Crc64Context.Data(_sectorCpiMai, out byte[] blockCrc); + Crc64Context.Data(_sectorCprMai, out byte[] blockCrc); - var cpiMaiBlock = new BlockHeader + var cprMaiBlock = new BlockHeader { identifier = BlockType.DataBlock, - type = DataType.DvdSectorCpiMai, - length = (uint)_sectorCpiMai.Length, + type = DataType.DvdSectorCprMai, + length = (uint)_sectorCprMai.Length, crc64 = BitConverter.ToUInt64(blockCrc, 0), sectorSize = 6 }; @@ -4064,28 +4109,28 @@ public sealed partial class AaruFormat if(!_compress) { - cpiMaiBlock.compression = CompressionType.None; - cpiMaiBlock.cmpCrc64 = cpiMaiBlock.crc64; - cpiMaiBlock.cmpLength = cpiMaiBlock.length; - blockStream = new MemoryStream(_sectorCpiMai); + cprMaiBlock.compression = CompressionType.None; + cprMaiBlock.cmpCrc64 = cprMaiBlock.crc64; + cprMaiBlock.cmpLength = cprMaiBlock.length; + blockStream = new MemoryStream(_sectorCprMai); } else { startCompress = DateTime.Now; - byte[] cmpBuffer = new byte[_sectorCpiMai.Length + 262144]; + byte[] cmpBuffer = new byte[_sectorCprMai.Length + 262144]; int cmpLen; switch(_compressionAlgorithm) { case CompressionType.Lzma: - cmpLen = LZMA.EncodeBuffer(_sectorCpiMai, cmpBuffer, out lzmaProperties, 9, + cmpLen = LZMA.EncodeBuffer(_sectorCprMai, cmpBuffer, out lzmaProperties, 9, _dictionarySize, 4, 0, 2, 273); break; case CompressionType.None: - cmpBuffer = _sectorCpiMai; + cmpBuffer = _sectorCprMai; cmpLen = cmpBuffer.Length; break; @@ -4101,32 +4146,317 @@ public sealed partial class AaruFormat cmpCrc.Update(blockStream.ToArray()); blockCrc = cmpCrc.Final(); - cpiMaiBlock.cmpLength = (uint)blockStream.Length; + cprMaiBlock.cmpLength = (uint)blockStream.Length; if(_compressionAlgorithm == CompressionType.Lzma) - cpiMaiBlock.cmpLength += LZMA_PROPERTIES_LENGTH; + cprMaiBlock.cmpLength += LZMA_PROPERTIES_LENGTH; - cpiMaiBlock.cmpCrc64 = BitConverter.ToUInt64(blockCrc, 0); - cpiMaiBlock.compression = _compressionAlgorithm; + cprMaiBlock.cmpCrc64 = BitConverter.ToUInt64(blockCrc, 0); + cprMaiBlock.compression = _compressionAlgorithm; endCompress = DateTime.Now; AaruConsole.DebugWriteLine("Aaru Format plugin", - Localization.Took_0_seconds_to_compress_CPI_MAI, + Localization.Took_0_seconds_to_compress_CPR_MAI, (endCompress - startCompress).TotalSeconds); } _structureBytes = new byte[Marshal.SizeOf()]; - MemoryMarshal.Write(_structureBytes, ref cpiMaiBlock); + MemoryMarshal.Write(_structureBytes, ref cprMaiBlock); _imageStream.Write(_structureBytes, 0, _structureBytes.Length); - if(cpiMaiBlock.compression is CompressionType.Lzma + if(cprMaiBlock.compression is CompressionType.Lzma 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.DvdSectorCpiMai }); + _index.RemoveAll(t => t is { blockType: BlockType.DataBlock, dataType: DataType.DvdSectorCprMai }); + + _index.Add(idxEntry); + blockStream.Close(); + } + + if(_sectorId != null) + { + idxEntry = new IndexEntry + { + blockType = BlockType.DataBlock, + dataType = DataType.DvdSectorId, + offset = (ulong)_imageStream.Position + }; + + AaruConsole.DebugWriteLine("Aaru Format plugin", + Localization.Writing_DVD_ID_block_to_position_0, idxEntry.offset); + + Crc64Context.Data(_sectorId, out byte[] blockCrc); + + var idBlock = new BlockHeader + { + identifier = BlockType.DataBlock, + type = DataType.DvdSectorId, + length = (uint)_sectorId.Length, + crc64 = BitConverter.ToUInt64(blockCrc, 0), + sectorSize = 4 + }; + + byte[] lzmaProperties = null; + + if(!_compress) + { + idBlock.compression = CompressionType.None; + idBlock.cmpCrc64 = idBlock.crc64; + idBlock.cmpLength = idBlock.length; + blockStream = new MemoryStream(_sectorId); + } + else + { + startCompress = DateTime.Now; + + byte[] cmpBuffer = new byte[_sectorId.Length + 262144]; + + int cmpLen; + + switch(_compressionAlgorithm) + { + case CompressionType.Lzma: + cmpLen = LZMA.EncodeBuffer(_sectorId, cmpBuffer, out lzmaProperties, 9, + _dictionarySize, 4, 0, 2, 273); + + break; + case CompressionType.None: + cmpBuffer = _sectorId; + cmpLen = cmpBuffer.Length; + + break; + default: throw new ArgumentOutOfRangeException(); + } + + blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); + + var cmpCrc = new Crc64Context(); + + if(_compressionAlgorithm == CompressionType.Lzma) + cmpCrc.Update(lzmaProperties); + + cmpCrc.Update(blockStream.ToArray()); + blockCrc = cmpCrc.Final(); + idBlock.cmpLength = (uint)blockStream.Length; + + if(_compressionAlgorithm == CompressionType.Lzma) + idBlock.cmpLength += LZMA_PROPERTIES_LENGTH; + + idBlock.cmpCrc64 = BitConverter.ToUInt64(blockCrc, 0); + idBlock.compression = _compressionAlgorithm; + + endCompress = DateTime.Now; + + AaruConsole.DebugWriteLine("Aaru Format plugin", + Localization.Took_0_seconds_to_compress_ID, + (endCompress - startCompress).TotalSeconds); + } + + _structureBytes = new byte[Marshal.SizeOf()]; + MemoryMarshal.Write(_structureBytes, ref idBlock); + _imageStream.Write(_structureBytes, 0, _structureBytes.Length); + + if(idBlock.compression is CompressionType.Lzma + 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.DvdSectorId }); + + _index.Add(idxEntry); + blockStream.Close(); + } + + if(_sectorIed != null) + { + idxEntry = new IndexEntry + { + blockType = BlockType.DataBlock, + dataType = DataType.DvdSectorIed, + offset = (ulong)_imageStream.Position + }; + + AaruConsole.DebugWriteLine("Aaru Format plugin", + Localization.Writing_DVD_IED_block_to_position_0, idxEntry.offset); + + Crc64Context.Data(_sectorIed, out byte[] blockCrc); + + var iedBlock = new BlockHeader + { + identifier = BlockType.DataBlock, + type = DataType.DvdSectorIed, + length = (uint)_sectorIed.Length, + crc64 = BitConverter.ToUInt64(blockCrc, 0), + sectorSize = 2 + }; + + byte[] lzmaProperties = null; + + if(!_compress) + { + iedBlock.compression = CompressionType.None; + iedBlock.cmpCrc64 = iedBlock.crc64; + iedBlock.cmpLength = iedBlock.length; + blockStream = new MemoryStream(_sectorIed); + } + else + { + startCompress = DateTime.Now; + + byte[] cmpBuffer = new byte[_sectorIed.Length + 262144]; + + int cmpLen; + + switch(_compressionAlgorithm) + { + case CompressionType.Lzma: + cmpLen = LZMA.EncodeBuffer(_sectorIed, cmpBuffer, out lzmaProperties, 9, + _dictionarySize, 4, 0, 2, 273); + + break; + case CompressionType.None: + cmpBuffer = _sectorIed; + cmpLen = cmpBuffer.Length; + + break; + default: throw new ArgumentOutOfRangeException(); + } + + blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); + + var cmpCrc = new Crc64Context(); + + if(_compressionAlgorithm == CompressionType.Lzma) + cmpCrc.Update(lzmaProperties); + + cmpCrc.Update(blockStream.ToArray()); + blockCrc = cmpCrc.Final(); + iedBlock.cmpLength = (uint)blockStream.Length; + + if(_compressionAlgorithm == CompressionType.Lzma) + iedBlock.cmpLength += LZMA_PROPERTIES_LENGTH; + + iedBlock.cmpCrc64 = BitConverter.ToUInt64(blockCrc, 0); + iedBlock.compression = _compressionAlgorithm; + + endCompress = DateTime.Now; + + AaruConsole.DebugWriteLine("Aaru Format plugin", + Localization.Took_0_seconds_to_compress_IED, + (endCompress - startCompress).TotalSeconds); + } + + _structureBytes = new byte[Marshal.SizeOf()]; + MemoryMarshal.Write(_structureBytes, ref iedBlock); + _imageStream.Write(_structureBytes, 0, _structureBytes.Length); + + if(iedBlock.compression is CompressionType.Lzma + 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.DvdSectorIed }); + + _index.Add(idxEntry); + blockStream.Close(); + } + + if(_sectorEdc != null) + { + idxEntry = new IndexEntry + { + blockType = BlockType.DataBlock, + dataType = DataType.DvdSectorEdc, + offset = (ulong)_imageStream.Position + }; + + AaruConsole.DebugWriteLine("Aaru Format plugin", + Localization.Writing_DVD_EDC_block_to_position_0, idxEntry.offset); + + Crc64Context.Data(_sectorEdc, out byte[] blockCrc); + + var edcBlock = new BlockHeader + { + identifier = BlockType.DataBlock, + type = DataType.DvdSectorEdc, + length = (uint)_sectorEdc.Length, + crc64 = BitConverter.ToUInt64(blockCrc, 0), + sectorSize = 4 + }; + + byte[] lzmaProperties = null; + + if(!_compress) + { + edcBlock.compression = CompressionType.None; + edcBlock.cmpCrc64 = edcBlock.crc64; + edcBlock.cmpLength = edcBlock.length; + blockStream = new MemoryStream(_sectorEdc); + } + else + { + startCompress = DateTime.Now; + + byte[] cmpBuffer = new byte[_sectorEdc.Length + 262144]; + + int cmpLen; + + switch(_compressionAlgorithm) + { + case CompressionType.Lzma: + cmpLen = LZMA.EncodeBuffer(_sectorEdc, cmpBuffer, out lzmaProperties, 9, + _dictionarySize, 4, 0, 2, 273); + + break; + case CompressionType.None: + cmpBuffer = _sectorEdc; + cmpLen = cmpBuffer.Length; + + break; + default: throw new ArgumentOutOfRangeException(); + } + + blockStream = new MemoryStream(cmpBuffer, 0, cmpLen); + + var cmpCrc = new Crc64Context(); + + if(_compressionAlgorithm == CompressionType.Lzma) + cmpCrc.Update(lzmaProperties); + + cmpCrc.Update(blockStream.ToArray()); + blockCrc = cmpCrc.Final(); + edcBlock.cmpLength = (uint)blockStream.Length; + + if(_compressionAlgorithm == CompressionType.Lzma) + edcBlock.cmpLength += LZMA_PROPERTIES_LENGTH; + + edcBlock.cmpCrc64 = BitConverter.ToUInt64(blockCrc, 0); + edcBlock.compression = _compressionAlgorithm; + + endCompress = DateTime.Now; + + AaruConsole.DebugWriteLine("Aaru Format plugin", + Localization.Took_0_seconds_to_compress_EDC, + (endCompress - startCompress).TotalSeconds); + } + + _structureBytes = new byte[Marshal.SizeOf()]; + MemoryMarshal.Write(_structureBytes, ref edcBlock); + _imageStream.Write(_structureBytes, 0, _structureBytes.Length); + + if(edcBlock.compression is CompressionType.Lzma + 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.DvdSectorEdc }); _index.Add(idxEntry); blockStream.Close(); @@ -4929,7 +5259,7 @@ public sealed partial class AaruFormat return true; } - case SectorTagType.DvdCmi: + case SectorTagType.DvdSectorCmi: { if(data.Length != 1) { @@ -4938,13 +5268,14 @@ public sealed partial class AaruFormat return false; } - _sectorCpiMai ??= new byte[_imageInfo.Sectors * 6]; + _sectorCprMai ??= new byte[_imageInfo.Sectors * 6]; - Array.Copy(data, 0, _sectorCpiMai, (int)(6 * sectorAddress), 1); + Array.Copy(data, 0, _sectorCprMai, (int)(6 * sectorAddress), 1); return true; } - case SectorTagType.DvdTitleKey: + + case SectorTagType.DvdSectorTitleKey: { if(data.Length != 5) { @@ -4953,12 +5284,77 @@ public sealed partial class AaruFormat return false; } - _sectorCpiMai ??= new byte[_imageInfo.Sectors * 6]; + _sectorCprMai ??= new byte[_imageInfo.Sectors * 6]; - Array.Copy(data, 0, _sectorCpiMai, (int)(1 + (6 * sectorAddress)), 5); + Array.Copy(data, 0, _sectorCprMai, (int)(1 + (6 * sectorAddress)), 5); return true; } + + case SectorTagType.DvdSectorInformation: + { + if(data.Length != 1) + { + ErrorMessage = Localization.Incorrect_data_size_for_dvd_id_information; + + return false; + } + + _sectorId ??= new byte[_imageInfo.Sectors * 4]; + + Array.Copy(data, 0, _sectorId, (int)(4 * sectorAddress), 1); + + return true; + } + + case SectorTagType.DvdSectorNumber: + { + if(data.Length != 3) + { + ErrorMessage = Localization.Incorrect_data_size_for_dvd_id_number; + + return false; + } + + _sectorId ??= new byte[_imageInfo.Sectors * 4]; + + Array.Copy(data, 0, _sectorId, (int)(1 + (4 * sectorAddress)), 3); + + return true; + } + + case SectorTagType.DvdSectorIed: + { + if(data.Length != 2) + { + ErrorMessage = Localization.Incorrect_data_size_for_ied; + + return false; + } + + _sectorIed ??= new byte[_imageInfo.Sectors * 2]; + + Array.Copy(data, 0, _sectorIed, (int)(2 * sectorAddress), 2); + + return true; + } + + case SectorTagType.DvdSectorEdc: + { + if(data.Length != 4) + { + ErrorMessage = Localization.Incorrect_data_size_for_edc; + + return false; + } + + _sectorEdc ??= new byte[_imageInfo.Sectors * 4]; + + Array.Copy(data, 0, _sectorEdc, (int)(4 * sectorAddress), 4); + + return true; + } + case SectorTagType.DvdTitleKeyDecrypted: { if(data.Length != 5) diff --git a/Aaru.Images/Alcohol120/Read.cs b/Aaru.Images/Alcohol120/Read.cs index 64a6b3c12..7666d371d 100644 --- a/Aaru.Images/Alcohol120/Read.cs +++ b/Aaru.Images/Alcohol120/Read.cs @@ -43,6 +43,7 @@ using Aaru.Decoders.CD; using Aaru.Decoders.DVD; using Aaru.Helpers; using DMI = Aaru.Decoders.Xbox.DMI; +using Sector = Aaru.Decoders.CD.Sector; namespace Aaru.DiscImages; diff --git a/Aaru.Images/BlindWrite5/Read.cs b/Aaru.Images/BlindWrite5/Read.cs index 818b8ee64..5d2435f17 100644 --- a/Aaru.Images/BlindWrite5/Read.cs +++ b/Aaru.Images/BlindWrite5/Read.cs @@ -49,6 +49,7 @@ using Aaru.Decoders.SCSI.MMC; using Aaru.Filters; using Aaru.Helpers; using DMI = Aaru.Decoders.Xbox.DMI; +using Sector = Aaru.Decoders.CD.Sector; using Session = Aaru.CommonTypes.Structs.Session; namespace Aaru.DiscImages; diff --git a/Aaru.Images/Localization/Localization.Designer.cs b/Aaru.Images/Localization/Localization.Designer.cs index 85316b7ec..dd6a020eb 100644 --- a/Aaru.Images/Localization/Localization.Designer.cs +++ b/Aaru.Images/Localization/Localization.Designer.cs @@ -789,15 +789,51 @@ namespace Aaru.DiscImages { } } - internal static string Writing_DVD_CPI_MAI_block_to_position_0 { + internal static string Writing_DVD_CPR_MAI_block_to_position_0 { get { - return ResourceManager.GetString("Writing_DVD_CPI_MAI_block_to_position_0", resourceCulture); + return ResourceManager.GetString("Writing_DVD_CPR_MAI_block_to_position_0", resourceCulture); } } - internal static string Took_0_seconds_to_compress_CPI_MAI { + internal static string Took_0_seconds_to_compress_CPR_MAI { get { - return ResourceManager.GetString("Took_0_seconds_to_compress_CPI_MAI", resourceCulture); + return ResourceManager.GetString("Took_0_seconds_to_compress_CPR_MAI", resourceCulture); + } + } + + internal static string Writing_DVD_ID_block_to_position_0 { + get { + return ResourceManager.GetString("Writing_DVD_ID_block_to_position_0", resourceCulture); + } + } + + internal static string Took_0_seconds_to_compress_ID { + get { + return ResourceManager.GetString("Took_0_seconds_to_compress_ID", resourceCulture); + } + } + + internal static string Writing_DVD_IED_block_to_position_0 { + get { + return ResourceManager.GetString("Writing_DVD_IED_block_to_position_0", resourceCulture); + } + } + + internal static string Took_0_seconds_to_compress_IED { + get { + return ResourceManager.GetString("Took_0_seconds_to_compress_IED", resourceCulture); + } + } + + internal static string Writing_DVD_EDC_block_to_position_0 { + get { + return ResourceManager.GetString("Writing_DVD_EDC_block_to_position_0", resourceCulture); + } + } + + internal static string Took_0_seconds_to_compress_EDC { + get { + return ResourceManager.GetString("Took_0_seconds_to_compress_EDC", resourceCulture); } } @@ -891,6 +927,30 @@ namespace Aaru.DiscImages { } } + internal static string Incorrect_data_size_for_dvd_id_information { + get { + return ResourceManager.GetString("Incorrect_data_size_for_dvd_id_information", resourceCulture); + } + } + + internal static string Incorrect_data_size_for_dvd_id_number { + get { + return ResourceManager.GetString("Incorrect_data_size_for_dvd_id_number", resourceCulture); + } + } + + internal static string Incorrect_data_size_for_ied { + get { + return ResourceManager.GetString("Incorrect_data_size_for_ied", resourceCulture); + } + } + + internal static string Incorrect_data_size_for_edc { + get { + return ResourceManager.GetString("Incorrect_data_size_for_edc", resourceCulture); + } + } + internal static string Incorrect_data_size_for_decrypted_title_key { get { return ResourceManager.GetString("Incorrect_data_size_for_decrypted_title_key", resourceCulture); diff --git a/Aaru.Images/Localization/Localization.resx b/Aaru.Images/Localization/Localization.resx index 27011c819..3706d1859 100644 --- a/Aaru.Images/Localization/Localization.resx +++ b/Aaru.Images/Localization/Localization.resx @@ -397,11 +397,29 @@ Took {0} seconds to compress subchannel - - Writing DVD CPI_MAI block to position {0} + + Writing DVD CPR_MAI block to position {0} - - Took {0} seconds to compress CPI_MAI + + Took {0} seconds to compress CPR_MAI + + + Writing DVD ID block to position {0} + + + Took {0} seconds to compress ID + + + Writing DVD IED block to position {0} + + + Took {0} seconds to compress IED + + + Writing DVD EDC block to position {0} + + + Took {0} seconds to compress EDC Writing decrypted DVD title key block to position {0} @@ -448,6 +466,18 @@ Incorrect data size for title key + + Incorrect data size for DVD ID information + + + Incorrect data size for DVD ID number + + + Incorrect data size for IED + + + Incorrect data size for EDC + Incorrect data size for decrypted title key diff --git a/Aaru.Images/ZZZRawImage/Helpers.cs b/Aaru.Images/ZZZRawImage/Helpers.cs index 2576ed56f..cbd78553d 100644 --- a/Aaru.Images/ZZZRawImage/Helpers.cs +++ b/Aaru.Images/ZZZRawImage/Helpers.cs @@ -38,6 +38,12 @@ public sealed partial class ZZZRawImage { MediaType CalculateDiskType() { + if(_rawDvd) + { + // TODO: Add all types + return MediaType.DVDROM; + } + if(_imageInfo.SectorSize == 2048) return _imageInfo.Sectors switch { diff --git a/Aaru.Images/ZZZRawImage/Identify.cs b/Aaru.Images/ZZZRawImage/Identify.cs index bf1b6e727..468aa529c 100644 --- a/Aaru.Images/ZZZRawImage/Identify.cs +++ b/Aaru.Images/ZZZRawImage/Identify.cs @@ -59,6 +59,7 @@ public sealed partial class ZZZRawImage case ".256": return imageFilter.DataForkLength % 256 == 0; case ".toast" when imageFilter.DataForkLength % 2048 == 0: return true; case ".toast" when imageFilter.DataForkLength % 2056 == 0: return true; + case ".raw" when imageFilter.DataForkLength % 2064 == 0: return true; // Handle this properly on Open() //case ".toast" when imageFilter.DataForkLength % 2336 == 0: return true; diff --git a/Aaru.Images/ZZZRawImage/Read.cs b/Aaru.Images/ZZZRawImage/Read.cs index 1e92aa8db..23107b8e5 100644 --- a/Aaru.Images/ZZZRawImage/Read.cs +++ b/Aaru.Images/ZZZRawImage/Read.cs @@ -51,6 +51,7 @@ using Schemas; using DMI = Aaru.Decoders.Xbox.DMI; using File = System.IO.File; using Inquiry = Aaru.CommonTypes.Structs.Devices.SCSI.Inquiry; +using Sector = Aaru.Decoders.CD.Sector; using Session = Aaru.CommonTypes.Structs.Session; using Track = Aaru.CommonTypes.Structs.Track; using TrackType = Aaru.CommonTypes.Enums.TrackType; @@ -143,6 +144,11 @@ public sealed partial class ZZZRawImage case ".d81" when imageFilter.DataForkLength == 819200: _imageInfo.SectorSize = 256; + break; + case ".raw" when imageFilter.DataForkLength % 2064 == 0: + _imageInfo.SectorSize = 2048; + _rawDvd = true; + break; default: switch(_extension) @@ -377,6 +383,9 @@ public sealed partial class ZZZRawImage if(_toastXa) _imageInfo.MediaType = MediaType.CD; + if(_rawDvd) + _imageInfo.Sectors = _imageInfo.ImageSize / 2064; + // Sharp X68000 SASI hard disks if(_extension == ".hdf") if(_imageInfo.ImageSize % 256 == 0) @@ -1163,6 +1172,27 @@ public sealed partial class ZZZRawImage } _imageInfo.ReadableMediaTags = new List(_mediaTags.Keys); + + if(_rawDvd) + { + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorInformation)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorInformation); + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorNumber)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorNumber); + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorIed)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorIed); + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorCmi)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorCmi); + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorTitleKey)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorTitleKey); + + if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorEdc)) + _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorEdc); + } if(!_rawCompactDisc && !_toastXa) @@ -1254,6 +1284,13 @@ public sealed partial class ZZZRawImage if(_hasSubchannel) sectorSkip += 96; + if(_rawDvd) + { + sectorOffset = 12; + sectorSize = 2048; + sectorSkip = 4; + } + buffer = new byte[sectorSize * length]; var br = new BinaryReader(stream); @@ -1281,10 +1318,19 @@ public sealed partial class ZZZRawImage else for(int i = 0; i < length; i++) { - br.BaseStream.Seek(sectorOffset, SeekOrigin.Current); - byte[] sector = br.ReadBytes((int)sectorSize); - br.BaseStream.Seek(sectorSkip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); + if(_rawDvd) + { + byte[] sector = br.ReadBytes((int)(sectorSize + sectorSkip + sectorOffset)); + sector = _decoding.Scramble(sector); + Array.Copy(sector, sectorOffset, buffer, i * sectorSize, sectorSize); + } + else + { + br.BaseStream.Seek(sectorOffset, SeekOrigin.Current); + byte[] sector = br.ReadBytes((int)sectorSize); + br.BaseStream.Seek(sectorSkip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); + } } return ErrorNumber.NoError; @@ -1418,7 +1464,7 @@ public sealed partial class ZZZRawImage buffer = null; if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc || - (!_rawCompactDisc && !_toastXa && tag != SectorTagType.CdTrackFlags)) + (!_rawCompactDisc && !_toastXa && !_rawDvd && tag != SectorTagType.CdTrackFlags)) return ErrorNumber.NotSupported; if(tag == SectorTagType.CdTrackFlags) @@ -1534,6 +1580,60 @@ public sealed partial class ZZZRawImage break; } + case SectorTagType.DvdSectorNumber: + { + sectorOffset = 1; + sectorSize = 3; + sectorSkip = 2060; + + break; + } + + case SectorTagType.DvdSectorInformation: + { + sectorOffset = 0; + sectorSize = 1; + sectorSkip = 2063; + + break; + } + + case SectorTagType.DvdSectorIed: + { + sectorOffset = 4; + sectorSize = 2; + sectorSkip = 2058; + + break; + } + + case SectorTagType.DvdSectorCmi: + { + sectorOffset = 6; + sectorSize = 1; + sectorSkip = 2057; + + break; + } + + case SectorTagType.DvdSectorTitleKey: + { + sectorOffset = 7; + sectorSize = 5; + sectorSkip = 2052; + + break; + } + + case SectorTagType.DvdSectorEdc: + { + sectorOffset = 2060; + sectorSize = 4; + sectorSkip = 0; + + break; + } + default: return ErrorNumber.NotSupported; } @@ -1568,7 +1668,7 @@ public sealed partial class ZZZRawImage buffer = null; if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc || - (!_rawCompactDisc && !_toastXa)) + (!_rawCompactDisc && !_toastXa && !_rawDvd)) return ErrorNumber.NotSupported; if(sectorAddress > _imageInfo.Sectors - 1) @@ -1577,7 +1677,14 @@ public sealed partial class ZZZRawImage if(sectorAddress + length > _imageInfo.Sectors) return ErrorNumber.OutOfRange; - uint sectorSize = _toastXa ? 2056u : 2352u; + uint sectorSize = 2352u; + + if(_toastXa) + sectorSize = 2056u; + + if(_rawDvd) + sectorSize = 2064u; + uint sectorSkip = 0; if(_hasSubchannel) @@ -1604,6 +1711,15 @@ public sealed partial class ZZZRawImage Array.Copy(fullSector, 0, buffer, i * 2352, 2352); } } + else if(_rawDvd) + { + for(int i = 0; i < length; i++) + { + byte[] sector = br.ReadBytes((int)(sectorSize)); + sector = _decoding.Scramble(sector); + Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); + } + } else if(sectorSkip == 0) buffer = br.ReadBytes((int)(sectorSize * length)); else diff --git a/Aaru.Images/ZZZRawImage/ZZZRawImage.cs b/Aaru.Images/ZZZRawImage/ZZZRawImage.cs index fd1444ee3..6eb02bfdf 100644 --- a/Aaru.Images/ZZZRawImage/ZZZRawImage.cs +++ b/Aaru.Images/ZZZRawImage/ZZZRawImage.cs @@ -36,6 +36,7 @@ using System.IO; using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Structs; +using Aaru.Decoders.DVD; namespace Aaru.DiscImages; @@ -53,8 +54,10 @@ public sealed partial class ZZZRawImage : IWritableOpticalImage bool _mode2; bool _toastXa; bool _rawCompactDisc; + bool _rawDvd; IFilter _rawImageFilter; FileStream _writingStream; + Sector _decoding = new Sector(); /// Implements reading and writing raw (sector by sector) images public ZZZRawImage() => _imageInfo = new ImageInfo diff --git a/Aaru/Commands/Image/Convert.cs b/Aaru/Commands/Image/Convert.cs index c11d521c3..3c014d62c 100644 --- a/Aaru/Commands/Image/Convert.cs +++ b/Aaru/Commands/Image/Convert.cs @@ -885,7 +885,7 @@ sealed class ConvertImageCommand : Command if(sectorsToDo == 1) { if(inputOptical.ReadSectorTag(doneSectors + track.StartSector, - SectorTagType.DvdCmi, out cmi) == ErrorNumber.NoError && + SectorTagType.DvdSectorCmi, out cmi) == ErrorNumber.NoError && inputOptical.ReadSectorTag(doneSectors + track.StartSector, SectorTagType.DvdTitleKeyDecrypted, out titleKey) == ErrorNumber.NoError) @@ -927,7 +927,7 @@ sealed class ConvertImageCommand : Command else { if(inputOptical.ReadSectorsTag(doneSectors + track.StartSector, - sectorsToDo, SectorTagType.DvdCmi, out cmi) == + sectorsToDo, SectorTagType.DvdSectorCmi, out cmi) == ErrorNumber.NoError && inputOptical.ReadSectorsTag(doneSectors + track.StartSector, sectorsToDo, SectorTagType.DvdTitleKeyDecrypted, @@ -1100,6 +1100,12 @@ sealed class ConvertImageCommand : Command case SectorTagType.CdSectorEccP: case SectorTagType.CdSectorEccQ: case SectorTagType.CdSectorEcc: + case SectorTagType.DvdSectorCmi: + case SectorTagType.DvdSectorTitleKey: + case SectorTagType.DvdSectorEdc: + case SectorTagType.DvdSectorIed: + case SectorTagType.DvdSectorInformation: + case SectorTagType.DvdSectorNumber: // This tags are inline in long sector continue; }