mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
[Dumping] [CompactDisc] When trimming or retrying using scrambled mode, fix offset and check validity of data sectors because drive can report no error but return errored data. Fixes #390
This commit is contained in:
@@ -1119,12 +1119,6 @@ sealed partial class Dump
|
||||
}
|
||||
}
|
||||
|
||||
if(!_fixOffset || tracks.All(t => t.Type != TrackType.Audio))
|
||||
{
|
||||
offsetBytes = 0;
|
||||
sectorsForOffset = 0;
|
||||
}
|
||||
|
||||
mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, _maximumReadable, _private,
|
||||
_dimensions);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Aaru.Checksums;
|
||||
using Aaru.CommonTypes.AaruMetadata;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
@@ -304,12 +305,79 @@ partial class Dump
|
||||
// Try to workaround firmware
|
||||
if(decSense is { ASC: 0x11, ASCQ: 0x05 } || decSense?.ASC == 0x64)
|
||||
{
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, badSectorToReRead, blockSize, sectorsToReRead,
|
||||
MmcSectorTypes.Cdda, false, false, false, MmcHeaderCodes.None, true,
|
||||
false, MmcErrorField.None, supportedSubchannel, _dev.Timeout,
|
||||
out double cmdDuration2);
|
||||
byte scrambledSectorsToReRead = sectorsToReRead;
|
||||
uint scrambledBadSectorToReRead = badSectorToReRead;
|
||||
|
||||
// Contrary to normal read, this must always be offset fixed, because it's data not audio
|
||||
if(offsetBytes != 0)
|
||||
{
|
||||
if(offsetBytes < 0)
|
||||
{
|
||||
if(scrambledBadSectorToReRead == 0)
|
||||
scrambledBadSectorToReRead = uint.MaxValue - (uint)(sectorsForOffset - 1); // -1
|
||||
else
|
||||
scrambledBadSectorToReRead -= (uint)sectorsForOffset;
|
||||
}
|
||||
|
||||
scrambledSectorsToReRead += (byte)sectorsForOffset;
|
||||
}
|
||||
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, scrambledBadSectorToReRead, blockSize,
|
||||
scrambledSectorsToReRead, MmcSectorTypes.Cdda, false, false, false,
|
||||
MmcHeaderCodes.None, true, false, MmcErrorField.None,
|
||||
supportedSubchannel, _dev.Timeout, out double cmdDuration2);
|
||||
|
||||
cmdDuration += cmdDuration2;
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
uint scrambledBlocksToReRead = scrambledSectorsToReRead;
|
||||
FixOffsetData(offsetBytes, sectorSize, sectorsForOffset, supportedSubchannel,
|
||||
ref scrambledBlocksToReRead, subSize, ref cmdBuf, blockSize, false);
|
||||
|
||||
// Descramble
|
||||
cmdBuf = Sector.Scramble(cmdBuf);
|
||||
|
||||
// Check valid sector
|
||||
CdChecksums.CheckCdSector(cmdBuf, out bool? correctEccP, out bool? correctEccQ,
|
||||
out bool? correctEdc);
|
||||
|
||||
// Check mode, set sense if EDC/ECC validity is not correct
|
||||
switch(cmdBuf[15] & 0x03)
|
||||
{
|
||||
case 0:
|
||||
|
||||
for(var c = 16; c < 2352; c++)
|
||||
{
|
||||
if(cmdBuf[c] == 0x00)
|
||||
continue;
|
||||
|
||||
sense = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
sense = correctEdc != true || correctEccP != true || correctEccQ != true;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
if((cmdBuf[18] & 0x20) != 0x20)
|
||||
{
|
||||
if(correctEccP != true)
|
||||
sense = true;
|
||||
|
||||
if(correctEccQ != true)
|
||||
sense = true;
|
||||
}
|
||||
|
||||
if(correctEdc != true)
|
||||
sense = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Aaru.Checksums;
|
||||
using Aaru.CommonTypes.AaruMetadata;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
@@ -183,14 +184,81 @@ partial class Dump
|
||||
DecodedSense? decSense = Sense.Decode(senseBuf);
|
||||
|
||||
// Try to workaround firmware
|
||||
if(decSense?.ASC == 0x64)
|
||||
if(decSense is { ASC: 0x11, ASCQ: 0x05 } || decSense?.ASC == 0x64)
|
||||
{
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, badSectorToRead, blockSize, sectorsToTrim,
|
||||
MmcSectorTypes.Cdda, false, false, false, MmcHeaderCodes.None, true,
|
||||
false, MmcErrorField.None, supportedSubchannel, _dev.Timeout,
|
||||
out double cmdDuration2);
|
||||
byte scrambledSectorsToTrim = sectorsToTrim;
|
||||
uint scrambledBadSectorToRead = badSectorToRead;
|
||||
|
||||
// Contrary to normal read, this must always be offset fixed, because it's data not audio
|
||||
if(offsetBytes != 0)
|
||||
{
|
||||
if(offsetBytes < 0)
|
||||
{
|
||||
if(scrambledBadSectorToRead == 0)
|
||||
scrambledBadSectorToRead = uint.MaxValue - (uint)(sectorsForOffset - 1); // -1
|
||||
else
|
||||
scrambledBadSectorToRead -= (uint)sectorsForOffset;
|
||||
}
|
||||
|
||||
scrambledSectorsToTrim += (byte)sectorsForOffset;
|
||||
}
|
||||
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, scrambledBadSectorToRead, blockSize,
|
||||
scrambledSectorsToTrim, MmcSectorTypes.Cdda, false, false, false,
|
||||
MmcHeaderCodes.None, true, false, MmcErrorField.None,
|
||||
supportedSubchannel, _dev.Timeout, out double cmdDuration2);
|
||||
|
||||
cmdDuration += cmdDuration2;
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
uint scrambledBlocksToRead = scrambledSectorsToTrim;
|
||||
FixOffsetData(offsetBytes, sectorSize, sectorsForOffset, supportedSubchannel,
|
||||
ref scrambledBlocksToRead, subSize, ref cmdBuf, blockSize, false);
|
||||
|
||||
// Descramble
|
||||
cmdBuf = Sector.Scramble(cmdBuf);
|
||||
|
||||
// Check valid sector
|
||||
CdChecksums.CheckCdSector(cmdBuf, out bool? correctEccP, out bool? correctEccQ,
|
||||
out bool? correctEdc);
|
||||
|
||||
// Check mode, set sense if EDC/ECC validity is not correct
|
||||
switch(cmdBuf[15] & 0x03)
|
||||
{
|
||||
case 0:
|
||||
|
||||
for(var c = 16; c < 2352; c++)
|
||||
{
|
||||
if(cmdBuf[c] == 0x00)
|
||||
continue;
|
||||
|
||||
sense = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
sense = correctEdc != true || correctEccP != true || correctEccQ != true;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
if((cmdBuf[18] & 0x20) != 0x20)
|
||||
{
|
||||
if(correctEccP != true)
|
||||
sense = true;
|
||||
|
||||
if(correctEccQ != true)
|
||||
sense = true;
|
||||
}
|
||||
|
||||
if(correctEdc != true)
|
||||
sense = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user