mirror of
https://github.com/aaru-dps/Aaru.Checksums.git
synced 2025-12-16 19:24:29 +00:00
🐛Correct CD EDC calcuations.
This commit is contained in:
@@ -42,10 +42,9 @@ namespace DiscImageChef.Checksums
|
||||
/// </summary>
|
||||
public static class CdChecksums
|
||||
{
|
||||
const uint CDCRC32_POLY = 0xD8018001;
|
||||
const uint CDCRC32_SEED = 0x00000000;
|
||||
static byte[] eccFTable;
|
||||
static byte[] eccBTable;
|
||||
static uint[] edcTable;
|
||||
|
||||
static readonly ushort[] CcittCrc16Table =
|
||||
{
|
||||
@@ -109,12 +108,16 @@ namespace DiscImageChef.Checksums
|
||||
{
|
||||
eccFTable = new byte[256];
|
||||
eccBTable = new byte[256];
|
||||
edcTable = new uint[256];
|
||||
|
||||
for(uint i = 0; i < 256; i++)
|
||||
{
|
||||
uint edc = i;
|
||||
uint 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +134,7 @@ namespace DiscImageChef.Checksums
|
||||
uint minor;
|
||||
for(minor = 0; minor < minorCount; minor++)
|
||||
{
|
||||
byte temp;
|
||||
temp = index < 4 ? address[index] : data[index - 4];
|
||||
byte temp = index < 4 ? address[index] : data[index - 4];
|
||||
index += minorInc;
|
||||
if(index >= size) index -= size;
|
||||
eccA ^= temp;
|
||||
@@ -214,27 +216,23 @@ namespace DiscImageChef.Checksums
|
||||
"Mode 1 sector at address: {0:X2}:{1:X2}:{2:X2}, fails ECC Q check",
|
||||
channel[0x00C], channel[0x00D], channel[0x00E]);
|
||||
|
||||
return !failedEccP && !failedEccQ;
|
||||
uint storedEdc = BitConverter.ToUInt32(channel, 0x810);
|
||||
uint calculatedEdc = ComputeEdc(0, channel, 0x810);
|
||||
|
||||
/* TODO: This is not working
|
||||
byte[] SectorForCheck = new byte[0x810];
|
||||
uint StoredEDC = BitConverter.ToUInt32(channel, 0x810);
|
||||
byte[] CalculatedEDCBytes;
|
||||
Array.Copy(channel, 0, SectorForCheck, 0, 0x810);
|
||||
CRC32Context.Data(SectorForCheck, 0x810, out CalculatedEDCBytes, CDCRC32Poly, CDCRC32Seed);
|
||||
uint CalculatedEDC = BitConverter.ToUInt32(CalculatedEDCBytes, 0);
|
||||
if(calculatedEdc == storedEdc) return !failedEccP && !failedEccQ;
|
||||
|
||||
if(CalculatedEDC != StoredEDC)
|
||||
{
|
||||
DicConsole.DebugWriteLine("CD checksums", "Mode 1 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}", channel[0x00C], channel[0x00D], channel[0x00E], CalculatedEDC, StoredEDC);
|
||||
DicConsole.DebugWriteLine("CD checksums",
|
||||
"Mode 1 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}",
|
||||
channel[0x00C], channel[0x00D], channel[0x00E], calculatedEdc, storedEdc);
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
|
||||
if(channel[0x00F] == 0x02) // mode (1 byte)
|
||||
{
|
||||
DicConsole.DebugWriteLine("CD checksums", "Mode 2 sector at address {0:X2}:{1:X2}:{2:X2}",
|
||||
channel[0x00C], channel[0x00D], channel[0x00E]);
|
||||
//DicConsole.DebugWriteLine("CD checksums", "Mode 2 sector at address {0:X2}:{1:X2}:{2:X2}",
|
||||
// channel[0x00C], channel[0x00D], channel[0x00E]);
|
||||
byte[] mode2Sector = new byte[channel.Length - 0x10];
|
||||
Array.Copy(channel, 0x10, mode2Sector, 0, mode2Sector.Length);
|
||||
|
||||
if((channel[0x012] & 0x20) == 0x20) // mode 2 form 2
|
||||
{
|
||||
@@ -244,19 +242,18 @@ namespace DiscImageChef.Checksums
|
||||
"Subheader copies differ in mode 2 form 2 sector at address: {0:X2}:{1:X2}:{2:X2}",
|
||||
channel[0x00C], channel[0x00D], channel[0x00E]);
|
||||
|
||||
/* TODO: This is not working
|
||||
byte[] SectorForCheck = new byte[0x91C];
|
||||
uint StoredEDC = BitConverter.ToUInt32(channel, 0x92C);
|
||||
byte[] CalculatedEDCBytes;
|
||||
Array.Copy(channel, 0x10, SectorForCheck, 0, 0x91C);
|
||||
CRC32Context.Data(SectorForCheck, 0x91C, out CalculatedEDCBytes, CDCRC32Poly, CDCRC32Seed);
|
||||
uint CalculatedEDC = BitConverter.ToUInt32(CalculatedEDCBytes, 0);
|
||||
uint storedEdc = BitConverter.ToUInt32(mode2Sector, 0x91C);
|
||||
// No CRC stored!
|
||||
if(storedEdc == 0x00000000) return true;
|
||||
|
||||
if(CalculatedEDC != StoredEDC && StoredEDC != 0x00000000)
|
||||
{
|
||||
DicConsole.DebugWriteLine("CD checksums", "Mode 2 form 2 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}", channel[0x00C], channel[0x00D], channel[0x00E], CalculatedEDC, StoredEDC);
|
||||
uint calculatedEdc = ComputeEdc(0, mode2Sector, 0x91C);
|
||||
|
||||
if(calculatedEdc == storedEdc || storedEdc == 0x00000000) return true;
|
||||
|
||||
DicConsole.DebugWriteLine("CD checksums",
|
||||
"Mode 2 form 2 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}",
|
||||
channel[0x00C], channel[0x00D], channel[0x00E], calculatedEdc, storedEdc);
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -291,23 +288,17 @@ namespace DiscImageChef.Checksums
|
||||
if(failedEccQ)
|
||||
DicConsole.DebugWriteLine("CD checksums",
|
||||
"Mode 2 form 1 sector at address: {0:X2}:{1:X2}:{2:X2}, fails ECC Q check",
|
||||
channel[0x00F], channel[0x00C], channel[0x00D], channel[0x00E]);
|
||||
channel[0x00C], channel[0x00D], channel[0x00E]);
|
||||
|
||||
return !failedEccP && !failedEccQ;
|
||||
uint storedEdc = BitConverter.ToUInt32(mode2Sector, 0x808);
|
||||
uint calculatedEdc = ComputeEdc(0, mode2Sector, 0x808);
|
||||
|
||||
/* TODO: This is not working
|
||||
byte[] SectorForCheck = new byte[0x808];
|
||||
uint StoredEDC = BitConverter.ToUInt32(channel, 0x818);
|
||||
byte[] CalculatedEDCBytes;
|
||||
Array.Copy(channel, 0x10, SectorForCheck, 0, 0x808);
|
||||
CRC32Context.Data(SectorForCheck, 0x808, out CalculatedEDCBytes, CDCRC32Poly, CDCRC32Seed);
|
||||
uint CalculatedEDC = BitConverter.ToUInt32(CalculatedEDCBytes, 0);
|
||||
if(calculatedEdc == storedEdc) return !failedEccP && !failedEccQ;
|
||||
|
||||
if(CalculatedEDC != StoredEDC)
|
||||
{
|
||||
DicConsole.DebugWriteLine("CD checksums", "Mode 2 form 1 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}", channel[0x00C], channel[0x00D], channel[0x00E], CalculatedEDC, StoredEDC);
|
||||
DicConsole.DebugWriteLine("CD checksums",
|
||||
"Mode 1 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}",
|
||||
channel[0x00C], channel[0x00D], channel[0x00E], calculatedEdc, storedEdc);
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -318,6 +309,14 @@ namespace DiscImageChef.Checksums
|
||||
return null;
|
||||
}
|
||||
|
||||
static uint ComputeEdc(uint edc, byte[] src, int size)
|
||||
{
|
||||
int pos = 0;
|
||||
for(; size > 0; size--) edc = (edc >> 8) ^ edcTable[(edc ^ src[pos++]) & 0xFF];
|
||||
|
||||
return edc;
|
||||
}
|
||||
|
||||
static bool? CheckCdSectorSubChannel(byte[] subchannel)
|
||||
{
|
||||
bool? status = true;
|
||||
|
||||
Reference in New Issue
Block a user