[AaruFormat] Remove old implementation.

This commit is contained in:
2025-10-14 02:54:21 +01:00
parent 6b170b94d1
commit 08f63f8aa3
13 changed files with 0 additions and 11057 deletions

View File

@@ -1,191 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : AaruFormat.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Manages Aaru Format disk images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// Copyright © 2020-2025 Rebecca Wallander
// ****************************************************************************/
/*
The idea of the format is being able to easily store, retrieve, and access any data that can be read from media.
At the start of a file there's a header that contains a format version, application creator name, and a pointer to
the index.
The index points to one or several DeDuplication Tables, or media tag blocks.
A deduplication table is a table of offsets to blocks and sectors inside blocks. Each entry equals to an LBA and points
to a byte offset in the file shift left to the number of sectors contained in a block, plus the number of sector inside
the block.
Each block must contain sectors of equal size, but that size can be different between blocks.
The deduplication table should be stored decompressed if its size is too big to be stored on-memory. This is chosen at
creation time but it is a good idea to set the limit to 256MiB (this allows for a device of 33 million sectors,
17Gb at 512 bps, 68Gb at 2048 bps and 137Gb at 4096 bps).
Sector tags that are simply too small to be deduplicated are contained in a single block pointed by the index (e.g.
Apple GCR sector tags).
Optical disks contain a track block that describes the tracks.
TODO: Streaming tapes contain a file block that describes the files and an optional partition block that describes the tape
partitions.
There are also blocks for image metadata, contents metadata and dump hardware information.
A differencing image will have all the metadata and deduplication tables, but the entries in these ones will be set to
0 if the block is stored in the parent image. TODO: This is not yet implemented.
Also because the file becomes useless without the index and deduplication table, each can be stored twice. In case of
the index it should just be searched for. In case of deduplication tables, both copies should be indexed.
Finally, writing new data to an existing image is just Copy-On-Write. Create a new block with the modified data, change
the pointer in the corresponding deduplication table.
P.S.: Data Position Measurement is doable, as soon as I know how to do it.
P.S.2: Support for floppy image contaning bitslices and/or fluxes will be added soon.
*/
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using Aaru.Checksums;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
namespace Aaru.Images;
/// <inheritdoc cref="Aaru.CommonTypes.Interfaces.IWritableOpticalImage" />
/// <summary>Implements reading and writing AaruFormat media images</summary>
public sealed partial class AaruFormatOld : IWritableOpticalImage, IVerifiableImage, IWritableTapeImage
{
const string MODULE_NAME = "Aaru Format plugin";
bool _alreadyWrittenZero;
/// <summary>Cache of uncompressed blocks.</summary>
Dictionary<ulong, byte[]> _blockCache;
/// <summary>Cache of block headers.</summary>
Dictionary<ulong, BlockHeader> _blockHeaderCache;
/// <summary>Provides checksum for deduplication of sectors.</summary>
SHA256 _checksumProvider;
bool _compress;
byte[] _compressedBuffer;
CompressionType _compressionAlgorithm;
/// <summary>Provides CRC64.</summary>
Crc64Context _crc64;
/// <summary>Header of the currently writing block.</summary>
BlockHeader _currentBlockHeader;
/// <summary>Sector offset of writing position in currently writing block.</summary>
uint _currentBlockOffset;
/// <summary>Current size in bytes of the block cache</summary>
uint _currentCacheSize;
/// <summary>Cache of DDT entries.</summary>
Dictionary<ulong, ulong> _ddtEntryCache;
bool _deduplicate;
/// <summary>On-memory deduplication table indexed by checksum.</summary>
Dictionary<string, ulong> _deduplicationTable;
/// <summary>Dictionary size for compression algorithms</summary>
uint _dictionarySize;
/// <summary>Block with logical geometry.</summary>
GeometryBlock _geometryBlock;
/// <summary>Image header.</summary>
AaruHeader _header;
/// <summary>Image information.</summary>
ImageInfo _imageInfo;
/// <summary>Image data stream.</summary>
Stream _imageStream;
/// <summary>Index.</summary>
List<IndexEntry> _index;
/// <summary>If set to <c>true</c>, the DDT entries are in-memory.</summary>
bool _inMemoryDdt;
ulong _lastWrittenBlock;
Md5Context _md5Provider;
/// <summary>Cache of media tags.</summary>
Dictionary<MediaTagType, byte[]> _mediaTags;
byte[] _mode2Subheaders;
/// <summary>If DDT is on-disk, this is the image stream offset at which it starts.</summary>
long _outMemoryDdtPosition;
bool _rewinded;
byte[] _sectorCprMai;
byte[] _sectorDecryptedTitleKey;
byte[] _sectorEdc;
byte[] _sectorId;
byte[] _sectorIed;
/// <summary>Cache for data that prefixes the user data on a sector (e.g. sync).</summary>
byte[] _sectorPrefix;
uint[] _sectorPrefixDdt;
MemoryStream _sectorPrefixMs;
/// <summary>Cache for data that goes side by side with user data (e.g. CompactDisc subchannel).</summary>
byte[] _sectorSubchannel;
/// <summary>Cache for data that suffixes the user data on a sector (e.g. edc, ecc).</summary>
byte[] _sectorSuffix;
uint[] _sectorSuffixDdt;
MemoryStream _sectorSuffixMs;
Sha1Context _sha1Provider;
Sha256Context _sha256Provider;
/// <summary>Shift for calculating number of sectors in a block.</summary>
byte _shift;
SpamSumContext _spamsumProvider;
/// <summary>Cache for bytes to write/rad on-disk.</summary>
byte[] _structureBytes;
/// <summary>Cache for pointer for marshaling structures.</summary>
nint _structurePointer;
Dictionary<ulong, ulong> _tapeDdt;
/// <summary>Cache of CompactDisc track's flags</summary>
Dictionary<byte, byte> _trackFlags;
/// <summary>Cache of CompactDisc track's ISRC</summary>
Dictionary<byte, string> _trackIsrcs;
/// <summary>In-memory deduplication table</summary>
ulong[] _userDataDdt;
byte[] _writingBuffer;
int _writingBufferPosition;
bool _writingLong;
ulong _writtenSectors;
public AaruFormatOld() => _imageInfo = new ImageInfo
{
ReadableSectorTags = [],
ReadableMediaTags = [],
HasPartitions = false,
HasSessions = false,
Version = null,
Application = "Aaru",
ApplicationVersion = null,
Creator = null,
Comments = null,
MediaManufacturer = null,
MediaModel = null,
MediaSerialNumber = null,
MediaBarcode = null,
MediaPartNumber = null,
MediaSequence = 0,
LastMediaSequence = 0,
DriveManufacturer = null,
DriveModel = null,
DriveSerialNumber = null,
DriveFirmwareRevision = null
};
}

View File

@@ -1,343 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : ClauniaSubchannelTransform.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains the CD ECC algorithm.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ECC algorithm from ECM(c) 2002-2011 Neill Corlett
// ****************************************************************************/
using System;
using Aaru.CommonTypes.Enums;
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
byte[] _eccBTable;
byte[] _eccFTable;
uint[] _edcTable;
bool _initedEdc;
void EccInit()
{
if(_initedEdc) return;
_eccFTable = new byte[256];
_eccBTable = new byte[256];
_edcTable = new uint[256];
for(uint i = 0; i < 256; i++)
{
uint edc = i;
var j = (uint)(i << 1 ^ ((i & 0x80) == 0x80 ? 0x11D : 0));
_eccFTable[i] = (byte)j;
_eccBTable[i ^ j] = (byte)i;
for(j = 0; j < 8; j++) edc = edc >> 1 ^ ((edc & 1) > 0 ? 0xD8018001 : 0);
_edcTable[i] = edc;
}
_initedEdc = true;
}
bool SuffixIsCorrect(byte[] sector)
{
if(!_initedEdc) EccInit();
if(sector[0x814] != 0x00 || // reserved (8 bytes)
sector[0x815] != 0x00 ||
sector[0x816] != 0x00 ||
sector[0x817] != 0x00 ||
sector[0x818] != 0x00 ||
sector[0x819] != 0x00 ||
sector[0x81A] != 0x00 ||
sector[0x81B] != 0x00)
return false;
bool correctEccP = CheckEcc(sector, sector, 86, 24, 2, 86, sector, 0xC, 0x10, 0x81C);
if(!correctEccP) return false;
bool correctEccQ = CheckEcc(sector, sector, 52, 43, 86, 88, sector, 0xC, 0x10, 0x81C + 0xAC);
if(!correctEccQ) return false;
var storedEdc = BitConverter.ToUInt32(sector, 0x810);
uint edc = 0;
var size = 0x810;
var pos = 0;
for(; size > 0; size--) edc = edc >> 8 ^ _edcTable[(edc ^ sector[pos++]) & 0xFF];
uint calculatedEdc = edc;
return calculatedEdc == storedEdc;
}
bool SuffixIsCorrectMode2(byte[] sector)
{
if(!_initedEdc) EccInit();
var zeroAddress = new byte[4];
bool correctEccP = CheckEcc(zeroAddress, sector, 86, 24, 2, 86, sector, 0, 0x10, 0x81C);
if(!correctEccP) return false;
bool correctEccQ = CheckEcc(zeroAddress, sector, 52, 43, 86, 88, sector, 0, 0x10, 0x81C + 0xAC);
if(!correctEccQ) return false;
var storedEdc = BitConverter.ToUInt32(sector, 0x818);
uint edc = 0;
var size = 0x808;
var pos = 0x10;
for(; size > 0; size--) edc = edc >> 8 ^ _edcTable[(edc ^ sector[pos++]) & 0xFF];
uint calculatedEdc = edc;
return calculatedEdc == storedEdc;
}
bool CheckEcc(byte[] address, byte[] data, uint majorCount, uint minorCount, uint majorMult, uint minorInc,
byte[] ecc, int addressOffset, int dataOffset, int eccOffset)
{
uint size = majorCount * minorCount;
uint major;
for(major = 0; major < majorCount; major++)
{
uint idx = (major >> 1) * majorMult + (major & 1);
byte eccA = 0;
byte eccB = 0;
uint minor;
for(minor = 0; minor < minorCount; minor++)
{
byte temp = idx < 4 ? address[idx + addressOffset] : data[idx + dataOffset - 4];
idx += minorInc;
if(idx >= size) idx -= size;
eccA ^= temp;
eccB ^= temp;
eccA = _eccFTable[eccA];
}
eccA = _eccBTable[_eccFTable[eccA] ^ eccB];
if(ecc[major + eccOffset] != eccA || ecc[major + majorCount + eccOffset] != (eccA ^ eccB)) return false;
}
return true;
}
void WriteEcc(byte[] address, byte[] data, uint majorCount, uint minorCount, uint majorMult, uint minorInc,
ref byte[] ecc, int addressOffset, int dataOffset, int eccOffset)
{
uint size = majorCount * minorCount;
uint major;
for(major = 0; major < majorCount; major++)
{
uint idx = (major >> 1) * majorMult + (major & 1);
byte eccA = 0;
byte eccB = 0;
uint minor;
for(minor = 0; minor < minorCount; minor++)
{
byte temp = idx < 4 ? address[idx + addressOffset] : data[idx + dataOffset - 4];
idx += minorInc;
if(idx >= size) idx -= size;
eccA ^= temp;
eccB ^= temp;
eccA = _eccFTable[eccA];
}
eccA = _eccBTable[_eccFTable[eccA] ^ eccB];
ecc[major + eccOffset] = eccA;
ecc[major + majorCount + eccOffset] = (byte)(eccA ^ eccB);
}
}
void EccWriteSector(byte[] address, byte[] data, ref byte[] ecc, int addressOffset, int dataOffset, int eccOffset)
{
WriteEcc(address, data, 86, 24, 2, 86, ref ecc, addressOffset, dataOffset, eccOffset); // P
WriteEcc(address, data, 52, 43, 86, 88, ref ecc, addressOffset, dataOffset, eccOffset + 0xAC); // Q
}
static (byte minute, byte second, byte frame) LbaToMsf(long pos) =>
((byte)((pos + 150) / 75 / 60), (byte)((pos + 150) / 75 % 60), (byte)((pos + 150) % 75));
static void ReconstructPrefix(ref byte[] sector, // must point to a full 2352-byte sector
TrackType type, long lba)
{
//
// Sync
//
sector[0x000] = 0x00;
sector[0x001] = 0xFF;
sector[0x002] = 0xFF;
sector[0x003] = 0xFF;
sector[0x004] = 0xFF;
sector[0x005] = 0xFF;
sector[0x006] = 0xFF;
sector[0x007] = 0xFF;
sector[0x008] = 0xFF;
sector[0x009] = 0xFF;
sector[0x00A] = 0xFF;
sector[0x00B] = 0x00;
(byte minute, byte second, byte frame) msf = LbaToMsf(lba);
sector[0x00C] = (byte)((msf.minute / 10 << 4) + msf.minute % 10);
sector[0x00D] = (byte)((msf.second / 10 << 4) + msf.second % 10);
sector[0x00E] = (byte)((msf.frame / 10 << 4) + msf.frame % 10);
switch(type)
{
case TrackType.CdMode1:
//
// Mode
//
sector[0x00F] = 0x01;
break;
case TrackType.CdMode2Form1:
case TrackType.CdMode2Form2:
case TrackType.CdMode2Formless:
//
// Mode
//
sector[0x00F] = 0x02;
//
// Flags
//
sector[0x010] = sector[0x014];
sector[0x011] = sector[0x015];
sector[0x012] = sector[0x016];
sector[0x013] = sector[0x017];
break;
default:
return;
}
}
void ReconstructEcc(ref byte[] sector, // must point to a full 2352-byte sector
TrackType type)
{
byte[] computedEdc;
if(!_initedEdc) EccInit();
switch(type)
{
//
// Compute EDC
//
case TrackType.CdMode1:
computedEdc = BitConverter.GetBytes(ComputeEdc(0, sector, 0x810));
sector[0x810] = computedEdc[0];
sector[0x811] = computedEdc[1];
sector[0x812] = computedEdc[2];
sector[0x813] = computedEdc[3];
break;
case TrackType.CdMode2Form1:
computedEdc = BitConverter.GetBytes(ComputeEdc(0, sector, 0x808, 0x10));
sector[0x818] = computedEdc[0];
sector[0x819] = computedEdc[1];
sector[0x81A] = computedEdc[2];
sector[0x81B] = computedEdc[3];
break;
case TrackType.CdMode2Form2:
computedEdc = BitConverter.GetBytes(ComputeEdc(0, sector, 0x91C, 0x10));
sector[0x92C] = computedEdc[0];
sector[0x92D] = computedEdc[1];
sector[0x92E] = computedEdc[2];
sector[0x92F] = computedEdc[3];
break;
default:
return;
}
var zeroAddress = new byte[4];
switch(type)
{
//
// Compute ECC
//
case TrackType.CdMode1:
//
// Reserved
//
sector[0x814] = 0x00;
sector[0x815] = 0x00;
sector[0x816] = 0x00;
sector[0x817] = 0x00;
sector[0x818] = 0x00;
sector[0x819] = 0x00;
sector[0x81A] = 0x00;
sector[0x81B] = 0x00;
EccWriteSector(sector, sector, ref sector, 0xC, 0x10, 0x81C);
break;
case TrackType.CdMode2Form1:
EccWriteSector(zeroAddress, sector, ref sector, 0, 0x10, 0x81C);
break;
default:
return;
}
//
// Done
//
}
uint ComputeEdc(uint edc, byte[] src, int size, int srcOffset = 0)
{
if(!_initedEdc) EccInit();
int pos = srcOffset;
for(; size > 0; size--) edc = edc >> 8 ^ _edcTable[(edc ^ src[pos++]) & 0xFF];
return edc;
}
}

View File

@@ -1,310 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : ClauniaSubchannelTransform.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains the Claunia Subchannel Transform algorithm.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics;
using Aaru.Logging;
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
static byte[] ClauniaSubchannelTransform(byte[] interleaved)
{
if(interleaved == null) return null;
int[] p = new int[interleaved.Length / 8];
int[] q = new int[interleaved.Length / 8];
int[] r = new int[interleaved.Length / 8];
int[] s = new int[interleaved.Length / 8];
int[] t = new int[interleaved.Length / 8];
int[] u = new int[interleaved.Length / 8];
int[] v = new int[interleaved.Length / 8];
int[] w = new int[interleaved.Length / 8];
var stopwatch = new Stopwatch();
stopwatch.Start();
for(int i = 0; i < interleaved.Length; i += 8)
{
p[i / 8] = interleaved[i] & 0x80;
p[i / 8] += (interleaved[i + 1] & 0x80) >> 1;
p[i / 8] += (interleaved[i + 2] & 0x80) >> 2;
p[i / 8] += (interleaved[i + 3] & 0x80) >> 3;
p[i / 8] += (interleaved[i + 4] & 0x80) >> 4;
p[i / 8] += (interleaved[i + 5] & 0x80) >> 5;
p[i / 8] += (interleaved[i + 6] & 0x80) >> 6;
p[i / 8] += (interleaved[i + 7] & 0x80) >> 7;
q[i / 8] = (interleaved[i] & 0x40) << 1;
q[i / 8] += interleaved[i + 1] & 0x40;
q[i / 8] += (interleaved[i + 2] & 0x40) >> 1;
q[i / 8] += (interleaved[i + 3] & 0x40) >> 2;
q[i / 8] += (interleaved[i + 4] & 0x40) >> 3;
q[i / 8] += (interleaved[i + 5] & 0x40) >> 4;
q[i / 8] += (interleaved[i + 6] & 0x40) >> 5;
q[i / 8] += (interleaved[i + 7] & 0x40) >> 6;
r[i / 8] = (interleaved[i] & 0x20) << 2;
r[i / 8] += (interleaved[i + 1] & 0x20) << 1;
r[i / 8] += interleaved[i + 2] & 0x20;
r[i / 8] += (interleaved[i + 3] & 0x20) >> 1;
r[i / 8] += (interleaved[i + 4] & 0x20) >> 2;
r[i / 8] += (interleaved[i + 5] & 0x20) >> 3;
r[i / 8] += (interleaved[i + 6] & 0x20) >> 4;
r[i / 8] += (interleaved[i + 7] & 0x20) >> 5;
s[i / 8] = (interleaved[i] & 0x10) << 3;
s[i / 8] += (interleaved[i + 1] & 0x10) << 2;
s[i / 8] += (interleaved[i + 2] & 0x10) << 1;
s[i / 8] += interleaved[i + 3] & 0x10;
s[i / 8] += (interleaved[i + 4] & 0x10) >> 1;
s[i / 8] += (interleaved[i + 5] & 0x10) >> 2;
s[i / 8] += (interleaved[i + 6] & 0x10) >> 3;
s[i / 8] += (interleaved[i + 7] & 0x10) >> 4;
t[i / 8] = (interleaved[i] & 0x08) << 4;
t[i / 8] += (interleaved[i + 1] & 0x08) << 3;
t[i / 8] += (interleaved[i + 2] & 0x08) << 2;
t[i / 8] += (interleaved[i + 3] & 0x08) << 1;
t[i / 8] += interleaved[i + 4] & 0x08;
t[i / 8] += (interleaved[i + 5] & 0x08) >> 1;
t[i / 8] += (interleaved[i + 6] & 0x08) >> 2;
t[i / 8] += (interleaved[i + 7] & 0x08) >> 3;
u[i / 8] = (interleaved[i] & 0x04) << 5;
u[i / 8] += (interleaved[i + 1] & 0x04) << 4;
u[i / 8] += (interleaved[i + 2] & 0x04) << 3;
u[i / 8] += (interleaved[i + 3] & 0x04) << 2;
u[i / 8] += (interleaved[i + 4] & 0x04) << 1;
u[i / 8] += interleaved[i + 5] & 0x04;
u[i / 8] += (interleaved[i + 6] & 0x04) >> 1;
u[i / 8] += (interleaved[i + 7] & 0x04) >> 2;
v[i / 8] = (interleaved[i] & 0x02) << 6;
v[i / 8] += (interleaved[i + 1] & 0x02) << 5;
v[i / 8] += (interleaved[i + 2] & 0x02) << 4;
v[i / 8] += (interleaved[i + 3] & 0x02) << 3;
v[i / 8] += (interleaved[i + 4] & 0x02) << 2;
v[i / 8] += (interleaved[i + 5] & 0x02) << 1;
v[i / 8] += interleaved[i + 6] & 0x02;
v[i / 8] += (interleaved[i + 7] & 0x02) >> 1;
w[i / 8] = (interleaved[i] & 0x01) << 7;
w[i / 8] += (interleaved[i + 1] & 0x01) << 6;
w[i / 8] += (interleaved[i + 2] & 0x01) << 5;
w[i / 8] += (interleaved[i + 3] & 0x01) << 4;
w[i / 8] += (interleaved[i + 4] & 0x01) << 3;
w[i / 8] += (interleaved[i + 5] & 0x01) << 2;
w[i / 8] += (interleaved[i + 6] & 0x01) << 1;
w[i / 8] += interleaved[i + 7] & 0x01;
}
stopwatch.Stop();
TimeSpan deinterleave = stopwatch.Elapsed;
byte[] sequential = new byte[interleaved.Length];
stopwatch.Restart();
int qStart = p.Length * 1;
int rStart = p.Length * 2;
int sStart = p.Length * 3;
int tStart = p.Length * 4;
int uStart = p.Length * 5;
int vStart = p.Length * 6;
int wStart = p.Length * 7;
for(int i = 0; i < p.Length; i++)
{
sequential[i] = (byte)p[i];
sequential[qStart + i] = (byte)q[i];
sequential[rStart + i] = (byte)r[i];
sequential[sStart + i] = (byte)s[i];
sequential[tStart + i] = (byte)t[i];
sequential[uStart + i] = (byte)u[i];
sequential[vStart + i] = (byte)v[i];
sequential[wStart + i] = (byte)w[i];
}
stopwatch.Stop();
TimeSpan sequentialize = stopwatch.Elapsed;
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_ms_to_deinterleave_subchannel,
deinterleave.TotalMilliseconds);
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_ms_to_sequentialize_subchannel,
sequentialize.TotalMilliseconds);
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_ms_to_transform_subchannel,
deinterleave.TotalMilliseconds + sequentialize.TotalMilliseconds);
return sequential;
}
static byte[] ClauniaSubchannelUntransform(byte[] sequential)
{
if(sequential == null) return null;
int[] p = new int[sequential.Length / 8];
int[] q = new int[sequential.Length / 8];
int[] r = new int[sequential.Length / 8];
int[] s = new int[sequential.Length / 8];
int[] t = new int[sequential.Length / 8];
int[] u = new int[sequential.Length / 8];
int[] v = new int[sequential.Length / 8];
int[] w = new int[sequential.Length / 8];
int qStart = p.Length * 1;
int rStart = p.Length * 2;
int sStart = p.Length * 3;
int tStart = p.Length * 4;
int uStart = p.Length * 5;
int vStart = p.Length * 6;
int wStart = p.Length * 7;
var stopwatch = new Stopwatch();
stopwatch.Start();
for(int i = 0; i < p.Length; i++)
{
p[i] = sequential[i];
q[i] = sequential[qStart + i];
r[i] = sequential[rStart + i];
s[i] = sequential[sStart + i];
t[i] = sequential[tStart + i];
u[i] = sequential[uStart + i];
v[i] = sequential[vStart + i];
w[i] = sequential[wStart + i];
}
stopwatch.Stop();
TimeSpan desequentialize = stopwatch.Elapsed;
byte[] interleaved = new byte[sequential.Length];
stopwatch.Restart();
for(int i = 0; i < interleaved.Length; i += 8)
{
interleaved[i] = (byte)((p[i / 8] & 0x80) == 0x80 ? 0x80 : 0);
interleaved[i + 1] += (byte)((p[i / 8] & 0x40) == 0x40 ? 0x80 : 0);
interleaved[i + 2] += (byte)((p[i / 8] & 0x20) == 0x20 ? 0x80 : 0);
interleaved[i + 3] += (byte)((p[i / 8] & 0x10) == 0x10 ? 0x80 : 0);
interleaved[i + 4] += (byte)((p[i / 8] & 0x08) == 0x08 ? 0x80 : 0);
interleaved[i + 5] += (byte)((p[i / 8] & 0x04) == 0x04 ? 0x80 : 0);
interleaved[i + 6] += (byte)((p[i / 8] & 0x02) == 0x02 ? 0x80 : 0);
interleaved[i + 7] += (byte)((p[i / 8] & 0x01) == 0x01 ? 0x80 : 0);
interleaved[i] += (byte)((q[i / 8] & 0x80) == 0x80 ? 0x40 : 0);
interleaved[i + 1] += (byte)((q[i / 8] & 0x40) == 0x40 ? 0x40 : 0);
interleaved[i + 2] += (byte)((q[i / 8] & 0x20) == 0x20 ? 0x40 : 0);
interleaved[i + 3] += (byte)((q[i / 8] & 0x10) == 0x10 ? 0x40 : 0);
interleaved[i + 4] += (byte)((q[i / 8] & 0x08) == 0x08 ? 0x40 : 0);
interleaved[i + 5] += (byte)((q[i / 8] & 0x04) == 0x04 ? 0x40 : 0);
interleaved[i + 6] += (byte)((q[i / 8] & 0x02) == 0x02 ? 0x40 : 0);
interleaved[i + 7] += (byte)((q[i / 8] & 0x01) == 0x01 ? 0x40 : 0);
interleaved[i] += (byte)((r[i / 8] & 0x80) == 0x80 ? 0x20 : 0);
interleaved[i + 1] += (byte)((r[i / 8] & 0x40) == 0x40 ? 0x20 : 0);
interleaved[i + 2] += (byte)((r[i / 8] & 0x20) == 0x20 ? 0x20 : 0);
interleaved[i + 3] += (byte)((r[i / 8] & 0x10) == 0x10 ? 0x20 : 0);
interleaved[i + 4] += (byte)((r[i / 8] & 0x08) == 0x08 ? 0x20 : 0);
interleaved[i + 5] += (byte)((r[i / 8] & 0x04) == 0x04 ? 0x20 : 0);
interleaved[i + 6] += (byte)((r[i / 8] & 0x02) == 0x02 ? 0x20 : 0);
interleaved[i + 7] += (byte)((r[i / 8] & 0x01) == 0x01 ? 0x20 : 0);
interleaved[i] += (byte)((s[i / 8] & 0x80) == 0x80 ? 0x10 : 0);
interleaved[i + 1] += (byte)((s[i / 8] & 0x40) == 0x40 ? 0x10 : 0);
interleaved[i + 2] += (byte)((s[i / 8] & 0x20) == 0x20 ? 0x10 : 0);
interleaved[i + 3] += (byte)((s[i / 8] & 0x10) == 0x10 ? 0x10 : 0);
interleaved[i + 4] += (byte)((s[i / 8] & 0x08) == 0x08 ? 0x10 : 0);
interleaved[i + 5] += (byte)((s[i / 8] & 0x04) == 0x04 ? 0x10 : 0);
interleaved[i + 6] += (byte)((s[i / 8] & 0x02) == 0x02 ? 0x10 : 0);
interleaved[i + 7] += (byte)((s[i / 8] & 0x01) == 0x01 ? 0x10 : 0);
interleaved[i] += (byte)((t[i / 8] & 0x80) == 0x80 ? 0x08 : 0);
interleaved[i + 1] += (byte)((t[i / 8] & 0x40) == 0x40 ? 0x08 : 0);
interleaved[i + 2] += (byte)((t[i / 8] & 0x20) == 0x20 ? 0x08 : 0);
interleaved[i + 3] += (byte)((t[i / 8] & 0x10) == 0x10 ? 0x08 : 0);
interleaved[i + 4] += (byte)((t[i / 8] & 0x08) == 0x08 ? 0x08 : 0);
interleaved[i + 5] += (byte)((t[i / 8] & 0x04) == 0x04 ? 0x08 : 0);
interleaved[i + 6] += (byte)((t[i / 8] & 0x02) == 0x02 ? 0x08 : 0);
interleaved[i + 7] += (byte)((t[i / 8] & 0x01) == 0x01 ? 0x08 : 0);
interleaved[i] += (byte)((u[i / 8] & 0x80) == 0x80 ? 0x04 : 0);
interleaved[i + 1] += (byte)((u[i / 8] & 0x40) == 0x40 ? 0x04 : 0);
interleaved[i + 2] += (byte)((u[i / 8] & 0x20) == 0x20 ? 0x04 : 0);
interleaved[i + 3] += (byte)((u[i / 8] & 0x10) == 0x10 ? 0x04 : 0);
interleaved[i + 4] += (byte)((u[i / 8] & 0x08) == 0x08 ? 0x04 : 0);
interleaved[i + 5] += (byte)((u[i / 8] & 0x04) == 0x04 ? 0x04 : 0);
interleaved[i + 6] += (byte)((u[i / 8] & 0x02) == 0x02 ? 0x04 : 0);
interleaved[i + 7] += (byte)((u[i / 8] & 0x01) == 0x01 ? 0x04 : 0);
interleaved[i] += (byte)((v[i / 8] & 0x80) == 0x80 ? 0x02 : 0);
interleaved[i + 1] += (byte)((v[i / 8] & 0x40) == 0x40 ? 0x02 : 0);
interleaved[i + 2] += (byte)((v[i / 8] & 0x20) == 0x20 ? 0x02 : 0);
interleaved[i + 3] += (byte)((v[i / 8] & 0x10) == 0x10 ? 0x02 : 0);
interleaved[i + 4] += (byte)((v[i / 8] & 0x08) == 0x08 ? 0x02 : 0);
interleaved[i + 5] += (byte)((v[i / 8] & 0x04) == 0x04 ? 0x02 : 0);
interleaved[i + 6] += (byte)((v[i / 8] & 0x02) == 0x02 ? 0x02 : 0);
interleaved[i + 7] += (byte)((v[i / 8] & 0x01) == 0x01 ? 0x02 : 0);
interleaved[i] += (byte)((w[i / 8] & 0x80) == 0x80 ? 0x01 : 0);
interleaved[i + 1] += (byte)((w[i / 8] & 0x40) == 0x40 ? 0x01 : 0);
interleaved[i + 2] += (byte)((w[i / 8] & 0x20) == 0x20 ? 0x01 : 0);
interleaved[i + 3] += (byte)((w[i / 8] & 0x10) == 0x10 ? 0x01 : 0);
interleaved[i + 4] += (byte)((w[i / 8] & 0x08) == 0x08 ? 0x01 : 0);
interleaved[i + 5] += (byte)((w[i / 8] & 0x04) == 0x04 ? 0x01 : 0);
interleaved[i + 6] += (byte)((w[i / 8] & 0x02) == 0x02 ? 0x01 : 0);
interleaved[i + 7] += (byte)((w[i / 8] & 0x01) == 0x01 ? 0x01 : 0);
}
stopwatch.Stop();
TimeSpan interleave = stopwatch.Elapsed;
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_ms_to_desequentialize_subchannel,
desequentialize.TotalMilliseconds);
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_ms_to_interleave_subchannel,
interleave.TotalMilliseconds);
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_ms_to_untransform_subchannel,
interleave.TotalMilliseconds + desequentialize.TotalMilliseconds);
return interleaved;
}
}

View File

@@ -1,67 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Constants.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains constants for Aaru Format disk images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
/// <summary>Old magic identifier = "DICMFRMT".</summary>
const ulong DIC_MAGIC = 0x544D52464D434944;
/// <summary>Magic identifier = "AARUFRMT".</summary>
const ulong AARU_MAGIC = 0x544D524655524141;
/// <summary>
/// Image format version. A change in this number indicates an incompatible change to the format that prevents
/// older implementations from reading it correctly, if at all.
/// </summary>
const byte AARUFMT_VERSION_V1 = 1;
/// <summary>Adds new index format with 64-bit entries counter</summary>
const byte AARUFMT_VERSION = 2;
/// <summary>Maximum read cache size, 256MiB.</summary>
const uint MAX_CACHE_SIZE = 256 * 1024 * 1024;
/// <summary>Size in bytes of LZMA properties.</summary>
const int LZMA_PROPERTIES_LENGTH = 5;
/// <summary>Maximum number of entries for the DDT cache.</summary>
const int MAX_DDT_ENTRY_CACHE = 16000000;
/// <summary>How many samples are contained in a RedBook sector.</summary>
const int SAMPLES_PER_SECTOR = 588;
/// <summary>Maximum number of samples for a FLAC block. Bigger than 4608 gives no benefit.</summary>
const int MAX_FLAKE_BLOCK = 4608;
/// <summary>
/// Minimum number of samples for a FLAC block. <see cref="CUETools.Codecs.Flake" /> does not support it to be
/// smaller than 256.
/// </summary>
const int MIN_FLAKE_BLOCK = 256;
/// <summary>This mask is to check for flags in CompactDisc suffix/prefix DDT</summary>
const uint CD_XFIX_MASK = 0xFF000000;
/// <summary>This mask is to check for position in CompactDisc suffix/prefix deduplicated block</summary>
const uint CD_DFIX_MASK = 0x00FFFFFF;
}

View File

@@ -1,309 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Enums.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains enumerations for Aaru Format disk images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
// ReSharper disable UnusedMember.Local
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
#region Nested type: BlockType
/// <summary>List of known blocks types</summary>
enum BlockType : uint
{
/// <summary>Block containing data</summary>
DataBlock = 0x4B4C4244,
/// <summary>Block containing a deduplication table</summary>
DeDuplicationTable = 0x2A544444,
/// <summary>Block containing the index</summary>
Index = 0x58444E49,
/// <summary>Block containing the index</summary>
Index2 = 0x32584449,
/// <summary>Block containing logical geometry</summary>
GeometryBlock = 0x4D4F4547,
/// <summary>Block containing metadata</summary>
MetadataBlock = 0x4154454D,
/// <summary>Block containing optical disc tracks</summary>
TracksBlock = 0x534B5254,
/// <summary>Block containing CICM XML metadata</summary>
CicmBlock = 0x4D434943,
/// <summary>Block containing contents checksums</summary>
ChecksumBlock = 0x4D534B43,
/// <summary>TODO: Block containing data position measurements</summary>
DataPositionMeasurementBlock = 0x2A4D5044,
/// <summary>TODO: Block containing a snapshot index</summary>
SnapshotBlock = 0x50414E53,
/// <summary>TODO: Block containing how to locate the parent image</summary>
ParentBlock = 0x544E5250,
/// <summary>Block containing an array of hardware used to create the image</summary>
DumpHardwareBlock = 0x2A504D44,
/// <summary>Block containing list of files for a tape image</summary>
TapeFileBlock = 0x454C4654,
/// <summary>Block containing list of partitions for a tape image</summary>
TapePartitionBlock = 0x54425054,
/// <summary>Block containing list of indexes for Compact Disc tracks</summary>
CompactDiscIndexesBlock = 0x58494443,
/// <summary>Block containing JSON version of Aaru Metadata</summary>
AaruMetadataJsonBlock = 0x444D534A
}
#endregion
#region Nested type: CdFixFlags
enum CdFixFlags : uint
{
NotDumped = 0x10000000,
Correct = 0x20000000,
Mode2Form1Ok = 0x30000000,
Mode2Form2Ok = 0x40000000,
Mode2Form2NoCrc = 0x50000000
}
#endregion
#region Nested type: ChecksumAlgorithm
enum ChecksumAlgorithm : byte
{
Invalid = 0,
Md5 = 1,
Sha1 = 2,
Sha256 = 3,
SpamSum = 4
}
#endregion
#region Nested type: CompressionType
/// <summary>List of known compression types</summary>
enum CompressionType : ushort
{
/// <summary>Not compressed</summary>
None = 0,
/// <summary>LZMA</summary>
Lzma = 1,
/// <summary>FLAC</summary>
Flac = 2,
/// <summary>LZMA in Claunia Subchannel Transform processed data</summary>
LzmaClauniaSubchannelTransform = 3
}
#endregion
#region Nested type: DataType
/// <summary>List of known data types</summary>
enum DataType : ushort
{
/// <summary>No data</summary>
NoData = 0,
/// <summary>User data</summary>
UserData = 1,
/// <summary>CompactDisc partial Table of Contents</summary>
CompactDiscPartialToc = 2,
/// <summary>CompactDisc session information</summary>
CompactDiscSessionInfo = 3,
/// <summary>CompactDisc Table of Contents</summary>
CompactDiscToc = 4,
/// <summary>CompactDisc Power Management Area</summary>
CompactDiscPma = 5,
/// <summary>CompactDisc Absolute Time In Pregroove</summary>
CompactDiscAtip = 6,
/// <summary>CompactDisc Lead-in's CD-Text</summary>
CompactDiscLeadInCdText = 7,
/// <summary>DVD Physical Format Information</summary>
DvdPfi = 8,
/// <summary>DVD Lead-in's Copyright Management Information</summary>
DvdLeadInCmi = 9,
/// <summary>DVD Disc Key</summary>
DvdDiscKey = 10,
/// <summary>DVD Burst Cutting Area</summary>
DvdBca = 11,
/// <summary>DVD DMI</summary>
DvdDmi = 12,
/// <summary>DVD Media Identifier</summary>
DvdMediaIdentifier = 13,
/// <summary>DVD Media Key Block</summary>
DvdMediaKeyBlock = 14,
/// <summary>DVD-RAM Disc Definition Structure</summary>
DvdRamDds = 15,
/// <summary>DVD-RAM Medium Status</summary>
DvdRamMediumStatus = 16,
/// <summary>DVD-RAM Spare Area Information</summary>
DvdRamSpareArea = 17,
/// <summary>DVD-R RMD</summary>
DvdRRmd = 18,
/// <summary>DVD-R Pre-recorded Information</summary>
DvdRPrerecordedInfo = 19,
/// <summary>DVD-R Media Identifier</summary>
DvdRMediaIdentifier = 20,
/// <summary>DVD-R Physical Format Information</summary>
DvdRPfi = 21,
/// <summary>DVD ADress In Pregroove</summary>
DvdAdip = 22,
/// <summary>HD DVD Copy Protection Information</summary>
HdDvdCpi = 23,
/// <summary>HD DVD Medium Status</summary>
HdDvdMediumStatus = 24,
/// <summary>DVD DL Layer Capacity</summary>
DvdDlLayerCapacity = 25,
/// <summary>DVD DL Middle Zone Address</summary>
DvdDlMiddleZoneAddress = 26,
/// <summary>DVD DL Jump Interval Size</summary>
DvdDlJumpIntervalSize = 27,
/// <summary>DVD DL Manual Layer Jump LBA</summary>
DvdDlManualLayerJumpLba = 28,
/// <summary>Bluray Disc Information</summary>
BlurayDi = 29,
/// <summary>Bluray Burst Cutting Area</summary>
BlurayBca = 30,
/// <summary>Bluray Disc Definition Structure</summary>
BlurayDds = 31,
/// <summary>Bluray Cartridge Status</summary>
BlurayCartridgeStatus = 32,
/// <summary>Bluray Spare Area Information</summary>
BluraySpareArea = 33,
/// <summary>AACS Volume Identifier</summary>
AacsVolumeIdentifier = 34,
/// <summary>AACS Serial Number</summary>
AacsSerialNumber = 35,
/// <summary>AACS Media Identifier</summary>
AacsMediaIdentifier = 36,
/// <summary>AACS Media Key Block</summary>
AacsMediaKeyBlock = 37,
/// <summary>AACS Data Keys</summary>
AacsDataKeys = 38,
/// <summary>AACS LBA Extents</summary>
AacsLbaExtents = 39,
/// <summary>CPRM Media Key Block</summary>
CprmMediaKeyBlock = 40,
/// <summary>Recognized Layers</summary>
HybridRecognizedLayers = 41,
/// <summary>MMC Write Protection</summary>
ScsiMmcWriteProtection = 42,
/// <summary>MMC Disc Information</summary>
ScsiMmcDiscInformation = 43,
/// <summary>MMC Track Resources Information</summary>
ScsiMmcTrackResourcesInformation = 44,
/// <summary>MMC POW Resources Information</summary>
ScsiMmcPowResourcesInformation = 45,
/// <summary>SCSI INQUIRY RESPONSE</summary>
ScsiInquiry = 46,
/// <summary>SCSI MODE PAGE 2Ah</summary>
ScsiModePage2A = 47,
/// <summary>ATA IDENTIFY response</summary>
AtaIdentify = 48,
/// <summary>ATAPI IDENTIFY response</summary>
AtapiIdentify = 49,
/// <summary>PCMCIA CIS</summary>
PcmciaCis = 50,
/// <summary>SecureDigital CID</summary>
SecureDigitalCid = 51,
/// <summary>SecureDigital CSD</summary>
SecureDigitalCsd = 52,
/// <summary>SecureDigital SCR</summary>
SecureDigitalScr = 53,
/// <summary>SecureDigital OCR</summary>
SecureDigitalOcr = 54,
/// <summary>MultiMediaCard CID</summary>
MultiMediaCardCid = 55,
/// <summary>MultiMediaCard CSD</summary>
MultiMediaCardCsd = 56,
/// <summary>MultiMediaCard OCR</summary>
MultiMediaCardOcr = 57,
/// <summary>MultiMediaCard Extended CSD</summary>
MultiMediaCardExtendedCsd = 58,
/// <summary>Xbox Security Sector</summary>
XboxSecuritySector = 59,
/// <summary>Floppy Lead-out</summary>
FloppyLeadOut = 60,
/// <summary>Dvd Disc Control Block</summary>
DvdDiscControlBlock = 61,
/// <summary>CompactDisc First track pregap</summary>
CompactDiscFirstTrackPregap = 62,
/// <summary>CompactDisc Lead-out</summary>
CompactDiscLeadOut = 63,
/// <summary>SCSI MODE SENSE (6) response</summary>
ScsiModeSense6 = 64,
/// <summary>SCSI MODE SENSE (10) response</summary>
ScsiModeSense10 = 65,
/// <summary>USB descriptors</summary>
UsbDescriptors = 66,
/// <summary>Xbox DMI</summary>
XboxDmi = 67,
/// <summary>Xbox Physical Format Information</summary>
XboxPfi = 68,
/// <summary>CompactDisc sector prefix (sync, header</summary>
CdSectorPrefix = 69,
/// <summary>CompactDisc sector suffix (edc, ecc p, ecc q)</summary>
CdSectorSuffix = 70,
/// <summary>CompactDisc subchannel</summary>
CdSectorSubchannel = 71,
/// <summary>Apple Profile (20 byte) tag</summary>
AppleProfileTag = 72,
/// <summary>Apple Sony (12 byte) tag</summary>
AppleSonyTag = 73,
/// <summary>Priam Data Tower (24 byte) tag</summary>
PriamDataTowerTag = 74,
/// <summary>CompactDisc Media Catalogue Number (as in Lead-in), 13 bytes, ASCII</summary>
CompactDiscMediaCatalogueNumber = 75,
/// <summary>CompactDisc sector prefix (sync, header), only incorrect stored</summary>
CdSectorPrefixCorrected = 76,
/// <summary>CompactDisc sector suffix (edc, ecc p, ecc q), only incorrect stored</summary>
CdSectorSuffixCorrected = 77,
/// <summary>CompactDisc MODE 2 subheader</summary>
CompactDiscMode2Subheader = 78,
/// <summary>CompactDisc Lead-in</summary>
CompactDiscLeadIn = 79,
/// <summary>Decrypted DVD Disc Key</summary>
DvdDiscKeyDecrypted = 80,
/// <summary>DVD Copyright Management Information (CPR_MAI)</summary>
DvdSectorCprMai = 81,
/// <summary>Decrypted DVD Title Key</summary>
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>DVD Error Correction Code (ECC) Parity of Inner Code (PI)</summary>
DvdSectorEccPi = 86,
/// <summary>DVD Error Correction Code (ECC) Parity of Outer Code (PO)</summary>
DvdEccBlockPo = 87,
}
#endregion
}

View File

@@ -1,532 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Helpers.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains helpers for Aaru Format disk images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.CommonTypes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Structs.Devices.ATA;
using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Decoders.SecureDigital;
using Aaru.Helpers;
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
/// <summary>Checks for media tags that may contain metadata and sets it up if not already set</summary>
void SetMetadataFromTags()
{
// Search for SecureDigital CID
if(_mediaTags.TryGetValue(MediaTagType.SD_CID, out byte[] sdCid))
{
CID decoded = Decoders.SecureDigital.Decoders.DecodeCID(sdCid);
if(string.IsNullOrWhiteSpace(_imageInfo.DriveManufacturer))
_imageInfo.DriveManufacturer = VendorString.Prettify(decoded.Manufacturer);
if(string.IsNullOrWhiteSpace(_imageInfo.DriveModel)) _imageInfo.DriveModel = decoded.ProductName;
if(string.IsNullOrWhiteSpace(_imageInfo.DriveFirmwareRevision))
{
_imageInfo.DriveFirmwareRevision =
$"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}";
}
if(string.IsNullOrWhiteSpace(_imageInfo.DriveSerialNumber))
_imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}";
}
// Search for MultiMediaCard CID
if(_mediaTags.TryGetValue(MediaTagType.MMC_CID, out byte[] mmcCid))
{
Decoders.MMC.CID decoded = Decoders.MMC.Decoders.DecodeCID(mmcCid);
if(string.IsNullOrWhiteSpace(_imageInfo.DriveManufacturer))
_imageInfo.DriveManufacturer = Decoders.MMC.VendorString.Prettify(decoded.Manufacturer);
if(string.IsNullOrWhiteSpace(_imageInfo.DriveModel)) _imageInfo.DriveModel = decoded.ProductName;
if(string.IsNullOrWhiteSpace(_imageInfo.DriveFirmwareRevision))
{
_imageInfo.DriveFirmwareRevision =
$"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}";
}
if(string.IsNullOrWhiteSpace(_imageInfo.DriveSerialNumber))
_imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}";
}
// Search for SCSI INQUIRY
if(_mediaTags.TryGetValue(MediaTagType.SCSI_INQUIRY, out byte[] scsiInquiry))
{
Inquiry? nullableInquiry = Inquiry.Decode(scsiInquiry);
if(nullableInquiry.HasValue)
{
Inquiry inquiry = nullableInquiry.Value;
if(string.IsNullOrWhiteSpace(_imageInfo.DriveManufacturer))
_imageInfo.DriveManufacturer = StringHandlers.CToString(inquiry.VendorIdentification)?.Trim();
if(string.IsNullOrWhiteSpace(_imageInfo.DriveModel))
_imageInfo.DriveModel = StringHandlers.CToString(inquiry.ProductIdentification)?.Trim();
if(string.IsNullOrWhiteSpace(_imageInfo.DriveFirmwareRevision))
_imageInfo.DriveFirmwareRevision = StringHandlers.CToString(inquiry.ProductRevisionLevel)?.Trim();
}
}
// Search for ATA or ATAPI IDENTIFY
if(!_mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out byte[] ataIdentify) &&
!_mediaTags.TryGetValue(MediaTagType.ATAPI_IDENTIFY, out ataIdentify))
return;
Identify.IdentifyDevice? nullableIdentify = CommonTypes.Structs.Devices.ATA.Identify.Decode(ataIdentify);
if(!nullableIdentify.HasValue) return;
Identify.IdentifyDevice identify = nullableIdentify.Value;
string[] separated = identify.Model.Split(' ');
if(separated.Length == 1)
{
if(string.IsNullOrWhiteSpace(_imageInfo.DriveModel))
_imageInfo.DriveModel = separated[0];
else
{
if(string.IsNullOrWhiteSpace(_imageInfo.DriveManufacturer)) _imageInfo.DriveManufacturer = separated[0];
if(string.IsNullOrWhiteSpace(_imageInfo.DriveModel)) _imageInfo.DriveModel = separated[^1];
}
}
if(string.IsNullOrWhiteSpace(_imageInfo.DriveFirmwareRevision))
_imageInfo.DriveFirmwareRevision = identify.FirmwareRevision;
if(string.IsNullOrWhiteSpace(_imageInfo.DriveSerialNumber))
_imageInfo.DriveSerialNumber = identify.SerialNumber;
}
// Get the Aaru Metadata media type from Aaru media type
static MetadataMediaType GetMetadataMediaType(MediaType type)
{
return type switch
{
MediaType.CD
or MediaType.CDDA
or MediaType.CDG
or MediaType.CDEG
or MediaType.CDI
or MediaType.CDIREADY
or MediaType.CDROM
or MediaType.CDROMXA
or MediaType.CDPLUS
or MediaType.CDMO
or MediaType.CDR
or MediaType.CDRW
or MediaType.CDMRW
or MediaType.VCD
or MediaType.SVCD
or MediaType.PCD
or MediaType.SACD
or MediaType.DDCD
or MediaType.DDCDR
or MediaType.DDCDRW
or MediaType.DTSCD
or MediaType.CDMIDI
or MediaType.CDV
or MediaType.DVDROM
or MediaType.DVDR
or MediaType.DVDRW
or MediaType.DVDPR
or MediaType.DVDPRW
or MediaType.DVDPRWDL
or MediaType.DVDRDL
or MediaType.DVDPRDL
or MediaType.DVDRAM
or MediaType.DVDRWDL
or MediaType.DVDDownload
or MediaType.HDDVDROM
or MediaType.HDDVDRAM
or MediaType.HDDVDR
or MediaType.HDDVDRW
or MediaType.HDDVDRDL
or MediaType.HDDVDRWDL
or MediaType.BDROM
or MediaType.UHDBD
or MediaType.BDR
or MediaType.BDRE
or MediaType.BDRXL
or MediaType.BDREXL
or MediaType.EVD
or MediaType.FVD
or MediaType.HVD
or MediaType.CBHD
or MediaType.HDVMD
or MediaType.VCDHD
or MediaType.SVOD
or MediaType.FDDVD
or MediaType.LD
or MediaType.LDROM
or MediaType.CRVdisc
or MediaType.LDROM2
or MediaType.LVROM
or MediaType.MegaLD
or MediaType.PS1CD
or MediaType.PS2CD
or MediaType.PS2DVD
or MediaType.PS3DVD
or MediaType.PS3BD
or MediaType.PS4BD
or MediaType.PS5BD
or MediaType.UMD
or MediaType.XGD
or MediaType.XGD2
or MediaType.XGD3
or MediaType.XGD4
or MediaType.MEGACD
or MediaType.SATURNCD
or MediaType.GDROM
or MediaType.GDR
or MediaType.SuperCDROM2
or MediaType.JaguarCD
or MediaType.ThreeDO
or MediaType.PCFX
or MediaType.NeoGeoCD
or MediaType.GOD
or MediaType.WOD
or MediaType.WUOD
or MediaType.CDTV
or MediaType.CD32
or MediaType.Nuon
or MediaType.Playdia
or MediaType.Pippin
or MediaType.FMTOWNS
or MediaType.MilCD
or MediaType.VideoNow
or MediaType.VideoNowColor
or MediaType.VideoNowXp
or MediaType.CVD => MetadataMediaType.OpticalDisc,
_ => MetadataMediaType.BlockMedia
};
}
// Gets a DDT entry
ulong GetDdtEntry(ulong sectorAddress)
{
if(_inMemoryDdt) return _userDataDdt[sectorAddress];
if(_ddtEntryCache.TryGetValue(sectorAddress, out ulong entry)) return entry;
long oldPosition = _imageStream.Position;
_imageStream.Position = _outMemoryDdtPosition + Marshal.SizeOf<DdtHeader>();
_imageStream.Position += (long)(sectorAddress * sizeof(ulong));
var temp = new byte[sizeof(ulong)];
_imageStream.EnsureRead(temp, 0, sizeof(ulong));
_imageStream.Position = oldPosition;
entry = BitConverter.ToUInt64(temp, 0);
if(_ddtEntryCache.Count >= MAX_DDT_ENTRY_CACHE) _ddtEntryCache.Clear();
_ddtEntryCache.Add(sectorAddress, entry);
return entry;
}
// Sets a DDT entry
void SetDdtEntry(ulong sectorAddress, ulong pointer)
{
if(_inMemoryDdt)
{
if(IsTape)
_tapeDdt[sectorAddress] = pointer;
else
_userDataDdt[sectorAddress] = pointer;
return;
}
long oldPosition = _imageStream.Position;
_imageStream.Position = _outMemoryDdtPosition + Marshal.SizeOf<DdtHeader>();
_imageStream.Position += (long)(sectorAddress * sizeof(ulong));
_imageStream.Write(BitConverter.GetBytes(pointer), 0, sizeof(ulong));
_imageStream.Position = oldPosition;
}
// Converts between image data type and Aaru media tag type
static MediaTagType GetMediaTagTypeForDataType(DataType type) => type switch
{
DataType.CompactDiscPartialToc => MediaTagType
.CD_TOC,
DataType.CompactDiscSessionInfo => MediaTagType
.CD_SessionInfo,
DataType.CompactDiscToc => MediaTagType
.CD_FullTOC,
DataType.CompactDiscPma => MediaTagType.CD_PMA,
DataType.CompactDiscAtip => MediaTagType
.CD_ATIP,
DataType.CompactDiscLeadInCdText =>
MediaTagType.CD_TEXT,
DataType.DvdPfi => MediaTagType.DVD_PFI,
DataType.DvdLeadInCmi => MediaTagType.DVD_CMI,
DataType.DvdDiscKey =>
MediaTagType.DVD_DiscKey,
DataType.DvdBca => MediaTagType.DVD_BCA,
DataType.DvdDmi => MediaTagType.DVD_DMI,
DataType.DvdMediaIdentifier => MediaTagType
.DVD_MediaIdentifier,
DataType.DvdMediaKeyBlock => MediaTagType
.DVD_MKB,
DataType.DvdRamDds => MediaTagType.DVDRAM_DDS,
DataType.DvdRamMediumStatus => MediaTagType
.DVDRAM_MediumStatus,
DataType.DvdRamSpareArea => MediaTagType
.DVDRAM_SpareArea,
DataType.DvdRRmd => MediaTagType.DVDR_RMD,
DataType.DvdRPrerecordedInfo => MediaTagType
.DVDR_PreRecordedInfo,
DataType.DvdRMediaIdentifier => MediaTagType
.DVDR_MediaIdentifier,
DataType.DvdRPfi => MediaTagType.DVDR_PFI,
DataType.DvdAdip => MediaTagType.DVD_ADIP,
DataType.HdDvdCpi => MediaTagType.HDDVD_CPI,
DataType.HdDvdMediumStatus => MediaTagType
.HDDVD_MediumStatus,
DataType.DvdDlLayerCapacity => MediaTagType
.DVDDL_LayerCapacity,
DataType.DvdDlMiddleZoneAddress => MediaTagType
.DVDDL_MiddleZoneAddress,
DataType.DvdDlJumpIntervalSize => MediaTagType
.DVDDL_JumpIntervalSize,
DataType.DvdDlManualLayerJumpLba =>
MediaTagType.DVDDL_ManualLayerJumpLBA,
DataType.BlurayDi => MediaTagType.BD_DI,
DataType.BlurayBca => MediaTagType.BD_BCA,
DataType.BlurayDds => MediaTagType.BD_DDS,
DataType.BlurayCartridgeStatus => MediaTagType
.BD_CartridgeStatus,
DataType.BluraySpareArea => MediaTagType
.BD_SpareArea,
DataType.AacsVolumeIdentifier => MediaTagType
.AACS_VolumeIdentifier,
DataType.AacsSerialNumber => MediaTagType
.AACS_SerialNumber,
DataType.AacsMediaIdentifier => MediaTagType
.AACS_MediaIdentifier,
DataType.AacsMediaKeyBlock => MediaTagType
.AACS_MKB,
DataType.AacsDataKeys => MediaTagType
.AACS_DataKeys,
DataType.AacsLbaExtents => MediaTagType
.AACS_LBAExtents,
DataType.CprmMediaKeyBlock => MediaTagType
.AACS_CPRM_MKB,
DataType.HybridRecognizedLayers => MediaTagType
.Hybrid_RecognizedLayers,
DataType.ScsiMmcWriteProtection => MediaTagType
.MMC_WriteProtection,
DataType.ScsiMmcDiscInformation => MediaTagType
.MMC_DiscInformation,
DataType.ScsiMmcTrackResourcesInformation =>
MediaTagType.MMC_TrackResourcesInformation,
DataType.ScsiMmcPowResourcesInformation =>
MediaTagType.MMC_POWResourcesInformation,
DataType.ScsiInquiry => MediaTagType
.SCSI_INQUIRY,
DataType.ScsiModePage2A => MediaTagType
.SCSI_MODEPAGE_2A,
DataType.AtaIdentify => MediaTagType
.ATA_IDENTIFY,
DataType.AtapiIdentify => MediaTagType
.ATAPI_IDENTIFY,
DataType.PcmciaCis => MediaTagType.PCMCIA_CIS,
DataType.SecureDigitalCid => MediaTagType
.SD_CID,
DataType.SecureDigitalCsd => MediaTagType
.SD_CSD,
DataType.SecureDigitalScr => MediaTagType
.SD_SCR,
DataType.SecureDigitalOcr => MediaTagType
.SD_OCR,
DataType.MultiMediaCardCid => MediaTagType
.MMC_CID,
DataType.MultiMediaCardCsd => MediaTagType
.MMC_CSD,
DataType.MultiMediaCardOcr => MediaTagType
.MMC_OCR,
DataType.MultiMediaCardExtendedCsd =>
MediaTagType.MMC_ExtendedCSD,
DataType.XboxSecuritySector => MediaTagType
.Xbox_SecuritySector,
DataType.FloppyLeadOut => MediaTagType
.Floppy_LeadOut,
DataType.DvdDiscControlBlock => MediaTagType
.DCB,
DataType.CompactDiscFirstTrackPregap =>
MediaTagType.CD_FirstTrackPregap,
DataType.CompactDiscLeadOut => MediaTagType
.CD_LeadOut,
DataType.ScsiModeSense6 => MediaTagType
.SCSI_MODESENSE_6,
DataType.ScsiModeSense10 => MediaTagType
.SCSI_MODESENSE_10,
DataType.UsbDescriptors => MediaTagType
.USB_Descriptors,
DataType.XboxDmi => MediaTagType.Xbox_DMI,
DataType.XboxPfi => MediaTagType.Xbox_PFI,
DataType.CompactDiscMediaCatalogueNumber =>
MediaTagType.CD_MCN,
DataType.CompactDiscLeadIn => MediaTagType
.CD_LeadIn,
DataType.DvdDiscKeyDecrypted => MediaTagType
.DVD_DiscKey_Decrypted,
_ => throw new ArgumentOutOfRangeException()
};
// Converts between Aaru media tag type and image data type
static DataType GetDataTypeForMediaTag(MediaTagType tag) => tag switch
{
MediaTagType.CD_TOC => DataType
.CompactDiscPartialToc,
MediaTagType.CD_SessionInfo => DataType
.CompactDiscSessionInfo,
MediaTagType.CD_FullTOC => DataType.CompactDiscToc,
MediaTagType.CD_PMA => DataType.CompactDiscPma,
MediaTagType.CD_ATIP => DataType.CompactDiscAtip,
MediaTagType.CD_TEXT => DataType
.CompactDiscLeadInCdText,
MediaTagType.DVD_PFI => DataType.DvdPfi,
MediaTagType.DVD_CMI => DataType.DvdLeadInCmi,
MediaTagType.DVD_DiscKey => DataType.DvdDiscKey,
MediaTagType.DVD_BCA => DataType.DvdBca,
MediaTagType.DVD_DMI => DataType.DvdDmi,
MediaTagType.DVD_MediaIdentifier => DataType
.DvdMediaIdentifier,
MediaTagType.DVD_MKB => DataType.DvdMediaKeyBlock,
MediaTagType.DVDRAM_DDS => DataType.DvdRamDds,
MediaTagType.DVDRAM_MediumStatus => DataType
.DvdRamMediumStatus,
MediaTagType.DVDRAM_SpareArea => DataType
.DvdRamSpareArea,
MediaTagType.DVDR_RMD => DataType.DvdRRmd,
MediaTagType.DVDR_PreRecordedInfo => DataType
.DvdRPrerecordedInfo,
MediaTagType.DVDR_MediaIdentifier => DataType
.DvdRMediaIdentifier,
MediaTagType.DVDR_PFI => DataType.DvdRPfi,
MediaTagType.DVD_ADIP => DataType.DvdAdip,
MediaTagType.HDDVD_CPI => DataType.HdDvdCpi,
MediaTagType.HDDVD_MediumStatus => DataType
.HdDvdMediumStatus,
MediaTagType.DVDDL_LayerCapacity => DataType
.DvdDlLayerCapacity,
MediaTagType.DVDDL_MiddleZoneAddress => DataType
.DvdDlMiddleZoneAddress,
MediaTagType.DVDDL_JumpIntervalSize => DataType
.DvdDlJumpIntervalSize,
MediaTagType.DVDDL_ManualLayerJumpLBA => DataType
.DvdDlManualLayerJumpLba,
MediaTagType.BD_DI => DataType.BlurayDi,
MediaTagType.BD_BCA => DataType.BlurayBca,
MediaTagType.BD_DDS => DataType.BlurayDds,
MediaTagType.BD_CartridgeStatus => DataType
.BlurayCartridgeStatus,
MediaTagType.BD_SpareArea => DataType
.BluraySpareArea,
MediaTagType.AACS_VolumeIdentifier => DataType
.AacsVolumeIdentifier,
MediaTagType.AACS_SerialNumber => DataType
.AacsSerialNumber,
MediaTagType.AACS_MediaIdentifier => DataType
.AacsMediaIdentifier,
MediaTagType.AACS_MKB => DataType.AacsMediaKeyBlock,
MediaTagType.AACS_DataKeys => DataType.AacsDataKeys,
MediaTagType.AACS_LBAExtents => DataType
.AacsLbaExtents,
MediaTagType.AACS_CPRM_MKB => DataType
.CprmMediaKeyBlock,
MediaTagType.Hybrid_RecognizedLayers => DataType
.HybridRecognizedLayers,
MediaTagType.MMC_WriteProtection => DataType
.ScsiMmcWriteProtection,
MediaTagType.MMC_DiscInformation => DataType
.ScsiMmcDiscInformation,
MediaTagType.MMC_TrackResourcesInformation =>
DataType.ScsiMmcTrackResourcesInformation,
MediaTagType.MMC_POWResourcesInformation => DataType
.ScsiMmcPowResourcesInformation,
MediaTagType.SCSI_INQUIRY => DataType.ScsiInquiry,
MediaTagType.SCSI_MODEPAGE_2A => DataType
.ScsiModePage2A,
MediaTagType.ATA_IDENTIFY => DataType.AtaIdentify,
MediaTagType.ATAPI_IDENTIFY => DataType
.AtapiIdentify,
MediaTagType.PCMCIA_CIS => DataType.PcmciaCis,
MediaTagType.SD_CID => DataType.SecureDigitalCid,
MediaTagType.SD_CSD => DataType.SecureDigitalCsd,
MediaTagType.SD_SCR => DataType.SecureDigitalScr,
MediaTagType.SD_OCR => DataType.SecureDigitalOcr,
MediaTagType.MMC_CID => DataType.MultiMediaCardCid,
MediaTagType.MMC_CSD => DataType.MultiMediaCardCsd,
MediaTagType.MMC_OCR => DataType.MultiMediaCardOcr,
MediaTagType.MMC_ExtendedCSD => DataType
.MultiMediaCardExtendedCsd,
MediaTagType.Xbox_SecuritySector => DataType
.XboxSecuritySector,
MediaTagType.Floppy_LeadOut => DataType
.FloppyLeadOut,
MediaTagType.DCB => DataType.DvdDiscControlBlock,
MediaTagType.CD_FirstTrackPregap => DataType
.CompactDiscFirstTrackPregap,
MediaTagType.CD_LeadOut => DataType
.CompactDiscLeadOut,
MediaTagType.SCSI_MODESENSE_6 => DataType
.ScsiModeSense6,
MediaTagType.SCSI_MODESENSE_10 => DataType
.ScsiModeSense10,
MediaTagType.USB_Descriptors => DataType
.UsbDescriptors,
MediaTagType.Xbox_DMI => DataType.XboxDmi,
MediaTagType.Xbox_PFI => DataType.XboxPfi,
MediaTagType.CD_MCN => DataType
.CompactDiscMediaCatalogueNumber,
MediaTagType.CD_LeadIn =>
DataType.CompactDiscLeadIn,
MediaTagType.DVD_DiscKey_Decrypted => DataType
.DvdDiscKeyDecrypted,
_ => throw new
ArgumentOutOfRangeException(nameof(tag),
tag,
null)
};
}

View File

@@ -1,58 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Identify.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Identifies Aaru Format disk images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using Aaru.CommonTypes.Interfaces;
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
#region IWritableOpticalImage Members
/// <inheritdoc />
public bool Identify(IFilter imageFilter) => false;
/*
_imageStream = imageFilter.GetDataForkStream();
_imageStream.Seek(0, SeekOrigin.Begin);
if(_imageStream.Length < Marshal.SizeOf<AaruHeader>()) return false;
_structureBytes = new byte[Marshal.SizeOf<AaruHeader>()];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
_header = Marshal.ByteArrayToStructureLittleEndian<AaruHeader>(_structureBytes);
return _header.identifier is DIC_MAGIC or AARU_MAGIC && _header.imageMajorVersion <= AARUFMT_VERSION;
*/
#endregion
}

View File

@@ -1,140 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Properties.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains properties for Aaru Format disk images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using Aaru.CommonTypes;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Structs;
using Partition = Aaru.CommonTypes.Partition;
using Track = Aaru.CommonTypes.Structs.Track;
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
#region IWritableOpticalImage Members
/// <inheritdoc />
public OpticalImageCapabilities OpticalCapabilities => OpticalImageCapabilities.CanStoreAudioTracks |
OpticalImageCapabilities.CanStoreDataTracks |
OpticalImageCapabilities.CanStorePregaps |
OpticalImageCapabilities.CanStoreSubchannelRw |
OpticalImageCapabilities.CanStoreSessions |
OpticalImageCapabilities.CanStoreIsrc |
OpticalImageCapabilities.CanStoreCdText |
OpticalImageCapabilities.CanStoreMcn |
OpticalImageCapabilities.CanStoreRawData |
OpticalImageCapabilities.CanStoreCookedData |
OpticalImageCapabilities.CanStoreMultipleTracks |
OpticalImageCapabilities.CanStoreNotCdSessions |
OpticalImageCapabilities.CanStoreNotCdTracks |
OpticalImageCapabilities.CanStoreIndexes |
OpticalImageCapabilities.CanStoreHiddenTracks;
/// <inheritdoc />
// ReSharper disable once ConvertToAutoProperty
public ImageInfo Info => _imageInfo;
/// <inheritdoc />
public string Name => "Aaru (old)";
/// <inheritdoc />
public Guid Id => new("49360069-1784-4A2F-B723-0C844D610B0A");
/// <inheritdoc />
public string Format => "Aaru (old)";
/// <inheritdoc />
public string Author => Authors.NataliaPortillo;
/// <inheritdoc />
public List<Partition> Partitions { get; private set; }
/// <inheritdoc />
public List<Track> Tracks { get; private set; }
/// <inheritdoc />
public List<Session> Sessions { get; private set; }
/// <inheritdoc />
public List<DumpHardware> DumpHardware { get; private set; }
/// <inheritdoc />
public Metadata AaruMetadata { get; private set; }
/// <inheritdoc />
public IEnumerable<MediaTagType> SupportedMediaTags => Enum.GetValues(typeof(MediaTagType)).Cast<MediaTagType>();
/// <inheritdoc />
public IEnumerable<SectorTagType> SupportedSectorTags =>
Enum.GetValues(typeof(SectorTagType)).Cast<SectorTagType>();
/// <inheritdoc />
public IEnumerable<MediaType> SupportedMediaTypes => Enum.GetValues(typeof(MediaType)).Cast<MediaType>();
/// <inheritdoc />
public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions => new[]
{
("sectors_per_block", typeof(uint),
Localization.How_many_sectors_to_store_per_block_will_be_rounded_to_next_power_of_two, 4096U),
("dictionary", typeof(uint), Localization.Size_in_bytes_of_the_LZMA_dictionary, (uint)(1 << 25)),
("max_ddt_size", typeof(uint),
Localization.Maximum_size_in_mebibytes_for_in_memory_DDT_If_image_needs_a_bigger_one_it_will_be_on_disk, 256U),
("md5", typeof(bool), Localization.Calculate_and_store_MD5_of_image_user_data, false),
("sha1", typeof(bool), Localization.Calculate_and_store_SHA1_of_image_user_data, false),
("sha256", typeof(bool), Localization.Calculate_and_store_SHA256_of_image_user_data, false),
("spamsum", typeof(bool), Localization.Calculate_and_store_SpamSum_of_image_user_data, false),
("deduplicate", typeof(bool),
Localization.Store_only_unique_sectors_This_consumes_more_memory_and_is_slower_but_its_enabled_by_default,
true),
("compress", typeof(bool), Localization.Compress_user_data_blocks_Other_blocks_will_always_be_compressed,
(object)true)
};
/// <inheritdoc />
public IEnumerable<string> KnownExtensions => new[]
{
".dicf", ".aaru", ".aaruformat", ".aaruf", ".aif"
};
/// <inheritdoc />
public bool IsWriting { get; private set; }
/// <inheritdoc />
public string ErrorMessage { get; private set; }
#endregion
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,508 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Structs.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains structures for Aaru Format disk images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System.Runtime.InteropServices;
using Aaru.CommonTypes;
using Aaru.CommonTypes.Enums;
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
#region Nested type: AaruHeader
/// <summary>Header, at start of file</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
struct AaruHeader
{
/// <summary>Header identifier, <see cref="AARU_MAGIC" /></summary>
public ulong identifier;
/// <summary>UTF-16LE name of the application that created the image</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string application;
/// <summary>Image format major version. A new major version means a possibly incompatible change of format</summary>
public byte imageMajorVersion;
/// <summary>Image format minor version. A new minor version indicates a compatible change of format</summary>
public byte imageMinorVersion;
/// <summary>Major version of the application that created the image</summary>
public byte applicationMajorVersion;
/// <summary>Minor version of the application that created the image</summary>
public byte applicationMinorVersion;
/// <summary>Type of media contained on image</summary>
public MediaType mediaType;
/// <summary>Offset to index</summary>
public ulong indexOffset;
/// <summary>Windows filetime (100 nanoseconds since 1601/01/01 00:00:00 UTC) of image creation time</summary>
public long creationTime;
/// <summary>Windows filetime (100 nanoseconds since 1601/01/01 00:00:00 UTC) of image last written time</summary>
public long lastWrittenTime;
}
#endregion
#region Nested type: AaruMetadataJsonBlock
/// <summary>Aaru Metadata JSON block</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AaruMetadataJsonBlock
{
/// <summary>Identifier, <see cref="BlockType.AaruMetadataJsonBlock" /></summary>
public BlockType identifier;
public uint length;
}
#endregion
#region Nested type: BlockHeader
/// <summary>Block header, precedes block data</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct BlockHeader
{
/// <summary>Identifier, <see cref="BlockType.DataBlock" /></summary>
public BlockType identifier;
/// <summary>Type of data contained by this block</summary>
public DataType type;
/// <summary>Compression algorithm used to compress the block</summary>
public CompressionType compression;
/// <summary>Size in bytes of each sector contained in this block</summary>
public uint sectorSize;
/// <summary>Compressed length for the block</summary>
public uint cmpLength;
/// <summary>Uncompressed length for the block</summary>
public uint length;
/// <summary>CRC64-ECMA of the compressed block</summary>
public ulong cmpCrc64;
/// <summary>CRC64-ECMA of the uncompressed block</summary>
public ulong crc64;
}
#endregion
#region Nested type: ChecksumEntry
/// <summary>Checksum entry, followed by checksum data itself</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ChecksumEntry
{
/// <summary>Checksum algorithm</summary>
public ChecksumAlgorithm type;
/// <summary>Length in bytes of checksum that follows this structure</summary>
public uint length;
}
#endregion
#region Nested type: ChecksumHeader
/// <summary>
/// Checksum block, contains a checksum of all user data sectors (except for optical discs that is 2352 bytes raw
/// sector if available
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ChecksumHeader
{
/// <summary>Identifier, <see cref="BlockType.ChecksumBlock" /></summary>
public BlockType identifier;
/// <summary>Length in bytes of the block</summary>
public uint length;
/// <summary>How many checksums follow</summary>
public byte entries;
}
#endregion
#region Nested type: CicmMetadataBlock
/// <summary>CICM Metadata XML block</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CicmMetadataBlock
{
/// <summary>Identifier, <see cref="BlockType.CicmBlock" /></summary>
public readonly BlockType identifier;
public readonly uint length;
}
#endregion
#region Nested type: CompactDiscIndexEntry
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CompactDiscIndexEntry
{
/// <summary>How many entries follow this header</summary>
public ushort Track;
/// <summary>Size of the whole block, not including this header, in bytes</summary>
public ushort Index;
/// <summary>CRC64-ECMA of the block</summary>
public int Lba;
}
#endregion
#region Nested type: CompactDiscIndexesHeader
/// <summary>
/// Compact Disc track indexes block, contains a cache of all Compact Disc indexes to not need to interpret
/// subchannel
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CompactDiscIndexesHeader
{
/// <summary>Identifier, <see cref="BlockType.CompactDiscIndexesBlock" /></summary>
public BlockType identifier;
/// <summary>How many entries follow this header</summary>
public ushort entries;
/// <summary>Size of the whole block, not including this header, in bytes</summary>
public readonly ulong length;
/// <summary>CRC64-ECMA of the block</summary>
public ulong crc64;
}
#endregion
#region Nested type: DdtHeader
/// <summary>Header for a deduplication table. Table follows it</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DdtHeader
{
/// <summary>Identifier, <see cref="BlockType.DeDuplicationTable" /></summary>
public BlockType identifier;
/// <summary>Type of data pointed by this DDT</summary>
public DataType type;
/// <summary>Compression algorithm used to compress the DDT</summary>
public CompressionType compression;
/// <summary>Each entry is ((byte offset in file) &lt;&lt; shift) + (sector offset in block)</summary>
public byte shift;
/// <summary>How many entries are in the table</summary>
public ulong entries;
/// <summary>Compressed length for the DDT</summary>
public ulong cmpLength;
/// <summary>Uncompressed length for the DDT</summary>
public ulong length;
/// <summary>CRC64-ECMA of the compressed DDT</summary>
public ulong cmpCrc64;
/// <summary>CRC64-ECMA of the uncompressed DDT</summary>
public readonly ulong crc64;
}
#endregion
#region Nested type: DumpHardwareEntry
/// <summary>Dump hardware entry, contains length of strings that follow, in the same order as the length, this structure</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DumpHardwareEntry
{
/// <summary>Length of UTF-8 manufacturer string</summary>
public uint manufacturerLength;
/// <summary>Length of UTF-8 model string</summary>
public uint modelLength;
/// <summary>Length of UTF-8 revision string</summary>
public uint revisionLength;
/// <summary>Length of UTF-8 firmware version string</summary>
public uint firmwareLength;
/// <summary>Length of UTF-8 serial string</summary>
public uint serialLength;
/// <summary>Length of UTF-8 software name string</summary>
public uint softwareNameLength;
/// <summary>Length of UTF-8 software version string</summary>
public uint softwareVersionLength;
/// <summary>Length of UTF-8 software operating system string</summary>
public uint softwareOperatingSystemLength;
/// <summary>How many extents are after the strings</summary>
public uint extents;
}
#endregion
#region Nested type: DumpHardwareHeader
/// <summary>Dump hardware block, contains a list of hardware used to dump the media on this image</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DumpHardwareHeader
{
/// <summary>Identifier, <see cref="BlockType.DumpHardwareBlock" /></summary>
public BlockType identifier;
/// <summary>How many entries follow this header</summary>
public ushort entries;
/// <summary>Size of the whole block, not including this header, in bytes</summary>
public uint length;
/// <summary>CRC64-ECMA of the block</summary>
public ulong crc64;
}
#endregion
#region Nested type: GeometryBlock
/// <summary>Geometry block, contains physical geometry information</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct GeometryBlock
{
/// <summary>Identifier, <see cref="BlockType.GeometryBlock" /></summary>
public BlockType identifier;
public uint cylinders;
public uint heads;
public uint sectorsPerTrack;
}
#endregion
#region Nested type: IndexEntry
/// <summary>Index entry</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct IndexEntry
{
/// <summary>Type of item pointed by this entry</summary>
public BlockType blockType;
/// <summary>Type of data contained by the block pointed by this entry</summary>
public DataType dataType;
/// <summary>Offset in file where item is stored</summary>
public ulong offset;
}
#endregion
#region Nested type: IndexHeader
/// <summary>Header for the index, followed by entries</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct IndexHeader
{
/// <summary>Identifier, <see cref="BlockType.Index" /></summary>
public BlockType identifier;
/// <summary>How many entries follow this header</summary>
public ushort entries;
/// <summary>CRC64-ECMA of the index</summary>
public ulong crc64;
}
#endregion
#region Nested type: IndexHeader2
/// <summary>Header for the index, followed by entries</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct IndexHeader2
{
/// <summary>Identifier, <see cref="BlockType.Index2" /></summary>
public BlockType identifier;
/// <summary>How many entries follow this header</summary>
public ulong entries;
/// <summary>CRC64-ECMA of the index</summary>
public ulong crc64;
}
#endregion
#region Nested type: MetadataBlock
/// <summary>Metadata block, contains metadata</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MetadataBlock
{
/// <summary>Identifier, <see cref="BlockType.MetadataBlock" /></summary>
public BlockType identifier;
/// <summary>Size in bytes of this whole metadata block</summary>
public uint blockSize;
/// <summary>Sequence of media set this media belongs to</summary>
public int mediaSequence;
/// <summary>Total number of media on the media set this media belongs to</summary>
public int lastMediaSequence;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint creatorOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint creatorLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint commentsOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint commentsLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint mediaTitleOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint mediaTitleLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint mediaManufacturerOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint mediaManufacturerLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint mediaModelOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint mediaModelLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint mediaSerialNumberOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint mediaSerialNumberLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint mediaBarcodeOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint mediaBarcodeLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint mediaPartNumberOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint mediaPartNumberLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint driveManufacturerOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint driveManufacturerLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint driveModelOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint driveModelLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint driveSerialNumberOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint driveSerialNumberLength;
/// <summary>Offset to start of creator string from start of this block</summary>
public uint driveFirmwareRevisionOffset;
/// <summary>Length in bytes of the null-terminated UTF-16LE creator string</summary>
public uint driveFirmwareRevisionLength;
}
#endregion
#region Nested type: TapeFileEntry
/// <summary>Tape file entry</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TapeFileEntry
{
/// <summary>File number</summary>
public uint File;
/// <summary>Partition number</summary>
public readonly byte Partition;
/// <summary>First block, inclusive, of the file</summary>
public ulong FirstBlock;
/// <summary>Last block, inclusive, of the file</summary>
public ulong LastBlock;
}
#endregion
#region Nested type: TapeFileHeader
/// <summary>Tape file block, contains a list of all files in a tape</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TapeFileHeader
{
/// <summary>Identifier, <see cref="BlockType.TapeFileBlock" /></summary>
public BlockType identifier;
/// <summary>How many entries follow this header</summary>
public uint entries;
/// <summary>Size of the whole block, not including this header, in bytes</summary>
public ulong length;
/// <summary>CRC64-ECMA of the block</summary>
public ulong crc64;
}
#endregion
#region Nested type: TapePartitionEntry
/// <summary>Tape partition entry</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TapePartitionEntry
{
/// <summary>Partition number</summary>
public byte Number;
/// <summary>First block, inclusive, of the partition</summary>
public ulong FirstBlock;
/// <summary>Last block, inclusive, of the partition</summary>
public ulong LastBlock;
}
#endregion
#region Nested type: TapePartitionHeader
/// <summary>Tape partition block, contains a list of all partitions in a tape</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TapePartitionHeader
{
/// <summary>Identifier, <see cref="BlockType.TapePartitionBlock" /></summary>
public BlockType identifier;
/// <summary>How many entries follow this header</summary>
public byte entries;
/// <summary>Size of the whole block, not including this header, in bytes</summary>
public ulong length;
/// <summary>CRC64-ECMA of the block</summary>
public ulong crc64;
}
#endregion
#region Nested type: TrackEntry
/// <summary>Optical disc track</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
struct TrackEntry
{
/// <summary>Track sequence</summary>
public byte sequence;
/// <summary>Track type</summary>
public TrackType type;
/// <summary>Track starting LBA</summary>
public long start;
/// <summary>Track last LBA</summary>
public long end;
/// <summary>Track pregap in sectors</summary>
public long pregap;
/// <summary>Track session</summary>
public byte session;
/// <summary>Track's ISRC in ASCII</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 13)]
public string isrc;
/// <summary>Track flags</summary>
public byte flags;
}
#endregion
#region Nested type: TracksHeader
/// <summary>Contains list of optical disc tracks</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TracksHeader
{
/// <summary>Identifier, <see cref="BlockType.TracksBlock" /></summary>
public BlockType identifier;
/// <summary>How many entries follow this header</summary>
public ushort entries;
/// <summary>CRC64-ECMA of the block</summary>
public ulong crc64;
}
#endregion
}

View File

@@ -1,90 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Tape.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Manages Aaru Format tape images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using System.Linq;
using Aaru.CommonTypes.Structs;
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
#region IWritableTapeImage Members
/// <inheritdoc />
public List<TapeFile> Files { get; private set; }
/// <inheritdoc />
public List<TapePartition> TapePartitions { get; private set; }
/// <inheritdoc />
public bool IsTape { get; private set; }
/// <inheritdoc />
public bool AddFile(TapeFile file)
{
if(Files.Any(f => f.File == file.File))
{
TapeFile removeMe = Files.FirstOrDefault(f => f.File == file.File);
Files.Remove(removeMe);
}
Files.Add(file);
return true;
}
/// <inheritdoc />
public bool AddPartition(TapePartition partition)
{
if(TapePartitions.Any(f => f.Number == partition.Number))
{
TapePartition removeMe = TapePartitions.FirstOrDefault(f => f.Number == partition.Number);
TapePartitions.Remove(removeMe);
}
TapePartitions.Add(partition);
return true;
}
/// <inheritdoc />
public bool SetTape()
{
Files = [];
TapePartitions = [];
return IsTape = true;
}
#endregion
}

View File

@@ -1,336 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Verify.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disk image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Verifies Aaru Format disk images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using Aaru.Checksums;
using Aaru.CommonTypes.Enums;
using Aaru.Helpers;
using Aaru.Logging;
namespace Aaru.Images;
public sealed partial class AaruFormatOld
{
#region IVerifiableImage Members
/// <inheritdoc />
public bool? VerifyMediaImage()
{
// This will traverse all blocks and check their CRC64 without uncompressing them
AaruLogging.Debug(MODULE_NAME, Localization.Checking_index_integrity_at_0, _header.indexOffset);
_imageStream.Position = (long)_header.indexOffset;
_structureBytes = new byte[Marshal.SizeOf<IndexHeader>()];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
IndexHeader idxHeader = Marshal.SpanToStructureLittleEndian<IndexHeader>(_structureBytes);
if(idxHeader.identifier != BlockType.Index)
{
AaruLogging.Debug(MODULE_NAME, Localization.Incorrect_index_identifier);
return false;
}
AaruLogging.Debug(MODULE_NAME,
Localization.Index_at_0_contains_1_entries,
_header.indexOffset,
idxHeader.entries);
_structureBytes = new byte[Marshal.SizeOf<IndexEntry>() * idxHeader.entries];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
Crc64Context.Data(_structureBytes, out byte[] verifyCrc);
if(BitConverter.ToUInt64(verifyCrc, 0) != idxHeader.crc64)
{
AaruLogging.Debug(MODULE_NAME,
Localization.Expected_index_CRC_0_X16_but_got_1_X16,
idxHeader.crc64,
BitConverter.ToUInt64(verifyCrc, 0));
return false;
}
_imageStream.Position -= _structureBytes.Length;
List<IndexEntry> vrIndex = [];
for(ushort i = 0; i < idxHeader.entries; i++)
{
_structureBytes = new byte[Marshal.SizeOf<IndexEntry>()];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
IndexEntry entry = Marshal.SpanToStructureLittleEndian<IndexEntry>(_structureBytes);
AaruLogging.Debug(MODULE_NAME,
Localization.Block_type_0_with_data_type_1_is_indexed_to_be_at_2,
entry.blockType,
entry.dataType,
entry.offset);
vrIndex.Add(entry);
}
// Read up to 1MiB at a time for verification
const int verifySize = 1024 * 1024;
foreach(IndexEntry entry in vrIndex)
{
_imageStream.Position = (long)entry.offset;
Crc64Context crcVerify;
ulong readBytes;
byte[] verifyBytes;
switch(entry.blockType)
{
case BlockType.DataBlock:
_structureBytes = new byte[Marshal.SizeOf<BlockHeader>()];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
BlockHeader blockHeader = Marshal.SpanToStructureLittleEndian<BlockHeader>(_structureBytes);
crcVerify = new Crc64Context();
readBytes = 0;
AaruLogging.Debug(MODULE_NAME,
Localization.Verifying_data_block_type_0_at_position_1,
entry.dataType,
entry.offset);
while(readBytes + verifySize < blockHeader.cmpLength)
{
verifyBytes = new byte[verifySize];
_imageStream.EnsureRead(verifyBytes, 0, verifyBytes.Length);
crcVerify.Update(verifyBytes);
readBytes += (ulong)verifyBytes.LongLength;
}
verifyBytes = new byte[blockHeader.cmpLength - readBytes];
_imageStream.EnsureRead(verifyBytes, 0, verifyBytes.Length);
crcVerify.Update(verifyBytes);
verifyCrc = crcVerify.Final();
if(BitConverter.ToUInt64(verifyCrc, 0) != blockHeader.cmpCrc64)
{
AaruLogging.Debug(MODULE_NAME,
Localization.Expected_block_CRC_0_X16_but_got_1_X16,
blockHeader.cmpCrc64,
BitConverter.ToUInt64(verifyCrc, 0));
return false;
}
break;
case BlockType.DeDuplicationTable:
_structureBytes = new byte[Marshal.SizeOf<DdtHeader>()];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
DdtHeader ddtHeader = Marshal.SpanToStructureLittleEndian<DdtHeader>(_structureBytes);
crcVerify = new Crc64Context();
readBytes = 0;
AaruLogging.Debug(MODULE_NAME,
Localization.Verifying_deduplication_table_type_0_at_position_1,
entry.dataType,
entry.offset);
while(readBytes + verifySize < ddtHeader.cmpLength)
{
verifyBytes = new byte[verifySize];
_imageStream.EnsureRead(verifyBytes, 0, verifyBytes.Length);
crcVerify.Update(verifyBytes);
readBytes += (ulong)verifyBytes.LongLength;
}
verifyBytes = new byte[ddtHeader.cmpLength - readBytes];
_imageStream.EnsureRead(verifyBytes, 0, verifyBytes.Length);
crcVerify.Update(verifyBytes);
verifyCrc = crcVerify.Final();
if(BitConverter.ToUInt64(verifyCrc, 0) != ddtHeader.cmpCrc64)
{
AaruLogging.Debug(MODULE_NAME,
Localization.Expected_DDT_CRC_0_but_got_1,
ddtHeader.cmpCrc64,
BitConverter.ToUInt64(verifyCrc, 0));
return false;
}
break;
case BlockType.TracksBlock:
_structureBytes = new byte[Marshal.SizeOf<TracksHeader>()];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
TracksHeader trkHeader = Marshal.SpanToStructureLittleEndian<TracksHeader>(_structureBytes);
AaruLogging.Debug(MODULE_NAME,
Localization.Track_block_at_0_contains_1_entries,
_header.indexOffset,
trkHeader.entries);
_structureBytes = new byte[Marshal.SizeOf<TrackEntry>() * trkHeader.entries];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
Crc64Context.Data(_structureBytes, out verifyCrc);
if(BitConverter.ToUInt64(verifyCrc, 0) != trkHeader.crc64)
{
AaruLogging.Debug(MODULE_NAME,
Localization.Expected_index_CRC_0_X16_but_got_1_X16,
trkHeader.crc64,
BitConverter.ToUInt64(verifyCrc, 0));
return false;
}
break;
default:
AaruLogging.Debug(MODULE_NAME, Localization.Ignored_field_type_0, entry.blockType);
break;
}
}
return true;
}
#endregion
#region IWritableOpticalImage Members
/// <inheritdoc />
public bool? VerifySector(ulong sectorAddress)
{
if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc) return null;
ErrorNumber errno = ReadSectorLong(sectorAddress, out byte[] buffer);
return errno != ErrorNumber.NoError ? null : CdChecksums.CheckCdSector(buffer);
}
/// <inheritdoc />
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas)
{
failingLbas = [];
unknownLbas = [];
// Right now only CompactDisc sectors are verifiable
if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc)
{
for(ulong i = sectorAddress; i < sectorAddress + length; i++) unknownLbas.Add(i);
return null;
}
ErrorNumber errno = ReadSectorsLong(sectorAddress, length, out byte[] buffer);
if(errno != ErrorNumber.NoError) return null;
int bps = (int)(buffer.Length / length);
byte[] sector = new byte[bps];
failingLbas = [];
unknownLbas = [];
for(int i = 0; i < length; i++)
{
Array.Copy(buffer, i * bps, sector, 0, bps);
bool? sectorStatus = CdChecksums.CheckCdSector(sector);
switch(sectorStatus)
{
case null:
unknownLbas.Add((ulong)i + sectorAddress);
break;
case false:
failingLbas.Add((ulong)i + sectorAddress);
break;
}
}
if(unknownLbas.Count > 0) return null;
return failingLbas.Count <= 0;
}
/// <inheritdoc />
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas)
{
// Right now only CompactDisc sectors are verifiable
if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc)
{
failingLbas = [];
unknownLbas = [];
for(ulong i = sectorAddress; i < sectorAddress + length; i++) unknownLbas.Add(i);
return null;
}
failingLbas = [];
unknownLbas = [];
ErrorNumber errno = ReadSectorsLong(sectorAddress, length, track, out byte[] buffer);
if(errno != ErrorNumber.NoError) return null;
int bps = (int)(buffer.Length / length);
byte[] sector = new byte[bps];
for(int i = 0; i < length; i++)
{
Array.Copy(buffer, i * bps, sector, 0, bps);
bool? sectorStatus = CdChecksums.CheckCdSector(sector);
switch(sectorStatus)
{
case null:
unknownLbas.Add((ulong)i + sectorAddress);
break;
case false:
failingLbas.Add((ulong)i + sectorAddress);
break;
}
}
if(unknownLbas.Count > 0) return null;
return failingLbas.Count <= 0;
}
#endregion
}

File diff suppressed because it is too large Load Diff