Save error log on dump.

This commit is contained in:
2020-07-13 18:54:41 +01:00
parent a5f5517007
commit 720bb1df6e
24 changed files with 784 additions and 70 deletions

View File

@@ -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="$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$/consoles/db" t="IncludeRecursive" />
<e p="$APPLICATION_CONFIG_DIR$/extensions" 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="$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">
<e p="Microsoft.NET.Test.Sdk.Program.cs" 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.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" />
@@ -316,6 +324,7 @@
<e p="ImageInfo.cs" t="Include" /> <e p="ImageInfo.cs" t="Include" />
<e p="Logging" t="Include"> <e p="Logging" t="Include">
<e p="DumpLog.cs" t="Include" /> <e p="DumpLog.cs" t="Include" />
<e p="ErrorLog.cs" t="Include" />
<e p="IBGLog.cs" t="Include" /> <e p="IBGLog.cs" t="Include" />
<e p="MHDDLog.cs" t="Include" /> <e p="MHDDLog.cs" t="Include" />
<e p="SubchannelLog.cs" t="Include" /> <e p="SubchannelLog.cs" t="Include" />

View File

@@ -77,6 +77,7 @@
<Compile Include="Entropy.cs" /> <Compile Include="Entropy.cs" />
<Compile Include="GetPluginBase.cs" /> <Compile Include="GetPluginBase.cs" />
<Compile Include="ImageInfo.cs" /> <Compile Include="ImageInfo.cs" />
<Compile Include="Logging\ErrorLog.cs" />
<Compile Include="Logging\SubchannelLog.cs" /> <Compile Include="Logging\SubchannelLog.cs" />
<Compile Include="Media\Detection\MMC.cs" /> <Compile Include="Media\Detection\MMC.cs" />
<Compile Include="Media\Info\CompactDisc.cs" /> <Compile Include="Media\Info\CompactDisc.cs" />

View File

@@ -39,11 +39,12 @@ using Aaru.CommonTypes;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Extents; using Aaru.CommonTypes.Extents;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs.Devices.ATA;
using Aaru.Core.Devices.Report; using Aaru.Core.Devices.Report;
using Aaru.Core.Logging; using Aaru.Core.Logging;
using Aaru.Decoders.ATA;
using Aaru.Decoders.PCMCIA; using Aaru.Decoders.PCMCIA;
using Schemas; using Schemas;
using Identify = Aaru.CommonTypes.Structs.Devices.ATA.Identify;
using Tuple = Aaru.Decoders.PCMCIA.Tuple; using Tuple = Aaru.Decoders.PCMCIA.Tuple;
using Version = Aaru.CommonTypes.Interop.Version; using Version = Aaru.CommonTypes.Interop.Version;
@@ -74,10 +75,11 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?.Invoke("Requesting ATA IDENTIFY DEVICE."); UpdateStatus?.Invoke("Requesting ATA IDENTIFY DEVICE.");
_dumpLog.WriteLine("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 && if(sense)
Identify.Decode(cmdBuf).HasValue) _errorLog?.WriteLine("ATA IDENTIFY DEVICE", _dev.Error, _dev.LastError, errorChs);
else if(Identify.Decode(cmdBuf).HasValue)
{ {
Identify.IdentifyDevice? ataIdNullable = Identify.Decode(cmdBuf); Identify.IdentifyDevice? ataIdNullable = Identify.Decode(cmdBuf);
@@ -97,7 +99,7 @@ namespace Aaru.Core.Devices.Dumping
// Initializate reader // Initializate reader
UpdateStatus?.Invoke("Initializing reader."); UpdateStatus?.Invoke("Initializing reader.");
_dumpLog.WriteLine("Initializing reader."); _dumpLog.WriteLine("Initializing reader.");
var ataReader = new Reader(_dev, TIMEOUT, ataIdentify); var ataReader = new Reader(_dev, TIMEOUT, ataIdentify, _errorLog);
// Fill reader blocks // Fill reader blocks
ulong blocks = ataReader.GetDeviceBlocks(); ulong blocks = ataReader.GetDeviceBlocks();

View File

@@ -291,6 +291,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i + r, _dev.Error, _dev.LastError, senseBuf);
leadOutExtents.Add(i + r, firstTrack.TrackStartSector - 1); leadOutExtents.Add(i + r, firstTrack.TrackStartSector - 1);
UpdateStatus?. UpdateStatus?.
@@ -388,6 +390,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
_resume.NextBlock = firstTrack.TrackStartSector; _resume.NextBlock = firstTrack.TrackStartSector;
break; break;

View File

@@ -434,6 +434,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i + r, _dev.Error, _dev.LastError, senseBuf);
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
@@ -574,6 +576,8 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
_errorLog?.WriteLine(firstSectorToRead, _dev.Error, _dev.LastError, senseBuf);
// TODO: Reset device after X errors // TODO: Reset device after X errors
if(_stopOnError) if(_stopOnError)
return; // TODO: Return more cleanly return; // TODO: Return more cleanly

View File

@@ -247,6 +247,8 @@ namespace Aaru.Core.Devices.Dumping
if(sense || _dev.Error) if(sense || _dev.Error)
{ {
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
if(!runningPersistent) if(!runningPersistent)
continue; continue;
@@ -279,6 +281,8 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Correctly retried sector {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried sector {0} in pass {1}.", badSector, pass);
sectorsNotEvenPartial.Remove(badSector); sectorsNotEvenPartial.Remove(badSector);
} }
else
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
if(supportedSubchannel != MmcSubchannel.None) if(supportedSubchannel != MmcSubchannel.None)
{ {
@@ -390,7 +394,11 @@ namespace Aaru.Core.Devices.Dumping
} }
if(sense || _dev.Error) if(sense || _dev.Error)
{
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
continue; continue;
}
_dumpLog.WriteLine("Got partial data for sector {0} in pass {1}.", badSector, pass); _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) if(sense || _dev.Error)
{
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
continue; continue;
}
WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, cmdBuf, badSector, 5, subLog, isrcs, WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, cmdBuf, badSector, 5, subLog, isrcs,
(byte)track.TrackSequence, ref mcn, tracks, subchannelExtents); (byte)track.TrackSequence, ref mcn, tracks, subchannelExtents);

View File

@@ -80,6 +80,7 @@ namespace Aaru.Core.Devices.Dumping
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
byte[] senseBuf = null;
UpdateStatus?.Invoke("Reading lead-outs"); UpdateStatus?.Invoke("Reading lead-outs");
_dumpLog.WriteLine("Reading lead-outs"); _dumpLog.WriteLine("Reading lead-outs");
@@ -117,23 +118,24 @@ namespace Aaru.Core.Devices.Dumping
if(readcd) if(readcd)
{ {
sense = _dev.ReadCd(out cmdBuf, out _, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes, false, sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes,
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, false, false, true, MmcHeaderCodes.AllHeaders, true, true,
supportedSubchannel, _dev.Timeout, out cmdDuration); MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
} }
else if(read16) 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); _dev.Timeout, out cmdDuration);
else if(read12) else if(read12)
sense = _dev.Read12(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1, sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
false, _dev.Timeout, out cmdDuration); 0, 1, false, _dev.Timeout, out cmdDuration);
else if(read10) else if(read10)
sense = _dev.Read10(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1, sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
_dev.Timeout, out cmdDuration); 0, 1, _dev.Timeout, out cmdDuration);
else if(read6) 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 && if(!sense &&
!_dev.Error) !_dev.Error)
@@ -178,6 +180,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
// TODO: Reset device after X errors // TODO: Reset device after X errors
if(_stopOnError) if(_stopOnError)
return; // TODO: Return more cleanly return; // TODO: Return more cleanly
@@ -244,6 +248,7 @@ namespace Aaru.Core.Devices.Dumping
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
byte[] senseBuf = null;
_dumpLog.WriteLine("Retrying lead-outs"); _dumpLog.WriteLine("Retrying lead-outs");
@@ -281,23 +286,24 @@ namespace Aaru.Core.Devices.Dumping
if(readcd) if(readcd)
{ {
sense = _dev.ReadCd(out cmdBuf, out _, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes, false, sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes,
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, false, false, true, MmcHeaderCodes.AllHeaders, true, true,
supportedSubchannel, _dev.Timeout, out cmdDuration); MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
} }
else if(read16) 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); _dev.Timeout, out cmdDuration);
else if(read12) else if(read12)
sense = _dev.Read12(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1, sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
false, _dev.Timeout, out cmdDuration); 0, 1, false, _dev.Timeout, out cmdDuration);
else if(read10) else if(read10)
sense = _dev.Read10(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1, sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
_dev.Timeout, out cmdDuration); 0, 1, _dev.Timeout, out cmdDuration);
else if(read6) 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 && if(!sense &&
!_dev.Error) !_dev.Error)
@@ -342,6 +348,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
// TODO: Reset device after X errors // TODO: Reset device after X errors
if(_stopOnError) if(_stopOnError)
return; // TODO: Return more cleanly return; // TODO: Return more cleanly

View File

@@ -62,6 +62,7 @@ namespace Aaru.Core.Devices.Dumping
double cmdDuration = 0; // Command execution time double cmdDuration = 0; // Command execution time
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
PlextorSubchannel supportedPlextorSubchannel; PlextorSubchannel supportedPlextorSubchannel;
byte[] senseBuf = null;
switch(supportedSubchannel) switch(supportedSubchannel)
{ {
@@ -135,32 +136,36 @@ namespace Aaru.Core.Devices.Dumping
if(_supportsPlextorD8 && audioExtents.Contains(badSector)) if(_supportsPlextorD8 && audioExtents.Contains(badSector))
{ {
sense = ReadPlextorWithSubchannel(out cmdBuf, out _, badSectorToRead, blockSize, sectorsToTrim, sense = ReadPlextorWithSubchannel(out cmdBuf, out senseBuf, badSectorToRead, blockSize,
supportedPlextorSubchannel, out cmdDuration); sectorsToTrim, supportedPlextorSubchannel, out cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
} }
else if(readcd) 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, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true,
true, MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration); true, MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);
else if(read16) 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); sectorsToTrim, false, _dev.Timeout, out cmdDuration);
else if(read12) else if(read12)
sense = _dev.Read12(out cmdBuf, out _, 0, false, true, false, false, badSectorToRead, blockSize, 0, sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, badSectorToRead,
sectorsToTrim, false, _dev.Timeout, out cmdDuration); blockSize, 0, sectorsToTrim, false, _dev.Timeout, out cmdDuration);
else if(read10) else if(read10)
sense = _dev.Read10(out cmdBuf, out _, 0, false, true, false, false, badSectorToRead, blockSize, 0, sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, badSectorToRead,
sectorsToTrim, _dev.Timeout, out cmdDuration); blockSize, 0, sectorsToTrim, _dev.Timeout, out cmdDuration);
else if(read6) else if(read6)
sense = _dev.Read6(out cmdBuf, out _, badSectorToRead, blockSize, sectorsToTrim, _dev.Timeout, sense = _dev.Read6(out cmdBuf, out senseBuf, badSectorToRead, blockSize, sectorsToTrim,
out cmdDuration); _dev.Timeout, out cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
if(sense || _dev.Error) if(sense || _dev.Error)
{
_errorLog?.WriteLine(badSectorToRead, _dev.Error, _dev.LastError, senseBuf);
continue; continue;
}
if(!sense && if(!sense &&
!_dev.Error) !_dev.Error)

View File

@@ -61,6 +61,7 @@ namespace Aaru.Core.Devices.Dumping
readonly DumpLog _dumpLog; readonly DumpLog _dumpLog;
readonly bool _dumpRaw; readonly bool _dumpRaw;
readonly Encoding _encoding; readonly Encoding _encoding;
readonly ErrorLog _errorLog;
readonly bool _fixSubchannel; readonly bool _fixSubchannel;
readonly bool _fixSubchannelCrc; readonly bool _fixSubchannelCrc;
readonly bool _fixSubchannelPosition; readonly bool _fixSubchannelPosition;
@@ -119,7 +120,7 @@ namespace Aaru.Core.Devices.Dumping
CICMMetadataType preSidecar, uint skip, bool metadata, bool trim, bool dumpFirstTrackPregap, CICMMetadataType preSidecar, uint skip, bool metadata, bool trim, bool dumpFirstTrackPregap,
bool fixOffset, bool debug, DumpSubchannel subchannel, int speed, bool @private, bool fixOffset, bool debug, DumpSubchannel subchannel, int speed, bool @private,
bool fixSubchannelPosition, bool retrySubchannel, bool fixSubchannel, bool fixSubchannelCrc, bool fixSubchannelPosition, bool retrySubchannel, bool fixSubchannel, bool fixSubchannelCrc,
bool skipCdireadyHole) bool skipCdireadyHole, ErrorLog errorLog)
{ {
_doResume = doResume; _doResume = doResume;
_dev = dev; _dev = dev;
@@ -154,6 +155,7 @@ namespace Aaru.Core.Devices.Dumping
_fixSubchannel = fixSubchannel; _fixSubchannel = fixSubchannel;
_fixSubchannelCrc = fixSubchannelCrc; _fixSubchannelCrc = fixSubchannelCrc;
_skipCdireadyHole = skipCdireadyHole; _skipCdireadyHole = skipCdireadyHole;
_errorLog = errorLog;
} }
/// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary> /// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>
@@ -215,6 +217,7 @@ namespace Aaru.Core.Devices.Dumping
return; return;
} }
_errorLog.Close();
_dumpLog.Close(); _dumpLog.Close();
if(_resume == null || if(_resume == null ||

View File

@@ -203,7 +203,7 @@ namespace Aaru.Core.Devices.Dumping
_speedMultiplier *= 150; _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(); ulong blocks = scsiReader.GetDeviceBlocks();
_dumpLog.WriteLine("Device reports disc has {0} blocks", blocks); _dumpLog.WriteLine("Device reports disc has {0} blocks", blocks);
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>();

View File

@@ -72,7 +72,7 @@ namespace Aaru.Core.Devices.Dumping
bool ret; bool ret;
_dumpLog.WriteLine("Initializing reader."); _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(); ulong blocks = scsiReader.GetDeviceBlocks();
uint blockSize = scsiReader.LogicalBlockSize; uint blockSize = scsiReader.LogicalBlockSize;

View File

@@ -65,6 +65,7 @@ namespace Aaru.Core.Devices.Dumping
DateTime end; DateTime end;
MediaType dskType; MediaType dskType;
bool sense; bool sense;
byte[] senseBuf;
sense = _dev.ReadCapacity(out byte[] readBuffer, out _, _dev.Timeout, out _); 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); 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); blocksToRead, false, _dev.Timeout, out double cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
@@ -212,6 +213,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
// TODO: Reset device after X errors // TODO: Reset device after X errors
if(_stopOnError) if(_stopOnError)
return; // TODO: Return more cleanly return; // TODO: Return more cleanly
@@ -297,11 +300,15 @@ namespace Aaru.Core.Devices.Dumping
PulseProgress?.Invoke($"Trimming sector {badSector}"); 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); BLOCK_SIZE, 0, 1, false, _dev.Timeout, out double cmdDuration);
if(sense || _dev.Error) if(sense || _dev.Error)
{
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
continue; continue;
}
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
@@ -397,7 +404,7 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?.Invoke("Sending MODE SELECT to drive (return damaged blocks)."); UpdateStatus?.Invoke("Sending MODE SELECT to drive (return damaged blocks).");
_dumpLog.WriteLine("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) if(sense)
{ {
@@ -431,11 +438,14 @@ namespace Aaru.Core.Devices.Dumping
forward ? "forward" : "reverse", forward ? "forward" : "reverse",
runningPersistent ? "recovering partial data, " : "")); 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); BLOCK_SIZE, 0, 1, false, _dev.Timeout, out double cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
if(sense || _dev.Error)
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
if(!sense && if(!sense &&
!_dev.Error) !_dev.Error)
{ {

View File

@@ -61,6 +61,7 @@ namespace Aaru.Core.Devices.Dumping
double minSpeed = double.MaxValue; double minSpeed = double.MaxValue;
DateTime start; DateTime start;
DateTime end; DateTime end;
byte[] senseBuf;
bool sense = _dev.Read12(out byte[] readBuffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false, bool sense = _dev.Read12(out byte[] readBuffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false,
_dev.Timeout, out _); _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, UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
(long)blocks); (long)blocks);
sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false, (uint)(umdStart + (i * 4)), sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false,
512, 0, blocksToRead * 4, false, _dev.Timeout, out double cmdDuration); (uint)(umdStart + (i * 4)), 512, 0, blocksToRead * 4, false, _dev.Timeout,
out double cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
@@ -229,6 +231,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
// TODO: Reset device after X errors // TODO: Reset device after X errors
if(_stopOnError) if(_stopOnError)
return; // TODO: Return more cleanly return; // TODO: Return more cleanly
@@ -312,12 +316,16 @@ namespace Aaru.Core.Devices.Dumping
PulseProgress?.Invoke($"Trimming sector {badSector}"); 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, (uint)(umdStart + (badSector * 4)), 512, 0, 4, false, _dev.Timeout,
out double cmdDuration); out double cmdDuration);
if(sense || _dev.Error) if(sense || _dev.Error)
{
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
continue; continue;
}
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
@@ -396,7 +404,7 @@ namespace Aaru.Core.Devices.Dumping
md6 = Modes.EncodeMode6(md, _dev.ScsiType); md6 = Modes.EncodeMode6(md, _dev.ScsiType);
_dumpLog.WriteLine("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) if(sense)
{ {
@@ -429,12 +437,15 @@ namespace Aaru.Core.Devices.Dumping
PulseProgress?. PulseProgress?.
Invoke($"Retrying sector {badSector}, pass {pass}, {(runningPersistent ? "recovering partial data, " : "")}{(forward ? "forward" : "reverse")}"); 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, (uint)(umdStart + (badSector * 4)), 512, 0, 4, false, _dev.Timeout,
out double cmdDuration); out double cmdDuration);
totalDuration += cmdDuration; totalDuration += cmdDuration;
if(sense || _dev.Error)
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
if(!sense && if(!sense &&
!_dev.Error) !_dev.Error)
{ {

View File

@@ -92,7 +92,7 @@ namespace Aaru.Core.Devices.Dumping
} }
_dumpLog.WriteLine("Initializing reader."); _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(); ulong blocks = scsiReader.GetDeviceBlocks();
uint blockSize = scsiReader.LogicalBlockSize; uint blockSize = scsiReader.LogicalBlockSize;

View File

@@ -82,6 +82,7 @@ namespace Aaru.Core.Devices.Dumping
byte[] scr = null; byte[] scr = null;
uint physicalBlockSize = 0; uint physicalBlockSize = 0;
bool byteAddressed = true; bool byteAddressed = true;
uint[] response;
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>();
@@ -91,7 +92,7 @@ namespace Aaru.Core.Devices.Dumping
{ {
UpdateStatus?.Invoke("Reading Extended CSD"); UpdateStatus?.Invoke("Reading Extended CSD");
_dumpLog.WriteLine("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) if(!sense)
{ {
@@ -110,11 +111,14 @@ namespace Aaru.Core.Devices.Dumping
mediaTags.Add(MediaTagType.MMC_ExtendedCSD, null); mediaTags.Add(MediaTagType.MMC_ExtendedCSD, null);
} }
else else
{
_errorLog?.WriteLine("Read eCSD", _dev.Error, _dev.LastError, response);
ecsd = null; ecsd = null;
}
UpdateStatus?.Invoke("Reading CSD"); UpdateStatus?.Invoke("Reading CSD");
_dumpLog.WriteLine("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) if(!sense)
{ {
@@ -128,14 +132,20 @@ namespace Aaru.Core.Devices.Dumping
mediaTags.Add(MediaTagType.MMC_CSD, null); mediaTags.Add(MediaTagType.MMC_CSD, null);
} }
else else
{
_errorLog?.WriteLine("Read CSD", _dev.Error, _dev.LastError, response);
csd = null; csd = null;
}
UpdateStatus?.Invoke("Reading OCR"); UpdateStatus?.Invoke("Reading OCR");
_dumpLog.WriteLine("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) if(sense)
{
_errorLog?.WriteLine("Read OCR", _dev.Error, _dev.LastError, response);
ocr = null; ocr = null;
}
else else
mediaTags.Add(MediaTagType.MMC_OCR, null); mediaTags.Add(MediaTagType.MMC_OCR, null);
@@ -146,7 +156,7 @@ namespace Aaru.Core.Devices.Dumping
{ {
UpdateStatus?.Invoke("Reading CSD"); UpdateStatus?.Invoke("Reading CSD");
_dumpLog.WriteLine("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) if(!sense)
{ {
@@ -163,23 +173,32 @@ namespace Aaru.Core.Devices.Dumping
mediaTags.Add(MediaTagType.SD_CSD, null); mediaTags.Add(MediaTagType.SD_CSD, null);
} }
else else
{
_errorLog?.WriteLine("Read CSD", _dev.Error, _dev.LastError, response);
csd = null; csd = null;
}
UpdateStatus?.Invoke("Reading OCR"); UpdateStatus?.Invoke("Reading OCR");
_dumpLog.WriteLine("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) if(sense)
{
_errorLog?.WriteLine("Read OCR", _dev.Error, _dev.LastError, response);
ocr = null; ocr = null;
}
else else
mediaTags.Add(MediaTagType.SD_OCR, null); mediaTags.Add(MediaTagType.SD_OCR, null);
UpdateStatus?.Invoke("Reading SCR"); UpdateStatus?.Invoke("Reading SCR");
_dumpLog.WriteLine("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) if(sense)
{
_errorLog?.WriteLine("Read SCR", _dev.Error, _dev.LastError, response);
scr = null; scr = null;
}
else else
mediaTags.Add(MediaTagType.SD_SCR, null); mediaTags.Add(MediaTagType.SD_SCR, null);
@@ -189,10 +208,13 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?.Invoke("Reading CID"); UpdateStatus?.Invoke("Reading CID");
_dumpLog.WriteLine("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) if(sense)
{
_errorLog?.WriteLine("Read CID", _dev.Error, _dev.LastError, response);
cid = null; cid = null;
}
else else
mediaTags.Add(_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID : MediaTagType.MMC_CID, null); 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, UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
(long)blocks); (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); out duration);
if(!error) if(!error)
@@ -359,6 +381,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, byteAddressed, response);
if(i + _skip > blocks) if(i + _skip > blocks)
_skip = (uint)(blocks - i); _skip = (uint)(blocks - i);
@@ -438,13 +462,17 @@ namespace Aaru.Core.Devices.Dumping
PulseProgress?.Invoke($"Trimming sector {badSector}"); 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); out duration);
totalDuration += duration; totalDuration += duration;
if(error) if(error)
{
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, byteAddressed, response);
continue; continue;
}
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
@@ -486,11 +514,14 @@ namespace Aaru.Core.Devices.Dumping
forward ? "forward" : "reverse", forward ? "forward" : "reverse",
runningPersistent ? "recovering partial data, " : "")); 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); out duration);
totalDuration += duration; totalDuration += duration;
if(error)
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, byteAddressed, response);
if(!error) if(!error)
{ {
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);

View File

@@ -151,6 +151,8 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
_errorLog?.WriteLine("Kreon lock", _dev.Error, _dev.LastError, senseBuf);
_dumpLog.WriteLine("Cannot lock drive, not continuing."); _dumpLog.WriteLine("Cannot lock drive, not continuing.");
StoppingErrorMessage?.Invoke("Cannot lock drive, not continuing."); StoppingErrorMessage?.Invoke("Cannot lock drive, not continuing.");
@@ -251,6 +253,7 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
_errorLog?.WriteLine("Kreon Xtreme unlock", _dev.Error, _dev.LastError, senseBuf);
_dumpLog.WriteLine("Cannot unlock drive, not continuing."); _dumpLog.WriteLine("Cannot unlock drive, not continuing.");
StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing."); StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing.");
@@ -282,6 +285,7 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
_errorLog?.WriteLine("Kreon Wxripper unlock", _dev.Error, _dev.LastError, senseBuf);
_dumpLog.WriteLine("Cannot unlock drive, not continuing."); _dumpLog.WriteLine("Cannot unlock drive, not continuing.");
StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing."); StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing.");
@@ -600,6 +604,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);
// TODO: Reset device after X errors // TODO: Reset device after X errors
if(_stopOnError) if(_stopOnError)
return; // TODO: Return more cleanly return; // TODO: Return more cleanly
@@ -794,6 +800,8 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
_errorLog?.WriteLine(currentSector, _dev.Error, _dev.LastError, senseBuf);
// TODO: Reset device after X errors // TODO: Reset device after X errors
if(_stopOnError) if(_stopOnError)
return; // TODO: Return more cleanly return; // TODO: Return more cleanly
@@ -844,6 +852,7 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
_errorLog?.WriteLine("Kreon Wxripper unlock", _dev.Error, _dev.LastError, senseBuf);
_dumpLog.WriteLine("Cannot unlock drive, not continuing."); _dumpLog.WriteLine("Cannot unlock drive, not continuing.");
StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing."); StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing.");
@@ -913,7 +922,11 @@ namespace Aaru.Core.Devices.Dumping
totalDuration += cmdDuration; totalDuration += cmdDuration;
if(sense || _dev.Error) if(sense || _dev.Error)
{
_errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
continue; continue;
}
_resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
@@ -1062,6 +1075,9 @@ namespace Aaru.Core.Devices.Dumping
totalDuration += cmdDuration; totalDuration += cmdDuration;
if(sense || _dev.Error)
_errorLog?.WriteLine(currentSector, _dev.Error, _dev.LastError, senseBuf);
if(!sense && if(!sense &&
!_dev.Error) !_dev.Error)
{ {

View File

@@ -33,6 +33,7 @@
using System; using System;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Structs.Devices.ATA; using Aaru.CommonTypes.Structs.Devices.ATA;
using Aaru.Core.Logging;
using Aaru.Devices; using Aaru.Devices;
namespace Aaru.Core.Devices namespace Aaru.Core.Devices
@@ -40,15 +41,17 @@ namespace Aaru.Core.Devices
/// <summary>Reduces common code used for scanning and dumping</summary> /// <summary>Reduces common code used for scanning and dumping</summary>
internal partial class Reader internal partial class Reader
{ {
readonly Device _dev; readonly Device _dev;
readonly uint _timeout; 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; _dev = dev;
_timeout = timeout; _timeout = timeout;
BlocksToRead = 64; BlocksToRead = 64;
CanReadRaw = raw; CanReadRaw = raw;
_errorLog = errorLog;
switch(dev.Type) switch(dev.Type)
{ {

View File

@@ -361,6 +361,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorLba48.Status & 0x27) == 0 && errorLba48.Error == 0 && buffer.Length > 0); error = !(!sense && (errorLba48.Status & 0x27) == 0 && errorLba48.Error == 0 && buffer.Length > 0);
status = errorLba48.Status; status = errorLba48.Status;
errorByte = errorLba48.Error; errorByte = errorLba48.Error;
if(error)
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba48);
} }
else if(_ataReadLba48) else if(_ataReadLba48)
{ {
@@ -368,6 +371,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorLba48.Status & 0x27) == 0 && errorLba48.Error == 0 && buffer.Length > 0); error = !(!sense && (errorLba48.Status & 0x27) == 0 && errorLba48.Error == 0 && buffer.Length > 0);
status = errorLba48.Status; status = errorLba48.Status;
errorByte = errorLba48.Error; errorByte = errorLba48.Error;
if(error)
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba48);
} }
else if(_ataReadDmaRetryLba) else if(_ataReadDmaRetryLba)
{ {
@@ -376,6 +382,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0); error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
status = errorLba.Status; status = errorLba.Status;
errorByte = errorLba.Error; errorByte = errorLba.Error;
if(error)
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
} }
else if(_ataReadDmaLba) else if(_ataReadDmaLba)
{ {
@@ -384,6 +393,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0); error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
status = errorLba.Status; status = errorLba.Status;
errorByte = errorLba.Error; errorByte = errorLba.Error;
if(error)
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
} }
else if(_ataReadRetryLba) else if(_ataReadRetryLba)
{ {
@@ -391,6 +403,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0); error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
status = errorLba.Status; status = errorLba.Status;
errorByte = errorLba.Error; errorByte = errorLba.Error;
if(error)
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
} }
else if(_ataReadLba) else if(_ataReadLba)
{ {
@@ -398,6 +413,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0); error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
status = errorLba.Status; status = errorLba.Status;
errorByte = errorLba.Error; errorByte = errorLba.Error;
if(error)
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, errorLba);
} }
if(error) if(error)
@@ -422,6 +440,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0); error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
status = errorChs.Status; status = errorChs.Status;
errorByte = errorChs.Error; errorByte = errorChs.Error;
if(error)
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
} }
else if(_ataReadDma) else if(_ataReadDma)
{ {
@@ -431,6 +452,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0); error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
status = errorChs.Status; status = errorChs.Status;
errorByte = errorChs.Error; errorByte = errorChs.Error;
if(error)
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
} }
else if(_ataReadRetry) else if(_ataReadRetry)
{ {
@@ -438,6 +462,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0); error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
status = errorChs.Status; status = errorChs.Status;
errorByte = errorChs.Error; errorByte = errorChs.Error;
if(error)
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
} }
else if(_ataRead) else if(_ataRead)
{ {
@@ -445,6 +472,9 @@ namespace Aaru.Core.Devices
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0); error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
status = errorChs.Status; status = errorChs.Status;
errorByte = errorChs.Error; errorByte = errorChs.Error;
if(error)
_errorLog?.WriteLine(cylinder, head, sector, _dev.Error, _dev.LastError, errorChs);
} }
if(error) if(error)
@@ -457,6 +487,9 @@ namespace Aaru.Core.Devices
{ {
bool sense = _dev.Seek(out AtaErrorRegistersLba28 errorLba, (uint)block, _timeout, out duration); 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); 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); 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); return !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0);
} }
} }

View File

@@ -622,6 +622,9 @@ namespace Aaru.Core.Devices
return true; return true;
} }
if(sense || _dev.Error)
_errorLog?.WriteLine(block, _dev.Error, _dev.LastError, senseBuf);
if(!sense && if(!sense &&
!_dev.Error) !_dev.Error)
return false; return false;

View File

@@ -56,7 +56,7 @@ namespace Aaru.Core.Devices.Scanning
Identify.Decode(cmdBuf).HasValue) Identify.Decode(cmdBuf).HasValue)
{ {
// Initializate reader // Initializate reader
var ataReader = new Reader(_dev, TIMEOUT, cmdBuf); var ataReader = new Reader(_dev, TIMEOUT, cmdBuf, null);
// Fill reader blocks // Fill reader blocks
results.Blocks = ataReader.GetDeviceBlocks(); results.Blocks = ataReader.GetDeviceBlocks();
@@ -204,8 +204,7 @@ namespace Aaru.Core.Devices.Scanning
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
(blockSize * (double)(results.Blocks + 1)) / 1024 / (blockSize * (double)(results.Blocks + 1)) / 1024 / (results.ProcessingTime / 1000),
(results.ProcessingTime / 1000),
_devicePath); _devicePath);
InitProgress?.Invoke(); InitProgress?.Invoke();
@@ -325,8 +324,7 @@ namespace Aaru.Core.Devices.Scanning
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
(blockSize * (double)(results.Blocks + 1)) / 1024 / (blockSize * (double)(results.Blocks + 1)) / 1024 / (results.ProcessingTime / 1000),
(results.ProcessingTime / 1000),
_devicePath); _devicePath);
InitProgress?.Invoke(); InitProgress?.Invoke();

View File

@@ -169,7 +169,7 @@ namespace Aaru.Core.Devices.Scanning
case PeripheralDeviceTypes.OpticalDevice: case PeripheralDeviceTypes.OpticalDevice:
case PeripheralDeviceTypes.SimplifiedDevice: case PeripheralDeviceTypes.SimplifiedDevice:
case PeripheralDeviceTypes.WriteOnceDevice: case PeripheralDeviceTypes.WriteOnceDevice:
scsiReader = new Reader(_dev, _dev.Timeout, null); scsiReader = new Reader(_dev, _dev.Timeout, null, null);
results.Blocks = scsiReader.GetDeviceBlocks(); results.Blocks = scsiReader.GetDeviceBlocks();
if(scsiReader.FindReadCommand()) if(scsiReader.FindReadCommand())

View 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();
}
}
}

View File

@@ -797,11 +797,13 @@ namespace Aaru.Gui.ViewModels.Windows
dumpLog.WriteLine("Output image format: {0}.", SelectedPlugin.Name); 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, _dumper = new Dump(Resume, _dev, _devicePath, SelectedPlugin.Plugin, (ushort)Retries, Force, false,
Persistent, StopOnError, _resume, dumpLog, encoding, _outputPrefix, Destination, Persistent, StopOnError, _resume, dumpLog, encoding, _outputPrefix, Destination,
parsedOptions, _sidecar, (uint)Skipped, ExistingMetadata == false, Trim == false, parsedOptions, _sidecar, (uint)Skipped, ExistingMetadata == false, Trim == false,
Track1Pregap, true, false, DumpSubchannel.Any, 0, false, false, false, false, false, Track1Pregap, true, false, DumpSubchannel.Any, 0, false, false, false, false, false,
true); true, errorLog);
new Thread(DoWork).Start(); new Thread(DoWork).Start();
} }

View File

@@ -469,11 +469,13 @@ namespace Aaru.Commands.Media
AaruConsole.WriteLine("Output image format: {0}.", outputFormat.Name); 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, var dumper = new Dump(resume, dev, devicePath, outputFormat, retryPasses, force, false, persistent,
stopOnError, resumeClass, dumpLog, encodingClass, outputPrefix, outputPath, stopOnError, resumeClass, dumpLog, encodingClass, outputPrefix, outputPath,
parsedOptions, sidecar, skip, metadata, trim, firstPregap, fixOffset, debug, parsedOptions, sidecar, skip, metadata, trim, firstPregap, fixOffset, debug,
wantedSubchannel, speed, @private, fixSubchannelPosition, retrySubchannel, wantedSubchannel, speed, @private, fixSubchannelPosition, retrySubchannel,
fixSubchannel, fixSubchannelCrc, skipCdireadyHole); fixSubchannel, fixSubchannelCrc, skipCdireadyHole, errorLog);
dumper.UpdateStatus += Progress.UpdateStatus; dumper.UpdateStatus += Progress.UpdateStatus;
dumper.ErrorMessage += Progress.ErrorMessage; dumper.ErrorMessage += Progress.ErrorMessage;
@@ -499,4 +501,4 @@ namespace Aaru.Commands.Media
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }
} }
} }