Add reader for DiscImageCreator DVD Raw dumps (#817)

This commit is contained in:
Rebecca Wallander
2023-08-22 16:27:52 +02:00
committed by GitHub
parent d1d9e0833e
commit ebf893e278
19 changed files with 798 additions and 95 deletions

View File

@@ -136,7 +136,7 @@ partial class Dump
outputFormat.WriteSectorTag(new[] outputFormat.WriteSectorTag(new[]
{ {
titleKey.Value.CMI titleKey.Value.CMI
}, i + j, SectorTagType.DvdCmi); }, i + j, SectorTagType.DvdSectorCmi);
else else
continue; continue;
@@ -147,7 +147,7 @@ partial class Dump
outputFormat.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKey); }, i + j, SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
@@ -166,7 +166,7 @@ partial class Dump
outputFormat.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, i + j, SectorTagType.DvdTitleKey); }, i + j, SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
@@ -178,7 +178,7 @@ partial class Dump
continue; continue;
} }
outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey); outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdSectorTitleKey);
_resume.MissingTitleKeys.Remove(i + j); _resume.MissingTitleKeys.Remove(i + j);
CSS.DecryptTitleKey(discKey, titleKey.Value.Key, out tmpBuf); 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 // Todo: Flag in the outputFormat that a sector has been decrypted
{ {
ErrorNumber errno = ErrorNumber errno =
outputFormat.ReadSectorsTag(i, blocksToRead, SectorTagType.DvdCmi, out byte[] cmi); outputFormat.ReadSectorsTag(i, blocksToRead, SectorTagType.DvdSectorCmi, out byte[] cmi);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
ErrorMessage?.Invoke(string.Format(Localization.Core.Error_retrieving_CMI_for_sector_0, i)); ErrorMessage?.Invoke(string.Format(Localization.Core.Error_retrieving_CMI_for_sector_0, i));

View File

@@ -378,7 +378,7 @@ partial class Dump
outputFormat.WriteSectorTag(new[] outputFormat.WriteSectorTag(new[]
{ {
titleKey.Value.CMI 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 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 // If the decoded title key is zeroed, there should be no copy protection
@@ -388,7 +388,7 @@ partial class Dump
outputFormat.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, missingKey, SectorTagType.DvdTitleKey); }, missingKey, SectorTagType.DvdSectorTitleKey);
outputFormat.WriteSectorTag(new byte[] outputFormat.WriteSectorTag(new byte[]
{ {
@@ -404,7 +404,7 @@ partial class Dump
} }
else else
{ {
outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdTitleKey); outputFormat.WriteSectorTag(titleKey.Value.Key, missingKey, SectorTagType.DvdSectorTitleKey);
_resume.MissingTitleKeys.Remove(missingKey); _resume.MissingTitleKeys.Remove(missingKey);
if(discKey != null) if(discKey != null)

View File

@@ -48,6 +48,7 @@ using Aaru.Decoders.Sega;
using Aaru.Devices; using Aaru.Devices;
using Aaru.Helpers; using Aaru.Helpers;
using DMI = Aaru.Decoders.Xbox.DMI; using DMI = Aaru.Decoders.Xbox.DMI;
using Sector = Aaru.Decoders.CD.Sector;
namespace Aaru.Core.Media.Detection; namespace Aaru.Core.Media.Detection;

View File

@@ -93,7 +93,7 @@ public partial class Device
/// If set to <c>true</c> requested blocks shall be assigned the lowest retention priority on cache /// If set to <c>true</c> requested blocks shall be assigned the lowest retention priority on cache
/// fetch/retain. /// fetch/retain.
/// </param> /// </param>
/// <param name="fua">If set to <c>true</c> requested blocks MUST bu read from medium and not the cache.</param> /// <param name="fua">If set to <c>true</c> requested blocks MUST be read from medium and not the cache.</param>
/// <param name="fuaNv"> /// <param name="fuaNv">
/// If set to <c>true</c> requested blocks will be returned from non-volatile cache. If they're not /// If set to <c>true</c> requested blocks will be returned from non-volatile cache. If they're not
/// present they shall be stored there. /// present they shall be stored there.

View File

@@ -128,7 +128,10 @@ public sealed partial class AaruFormat : IWritableOpticalImage, IVerifiableImage
/// <summary>If DDT is on-disk, this is the image stream offset at which it starts.</summary> /// <summary>If DDT is on-disk, this is the image stream offset at which it starts.</summary>
long _outMemoryDdtPosition; long _outMemoryDdtPosition;
bool _rewinded; bool _rewinded;
byte[] _sectorCpiMai; byte[] _sectorCprMai;
byte[] _sectorIed;
byte[] _sectorId;
byte[] _sectorEdc;
byte[] _sectorDecryptedTitleKey; byte[] _sectorDecryptedTitleKey;
/// <summary>Cache for data that prefixes the user data on a sector (e.g. sync).</summary> /// <summary>Cache for data that prefixes the user data on a sector (e.g. sync).</summary>
byte[] _sectorPrefix; byte[] _sectorPrefix;

View File

@@ -214,10 +214,16 @@ public sealed partial class AaruFormat
CompactDiscLeadIn = 79, CompactDiscLeadIn = 79,
/// <summary>Decrypted DVD Disc Key</summary> /// <summary>Decrypted DVD Disc Key</summary>
DvdDiscKeyDecrypted = 80, DvdDiscKeyDecrypted = 80,
/// <summary>DVD CPI_MAI</summary> /// <summary>DVD Copyright Management Information (CPR_MAI)</summary>
DvdSectorCpiMai = 81, DvdSectorCprMai = 81,
/// <summary>Decrypted DVD Title Key</summary> /// <summary>Decrypted DVD Title Key</summary>
DvdSectorTitleKeyDecrypted = 82 DvdSectorTitleKeyDecrypted = 82,
/// <summary>DVD Identification Data (ID)</summary>
DvdSectorId = 83,
/// <summary>DVD ID Error Detection Code (IED)</summary>
DvdSectorIed = 84,
/// <summary>DVD Error Detection Code (EDC)</summary>
DvdSectorEdc = 85
} }
/// <summary>List of known blocks types</summary> /// <summary>List of known blocks types</summary>

View File

@@ -382,14 +382,47 @@ public sealed partial class AaruFormat
GC.GetTotalMemory(false)); GC.GetTotalMemory(false));
break; break;
case DataType.DvdSectorCpiMai: case DataType.DvdSectorCprMai:
_sectorCpiMai = data; _sectorCprMai = data;
if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdCmi)) if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorCmi))
_imageInfo.ReadableSectorTags.Add(SectorTagType.DvdCmi); _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorCmi);
if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdTitleKey)) if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorTitleKey))
_imageInfo.ReadableSectorTags.Add(SectorTagType.DvdTitleKey); _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, AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes,
GC.GetTotalMemory(false)); GC.GetTotalMemory(false));
@@ -1769,8 +1802,12 @@ public sealed partial class AaruFormat
case SectorTagType.CdSectorSubchannel: case SectorTagType.CdSectorSubchannel:
case SectorTagType.CdSectorSubHeader: case SectorTagType.CdSectorSubHeader:
case SectorTagType.CdSectorSync: case SectorTagType.CdSectorSync:
case SectorTagType.DvdCmi: case SectorTagType.DvdSectorCmi:
case SectorTagType.DvdTitleKey: case SectorTagType.DvdSectorTitleKey:
case SectorTagType.DvdSectorInformation:
case SectorTagType.DvdSectorNumber:
case SectorTagType.DvdSectorIed:
case SectorTagType.DvdSectorEdc:
case SectorTagType.DvdTitleKeyDecrypted: break; case SectorTagType.DvdTitleKeyDecrypted: break;
case SectorTagType.CdTrackFlags: case SectorTagType.CdTrackFlags:
if(!_trackFlags.TryGetValue((byte)sectorAddress, out byte flags)) if(!_trackFlags.TryGetValue((byte)sectorAddress, out byte flags))
@@ -1954,21 +1991,57 @@ public sealed partial class AaruFormat
if(_imageInfo.MediaType == MediaType.DVDROM) if(_imageInfo.MediaType == MediaType.DVDROM)
switch(tag) switch(tag)
{ {
case SectorTagType.DvdCmi: case SectorTagType.DvdSectorCmi:
{ {
sectorOffset = 0; sectorOffset = 0;
sectorSize = 1; sectorSize = 1;
sectorSkip = 5; sectorSkip = 5;
dataSource = _sectorCpiMai; dataSource = _sectorCprMai;
break; break;
} }
case SectorTagType.DvdTitleKey: case SectorTagType.DvdSectorTitleKey:
{ {
sectorOffset = 1; sectorOffset = 1;
sectorSize = 5; sectorSize = 5;
sectorSkip = 0; 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; break;
} }

View File

@@ -554,14 +554,14 @@ public sealed partial class AaruFormat
GC.GetTotalMemory(false)); GC.GetTotalMemory(false));
break; break;
case DataType.DvdSectorCpiMai: case DataType.DvdSectorCprMai:
_sectorCpiMai = data; _sectorCprMai = data;
if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdCmi)) if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorCmi))
_imageInfo.ReadableSectorTags.Add(SectorTagType.DvdCmi); _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorCmi);
if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdTitleKey)) if(!_imageInfo.ReadableSectorTags.Contains(SectorTagType.DvdSectorTitleKey))
_imageInfo.ReadableSectorTags.Add(SectorTagType.DvdTitleKey); _imageInfo.ReadableSectorTags.Add(SectorTagType.DvdSectorTitleKey);
AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes, AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes,
GC.GetTotalMemory(false)); GC.GetTotalMemory(false));
@@ -2030,6 +2030,24 @@ public sealed partial class AaruFormat
track.EndSector == 0) track.EndSector == 0)
track.Type = TrackType.Data; 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) if(data.Length != 2352)
{ {
ErrorMessage = Localization.Incorrect_data_size; ErrorMessage = Localization.Incorrect_data_size;
@@ -2426,26 +2444,53 @@ public sealed partial class AaruFormat
switch(_imageInfo.MetadataMediaType) switch(_imageInfo.MetadataMediaType)
{ {
case MetadataMediaType.OpticalDisc: 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: case MetadataMediaType.BlockMedia:
switch(_imageInfo.MediaType) switch(_imageInfo.MediaType)
{ {
@@ -4037,25 +4082,25 @@ public sealed partial class AaruFormat
blockStream.Close(); blockStream.Close();
} }
if(_sectorCpiMai != null) if(_sectorCprMai != null)
{ {
idxEntry = new IndexEntry idxEntry = new IndexEntry
{ {
blockType = BlockType.DataBlock, blockType = BlockType.DataBlock,
dataType = DataType.DvdSectorCpiMai, dataType = DataType.DvdSectorCprMai,
offset = (ulong)_imageStream.Position offset = (ulong)_imageStream.Position
}; };
AaruConsole.DebugWriteLine("Aaru Format plugin", 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, identifier = BlockType.DataBlock,
type = DataType.DvdSectorCpiMai, type = DataType.DvdSectorCprMai,
length = (uint)_sectorCpiMai.Length, length = (uint)_sectorCprMai.Length,
crc64 = BitConverter.ToUInt64(blockCrc, 0), crc64 = BitConverter.ToUInt64(blockCrc, 0),
sectorSize = 6 sectorSize = 6
}; };
@@ -4064,28 +4109,28 @@ public sealed partial class AaruFormat
if(!_compress) if(!_compress)
{ {
cpiMaiBlock.compression = CompressionType.None; cprMaiBlock.compression = CompressionType.None;
cpiMaiBlock.cmpCrc64 = cpiMaiBlock.crc64; cprMaiBlock.cmpCrc64 = cprMaiBlock.crc64;
cpiMaiBlock.cmpLength = cpiMaiBlock.length; cprMaiBlock.cmpLength = cprMaiBlock.length;
blockStream = new MemoryStream(_sectorCpiMai); blockStream = new MemoryStream(_sectorCprMai);
} }
else else
{ {
startCompress = DateTime.Now; startCompress = DateTime.Now;
byte[] cmpBuffer = new byte[_sectorCpiMai.Length + 262144]; byte[] cmpBuffer = new byte[_sectorCprMai.Length + 262144];
int cmpLen; int cmpLen;
switch(_compressionAlgorithm) switch(_compressionAlgorithm)
{ {
case CompressionType.Lzma: case CompressionType.Lzma:
cmpLen = LZMA.EncodeBuffer(_sectorCpiMai, cmpBuffer, out lzmaProperties, 9, cmpLen = LZMA.EncodeBuffer(_sectorCprMai, cmpBuffer, out lzmaProperties, 9,
_dictionarySize, 4, 0, 2, 273); _dictionarySize, 4, 0, 2, 273);
break; break;
case CompressionType.None: case CompressionType.None:
cmpBuffer = _sectorCpiMai; cmpBuffer = _sectorCprMai;
cmpLen = cmpBuffer.Length; cmpLen = cmpBuffer.Length;
break; break;
@@ -4101,32 +4146,317 @@ public sealed partial class AaruFormat
cmpCrc.Update(blockStream.ToArray()); cmpCrc.Update(blockStream.ToArray());
blockCrc = cmpCrc.Final(); blockCrc = cmpCrc.Final();
cpiMaiBlock.cmpLength = (uint)blockStream.Length; cprMaiBlock.cmpLength = (uint)blockStream.Length;
if(_compressionAlgorithm == CompressionType.Lzma) if(_compressionAlgorithm == CompressionType.Lzma)
cpiMaiBlock.cmpLength += LZMA_PROPERTIES_LENGTH; cprMaiBlock.cmpLength += LZMA_PROPERTIES_LENGTH;
cpiMaiBlock.cmpCrc64 = BitConverter.ToUInt64(blockCrc, 0); cprMaiBlock.cmpCrc64 = BitConverter.ToUInt64(blockCrc, 0);
cpiMaiBlock.compression = _compressionAlgorithm; cprMaiBlock.compression = _compressionAlgorithm;
endCompress = DateTime.Now; endCompress = DateTime.Now;
AaruConsole.DebugWriteLine("Aaru Format plugin", AaruConsole.DebugWriteLine("Aaru Format plugin",
Localization.Took_0_seconds_to_compress_CPI_MAI, Localization.Took_0_seconds_to_compress_CPR_MAI,
(endCompress - startCompress).TotalSeconds); (endCompress - startCompress).TotalSeconds);
} }
_structureBytes = new byte[Marshal.SizeOf<BlockHeader>()]; _structureBytes = new byte[Marshal.SizeOf<BlockHeader>()];
MemoryMarshal.Write(_structureBytes, ref cpiMaiBlock); MemoryMarshal.Write(_structureBytes, ref cprMaiBlock);
_imageStream.Write(_structureBytes, 0, _structureBytes.Length); _imageStream.Write(_structureBytes, 0, _structureBytes.Length);
if(cpiMaiBlock.compression is CompressionType.Lzma if(cprMaiBlock.compression is CompressionType.Lzma
or CompressionType.LzmaClauniaSubchannelTransform) or CompressionType.LzmaClauniaSubchannelTransform)
_imageStream.Write(lzmaProperties, 0, lzmaProperties.Length); _imageStream.Write(lzmaProperties, 0, lzmaProperties.Length);
_imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.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<BlockHeader>()];
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<BlockHeader>()];
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<BlockHeader>()];
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); _index.Add(idxEntry);
blockStream.Close(); blockStream.Close();
@@ -4929,7 +5259,7 @@ public sealed partial class AaruFormat
return true; return true;
} }
case SectorTagType.DvdCmi: case SectorTagType.DvdSectorCmi:
{ {
if(data.Length != 1) if(data.Length != 1)
{ {
@@ -4938,13 +5268,14 @@ public sealed partial class AaruFormat
return false; 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; return true;
} }
case SectorTagType.DvdTitleKey:
case SectorTagType.DvdSectorTitleKey:
{ {
if(data.Length != 5) if(data.Length != 5)
{ {
@@ -4953,12 +5284,77 @@ public sealed partial class AaruFormat
return false; 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; 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: case SectorTagType.DvdTitleKeyDecrypted:
{ {
if(data.Length != 5) if(data.Length != 5)

View File

@@ -43,6 +43,7 @@ using Aaru.Decoders.CD;
using Aaru.Decoders.DVD; using Aaru.Decoders.DVD;
using Aaru.Helpers; using Aaru.Helpers;
using DMI = Aaru.Decoders.Xbox.DMI; using DMI = Aaru.Decoders.Xbox.DMI;
using Sector = Aaru.Decoders.CD.Sector;
namespace Aaru.DiscImages; namespace Aaru.DiscImages;

View File

@@ -49,6 +49,7 @@ using Aaru.Decoders.SCSI.MMC;
using Aaru.Filters; using Aaru.Filters;
using Aaru.Helpers; using Aaru.Helpers;
using DMI = Aaru.Decoders.Xbox.DMI; using DMI = Aaru.Decoders.Xbox.DMI;
using Sector = Aaru.Decoders.CD.Sector;
using Session = Aaru.CommonTypes.Structs.Session; using Session = Aaru.CommonTypes.Structs.Session;
namespace Aaru.DiscImages; namespace Aaru.DiscImages;

View File

@@ -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 { 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 { 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 { internal static string Incorrect_data_size_for_decrypted_title_key {
get { get {
return ResourceManager.GetString("Incorrect_data_size_for_decrypted_title_key", resourceCulture); return ResourceManager.GetString("Incorrect_data_size_for_decrypted_title_key", resourceCulture);

View File

@@ -397,11 +397,29 @@
<data name="Took_0_seconds_to_compress_subchannel" xml:space="preserve"> <data name="Took_0_seconds_to_compress_subchannel" xml:space="preserve">
<value>Took {0} seconds to compress subchannel</value> <value>Took {0} seconds to compress subchannel</value>
</data> </data>
<data name="Writing_DVD_CPI_MAI_block_to_position_0" xml:space="preserve"> <data name="Writing_DVD_CPR_MAI_block_to_position_0" xml:space="preserve">
<value>Writing DVD CPI_MAI block to position {0}</value> <value>Writing DVD CPR_MAI block to position {0}</value>
</data> </data>
<data name="Took_0_seconds_to_compress_CPI_MAI" xml:space="preserve"> <data name="Took_0_seconds_to_compress_CPR_MAI" xml:space="preserve">
<value>Took {0} seconds to compress CPI_MAI</value> <value>Took {0} seconds to compress CPR_MAI</value>
</data>
<data name="Writing_DVD_ID_block_to_position_0" xml:space="preserve">
<value>Writing DVD ID block to position {0}</value>
</data>
<data name="Took_0_seconds_to_compress_ID" xml:space="preserve">
<value>Took {0} seconds to compress ID</value>
</data>
<data name="Writing_DVD_IED_block_to_position_0" xml:space="preserve">
<value>Writing DVD IED block to position {0}</value>
</data>
<data name="Took_0_seconds_to_compress_IED" xml:space="preserve">
<value>Took {0} seconds to compress IED</value>
</data>
<data name="Writing_DVD_EDC_block_to_position_0" xml:space="preserve">
<value>Writing DVD EDC block to position {0}</value>
</data>
<data name="Took_0_seconds_to_compress_EDC" xml:space="preserve">
<value>Took {0} seconds to compress EDC</value>
</data> </data>
<data name="Writing_decrypted_DVD_title_key_block_to_position_0" xml:space="preserve"> <data name="Writing_decrypted_DVD_title_key_block_to_position_0" xml:space="preserve">
<value>Writing decrypted DVD title key block to position {0}</value> <value>Writing decrypted DVD title key block to position {0}</value>
@@ -448,6 +466,18 @@
<data name="Incorrect_data_size_for_title_key" xml:space="preserve"> <data name="Incorrect_data_size_for_title_key" xml:space="preserve">
<value>Incorrect data size for title key</value> <value>Incorrect data size for title key</value>
</data> </data>
<data name="Incorrect_data_size_for_dvd_id_information" xml:space="preserve">
<value>Incorrect data size for DVD ID information</value>
</data>
<data name="Incorrect_data_size_for_dvd_id_number" xml:space="preserve">
<value>Incorrect data size for DVD ID number</value>
</data>
<data name="Incorrect_data_size_for_ied" xml:space="preserve">
<value>Incorrect data size for IED</value>
</data>
<data name="Incorrect_data_size_for_edc" xml:space="preserve">
<value>Incorrect data size for EDC</value>
</data>
<data name="Incorrect_data_size_for_decrypted_title_key" xml:space="preserve"> <data name="Incorrect_data_size_for_decrypted_title_key" xml:space="preserve">
<value>Incorrect data size for decrypted title key</value> <value>Incorrect data size for decrypted title key</value>
</data> </data>

View File

@@ -38,6 +38,12 @@ public sealed partial class ZZZRawImage
{ {
MediaType CalculateDiskType() MediaType CalculateDiskType()
{ {
if(_rawDvd)
{
// TODO: Add all types
return MediaType.DVDROM;
}
if(_imageInfo.SectorSize == 2048) if(_imageInfo.SectorSize == 2048)
return _imageInfo.Sectors switch return _imageInfo.Sectors switch
{ {

View File

@@ -59,6 +59,7 @@ public sealed partial class ZZZRawImage
case ".256": return imageFilter.DataForkLength % 256 == 0; case ".256": return imageFilter.DataForkLength % 256 == 0;
case ".toast" when imageFilter.DataForkLength % 2048 == 0: return true; case ".toast" when imageFilter.DataForkLength % 2048 == 0: return true;
case ".toast" when imageFilter.DataForkLength % 2056 == 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() // Handle this properly on Open()
//case ".toast" when imageFilter.DataForkLength % 2336 == 0: return true; //case ".toast" when imageFilter.DataForkLength % 2336 == 0: return true;

View File

@@ -51,6 +51,7 @@ using Schemas;
using DMI = Aaru.Decoders.Xbox.DMI; using DMI = Aaru.Decoders.Xbox.DMI;
using File = System.IO.File; using File = System.IO.File;
using Inquiry = Aaru.CommonTypes.Structs.Devices.SCSI.Inquiry; using Inquiry = Aaru.CommonTypes.Structs.Devices.SCSI.Inquiry;
using Sector = Aaru.Decoders.CD.Sector;
using Session = Aaru.CommonTypes.Structs.Session; using Session = Aaru.CommonTypes.Structs.Session;
using Track = Aaru.CommonTypes.Structs.Track; using Track = Aaru.CommonTypes.Structs.Track;
using TrackType = Aaru.CommonTypes.Enums.TrackType; using TrackType = Aaru.CommonTypes.Enums.TrackType;
@@ -143,6 +144,11 @@ public sealed partial class ZZZRawImage
case ".d81" when imageFilter.DataForkLength == 819200: case ".d81" when imageFilter.DataForkLength == 819200:
_imageInfo.SectorSize = 256; _imageInfo.SectorSize = 256;
break;
case ".raw" when imageFilter.DataForkLength % 2064 == 0:
_imageInfo.SectorSize = 2048;
_rawDvd = true;
break; break;
default: default:
switch(_extension) switch(_extension)
@@ -377,6 +383,9 @@ public sealed partial class ZZZRawImage
if(_toastXa) if(_toastXa)
_imageInfo.MediaType = MediaType.CD; _imageInfo.MediaType = MediaType.CD;
if(_rawDvd)
_imageInfo.Sectors = _imageInfo.ImageSize / 2064;
// Sharp X68000 SASI hard disks // Sharp X68000 SASI hard disks
if(_extension == ".hdf") if(_extension == ".hdf")
if(_imageInfo.ImageSize % 256 == 0) if(_imageInfo.ImageSize % 256 == 0)
@@ -1163,6 +1172,27 @@ public sealed partial class ZZZRawImage
} }
_imageInfo.ReadableMediaTags = new List<MediaTagType>(_mediaTags.Keys); _imageInfo.ReadableMediaTags = new List<MediaTagType>(_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 && if(!_rawCompactDisc &&
!_toastXa) !_toastXa)
@@ -1254,6 +1284,13 @@ public sealed partial class ZZZRawImage
if(_hasSubchannel) if(_hasSubchannel)
sectorSkip += 96; sectorSkip += 96;
if(_rawDvd)
{
sectorOffset = 12;
sectorSize = 2048;
sectorSkip = 4;
}
buffer = new byte[sectorSize * length]; buffer = new byte[sectorSize * length];
var br = new BinaryReader(stream); var br = new BinaryReader(stream);
@@ -1281,10 +1318,19 @@ public sealed partial class ZZZRawImage
else else
for(int i = 0; i < length; i++) for(int i = 0; i < length; i++)
{ {
br.BaseStream.Seek(sectorOffset, SeekOrigin.Current); if(_rawDvd)
byte[] sector = br.ReadBytes((int)sectorSize); {
br.BaseStream.Seek(sectorSkip, SeekOrigin.Current); byte[] sector = br.ReadBytes((int)(sectorSize + sectorSkip + sectorOffset));
Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); 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; return ErrorNumber.NoError;
@@ -1418,7 +1464,7 @@ public sealed partial class ZZZRawImage
buffer = null; buffer = null;
if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc || if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc ||
(!_rawCompactDisc && !_toastXa && tag != SectorTagType.CdTrackFlags)) (!_rawCompactDisc && !_toastXa && !_rawDvd && tag != SectorTagType.CdTrackFlags))
return ErrorNumber.NotSupported; return ErrorNumber.NotSupported;
if(tag == SectorTagType.CdTrackFlags) if(tag == SectorTagType.CdTrackFlags)
@@ -1534,6 +1580,60 @@ public sealed partial class ZZZRawImage
break; 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; default: return ErrorNumber.NotSupported;
} }
@@ -1568,7 +1668,7 @@ public sealed partial class ZZZRawImage
buffer = null; buffer = null;
if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc || if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc ||
(!_rawCompactDisc && !_toastXa)) (!_rawCompactDisc && !_toastXa && !_rawDvd))
return ErrorNumber.NotSupported; return ErrorNumber.NotSupported;
if(sectorAddress > _imageInfo.Sectors - 1) if(sectorAddress > _imageInfo.Sectors - 1)
@@ -1577,7 +1677,14 @@ public sealed partial class ZZZRawImage
if(sectorAddress + length > _imageInfo.Sectors) if(sectorAddress + length > _imageInfo.Sectors)
return ErrorNumber.OutOfRange; return ErrorNumber.OutOfRange;
uint sectorSize = _toastXa ? 2056u : 2352u; uint sectorSize = 2352u;
if(_toastXa)
sectorSize = 2056u;
if(_rawDvd)
sectorSize = 2064u;
uint sectorSkip = 0; uint sectorSkip = 0;
if(_hasSubchannel) if(_hasSubchannel)
@@ -1604,6 +1711,15 @@ public sealed partial class ZZZRawImage
Array.Copy(fullSector, 0, buffer, i * 2352, 2352); 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) else if(sectorSkip == 0)
buffer = br.ReadBytes((int)(sectorSize * length)); buffer = br.ReadBytes((int)(sectorSize * length));
else else

View File

@@ -36,6 +36,7 @@ using System.IO;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs; using Aaru.CommonTypes.Structs;
using Aaru.Decoders.DVD;
namespace Aaru.DiscImages; namespace Aaru.DiscImages;
@@ -53,8 +54,10 @@ public sealed partial class ZZZRawImage : IWritableOpticalImage
bool _mode2; bool _mode2;
bool _toastXa; bool _toastXa;
bool _rawCompactDisc; bool _rawCompactDisc;
bool _rawDvd;
IFilter _rawImageFilter; IFilter _rawImageFilter;
FileStream _writingStream; FileStream _writingStream;
Sector _decoding = new Sector();
/// <summary>Implements reading and writing raw (sector by sector) images</summary> /// <summary>Implements reading and writing raw (sector by sector) images</summary>
public ZZZRawImage() => _imageInfo = new ImageInfo public ZZZRawImage() => _imageInfo = new ImageInfo

View File

@@ -885,7 +885,7 @@ sealed class ConvertImageCommand : Command
if(sectorsToDo == 1) if(sectorsToDo == 1)
{ {
if(inputOptical.ReadSectorTag(doneSectors + track.StartSector, if(inputOptical.ReadSectorTag(doneSectors + track.StartSector,
SectorTagType.DvdCmi, out cmi) == ErrorNumber.NoError && SectorTagType.DvdSectorCmi, out cmi) == ErrorNumber.NoError &&
inputOptical.ReadSectorTag(doneSectors + track.StartSector, inputOptical.ReadSectorTag(doneSectors + track.StartSector,
SectorTagType.DvdTitleKeyDecrypted, out titleKey) == SectorTagType.DvdTitleKeyDecrypted, out titleKey) ==
ErrorNumber.NoError) ErrorNumber.NoError)
@@ -927,7 +927,7 @@ sealed class ConvertImageCommand : Command
else else
{ {
if(inputOptical.ReadSectorsTag(doneSectors + track.StartSector, if(inputOptical.ReadSectorsTag(doneSectors + track.StartSector,
sectorsToDo, SectorTagType.DvdCmi, out cmi) == sectorsToDo, SectorTagType.DvdSectorCmi, out cmi) ==
ErrorNumber.NoError && ErrorNumber.NoError &&
inputOptical.ReadSectorsTag(doneSectors + track.StartSector, inputOptical.ReadSectorsTag(doneSectors + track.StartSector,
sectorsToDo, SectorTagType.DvdTitleKeyDecrypted, sectorsToDo, SectorTagType.DvdTitleKeyDecrypted,
@@ -1100,6 +1100,12 @@ sealed class ConvertImageCommand : Command
case SectorTagType.CdSectorEccP: case SectorTagType.CdSectorEccP:
case SectorTagType.CdSectorEccQ: case SectorTagType.CdSectorEccQ:
case SectorTagType.CdSectorEcc: 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 // This tags are inline in long sector
continue; continue;
} }