mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Save error log on dump.
This commit is contained in:
13
.idea/.idea.Aaru/.idea/contentModel.xml
generated
13
.idea/.idea.Aaru/.idea/contentModel.xml
generated
@@ -5,8 +5,6 @@
|
||||
<e p="$USER_HOME$/.cache/JetBrains/Rider2020.1/resharper-host/local/Transient/ReSharperHost/v201/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">
|
||||
<e p="Microsoft.NET.Test.Sdk.Program.cs" t="Include" />
|
||||
@@ -16,6 +14,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" />
|
||||
@@ -316,6 +324,7 @@
|
||||
<e p="ImageInfo.cs" t="Include" />
|
||||
<e p="Logging" t="Include">
|
||||
<e p="DumpLog.cs" t="Include" />
|
||||
<e p="ErrorLog.cs" t="Include" />
|
||||
<e p="IBGLog.cs" t="Include" />
|
||||
<e p="MHDDLog.cs" t="Include" />
|
||||
<e p="SubchannelLog.cs" t="Include" />
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
<Compile Include="Entropy.cs" />
|
||||
<Compile Include="GetPluginBase.cs" />
|
||||
<Compile Include="ImageInfo.cs" />
|
||||
<Compile Include="Logging\ErrorLog.cs" />
|
||||
<Compile Include="Logging\SubchannelLog.cs" />
|
||||
<Compile Include="Media\Detection\MMC.cs" />
|
||||
<Compile Include="Media\Info\CompactDisc.cs" />
|
||||
|
||||
@@ -39,11 +39,12 @@ using Aaru.CommonTypes;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.CommonTypes.Structs.Devices.ATA;
|
||||
using Aaru.Core.Devices.Report;
|
||||
using Aaru.Core.Logging;
|
||||
using Aaru.Decoders.ATA;
|
||||
using Aaru.Decoders.PCMCIA;
|
||||
using Schemas;
|
||||
using Identify = Aaru.CommonTypes.Structs.Devices.ATA.Identify;
|
||||
using Tuple = Aaru.Decoders.PCMCIA.Tuple;
|
||||
using Version = Aaru.CommonTypes.Interop.Version;
|
||||
|
||||
@@ -74,10 +75,11 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
UpdateStatus?.Invoke("Requesting ATA IDENTIFY DEVICE.");
|
||||
_dumpLog.WriteLine("Requesting ATA IDENTIFY DEVICE.");
|
||||
bool sense = _dev.AtaIdentify(out byte[] cmdBuf, out _);
|
||||
bool sense = _dev.AtaIdentify(out byte[] cmdBuf, out AtaErrorRegistersChs errorChs);
|
||||
|
||||
if(!sense &&
|
||||
Identify.Decode(cmdBuf).HasValue)
|
||||
if(sense)
|
||||
_errorLog?.WriteLine("ATA IDENTIFY DEVICE", _dev.Error, _dev.LastError, errorChs);
|
||||
else if(Identify.Decode(cmdBuf).HasValue)
|
||||
{
|
||||
Identify.IdentifyDevice? ataIdNullable = Identify.Decode(cmdBuf);
|
||||
|
||||
@@ -97,7 +99,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
// Initializate reader
|
||||
UpdateStatus?.Invoke("Initializing reader.");
|
||||
_dumpLog.WriteLine("Initializing reader.");
|
||||
var ataReader = new Reader(_dev, TIMEOUT, ataIdentify);
|
||||
var ataReader = new Reader(_dev, TIMEOUT, ataIdentify, _errorLog);
|
||||
|
||||
// Fill reader blocks
|
||||
ulong blocks = ataReader.GetDeviceBlocks();
|
||||
|
||||
@@ -291,6 +291,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i + r, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
leadOutExtents.Add(i + r, firstTrack.TrackStartSector - 1);
|
||||
|
||||
UpdateStatus?.
|
||||
@@ -388,6 +390,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
_resume.NextBlock = firstTrack.TrackStartSector;
|
||||
|
||||
break;
|
||||
|
||||
@@ -434,6 +434,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i + r, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
// Write empty data
|
||||
DateTime writeStart = DateTime.Now;
|
||||
|
||||
@@ -574,6 +576,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
continue;
|
||||
}
|
||||
|
||||
_errorLog?.WriteLine(firstSectorToRead, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
// TODO: Reset device after X errors
|
||||
if(_stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
|
||||
@@ -247,6 +247,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(sense || _dev.Error)
|
||||
{
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
if(!runningPersistent)
|
||||
continue;
|
||||
|
||||
@@ -279,6 +281,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dumpLog.WriteLine("Correctly retried sector {0} in pass {1}.", badSector, pass);
|
||||
sectorsNotEvenPartial.Remove(badSector);
|
||||
}
|
||||
else
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
@@ -390,7 +394,11 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
|
||||
if(sense || _dev.Error)
|
||||
{
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
_dumpLog.WriteLine("Got partial data for sector {0} in pass {1}.", badSector, pass);
|
||||
|
||||
@@ -541,7 +549,11 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
|
||||
if(sense || _dev.Error)
|
||||
{
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, cmdBuf, badSector, 5, subLog, isrcs,
|
||||
(byte)track.TrackSequence, ref mcn, tracks, subchannelExtents);
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
bool sense = true; // Sense indicator
|
||||
byte[] senseBuf = null;
|
||||
|
||||
UpdateStatus?.Invoke("Reading lead-outs");
|
||||
_dumpLog.WriteLine("Reading lead-outs");
|
||||
@@ -117,23 +118,24 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(readcd)
|
||||
{
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes, false,
|
||||
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
|
||||
supportedSubchannel, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes,
|
||||
false, false, true, MmcHeaderCodes.AllHeaders, true, true,
|
||||
MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(read16)
|
||||
sense = _dev.Read16(out cmdBuf, out _, 0, false, true, false, i, blockSize, 0, 1, false,
|
||||
sense = _dev.Read16(out cmdBuf, out senseBuf, 0, false, true, false, i, blockSize, 0, 1, false,
|
||||
_dev.Timeout, out cmdDuration);
|
||||
else if(read12)
|
||||
sense = _dev.Read12(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1,
|
||||
false, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
|
||||
0, 1, false, _dev.Timeout, out cmdDuration);
|
||||
else if(read10)
|
||||
sense = _dev.Read10(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1,
|
||||
_dev.Timeout, out cmdDuration);
|
||||
sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
|
||||
0, 1, _dev.Timeout, out cmdDuration);
|
||||
else if(read6)
|
||||
sense = _dev.Read6(out cmdBuf, out _, (uint)i, blockSize, 1, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.Read6(out cmdBuf, out senseBuf, (uint)i, blockSize, 1, _dev.Timeout,
|
||||
out cmdDuration);
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
@@ -178,6 +180,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
// TODO: Reset device after X errors
|
||||
if(_stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
@@ -244,6 +248,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
bool sense = true; // Sense indicator
|
||||
byte[] senseBuf = null;
|
||||
|
||||
_dumpLog.WriteLine("Retrying lead-outs");
|
||||
|
||||
@@ -281,23 +286,24 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(readcd)
|
||||
{
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes, false,
|
||||
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
|
||||
supportedSubchannel, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes,
|
||||
false, false, true, MmcHeaderCodes.AllHeaders, true, true,
|
||||
MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(read16)
|
||||
sense = _dev.Read16(out cmdBuf, out _, 0, false, true, false, i, blockSize, 0, 1, false,
|
||||
sense = _dev.Read16(out cmdBuf, out senseBuf, 0, false, true, false, i, blockSize, 0, 1, false,
|
||||
_dev.Timeout, out cmdDuration);
|
||||
else if(read12)
|
||||
sense = _dev.Read12(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1,
|
||||
false, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
|
||||
0, 1, false, _dev.Timeout, out cmdDuration);
|
||||
else if(read10)
|
||||
sense = _dev.Read10(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1,
|
||||
_dev.Timeout, out cmdDuration);
|
||||
sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
|
||||
0, 1, _dev.Timeout, out cmdDuration);
|
||||
else if(read6)
|
||||
sense = _dev.Read6(out cmdBuf, out _, (uint)i, blockSize, 1, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.Read6(out cmdBuf, out senseBuf, (uint)i, blockSize, 1, _dev.Timeout,
|
||||
out cmdDuration);
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
@@ -342,6 +348,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
// TODO: Reset device after X errors
|
||||
if(_stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
double cmdDuration = 0; // Command execution time
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
PlextorSubchannel supportedPlextorSubchannel;
|
||||
byte[] senseBuf = null;
|
||||
|
||||
switch(supportedSubchannel)
|
||||
{
|
||||
@@ -135,32 +136,36 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(_supportsPlextorD8 && audioExtents.Contains(badSector))
|
||||
{
|
||||
sense = ReadPlextorWithSubchannel(out cmdBuf, out _, badSectorToRead, blockSize, sectorsToTrim,
|
||||
supportedPlextorSubchannel, out cmdDuration);
|
||||
sense = ReadPlextorWithSubchannel(out cmdBuf, out senseBuf, badSectorToRead, blockSize,
|
||||
sectorsToTrim, supportedPlextorSubchannel, out cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(readcd)
|
||||
sense = _dev.ReadCd(out cmdBuf, out _, badSectorToRead, blockSize, sectorsToTrim,
|
||||
sense = _dev.ReadCd(out cmdBuf, out senseBuf, badSectorToRead, blockSize, sectorsToTrim,
|
||||
MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
|
||||
true, MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);
|
||||
else if(read16)
|
||||
sense = _dev.Read16(out cmdBuf, out _, 0, false, true, false, badSectorToRead, blockSize, 0,
|
||||
sense = _dev.Read16(out cmdBuf, out senseBuf, 0, false, true, false, badSectorToRead, blockSize, 0,
|
||||
sectorsToTrim, false, _dev.Timeout, out cmdDuration);
|
||||
else if(read12)
|
||||
sense = _dev.Read12(out cmdBuf, out _, 0, false, true, false, false, badSectorToRead, blockSize, 0,
|
||||
sectorsToTrim, false, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, badSectorToRead,
|
||||
blockSize, 0, sectorsToTrim, false, _dev.Timeout, out cmdDuration);
|
||||
else if(read10)
|
||||
sense = _dev.Read10(out cmdBuf, out _, 0, false, true, false, false, badSectorToRead, blockSize, 0,
|
||||
sectorsToTrim, _dev.Timeout, out cmdDuration);
|
||||
sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, badSectorToRead,
|
||||
blockSize, 0, sectorsToTrim, _dev.Timeout, out cmdDuration);
|
||||
else if(read6)
|
||||
sense = _dev.Read6(out cmdBuf, out _, badSectorToRead, blockSize, sectorsToTrim, _dev.Timeout,
|
||||
out cmdDuration);
|
||||
sense = _dev.Read6(out cmdBuf, out senseBuf, badSectorToRead, blockSize, sectorsToTrim,
|
||||
_dev.Timeout, out cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(sense || _dev.Error)
|
||||
{
|
||||
_errorLog?.WriteLine(badSectorToRead, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
readonly DumpLog _dumpLog;
|
||||
readonly bool _dumpRaw;
|
||||
readonly Encoding _encoding;
|
||||
readonly ErrorLog _errorLog;
|
||||
readonly bool _fixSubchannel;
|
||||
readonly bool _fixSubchannelCrc;
|
||||
readonly bool _fixSubchannelPosition;
|
||||
@@ -119,7 +120,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
CICMMetadataType preSidecar, uint skip, bool metadata, bool trim, bool dumpFirstTrackPregap,
|
||||
bool fixOffset, bool debug, DumpSubchannel subchannel, int speed, bool @private,
|
||||
bool fixSubchannelPosition, bool retrySubchannel, bool fixSubchannel, bool fixSubchannelCrc,
|
||||
bool skipCdireadyHole)
|
||||
bool skipCdireadyHole, ErrorLog errorLog)
|
||||
{
|
||||
_doResume = doResume;
|
||||
_dev = dev;
|
||||
@@ -154,6 +155,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_fixSubchannel = fixSubchannel;
|
||||
_fixSubchannelCrc = fixSubchannelCrc;
|
||||
_skipCdireadyHole = skipCdireadyHole;
|
||||
_errorLog = errorLog;
|
||||
}
|
||||
|
||||
/// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>
|
||||
@@ -215,6 +217,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
return;
|
||||
}
|
||||
|
||||
_errorLog.Close();
|
||||
_dumpLog.Close();
|
||||
|
||||
if(_resume == null ||
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
_speedMultiplier *= 150;
|
||||
|
||||
var scsiReader = new Reader(_dev, _dev.Timeout, null, _dumpRaw);
|
||||
var scsiReader = new Reader(_dev, _dev.Timeout, null, _errorLog, _dumpRaw);
|
||||
ulong blocks = scsiReader.GetDeviceBlocks();
|
||||
_dumpLog.WriteLine("Device reports disc has {0} blocks", blocks);
|
||||
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>();
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
bool ret;
|
||||
|
||||
_dumpLog.WriteLine("Initializing reader.");
|
||||
var scsiReader = new Reader(_dev, _dev.Timeout, null);
|
||||
var scsiReader = new Reader(_dev, _dev.Timeout, null, _errorLog);
|
||||
ulong blocks = scsiReader.GetDeviceBlocks();
|
||||
uint blockSize = scsiReader.LogicalBlockSize;
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
DateTime end;
|
||||
MediaType dskType;
|
||||
bool sense;
|
||||
byte[] senseBuf;
|
||||
|
||||
sense = _dev.ReadCapacity(out byte[] readBuffer, out _, _dev.Timeout, out _);
|
||||
|
||||
@@ -195,7 +196,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i, blocks);
|
||||
|
||||
sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false, (uint)i, BLOCK_SIZE, 0,
|
||||
sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)i, BLOCK_SIZE, 0,
|
||||
blocksToRead, false, _dev.Timeout, out double cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
@@ -212,6 +213,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
// TODO: Reset device after X errors
|
||||
if(_stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
@@ -297,11 +300,15 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
||||
|
||||
sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false, (uint)badSector,
|
||||
sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector,
|
||||
BLOCK_SIZE, 0, 1, false, _dev.Timeout, out double cmdDuration);
|
||||
|
||||
if(sense || _dev.Error)
|
||||
{
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
@@ -397,7 +404,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
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 _);
|
||||
sense = _dev.ModeSelect(md6, out senseBuf, true, false, _dev.Timeout, out _);
|
||||
|
||||
if(sense)
|
||||
{
|
||||
@@ -431,11 +438,14 @@ namespace Aaru.Core.Devices.Dumping
|
||||
forward ? "forward" : "reverse",
|
||||
runningPersistent ? "recovering partial data, " : ""));
|
||||
|
||||
sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false, (uint)badSector,
|
||||
sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector,
|
||||
BLOCK_SIZE, 0, 1, false, _dev.Timeout, out double cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(sense || _dev.Error)
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
double minSpeed = double.MaxValue;
|
||||
DateTime start;
|
||||
DateTime end;
|
||||
byte[] senseBuf;
|
||||
|
||||
bool sense = _dev.Read12(out byte[] readBuffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false,
|
||||
_dev.Timeout, out _);
|
||||
@@ -212,8 +213,9 @@ namespace Aaru.Core.Devices.Dumping
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
|
||||
(long)blocks);
|
||||
|
||||
sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false, (uint)(umdStart + (i * 4)),
|
||||
512, 0, blocksToRead * 4, false, _dev.Timeout, out double cmdDuration);
|
||||
sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false,
|
||||
(uint)(umdStart + (i * 4)), 512, 0, blocksToRead * 4, false, _dev.Timeout,
|
||||
out double cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
@@ -229,6 +231,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
// TODO: Reset device after X errors
|
||||
if(_stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
@@ -312,12 +316,16 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
||||
|
||||
sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false,
|
||||
sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false,
|
||||
(uint)(umdStart + (badSector * 4)), 512, 0, 4, false, _dev.Timeout,
|
||||
out double cmdDuration);
|
||||
|
||||
if(sense || _dev.Error)
|
||||
{
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
@@ -396,7 +404,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
md6 = Modes.EncodeMode6(md, _dev.ScsiType);
|
||||
|
||||
_dumpLog.WriteLine("Sending MODE SELECT to drive (return damaged blocks).");
|
||||
sense = _dev.ModeSelect(md6, out byte[] senseBuf, true, false, _dev.Timeout, out _);
|
||||
sense = _dev.ModeSelect(md6, out senseBuf, true, false, _dev.Timeout, out _);
|
||||
|
||||
if(sense)
|
||||
{
|
||||
@@ -429,12 +437,15 @@ namespace Aaru.Core.Devices.Dumping
|
||||
PulseProgress?.
|
||||
Invoke($"Retrying sector {badSector}, pass {pass}, {(runningPersistent ? "recovering partial data, " : "")}{(forward ? "forward" : "reverse")}");
|
||||
|
||||
sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false,
|
||||
sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false,
|
||||
(uint)(umdStart + (badSector * 4)), 512, 0, 4, false, _dev.Timeout,
|
||||
out double cmdDuration);
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(sense || _dev.Error)
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
{
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
|
||||
_dumpLog.WriteLine("Initializing reader.");
|
||||
var scsiReader = new Reader(_dev, _dev.Timeout, null, _dumpRaw);
|
||||
var scsiReader = new Reader(_dev, _dev.Timeout, null, _errorLog, _dumpRaw);
|
||||
ulong blocks = scsiReader.GetDeviceBlocks();
|
||||
uint blockSize = scsiReader.LogicalBlockSize;
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
byte[] scr = null;
|
||||
uint physicalBlockSize = 0;
|
||||
bool byteAddressed = true;
|
||||
uint[] response;
|
||||
|
||||
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>();
|
||||
|
||||
@@ -91,7 +92,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
{
|
||||
UpdateStatus?.Invoke("Reading Extended CSD");
|
||||
_dumpLog.WriteLine("Reading Extended CSD");
|
||||
sense = _dev.ReadExtendedCsd(out ecsd, out _, TIMEOUT, out duration);
|
||||
sense = _dev.ReadExtendedCsd(out ecsd, out response, TIMEOUT, out duration);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -110,11 +111,14 @@ namespace Aaru.Core.Devices.Dumping
|
||||
mediaTags.Add(MediaTagType.MMC_ExtendedCSD, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine("Read eCSD", _dev.Error, _dev.LastError, response);
|
||||
ecsd = null;
|
||||
}
|
||||
|
||||
UpdateStatus?.Invoke("Reading CSD");
|
||||
_dumpLog.WriteLine("Reading CSD");
|
||||
sense = _dev.ReadCsd(out csd, out _, TIMEOUT, out duration);
|
||||
sense = _dev.ReadCsd(out csd, out response, TIMEOUT, out duration);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -128,14 +132,20 @@ namespace Aaru.Core.Devices.Dumping
|
||||
mediaTags.Add(MediaTagType.MMC_CSD, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine("Read CSD", _dev.Error, _dev.LastError, response);
|
||||
csd = null;
|
||||
}
|
||||
|
||||
UpdateStatus?.Invoke("Reading OCR");
|
||||
_dumpLog.WriteLine("Reading OCR");
|
||||
sense = _dev.ReadOcr(out ocr, out _, TIMEOUT, out duration);
|
||||
sense = _dev.ReadOcr(out ocr, out response, TIMEOUT, out duration);
|
||||
|
||||
if(sense)
|
||||
{
|
||||
_errorLog?.WriteLine("Read OCR", _dev.Error, _dev.LastError, response);
|
||||
ocr = null;
|
||||
}
|
||||
else
|
||||
mediaTags.Add(MediaTagType.MMC_OCR, null);
|
||||
|
||||
@@ -146,7 +156,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
{
|
||||
UpdateStatus?.Invoke("Reading CSD");
|
||||
_dumpLog.WriteLine("Reading CSD");
|
||||
sense = _dev.ReadCsd(out csd, out _, TIMEOUT, out duration);
|
||||
sense = _dev.ReadCsd(out csd, out response, TIMEOUT, out duration);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -163,23 +173,32 @@ namespace Aaru.Core.Devices.Dumping
|
||||
mediaTags.Add(MediaTagType.SD_CSD, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine("Read CSD", _dev.Error, _dev.LastError, response);
|
||||
csd = null;
|
||||
}
|
||||
|
||||
UpdateStatus?.Invoke("Reading OCR");
|
||||
_dumpLog.WriteLine("Reading OCR");
|
||||
sense = _dev.ReadSdocr(out ocr, out _, TIMEOUT, out duration);
|
||||
sense = _dev.ReadSdocr(out ocr, out response, TIMEOUT, out duration);
|
||||
|
||||
if(sense)
|
||||
{
|
||||
_errorLog?.WriteLine("Read OCR", _dev.Error, _dev.LastError, response);
|
||||
ocr = null;
|
||||
}
|
||||
else
|
||||
mediaTags.Add(MediaTagType.SD_OCR, null);
|
||||
|
||||
UpdateStatus?.Invoke("Reading SCR");
|
||||
_dumpLog.WriteLine("Reading SCR");
|
||||
sense = _dev.ReadScr(out scr, out _, TIMEOUT, out duration);
|
||||
sense = _dev.ReadScr(out scr, out response, TIMEOUT, out duration);
|
||||
|
||||
if(sense)
|
||||
{
|
||||
_errorLog?.WriteLine("Read SCR", _dev.Error, _dev.LastError, response);
|
||||
scr = null;
|
||||
}
|
||||
else
|
||||
mediaTags.Add(MediaTagType.SD_SCR, null);
|
||||
|
||||
@@ -189,10 +208,13 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
UpdateStatus?.Invoke("Reading CID");
|
||||
_dumpLog.WriteLine("Reading CID");
|
||||
sense = _dev.ReadCid(out byte[] cid, out _, TIMEOUT, out duration);
|
||||
sense = _dev.ReadCid(out byte[] cid, out response, TIMEOUT, out duration);
|
||||
|
||||
if(sense)
|
||||
{
|
||||
_errorLog?.WriteLine("Read CID", _dev.Error, _dev.LastError, response);
|
||||
cid = null;
|
||||
}
|
||||
else
|
||||
mediaTags.Add(_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID : MediaTagType.MMC_CID, null);
|
||||
|
||||
@@ -345,7 +367,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
|
||||
(long)blocks);
|
||||
|
||||
error = _dev.Read(out cmdBuf, out _, (uint)i, blockSize, blocksToRead, byteAddressed, TIMEOUT,
|
||||
error = _dev.Read(out cmdBuf, out response, (uint)i, blockSize, blocksToRead, byteAddressed, TIMEOUT,
|
||||
out duration);
|
||||
|
||||
if(!error)
|
||||
@@ -359,6 +381,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, byteAddressed, response);
|
||||
|
||||
if(i + _skip > blocks)
|
||||
_skip = (uint)(blocks - i);
|
||||
|
||||
@@ -438,13 +462,17 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
PulseProgress?.Invoke($"Trimming sector {badSector}");
|
||||
|
||||
error = _dev.Read(out cmdBuf, out _, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT,
|
||||
error = _dev.Read(out cmdBuf, out response, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT,
|
||||
out duration);
|
||||
|
||||
totalDuration += duration;
|
||||
|
||||
if(error)
|
||||
{
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, byteAddressed, response);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
@@ -486,11 +514,14 @@ namespace Aaru.Core.Devices.Dumping
|
||||
forward ? "forward" : "reverse",
|
||||
runningPersistent ? "recovering partial data, " : ""));
|
||||
|
||||
error = _dev.Read(out cmdBuf, out _, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT,
|
||||
error = _dev.Read(out cmdBuf, out response, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT,
|
||||
out duration);
|
||||
|
||||
totalDuration += duration;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, byteAddressed, response);
|
||||
|
||||
if(!error)
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
|
||||
@@ -151,6 +151,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(sense)
|
||||
{
|
||||
_errorLog?.WriteLine("Kreon lock", _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
_dumpLog.WriteLine("Cannot lock drive, not continuing.");
|
||||
StoppingErrorMessage?.Invoke("Cannot lock drive, not continuing.");
|
||||
|
||||
@@ -251,6 +253,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(sense)
|
||||
{
|
||||
_errorLog?.WriteLine("Kreon Xtreme unlock", _dev.Error, _dev.LastError, senseBuf);
|
||||
_dumpLog.WriteLine("Cannot unlock drive, not continuing.");
|
||||
StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing.");
|
||||
|
||||
@@ -282,6 +285,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(sense)
|
||||
{
|
||||
_errorLog?.WriteLine("Kreon Wxripper unlock", _dev.Error, _dev.LastError, senseBuf);
|
||||
_dumpLog.WriteLine("Cannot unlock drive, not continuing.");
|
||||
StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing.");
|
||||
|
||||
@@ -600,6 +604,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
// TODO: Reset device after X errors
|
||||
if(_stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
@@ -794,6 +800,8 @@ namespace Aaru.Core.Devices.Dumping
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorLog?.WriteLine(currentSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
// TODO: Reset device after X errors
|
||||
if(_stopOnError)
|
||||
return; // TODO: Return more cleanly
|
||||
@@ -844,6 +852,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
if(sense)
|
||||
{
|
||||
_errorLog?.WriteLine("Kreon Wxripper unlock", _dev.Error, _dev.LastError, senseBuf);
|
||||
_dumpLog.WriteLine("Cannot unlock drive, not continuing.");
|
||||
StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing.");
|
||||
|
||||
@@ -913,7 +922,11 @@ namespace Aaru.Core.Devices.Dumping
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(sense || _dev.Error)
|
||||
{
|
||||
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
@@ -1062,6 +1075,9 @@ namespace Aaru.Core.Devices.Dumping
|
||||
|
||||
totalDuration += cmdDuration;
|
||||
|
||||
if(sense || _dev.Error)
|
||||
_errorLog?.WriteLine(currentSector, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
using System;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Structs.Devices.ATA;
|
||||
using Aaru.Core.Logging;
|
||||
using Aaru.Devices;
|
||||
|
||||
namespace Aaru.Core.Devices
|
||||
@@ -41,14 +42,16 @@ namespace Aaru.Core.Devices
|
||||
internal partial class Reader
|
||||
{
|
||||
readonly Device _dev;
|
||||
readonly ErrorLog _errorLog;
|
||||
readonly uint _timeout;
|
||||
|
||||
internal Reader(Device dev, uint timeout, byte[] identification, bool raw = false)
|
||||
internal Reader(Device dev, uint timeout, byte[] identification, ErrorLog errorLog, bool raw = false)
|
||||
{
|
||||
_dev = dev;
|
||||
_timeout = timeout;
|
||||
BlocksToRead = 64;
|
||||
CanReadRaw = raw;
|
||||
_errorLog = errorLog;
|
||||
|
||||
switch(dev.Type)
|
||||
{
|
||||
|
||||
@@ -361,6 +361,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorLba48.Status & 0x27) == 0 && errorLba48.Error == 0 && buffer.Length > 0);
|
||||
status = errorLba48.Status;
|
||||
errorByte = errorLba48.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba48);
|
||||
}
|
||||
else if(_ataReadLba48)
|
||||
{
|
||||
@@ -368,6 +371,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorLba48.Status & 0x27) == 0 && errorLba48.Error == 0 && buffer.Length > 0);
|
||||
status = errorLba48.Status;
|
||||
errorByte = errorLba48.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba48);
|
||||
}
|
||||
else if(_ataReadDmaRetryLba)
|
||||
{
|
||||
@@ -376,6 +382,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
|
||||
status = errorLba.Status;
|
||||
errorByte = errorLba.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
|
||||
}
|
||||
else if(_ataReadDmaLba)
|
||||
{
|
||||
@@ -384,6 +393,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
|
||||
status = errorLba.Status;
|
||||
errorByte = errorLba.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
|
||||
}
|
||||
else if(_ataReadRetryLba)
|
||||
{
|
||||
@@ -391,6 +403,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
|
||||
status = errorLba.Status;
|
||||
errorByte = errorLba.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
|
||||
}
|
||||
else if(_ataReadLba)
|
||||
{
|
||||
@@ -398,6 +413,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
|
||||
status = errorLba.Status;
|
||||
errorByte = errorLba.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
|
||||
}
|
||||
|
||||
if(error)
|
||||
@@ -422,6 +440,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
|
||||
status = errorChs.Status;
|
||||
errorByte = errorChs.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
|
||||
}
|
||||
else if(_ataReadDma)
|
||||
{
|
||||
@@ -431,6 +452,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
|
||||
status = errorChs.Status;
|
||||
errorByte = errorChs.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
|
||||
}
|
||||
else if(_ataReadRetry)
|
||||
{
|
||||
@@ -438,6 +462,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
|
||||
status = errorChs.Status;
|
||||
errorByte = errorChs.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
|
||||
}
|
||||
else if(_ataRead)
|
||||
{
|
||||
@@ -445,6 +472,9 @@ namespace Aaru.Core.Devices
|
||||
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
|
||||
status = errorChs.Status;
|
||||
errorByte = errorChs.Error;
|
||||
|
||||
if(error)
|
||||
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
|
||||
}
|
||||
|
||||
if(error)
|
||||
@@ -457,6 +487,9 @@ namespace Aaru.Core.Devices
|
||||
{
|
||||
bool sense = _dev.Seek(out AtaErrorRegistersLba28 errorLba, (uint)block, _timeout, out duration);
|
||||
|
||||
if(!(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0))
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
|
||||
|
||||
return !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0);
|
||||
}
|
||||
|
||||
@@ -464,6 +497,9 @@ namespace Aaru.Core.Devices
|
||||
{
|
||||
bool sense = _dev.Seek(out AtaErrorRegistersChs errorChs, cylinder, head, sector, _timeout, out duration);
|
||||
|
||||
if(!(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0))
|
||||
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
|
||||
|
||||
return !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,6 +622,9 @@ namespace Aaru.Core.Devices
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sense || _dev.Error)
|
||||
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, senseBuf);
|
||||
|
||||
if(!sense &&
|
||||
!_dev.Error)
|
||||
return false;
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
Identify.Decode(cmdBuf).HasValue)
|
||||
{
|
||||
// Initializate reader
|
||||
var ataReader = new Reader(_dev, TIMEOUT, cmdBuf);
|
||||
var ataReader = new Reader(_dev, TIMEOUT, cmdBuf, null);
|
||||
|
||||
// Fill reader blocks
|
||||
results.Blocks = ataReader.GetDeviceBlocks();
|
||||
@@ -204,8 +204,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
mhddLog.Close();
|
||||
|
||||
ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
|
||||
(blockSize * (double)(results.Blocks + 1)) / 1024 /
|
||||
(results.ProcessingTime / 1000),
|
||||
(blockSize * (double)(results.Blocks + 1)) / 1024 / (results.ProcessingTime / 1000),
|
||||
_devicePath);
|
||||
|
||||
InitProgress?.Invoke();
|
||||
@@ -325,8 +324,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
mhddLog.Close();
|
||||
|
||||
ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
|
||||
(blockSize * (double)(results.Blocks + 1)) / 1024 /
|
||||
(results.ProcessingTime / 1000),
|
||||
(blockSize * (double)(results.Blocks + 1)) / 1024 / (results.ProcessingTime / 1000),
|
||||
_devicePath);
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace Aaru.Core.Devices.Scanning
|
||||
case PeripheralDeviceTypes.OpticalDevice:
|
||||
case PeripheralDeviceTypes.SimplifiedDevice:
|
||||
case PeripheralDeviceTypes.WriteOnceDevice:
|
||||
scsiReader = new Reader(_dev, _dev.Timeout, null);
|
||||
scsiReader = new Reader(_dev, _dev.Timeout, null, null);
|
||||
results.Blocks = scsiReader.GetDeviceBlocks();
|
||||
|
||||
if(scsiReader.FindReadCommand())
|
||||
|
||||
554
Aaru.Core/Logging/ErrorLog.cs
Normal file
554
Aaru.Core/Logging/ErrorLog.cs
Normal file
@@ -0,0 +1,554 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Aaru.Decoders.ATA;
|
||||
using Aaru.Decoders.SCSI;
|
||||
|
||||
namespace Aaru.Core.Logging
|
||||
{
|
||||
public class ErrorLog
|
||||
{
|
||||
readonly StreamWriter _logSw;
|
||||
|
||||
/// <summary>Initializes the error log</summary>
|
||||
/// <param name="outputFile">Output log file</param>
|
||||
public ErrorLog(string outputFile)
|
||||
{
|
||||
if(string.IsNullOrEmpty(outputFile))
|
||||
return;
|
||||
|
||||
_logSw = new StreamWriter(outputFile, true);
|
||||
|
||||
_logSw.WriteLine("Start error logging at {0}", DateTime.Now);
|
||||
_logSw.WriteLine("######################################################");
|
||||
_logSw.Flush();
|
||||
}
|
||||
|
||||
/// <summary>Finishes and closes the error log</summary>
|
||||
public void Close()
|
||||
{
|
||||
_logSw.WriteLine("######################################################");
|
||||
_logSw.WriteLine("End logging at {0}", DateTime.Now);
|
||||
_logSw.Close();
|
||||
}
|
||||
|
||||
/// <summary>Register an ATA error after sending a CHS command</summary>
|
||||
/// <param name="command">Command</param>
|
||||
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
||||
/// <param name="errno">Operating system error number</param>
|
||||
/// <param name="registers">Error registers</param>
|
||||
public void WriteLine(string command, bool osError, int errno, AtaErrorRegistersChs registers)
|
||||
{
|
||||
if(osError)
|
||||
{
|
||||
_logSw.WriteLine("ATA command {0} operating system error: {1}.", command, errno);
|
||||
_logSw.Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> error = new List<string>();
|
||||
List<string> status = new List<string>();
|
||||
|
||||
if((registers.Status & 0x01) == 0x01)
|
||||
status.Add("ERR");
|
||||
|
||||
if((registers.Status & 0x02) == 0x02)
|
||||
status.Add("IDX");
|
||||
|
||||
if((registers.Status & 0x04) == 0x04)
|
||||
status.Add("CORR");
|
||||
|
||||
if((registers.Status & 0x08) == 0x08)
|
||||
status.Add("DRQ");
|
||||
|
||||
if((registers.Status & 0x10) == 0x10)
|
||||
status.Add("SRV");
|
||||
|
||||
if((registers.Status & 0x20) == 0x20)
|
||||
status.Add("DF");
|
||||
|
||||
if((registers.Status & 0x40) == 0x40)
|
||||
status.Add("RDY");
|
||||
|
||||
if((registers.Status & 0x80) == 0x80)
|
||||
status.Add("BSY");
|
||||
|
||||
if((registers.Error & 0x01) == 0x01)
|
||||
error.Add("AMNF");
|
||||
|
||||
if((registers.Error & 0x02) == 0x02)
|
||||
error.Add("T0NF");
|
||||
|
||||
if((registers.Error & 0x04) == 0x04)
|
||||
error.Add("ABRT");
|
||||
|
||||
if((registers.Error & 0x08) == 0x08)
|
||||
error.Add("MCR");
|
||||
|
||||
if((registers.Error & 0x10) == 0x10)
|
||||
error.Add("IDNF");
|
||||
|
||||
if((registers.Error & 0x20) == 0x20)
|
||||
error.Add("MC");
|
||||
|
||||
if((registers.Error & 0x40) == 0x40)
|
||||
error.Add("UNC");
|
||||
|
||||
if((registers.Error & 0x80) == 0x80)
|
||||
error.Add("BBK");
|
||||
|
||||
_logSw.WriteLine("ATA command {0} error: status = {1}, error = {2}.", command, string.Join(' ', status),
|
||||
string.Join(' ', error));
|
||||
|
||||
_logSw.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Register an ATA error after trying to read using CHS commands</summary>
|
||||
/// <param name="cylinder">Cylinder</param>
|
||||
/// <param name="head">Head</param>
|
||||
/// <param name="sector">Sector</param>
|
||||
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
||||
/// <param name="errno">Operating system error number</param>
|
||||
/// <param name="registers">Error registers</param>
|
||||
public void WriteLine(ushort cylinder, byte head, byte sector, bool osError, int errno,
|
||||
AtaErrorRegistersChs registers)
|
||||
{
|
||||
if(osError)
|
||||
{
|
||||
_logSw.WriteLine("ATA reading C/H/S {0}/{1}/{2} operating system error: {3}.", cylinder, head, sector,
|
||||
errno);
|
||||
|
||||
_logSw.Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> error = new List<string>();
|
||||
List<string> status = new List<string>();
|
||||
|
||||
if((registers.Status & 0x01) == 0x01)
|
||||
status.Add("ERR");
|
||||
|
||||
if((registers.Status & 0x02) == 0x02)
|
||||
status.Add("IDX");
|
||||
|
||||
if((registers.Status & 0x04) == 0x04)
|
||||
status.Add("CORR");
|
||||
|
||||
if((registers.Status & 0x08) == 0x08)
|
||||
status.Add("DRQ");
|
||||
|
||||
if((registers.Status & 0x10) == 0x10)
|
||||
status.Add("SRV");
|
||||
|
||||
if((registers.Status & 0x20) == 0x20)
|
||||
status.Add("DF");
|
||||
|
||||
if((registers.Status & 0x40) == 0x40)
|
||||
status.Add("RDY");
|
||||
|
||||
if((registers.Status & 0x80) == 0x80)
|
||||
status.Add("BSY");
|
||||
|
||||
if((registers.Error & 0x01) == 0x01)
|
||||
error.Add("AMNF");
|
||||
|
||||
if((registers.Error & 0x02) == 0x02)
|
||||
error.Add("T0NF");
|
||||
|
||||
if((registers.Error & 0x04) == 0x04)
|
||||
error.Add("ABRT");
|
||||
|
||||
if((registers.Error & 0x08) == 0x08)
|
||||
error.Add("MCR");
|
||||
|
||||
if((registers.Error & 0x10) == 0x10)
|
||||
error.Add("IDNF");
|
||||
|
||||
if((registers.Error & 0x20) == 0x20)
|
||||
error.Add("MC");
|
||||
|
||||
if((registers.Error & 0x40) == 0x40)
|
||||
error.Add("UNC");
|
||||
|
||||
if((registers.Error & 0x80) == 0x80)
|
||||
error.Add("BBK");
|
||||
|
||||
_logSw.WriteLine("ATA reading C/H/S {0}/{1}/{2} error: status = {3}, error = {4}.", cylinder, head,
|
||||
sector, string.Join(' ', status), string.Join(' ', error));
|
||||
|
||||
_logSw.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Register an ATA error after trying to read using 28-bit LBA commands</summary>
|
||||
/// <param name="block">Starting block</param>
|
||||
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
||||
/// <param name="errno">Operating system error number</param>
|
||||
/// <param name="registers">Error registers</param>
|
||||
public void WriteLine(ulong block, bool osError, int errno, AtaErrorRegistersLba28 registers)
|
||||
{
|
||||
if(osError)
|
||||
{
|
||||
_logSw.WriteLine("ATA reading LBA {0} operating system error: {1}.", block, errno);
|
||||
_logSw.Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> error = new List<string>();
|
||||
List<string> status = new List<string>();
|
||||
|
||||
if((registers.Status & 0x01) == 0x01)
|
||||
status.Add("ERR");
|
||||
|
||||
if((registers.Status & 0x02) == 0x02)
|
||||
status.Add("IDX");
|
||||
|
||||
if((registers.Status & 0x04) == 0x04)
|
||||
status.Add("CORR");
|
||||
|
||||
if((registers.Status & 0x08) == 0x08)
|
||||
status.Add("DRQ");
|
||||
|
||||
if((registers.Status & 0x10) == 0x10)
|
||||
status.Add("SRV");
|
||||
|
||||
if((registers.Status & 0x20) == 0x20)
|
||||
status.Add("DF");
|
||||
|
||||
if((registers.Status & 0x40) == 0x40)
|
||||
status.Add("RDY");
|
||||
|
||||
if((registers.Status & 0x80) == 0x80)
|
||||
status.Add("BSY");
|
||||
|
||||
if((registers.Error & 0x01) == 0x01)
|
||||
error.Add("AMNF");
|
||||
|
||||
if((registers.Error & 0x02) == 0x02)
|
||||
error.Add("T0NF");
|
||||
|
||||
if((registers.Error & 0x04) == 0x04)
|
||||
error.Add("ABRT");
|
||||
|
||||
if((registers.Error & 0x08) == 0x08)
|
||||
error.Add("MCR");
|
||||
|
||||
if((registers.Error & 0x10) == 0x10)
|
||||
error.Add("IDNF");
|
||||
|
||||
if((registers.Error & 0x20) == 0x20)
|
||||
error.Add("MC");
|
||||
|
||||
if((registers.Error & 0x40) == 0x40)
|
||||
error.Add("UNC");
|
||||
|
||||
if((registers.Error & 0x80) == 0x80)
|
||||
error.Add("BBK");
|
||||
|
||||
_logSw.WriteLine("ATA reading LBA {0} error: status = {1}, error = {2}.", block,
|
||||
string.Join(' ', status), string.Join(' ', error));
|
||||
|
||||
_logSw.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Register an ATA error after trying to read using 48-bit LBA commands</summary>
|
||||
/// <param name="block">Starting block</param>
|
||||
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
||||
/// <param name="errno">Operating system error number</param>
|
||||
/// <param name="registers">Error registers</param>
|
||||
public void WriteLine(ulong block, bool osError, int errno, AtaErrorRegistersLba48 registers)
|
||||
{
|
||||
if(osError)
|
||||
{
|
||||
_logSw.WriteLine("ATA reading LBA {0} operating system error: {1}.", block, errno);
|
||||
_logSw.Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> error = new List<string>();
|
||||
List<string> status = new List<string>();
|
||||
|
||||
if((registers.Status & 0x01) == 0x01)
|
||||
status.Add("ERR");
|
||||
|
||||
if((registers.Status & 0x02) == 0x02)
|
||||
status.Add("IDX");
|
||||
|
||||
if((registers.Status & 0x04) == 0x04)
|
||||
status.Add("CORR");
|
||||
|
||||
if((registers.Status & 0x08) == 0x08)
|
||||
status.Add("DRQ");
|
||||
|
||||
if((registers.Status & 0x10) == 0x10)
|
||||
status.Add("SRV");
|
||||
|
||||
if((registers.Status & 0x20) == 0x20)
|
||||
status.Add("DF");
|
||||
|
||||
if((registers.Status & 0x40) == 0x40)
|
||||
status.Add("RDY");
|
||||
|
||||
if((registers.Status & 0x80) == 0x80)
|
||||
status.Add("BSY");
|
||||
|
||||
if((registers.Error & 0x01) == 0x01)
|
||||
error.Add("AMNF");
|
||||
|
||||
if((registers.Error & 0x02) == 0x02)
|
||||
error.Add("T0NF");
|
||||
|
||||
if((registers.Error & 0x04) == 0x04)
|
||||
error.Add("ABRT");
|
||||
|
||||
if((registers.Error & 0x08) == 0x08)
|
||||
error.Add("MCR");
|
||||
|
||||
if((registers.Error & 0x10) == 0x10)
|
||||
error.Add("IDNF");
|
||||
|
||||
if((registers.Error & 0x20) == 0x20)
|
||||
error.Add("MC");
|
||||
|
||||
if((registers.Error & 0x40) == 0x40)
|
||||
error.Add("UNC");
|
||||
|
||||
if((registers.Error & 0x80) == 0x80)
|
||||
error.Add("BBK");
|
||||
|
||||
_logSw.WriteLine("ATA reading LBA {0} error: status = {1}, error = {2}.", block,
|
||||
string.Join(' ', status), string.Join(' ', error));
|
||||
|
||||
_logSw.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Register a SCSI error after sending a command</summary>
|
||||
/// <param name="command">Command</param>
|
||||
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
||||
/// <param name="errno">Operating system error number</param>
|
||||
/// <param name="senseBuffer">REQUEST SENSE response buffer</param>
|
||||
public void WriteLine(string command, bool osError, int errno, byte[] senseBuffer)
|
||||
{
|
||||
if(osError)
|
||||
{
|
||||
_logSw.WriteLine("SCSI command {0} operating system error: {1}.", command, errno);
|
||||
_logSw.Flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FixedSense? decodedFixedSense = Sense.DecodeFixed(senseBuffer);
|
||||
DescriptorSense? decodedDescriptorSense = Sense.DecodeDescriptor(senseBuffer);
|
||||
string prettySense = Sense.PrettifySense(senseBuffer);
|
||||
string hexSense = string.Join(' ', senseBuffer.Select(b => $"{b:X2}"));
|
||||
|
||||
if(decodedFixedSense.HasValue)
|
||||
{
|
||||
if(prettySense != null)
|
||||
{
|
||||
if(prettySense.StartsWith("SCSI SENSE: "))
|
||||
prettySense = prettySense.Substring(12);
|
||||
|
||||
if(prettySense.EndsWith("\n"))
|
||||
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
||||
|
||||
prettySense = prettySense.Replace("\n", " - ");
|
||||
|
||||
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", command,
|
||||
decodedFixedSense?.SenseKey, decodedFixedSense?.ASC, decodedFixedSense?.ASCQ,
|
||||
hexSense, prettySense);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", command,
|
||||
decodedFixedSense?.SenseKey, decodedFixedSense?.ASC, decodedFixedSense?.ASCQ,
|
||||
hexSense);
|
||||
}
|
||||
}
|
||||
else if(decodedDescriptorSense.HasValue)
|
||||
{
|
||||
if(prettySense != null)
|
||||
{
|
||||
if(prettySense.StartsWith("SCSI SENSE: "))
|
||||
prettySense = prettySense.Substring(12);
|
||||
|
||||
if(prettySense.EndsWith("\n"))
|
||||
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
||||
|
||||
prettySense = prettySense.Replace("\n", " - ");
|
||||
|
||||
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", command,
|
||||
decodedDescriptorSense?.SenseKey, decodedDescriptorSense?.ASC,
|
||||
decodedDescriptorSense?.ASCQ, hexSense, prettySense);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", command,
|
||||
decodedDescriptorSense?.SenseKey, decodedDescriptorSense?.ASC,
|
||||
decodedDescriptorSense?.ASCQ, hexSense);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(prettySense != null)
|
||||
{
|
||||
if(prettySense.StartsWith("SCSI SENSE: "))
|
||||
prettySense = prettySense.Substring(12);
|
||||
|
||||
if(prettySense.EndsWith("\n"))
|
||||
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
||||
|
||||
prettySense = prettySense.Replace("\n", " - ");
|
||||
|
||||
_logSw.WriteLine("SCSI command {0} error: {1}, {2}.", command, hexSense, prettySense);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logSw.WriteLine("SCSI command {0} error: {1}", command, hexSense);
|
||||
}
|
||||
}
|
||||
|
||||
_logSw.Flush();
|
||||
}
|
||||
|
||||
/// <summary>Register an SCSI error after trying to read</summary>
|
||||
/// <param name="block">Starting block</param>
|
||||
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
||||
/// <param name="errno">Operating system error number</param>
|
||||
/// <param name="senseBuffer">REQUEST SENSE response buffer</param>
|
||||
public void WriteLine(ulong block, bool osError, int errno, byte[] senseBuffer)
|
||||
{
|
||||
if(osError)
|
||||
{
|
||||
_logSw.WriteLine("SCSI reading LBA {0} operating system error: {1}.", block, errno);
|
||||
_logSw.Flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FixedSense? decodedFixedSense = Sense.DecodeFixed(senseBuffer);
|
||||
DescriptorSense? decodedDescriptorSense = Sense.DecodeDescriptor(senseBuffer);
|
||||
string prettySense = Sense.PrettifySense(senseBuffer);
|
||||
string hexSense = string.Join(' ', senseBuffer.Select(b => $"{b:X2}"));
|
||||
|
||||
if(decodedFixedSense.HasValue)
|
||||
{
|
||||
if(prettySense != null)
|
||||
{
|
||||
if(prettySense.StartsWith("SCSI SENSE: "))
|
||||
prettySense = prettySense.Substring(12);
|
||||
|
||||
if(prettySense.EndsWith("\n"))
|
||||
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
||||
|
||||
prettySense = prettySense.Replace("\n", " - ");
|
||||
|
||||
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", block,
|
||||
decodedFixedSense?.SenseKey, decodedFixedSense?.ASC, decodedFixedSense?.ASCQ,
|
||||
hexSense, prettySense);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", block,
|
||||
decodedFixedSense?.SenseKey, decodedFixedSense?.ASC, decodedFixedSense?.ASCQ,
|
||||
hexSense);
|
||||
}
|
||||
}
|
||||
else if(decodedDescriptorSense.HasValue)
|
||||
{
|
||||
if(prettySense != null)
|
||||
{
|
||||
if(prettySense.StartsWith("SCSI SENSE: "))
|
||||
prettySense = prettySense.Substring(12);
|
||||
|
||||
if(prettySense.EndsWith("\n"))
|
||||
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
||||
|
||||
prettySense = prettySense.Replace("\n", " - ");
|
||||
|
||||
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", block,
|
||||
decodedDescriptorSense?.SenseKey, decodedDescriptorSense?.ASC,
|
||||
decodedDescriptorSense?.ASCQ, hexSense, prettySense);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", block,
|
||||
decodedDescriptorSense?.SenseKey, decodedDescriptorSense?.ASC,
|
||||
decodedDescriptorSense?.ASCQ, hexSense);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(prettySense != null)
|
||||
{
|
||||
if(prettySense.StartsWith("SCSI SENSE: "))
|
||||
prettySense = prettySense.Substring(12);
|
||||
|
||||
if(prettySense.EndsWith("\n"))
|
||||
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
||||
|
||||
prettySense = prettySense.Replace("\n", " - ");
|
||||
|
||||
_logSw.WriteLine("SCSI reading LBA {0} error: {1}, {2}.", block, hexSense, prettySense);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logSw.WriteLine("SCSI reading LBA {0} error: {1}", block, hexSense);
|
||||
}
|
||||
}
|
||||
|
||||
_logSw.Flush();
|
||||
}
|
||||
|
||||
/// <summary>Register a SecureDigital / MultiMediaCard error after sending a command</summary>
|
||||
/// <param name="command">Command</param>
|
||||
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
||||
/// <param name="errno">Operating system error number</param>
|
||||
/// <param name="response">Response</param>
|
||||
public void WriteLine(string command, bool osError, int errno, uint[] response)
|
||||
{
|
||||
if(osError)
|
||||
{
|
||||
_logSw.WriteLine("SD/MMC command {0} operating system error: {1}.", command, errno);
|
||||
_logSw.Flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Decode response
|
||||
_logSw.WriteLine("SD/MMC command {0} error: {1}", command,
|
||||
string.Join(" - ", response.Select(r => $"0x{r:X8}")));
|
||||
|
||||
_logSw.Flush();
|
||||
}
|
||||
|
||||
/// <summary>Register a SecureDigital / MultiMediaCard error after trying to read</summary>
|
||||
/// <param name="block">Starting block</param>
|
||||
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
||||
/// <param name="errno">Operating system error number</param>
|
||||
/// <param name="byteAddressed">Byte addressed</param>
|
||||
/// <param name="response">Response</param>
|
||||
public void WriteLine(ulong block, bool osError, int errno, bool byteAddressed, uint[] response)
|
||||
|
||||
{
|
||||
if(osError)
|
||||
{
|
||||
_logSw.WriteLine("SD/MMC reading LBA {0} ({1}-addressed) operating system error: {2}.", block,
|
||||
byteAddressed ? "byte" : "block", errno);
|
||||
|
||||
_logSw.Flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_logSw.WriteLine("SD/MMC reading LBA {0} ({1}-addressed) error: {2}", block,
|
||||
byteAddressed ? "byte" : "block", string.Join(" - ", response.Select(r => $"0x{r:X8}")));
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -797,11 +797,13 @@ namespace Aaru.Gui.ViewModels.Windows
|
||||
|
||||
dumpLog.WriteLine("Output image format: {0}.", SelectedPlugin.Name);
|
||||
|
||||
var errorLog = new ErrorLog(_outputPrefix + ".error.log");
|
||||
|
||||
_dumper = new Dump(Resume, _dev, _devicePath, SelectedPlugin.Plugin, (ushort)Retries, Force, false,
|
||||
Persistent, StopOnError, _resume, dumpLog, encoding, _outputPrefix, Destination,
|
||||
parsedOptions, _sidecar, (uint)Skipped, ExistingMetadata == false, Trim == false,
|
||||
Track1Pregap, true, false, DumpSubchannel.Any, 0, false, false, false, false, false,
|
||||
true);
|
||||
true, errorLog);
|
||||
|
||||
new Thread(DoWork).Start();
|
||||
}
|
||||
|
||||
@@ -469,11 +469,13 @@ namespace Aaru.Commands.Media
|
||||
AaruConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
|
||||
}
|
||||
|
||||
var errorLog = new ErrorLog(outputPrefix + ".error.log");
|
||||
|
||||
var dumper = new Dump(resume, dev, devicePath, outputFormat, retryPasses, force, false, persistent,
|
||||
stopOnError, resumeClass, dumpLog, encodingClass, outputPrefix, outputPath,
|
||||
parsedOptions, sidecar, skip, metadata, trim, firstPregap, fixOffset, debug,
|
||||
wantedSubchannel, speed, @private, fixSubchannelPosition, retrySubchannel,
|
||||
fixSubchannel, fixSubchannelCrc, skipCdireadyHole);
|
||||
fixSubchannel, fixSubchannelCrc, skipCdireadyHole, errorLog);
|
||||
|
||||
dumper.UpdateStatus += Progress.UpdateStatus;
|
||||
dumper.ErrorMessage += Progress.ErrorMessage;
|
||||
|
||||
Reference in New Issue
Block a user