mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
* DiscImageChef.DiscImages/NDIF.cs:
Corrected sector calculation. Added support for multiple block chunk resources. * DiscImageChef.DiscImages/UDIF.cs: Corrected sector calculation.
This commit is contained in:
@@ -85,9 +85,9 @@ namespace DiscImageChef.DiscImages
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint maxSectorsPerChunk;
|
public uint maxSectorsPerChunk;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Always 0?
|
/// Offset to add to every chunk offset
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint zeroOffset;
|
public uint dataOffset;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CRC28 of whole image
|
/// CRC28 of whole image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -135,7 +135,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public byte type;
|
public byte type;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Offset in image to start of chunk
|
/// Offset in start of chunk
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint offset;
|
public uint offset;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -255,7 +255,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
|
|
||||||
ResourceFork rsrcFork;
|
ResourceFork rsrcFork;
|
||||||
Resource rsrc;
|
Resource rsrc;
|
||||||
byte[] bcem;
|
short[] bcems;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -265,76 +265,84 @@ namespace DiscImageChef.DiscImages
|
|||||||
|
|
||||||
rsrc = rsrcFork.GetResource(NDIF_Resource);
|
rsrc = rsrcFork.GetResource(NDIF_Resource);
|
||||||
|
|
||||||
if(!rsrc.ContainsId(NDIF_ResourceID))
|
bcems = rsrc.GetIds();
|
||||||
return false;
|
|
||||||
|
|
||||||
bcem = rsrc.GetResource(NDIF_ResourceID);
|
if(bcems == null || bcems.Length == 0)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
catch(InvalidCastException)
|
catch(InvalidCastException)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bcem.Length < 128)
|
ImageInfo.sectors = 0;
|
||||||
return false;
|
foreach(short id in bcems)
|
||||||
|
|
||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<ChunkHeader>(bcem);
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.type = {0}", header.version);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.driver = {0}", header.driver);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.name = {0}", StringHandlers.PascalToString(header.name));
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.sectors = {0}", header.sectors);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.maxSectorsPerChunk = {0}", header.maxSectorsPerChunk);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.zeroOffset = {0}", header.zeroOffset);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.crc = 0x{0:X7}", header.crc);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.segmented = {0}", header.segmented);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.p1 = 0x{0:X8}", header.p1);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.p2 = 0x{0:X8}", header.p2);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[0] = 0x{0:X8}", header.unknown[0]);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[1] = 0x{0:X8}", header.unknown[1]);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[2] = 0x{0:X8}", header.unknown[2]);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[3] = 0x{0:X8}", header.unknown[3]);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[4] = 0x{0:X8}", header.unknown[4]);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.encrypted = {0}", header.encrypted);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.hash = 0x{0:X8}", header.hash);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "footer.chunks = {0}", header.chunks);
|
|
||||||
|
|
||||||
// Block chunks and headers
|
|
||||||
chunks = new Dictionary<ulong, BlockChunk>();
|
|
||||||
|
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
|
||||||
|
|
||||||
for(int i = 0; i < header.chunks; i++)
|
|
||||||
{
|
{
|
||||||
// Obsolete read-only NDIF only prepended the header and then put the image without any kind of block references.
|
byte[] bcem = rsrc.GetResource(NDIF_ResourceID);
|
||||||
// So let's falsify a block chunk
|
|
||||||
BlockChunk bChnk = new BlockChunk();
|
|
||||||
byte[] sector = new byte[4];
|
|
||||||
Array.Copy(bcem, 128 + 0 + i * 12, sector, 1, 3);
|
|
||||||
bChnk.sector = BigEndianBitConverter.ToUInt32(sector, 0);
|
|
||||||
bChnk.type = bcem[128 + 3 + i * 12];
|
|
||||||
bChnk.offset = BigEndianBitConverter.ToUInt32(bcem, 128 + 4 + i * 12);
|
|
||||||
bChnk.length = BigEndianBitConverter.ToUInt32(bcem, 128 + 8 + i * 12);
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].type = 0x{1:X2}", i, bChnk.type);
|
if(bcem.Length < 128)
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].sector = {1}", i, bChnk.sector);
|
return false;
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].offset = {1}", i, bChnk.offset);
|
|
||||||
DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].length = {1}", i, bChnk.length);
|
|
||||||
|
|
||||||
if(bChnk.type == ChunkType_End)
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<ChunkHeader>(bcem);
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.type = {0}", header.version);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.driver = {0}", header.driver);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.name = {0}", StringHandlers.PascalToString(header.name));
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.sectors = {0}", header.sectors);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.maxSectorsPerChunk = {0}", header.maxSectorsPerChunk);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.dataOffset = {0}", header.dataOffset);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.crc = 0x{0:X7}", header.crc);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.segmented = {0}", header.segmented);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.p1 = 0x{0:X8}", header.p1);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.p2 = 0x{0:X8}", header.p2);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[0] = 0x{0:X8}", header.unknown[0]);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[1] = 0x{0:X8}", header.unknown[1]);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[2] = 0x{0:X8}", header.unknown[2]);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[3] = 0x{0:X8}", header.unknown[3]);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[4] = 0x{0:X8}", header.unknown[4]);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.encrypted = {0}", header.encrypted);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.hash = 0x{0:X8}", header.hash);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "footer.chunks = {0}", header.chunks);
|
||||||
|
|
||||||
|
// Block chunks and headers
|
||||||
|
chunks = new Dictionary<ulong, BlockChunk>();
|
||||||
|
|
||||||
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
|
|
||||||
|
ImageInfo.sectors += header.sectors;
|
||||||
|
|
||||||
|
for(int i = 0; i < header.chunks; i++)
|
||||||
{
|
{
|
||||||
ImageInfo.sectors = bChnk.sector;
|
// Obsolete read-only NDIF only prepended the header and then put the image without any kind of block references.
|
||||||
break;
|
// So let's falsify a block chunk
|
||||||
|
BlockChunk bChnk = new BlockChunk();
|
||||||
|
byte[] sector = new byte[4];
|
||||||
|
Array.Copy(bcem, 128 + 0 + i * 12, sector, 1, 3);
|
||||||
|
bChnk.sector = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||||
|
bChnk.type = bcem[128 + 3 + i * 12];
|
||||||
|
bChnk.offset = BigEndianBitConverter.ToUInt32(bcem, 128 + 4 + i * 12);
|
||||||
|
bChnk.length = BigEndianBitConverter.ToUInt32(bcem, 128 + 8 + i * 12);
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].type = 0x{1:X2}", i, bChnk.type);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].sector = {1}", i, bChnk.sector);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].offset = {1}", i, bChnk.offset);
|
||||||
|
DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].length = {1}", i, bChnk.length);
|
||||||
|
|
||||||
|
if(bChnk.type == ChunkType_End)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bChnk.offset += header.dataOffset;
|
||||||
|
bChnk.sector += (uint)ImageInfo.sectors;
|
||||||
|
|
||||||
|
// TODO: Handle compressed chunks
|
||||||
|
if((bChnk.type & ChunkType_CompressedMask) == ChunkType_CompressedMask)
|
||||||
|
throw new ImageNotSupportedException("Compressed chunks are not yet supported.");
|
||||||
|
|
||||||
|
if(bChnk.type != ChunkType_Copy && bChnk.type != ChunkType_NoCopy)
|
||||||
|
throw new ImageNotSupportedException(string.Format("Unsupported chunk type 0x{0:X8} found", bChnk.type));
|
||||||
|
|
||||||
|
chunks.Add(bChnk.sector, bChnk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle compressed chunks
|
|
||||||
if((bChnk.type & ChunkType_CompressedMask) == ChunkType_CompressedMask)
|
|
||||||
throw new ImageNotSupportedException("Compressed chunks are not yet supported.");
|
|
||||||
|
|
||||||
if(bChnk.type != ChunkType_Copy && bChnk.type != ChunkType_NoCopy)
|
|
||||||
throw new ImageNotSupportedException(string.Format("Unsupported chunk type 0x{0:X8} found", bChnk.type));
|
|
||||||
|
|
||||||
chunks.Add(bChnk.sector, bChnk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(header.segmented > 0)
|
if(header.segmented > 0)
|
||||||
|
|||||||
@@ -405,6 +405,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
ImageInfo.imageApplication = "DiskCopy";
|
ImageInfo.imageApplication = "DiskCopy";
|
||||||
DicConsole.DebugWriteLine("UDIF plugin", "Image application = {0} version {1}", ImageInfo.imageApplication, ImageInfo.imageApplicationVersion);
|
DicConsole.DebugWriteLine("UDIF plugin", "Image application = {0} version {1}", ImageInfo.imageApplication, ImageInfo.imageApplicationVersion);
|
||||||
|
|
||||||
|
ImageInfo.sectors = 0;
|
||||||
if(!fakeBlockChunks)
|
if(!fakeBlockChunks)
|
||||||
{
|
{
|
||||||
if(blkxList.Count == 0)
|
if(blkxList.Count == 0)
|
||||||
@@ -452,10 +453,13 @@ namespace DiscImageChef.DiscImages
|
|||||||
DicConsole.DebugWriteLine("UDIF plugin", "bHdr.chunk[{0}].length = {1}", i, bChnk.length);
|
DicConsole.DebugWriteLine("UDIF plugin", "bHdr.chunk[{0}].length = {1}", i, bChnk.length);
|
||||||
|
|
||||||
if(bChnk.type == ChunkType_End)
|
if(bChnk.type == ChunkType_End)
|
||||||
{
|
|
||||||
ImageInfo.sectors = bChnk.sector;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
ImageInfo.sectors += bChnk.sectors;
|
||||||
|
|
||||||
|
// Chunk offset is relative
|
||||||
|
bChnk.sector += bHdr.sectorStart;
|
||||||
|
bChnk.offset += bHdr.dataOffset;
|
||||||
|
|
||||||
// TODO: Handle comments
|
// TODO: Handle comments
|
||||||
if(bChnk.type == ChunkType_Commnt)
|
if(bChnk.type == ChunkType_Commnt)
|
||||||
|
|||||||
Reference in New Issue
Block a user