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="$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" />

View File

@@ -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" />

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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 ||

View File

@@ -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[]>();

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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())

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

View File

@@ -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;