mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Split SBC dumping code in several files.
This commit is contained in:
20
.idea/.idea.Aaru/.idea/contentModel.xml
generated
20
.idea/.idea.Aaru/.idea/contentModel.xml
generated
@@ -3,9 +3,6 @@
|
|||||||
<component name="ContentModelStore">
|
<component name="ContentModelStore">
|
||||||
<e p="$USER_HOME$/.cache/JetBrains/Rider2020.2/extResources" t="IncludeRecursive" />
|
<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$/.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="$USER_HOME$/.config/git/ignore" t="IncludeRecursive" />
|
||||||
<e p="$APPLICATION_PLUGINS_DIR$/puppet/lib/stubs" 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="$USER_HOME$/.nuget/packages/microsoft.net.test.sdk/16.4.0/build/netcoreapp2.1" t="Include">
|
||||||
@@ -16,16 +13,6 @@
|
|||||||
<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.api.dll" t="Include" />
|
||||||
<e p="$USER_HOME$/.nuget/packages/nunit3testadapter/3.15.1/build/netcoreapp2.0/nunit.engine.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="$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/CODE_OF_CONDUCT.md" t="Include" />
|
||||||
<e p=".github/ISSUE_TEMPLATE.md" t="Include" />
|
<e p=".github/ISSUE_TEMPLATE.md" t="Include" />
|
||||||
<e p=".github/PULL_REQUEST_TEMPLATE.md" t="Include" />
|
<e p=".github/PULL_REQUEST_TEMPLATE.md" t="Include" />
|
||||||
@@ -284,9 +271,14 @@
|
|||||||
<e p="UMD.cs" t="Include" />
|
<e p="UMD.cs" t="Include" />
|
||||||
</e>
|
</e>
|
||||||
<e p="ResumeSupport.cs" t="Include" />
|
<e p="ResumeSupport.cs" t="Include" />
|
||||||
<e p="SBC.cs" t="Include" />
|
|
||||||
<e p="SCSI.cs" t="Include" />
|
<e p="SCSI.cs" t="Include" />
|
||||||
<e p="SSC.cs" t="Include" />
|
<e p="SSC.cs" t="Include" />
|
||||||
|
<e p="Sbc" t="Include">
|
||||||
|
<e p="Data.cs" t="Include" />
|
||||||
|
<e p="Dump.cs" t="Include" />
|
||||||
|
<e p="Error.cs" t="Include" />
|
||||||
|
<e p="Trim.cs" t="Include" />
|
||||||
|
</e>
|
||||||
<e p="SecureDigital.cs" t="Include" />
|
<e p="SecureDigital.cs" t="Include" />
|
||||||
<e p="XGD.cs" t="Include" />
|
<e p="XGD.cs" t="Include" />
|
||||||
</e>
|
</e>
|
||||||
|
|||||||
@@ -65,6 +65,10 @@
|
|||||||
<Compile Include="Devices\Dumping\PlayStationPortable\MemoryStick.cs" />
|
<Compile Include="Devices\Dumping\PlayStationPortable\MemoryStick.cs" />
|
||||||
<Compile Include="Devices\Dumping\PlayStationPortable\PlayStationPortable.cs" />
|
<Compile Include="Devices\Dumping\PlayStationPortable\PlayStationPortable.cs" />
|
||||||
<Compile Include="Devices\Dumping\PlayStationPortable\UMD.cs" />
|
<Compile Include="Devices\Dumping\PlayStationPortable\UMD.cs" />
|
||||||
|
<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\Trim.cs" />
|
||||||
<Compile Include="Devices\Info\DeviceInfo.cs" />
|
<Compile Include="Devices\Info\DeviceInfo.cs" />
|
||||||
<Compile Include="Devices\Info\Plextor.cs" />
|
<Compile Include="Devices\Info\Plextor.cs" />
|
||||||
<Compile Include="Devices\Info\Properties.cs" />
|
<Compile Include="Devices\Info\Properties.cs" />
|
||||||
@@ -116,7 +120,6 @@
|
|||||||
<Compile Include="Devices\ReaderSCSI.cs" />
|
<Compile Include="Devices\ReaderSCSI.cs" />
|
||||||
<Compile Include="Devices\Dumping\SSC.cs" />
|
<Compile Include="Devices\Dumping\SSC.cs" />
|
||||||
<Compile Include="Devices\Dumping\MMC.cs" />
|
<Compile Include="Devices\Dumping\MMC.cs" />
|
||||||
<Compile Include="Devices\Dumping\SBC.cs" />
|
|
||||||
<Compile Include="Devices\Dumping\XGD.cs" />
|
<Compile Include="Devices\Dumping\XGD.cs" />
|
||||||
<Compile Include="Devices\Dumping\ResumeSupport.cs" />
|
<Compile Include="Devices\Dumping\ResumeSupport.cs" />
|
||||||
<Compile Include="Partitions.cs" />
|
<Compile Include="Partitions.cs" />
|
||||||
|
|||||||
143
Aaru.Core/Devices/Dumping/Sbc/Data.cs
Normal file
143
Aaru.Core/Devices/Dumping/Sbc/Data.cs
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Data.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2020 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Aaru.CommonTypes.Extents;
|
||||||
|
using Aaru.Core.Logging;
|
||||||
|
using Schemas;
|
||||||
|
|
||||||
|
// ReSharper disable JoinDeclarationAndInitializer
|
||||||
|
// ReSharper disable InlineOutVariableDeclaration
|
||||||
|
// ReSharper disable TooWideLocalVariableScope
|
||||||
|
|
||||||
|
namespace Aaru.Core.Devices.Dumping
|
||||||
|
{
|
||||||
|
partial class Dump
|
||||||
|
{
|
||||||
|
void ReadSbcData(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)
|
||||||
|
{
|
||||||
|
ulong sectorSpeedStart = 0;
|
||||||
|
bool sense;
|
||||||
|
DateTime timeSpeedStart = DateTime.UtcNow;
|
||||||
|
byte[] buffer;
|
||||||
|
uint blocksToRead = maxBlocksToRead;
|
||||||
|
|
||||||
|
for(ulong i = _resume.NextBlock; i < blocks; i += blocksToRead)
|
||||||
|
{
|
||||||
|
if(_aborted)
|
||||||
|
{
|
||||||
|
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
|
||||||
|
UpdateStatus?.Invoke("Aborted!");
|
||||||
|
_dumpLog.WriteLine("Aborted!");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(blocks - i < blocksToRead)
|
||||||
|
blocksToRead = (uint)(blocks - 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 _);
|
||||||
|
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
|
||||||
|
{
|
||||||
|
if(_dev.Manufacturer.ToLowerInvariant() == "insite")
|
||||||
|
{
|
||||||
|
_resume.BadBlocks.Add(i);
|
||||||
|
_resume.NextBlock++;
|
||||||
|
_aborted = true;
|
||||||
|
|
||||||
|
_dumpLog?.
|
||||||
|
WriteLine("INSITE floptical drives get crazy on the SCSI bus when an error is found, stopping so you can reboot the computer or reset the scsi bus appropriately.");
|
||||||
|
|
||||||
|
UpdateStatus?.
|
||||||
|
Invoke("INSITE floptical drives get crazy on the SCSI bus when an error is found, stopping so you can reboot the computer or reset the scsi bus appropriately");
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Reset device after X errors
|
||||||
|
if(_stopOnError)
|
||||||
|
return; // TODO: Return more cleanly
|
||||||
|
|
||||||
|
if(i + _skip > blocks)
|
||||||
|
_skip = (uint)(blocks - 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -81,7 +81,6 @@ namespace Aaru.Core.Devices.Dumping
|
|||||||
byte[] readBuffer;
|
byte[] readBuffer;
|
||||||
Modes.DecodedMode? decMode = null;
|
Modes.DecodedMode? decMode = null;
|
||||||
bool ret;
|
bool ret;
|
||||||
bool recoveredError;
|
|
||||||
|
|
||||||
if(opticalDisc)
|
if(opticalDisc)
|
||||||
switch(dskType)
|
switch(dskType)
|
||||||
@@ -592,101 +591,12 @@ namespace Aaru.Core.Devices.Dumping
|
|||||||
_dev.SetCdSpeed(out _, RotationalControl.ClvAndImpureCav, (ushort)_speed, 0, _dev.Timeout, out _);
|
_dev.SetCdSpeed(out _, RotationalControl.ClvAndImpureCav, (ushort)_speed, 0, _dev.Timeout, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool newTrim = false;
|
bool newTrim = false;
|
||||||
DateTime timeSpeedStart = DateTime.UtcNow;
|
|
||||||
ulong sectorSpeedStart = 0;
|
|
||||||
InitProgress?.Invoke();
|
InitProgress?.Invoke();
|
||||||
|
|
||||||
for(ulong i = _resume.NextBlock; i < blocks; i += blocksToRead)
|
ReadSbcData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed,
|
||||||
{
|
ref maxSpeed, ref totalDuration, scsiReader, mhddLog, ibgLog, ref imageWriteDuration,
|
||||||
if(_aborted)
|
ref newTrim);
|
||||||
{
|
|
||||||
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
|
|
||||||
UpdateStatus?.Invoke("Aborted!");
|
|
||||||
_dumpLog.WriteLine("Aborted!");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(blocks - i < blocksToRead)
|
|
||||||
blocksToRead = (uint)(blocks - 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 readBuffer, i, blocksToRead, out double cmdDuration, out _);
|
|
||||||
totalDuration += cmdDuration;
|
|
||||||
|
|
||||||
if(!sense &&
|
|
||||||
!_dev.Error)
|
|
||||||
{
|
|
||||||
mhddLog.Write(i, cmdDuration);
|
|
||||||
ibgLog.Write(i, currentSpeed * 1024);
|
|
||||||
DateTime writeStart = DateTime.Now;
|
|
||||||
_outputPlugin.WriteSectors(readBuffer, i, blocksToRead);
|
|
||||||
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
|
|
||||||
extents.Add(i, blocksToRead, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(_dev.Manufacturer.ToLowerInvariant() == "insite")
|
|
||||||
{
|
|
||||||
_resume.BadBlocks.Add(i);
|
|
||||||
_resume.NextBlock++;
|
|
||||||
_aborted = true;
|
|
||||||
|
|
||||||
_dumpLog?.
|
|
||||||
WriteLine("INSITE floptical drives get crazy on the SCSI bus when an error is found, stopping so you can reboot the computer or reset the scsi bus appropriately.");
|
|
||||||
|
|
||||||
UpdateStatus?.
|
|
||||||
Invoke("INSITE floptical drives get crazy on the SCSI bus when an error is found, stopping so you can reboot the computer or reset the scsi bus appropriately");
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Reset device after X errors
|
|
||||||
if(_stopOnError)
|
|
||||||
return; // TODO: Return more cleanly
|
|
||||||
|
|
||||||
if(i + _skip > blocks)
|
|
||||||
_skip = (uint)(blocks - 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
end = DateTime.UtcNow;
|
end = DateTime.UtcNow;
|
||||||
EndProgress?.Invoke();
|
EndProgress?.Invoke();
|
||||||
@@ -721,32 +631,9 @@ namespace Aaru.Core.Devices.Dumping
|
|||||||
UpdateStatus?.Invoke("Trimming skipped sectors");
|
UpdateStatus?.Invoke("Trimming skipped sectors");
|
||||||
_dumpLog.WriteLine("Trimming skipped sectors");
|
_dumpLog.WriteLine("Trimming skipped sectors");
|
||||||
|
|
||||||
ulong[] tmpArray = _resume.BadBlocks.ToArray();
|
|
||||||
InitProgress?.Invoke();
|
InitProgress?.Invoke();
|
||||||
|
|
||||||
foreach(ulong badSector in tmpArray)
|
TrimSbcData(scsiReader, extents, currentTry);
|
||||||
{
|
|
||||||
if(_aborted)
|
|
||||||
{
|
|
||||||
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
|
|
||||||
UpdateStatus?.Invoke("Aborted!");
|
|
||||||
_dumpLog.WriteLine("Aborted!");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
|
||||||
|
|
||||||
sense = scsiReader.ReadBlock(out readBuffer, badSector, out double _, out recoveredError);
|
|
||||||
|
|
||||||
if((sense || _dev.Error) &&
|
|
||||||
!recoveredError)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
_resume.BadBlocks.Remove(badSector);
|
|
||||||
extents.Add(badSector);
|
|
||||||
_outputPlugin.WriteSector(readBuffer, badSector);
|
|
||||||
}
|
|
||||||
|
|
||||||
EndProgress?.Invoke();
|
EndProgress?.Invoke();
|
||||||
end = DateTime.UtcNow;
|
end = DateTime.UtcNow;
|
||||||
@@ -759,248 +646,7 @@ namespace Aaru.Core.Devices.Dumping
|
|||||||
if(_resume.BadBlocks.Count > 0 &&
|
if(_resume.BadBlocks.Count > 0 &&
|
||||||
!_aborted &&
|
!_aborted &&
|
||||||
_retryPasses > 0)
|
_retryPasses > 0)
|
||||||
{
|
RetrySbcData(scsiReader, currentTry, extents, ref totalDuration);
|
||||||
int pass = 1;
|
|
||||||
bool forward = true;
|
|
||||||
bool runningPersistent = false;
|
|
||||||
|
|
||||||
Modes.ModePage? currentModePage = null;
|
|
||||||
byte[] md6;
|
|
||||||
byte[] md10;
|
|
||||||
|
|
||||||
if(_persistent)
|
|
||||||
{
|
|
||||||
Modes.ModePage_01_MMC pgMmc;
|
|
||||||
Modes.ModePage_01 pg;
|
|
||||||
|
|
||||||
sense = _dev.ModeSense6(out readBuffer, out _, false, ScsiModeSensePageControl.Current, 0x01,
|
|
||||||
_dev.Timeout, out _);
|
|
||||||
|
|
||||||
if(sense)
|
|
||||||
{
|
|
||||||
sense = _dev.ModeSense10(out readBuffer, out _, false, ScsiModeSensePageControl.Current, 0x01,
|
|
||||||
_dev.Timeout, out _);
|
|
||||||
|
|
||||||
if(!sense)
|
|
||||||
{
|
|
||||||
Modes.DecodedMode? dcMode10 = Modes.DecodeMode10(readBuffer, _dev.ScsiType);
|
|
||||||
|
|
||||||
if(dcMode10?.Pages != null)
|
|
||||||
foreach(Modes.ModePage modePage in dcMode10.Value.Pages.Where(modePage =>
|
|
||||||
modePage.Page == 0x01 && modePage.Subpage == 0x00))
|
|
||||||
currentModePage = modePage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Modes.DecodedMode? dcMode6 = Modes.DecodeMode6(readBuffer, _dev.ScsiType);
|
|
||||||
|
|
||||||
if(dcMode6?.Pages != null)
|
|
||||||
foreach(Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage =>
|
|
||||||
modePage.Page == 0x01 && modePage.Subpage == 0x00))
|
|
||||||
currentModePage = modePage;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(currentModePage == null)
|
|
||||||
{
|
|
||||||
if(_dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
|
|
||||||
{
|
|
||||||
pgMmc = new Modes.ModePage_01_MMC
|
|
||||||
{
|
|
||||||
PS = false,
|
|
||||||
ReadRetryCount = 32,
|
|
||||||
Parameter = 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
currentModePage = new Modes.ModePage
|
|
||||||
{
|
|
||||||
Page = 0x01,
|
|
||||||
Subpage = 0x00,
|
|
||||||
PageResponse = Modes.EncodeModePage_01_MMC(pgMmc)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pg = new Modes.ModePage_01
|
|
||||||
{
|
|
||||||
PS = false,
|
|
||||||
AWRE = true,
|
|
||||||
ARRE = true,
|
|
||||||
TB = false,
|
|
||||||
RC = false,
|
|
||||||
EER = true,
|
|
||||||
PER = false,
|
|
||||||
DTE = true,
|
|
||||||
DCR = false,
|
|
||||||
ReadRetryCount = 32
|
|
||||||
};
|
|
||||||
|
|
||||||
currentModePage = new Modes.ModePage
|
|
||||||
{
|
|
||||||
Page = 0x01,
|
|
||||||
Subpage = 0x00,
|
|
||||||
PageResponse = Modes.EncodeModePage_01(pg)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
|
|
||||||
{
|
|
||||||
pgMmc = new Modes.ModePage_01_MMC
|
|
||||||
{
|
|
||||||
PS = false,
|
|
||||||
ReadRetryCount = 255,
|
|
||||||
Parameter = 0x20
|
|
||||||
};
|
|
||||||
|
|
||||||
var md = new Modes.DecodedMode
|
|
||||||
{
|
|
||||||
Header = new Modes.ModeHeader(),
|
|
||||||
Pages = new[]
|
|
||||||
{
|
|
||||||
new Modes.ModePage
|
|
||||||
{
|
|
||||||
Page = 0x01,
|
|
||||||
Subpage = 0x00,
|
|
||||||
PageResponse = Modes.EncodeModePage_01_MMC(pgMmc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
md6 = Modes.EncodeMode6(md, _dev.ScsiType);
|
|
||||||
md10 = Modes.EncodeMode10(md, _dev.ScsiType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pg = new Modes.ModePage_01
|
|
||||||
{
|
|
||||||
PS = false,
|
|
||||||
AWRE = false,
|
|
||||||
ARRE = false,
|
|
||||||
TB = true,
|
|
||||||
RC = false,
|
|
||||||
EER = true,
|
|
||||||
PER = false,
|
|
||||||
DTE = false,
|
|
||||||
DCR = false,
|
|
||||||
ReadRetryCount = 255
|
|
||||||
};
|
|
||||||
|
|
||||||
var md = new Modes.DecodedMode
|
|
||||||
{
|
|
||||||
Header = new Modes.ModeHeader(),
|
|
||||||
Pages = new[]
|
|
||||||
{
|
|
||||||
new Modes.ModePage
|
|
||||||
{
|
|
||||||
Page = 0x01,
|
|
||||||
Subpage = 0x00,
|
|
||||||
PageResponse = Modes.EncodeModePage_01(pg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
md6 = Modes.EncodeMode6(md, _dev.ScsiType);
|
|
||||||
md10 = Modes.EncodeMode10(md, _dev.ScsiType);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateStatus?.Invoke("Sending MODE SELECT to drive (return damaged blocks).");
|
|
||||||
_dumpLog.WriteLine("Sending MODE SELECT to drive (return damaged blocks).");
|
|
||||||
sense = _dev.ModeSelect(md6, out byte[] senseBuf, true, false, _dev.Timeout, out _);
|
|
||||||
|
|
||||||
if(sense)
|
|
||||||
sense = _dev.ModeSelect10(md10, out senseBuf, true, false, _dev.Timeout, out _);
|
|
||||||
|
|
||||||
if(sense)
|
|
||||||
{
|
|
||||||
UpdateStatus?.
|
|
||||||
Invoke("Drive did not accept MODE SELECT command for persistent error reading, try another drive.");
|
|
||||||
|
|
||||||
AaruConsole.DebugWriteLine("Error: {0}", Sense.PrettifySense(senseBuf));
|
|
||||||
|
|
||||||
_dumpLog.
|
|
||||||
WriteLine("Drive did not accept MODE SELECT command for persistent error reading, try another drive.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
runningPersistent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InitProgress?.Invoke();
|
|
||||||
repeatRetry:
|
|
||||||
ulong[] tmpArray = _resume.BadBlocks.ToArray();
|
|
||||||
|
|
||||||
foreach(ulong badSector in tmpArray)
|
|
||||||
{
|
|
||||||
if(_aborted)
|
|
||||||
{
|
|
||||||
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
|
|
||||||
UpdateStatus?.Invoke("Aborted!");
|
|
||||||
_dumpLog.WriteLine("Aborted!");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PulseProgress?.Invoke(string.Format("Retrying sector {0}, pass {1}, {3}{2}", badSector, pass,
|
|
||||||
forward ? "forward" : "reverse",
|
|
||||||
runningPersistent ? "recovering partial data, " : ""));
|
|
||||||
|
|
||||||
sense = scsiReader.ReadBlock(out readBuffer, badSector, out double cmdDuration, out recoveredError);
|
|
||||||
totalDuration += cmdDuration;
|
|
||||||
|
|
||||||
if((!sense && !_dev.Error) || recoveredError)
|
|
||||||
{
|
|
||||||
_resume.BadBlocks.Remove(badSector);
|
|
||||||
extents.Add(badSector);
|
|
||||||
_outputPlugin.WriteSector(readBuffer, badSector);
|
|
||||||
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
|
|
||||||
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
|
|
||||||
}
|
|
||||||
else if(runningPersistent)
|
|
||||||
{
|
|
||||||
_outputPlugin.WriteSector(readBuffer, badSector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pass < _retryPasses &&
|
|
||||||
!_aborted &&
|
|
||||||
_resume.BadBlocks.Count > 0)
|
|
||||||
{
|
|
||||||
pass++;
|
|
||||||
forward = !forward;
|
|
||||||
_resume.BadBlocks.Sort();
|
|
||||||
|
|
||||||
if(!forward)
|
|
||||||
_resume.BadBlocks.Reverse();
|
|
||||||
|
|
||||||
goto repeatRetry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(runningPersistent && currentModePage.HasValue)
|
|
||||||
{
|
|
||||||
var md = new Modes.DecodedMode
|
|
||||||
{
|
|
||||||
Header = new Modes.ModeHeader(),
|
|
||||||
Pages = new[]
|
|
||||||
{
|
|
||||||
currentModePage.Value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
md6 = Modes.EncodeMode6(md, _dev.ScsiType);
|
|
||||||
md10 = Modes.EncodeMode10(md, _dev.ScsiType);
|
|
||||||
|
|
||||||
UpdateStatus?.Invoke("Sending MODE SELECT to drive (return device to previous status).");
|
|
||||||
_dumpLog.WriteLine("Sending MODE SELECT to drive (return device to previous status).");
|
|
||||||
sense = _dev.ModeSelect(md6, out _, true, false, _dev.Timeout, out _);
|
|
||||||
|
|
||||||
if(sense)
|
|
||||||
_dev.ModeSelect10(md10, out _, true, false, _dev.Timeout, out _);
|
|
||||||
}
|
|
||||||
|
|
||||||
EndProgress?.Invoke();
|
|
||||||
}
|
|
||||||
#endregion Error handling
|
#endregion Error handling
|
||||||
|
|
||||||
if(!_aborted)
|
if(!_aborted)
|
||||||
@@ -1352,8 +998,6 @@ namespace Aaru.Core.Devices.Dumping
|
|||||||
sense = _dev.ModeSense10(out cmdBuf, out _, false, true,
|
sense = _dev.ModeSense10(out cmdBuf, out _, false, true,
|
||||||
ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _);
|
ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _);
|
||||||
|
|
||||||
decMode = null;
|
|
||||||
|
|
||||||
if(!sense &&
|
if(!sense &&
|
||||||
!_dev.Error)
|
!_dev.Error)
|
||||||
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
|
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
|
||||||
290
Aaru.Core/Devices/Dumping/Sbc/Error.cs
Normal file
290
Aaru.Core/Devices/Dumping/Sbc/Error.cs
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Error.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2020 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using Aaru.CommonTypes.Extents;
|
||||||
|
using Aaru.CommonTypes.Structs.Devices.SCSI;
|
||||||
|
using Aaru.Console;
|
||||||
|
using Aaru.Decoders.SCSI;
|
||||||
|
using Aaru.Devices;
|
||||||
|
using Schemas;
|
||||||
|
|
||||||
|
// ReSharper disable JoinDeclarationAndInitializer
|
||||||
|
// ReSharper disable InlineOutVariableDeclaration
|
||||||
|
// ReSharper disable TooWideLocalVariableScope
|
||||||
|
|
||||||
|
namespace Aaru.Core.Devices.Dumping
|
||||||
|
{
|
||||||
|
partial class Dump
|
||||||
|
{
|
||||||
|
void RetrySbcData(Reader scsiReader, DumpHardwareType currentTry, ExtentsULong extents,
|
||||||
|
ref double totalDuration)
|
||||||
|
{
|
||||||
|
int pass = 1;
|
||||||
|
bool forward = true;
|
||||||
|
bool runningPersistent = false;
|
||||||
|
bool sense;
|
||||||
|
byte[] buffer;
|
||||||
|
bool recoveredError;
|
||||||
|
|
||||||
|
Modes.ModePage? currentModePage = null;
|
||||||
|
byte[] md6;
|
||||||
|
byte[] md10;
|
||||||
|
|
||||||
|
if(_persistent)
|
||||||
|
{
|
||||||
|
Modes.ModePage_01_MMC pgMmc;
|
||||||
|
Modes.ModePage_01 pg;
|
||||||
|
|
||||||
|
sense = _dev.ModeSense6(out buffer, out _, false, ScsiModeSensePageControl.Current, 0x01, _dev.Timeout,
|
||||||
|
out _);
|
||||||
|
|
||||||
|
if(sense)
|
||||||
|
{
|
||||||
|
sense = _dev.ModeSense10(out buffer, out _, false, ScsiModeSensePageControl.Current, 0x01,
|
||||||
|
_dev.Timeout, out _);
|
||||||
|
|
||||||
|
if(!sense)
|
||||||
|
{
|
||||||
|
Modes.DecodedMode? dcMode10 = Modes.DecodeMode10(buffer, _dev.ScsiType);
|
||||||
|
|
||||||
|
if(dcMode10?.Pages != null)
|
||||||
|
foreach(Modes.ModePage modePage in dcMode10.Value.Pages.Where(modePage =>
|
||||||
|
modePage.Page == 0x01 && modePage.Subpage == 0x00))
|
||||||
|
currentModePage = modePage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Modes.DecodedMode? dcMode6 = Modes.DecodeMode6(buffer, _dev.ScsiType);
|
||||||
|
|
||||||
|
if(dcMode6?.Pages != null)
|
||||||
|
foreach(Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage =>
|
||||||
|
modePage.Page == 0x01 && modePage.Subpage == 0x00))
|
||||||
|
currentModePage = modePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentModePage == null)
|
||||||
|
{
|
||||||
|
if(_dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
|
||||||
|
{
|
||||||
|
pgMmc = new Modes.ModePage_01_MMC
|
||||||
|
{
|
||||||
|
PS = false,
|
||||||
|
ReadRetryCount = 32,
|
||||||
|
Parameter = 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
currentModePage = new Modes.ModePage
|
||||||
|
{
|
||||||
|
Page = 0x01,
|
||||||
|
Subpage = 0x00,
|
||||||
|
PageResponse = Modes.EncodeModePage_01_MMC(pgMmc)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pg = new Modes.ModePage_01
|
||||||
|
{
|
||||||
|
PS = false,
|
||||||
|
AWRE = true,
|
||||||
|
ARRE = true,
|
||||||
|
TB = false,
|
||||||
|
RC = false,
|
||||||
|
EER = true,
|
||||||
|
PER = false,
|
||||||
|
DTE = true,
|
||||||
|
DCR = false,
|
||||||
|
ReadRetryCount = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
currentModePage = new Modes.ModePage
|
||||||
|
{
|
||||||
|
Page = 0x01,
|
||||||
|
Subpage = 0x00,
|
||||||
|
PageResponse = Modes.EncodeModePage_01(pg)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
|
||||||
|
{
|
||||||
|
pgMmc = new Modes.ModePage_01_MMC
|
||||||
|
{
|
||||||
|
PS = false,
|
||||||
|
ReadRetryCount = 255,
|
||||||
|
Parameter = 0x20
|
||||||
|
};
|
||||||
|
|
||||||
|
var md = new Modes.DecodedMode
|
||||||
|
{
|
||||||
|
Header = new Modes.ModeHeader(),
|
||||||
|
Pages = new[]
|
||||||
|
{
|
||||||
|
new Modes.ModePage
|
||||||
|
{
|
||||||
|
Page = 0x01,
|
||||||
|
Subpage = 0x00,
|
||||||
|
PageResponse = Modes.EncodeModePage_01_MMC(pgMmc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
md6 = Modes.EncodeMode6(md, _dev.ScsiType);
|
||||||
|
md10 = Modes.EncodeMode10(md, _dev.ScsiType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pg = new Modes.ModePage_01
|
||||||
|
{
|
||||||
|
PS = false,
|
||||||
|
AWRE = false,
|
||||||
|
ARRE = false,
|
||||||
|
TB = true,
|
||||||
|
RC = false,
|
||||||
|
EER = true,
|
||||||
|
PER = false,
|
||||||
|
DTE = false,
|
||||||
|
DCR = false,
|
||||||
|
ReadRetryCount = 255
|
||||||
|
};
|
||||||
|
|
||||||
|
var md = new Modes.DecodedMode
|
||||||
|
{
|
||||||
|
Header = new Modes.ModeHeader(),
|
||||||
|
Pages = new[]
|
||||||
|
{
|
||||||
|
new Modes.ModePage
|
||||||
|
{
|
||||||
|
Page = 0x01,
|
||||||
|
Subpage = 0x00,
|
||||||
|
PageResponse = Modes.EncodeModePage_01(pg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
md6 = Modes.EncodeMode6(md, _dev.ScsiType);
|
||||||
|
md10 = Modes.EncodeMode10(md, _dev.ScsiType);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateStatus?.Invoke("Sending MODE SELECT to drive (return damaged blocks).");
|
||||||
|
_dumpLog.WriteLine("Sending MODE SELECT to drive (return damaged blocks).");
|
||||||
|
sense = _dev.ModeSelect(md6, out byte[] senseBuf, true, false, _dev.Timeout, out _);
|
||||||
|
|
||||||
|
if(sense)
|
||||||
|
sense = _dev.ModeSelect10(md10, out senseBuf, true, false, _dev.Timeout, out _);
|
||||||
|
|
||||||
|
if(sense)
|
||||||
|
{
|
||||||
|
UpdateStatus?.
|
||||||
|
Invoke("Drive did not accept MODE SELECT command for persistent error reading, try another drive.");
|
||||||
|
|
||||||
|
AaruConsole.DebugWriteLine("Error: {0}", Sense.PrettifySense(senseBuf));
|
||||||
|
|
||||||
|
_dumpLog.WriteLine("Drive did not accept MODE SELECT command for persistent error reading, try another drive.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
runningPersistent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InitProgress?.Invoke();
|
||||||
|
repeatRetry:
|
||||||
|
ulong[] tmpArray = _resume.BadBlocks.ToArray();
|
||||||
|
|
||||||
|
foreach(ulong badSector in tmpArray)
|
||||||
|
{
|
||||||
|
if(_aborted)
|
||||||
|
{
|
||||||
|
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
|
||||||
|
UpdateStatus?.Invoke("Aborted!");
|
||||||
|
_dumpLog.WriteLine("Aborted!");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PulseProgress?.Invoke(string.Format("Retrying sector {0}, pass {1}, {3}{2}", badSector, pass,
|
||||||
|
forward ? "forward" : "reverse",
|
||||||
|
runningPersistent ? "recovering partial data, " : ""));
|
||||||
|
|
||||||
|
sense = scsiReader.ReadBlock(out buffer, badSector, out double cmdDuration, out recoveredError);
|
||||||
|
totalDuration += cmdDuration;
|
||||||
|
|
||||||
|
if((!sense && !_dev.Error) || recoveredError)
|
||||||
|
{
|
||||||
|
_resume.BadBlocks.Remove(badSector);
|
||||||
|
extents.Add(badSector);
|
||||||
|
_outputPlugin.WriteSector(buffer, badSector);
|
||||||
|
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
|
||||||
|
_dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
|
||||||
|
}
|
||||||
|
else if(runningPersistent)
|
||||||
|
{
|
||||||
|
_outputPlugin.WriteSector(buffer, badSector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pass < _retryPasses &&
|
||||||
|
!_aborted &&
|
||||||
|
_resume.BadBlocks.Count > 0)
|
||||||
|
{
|
||||||
|
pass++;
|
||||||
|
forward = !forward;
|
||||||
|
_resume.BadBlocks.Sort();
|
||||||
|
|
||||||
|
if(!forward)
|
||||||
|
_resume.BadBlocks.Reverse();
|
||||||
|
|
||||||
|
goto repeatRetry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(runningPersistent && currentModePage.HasValue)
|
||||||
|
{
|
||||||
|
var md = new Modes.DecodedMode
|
||||||
|
{
|
||||||
|
Header = new Modes.ModeHeader(),
|
||||||
|
Pages = new[]
|
||||||
|
{
|
||||||
|
currentModePage.Value
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
md6 = Modes.EncodeMode6(md, _dev.ScsiType);
|
||||||
|
md10 = Modes.EncodeMode10(md, _dev.ScsiType);
|
||||||
|
|
||||||
|
UpdateStatus?.Invoke("Sending MODE SELECT to drive (return device to previous status).");
|
||||||
|
_dumpLog.WriteLine("Sending MODE SELECT to drive (return device to previous status).");
|
||||||
|
sense = _dev.ModeSelect(md6, out _, true, false, _dev.Timeout, out _);
|
||||||
|
|
||||||
|
if(sense)
|
||||||
|
_dev.ModeSelect10(md10, out _, true, false, _dev.Timeout, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndProgress?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
70
Aaru.Core/Devices/Dumping/Sbc/Trim.cs
Normal file
70
Aaru.Core/Devices/Dumping/Sbc/Trim.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Trim.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2020 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using Aaru.CommonTypes.Extents;
|
||||||
|
using Schemas;
|
||||||
|
|
||||||
|
// ReSharper disable JoinDeclarationAndInitializer
|
||||||
|
// ReSharper disable InlineOutVariableDeclaration
|
||||||
|
// ReSharper disable TooWideLocalVariableScope
|
||||||
|
|
||||||
|
namespace Aaru.Core.Devices.Dumping
|
||||||
|
{
|
||||||
|
partial class Dump
|
||||||
|
{
|
||||||
|
void TrimSbcData(Reader scsiReader, ExtentsULong extents, DumpHardwareType currentTry)
|
||||||
|
{
|
||||||
|
ulong[] tmpArray = _resume.BadBlocks.ToArray();
|
||||||
|
bool sense;
|
||||||
|
bool recoveredError;
|
||||||
|
byte[] buffer;
|
||||||
|
|
||||||
|
foreach(ulong badSector in tmpArray)
|
||||||
|
{
|
||||||
|
if(_aborted)
|
||||||
|
{
|
||||||
|
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
|
||||||
|
UpdateStatus?.Invoke("Aborted!");
|
||||||
|
_dumpLog.WriteLine("Aborted!");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
||||||
|
|
||||||
|
sense = scsiReader.ReadBlock(out buffer, badSector, out double _, out recoveredError);
|
||||||
|
|
||||||
|
if((sense || _dev.Error) &&
|
||||||
|
!recoveredError)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_resume.BadBlocks.Remove(badSector);
|
||||||
|
extents.Add(badSector);
|
||||||
|
_outputPlugin.WriteSector(buffer, badSector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user