mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
When dumping media if device returns "corrected error", consider it as a good read.
This commit is contained in:
13
.idea/.idea.Aaru/.idea/contentModel.xml
generated
13
.idea/.idea.Aaru/.idea/contentModel.xml
generated
@@ -3,6 +3,9 @@
|
||||
<component name="ContentModelStore">
|
||||
<e p="$USER_HOME$/.cache/JetBrains/Rider2020.2/extResources" t="IncludeRecursive" />
|
||||
<e p="$USER_HOME$/.cache/JetBrains/Rider2020.2/resharper-host/local/Transient/Rider/v202/SolutionCaches/_Aaru.232757112.00" t="ExcludeRecursive" />
|
||||
<e p="$APPLICATION_CONFIG_DIR$/consoles/db" t="IncludeRecursive" />
|
||||
<e p="$APPLICATION_CONFIG_DIR$/extensions" t="IncludeRecursive" />
|
||||
<e p="$APPLICATION_CONFIG_DIR$/scratches" t="IncludeRecursive" />
|
||||
<e p="$USER_HOME$/.config/git/ignore" t="IncludeRecursive" />
|
||||
<e p="$APPLICATION_PLUGINS_DIR$/puppet/lib/stubs" t="IncludeRecursive" />
|
||||
<e p="$USER_HOME$/.nuget/packages/microsoft.net.test.sdk/16.4.0/build/netcoreapp2.1" t="Include">
|
||||
@@ -13,6 +16,16 @@
|
||||
<e p="$USER_HOME$/.nuget/packages/nunit3testadapter/3.15.1/build/netcoreapp2.0/nunit.engine.api.dll" t="Include" />
|
||||
<e p="$USER_HOME$/.nuget/packages/nunit3testadapter/3.15.1/build/netcoreapp2.0/nunit.engine.dll" t="Include" />
|
||||
<e p="$PROJECT_DIR$" t="IncludeFlat">
|
||||
<e p=".git/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/Aaru.Checksums/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/Aaru.CommonTypes/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/Aaru.Console/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/Aaru.Decoders/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/Aaru.Dto/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/Aaru.Helpers/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/CICMMetadata/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/cuetools.net/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".git/modules/cuetoolsnet/info/exclude" t="IncludeRecursive" />
|
||||
<e p=".github/CODE_OF_CONDUCT.md" t="Include" />
|
||||
<e p=".github/ISSUE_TEMPLATE.md" t="Include" />
|
||||
<e p=".github/PULL_REQUEST_TEMPLATE.md" t="Include" />
|
||||
|
||||
@@ -56,6 +56,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
/// <summary>Dumps an ATA device</summary>
|
||||
void Ata()
|
||||
{
|
||||
bool recoveredError;
|
||||
|
||||
if(_dumpRaw)
|
||||
{
|
||||
if(_force)
|
||||
@@ -288,7 +290,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)",
|
||||
(long)i, (long)blocks);
|
||||
|
||||
bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration);
|
||||
bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration, out _);
|
||||
|
||||
if(!error)
|
||||
{
|
||||
@@ -380,11 +382,12 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
||||
|
||||
bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration);
|
||||
bool error =
|
||||
ataReader.ReadBlock(out cmdBuf, badSector, out duration, out recoveredError);
|
||||
|
||||
totalDuration += duration;
|
||||
|
||||
if(error)
|
||||
if(error && !recoveredError)
|
||||
continue;
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
@@ -426,11 +429,12 @@ namespace Aaru.Core.Devices.Dumping
|
||||
pass, forward ? "forward" : "reverse",
|
||||
_persistent ? "recovering partial data, " : ""));
|
||||
|
||||
bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration);
|
||||
bool error =
|
||||
ataReader.ReadBlock(out cmdBuf, badSector, out duration, out recoveredError);
|
||||
|
||||
totalDuration += duration;
|
||||
|
||||
if(!error)
|
||||
if(!error || recoveredError)
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
@@ -502,11 +506,12 @@ namespace Aaru.Core.Devices.Dumping
|
||||
PulseProgress?.
|
||||
Invoke($"Reading cylinder {cy} head {hd} sector {sc} ({currentSpeed:F3} MiB/sec.)");
|
||||
|
||||
bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);
|
||||
bool error =
|
||||
ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration, out recoveredError);
|
||||
|
||||
totalDuration += duration;
|
||||
|
||||
if(!error)
|
||||
if(!error || recoveredError)
|
||||
{
|
||||
mhddLog.Write(currentBlock, duration);
|
||||
ibgLog.Write(currentBlock, currentSpeed * 1024);
|
||||
|
||||
@@ -81,6 +81,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
byte[] readBuffer;
|
||||
Modes.DecodedMode? decMode = null;
|
||||
bool ret;
|
||||
bool recoveredError;
|
||||
|
||||
if(opticalDisc)
|
||||
switch(dskType)
|
||||
@@ -621,7 +622,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
|
||||
(long)blocks);
|
||||
|
||||
sense = scsiReader.ReadBlocks(out readBuffer, i, blocksToRead, out double cmdDuration);
|
||||
sense = scsiReader.ReadBlocks(out readBuffer, i, blocksToRead, out double cmdDuration, out _);
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(!sense &&
|
||||
@@ -736,9 +737,10 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
||||
|
||||
sense = scsiReader.ReadBlock(out readBuffer, badSector, out double _);
|
||||
sense = scsiReader.ReadBlock(out readBuffer, badSector, out double _, out recoveredError);
|
||||
|
||||
if(sense || _dev.Error)
|
||||
if((sense || _dev.Error) &&
|
||||
!recoveredError)
|
||||
continue;
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
@@ -785,9 +787,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(dcMode10?.Pages != null)
|
||||
foreach(Modes.ModePage modePage in dcMode10.Value.Pages.Where(modePage =>
|
||||
modePage.Page ==
|
||||
0x01 && modePage.
|
||||
Subpage == 0x00))
|
||||
modePage.Page == 0x01 && modePage.Subpage == 0x00))
|
||||
currentModePage = modePage;
|
||||
}
|
||||
}
|
||||
@@ -796,8 +796,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
Modes.DecodedMode? dcMode6 = Modes.DecodeMode6(readBuffer, _dev.ScsiType);
|
||||
|
||||
if(dcMode6?.Pages != null)
|
||||
foreach(var modePage in dcMode6.Value.Pages.Where(modePage => modePage.Page == 0x01 &&
|
||||
modePage.Subpage == 0x00))
|
||||
foreach(Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage =>
|
||||
modePage.Page == 0x01 && modePage.Subpage == 0x00))
|
||||
currentModePage = modePage;
|
||||
}
|
||||
|
||||
@@ -946,11 +946,10 @@ namespace Aaru.Core.Devices.Dumping
|
||||
forward ? "forward" : "reverse",
|
||||
runningPersistent ? "recovering partial data, " : ""));
|
||||
|
||||
sense = scsiReader.ReadBlock(out readBuffer, badSector, out double cmdDuration);
|
||||
sense = scsiReader.ReadBlock(out readBuffer, badSector, out double cmdDuration, out recoveredError);
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
if((!sense && !_dev.Error) || recoveredError)
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Aaru.Core.Devices
|
||||
internal uint PhysicalBlockSize { get; private set; }
|
||||
internal uint LongBlockSize { get; private set; }
|
||||
internal bool CanReadRaw { get; private set; }
|
||||
internal bool CanSeek => _ataSeek || _seek6 || _seek10;
|
||||
internal bool CanSeek => _ataSeek || _seek6 || _seek10;
|
||||
internal bool CanSeekLba => _ataSeekLba || _seek6 || _seek10;
|
||||
|
||||
internal ulong GetDeviceBlocks()
|
||||
@@ -132,35 +132,40 @@ namespace Aaru.Core.Devices
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ReadBlock(out byte[] buffer, ulong block, out double duration) =>
|
||||
ReadBlocks(out buffer, block, 1, out duration);
|
||||
internal bool ReadBlock(out byte[] buffer, ulong block, out double duration, out bool recoveredError) =>
|
||||
ReadBlocks(out buffer, block, 1, out duration, out recoveredError);
|
||||
|
||||
internal bool ReadBlocks(out byte[] buffer, ulong block, out double duration) =>
|
||||
ReadBlocks(out buffer, block, BlocksToRead, out duration);
|
||||
internal bool ReadBlocks(out byte[] buffer, ulong block, out double duration, out bool recoveredError) =>
|
||||
ReadBlocks(out buffer, block, BlocksToRead, out duration, out recoveredError);
|
||||
|
||||
internal bool ReadBlocks(out byte[] buffer, ulong block, uint count, out double duration)
|
||||
internal bool ReadBlocks(out byte[] buffer, ulong block, uint count, out double duration,
|
||||
out bool recoveredError)
|
||||
{
|
||||
switch(_dev.Type)
|
||||
{
|
||||
case DeviceType.ATA: return AtaReadBlocks(out buffer, block, count, out duration);
|
||||
case DeviceType.ATA: return AtaReadBlocks(out buffer, block, count, out duration, out recoveredError);
|
||||
case DeviceType.ATAPI:
|
||||
case DeviceType.SCSI: return ScsiReadBlocks(out buffer, block, count, out duration);
|
||||
case DeviceType.SCSI: return ScsiReadBlocks(out buffer, block, count, out duration, out recoveredError);
|
||||
default:
|
||||
buffer = null;
|
||||
duration = 0d;
|
||||
buffer = null;
|
||||
duration = 0d;
|
||||
recoveredError = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ReadChs(out byte[] buffer, ushort cylinder, byte head, byte sector, out double duration)
|
||||
internal bool ReadChs(out byte[] buffer, ushort cylinder, byte head, byte sector, out double duration,
|
||||
out bool recoveredError)
|
||||
{
|
||||
switch(_dev.Type)
|
||||
{
|
||||
case DeviceType.ATA: return AtaReadChs(out buffer, cylinder, head, sector, out duration);
|
||||
case DeviceType.ATA:
|
||||
return AtaReadChs(out buffer, cylinder, head, sector, out duration, out recoveredError);
|
||||
default:
|
||||
buffer = null;
|
||||
duration = 0d;
|
||||
buffer = null;
|
||||
duration = 0d;
|
||||
recoveredError = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -343,15 +343,16 @@ namespace Aaru.Core.Devices
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtaReadBlocks(out byte[] buffer, ulong block, uint count, out double duration)
|
||||
bool AtaReadBlocks(out byte[] buffer, ulong block, uint count, out double duration, out bool recoveredError)
|
||||
{
|
||||
bool error = true;
|
||||
bool sense;
|
||||
AtaErrorRegistersLba28 errorLba;
|
||||
AtaErrorRegistersLba48 errorLba48;
|
||||
byte status = 0, errorByte = 0;
|
||||
buffer = null;
|
||||
duration = 0;
|
||||
buffer = null;
|
||||
duration = 0;
|
||||
recoveredError = false;
|
||||
|
||||
if(_ataReadDmaLba48)
|
||||
{
|
||||
@@ -416,20 +417,27 @@ namespace Aaru.Core.Devices
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
|
||||
}
|
||||
|
||||
if(error)
|
||||
AaruConsole.DebugWriteLine("ATA Reader", "ATA ERROR: {0} STATUS: {1}", errorByte, status);
|
||||
if(!error)
|
||||
return false;
|
||||
|
||||
return error;
|
||||
if((status & 0x04) == 0x04)
|
||||
recoveredError = true;
|
||||
|
||||
AaruConsole.DebugWriteLine("ATA Reader", "ATA ERROR: {0} STATUS: {1}", errorByte, status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtaReadChs(out byte[] buffer, ushort cylinder, byte head, byte sector, out double duration)
|
||||
bool AtaReadChs(out byte[] buffer, ushort cylinder, byte head, byte sector, out double duration,
|
||||
out bool recoveredError)
|
||||
{
|
||||
bool error = true;
|
||||
bool sense;
|
||||
AtaErrorRegistersChs errorChs;
|
||||
byte status = 0, errorByte = 0;
|
||||
buffer = null;
|
||||
duration = 0;
|
||||
buffer = null;
|
||||
duration = 0;
|
||||
recoveredError = false;
|
||||
|
||||
if(_ataReadDmaRetry)
|
||||
{
|
||||
@@ -475,10 +483,15 @@ namespace Aaru.Core.Devices
|
||||
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
|
||||
}
|
||||
|
||||
if(error)
|
||||
AaruConsole.DebugWriteLine("ATA Reader", "ATA ERROR: {0} STATUS: {1}", errorByte, status);
|
||||
if(!error)
|
||||
return false;
|
||||
|
||||
return error;
|
||||
if((status & 0x04) == 0x04)
|
||||
recoveredError = true;
|
||||
|
||||
AaruConsole.DebugWriteLine("ATA Reader", "ATA ERROR: {0} STATUS: {1}", errorByte, status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtaSeek(ulong block, out double duration)
|
||||
|
||||
@@ -571,12 +571,13 @@ namespace Aaru.Core.Devices
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScsiReadBlocks(out byte[] buffer, ulong block, uint count, out double duration)
|
||||
bool ScsiReadBlocks(out byte[] buffer, ulong block, uint count, out double duration, out bool recoveredError)
|
||||
{
|
||||
bool sense;
|
||||
byte[] senseBuf;
|
||||
buffer = null;
|
||||
duration = 0;
|
||||
buffer = null;
|
||||
duration = 0;
|
||||
recoveredError = false;
|
||||
|
||||
if(CanReadRaw)
|
||||
if(_readLong16)
|
||||
@@ -624,6 +625,9 @@ namespace Aaru.Core.Devices
|
||||
!_dev.Error)
|
||||
return false;
|
||||
|
||||
recoveredError = Sense.DecodeFixed(senseBuf)?.SenseKey == SenseKeys.RecoveredError ||
|
||||
Sense.DecodeDescriptor(senseBuf)?.SenseKey == SenseKeys.RecoveredError;
|
||||
|
||||
AaruConsole.DebugWriteLine("SCSI Reader", "READ error:\n{0}", Sense.PrettifySense(senseBuf));
|
||||
|
||||
return sense;
|
||||
|
||||
@@ -152,7 +152,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
|
||||
(long)i, (long)results.Blocks);
|
||||
|
||||
bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration);
|
||||
bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration, out _);
|
||||
|
||||
if(!error)
|
||||
{
|
||||
@@ -268,7 +268,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
PulseProgress?.
|
||||
Invoke($"Reading cylinder {cy} head {hd} sector {sc} ({currentSpeed:F3} MiB/sec.)");
|
||||
|
||||
bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);
|
||||
bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration, out _);
|
||||
|
||||
if(!error)
|
||||
{
|
||||
|
||||
@@ -481,7 +481,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
|
||||
(long)i, (long)results.Blocks);
|
||||
|
||||
sense = scsiReader.ReadBlocks(out _, i, blocksToRead, out double cmdDuration);
|
||||
sense = scsiReader.ReadBlocks(out _, i, blocksToRead, out double cmdDuration, out _);
|
||||
results.ProcessingTime += cmdDuration;
|
||||
|
||||
if(!sense &&
|
||||
@@ -563,7 +563,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
if(scsiReader.CanSeek)
|
||||
scsiReader.Seek(seekPos, out seekCur);
|
||||
else
|
||||
scsiReader.ReadBlock(out _, seekPos, out seekCur);
|
||||
scsiReader.ReadBlock(out _, seekPos, out seekCur, out _);
|
||||
|
||||
if(seekCur > results.SeekMax &&
|
||||
seekCur > 0)
|
||||
|
||||
Reference in New Issue
Block a user