mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add reader for DiscImageCreator DVD Raw dumps (#817)
This commit is contained in:
committed by
GitHub
parent
d1d9e0833e
commit
ebf893e278
Submodule Aaru.CommonTypes updated: d007f1ac9a...1d4add3282
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Submodule Aaru.Decoders updated: 66c6b4b7f9...6e0e9405ae
@@ -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
|
||||
/// fetch/retain.
|
||||
/// </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">
|
||||
/// 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.
|
||||
|
||||
@@ -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>
|
||||
long _outMemoryDdtPosition;
|
||||
bool _rewinded;
|
||||
byte[] _sectorCpiMai;
|
||||
byte[] _sectorCprMai;
|
||||
byte[] _sectorIed;
|
||||
byte[] _sectorId;
|
||||
byte[] _sectorEdc;
|
||||
byte[] _sectorDecryptedTitleKey;
|
||||
/// <summary>Cache for data that prefixes the user data on a sector (e.g. sync).</summary>
|
||||
byte[] _sectorPrefix;
|
||||
|
||||
@@ -214,10 +214,16 @@ public sealed partial class AaruFormat
|
||||
CompactDiscLeadIn = 79,
|
||||
/// <summary>Decrypted DVD Disc Key</summary>
|
||||
DvdDiscKeyDecrypted = 80,
|
||||
/// <summary>DVD CPI_MAI</summary>
|
||||
DvdSectorCpiMai = 81,
|
||||
/// <summary>DVD Copyright Management Information (CPR_MAI)</summary>
|
||||
DvdSectorCprMai = 81,
|
||||
/// <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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,6 +2444,31 @@ public sealed partial class AaruFormat
|
||||
switch(_imageInfo.MetadataMediaType)
|
||||
{
|
||||
case MetadataMediaType.OpticalDisc:
|
||||
switch(_imageInfo.MediaType)
|
||||
{
|
||||
case MediaType.DVDROM:
|
||||
if(data.Length % 2064 != 0)
|
||||
{
|
||||
ErrorMessage = Localization.Incorrect_data_size;
|
||||
|
||||
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;
|
||||
@@ -2446,6 +2489,8 @@ public sealed partial class AaruFormat
|
||||
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<BlockHeader>()];
|
||||
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<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);
|
||||
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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
68
Aaru.Images/Localization/Localization.Designer.cs
generated
68
Aaru.Images/Localization/Localization.Designer.cs
generated
@@ -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);
|
||||
|
||||
@@ -397,11 +397,29 @@
|
||||
<data name="Took_0_seconds_to_compress_subchannel" xml:space="preserve">
|
||||
<value>Took {0} seconds to compress subchannel</value>
|
||||
</data>
|
||||
<data name="Writing_DVD_CPI_MAI_block_to_position_0" xml:space="preserve">
|
||||
<value>Writing DVD CPI_MAI block to position {0}</value>
|
||||
<data name="Writing_DVD_CPR_MAI_block_to_position_0" xml:space="preserve">
|
||||
<value>Writing DVD CPR_MAI block to position {0}</value>
|
||||
</data>
|
||||
<data name="Took_0_seconds_to_compress_CPI_MAI" xml:space="preserve">
|
||||
<value>Took {0} seconds to compress CPI_MAI</value>
|
||||
<data name="Took_0_seconds_to_compress_CPR_MAI" xml:space="preserve">
|
||||
<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 name="Writing_decrypted_DVD_title_key_block_to_position_0" xml:space="preserve">
|
||||
<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">
|
||||
<value>Incorrect data size for title key</value>
|
||||
</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">
|
||||
<value>Incorrect data size for decrypted title key</value>
|
||||
</data>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
@@ -1164,6 +1173,27 @@ public sealed partial class ZZZRawImage
|
||||
|
||||
_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 &&
|
||||
!_toastXa)
|
||||
return ErrorNumber.NoError;
|
||||
@@ -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);
|
||||
@@ -1280,12 +1317,21 @@ public sealed partial class ZZZRawImage
|
||||
buffer = br.ReadBytes((int)(sectorSize * length));
|
||||
else
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
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
|
||||
|
||||
@@ -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();
|
||||
|
||||
/// <summary>Implements reading and writing raw (sector by sector) images</summary>
|
||||
public ZZZRawImage() => _imageInfo = new ImageInfo
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user