mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
In dicformat deconstruct MODE 2 sectors so if they have correct ECC, correct/empty EDC, those fields are not stored in the image.
This commit is contained in:
@@ -41,9 +41,12 @@ namespace DiscImageChef.DiscImages
|
||||
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];
|
||||
@@ -57,30 +60,22 @@ namespace DiscImageChef.DiscImages
|
||||
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;
|
||||
|
||||
byte[] address = new byte[4];
|
||||
byte[] data = new byte[2060];
|
||||
byte[] data2 = new byte[2232];
|
||||
byte[] eccP = new byte[172];
|
||||
byte[] eccQ = new byte[104];
|
||||
|
||||
Array.Copy(sector, 0x0C, address, 0, 4);
|
||||
Array.Copy(sector, 0x10, data, 0, 2060);
|
||||
Array.Copy(sector, 0x10, data2, 0, 2232);
|
||||
Array.Copy(sector, 0x81C, eccP, 0, 172);
|
||||
Array.Copy(sector, 0x8C8, eccQ, 0, 104);
|
||||
|
||||
bool correctEccP = CheckEcc(ref address, ref data, 86, 24, 2, 86, ref eccP);
|
||||
bool correctEccP = CheckEcc(sector, sector, 86, 24, 2, 86, sector, 0xC, 0x10, 0x81C);
|
||||
if(!correctEccP) return false;
|
||||
|
||||
bool correctEccQ = CheckEcc(ref address, ref data2, 52, 43, 86, 88, ref eccQ);
|
||||
bool correctEccQ = CheckEcc(sector, sector, 52, 43, 86, 88, sector, 0xC, 0x10, 0x81C + 0xAC);
|
||||
if(!correctEccQ) return false;
|
||||
|
||||
uint storedEdc = BitConverter.ToUInt32(sector, 0x810);
|
||||
@@ -93,8 +88,31 @@ namespace DiscImageChef.DiscImages
|
||||
return calculatedEdc == storedEdc;
|
||||
}
|
||||
|
||||
bool CheckEcc(ref byte[] address, ref byte[] data, uint majorCount, uint minorCount, uint majorMult,
|
||||
uint minorInc, ref byte[] ecc)
|
||||
bool SuffixIsCorrectMode2(byte[] sector)
|
||||
{
|
||||
if(!initedEdc) EccInit();
|
||||
|
||||
byte[] 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;
|
||||
|
||||
uint storedEdc = BitConverter.ToUInt32(sector, 0x818);
|
||||
uint edc = 0;
|
||||
int size = 0x808;
|
||||
int 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;
|
||||
@@ -106,7 +124,7 @@ namespace DiscImageChef.DiscImages
|
||||
uint minor;
|
||||
for(minor = 0; minor < minorCount; minor++)
|
||||
{
|
||||
byte temp = idx < 4 ? address[idx] : data[idx - 4];
|
||||
byte temp = idx < 4 ? address[idx + addressOffset] : data[idx + dataOffset - 4];
|
||||
idx += minorInc;
|
||||
if(idx >= size) idx -= size;
|
||||
eccA ^= temp;
|
||||
@@ -115,7 +133,7 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
|
||||
eccA = eccBTable[eccFTable[eccA] ^ eccB];
|
||||
if(ecc[major] != eccA || ecc[major + majorCount] != (eccA ^ eccB)) return false;
|
||||
if(ecc[major + eccOffset] != eccA || ecc[major + majorCount + eccOffset] != (eccA ^ eccB)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -217,6 +235,7 @@ namespace DiscImageChef.DiscImages
|
||||
TrackType type)
|
||||
{
|
||||
byte[] computedEdc;
|
||||
if(!initedEdc) EccInit();
|
||||
|
||||
switch(type)
|
||||
{
|
||||
@@ -281,6 +300,7 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
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];
|
||||
|
||||
|
||||
@@ -253,7 +253,10 @@ namespace DiscImageChef.DiscImages
|
||||
enum CdFixFlags : uint
|
||||
{
|
||||
NotDumped = 0x10000000,
|
||||
Correct = 0x20000000
|
||||
Correct = 0x20000000,
|
||||
Mode2Form1Ok = 0x30000000,
|
||||
Mode2Form2Ok = 0x40000000,
|
||||
Mode2Form2NoCrc = 0x50000000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1249,8 +1249,46 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
if(mode2Subheaders == null) mode2Subheaders = new byte[imageInfo.Sectors * 8];
|
||||
|
||||
bool correctEcc = SuffixIsCorrectMode2(data);
|
||||
bool correctEdc = false;
|
||||
|
||||
if(correctEcc)
|
||||
{
|
||||
uint computedEdc = ComputeEdc(0, data, 0x808, 0x10);
|
||||
uint edc = BitConverter.ToUInt32(data, 0x818);
|
||||
correctEdc = computedEdc == edc;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint computedEdc = ComputeEdc(0, data, 0x91C, 0x10);
|
||||
uint edc = BitConverter.ToUInt32(data, 0x92C);
|
||||
correctEdc = computedEdc == edc;
|
||||
}
|
||||
|
||||
if(correctEcc && correctEdc)
|
||||
{
|
||||
sector = new byte[2048];
|
||||
if(sectorSuffixDdt == null) sectorSuffixDdt = new uint[imageInfo.Sectors];
|
||||
sectorSuffixDdt[sectorAddress] = (uint)CdFixFlags.Mode2Form1Ok;
|
||||
Array.Copy(data, 24, sector, 0, 2048);
|
||||
}
|
||||
else if(correctEdc)
|
||||
{
|
||||
sector = new byte[2324];
|
||||
if(sectorSuffixDdt == null) sectorSuffixDdt = new uint[imageInfo.Sectors];
|
||||
sectorSuffixDdt[sectorAddress] = (uint)CdFixFlags.Mode2Form2Ok;
|
||||
Array.Copy(data, 24, sector, 0, 2324);
|
||||
}
|
||||
else if(BitConverter.ToUInt32(data, 0x92C) == 0)
|
||||
{
|
||||
sector = new byte[2324];
|
||||
if(sectorSuffixDdt == null) sectorSuffixDdt = new uint[imageInfo.Sectors];
|
||||
sectorSuffixDdt[sectorAddress] = (uint)CdFixFlags.Mode2Form2NoCrc;
|
||||
Array.Copy(data, 24, sector, 0, 2324);
|
||||
}
|
||||
else Array.Copy(data, 24, sector, 0, 2328);
|
||||
|
||||
Array.Copy(data, 16, mode2Subheaders, (int)sectorAddress * 8, 8);
|
||||
Array.Copy(data, 24, sector, 0, 2328);
|
||||
return WriteSector(sector, sectorAddress);
|
||||
}
|
||||
|
||||
@@ -2454,7 +2492,6 @@ namespace DiscImageChef.DiscImages
|
||||
blockStream = null;
|
||||
}
|
||||
|
||||
|
||||
if(sectorSubchannel != null)
|
||||
{
|
||||
idxEntry = new IndexEntry
|
||||
|
||||
Reference in New Issue
Block a user