mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Read existing tape file and partition blocks in dicformat.
This commit is contained in:
@@ -122,7 +122,6 @@ namespace DiscImageChef.DiscImages
|
|||||||
List<IndexEntry> index;
|
List<IndexEntry> index;
|
||||||
/// <summary>If set to <c>true</c>, the DDT entries are in-memory.</summary>
|
/// <summary>If set to <c>true</c>, the DDT entries are in-memory.</summary>
|
||||||
bool inMemoryDdt;
|
bool inMemoryDdt;
|
||||||
bool isTape;
|
|
||||||
ulong lastWrittenBlock;
|
ulong lastWrittenBlock;
|
||||||
/// <summary>LZMA stream.</summary>
|
/// <summary>LZMA stream.</summary>
|
||||||
LzmaStream lzmaBlockStream;
|
LzmaStream lzmaBlockStream;
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
if(inMemoryDdt)
|
if(inMemoryDdt)
|
||||||
{
|
{
|
||||||
if(isTape) tapeDdt[sectorAddress] = pointer;
|
if(IsTape) tapeDdt[sectorAddress] = pointer;
|
||||||
else userDataDdt[sectorAddress] = pointer;
|
else userDataDdt[sectorAddress] = pointer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -811,6 +811,59 @@ namespace DiscImageChef.DiscImages
|
|||||||
DicConsole.DebugWriteLine("DiscImageChef format plugin", "Memory snapshot: {0} bytes",
|
DicConsole.DebugWriteLine("DiscImageChef format plugin", "Memory snapshot: {0} bytes",
|
||||||
GC.GetTotalMemory(false));
|
GC.GetTotalMemory(false));
|
||||||
break;
|
break;
|
||||||
|
// Tape partition block
|
||||||
|
case BlockType.TapePartitionBlock:
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<TapePartitionHeader>()];
|
||||||
|
imageStream.Read(structureBytes, 0, structureBytes.Length);
|
||||||
|
TapePartitionHeader partitionHeader =
|
||||||
|
Marshal.SpanToStructureLittleEndian<TapePartitionHeader>(structureBytes);
|
||||||
|
if(partitionHeader.identifier != BlockType.TapePartitionBlock) break;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("DiscImageChef format plugin",
|
||||||
|
"Found tape partition block at position {0}", entry.offset);
|
||||||
|
|
||||||
|
byte[] tapePartitionBytes = new byte[partitionHeader.length];
|
||||||
|
imageStream.Read(tapePartitionBytes, 0, tapePartitionBytes.Length);
|
||||||
|
Span<TapePartitionEntry> tapePartitions =
|
||||||
|
MemoryMarshal.Cast<byte, TapePartitionEntry>(tapePartitionBytes);
|
||||||
|
TapePartitions = new List<TapePartition>();
|
||||||
|
|
||||||
|
foreach(TapePartitionEntry tapePartition in tapePartitions)
|
||||||
|
TapePartitions.Add(new TapePartition
|
||||||
|
{
|
||||||
|
FirstBlock = tapePartition.FirstBlock,
|
||||||
|
LastBlock = tapePartition.LastBlock,
|
||||||
|
Number = tapePartition.Number
|
||||||
|
});
|
||||||
|
|
||||||
|
IsTape = true;
|
||||||
|
break;
|
||||||
|
// Tape file block
|
||||||
|
case BlockType.TapeFileBlock:
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<TapeFileHeader>()];
|
||||||
|
imageStream.Read(structureBytes, 0, structureBytes.Length);
|
||||||
|
TapeFileHeader fileHeader = Marshal.SpanToStructureLittleEndian<TapeFileHeader>(structureBytes);
|
||||||
|
if(fileHeader.identifier != BlockType.TapeFileBlock) break;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("DiscImageChef format plugin",
|
||||||
|
"Found tape file block at position {0}", entry.offset);
|
||||||
|
|
||||||
|
byte[] tapeFileBytes = new byte[fileHeader.length];
|
||||||
|
imageStream.Read(tapeFileBytes, 0, tapeFileBytes.Length);
|
||||||
|
Span<TapeFileEntry> tapeFiles = MemoryMarshal.Cast<byte, TapeFileEntry>(tapeFileBytes);
|
||||||
|
Files = new List<TapeFile>();
|
||||||
|
|
||||||
|
foreach(TapeFileEntry file in tapeFiles)
|
||||||
|
Files.Add(new TapeFile
|
||||||
|
{
|
||||||
|
FirstBlock = file.FirstBlock,
|
||||||
|
LastBlock = file.LastBlock,
|
||||||
|
Partition = file.Partition,
|
||||||
|
File = file.File
|
||||||
|
});
|
||||||
|
|
||||||
|
IsTape = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1150,6 +1203,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorPrefix;
|
dataSource = sectorPrefix;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SectorTagType.CdSectorHeader:
|
case SectorTagType.CdSectorHeader:
|
||||||
{
|
{
|
||||||
sectorOffset = 12;
|
sectorOffset = 12;
|
||||||
@@ -1158,6 +1212,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorPrefix;
|
dataSource = sectorPrefix;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SectorTagType.CdSectorSubHeader:
|
case SectorTagType.CdSectorSubHeader:
|
||||||
throw new ArgumentException("Unsupported tag requested for this track", nameof(tag));
|
throw new ArgumentException("Unsupported tag requested for this track", nameof(tag));
|
||||||
case SectorTagType.CdSectorEcc:
|
case SectorTagType.CdSectorEcc:
|
||||||
@@ -1168,6 +1223,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorSuffix;
|
dataSource = sectorSuffix;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SectorTagType.CdSectorEccP:
|
case SectorTagType.CdSectorEccP:
|
||||||
{
|
{
|
||||||
sectorOffset = 12;
|
sectorOffset = 12;
|
||||||
@@ -1176,6 +1232,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorSuffix;
|
dataSource = sectorSuffix;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SectorTagType.CdSectorEccQ:
|
case SectorTagType.CdSectorEccQ:
|
||||||
{
|
{
|
||||||
sectorOffset = 184;
|
sectorOffset = 184;
|
||||||
@@ -1184,6 +1241,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorSuffix;
|
dataSource = sectorSuffix;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SectorTagType.CdSectorEdc:
|
case SectorTagType.CdSectorEdc:
|
||||||
{
|
{
|
||||||
sectorOffset = 0;
|
sectorOffset = 0;
|
||||||
@@ -1192,6 +1250,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorSuffix;
|
dataSource = sectorSuffix;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SectorTagType.CdSectorSubchannel:
|
case SectorTagType.CdSectorSubchannel:
|
||||||
{
|
{
|
||||||
sectorOffset = 0;
|
sectorOffset = 0;
|
||||||
@@ -1200,6 +1259,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorSubchannel;
|
dataSource = sectorSubchannel;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
|
default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1218,6 +1278,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorPrefix;
|
dataSource = sectorPrefix;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SectorTagType.CdSectorHeader:
|
case SectorTagType.CdSectorHeader:
|
||||||
{
|
{
|
||||||
sectorOffset = 12;
|
sectorOffset = 12;
|
||||||
@@ -1226,6 +1287,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorPrefix;
|
dataSource = sectorPrefix;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These could be implemented
|
// These could be implemented
|
||||||
case SectorTagType.CdSectorEcc:
|
case SectorTagType.CdSectorEcc:
|
||||||
case SectorTagType.CdSectorEccP:
|
case SectorTagType.CdSectorEccP:
|
||||||
@@ -1241,11 +1303,13 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorSubchannel;
|
dataSource = sectorSubchannel;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
|
default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TrackType.Audio:
|
case TrackType.Audio:
|
||||||
{
|
{
|
||||||
switch(tag)
|
switch(tag)
|
||||||
@@ -1258,11 +1322,13 @@ namespace DiscImageChef.DiscImages
|
|||||||
dataSource = sectorSubchannel;
|
dataSource = sectorSubchannel;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
|
default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
|
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
public List<TapeFile> Files { get; private set; }
|
public List<TapeFile> Files { get; private set; }
|
||||||
public List<TapePartition> TapePartitions { get; private set; }
|
public List<TapePartition> TapePartitions { get; private set; }
|
||||||
|
public bool IsTape { get; private set; }
|
||||||
|
|
||||||
public bool AddFile(TapeFile file)
|
public bool AddFile(TapeFile file)
|
||||||
{
|
{
|
||||||
@@ -69,7 +70,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
Files = new List<TapeFile>();
|
Files = new List<TapeFile>();
|
||||||
TapePartitions = new List<TapePartition>();
|
TapePartitions = new List<TapePartition>();
|
||||||
return isTape = true;
|
return IsTape = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -407,7 +407,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
|
|
||||||
if(ddtHeader.identifier != BlockType.DeDuplicationTable) break;
|
if(ddtHeader.identifier != BlockType.DeDuplicationTable) break;
|
||||||
|
|
||||||
if(ddtHeader.entries != imageInfo.Sectors && !isTape)
|
if(ddtHeader.entries != imageInfo.Sectors && !IsTape)
|
||||||
{
|
{
|
||||||
ErrorMessage =
|
ErrorMessage =
|
||||||
$"Trying to write a media with {imageInfo.Sectors} sectors to an image with {ddtHeader.entries} sectors, not continuing...";
|
$"Trying to write a media with {imageInfo.Sectors} sectors to an image with {ddtHeader.entries} sectors, not continuing...";
|
||||||
@@ -449,7 +449,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
ImageNotSupportedException($"Found unsupported compression algorithm {(ushort)ddtHeader.compression}");
|
ImageNotSupportedException($"Found unsupported compression algorithm {(ushort)ddtHeader.compression}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isTape)
|
if(IsTape)
|
||||||
{
|
{
|
||||||
tapeDdt = new Dictionary<ulong, ulong>();
|
tapeDdt = new Dictionary<ulong, ulong>();
|
||||||
for(long i = 0; i < userDataDdt.LongLength; i++)
|
for(long i = 0; i < userDataDdt.LongLength; i++)
|
||||||
@@ -672,6 +672,60 @@ namespace DiscImageChef.DiscImages
|
|||||||
|
|
||||||
if(DumpHardware.Count == 0) DumpHardware = null;
|
if(DumpHardware.Count == 0) DumpHardware = null;
|
||||||
break;
|
break;
|
||||||
|
// Tape partition block
|
||||||
|
case BlockType.TapePartitionBlock:
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<TapePartitionHeader>()];
|
||||||
|
imageStream.Read(structureBytes, 0, structureBytes.Length);
|
||||||
|
TapePartitionHeader partitionHeader =
|
||||||
|
Marshal.SpanToStructureLittleEndian<TapePartitionHeader>(structureBytes);
|
||||||
|
if(partitionHeader.identifier != BlockType.TapePartitionBlock) break;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("DiscImageChef format plugin",
|
||||||
|
"Found tape partition block at position {0}", entry.offset);
|
||||||
|
|
||||||
|
byte[] tapePartitionBytes = new byte[partitionHeader.length];
|
||||||
|
imageStream.Read(tapePartitionBytes, 0, tapePartitionBytes.Length);
|
||||||
|
Span<TapePartitionEntry> tapePartitions =
|
||||||
|
MemoryMarshal.Cast<byte, TapePartitionEntry>(tapePartitionBytes);
|
||||||
|
TapePartitions = new List<TapePartition>();
|
||||||
|
|
||||||
|
foreach(TapePartitionEntry tapePartition in tapePartitions)
|
||||||
|
TapePartitions.Add(new TapePartition
|
||||||
|
{
|
||||||
|
FirstBlock = tapePartition.FirstBlock,
|
||||||
|
LastBlock = tapePartition.LastBlock,
|
||||||
|
Number = tapePartition.Number
|
||||||
|
});
|
||||||
|
|
||||||
|
IsTape = true;
|
||||||
|
break;
|
||||||
|
// Tape file block
|
||||||
|
case BlockType.TapeFileBlock:
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<TapeFileHeader>()];
|
||||||
|
imageStream.Read(structureBytes, 0, structureBytes.Length);
|
||||||
|
TapeFileHeader fileHeader =
|
||||||
|
Marshal.SpanToStructureLittleEndian<TapeFileHeader>(structureBytes);
|
||||||
|
if(fileHeader.identifier != BlockType.TapeFileBlock) break;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("DiscImageChef format plugin",
|
||||||
|
"Found tape file block at position {0}", entry.offset);
|
||||||
|
|
||||||
|
byte[] tapeFileBytes = new byte[fileHeader.length];
|
||||||
|
imageStream.Read(tapeFileBytes, 0, tapeFileBytes.Length);
|
||||||
|
Span<TapeFileEntry> tapeFiles = MemoryMarshal.Cast<byte, TapeFileEntry>(tapeFileBytes);
|
||||||
|
Files = new List<TapeFile>();
|
||||||
|
|
||||||
|
foreach(TapeFileEntry file in tapeFiles)
|
||||||
|
Files.Add(new TapeFile
|
||||||
|
{
|
||||||
|
FirstBlock = file.FirstBlock,
|
||||||
|
LastBlock = file.LastBlock,
|
||||||
|
Partition = file.Partition,
|
||||||
|
File = file.File
|
||||||
|
});
|
||||||
|
|
||||||
|
IsTape = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,7 +753,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
// If in memory, easy
|
// If in memory, easy
|
||||||
if(inMemoryDdt)
|
if(inMemoryDdt)
|
||||||
{
|
{
|
||||||
if(isTape) tapeDdt = new Dictionary<ulong, ulong>();
|
if(IsTape) tapeDdt = new Dictionary<ulong, ulong>();
|
||||||
else userDataDdt = new ulong[sectors];
|
else userDataDdt = new ulong[sectors];
|
||||||
}
|
}
|
||||||
// If not, create the block, add to index, and enlarge the file to allow the DDT to exist on-disk
|
// If not, create the block, add to index, and enlarge the file to allow the DDT to exist on-disk
|
||||||
@@ -811,7 +865,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sectorAddress >= Info.Sectors && !isTape)
|
if(sectorAddress >= Info.Sectors && !IsTape)
|
||||||
{
|
{
|
||||||
ErrorMessage = "Tried to write past image size";
|
ErrorMessage = "Tried to write past image size";
|
||||||
return false;
|
return false;
|
||||||
@@ -1867,7 +1921,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isTape)
|
if(IsTape)
|
||||||
{
|
{
|
||||||
ulong latestBlock = tapeDdt.Max(b => b.Key);
|
ulong latestBlock = tapeDdt.Max(b => b.Key);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user