mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
[AaruFormat] Remove old implementation.
This commit is contained in:
@@ -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
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
@@ -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) << 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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user