mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Scan blank blocks in magneto-optical disks before dumping, and do not treat them as errors. Fixes #316
This commit is contained in:
4
.idea/.idea.Aaru/.idea/contentModel.xml
generated
4
.idea/.idea.Aaru/.idea/contentModel.xml
generated
@@ -3,7 +3,8 @@
|
||||
<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="$USER_HOME$/.config/git/ignore" t="IncludeRecursive" />
|
||||
<e p="$APPLICATION_CONFIG_DIR$/consoles/db" t="IncludeRecursive" />
|
||||
<e p="$APPLICATION_CONFIG_DIR$/extensions" 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">
|
||||
<e p="Microsoft.NET.Test.Sdk.Program.cs" t="Include" />
|
||||
@@ -277,6 +278,7 @@
|
||||
<e p="Data.cs" t="Include" />
|
||||
<e p="Dump.cs" t="Include" />
|
||||
<e p="Error.cs" t="Include" />
|
||||
<e p="Optical.cs" t="Include" />
|
||||
<e p="Trim.cs" t="Include" />
|
||||
</e>
|
||||
<e p="SecureDigital.cs" t="Include" />
|
||||
|
||||
Submodule Aaru.CommonTypes updated: 3225283e04...f4eb9f5b4a
@@ -68,6 +68,7 @@
|
||||
<Compile Include="Devices\Dumping\Sbc\Data.cs" />
|
||||
<Compile Include="Devices\Dumping\Sbc\Error.cs" />
|
||||
<Compile Include="Devices\Dumping\Sbc\Dump.cs" />
|
||||
<Compile Include="Devices\Dumping\Sbc\Optical.cs" />
|
||||
<Compile Include="Devices\Dumping\Sbc\Trim.cs" />
|
||||
<Compile Include="Devices\Info\DeviceInfo.cs" />
|
||||
<Compile Include="Devices\Info\Plextor.cs" />
|
||||
|
||||
@@ -290,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, out _);
|
||||
bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration, out _, out _);
|
||||
|
||||
if(!error)
|
||||
{
|
||||
@@ -383,7 +383,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
||||
|
||||
bool error =
|
||||
ataReader.ReadBlock(out cmdBuf, badSector, out duration, out recoveredError);
|
||||
ataReader.ReadBlock(out cmdBuf, badSector, out duration, out recoveredError, out _);
|
||||
|
||||
totalDuration += duration;
|
||||
|
||||
@@ -430,7 +430,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_persistent ? "recovering partial data, " : ""));
|
||||
|
||||
bool error =
|
||||
ataReader.ReadBlock(out cmdBuf, badSector, out duration, out recoveredError);
|
||||
ataReader.ReadBlock(out cmdBuf, badSector, out duration, out recoveredError, out _);
|
||||
|
||||
totalDuration += duration;
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
byte[] buffer;
|
||||
uint blocksToRead = maxBlocksToRead;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
for(ulong i = _resume.NextBlock; i < blocks; i += blocksToRead)
|
||||
{
|
||||
if(_aborted)
|
||||
@@ -73,7 +75,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 buffer, i, blocksToRead, out double cmdDuration, out _);
|
||||
sense = scsiReader.ReadBlocks(out buffer, i, blocksToRead, out double cmdDuration, out _, out _);
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(!sense &&
|
||||
@@ -138,6 +140,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
sectorSpeedStart = 0;
|
||||
timeSpeedStart = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
EndProgress?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
byte[] readBuffer;
|
||||
Modes.DecodedMode? decMode = null;
|
||||
bool ret;
|
||||
ExtentsULong blankExtents = null;
|
||||
|
||||
if(opticalDisc)
|
||||
switch(dskType)
|
||||
@@ -591,15 +592,21 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dev.SetCdSpeed(out _, RotationalControl.ClvAndImpureCav, (ushort)_speed, 0, _dev.Timeout, out _);
|
||||
}
|
||||
|
||||
bool newTrim = false;
|
||||
InitProgress?.Invoke();
|
||||
if(_resume?.BlankExtents != null)
|
||||
blankExtents = ExtentsConverter.FromMetadata(_resume.BlankExtents);
|
||||
|
||||
ReadSbcData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed,
|
||||
ref maxSpeed, ref totalDuration, scsiReader, mhddLog, ibgLog, ref imageWriteDuration,
|
||||
ref newTrim);
|
||||
bool newTrim = false;
|
||||
|
||||
if(_dev.ScsiType == PeripheralDeviceTypes.OpticalDevice)
|
||||
ReadOpticalData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed,
|
||||
ref maxSpeed, ref totalDuration, scsiReader, mhddLog, ibgLog, ref imageWriteDuration,
|
||||
ref newTrim, ref blankExtents);
|
||||
else
|
||||
ReadSbcData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed,
|
||||
ref maxSpeed, ref totalDuration, scsiReader, mhddLog, ibgLog, ref imageWriteDuration,
|
||||
ref newTrim);
|
||||
|
||||
end = DateTime.UtcNow;
|
||||
EndProgress?.Invoke();
|
||||
mhddLog.Close();
|
||||
|
||||
ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
|
||||
@@ -633,7 +640,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
TrimSbcData(scsiReader, extents, currentTry);
|
||||
TrimSbcData(scsiReader, extents, currentTry, blankExtents);
|
||||
|
||||
EndProgress?.Invoke();
|
||||
end = DateTime.UtcNow;
|
||||
@@ -646,7 +653,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
if(_resume.BadBlocks.Count > 0 &&
|
||||
!_aborted &&
|
||||
_retryPasses > 0)
|
||||
RetrySbcData(scsiReader, currentTry, extents, ref totalDuration);
|
||||
RetrySbcData(scsiReader, currentTry, extents, ref totalDuration, blankExtents);
|
||||
#endregion Error handling
|
||||
|
||||
if(!_aborted)
|
||||
|
||||
@@ -41,18 +41,19 @@ namespace Aaru.Core.Devices.Dumping
|
||||
partial class Dump
|
||||
{
|
||||
void RetrySbcData(Reader scsiReader, DumpHardwareType currentTry, ExtentsULong extents,
|
||||
ref double totalDuration)
|
||||
ref double totalDuration, ExtentsULong blankExtents)
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
bool sense;
|
||||
byte[] buffer;
|
||||
bool recoveredError;
|
||||
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
bool sense;
|
||||
byte[] buffer;
|
||||
bool recoveredError;
|
||||
Modes.ModePage? currentModePage = null;
|
||||
byte[] md6;
|
||||
byte[] md10;
|
||||
bool blankCheck;
|
||||
bool newBlank = false;
|
||||
|
||||
if(_persistent)
|
||||
{
|
||||
@@ -231,9 +232,23 @@ namespace Aaru.Core.Devices.Dumping
|
||||
forward ? "forward" : "reverse",
|
||||
runningPersistent ? "recovering partial data, " : ""));
|
||||
|
||||
sense = scsiReader.ReadBlock(out buffer, badSector, out double cmdDuration, out recoveredError);
|
||||
sense = scsiReader.ReadBlock(out buffer, badSector, out double cmdDuration, out recoveredError,
|
||||
out blankCheck);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(blankCheck)
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
blankExtents.Add(badSector, badSector);
|
||||
newBlank = true;
|
||||
|
||||
UpdateStatus?.Invoke($"Found blank block {badSector} in pass {pass}.");
|
||||
_dumpLog.WriteLine("Found blank block {0} in pass {1}.", badSector, pass);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if((!sense && !_dev.Error) || recoveredError)
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
@@ -284,6 +299,9 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dev.ModeSelect10(md10, out _, true, false, _dev.Timeout, out _);
|
||||
}
|
||||
|
||||
if(newBlank)
|
||||
_resume.BlankExtents = ExtentsConverter.ToMetadata(blankExtents);
|
||||
|
||||
EndProgress?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
227
Aaru.Core/Devices/Dumping/Sbc/Optical.cs
Normal file
227
Aaru.Core/Devices/Dumping/Sbc/Optical.cs
Normal file
@@ -0,0 +1,227 @@
|
||||
using System;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.Console;
|
||||
using Aaru.Core.Logging;
|
||||
using Schemas;
|
||||
|
||||
// ReSharper disable JoinDeclarationAndInitializer
|
||||
// ReSharper disable InlineOutVariableDeclaration
|
||||
// ReSharper disable TooWideLocalVariableScope
|
||||
|
||||
namespace Aaru.Core.Devices.Dumping
|
||||
{
|
||||
partial class Dump
|
||||
{
|
||||
void ReadOpticalData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, DumpHardwareType currentTry,
|
||||
ExtentsULong extents, ref double currentSpeed, ref double minSpeed, ref double maxSpeed,
|
||||
ref double totalDuration, Reader scsiReader, MhddLog mhddLog, IbgLog ibgLog,
|
||||
ref double imageWriteDuration, ref bool newTrim, ref ExtentsULong blankExtents)
|
||||
{
|
||||
const uint maxBlocks = 256;
|
||||
var writtenExtents = new ExtentsULong();
|
||||
bool written;
|
||||
uint c = maxBlocks;
|
||||
bool conditionMet;
|
||||
bool changingCounter;
|
||||
bool changingWritten;
|
||||
uint blocksToRead = maxBlocksToRead;
|
||||
bool sense;
|
||||
byte[] buffer;
|
||||
ulong sectorSpeedStart = 0;
|
||||
DateTime timeSpeedStart = DateTime.UtcNow;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
if(blankExtents is null)
|
||||
{
|
||||
blankExtents = new ExtentsULong();
|
||||
|
||||
written = _dev.MediumScan(out buffer, true, false, false, false, false, 0, 1, 1, out _, out _,
|
||||
uint.MaxValue, out _);
|
||||
|
||||
// TODO: Find a place where MEDIUM SCAN works properly
|
||||
if(buffer?.Length > 0)
|
||||
AaruConsole.
|
||||
WriteLine("Please open a bug report in github with the manufacturer and model of this device, as well as your operating system name and version and this message: This environment correctly supports MEDIUM SCAN command.");
|
||||
|
||||
changingCounter = false;
|
||||
changingWritten = false;
|
||||
|
||||
for(uint b = 0; b < blocks; b += c)
|
||||
{
|
||||
if(_aborted)
|
||||
{
|
||||
_resume.BlankExtents = null;
|
||||
UpdateStatus?.Invoke("Aborted!");
|
||||
_dumpLog.WriteLine("Aborted!");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(changingWritten)
|
||||
{
|
||||
changingWritten = false;
|
||||
written = !written;
|
||||
c = maxBlocks;
|
||||
}
|
||||
|
||||
if(changingCounter)
|
||||
{
|
||||
b -= c;
|
||||
changingCounter = false;
|
||||
}
|
||||
|
||||
if(b + c >= blocks)
|
||||
c = (uint)(blocks - b);
|
||||
|
||||
UpdateProgress?.
|
||||
Invoke($"Scanning for {c} {(written ? "written" : "blank")} blocks starting in block {b}", b,
|
||||
(long)blocks);
|
||||
|
||||
conditionMet = _dev.MediumScan(out _, written, false, false, false, false, b, c, c, out _, out _,
|
||||
uint.MaxValue, out _);
|
||||
|
||||
if(conditionMet)
|
||||
{
|
||||
if(written)
|
||||
writtenExtents.Add(b, c, true);
|
||||
else
|
||||
blankExtents.Add(b, c, true);
|
||||
|
||||
if(c < maxBlocks)
|
||||
changingWritten = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(c > 64)
|
||||
c /= 2;
|
||||
else
|
||||
c--;
|
||||
|
||||
changingCounter = true;
|
||||
|
||||
if(c != 0)
|
||||
continue;
|
||||
|
||||
written = !written;
|
||||
c = maxBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
if(_resume != null)
|
||||
_resume.BlankExtents = ExtentsConverter.ToMetadata(blankExtents);
|
||||
|
||||
EndProgress?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
writtenExtents.Add(0, blocks - 1);
|
||||
|
||||
foreach(Tuple<ulong, ulong> blank in blankExtents.ToArray())
|
||||
for(ulong b = blank.Item1; b <= blank.Item2; b++)
|
||||
writtenExtents.Remove(b);
|
||||
}
|
||||
|
||||
if(writtenExtents.Count == 0)
|
||||
{
|
||||
UpdateStatus?.Invoke("Cannot dump empty media!");
|
||||
_dumpLog.WriteLine("Cannot dump empty media!");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
Tuple<ulong, ulong>[] extentsToDump = writtenExtents.ToArray();
|
||||
|
||||
foreach(Tuple<ulong, ulong> extent in extentsToDump)
|
||||
{
|
||||
if(extent.Item2 < _resume.NextBlock)
|
||||
continue; // Skip this extent
|
||||
|
||||
ulong nextBlock = extent.Item1;
|
||||
|
||||
if(extent.Item1 < _resume.NextBlock)
|
||||
nextBlock = (uint)_resume.NextBlock;
|
||||
|
||||
for(ulong i = nextBlock; i <= extent.Item2; i += blocksToRead)
|
||||
{
|
||||
if(_aborted)
|
||||
{
|
||||
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
|
||||
UpdateStatus?.Invoke("Aborted!");
|
||||
_dumpLog.WriteLine("Aborted!");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if((extent.Item2 + 1) - i < blocksToRead)
|
||||
blocksToRead = (uint)((extent.Item2 + 1) - i);
|
||||
|
||||
if(currentSpeed > maxSpeed &&
|
||||
currentSpeed > 0)
|
||||
maxSpeed = currentSpeed;
|
||||
|
||||
if(currentSpeed < minSpeed &&
|
||||
currentSpeed > 0)
|
||||
minSpeed = currentSpeed;
|
||||
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
|
||||
(long)blocks);
|
||||
|
||||
sense = scsiReader.ReadBlocks(out buffer, i, blocksToRead, out double cmdDuration, out _, out _);
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
{
|
||||
mhddLog.Write(i, cmdDuration);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
DateTime writeStart = DateTime.Now;
|
||||
_outputPlugin.WriteSectors(buffer, i, blocksToRead);
|
||||
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Reset device after X errors
|
||||
if(_stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
|
||||
if(i + _skip > extent.Item2 + 1)
|
||||
_skip = (uint)((extent.Item2 + 1) - i);
|
||||
|
||||
// Write empty data
|
||||
DateTime writeStart = DateTime.Now;
|
||||
_outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
|
||||
|
||||
for(ulong b = i; b < i + _skip; b++)
|
||||
_resume.BadBlocks.Add(b);
|
||||
|
||||
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
|
||||
|
||||
ibgLog.Write(i, 0);
|
||||
_dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
|
||||
i += _skip - blocksToRead;
|
||||
newTrim = true;
|
||||
}
|
||||
|
||||
sectorSpeedStart += blocksToRead;
|
||||
_resume.NextBlock = i + blocksToRead;
|
||||
|
||||
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
|
||||
|
||||
if(elapsed < 1)
|
||||
continue;
|
||||
|
||||
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
|
||||
sectorSpeedStart = 0;
|
||||
timeSpeedStart = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
EndProgress?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,12 +35,15 @@ namespace Aaru.Core.Devices.Dumping
|
||||
{
|
||||
partial class Dump
|
||||
{
|
||||
void TrimSbcData(Reader scsiReader, ExtentsULong extents, DumpHardwareType currentTry)
|
||||
void TrimSbcData(Reader scsiReader, ExtentsULong extents, DumpHardwareType currentTry,
|
||||
ExtentsULong blankExtents)
|
||||
{
|
||||
ulong[] tmpArray = _resume.BadBlocks.ToArray();
|
||||
bool sense;
|
||||
bool recoveredError;
|
||||
bool blankCheck;
|
||||
byte[] buffer;
|
||||
bool newBlank = false;
|
||||
|
||||
foreach(ulong badSector in tmpArray)
|
||||
{
|
||||
@@ -55,7 +58,19 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
||||
|
||||
sense = scsiReader.ReadBlock(out buffer, badSector, out double _, out recoveredError);
|
||||
sense = scsiReader.ReadBlock(out buffer, badSector, out double _, out recoveredError, out blankCheck);
|
||||
|
||||
if(blankCheck)
|
||||
{
|
||||
blankExtents.Add(badSector, badSector);
|
||||
newBlank = true;
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
|
||||
UpdateStatus?.Invoke($"Found blank block {badSector}.");
|
||||
_dumpLog.WriteLine("Found blank block {0} in pass {1}.", badSector);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if((sense || _dev.Error) &&
|
||||
!recoveredError)
|
||||
@@ -65,6 +80,9 @@ namespace Aaru.Core.Devices.Dumping
|
||||
extents.Add(badSector);
|
||||
_outputPlugin.WriteSector(buffer, badSector);
|
||||
}
|
||||
|
||||
if(newBlank)
|
||||
_resume.BlankExtents = ExtentsConverter.ToMetadata(blankExtents);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,24 +132,31 @@ namespace Aaru.Core.Devices
|
||||
}
|
||||
}
|
||||
|
||||
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 ReadBlock(out byte[] buffer, ulong block, out double duration, out bool recoveredError,
|
||||
out bool blankCheck) =>
|
||||
ReadBlocks(out buffer, block, 1, out duration, out recoveredError, out blankCheck);
|
||||
|
||||
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, out double duration, out bool recoveredError,
|
||||
out bool blankCheck) => ReadBlocks(out buffer, block, BlocksToRead, out duration,
|
||||
out recoveredError, out blankCheck);
|
||||
|
||||
internal bool ReadBlocks(out byte[] buffer, ulong block, uint count, out double duration,
|
||||
out bool recoveredError)
|
||||
out bool recoveredError, out bool blankCheck)
|
||||
{
|
||||
switch(_dev.Type)
|
||||
{
|
||||
case DeviceType.ATA: return AtaReadBlocks(out buffer, block, count, out duration, out recoveredError);
|
||||
case DeviceType.ATA:
|
||||
blankCheck = false;
|
||||
|
||||
return AtaReadBlocks(out buffer, block, count, out duration, out recoveredError);
|
||||
case DeviceType.ATAPI:
|
||||
case DeviceType.SCSI: return ScsiReadBlocks(out buffer, block, count, out duration, out recoveredError);
|
||||
case DeviceType.SCSI:
|
||||
return ScsiReadBlocks(out buffer, block, count, out duration, out recoveredError, out blankCheck);
|
||||
default:
|
||||
buffer = null;
|
||||
duration = 0d;
|
||||
recoveredError = false;
|
||||
blankCheck = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -571,13 +571,15 @@ namespace Aaru.Core.Devices
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScsiReadBlocks(out byte[] buffer, ulong block, uint count, out double duration, out bool recoveredError)
|
||||
bool ScsiReadBlocks(out byte[] buffer, ulong block, uint count, out double duration, out bool recoveredError,
|
||||
out bool blankCheck)
|
||||
{
|
||||
bool sense;
|
||||
byte[] senseBuf;
|
||||
buffer = null;
|
||||
duration = 0;
|
||||
recoveredError = false;
|
||||
blankCheck = false;
|
||||
|
||||
if(CanReadRaw)
|
||||
if(_readLong16)
|
||||
@@ -628,6 +630,9 @@ namespace Aaru.Core.Devices
|
||||
recoveredError = Sense.DecodeFixed(senseBuf)?.SenseKey == SenseKeys.RecoveredError ||
|
||||
Sense.DecodeDescriptor(senseBuf)?.SenseKey == SenseKeys.RecoveredError;
|
||||
|
||||
blankCheck = Sense.DecodeFixed(senseBuf)?.SenseKey == SenseKeys.BlankCheck ||
|
||||
Sense.DecodeDescriptor(senseBuf)?.SenseKey == SenseKeys.BlankCheck;
|
||||
|
||||
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, out _);
|
||||
bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration, out _, out _);
|
||||
|
||||
if(!error)
|
||||
{
|
||||
|
||||
@@ -52,10 +52,11 @@ namespace Aaru.Core.Devices.Scanning
|
||||
MhddLog mhddLog;
|
||||
IbgLog ibgLog;
|
||||
byte[] senseBuf;
|
||||
bool sense = false;
|
||||
bool sense = false;
|
||||
uint blockSize = 0;
|
||||
ushort currentProfile = 0x0001;
|
||||
|
||||
results.Blocks = 0;
|
||||
uint blockSize = 0;
|
||||
ushort currentProfile = 0x0001;
|
||||
|
||||
if(_dev.IsRemovable)
|
||||
{
|
||||
@@ -481,7 +482,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, out _);
|
||||
sense = scsiReader.ReadBlocks(out _, i, blocksToRead, out double cmdDuration, out _, out _);
|
||||
results.ProcessingTime += cmdDuration;
|
||||
|
||||
if(!sense &&
|
||||
@@ -563,7 +564,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
if(scsiReader.CanSeek)
|
||||
scsiReader.Seek(seekPos, out seekCur);
|
||||
else
|
||||
scsiReader.ReadBlock(out _, seekPos, out seekCur, out _);
|
||||
scsiReader.ReadBlock(out _, seekPos, out seekCur, out _, out _);
|
||||
|
||||
if(seekCur > results.SeekMax &&
|
||||
seekCur > 0)
|
||||
|
||||
Reference in New Issue
Block a user