Add option to skip more sectors than tried to read when a bad sector is found.

This commit is contained in:
2018-02-02 18:44:28 +00:00
parent 2a26a22e21
commit efcf1720e2
10 changed files with 91 additions and 61 deletions

View File

@@ -81,7 +81,7 @@ namespace DiscImageChef.Core.Devices.Dumping
DumpLog dumpLog, Encoding encoding, string outputPrefix, DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath, string outputPath,
Dictionary<string, string> Dictionary<string, string>
formatOptions, CICMMetadataType preSidecar) formatOptions, CICMMetadataType preSidecar, uint skip)
{ {
bool aborted; bool aborted;
@@ -232,6 +232,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(ataReader.IsLba) if(ataReader.IsLba)
{ {
DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead); DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead);
if(skip < blocksToRead) skip = blocksToRead;
mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead); mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(outputPrefix + ".ibg", ATA_PROFILE); ibgLog = new IbgLog(outputPrefix + ".ibg", ATA_PROFILE);
@@ -270,15 +271,16 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
else else
{ {
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); for(ulong b = i; b < i + skip; b++) resume.BadBlocks.Add(b);
mhddLog.Write(i, duration < 500 ? 65535 : duration); mhddLog.Write(i, duration < 500 ? 65535 : duration);
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead); outputPlugin.WriteSectors(new byte[blockSize * skip], i, skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i); dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i);
i += skip - blocksToRead;
} }
double newSpeed = double newSpeed =
@@ -428,7 +430,8 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.", dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (imageWriteDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1024 /
(imageWriteDuration / 1000));
} }
foreach(ulong bad in resume.BadBlocks) dumpLog.WriteLine("Sector {0} could not be read.", bad); foreach(ulong bad in resume.BadBlocks) dumpLog.WriteLine("Sector {0} could not be read.", bad);
@@ -594,8 +597,10 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine(); DicConsole.WriteLine();
DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", DicConsole
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd -closeStart).TotalSeconds); .WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).",
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000,
imageWriteDuration, (closeEnd - closeStart).TotalSeconds);
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000));
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);

View File

@@ -91,7 +91,7 @@ namespace DiscImageChef.Core.Devices.Dumping
string string
outputPrefix, string outputPath, Dictionary<string, string> formatOptions, outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType CICMMetadataType
preSidecar) preSidecar, uint skip)
{ {
uint subSize; uint subSize;
DateTime start; DateTime start;
@@ -662,6 +662,8 @@ namespace DiscImageChef.Core.Devices.Dumping
double imageWriteDuration = 0; double imageWriteDuration = 0;
if(skip < blocksToRead) skip = blocksToRead;
// Start reading // Start reading
start = DateTime.UtcNow; start = DateTime.UtcNow;
for(int t = 0; t < tracks.Length; t++) for(int t = 0; t < tracks.Length; t++)
@@ -733,20 +735,22 @@ namespace DiscImageChef.Core.Devices.Dumping
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
if(supportedSubchannel != MmcSubchannel.None) if(supportedSubchannel != MmcSubchannel.None)
{ {
outputPlugin.WriteSectorsLong(new byte[SECTOR_SIZE * blocksToRead], i, blocksToRead); outputPlugin.WriteSectorsLong(new byte[SECTOR_SIZE * skip], i, skip);
outputPlugin.WriteSectorsTag(new byte[subSize * blocksToRead], i, blocksToRead, outputPlugin.WriteSectorsTag(new byte[subSize * skip], i, skip,
SectorTagType.CdSectorSubchannel); SectorTagType.CdSectorSubchannel);
} }
else outputPlugin.WriteSectorsLong(new byte[blockSize * blocksToRead], i, blocksToRead); else outputPlugin.WriteSectorsLong(new byte[blockSize * skip], i, skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); for(ulong b = i; b < i + skip; b++) resume.BadBlocks.Add(b);
DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Sense.PrettifySense(senseBuf)); DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Sense.PrettifySense(senseBuf));
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
dumpLog.WriteLine("Error reading {0} sectors from sector {1}.", blocksToRead, i); dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i);
i += skip - blocksToRead;
} }
double newSpeed = double newSpeed =
@@ -963,7 +967,9 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine(); DicConsole.WriteLine();
DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).",
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd-closeStart).TotalSeconds); (end - start).TotalSeconds, totalDuration / 1000,
totalChkDuration / 1000,
imageWriteDuration, (closeEnd - closeStart).TotalSeconds);
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000));
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);

View File

@@ -84,7 +84,7 @@ namespace DiscImageChef.Core.Devices.Dumping
string string
outputPrefix, string outputPath, Dictionary<string, string> formatOptions, outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType CICMMetadataType
preSidecar) preSidecar, uint skip)
{ {
bool sense; bool sense;
ulong blocks; ulong blocks;
@@ -200,7 +200,7 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
CompactDisc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, CompactDisc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError,
ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath, ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath,
formatOptions, preSidecar); formatOptions, preSidecar, skip);
return; return;
} }
@@ -602,13 +602,13 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
Xgd.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags, Xgd.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags,
ref dskType, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions, ref dskType, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions,
preSidecar); preSidecar, skip);
return; return;
} }
Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags, Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags,
ref dskType, true, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions, ref dskType, true, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions,
preSidecar); preSidecar, skip);
} }
internal static void AddMediaTagToSidecar(string outputPath, internal static void AddMediaTagToSidecar(string outputPath,

View File

@@ -50,7 +50,7 @@ namespace DiscImageChef.Core.Devices.Dumping
DumpLog dumpLog, Encoding encoding, string outputPrefix, DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath, string outputPath,
Dictionary<string, string> Dictionary<string, string>
formatOptions, CICMMetadataType preSidecar) formatOptions, CICMMetadataType preSidecar, uint skip)
{ {
throw new NotImplementedException("NVMe devices not yet supported."); throw new NotImplementedException("NVMe devices not yet supported.");
} }

View File

@@ -86,7 +86,8 @@ namespace DiscImageChef.Core.Devices.Dumping
ref DumpLog dumpLog, Encoding encoding, string outputPrefix, ref DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath, string outputPath,
Dictionary<string, string> formatOptions, Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar) CICMMetadataType preSidecar,
uint skip)
{ {
bool sense; bool sense;
ulong blocks; ulong blocks;
@@ -387,15 +388,16 @@ namespace DiscImageChef.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead); outputPlugin.WriteSectors(new byte[blockSize * skip], i, skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); for(ulong b = i; b < i + skip; b++) resume.BadBlocks.Add(b);
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i); dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i);
i += skip - blocksToRead;
} }
double newSpeed = double newSpeed =
@@ -883,7 +885,9 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine(); DicConsole.WriteLine();
DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).",
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd -closeStart).TotalSeconds); (end - start).TotalSeconds, totalDuration / 1000,
totalChkDuration / 1000,
imageWriteDuration, (closeEnd - closeStart).TotalSeconds);
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000));
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);

View File

@@ -79,7 +79,7 @@ namespace DiscImageChef.Core.Devices.Dumping
string string
outputPath, Dictionary<string, string> formatOptions, outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType CICMMetadataType
preSidecar) preSidecar, uint skip)
{ {
MediaType dskType = MediaType.Unknown; MediaType dskType = MediaType.Unknown;
int resets = 0; int resets = 0;
@@ -212,12 +212,12 @@ namespace DiscImageChef.Core.Devices.Dumping
case PeripheralDeviceTypes.MultiMediaDevice: case PeripheralDeviceTypes.MultiMediaDevice:
Mmc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, Mmc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError,
ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath, ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath,
formatOptions, preSidecar); formatOptions, preSidecar, skip);
return; return;
default: default:
Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, null, Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, null,
ref dskType, false, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, ref dskType, false, ref resume, ref dumpLog, encoding, outputPrefix, outputPath,
formatOptions, preSidecar); formatOptions, preSidecar, skip);
break; break;
} }
} }

View File

@@ -79,7 +79,7 @@ namespace DiscImageChef.Core.Devices.Dumping
DumpLog dumpLog, Encoding encoding, string outputPrefix, DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath, string outputPath,
Dictionary<string, string> Dictionary<string, string>
formatOptions, CICMMetadataType preSidecar) formatOptions, CICMMetadataType preSidecar, uint skip)
{ {
bool aborted; bool aborted;
@@ -234,6 +234,8 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead); dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead);
if(skip < blocksToRead) skip = blocksToRead;
DumpHardwareType currentTry = null; DumpHardwareType currentTry = null;
ExtentsULong extents = null; ExtentsULong extents = null;
ResumeSupport.Process(true, false, blocks, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformId, ResumeSupport.Process(true, false, blocks, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformId,
@@ -316,15 +318,16 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
else else
{ {
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); for(ulong b = i; b < i + skip; b++) resume.BadBlocks.Add(b);
mhddLog.Write(i, duration < 500 ? 65535 : duration); mhddLog.Write(i, duration < 500 ? 65535 : duration);
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead); outputPlugin.WriteSectors(new byte[blockSize * skip], i, skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i); dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i);
i += skip - blocksToRead;
} }
double newSpeed = double newSpeed =
@@ -598,7 +601,9 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine(); DicConsole.WriteLine();
DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).",
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd -closeStart).TotalSeconds); (end - start).TotalSeconds, totalDuration / 1000,
totalChkDuration / 1000,
imageWriteDuration, (closeEnd - closeStart).TotalSeconds);
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); (double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000));
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);

View File

@@ -88,7 +88,7 @@ namespace DiscImageChef.Core.Devices.Dumping
ref DumpLog dumpLog, ref DumpLog dumpLog,
Encoding encoding, string outputPrefix, string outputPath, Encoding encoding, string outputPrefix, string outputPath,
Dictionary<string, string> formatOptions, Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar) CICMMetadataType preSidecar, uint skip)
{ {
bool sense; bool sense;
ulong blocks; ulong blocks;
@@ -311,6 +311,8 @@ namespace DiscImageChef.Core.Devices.Dumping
return; return;
} }
if(skip < blocksToRead) skip = blocksToRead;
bool ret = true; bool ret = true;
foreach(MediaTagType tag in mediaTags.Keys) foreach(MediaTagType tag in mediaTags.Keys)
@@ -438,17 +440,18 @@ namespace DiscImageChef.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(new byte[BLOCK_SIZE * blocksToRead], i, blocksToRead); outputPlugin.WriteSectors(new byte[BLOCK_SIZE * skip], i, skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b); for(ulong b = i; b < i + skip; b++) resume.BadBlocks.Add(b);
DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Sense.PrettifySense(senseBuf)); DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Sense.PrettifySense(senseBuf));
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i); dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i);
i += skip - blocksToRead;
string[] senseLines = Sense.PrettifySense(senseBuf).Split(new[] {Environment.NewLine}, string[] senseLines = Sense.PrettifySense(senseBuf).Split(new[] {Environment.NewLine},
StringSplitOptions StringSplitOptions
.RemoveEmptyEntries); .RemoveEmptyEntries);
@@ -577,7 +580,7 @@ namespace DiscImageChef.Core.Devices.Dumping
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(new byte[BLOCK_SIZE * blocksToRead], currentSector, blocksToRead); outputPlugin.WriteSectors(new byte[BLOCK_SIZE * skip], currentSector, skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
// TODO: Handle errors in video partition // TODO: Handle errors in video partition
@@ -587,7 +590,8 @@ namespace DiscImageChef.Core.Devices.Dumping
mhddLog.Write(l1, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(l1, cmdDuration < 500 ? 65535 : cmdDuration);
ibgLog.Write(l1, 0); ibgLog.Write(l1, 0);
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, l1); dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, l1);
l1 += skip - blocksToRead;
string[] senseLines = Sense.PrettifySense(senseBuf).Split(new[] {Environment.NewLine}, string[] senseLines = Sense.PrettifySense(senseBuf).Split(new[] {Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries); StringSplitOptions.RemoveEmptyEntries);
foreach(string senseLine in senseLines) dumpLog.WriteLine(senseLine); foreach(string senseLine in senseLines) dumpLog.WriteLine(senseLine);
@@ -861,7 +865,9 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine(); DicConsole.WriteLine();
DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).",
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000, imageWriteDuration, (closeEnd -closeStart).TotalSeconds); (end - start).TotalSeconds, totalDuration / 1000,
totalChkDuration / 1000,
imageWriteDuration, (closeEnd - closeStart).TotalSeconds);
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.",
(double)BLOCK_SIZE * (double)(blocks + 1) / 1048576 / (totalDuration / 1000)); (double)BLOCK_SIZE * (double)(blocks + 1) / 1048576 / (totalDuration / 1000));
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);

View File

@@ -76,6 +76,7 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", options.Force); DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", options.Force);
DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", options.Options); DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", options.Options);
DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", options.CicmXml); DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", options.CicmXml);
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", options.Skip);
Dictionary<string, string> parsedOptions = Options.Parse(options.Options); Dictionary<string, string> parsedOptions = Options.Parse(options.Options);
DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:"); DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");
@@ -205,24 +206,24 @@ namespace DiscImageChef.Commands
case DeviceType.ATA: case DeviceType.ATA:
Ata.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, Ata.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix, options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix,
options.OutputFile, parsedOptions, sidecar); options.OutputFile, parsedOptions, sidecar, options.Skip);
break; break;
case DeviceType.MMC: case DeviceType.MMC:
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
SecureDigital.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, SecureDigital.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force,
options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog, options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog,
encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar); encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar, options.Skip);
break; break;
case DeviceType.NVMe: case DeviceType.NVMe:
NvMe.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, NvMe.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix, options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix,
options.OutputFile, parsedOptions, sidecar); options.OutputFile, parsedOptions, sidecar, options.Skip);
break; break;
case DeviceType.ATAPI: case DeviceType.ATAPI:
case DeviceType.SCSI: case DeviceType.SCSI:
Scsi.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, Scsi.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, options.LeadIn, options.Persistent, options.StopOnError, ref resume, ref dumpLog, options.LeadIn,
encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar); encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar, options.Skip);
break; break;
default: default:
dumpLog.WriteLine("Unknown device type."); dumpLog.WriteLine("Unknown device type.");

View File

@@ -308,6 +308,9 @@ namespace DiscImageChef
[Option('x', "cicm-xml", Default = null, HelpText = "Take metadata from existing CICM XML sidecar.")] [Option('x', "cicm-xml", Default = null, HelpText = "Take metadata from existing CICM XML sidecar.")]
public string CicmXml { get; set; } public string CicmXml { get; set; }
[Option('k', "skip", Default = 512, HelpText = "When an unreadable sector is found skip this many sectors.")]
public uint Skip { get; set; }
} }
[Verb("device-report", HelpText = "Tests the device capabilities and creates an XML report of them.")] [Verb("device-report", HelpText = "Tests the device capabilities and creates an XML report of them.")]