mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add option to skip more sectors than tried to read when a bad sector is found.
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
@@ -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.")]
|
||||||
|
|||||||
Reference in New Issue
Block a user