Refactor.

This commit is contained in:
2019-12-25 18:07:05 +00:00
parent ba9a108a62
commit fb4eba6703
13 changed files with 2203 additions and 2180 deletions

View File

@@ -53,9 +53,9 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <summary>Dumps an ATA device</summary> /// <summary>Dumps an ATA device</summary>
public void Ata() public void Ata()
{ {
if(dumpRaw) if(_dumpRaw)
{ {
if(force) if(_force)
ErrorMessage?.Invoke("Raw dumping not yet supported in ATA devices, continuing..."); ErrorMessage?.Invoke("Raw dumping not yet supported in ATA devices, continuing...");
else else
{ {
@@ -70,8 +70,8 @@ namespace DiscImageChef.Core.Devices.Dumping
double imageWriteDuration = 0; double imageWriteDuration = 0;
UpdateStatus?.Invoke("Requesting ATA IDENTIFY DEVICE."); UpdateStatus?.Invoke("Requesting ATA IDENTIFY DEVICE.");
dumpLog.WriteLine("Requesting ATA IDENTIFY DEVICE."); _dumpLog.WriteLine("Requesting ATA IDENTIFY DEVICE.");
bool sense = dev.AtaIdentify(out byte[] cmdBuf, out _); bool sense = _dev.AtaIdentify(out byte[] cmdBuf, out _);
if(!sense && if(!sense &&
Identify.Decode(cmdBuf).HasValue) Identify.Decode(cmdBuf).HasValue)
@@ -93,8 +93,8 @@ namespace DiscImageChef.Core.Devices.Dumping
// Initializate reader // Initializate reader
UpdateStatus?.Invoke("Initializing reader."); UpdateStatus?.Invoke("Initializing reader.");
dumpLog.WriteLine("Initializing reader."); _dumpLog.WriteLine("Initializing reader.");
var ataReader = new Reader(dev, TIMEOUT, ataIdentify); var ataReader = new Reader(_dev, TIMEOUT, ataIdentify);
// Fill reader blocks // Fill reader blocks
ulong blocks = ataReader.GetDeviceBlocks(); ulong blocks = ataReader.GetDeviceBlocks();
@@ -102,7 +102,7 @@ namespace DiscImageChef.Core.Devices.Dumping
// Check block sizes // Check block sizes
if(ataReader.GetBlockSize()) if(ataReader.GetBlockSize())
{ {
dumpLog.WriteLine("ERROR: Cannot get block size: {0}.", ataReader.ErrorMessage); _dumpLog.WriteLine("ERROR: Cannot get block size: {0}.", ataReader.ErrorMessage);
ErrorMessage(ataReader.ErrorMessage); ErrorMessage(ataReader.ErrorMessage);
return; return;
@@ -113,7 +113,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(ataReader.FindReadCommand()) if(ataReader.FindReadCommand())
{ {
dumpLog.WriteLine("ERROR: Cannot find correct read command: {0}.", ataReader.ErrorMessage); _dumpLog.WriteLine("ERROR: Cannot find correct read command: {0}.", ataReader.ErrorMessage);
ErrorMessage(ataReader.ErrorMessage); ErrorMessage(ataReader.ErrorMessage);
return; return;
@@ -122,7 +122,7 @@ namespace DiscImageChef.Core.Devices.Dumping
// Check how many blocks to read, if error show and return // Check how many blocks to read, if error show and return
if(ataReader.GetBlocksToRead()) if(ataReader.GetBlocksToRead())
{ {
dumpLog.WriteLine("ERROR: Cannot get blocks to read: {0}.", ataReader.ErrorMessage); _dumpLog.WriteLine("ERROR: Cannot get blocks to read: {0}.", ataReader.ErrorMessage);
ErrorMessage(ataReader.ErrorMessage); ErrorMessage(ataReader.ErrorMessage);
return; return;
@@ -141,23 +141,23 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time."); UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time.");
UpdateStatus?.Invoke($"Device reports {blockSize} bytes per logical block."); UpdateStatus?.Invoke($"Device reports {blockSize} bytes per logical block.");
UpdateStatus?.Invoke($"Device reports {physicalsectorsize} bytes per physical block."); UpdateStatus?.Invoke($"Device reports {physicalsectorsize} bytes per physical block.");
dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize); _dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize);
dumpLog.WriteLine("Device reports {0} cylinders {1} heads {2} sectors per track.", cylinders, heads, _dumpLog.WriteLine("Device reports {0} cylinders {1} heads {2} sectors per track.", cylinders,
sectors); heads, sectors);
dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead); _dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead);
dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize); _dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize);
dumpLog.WriteLine("Device reports {0} bytes per physical block.", physicalsectorsize); _dumpLog.WriteLine("Device reports {0} bytes per physical block.", physicalsectorsize);
bool removable = !dev.IsCompactFlash && bool removable = !_dev.IsCompactFlash &&
ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable); ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable);
DumpHardwareType currentTry = null; DumpHardwareType currentTry = null;
ExtentsULong extents = null; ExtentsULong extents = null;
ResumeSupport.Process(ataReader.IsLba, removable, blocks, dev.Manufacturer, dev.Model, dev.Serial, ResumeSupport.Process(ataReader.IsLba, removable, blocks, _dev.Manufacturer, _dev.Model,
dev.PlatformId, ref resume, ref currentTry, ref extents); _dev.Serial, _dev.PlatformId, ref _resume, ref currentTry, ref extents);
if(currentTry == null || if(currentTry == null ||
extents == null) extents == null)
@@ -173,36 +173,36 @@ namespace DiscImageChef.Core.Devices.Dumping
bool ret = true; bool ret = true;
if(dev.IsUsb && if(_dev.IsUsb &&
dev.UsbDescriptors != null && _dev.UsbDescriptors != null &&
!outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors)) !_outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors))
{ {
ret = false; ret = false;
dumpLog.WriteLine("Output format does not support USB descriptors."); _dumpLog.WriteLine("Output format does not support USB descriptors.");
ErrorMessage("Output format does not support USB descriptors."); ErrorMessage("Output format does not support USB descriptors.");
} }
if(dev.IsPcmcia && if(_dev.IsPcmcia &&
dev.Cis != null && _dev.Cis != null &&
!outputPlugin.SupportedMediaTags.Contains(MediaTagType.PCMCIA_CIS)) !_outputPlugin.SupportedMediaTags.Contains(MediaTagType.PCMCIA_CIS))
{ {
ret = false; ret = false;
dumpLog.WriteLine("Output format does not support PCMCIA CIS descriptors."); _dumpLog.WriteLine("Output format does not support PCMCIA CIS descriptors.");
ErrorMessage("Output format does not support PCMCIA CIS descriptors."); ErrorMessage("Output format does not support PCMCIA CIS descriptors.");
} }
if(!outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) if(!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
{ {
ret = false; ret = false;
dumpLog.WriteLine("Output format does not support ATA IDENTIFY."); _dumpLog.WriteLine("Output format does not support ATA IDENTIFY.");
ErrorMessage("Output format does not support ATA IDENTIFY."); ErrorMessage("Output format does not support ATA IDENTIFY.");
} }
if(!ret) if(!ret)
{ {
dumpLog.WriteLine("Several media tags not supported, {0}continuing...", force ? "" : "not "); _dumpLog.WriteLine("Several media tags not supported, {0}continuing...", _force ? "" : "not ");
if(force) if(_force)
ErrorMessage("Several media tags not supported, continuing..."); ErrorMessage("Several media tags not supported, continuing...");
else else
{ {
@@ -212,40 +212,40 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
} }
ret = outputPlugin.Create(outputPath, ret = _outputPlugin.Create(_outputPath,
dev.IsCompactFlash ? MediaType.CompactFlash : MediaType.GENERIC_HDD, _dev.IsCompactFlash ? MediaType.CompactFlash : MediaType.GENERIC_HDD,
formatOptions, blocks, blockSize); _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
dumpLog.WriteLine(outputPlugin.ErrorMessage); _dumpLog.WriteLine(_outputPlugin.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." +
Environment.NewLine + Environment.NewLine +
outputPlugin.ErrorMessage); _outputPlugin.ErrorMessage);
return; return;
} }
// Setting geometry // Setting geometry
outputPlugin.SetGeometry(cylinders, heads, sectors); _outputPlugin.SetGeometry(cylinders, heads, sectors);
if(ataReader.IsLba) if(ataReader.IsLba)
{ {
UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time."); UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");
if(skip < blocksToRead) if(_skip < blocksToRead)
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);
if(resume.NextBlock > 0) if(_resume.NextBlock > 0)
{ {
UpdateStatus?.Invoke($"Resuming from block {resume.NextBlock}."); UpdateStatus?.Invoke($"Resuming from block {_resume.NextBlock}.");
dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock); _dumpLog.WriteLine("Resuming from block {0}.", _resume.NextBlock);
} }
bool newTrim = false; bool newTrim = false;
@@ -255,13 +255,13 @@ namespace DiscImageChef.Core.Devices.Dumping
ulong sectorSpeedStart = 0; ulong sectorSpeedStart = 0;
InitProgress?.Invoke(); InitProgress?.Invoke();
for(ulong i = resume.NextBlock; i < blocks; i += blocksToRead) for(ulong i = _resume.NextBlock; i < blocks; i += blocksToRead)
{ {
if(aborted) if(_aborted)
{ {
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
break; break;
} }
@@ -289,38 +289,38 @@ namespace DiscImageChef.Core.Devices.Dumping
mhddLog.Write(i, duration); mhddLog.Write(i, duration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(cmdBuf, i, blocksToRead); _outputPlugin.WriteSectors(cmdBuf, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
else else
{ {
if(i + skip > blocks) if(i + _skip > blocks)
skip = (uint)(blocks - i); _skip = (uint)(blocks - i);
for(ulong b = i; b < i + skip; b++) for(ulong b = i; b < i + _skip; b++)
resume.BadBlocks.Add(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 * skip], i, skip); _outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i); _dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
i += skip - blocksToRead; i += _skip - blocksToRead;
newTrim = true; newTrim = true;
} }
sectorSpeedStart += blocksToRead; sectorSpeedStart += blocksToRead;
resume.NextBlock = i + blocksToRead; _resume.NextBlock = i + blocksToRead;
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds; double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
if(elapsed < 1) if(elapsed < 1)
continue; continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed); currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }
@@ -329,46 +329,46 @@ namespace DiscImageChef.Core.Devices.Dumping
EndProgress?.Invoke(); EndProgress?.Invoke();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (blockSize * (double)(blocks + 1)) / 1024 /
(totalDuration / 1000), devicePath); (totalDuration / 1000), _devicePath);
UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average dump speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000):F3} KiB/sec."); Invoke($"Average dump speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000):F3} KiB/sec.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average write speed {(double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration:F3} KiB/sec."); Invoke($"Average write speed {((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration:F3} KiB/sec.");
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds); _dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
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); ((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration);
#region Trimming #region Trimming
if(resume.BadBlocks.Count > 0 && if(_resume.BadBlocks.Count > 0 &&
!aborted && !_aborted &&
!notrim && !_notrim &&
newTrim) newTrim)
{ {
start = DateTime.UtcNow; start = DateTime.UtcNow;
UpdateStatus?.Invoke("Trimming bad sectors"); UpdateStatus?.Invoke("Trimming bad sectors");
dumpLog.WriteLine("Trimming bad sectors"); _dumpLog.WriteLine("Trimming bad sectors");
ulong[] tmpArray = resume.BadBlocks.ToArray(); ulong[] tmpArray = _resume.BadBlocks.ToArray();
InitProgress?.Invoke(); InitProgress?.Invoke();
foreach(ulong badSector in tmpArray) foreach(ulong badSector in tmpArray)
{ {
if(aborted) if(_aborted)
{ {
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
break; break;
} }
@@ -382,44 +382,44 @@ namespace DiscImageChef.Core.Devices.Dumping
if(error) if(error)
continue; continue;
resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
outputPlugin.WriteSector(cmdBuf, badSector); _outputPlugin.WriteSector(cmdBuf, badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
end = DateTime.UtcNow; end = DateTime.UtcNow;
UpdateStatus?.Invoke($"Trimmming finished in {(end - start).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Trimmming finished in {(end - start).TotalSeconds} seconds.");
dumpLog.WriteLine("Trimmming finished in {0} seconds.", (end - start).TotalSeconds); _dumpLog.WriteLine("Trimmming finished in {0} seconds.", (end - start).TotalSeconds);
} }
#endregion Trimming #endregion Trimming
#region Error handling #region Error handling
if(resume.BadBlocks.Count > 0 && if(_resume.BadBlocks.Count > 0 &&
!aborted && !_aborted &&
retryPasses > 0) _retryPasses > 0)
{ {
int pass = 1; int pass = 1;
bool forward = true; bool forward = true;
InitProgress?.Invoke(); InitProgress?.Invoke();
repeatRetryLba: repeatRetryLba:
ulong[] tmpArray = resume.BadBlocks.ToArray(); ulong[] tmpArray = _resume.BadBlocks.ToArray();
foreach(ulong badSector in tmpArray) foreach(ulong badSector in tmpArray)
{ {
if(aborted) if(_aborted)
{ {
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
break; break;
} }
PulseProgress?.Invoke(string.Format("Retrying sector {0}, pass {1}, {3}{2}", badSector, PulseProgress?.Invoke(string.Format("Retrying sector {0}, pass {1}, {3}{2}", badSector,
pass, forward ? "forward" : "reverse", pass, forward ? "forward" : "reverse",
persistent ? "recovering partial data, " : "")); _persistent ? "recovering partial data, " : ""));
bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration); bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration);
@@ -427,24 +427,24 @@ namespace DiscImageChef.Core.Devices.Dumping
if(!error) if(!error)
{ {
resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
outputPlugin.WriteSector(cmdBuf, badSector); _outputPlugin.WriteSector(cmdBuf, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(persistent) else if(_persistent)
outputPlugin.WriteSector(cmdBuf, badSector); _outputPlugin.WriteSector(cmdBuf, badSector);
} }
if(pass < retryPasses && if(pass < _retryPasses &&
!aborted && !_aborted &&
resume.BadBlocks.Count > 0) _resume.BadBlocks.Count > 0)
{ {
pass++; pass++;
forward = !forward; forward = !forward;
resume.BadBlocks.Sort(); _resume.BadBlocks.Sort();
resume.BadBlocks.Reverse(); _resume.BadBlocks.Reverse();
goto repeatRetryLba; goto repeatRetryLba;
} }
@@ -457,8 +457,8 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
else else
{ {
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);
ulong currentBlock = 0; ulong currentBlock = 0;
blocks = (ulong)(cylinders * heads * sectors); blocks = (ulong)(cylinders * heads * sectors);
@@ -473,11 +473,11 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
for(byte sc = 1; sc < sectors; sc++) for(byte sc = 1; sc < sectors; sc++)
{ {
if(aborted) if(_aborted)
{ {
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
break; break;
} }
@@ -505,25 +505,25 @@ namespace DiscImageChef.Core.Devices.Dumping
ibgLog.Write(currentBlock, currentSpeed * 1024); ibgLog.Write(currentBlock, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSector(cmdBuf, _outputPlugin.WriteSector(cmdBuf,
(ulong)((cy * heads + hd) * sectors + (sc - 1))); (ulong)((((cy * heads) + hd) * sectors) + (sc - 1)));
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(currentBlock); extents.Add(currentBlock);
dumpLog.WriteLine("Error reading cylinder {0} head {1} sector {2}.", cy, hd, _dumpLog.WriteLine("Error reading cylinder {0} head {1} sector {2}.", cy, hd,
sc); sc);
} }
else else
{ {
resume.BadBlocks.Add(currentBlock); _resume.BadBlocks.Add(currentBlock);
mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration); mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration);
ibgLog.Write(currentBlock, 0); ibgLog.Write(currentBlock, 0);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSector(new byte[blockSize], _outputPlugin.WriteSector(new byte[blockSize],
(ulong)((cy * heads + hd) * sectors + (sc - 1))); (ulong)((((cy * heads) + hd) * sectors) + (sc - 1)));
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
} }
@@ -536,7 +536,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(elapsed < 1) if(elapsed < 1)
continue; continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed); currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }
@@ -547,47 +547,47 @@ namespace DiscImageChef.Core.Devices.Dumping
EndProgress?.Invoke(); EndProgress?.Invoke();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (blockSize * (double)(blocks + 1)) / 1024 /
(totalDuration / 1000), devicePath); (totalDuration / 1000), _devicePath);
UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average dump speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000):F3} KiB/sec."); Invoke($"Average dump speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000):F3} KiB/sec.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average write speed {(double)blockSize * (double)(blocks + 1) / 1024 / (imageWriteDuration / 1000):F3} KiB/sec."); Invoke($"Average write speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (imageWriteDuration / 1000):F3} KiB/sec.");
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds); _dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
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 / ((double)blockSize * (double)(blocks + 1)) / 1024 /
(imageWriteDuration / 1000)); (imageWriteDuration / 1000));
} }
foreach(ulong bad in resume.BadBlocks) foreach(ulong bad in _resume.BadBlocks)
dumpLog.WriteLine("Sector {0} could not be read.", bad); _dumpLog.WriteLine("Sector {0} could not be read.", bad);
outputPlugin.SetDumpHardware(resume.Tries); _outputPlugin.SetDumpHardware(_resume.Tries);
if(preSidecar != null) if(_preSidecar != null)
outputPlugin.SetCicmMetadata(preSidecar); _outputPlugin.SetCicmMetadata(_preSidecar);
dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
outputPlugin.Close(); _outputPlugin.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);
if(aborted) if(_aborted)
{ {
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
return; return;
@@ -595,12 +595,12 @@ namespace DiscImageChef.Core.Devices.Dumping
double totalChkDuration = 0; double totalChkDuration = 0;
if(!nometadata) if(!_nometadata)
{ {
dumpLog.WriteLine("Creating sidecar."); _dumpLog.WriteLine("Creating sidecar.");
UpdateStatus?.Invoke("Creating sidecar."); UpdateStatus?.Invoke("Creating sidecar.");
var filters = new FiltersList(); var filters = new FiltersList();
IFilter filter = filters.GetFilter(outputPath); IFilter filter = filters.GetFilter(_outputPath);
IMediaImage inputPlugin = ImageFormat.Detect(filter); IMediaImage inputPlugin = ImageFormat.Detect(filter);
if(!inputPlugin.Open(filter)) if(!inputPlugin.Open(filter))
@@ -611,60 +611,64 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
DateTime chkStart = DateTime.UtcNow; DateTime chkStart = DateTime.UtcNow;
sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding);
sidecarClass.InitProgressEvent += InitProgress;
sidecarClass.UpdateProgressEvent += UpdateProgress;
sidecarClass.EndProgressEvent += EndProgress;
sidecarClass.InitProgressEvent2 += InitProgress2;
sidecarClass.UpdateProgressEvent2 += UpdateProgress2;
sidecarClass.EndProgressEvent2 += EndProgress2;
sidecarClass.UpdateStatusEvent += UpdateStatus;
CICMMetadataType sidecar = sidecarClass.Create();
if(preSidecar != null) _sidecarClass =
new Sidecar(inputPlugin, _outputPath, filter.Id, _encoding);
_sidecarClass.InitProgressEvent += InitProgress;
_sidecarClass.UpdateProgressEvent += UpdateProgress;
_sidecarClass.EndProgressEvent += EndProgress;
_sidecarClass.InitProgressEvent2 += InitProgress2;
_sidecarClass.UpdateProgressEvent2 += UpdateProgress2;
_sidecarClass.EndProgressEvent2 += EndProgress2;
_sidecarClass.UpdateStatusEvent += UpdateStatus;
CICMMetadataType sidecar = _sidecarClass.Create();
if(_preSidecar != null)
{ {
preSidecar.BlockMedia = sidecar.BlockMedia; _preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = preSidecar; sidecar = _preSidecar;
} }
if(dev.IsUsb && if(_dev.IsUsb &&
dev.UsbDescriptors != null) _dev.UsbDescriptors != null)
{ {
dumpLog.WriteLine("Reading USB descriptors."); _dumpLog.WriteLine("Reading USB descriptors.");
UpdateStatus?.Invoke("Reading USB descriptors."); UpdateStatus?.Invoke("Reading USB descriptors.");
ret = outputPlugin.WriteMediaTag(dev.UsbDescriptors, MediaTagType.USB_Descriptors); ret = _outputPlugin.WriteMediaTag(_dev.UsbDescriptors, MediaTagType.USB_Descriptors);
if(ret) if(ret)
sidecar.BlockMedia[0].USB = new USBType sidecar.BlockMedia[0].USB = new USBType
{ {
ProductID = dev.UsbProductId, VendorID = dev.UsbVendorId, Descriptors = new DumpType ProductID = _dev.UsbProductId, VendorID = _dev.UsbVendorId, Descriptors =
{ new DumpType
Image = outputPath, Size = (ulong)dev.UsbDescriptors.Length, {
Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray() Image = _outputPath, Size = (ulong)_dev.UsbDescriptors.Length,
} Checksums = Checksum.GetChecksums(_dev.UsbDescriptors).ToArray()
}
}; };
} }
if(dev.IsPcmcia && if(_dev.IsPcmcia &&
dev.Cis != null) _dev.Cis != null)
{ {
dumpLog.WriteLine("Reading PCMCIA CIS."); _dumpLog.WriteLine("Reading PCMCIA CIS.");
UpdateStatus?.Invoke("Reading PCMCIA CIS."); UpdateStatus?.Invoke("Reading PCMCIA CIS.");
ret = outputPlugin.WriteMediaTag(dev.Cis, MediaTagType.PCMCIA_CIS); ret = _outputPlugin.WriteMediaTag(_dev.Cis, MediaTagType.PCMCIA_CIS);
if(ret) if(ret)
sidecar.BlockMedia[0].PCMCIA = new PCMCIAType sidecar.BlockMedia[0].PCMCIA = new PCMCIAType
{ {
CIS = new DumpType CIS = new DumpType
{ {
Image = outputPath, Size = (ulong)dev.Cis.Length, Image = _outputPath, Size = (ulong)_dev.Cis.Length,
Checksums = Checksum.GetChecksums(dev.Cis).ToArray() Checksums = Checksum.GetChecksums(_dev.Cis).ToArray()
} }
}; };
dumpLog.WriteLine("Decoding PCMCIA CIS."); _dumpLog.WriteLine("Decoding PCMCIA CIS.");
UpdateStatus?.Invoke("Decoding PCMCIA CIS."); UpdateStatus?.Invoke("Decoding PCMCIA CIS.");
Tuple[] tuples = CIS.GetTuples(dev.Cis); Tuple[] tuples = CIS.GetTuples(_dev.Cis);
if(tuples != null) if(tuples != null)
foreach(Tuple tuple in tuples) foreach(Tuple tuple in tuples)
@@ -676,8 +680,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(manfid != null) if(manfid != null)
{ {
sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = manfid.ManufacturerID;
manfid.ManufacturerID;
sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID; sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID;
sidecar.BlockMedia[0].PCMCIA.ManufacturerCodeSpecified = true; sidecar.BlockMedia[0].PCMCIA.ManufacturerCodeSpecified = true;
@@ -704,14 +707,14 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
} }
ret = outputPlugin.WriteMediaTag(ataIdentify, MediaTagType.ATA_IDENTIFY); ret = _outputPlugin.WriteMediaTag(ataIdentify, MediaTagType.ATA_IDENTIFY);
if(ret) if(ret)
sidecar.BlockMedia[0].ATA = new ATAType sidecar.BlockMedia[0].ATA = new ATAType
{ {
Identify = new DumpType Identify = new DumpType
{ {
Image = outputPath, Size = (ulong)cmdBuf.Length, Image = _outputPath, Size = (ulong)cmdBuf.Length,
Checksums = Checksum.GetChecksums(cmdBuf).ToArray() Checksums = Checksum.GetChecksums(cmdBuf).ToArray()
} }
}; };
@@ -722,12 +725,13 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke($"Sidecar created in {(chkEnd - chkStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Sidecar created in {(chkEnd - chkStart).TotalSeconds} seconds.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average checksum speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000):F3} KiB/sec."); Invoke($"Average checksum speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (totalChkDuration / 1000):F3} KiB/sec.");
dumpLog.WriteLine("Sidecar created in {0} seconds.", (chkEnd - chkStart).TotalSeconds); _dumpLog.WriteLine("Sidecar created in {0} seconds.", (chkEnd - chkStart).TotalSeconds);
dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", _dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); ((double)blockSize * (double)(blocks + 1)) / 1024 /
(totalChkDuration / 1000));
List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>();
@@ -746,15 +750,15 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?. UpdateStatus?.
Invoke($"Found filesystem {filesystem.type} at sector {filesystem.start}"); Invoke($"Found filesystem {filesystem.type} at sector {filesystem.start}");
dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, _dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type,
filesystem.start); filesystem.start);
} }
(string type, string subType) xmlType; (string type, string subType) xmlType;
if(dev.IsCompactFlash) if(_dev.IsCompactFlash)
xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.CompactFlash); xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.CompactFlash);
else if(dev.IsPcmcia) else if(_dev.IsPcmcia)
xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.PCCardTypeI); xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.PCCardTypeI);
else else
xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.GENERIC_HDD); xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.GENERIC_HDD);
@@ -765,9 +769,9 @@ namespace DiscImageChef.Core.Devices.Dumping
sidecar.BlockMedia[0].LogicalBlocks = blocks; sidecar.BlockMedia[0].LogicalBlocks = blocks;
sidecar.BlockMedia[0].PhysicalBlockSize = physicalsectorsize; sidecar.BlockMedia[0].PhysicalBlockSize = physicalsectorsize;
sidecar.BlockMedia[0].LogicalBlockSize = blockSize; sidecar.BlockMedia[0].LogicalBlockSize = blockSize;
sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer; sidecar.BlockMedia[0].Manufacturer = _dev.Manufacturer;
sidecar.BlockMedia[0].Model = dev.Model; sidecar.BlockMedia[0].Model = _dev.Model;
sidecar.BlockMedia[0].Serial = dev.Serial; sidecar.BlockMedia[0].Serial = _dev.Serial;
sidecar.BlockMedia[0].Size = blocks * blockSize; sidecar.BlockMedia[0].Size = blocks * blockSize;
if(cylinders > 0 && if(cylinders > 0 &&
@@ -784,7 +788,7 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke("Writing metadata sidecar"); UpdateStatus?.Invoke("Writing metadata sidecar");
var xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); var xmlFs = new FileStream(_outputPrefix + ".cicm.xml", FileMode.Create);
var xmlSer = new XmlSerializer(typeof(CICMMetadataType)); var xmlSer = new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar); xmlSer.Serialize(xmlFs, sidecar);
@@ -797,21 +801,21 @@ namespace DiscImageChef.Core.Devices.Dumping
Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing)."); Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing).");
UpdateStatus?. UpdateStatus?.
Invoke($"Average speed: {(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000):F3} MiB/sec."); Invoke($"Average speed: {((double)blockSize * (double)(blocks + 1)) / 1048576 / (totalDuration / 1000):F3} MiB/sec.");
UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec."); UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec.");
UpdateStatus?.Invoke($"Slowest speed burst: {minSpeed:F3} MiB/sec."); UpdateStatus?.Invoke($"Slowest speed burst: {minSpeed:F3} MiB/sec.");
UpdateStatus?.Invoke($"{resume.BadBlocks.Count} sectors could not be read."); UpdateStatus?.Invoke($"{_resume.BadBlocks.Count} sectors could not be read.");
if(resume.BadBlocks.Count > 0) if(_resume.BadBlocks.Count > 0)
resume.BadBlocks.Sort(); _resume.BadBlocks.Sort();
UpdateStatus?.Invoke(""); UpdateStatus?.Invoke("");
} }
if(dev.IsCompactFlash) if(_dev.IsCompactFlash)
Statistics.AddMedia(MediaType.CompactFlash, true); Statistics.AddMedia(MediaType.CompactFlash, true);
else if(dev.IsPcmcia) else if(_dev.IsPcmcia)
Statistics.AddMedia(MediaType.PCCardTypeI, true); Statistics.AddMedia(MediaType.PCCardTypeI, true);
else else
Statistics.AddMedia(MediaType.GENERIC_HDD, true); Statistics.AddMedia(MediaType.GENERIC_HDD, true);

File diff suppressed because it is too large Load Diff

View File

@@ -14,32 +14,30 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
public partial class Dump public partial class Dump
{ {
readonly Device dev; readonly Device _dev;
readonly string devicePath; readonly string _devicePath;
readonly bool doResume; readonly bool _doResume;
readonly DumpLog dumpLog; readonly DumpLog _dumpLog;
readonly bool dumpRaw; readonly bool _dumpRaw;
readonly Encoding encoding; readonly Encoding _encoding;
readonly bool force; readonly bool _force;
readonly Dictionary<string, string> formatOptions; readonly Dictionary<string, string> _formatOptions;
readonly bool nometadata; readonly bool _nometadata;
readonly bool notrim; readonly bool _notrim;
readonly string outputPath; readonly string _outputPath;
readonly IWritableImage outputPlugin; readonly IWritableImage _outputPlugin;
readonly string outputPrefix; readonly string _outputPrefix;
readonly bool persistent; readonly bool _persistent;
readonly CICMMetadataType preSidecar; readonly CICMMetadataType _preSidecar;
readonly ushort retryPasses; readonly ushort _retryPasses;
readonly bool stopOnError; readonly bool _stopOnError;
bool aborted; bool _aborted;
bool dumpFirstTrackPregap; bool _dumpFirstTrackPregap;
Resume resume; Resume _resume;
Sidecar sidecarClass; Sidecar _sidecarClass;
uint skip; uint _skip;
/// <summary> /// <summary>Initializes dumpers</summary>
/// Initializes dumpers
/// </summary>
/// <param name="doResume">Should resume?</param> /// <param name="doResume">Should resume?</param>
/// <param name="dev">Device</param> /// <param name="dev">Device</param>
/// <param name="devicePath">Path to the device</param> /// <param name="devicePath">Path to the device</param>
@@ -60,130 +58,113 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <param name="preSidecar">Sidecar to store in dumped image</param> /// <param name="preSidecar">Sidecar to store in dumped image</param>
/// <param name="skip">How many sectors to skip reading on error</param> /// <param name="skip">How many sectors to skip reading on error</param>
/// <param name="nometadata">Create metadata sidecar after dump?</param> /// <param name="nometadata">Create metadata sidecar after dump?</param>
public Dump(bool doResume, Device dev, string devicePath, public Dump(bool doResume, Device dev, string devicePath, IWritableImage outputPlugin, ushort retryPasses,
IWritableImage outputPlugin, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, Resume resume, DumpLog dumpLog,
bool force, bool dumpRaw, bool persistent, Encoding encoding, string outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
bool stopOnError, Resume resume, DumpLog dumpLog, CICMMetadataType preSidecar, uint skip, bool nometadata, bool notrim, bool dumpFirstTrackPregap)
Encoding encoding, string outputPrefix, string outputPath,
Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar, uint skip, bool nometadata,
bool notrim, bool dumpFirstTrackPregap)
{ {
this.doResume = doResume; _doResume = doResume;
this.dev = dev; _dev = dev;
this.devicePath = devicePath; _devicePath = devicePath;
this.outputPlugin = outputPlugin; _outputPlugin = outputPlugin;
this.retryPasses = retryPasses; _retryPasses = retryPasses;
this.force = force; _force = force;
this.dumpRaw = dumpRaw; _dumpRaw = dumpRaw;
this.persistent = persistent; _persistent = persistent;
this.stopOnError = stopOnError; _stopOnError = stopOnError;
this.resume = resume; _resume = resume;
this.dumpLog = dumpLog; _dumpLog = dumpLog;
this.encoding = encoding; _encoding = encoding;
this.outputPrefix = outputPrefix; _outputPrefix = outputPrefix;
this.outputPath = outputPath; _outputPath = outputPath;
this.formatOptions = formatOptions; _formatOptions = formatOptions;
this.preSidecar = preSidecar; _preSidecar = preSidecar;
this.skip = skip; _skip = skip;
this.nometadata = nometadata; _nometadata = nometadata;
this.notrim = notrim; _notrim = notrim;
this.dumpFirstTrackPregap = dumpFirstTrackPregap; _dumpFirstTrackPregap = dumpFirstTrackPregap;
aborted = false; _aborted = false;
} }
/// <summary> /// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>
/// Starts dumping with the stablished fields and autodetecting the device type
/// </summary>
public void Start() public void Start()
{ {
if(dev.IsUsb && dev.UsbVendorId == 0x054C && if(_dev.IsUsb &&
(dev.UsbProductId == 0x01C8 || dev.UsbProductId == 0x01C9 || dev.UsbProductId == 0x02D2)) _dev.UsbVendorId == 0x054C &&
(_dev.UsbProductId == 0x01C8 || _dev.UsbProductId == 0x01C9 || _dev.UsbProductId == 0x02D2))
PlayStationPortable(); PlayStationPortable();
else else
switch(dev.Type) switch(_dev.Type)
{ {
case DeviceType.ATA: case DeviceType.ATA:
Ata(); Ata();
break; break;
case DeviceType.MMC: case DeviceType.MMC:
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
SecureDigital(); SecureDigital();
break; break;
case DeviceType.NVMe: case DeviceType.NVMe:
NVMe(); NVMe();
break; break;
case DeviceType.ATAPI: case DeviceType.ATAPI:
case DeviceType.SCSI: case DeviceType.SCSI:
Scsi(); Scsi();
break; break;
default: default:
dumpLog.WriteLine("Unknown device type."); _dumpLog.WriteLine("Unknown device type.");
dumpLog.Close(); _dumpLog.Close();
StoppingErrorMessage?.Invoke("Unknown device type."); StoppingErrorMessage?.Invoke("Unknown device type.");
return; return;
} }
dumpLog.Close(); _dumpLog.Close();
if(resume == null || !doResume) return; if(_resume == null ||
!_doResume)
return;
resume.LastWriteDate = DateTime.UtcNow; _resume.LastWriteDate = DateTime.UtcNow;
resume.BadBlocks.Sort(); _resume.BadBlocks.Sort();
if(File.Exists(outputPrefix + ".resume.xml")) File.Delete(outputPrefix + ".resume.xml"); if(File.Exists(_outputPrefix + ".resume.xml"))
File.Delete(_outputPrefix + ".resume.xml");
FileStream fs = new FileStream(outputPrefix + ".resume.xml", FileMode.Create, FileAccess.ReadWrite); var fs = new FileStream(_outputPrefix + ".resume.xml", FileMode.Create, FileAccess.ReadWrite);
XmlSerializer xs = new XmlSerializer(resume.GetType()); var xs = new XmlSerializer(_resume.GetType());
xs.Serialize(fs, resume); xs.Serialize(fs, _resume);
fs.Close(); fs.Close();
} }
public void Abort() public void Abort()
{ {
aborted = true; _aborted = true;
sidecarClass?.Abort(); _sidecarClass?.Abort();
} }
/// <summary> /// <summary>Event raised when the progress bar is not longer needed</summary>
/// Event raised when the progress bar is not longer needed
/// </summary>
public event EndProgressHandler EndProgress; public event EndProgressHandler EndProgress;
/// <summary> /// <summary>Event raised when a progress bar is needed</summary>
/// Event raised when a progress bar is needed
/// </summary>
public event InitProgressHandler InitProgress; public event InitProgressHandler InitProgress;
/// <summary> /// <summary>Event raised to report status updates</summary>
/// Event raised to report status updates
/// </summary>
public event UpdateStatusHandler UpdateStatus; public event UpdateStatusHandler UpdateStatus;
/// <summary> /// <summary>Event raised to report a non-fatal error</summary>
/// Event raised to report a non-fatal error
/// </summary>
public event ErrorMessageHandler ErrorMessage; public event ErrorMessageHandler ErrorMessage;
/// <summary> /// <summary>Event raised to report a fatal error that stops the dumping operation and should call user's attention</summary>
/// Event raised to report a fatal error that stops the dumping operation and should call user's attention
/// </summary>
public event ErrorMessageHandler StoppingErrorMessage; public event ErrorMessageHandler StoppingErrorMessage;
/// <summary> /// <summary>Event raised to update the values of a determinate progress bar</summary>
/// Event raised to update the values of a determinate progress bar
/// </summary>
public event UpdateProgressHandler UpdateProgress; public event UpdateProgressHandler UpdateProgress;
/// <summary> /// <summary>Event raised to update the status of an undeterminate progress bar</summary>
/// Event raised to update the status of an undeterminate progress bar
/// </summary>
public event PulseProgressHandler PulseProgress; public event PulseProgressHandler PulseProgress;
/// <summary> /// <summary>Event raised when the progress bar is not longer needed</summary>
/// Event raised when the progress bar is not longer needed
/// </summary>
public event EndProgressHandler2 EndProgress2; public event EndProgressHandler2 EndProgress2;
/// <summary> /// <summary>Event raised when a progress bar is needed</summary>
/// Event raised when a progress bar is needed
/// </summary>
public event InitProgressHandler2 InitProgress2; public event InitProgressHandler2 InitProgress2;
/// <summary> /// <summary>Event raised to update the values of a determinate progress bar</summary>
/// Event raised to update the values of a determinate progress bar
/// </summary>
public event UpdateProgressHandler2 UpdateProgress2; public event UpdateProgressHandler2 UpdateProgress2;
} }
} }

View File

@@ -58,13 +58,13 @@ namespace DiscImageChef.Core.Devices.Dumping
bool isXbox = false; bool isXbox = false;
// TODO: Log not only what is it reading, but if it was read correctly or not. // TODO: Log not only what is it reading, but if it was read correctly or not.
sense = dev.GetConfiguration(out byte[] cmdBuf, out _, 0, MmcGetConfigurationRt.Current, dev.Timeout, sense = _dev.GetConfiguration(out byte[] cmdBuf, out _, 0, MmcGetConfigurationRt.Current, _dev.Timeout,
out _); out _);
if(!sense) if(!sense)
{ {
Features.SeparatedFeatures ftr = Features.Separate(cmdBuf); Features.SeparatedFeatures ftr = Features.Separate(cmdBuf);
dumpLog.WriteLine("Device reports current profile is 0x{0:X4}", ftr.CurrentProfile); _dumpLog.WriteLine("Device reports current profile is 0x{0:X4}", ftr.CurrentProfile);
switch(ftr.CurrentProfile) switch(ftr.CurrentProfile)
{ {
@@ -176,9 +176,9 @@ namespace DiscImageChef.Core.Devices.Dumping
return; return;
} }
var scsiReader = new Reader(dev, dev.Timeout, null, dumpRaw); var scsiReader = new Reader(_dev, _dev.Timeout, null, _dumpRaw);
ulong blocks = scsiReader.GetDeviceBlocks(); ulong blocks = scsiReader.GetDeviceBlocks();
dumpLog.WriteLine("Device reports disc has {0} blocks", blocks); _dumpLog.WriteLine("Device reports disc has {0} blocks", blocks);
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>();
if(dskType == MediaType.PD650) if(dskType == MediaType.PD650)
@@ -208,10 +208,10 @@ namespace DiscImageChef.Core.Devices.Dumping
switch(dskType) switch(dskType)
{ {
case MediaType.Unknown when blocks > 0: case MediaType.Unknown when blocks > 0:
dumpLog.WriteLine("Reading Physical Format Information"); _dumpLog.WriteLine("Reading Physical Format Information");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out _); MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -221,7 +221,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(nintendoPfi.Value.DiskCategory == DiskCategory.Nintendo && if(nintendoPfi.Value.DiskCategory == DiskCategory.Nintendo &&
nintendoPfi.Value.PartVersion == 15) nintendoPfi.Value.PartVersion == 15)
{ {
dumpLog.WriteLine("Dumping Nintendo GameCube or Wii discs is not yet implemented."); _dumpLog.WriteLine("Dumping Nintendo GameCube or Wii discs is not yet implemented.");
StoppingErrorMessage?. StoppingErrorMessage?.
Invoke("Dumping Nintendo GameCube or Wii discs is not yet implemented."); Invoke("Dumping Nintendo GameCube or Wii discs is not yet implemented.");
@@ -248,10 +248,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.HDDVDROM: case MediaType.HDDVDROM:
case MediaType.HDDVDRW: case MediaType.HDDVDRW:
case MediaType.HDDVDRWDL: case MediaType.HDDVDRWDL:
dumpLog.WriteLine("Reading Physical Format Information"); _dumpLog.WriteLine("Reading Physical Format Information");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out _); MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
if(PFI.Decode(cmdBuf).HasValue) if(PFI.Decode(cmdBuf).HasValue)
@@ -326,11 +326,11 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
} }
dumpLog.WriteLine("Reading Disc Manufacturing Information"); _dumpLog.WriteLine("Reading Disc Manufacturing Information");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DiscManufacturingInformation, 0, dev.Timeout, MmcDiscStructureFormat.DiscManufacturingInformation, 0, _dev.Timeout,
out _); out _);
if(!sense) if(!sense)
{ {
@@ -352,13 +352,13 @@ namespace DiscImageChef.Core.Devices.Dumping
dskType = MediaType.XGD3; dskType = MediaType.XGD3;
} }
sense = dev.ScsiInquiry(out byte[] inqBuf, out _); sense = _dev.ScsiInquiry(out byte[] inqBuf, out _);
if(sense || if(sense ||
!Inquiry.Decode(inqBuf).HasValue || !Inquiry.Decode(inqBuf).HasValue ||
(Inquiry.Decode(inqBuf).HasValue && !Inquiry.Decode(inqBuf).Value.KreonPresent)) (Inquiry.Decode(inqBuf).HasValue && !Inquiry.Decode(inqBuf).Value.KreonPresent))
{ {
dumpLog.WriteLine("Dumping Xbox Game Discs requires a drive with Kreon firmware."); _dumpLog.WriteLine("Dumping Xbox Game Discs requires a drive with Kreon firmware.");
StoppingErrorMessage?. StoppingErrorMessage?.
Invoke("Dumping Xbox Game Discs requires a drive with Kreon firmware."); Invoke("Dumping Xbox Game Discs requires a drive with Kreon firmware.");
@@ -366,7 +366,7 @@ namespace DiscImageChef.Core.Devices.Dumping
return; return;
} }
if(dumpRaw && !force) if(_dumpRaw && !_force)
{ {
StoppingErrorMessage?. StoppingErrorMessage?.
Invoke("Not continuing. If you want to continue reading cooked data when raw is not available use the force option."); Invoke("Not continuing. If you want to continue reading cooked data when raw is not available use the force option.");
@@ -397,10 +397,10 @@ namespace DiscImageChef.Core.Devices.Dumping
if(dskType == MediaType.DVDDownload || if(dskType == MediaType.DVDDownload ||
dskType == MediaType.DVDROM) dskType == MediaType.DVDROM)
{ {
dumpLog.WriteLine("Reading Lead-in Copyright Information."); _dumpLog.WriteLine("Reading Lead-in Copyright Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.CopyrightInformation, 0, dev.Timeout, out _); MmcDiscStructureFormat.CopyrightInformation, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
if(CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue) if(CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue)
@@ -418,10 +418,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.DVDDownload: case MediaType.DVDDownload:
case MediaType.DVDROM: case MediaType.DVDROM:
case MediaType.HDDVDROM: case MediaType.HDDVDROM:
dumpLog.WriteLine("Reading Burst Cutting Area."); _dumpLog.WriteLine("Reading Burst Cutting Area.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.BurstCuttingArea, 0, dev.Timeout, out _); MmcDiscStructureFormat.BurstCuttingArea, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -436,10 +436,10 @@ namespace DiscImageChef.Core.Devices.Dumping
#region DVD-RAM and HD DVD-RAM #region DVD-RAM and HD DVD-RAM
case MediaType.DVDRAM: case MediaType.DVDRAM:
case MediaType.HDDVDRAM: case MediaType.HDDVDRAM:
dumpLog.WriteLine("Reading Disc Description Structure."); _dumpLog.WriteLine("Reading Disc Description Structure.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdramDds, 0, dev.Timeout, out _); MmcDiscStructureFormat.DvdramDds, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
if(DDS.Decode(cmdBuf).HasValue) if(DDS.Decode(cmdBuf).HasValue)
@@ -449,11 +449,11 @@ namespace DiscImageChef.Core.Devices.Dumping
mediaTags.Add(MediaTagType.DVDRAM_DDS, tmpBuf); mediaTags.Add(MediaTagType.DVDRAM_DDS, tmpBuf);
} }
dumpLog.WriteLine("Reading Spare Area Information."); _dumpLog.WriteLine("Reading Spare Area Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, dev.Timeout, MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, _dev.Timeout,
out _); out _);
if(!sense) if(!sense)
if(Spare.Decode(cmdBuf).HasValue) if(Spare.Decode(cmdBuf).HasValue)
@@ -469,10 +469,10 @@ namespace DiscImageChef.Core.Devices.Dumping
#region DVD-R and DVD-RW #region DVD-R and DVD-RW
case MediaType.DVDR: case MediaType.DVDR:
case MediaType.DVDRW: case MediaType.DVDRW:
dumpLog.WriteLine("Reading Pre-Recorded Information."); _dumpLog.WriteLine("Reading Pre-Recorded Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PreRecordedInfo, 0, dev.Timeout, out _); MmcDiscStructureFormat.PreRecordedInfo, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -491,10 +491,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.DVDR: case MediaType.DVDR:
case MediaType.DVDRW: case MediaType.DVDRW:
case MediaType.HDDVDR: case MediaType.HDDVDR:
dumpLog.WriteLine("Reading Media Identifier."); _dumpLog.WriteLine("Reading Media Identifier.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdrMediaIdentifier, 0, dev.Timeout, out _); MmcDiscStructureFormat.DvdrMediaIdentifier, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -503,11 +503,11 @@ namespace DiscImageChef.Core.Devices.Dumping
mediaTags.Add(MediaTagType.DVDR_MediaIdentifier, tmpBuf); mediaTags.Add(MediaTagType.DVDR_MediaIdentifier, tmpBuf);
} }
dumpLog.WriteLine("Reading Recordable Physical Information."); _dumpLog.WriteLine("Reading Recordable Physical Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdrPhysicalInformation, 0, dev.Timeout, MmcDiscStructureFormat.DvdrPhysicalInformation, 0, _dev.Timeout,
out _); out _);
if(!sense) if(!sense)
{ {
@@ -524,10 +524,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.DVDPRDL: case MediaType.DVDPRDL:
case MediaType.DVDPRW: case MediaType.DVDPRW:
case MediaType.DVDPRWDL: case MediaType.DVDPRWDL:
dumpLog.WriteLine("Reading ADdress In Pregroove."); _dumpLog.WriteLine("Reading ADdress In Pregroove.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.Adip, 0, dev.Timeout, out _); MmcDiscStructureFormat.Adip, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -536,10 +536,10 @@ namespace DiscImageChef.Core.Devices.Dumping
mediaTags.Add(MediaTagType.DVD_ADIP, tmpBuf); mediaTags.Add(MediaTagType.DVD_ADIP, tmpBuf);
} }
dumpLog.WriteLine("Reading Disc Control Blocks."); _dumpLog.WriteLine("Reading Disc Control Blocks.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.Dcb, 0, dev.Timeout, out _); MmcDiscStructureFormat.Dcb, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -553,11 +553,11 @@ namespace DiscImageChef.Core.Devices.Dumping
#region HD DVD-ROM #region HD DVD-ROM
case MediaType.HDDVDROM: case MediaType.HDDVDROM:
dumpLog.WriteLine("Reading Lead-in Copyright Information."); _dumpLog.WriteLine("Reading Lead-in Copyright Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.HddvdCopyrightInformation, 0, dev.Timeout, MmcDiscStructureFormat.HddvdCopyrightInformation, 0, _dev.Timeout,
out _); out _);
if(!sense) if(!sense)
{ {
@@ -575,10 +575,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.BDROM: case MediaType.BDROM:
case MediaType.BDRXL: case MediaType.BDRXL:
case MediaType.BDREXL: case MediaType.BDREXL:
dumpLog.WriteLine("Reading Disc Information."); _dumpLog.WriteLine("Reading Disc Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.DiscInformation, 0, dev.Timeout, out _); MmcDiscStructureFormat.DiscInformation, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
if(DI.Decode(cmdBuf).HasValue) if(DI.Decode(cmdBuf).HasValue)
@@ -607,10 +607,10 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
#region BD-ROM only #region BD-ROM only
case MediaType.BDROM: case MediaType.BDROM:
dumpLog.WriteLine("Reading Burst Cutting Area."); _dumpLog.WriteLine("Reading Burst Cutting Area.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.BdBurstCuttingArea, 0, dev.Timeout, out _); MmcDiscStructureFormat.BdBurstCuttingArea, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -627,10 +627,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.BDRE: case MediaType.BDRE:
case MediaType.BDRXL: case MediaType.BDRXL:
case MediaType.BDREXL: case MediaType.BDREXL:
dumpLog.WriteLine("Reading Disc Definition Structure."); _dumpLog.WriteLine("Reading Disc Definition Structure.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.BdDds, 0, dev.Timeout, out _); MmcDiscStructureFormat.BdDds, 0, _dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -639,10 +639,11 @@ namespace DiscImageChef.Core.Devices.Dumping
mediaTags.Add(MediaTagType.BD_DDS, tmpBuf); mediaTags.Add(MediaTagType.BD_DDS, tmpBuf);
} }
dumpLog.WriteLine("Reading Spare Area Information."); _dumpLog.WriteLine("Reading Spare Area Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.BdSpareAreaInformation, 0, dev.Timeout, out _); MmcDiscStructureFormat.BdSpareAreaInformation, 0, _dev.Timeout,
out _);
if(!sense) if(!sense)
{ {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -37,59 +37,66 @@ using DiscImageChef.Decoders.SCSI;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary> /// <summary>Implements dumping SCSI and ATAPI devices</summary>
/// Implements dumping SCSI and ATAPI devices
/// </summary>
public partial class Dump public partial class Dump
{ {
// TODO: Get cartridge serial number from Certance vendor EVPD // TODO: Get cartridge serial number from Certance vendor EVPD
/// <summary> /// <summary>Dumps a SCSI Block Commands device or a Reduced Block Commands devices</summary>
/// Dumps a SCSI Block Commands device or a Reduced Block Commands devices
/// </summary>
public void Scsi() public void Scsi()
{ {
MediaType dskType = MediaType.Unknown; MediaType dskType = MediaType.Unknown;
int resets = 0; int resets = 0;
if(dev.IsRemovable) if(_dev.IsRemovable)
{ {
InitProgress?.Invoke(); InitProgress?.Invoke();
deviceGotReset: deviceGotReset:
bool sense = dev.ScsiTestUnitReady(out byte[] senseBuf, dev.Timeout, out _); bool sense = _dev.ScsiTestUnitReady(out byte[] senseBuf, _dev.Timeout, out _);
if(sense) if(sense)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuf); FixedSense? decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {
ErrorMessage ErrorMessage?.
?.Invoke($"Device not ready. Sense {decSense.Value.SenseKey} ASC {decSense.Value.ASC:X2}h ASCQ {decSense.Value.ASCQ:X2}h"); Invoke($"Device not ready. Sense {decSense.Value.SenseKey} ASC {decSense.Value.ASC:X2}h ASCQ {decSense.Value.ASCQ:X2}h");
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ); _dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
// Just retry, for 5 times // Just retry, for 5 times
if(decSense.Value.ASC == 0x29) if(decSense.Value.ASC == 0x29)
{ {
resets++; resets++;
if(resets < 5) goto deviceGotReset;
if(resets < 5)
goto deviceGotReset;
} }
if(decSense.Value.ASC == 0x3A) if(decSense.Value.ASC == 0x3A)
{ {
int leftRetries = 5; int leftRetries = 5;
while(leftRetries > 0) while(leftRetries > 0)
{ {
PulseProgress?.Invoke("Waiting for drive to become ready"); PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _); sense = _dev.ScsiTestUnitReady(out senseBuf, _dev.Timeout, out _);
if(!sense) break;
if(!sense)
break;
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {
ErrorMessage ErrorMessage?.
?.Invoke($"Device not ready. Sense {decSense.Value.SenseKey} ASC {decSense.Value.ASC:X2}h ASCQ {decSense.Value.ASCQ:X2}h"); Invoke($"Device not ready. Sense {decSense.Value.SenseKey} ASC {decSense.Value.ASC:X2}h ASCQ {decSense.Value.ASCQ:X2}h");
dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ); _dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC,
decSense.Value.ASCQ);
} }
leftRetries--; leftRetries--;
@@ -98,26 +105,34 @@ namespace DiscImageChef.Core.Devices.Dumping
if(sense) if(sense)
{ {
StoppingErrorMessage?.Invoke("Please insert media in drive"); StoppingErrorMessage?.Invoke("Please insert media in drive");
return; return;
} }
} }
else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) else if(decSense.Value.ASC == 0x04 &&
decSense.Value.ASCQ == 0x01)
{ {
int leftRetries = 50; int leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
PulseProgress?.Invoke("Waiting for drive to become ready"); PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _); sense = _dev.ScsiTestUnitReady(out senseBuf, _dev.Timeout, out _);
if(!sense) break;
if(!sense)
break;
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {
ErrorMessage ErrorMessage?.
?.Invoke($"Device not ready. Sense {decSense.Value.SenseKey} ASC {decSense.Value.ASC:X2}h ASCQ {decSense.Value.ASCQ:X2}h"); Invoke($"Device not ready. Sense {decSense.Value.SenseKey} ASC {decSense.Value.ASC:X2}h ASCQ {decSense.Value.ASCQ:X2}h");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ); _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC,
decSense.Value.ASCQ);
} }
leftRetries--; leftRetries--;
@@ -125,8 +140,9 @@ namespace DiscImageChef.Core.Devices.Dumping
if(sense) if(sense)
{ {
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}"); Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return; return;
} }
} }
@@ -147,20 +163,26 @@ namespace DiscImageChef.Core.Devices.Dumping
else if(decSense.Value.ASC == 0x28) else if(decSense.Value.ASC == 0x28)
{ {
int leftRetries = 10; int leftRetries = 10;
while(leftRetries > 0) while(leftRetries > 0)
{ {
PulseProgress?.Invoke("Waiting for drive to become ready"); PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _); sense = _dev.ScsiTestUnitReady(out senseBuf, _dev.Timeout, out _);
if(!sense) break;
if(!sense)
break;
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {
ErrorMessage ErrorMessage?.
?.Invoke($"Device not ready. Sense {decSense.Value.SenseKey} ASC {decSense.Value.ASC:X2}h ASCQ {decSense.Value.ASCQ:X2}h"); Invoke($"Device not ready. Sense {decSense.Value.SenseKey} ASC {decSense.Value.ASC:X2}h ASCQ {decSense.Value.ASCQ:X2}h");
dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ); _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC,
decSense.Value.ASCQ);
} }
leftRetries--; leftRetries--;
@@ -168,21 +190,24 @@ namespace DiscImageChef.Core.Devices.Dumping
if(sense) if(sense)
{ {
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}"); Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return; return;
} }
} }
else else
{ {
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}"); Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return; return;
} }
} }
else else
{ {
StoppingErrorMessage?.Invoke("Unknown testing unit was ready."); StoppingErrorMessage?.Invoke("Unknown testing unit was ready.");
return; return;
} }
} }
@@ -190,28 +215,34 @@ namespace DiscImageChef.Core.Devices.Dumping
EndProgress?.Invoke(); EndProgress?.Invoke();
} }
switch(dev.ScsiType) switch(_dev.ScsiType)
{ {
case PeripheralDeviceTypes.SequentialAccess: case PeripheralDeviceTypes.SequentialAccess:
if(dumpRaw) if(_dumpRaw)
{ {
StoppingErrorMessage?.Invoke("Tapes cannot be dumped raw."); StoppingErrorMessage?.Invoke("Tapes cannot be dumped raw.");
return; return;
} }
if(outputPlugin is IWritableTapeImage) Ssc(); if(_outputPlugin is IWritableTapeImage)
Ssc();
else else
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke("The specified plugin does not support storing streaming tape images."); Invoke("The specified plugin does not support storing streaming tape images.");
return; return;
case PeripheralDeviceTypes.MultiMediaDevice: case PeripheralDeviceTypes.MultiMediaDevice:
if(outputPlugin is IWritableOpticalImage) Mmc(ref dskType); if(_outputPlugin is IWritableOpticalImage)
Mmc(ref dskType);
else else
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke("The specified plugin does not support storing optical disc images."); Invoke("The specified plugin does not support storing optical disc images.");
return; return;
default: default:
Sbc(null, ref dskType, false); Sbc(null, ref dskType, false);
break; break;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -53,9 +53,9 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <summary>Dumps a MultiMediaCard or SecureDigital flash card</summary> /// <summary>Dumps a MultiMediaCard or SecureDigital flash card</summary>
public void SecureDigital() public void SecureDigital()
{ {
if(dumpRaw) if(_dumpRaw)
{ {
if(force) if(_force)
ErrorMessage?. ErrorMessage?.
Invoke("Raw dumping is not supported in MultiMediaCard or SecureDigital devices. Continuing..."); Invoke("Raw dumping is not supported in MultiMediaCard or SecureDigital devices. Continuing...");
else else
@@ -84,13 +84,13 @@ namespace DiscImageChef.Core.Devices.Dumping
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>();
switch(dev.Type) switch(_dev.Type)
{ {
case DeviceType.MMC: case DeviceType.MMC:
{ {
UpdateStatus?.Invoke("Reading Extended CSD"); UpdateStatus?.Invoke("Reading Extended CSD");
dumpLog.WriteLine("Reading Extended CSD"); _dumpLog.WriteLine("Reading Extended CSD");
sense = dev.ReadExtendedCsd(out ecsd, out _, TIMEOUT, out duration); sense = _dev.ReadExtendedCsd(out ecsd, out _, TIMEOUT, out duration);
if(!sense) if(!sense)
{ {
@@ -112,8 +112,8 @@ namespace DiscImageChef.Core.Devices.Dumping
ecsd = null; ecsd = null;
UpdateStatus?.Invoke("Reading CSD"); UpdateStatus?.Invoke("Reading CSD");
dumpLog.WriteLine("Reading CSD"); _dumpLog.WriteLine("Reading CSD");
sense = dev.ReadCsd(out csd, out _, TIMEOUT, out duration); sense = _dev.ReadCsd(out csd, out _, TIMEOUT, out duration);
if(!sense) if(!sense)
{ {
@@ -130,8 +130,8 @@ namespace DiscImageChef.Core.Devices.Dumping
csd = null; csd = null;
UpdateStatus?.Invoke("Reading OCR"); UpdateStatus?.Invoke("Reading OCR");
dumpLog.WriteLine("Reading OCR"); _dumpLog.WriteLine("Reading OCR");
sense = dev.ReadOcr(out ocr, out _, TIMEOUT, out duration); sense = _dev.ReadOcr(out ocr, out _, TIMEOUT, out duration);
if(sense) if(sense)
ocr = null; ocr = null;
@@ -144,8 +144,8 @@ namespace DiscImageChef.Core.Devices.Dumping
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
{ {
UpdateStatus?.Invoke("Reading CSD"); UpdateStatus?.Invoke("Reading CSD");
dumpLog.WriteLine("Reading CSD"); _dumpLog.WriteLine("Reading CSD");
sense = dev.ReadCsd(out csd, out _, TIMEOUT, out duration); sense = _dev.ReadCsd(out csd, out _, TIMEOUT, out duration);
if(!sense) if(!sense)
{ {
@@ -165,8 +165,8 @@ namespace DiscImageChef.Core.Devices.Dumping
csd = null; csd = null;
UpdateStatus?.Invoke("Reading OCR"); UpdateStatus?.Invoke("Reading OCR");
dumpLog.WriteLine("Reading OCR"); _dumpLog.WriteLine("Reading OCR");
sense = dev.ReadSdocr(out ocr, out _, TIMEOUT, out duration); sense = _dev.ReadSdocr(out ocr, out _, TIMEOUT, out duration);
if(sense) if(sense)
ocr = null; ocr = null;
@@ -174,8 +174,8 @@ namespace DiscImageChef.Core.Devices.Dumping
mediaTags.Add(MediaTagType.SD_OCR, null); mediaTags.Add(MediaTagType.SD_OCR, null);
UpdateStatus?.Invoke("Reading SCR"); UpdateStatus?.Invoke("Reading SCR");
dumpLog.WriteLine("Reading SCR"); _dumpLog.WriteLine("Reading SCR");
sense = dev.ReadScr(out scr, out _, TIMEOUT, out duration); sense = _dev.ReadScr(out scr, out _, TIMEOUT, out duration);
if(sense) if(sense)
scr = null; scr = null;
@@ -187,13 +187,13 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
UpdateStatus?.Invoke("Reading CID"); UpdateStatus?.Invoke("Reading CID");
dumpLog.WriteLine("Reading CID"); _dumpLog.WriteLine("Reading CID");
sense = dev.ReadCid(out byte[] cid, out _, TIMEOUT, out duration); sense = _dev.ReadCid(out byte[] cid, out _, TIMEOUT, out duration);
if(sense) if(sense)
cid = null; cid = null;
else else
mediaTags.Add(dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID : MediaTagType.MMC_CID, null); mediaTags.Add(_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID : MediaTagType.MMC_CID, null);
DateTime start; DateTime start;
DateTime end; DateTime end;
@@ -204,21 +204,21 @@ namespace DiscImageChef.Core.Devices.Dumping
if(blocks == 0) if(blocks == 0)
{ {
dumpLog.WriteLine("Unable to get device size."); _dumpLog.WriteLine("Unable to get device size.");
StoppingErrorMessage?.Invoke("Unable to get device size."); StoppingErrorMessage?.Invoke("Unable to get device size.");
return; return;
} }
UpdateStatus?.Invoke($"Device reports {blocks} blocks."); UpdateStatus?.Invoke($"Device reports {blocks} blocks.");
dumpLog.WriteLine("Device reports {0} blocks.", blocks); _dumpLog.WriteLine("Device reports {0} blocks.", blocks);
byte[] cmdBuf; byte[] cmdBuf;
bool error; bool error;
while(true) while(true)
{ {
error = dev.Read(out cmdBuf, out _, 0, blockSize, blocksToRead, byteAddressed, TIMEOUT, out duration); error = _dev.Read(out cmdBuf, out _, 0, blockSize, blocksToRead, byteAddressed, TIMEOUT, out duration);
if(error) if(error)
blocksToRead /= 2; blocksToRead /= 2;
@@ -230,23 +230,23 @@ namespace DiscImageChef.Core.Devices.Dumping
if(error) if(error)
{ {
dumpLog.WriteLine("ERROR: Cannot get blocks to read, device error {0}.", dev.LastError); _dumpLog.WriteLine("ERROR: Cannot get blocks to read, device error {0}.", _dev.LastError);
StoppingErrorMessage?.Invoke($"Device error {dev.LastError} trying to guess ideal transfer length."); StoppingErrorMessage?.Invoke($"Device error {_dev.LastError} trying to guess ideal transfer length.");
return; return;
} }
UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time."); UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time.");
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) if(_skip < blocksToRead)
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,
ref resume, ref currentTry, ref extents); ref _resume, ref currentTry, ref extents);
if(currentTry == null || if(currentTry == null ||
extents == null) extents == null)
@@ -260,53 +260,53 @@ namespace DiscImageChef.Core.Devices.Dumping
foreach(MediaTagType tag in mediaTags.Keys) foreach(MediaTagType tag in mediaTags.Keys)
{ {
if(outputPlugin.SupportedMediaTags.Contains(tag)) if(_outputPlugin.SupportedMediaTags.Contains(tag))
continue; continue;
ret = false; ret = false;
dumpLog.WriteLine($"Output format does not support {tag}."); _dumpLog.WriteLine($"Output format does not support {tag}.");
ErrorMessage?.Invoke($"Output format does not support {tag}."); ErrorMessage?.Invoke($"Output format does not support {tag}.");
} }
if(!ret) if(!ret)
{ {
if(force) if(_force)
{ {
dumpLog.WriteLine("Several media tags not supported, continuing..."); _dumpLog.WriteLine("Several media tags not supported, continuing...");
ErrorMessage?.Invoke("Several media tags not supported, continuing..."); ErrorMessage?.Invoke("Several media tags not supported, continuing...");
} }
else else
{ {
dumpLog.WriteLine("Several media tags not supported, not continuing..."); _dumpLog.WriteLine("Several media tags not supported, not continuing...");
StoppingErrorMessage?.Invoke("Several media tags not supported, not continuing..."); StoppingErrorMessage?.Invoke("Several media tags not supported, not continuing...");
return; return;
} }
} }
var mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead); var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead);
var ibgLog = new IbgLog(outputPrefix + ".ibg", SD_PROFILE); var ibgLog = new IbgLog(_outputPrefix + ".ibg", SD_PROFILE);
ret = outputPlugin.Create(outputPath, ret = _outputPlugin.Create(_outputPath,
dev.Type == DeviceType.SecureDigital ? MediaType.SecureDigital : MediaType.MMC, _dev.Type == DeviceType.SecureDigital ? MediaType.SecureDigital : MediaType.MMC,
formatOptions, blocks, blockSize); _formatOptions, blocks, blockSize);
// Cannot create image // Cannot create image
if(!ret) if(!ret)
{ {
dumpLog.WriteLine("Error creating output image, not continuing."); _dumpLog.WriteLine("Error creating output image, not continuing.");
dumpLog.WriteLine(outputPlugin.ErrorMessage); _dumpLog.WriteLine(_outputPlugin.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine + StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
outputPlugin.ErrorMessage); _outputPlugin.ErrorMessage);
return; return;
} }
if(resume.NextBlock > 0) if(_resume.NextBlock > 0)
{ {
UpdateStatus?.Invoke($"Resuming from block {resume.NextBlock}."); UpdateStatus?.Invoke($"Resuming from block {_resume.NextBlock}.");
dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock); _dumpLog.WriteLine("Resuming from block {0}.", _resume.NextBlock);
} }
start = DateTime.UtcNow; start = DateTime.UtcNow;
@@ -317,13 +317,13 @@ namespace DiscImageChef.Core.Devices.Dumping
InitProgress?.Invoke(); InitProgress?.Invoke();
for(ulong i = resume.NextBlock; i < blocks; i += blocksToRead) for(ulong i = _resume.NextBlock; i < blocks; i += blocksToRead)
{ {
if(aborted) if(_aborted)
{ {
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
break; break;
} }
@@ -344,46 +344,46 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i, UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
(long)blocks); (long)blocks);
error = dev.Read(out cmdBuf, out _, (uint)i, blockSize, blocksToRead, byteAddressed, TIMEOUT, error = _dev.Read(out cmdBuf, out _, (uint)i, blockSize, blocksToRead, byteAddressed, TIMEOUT,
out duration); out duration);
if(!error) if(!error)
{ {
mhddLog.Write(i, duration); mhddLog.Write(i, duration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(cmdBuf, i, blocksToRead); _outputPlugin.WriteSectors(cmdBuf, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true); extents.Add(i, blocksToRead, true);
} }
else else
{ {
if(i + skip > blocks) if(i + _skip > blocks)
skip = (uint)(blocks - i); _skip = (uint)(blocks - i);
for(ulong b = i; b < i + skip; b++) for(ulong b = i; b < i + _skip; b++)
resume.BadBlocks.Add(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 * skip], i, skip); _outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds; imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i); _dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
i += skip - blocksToRead; i += _skip - blocksToRead;
newTrim = true; newTrim = true;
} }
sectorSpeedStart += blocksToRead; sectorSpeedStart += blocksToRead;
resume.NextBlock = i + blocksToRead; _resume.NextBlock = i + blocksToRead;
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds; double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
if(elapsed < 1) if(elapsed < 1)
continue; continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed); currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }
@@ -392,76 +392,76 @@ namespace DiscImageChef.Core.Devices.Dumping
EndProgress?.Invoke(); EndProgress?.Invoke();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000), (blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000),
devicePath); _devicePath);
UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average dump speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000):F3} KiB/sec."); Invoke($"Average dump speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000):F3} KiB/sec.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average write speed {(double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration:F3} KiB/sec."); Invoke($"Average write speed {((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration:F3} KiB/sec.");
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds); _dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
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); ((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration);
#region Trimming #region Trimming
if(resume.BadBlocks.Count > 0 && if(_resume.BadBlocks.Count > 0 &&
!aborted && !_aborted &&
!notrim && !_notrim &&
newTrim) newTrim)
{ {
start = DateTime.UtcNow; start = DateTime.UtcNow;
UpdateStatus?.Invoke("Trimming bad sectors"); UpdateStatus?.Invoke("Trimming bad sectors");
dumpLog.WriteLine("Trimming bad sectors"); _dumpLog.WriteLine("Trimming bad sectors");
ulong[] tmpArray = resume.BadBlocks.ToArray(); ulong[] tmpArray = _resume.BadBlocks.ToArray();
InitProgress?.Invoke(); InitProgress?.Invoke();
foreach(ulong badSector in tmpArray) foreach(ulong badSector in tmpArray)
{ {
if(aborted) if(_aborted)
{ {
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
break; break;
} }
PulseProgress?.Invoke($"Trimming sector {badSector}"); PulseProgress?.Invoke($"Trimming sector {badSector}");
error = dev.Read(out cmdBuf, out _, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT, error = _dev.Read(out cmdBuf, out _, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT,
out duration); out duration);
totalDuration += duration; totalDuration += duration;
if(error) if(error)
continue; continue;
resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
outputPlugin.WriteSector(cmdBuf, badSector); _outputPlugin.WriteSector(cmdBuf, badSector);
} }
EndProgress?.Invoke(); EndProgress?.Invoke();
end = DateTime.UtcNow; end = DateTime.UtcNow;
UpdateStatus?.Invoke($"Trimmming finished in {(end - start).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Trimmming finished in {(end - start).TotalSeconds} seconds.");
dumpLog.WriteLine("Trimmming finished in {0} seconds.", (end - start).TotalSeconds); _dumpLog.WriteLine("Trimmming finished in {0} seconds.", (end - start).TotalSeconds);
} }
#endregion Trimming #endregion Trimming
#region Error handling #region Error handling
if(resume.BadBlocks.Count > 0 && if(_resume.BadBlocks.Count > 0 &&
!aborted && !_aborted &&
retryPasses > 0) _retryPasses > 0)
{ {
int pass = 1; int pass = 1;
bool forward = true; bool forward = true;
@@ -469,15 +469,15 @@ namespace DiscImageChef.Core.Devices.Dumping
InitProgress?.Invoke(); InitProgress?.Invoke();
repeatRetryLba: repeatRetryLba:
ulong[] tmpArray = resume.BadBlocks.ToArray(); ulong[] tmpArray = _resume.BadBlocks.ToArray();
foreach(ulong badSector in tmpArray) foreach(ulong badSector in tmpArray)
{ {
if(aborted) if(_aborted)
{ {
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
break; break;
} }
@@ -486,31 +486,31 @@ namespace DiscImageChef.Core.Devices.Dumping
forward ? "forward" : "reverse", forward ? "forward" : "reverse",
runningPersistent ? "recovering partial data, " : "")); runningPersistent ? "recovering partial data, " : ""));
error = dev.Read(out cmdBuf, out _, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT, error = _dev.Read(out cmdBuf, out _, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT,
out duration); out duration);
totalDuration += duration; totalDuration += duration;
if(!error) if(!error)
{ {
resume.BadBlocks.Remove(badSector); _resume.BadBlocks.Remove(badSector);
extents.Add(badSector); extents.Add(badSector);
outputPlugin.WriteSector(cmdBuf, badSector); _outputPlugin.WriteSector(cmdBuf, badSector);
UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}."); UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
} }
else if(runningPersistent) else if(runningPersistent)
outputPlugin.WriteSector(cmdBuf, badSector); _outputPlugin.WriteSector(cmdBuf, badSector);
} }
if(pass < retryPasses && if(pass < _retryPasses &&
!aborted && !_aborted &&
resume.BadBlocks.Count > 0) _resume.BadBlocks.Count > 0)
{ {
pass++; pass++;
forward = !forward; forward = !forward;
resume.BadBlocks.Sort(); _resume.BadBlocks.Sort();
resume.BadBlocks.Reverse(); _resume.BadBlocks.Reverse();
goto repeatRetryLba; goto repeatRetryLba;
} }
@@ -521,58 +521,58 @@ namespace DiscImageChef.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
outputPlugin.SetDumpHardware(resume.Tries); _outputPlugin.SetDumpHardware(_resume.Tries);
if(preSidecar != null) if(_preSidecar != null)
outputPlugin.SetCicmMetadata(preSidecar); _outputPlugin.SetCicmMetadata(_preSidecar);
dumpLog.WriteLine("Closing output file."); _dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file."); UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now; DateTime closeStart = DateTime.Now;
outputPlugin.Close(); _outputPlugin.Close();
DateTime closeEnd = DateTime.Now; DateTime closeEnd = DateTime.Now;
UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds); _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);
if(aborted) if(_aborted)
{ {
UpdateStatus?.Invoke("Aborted!"); UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!"); _dumpLog.WriteLine("Aborted!");
return; return;
} }
double totalChkDuration = 0; double totalChkDuration = 0;
if(!nometadata) if(!_nometadata)
{ {
UpdateStatus?.Invoke("Creating sidecar."); UpdateStatus?.Invoke("Creating sidecar.");
dumpLog.WriteLine("Creating sidecar."); _dumpLog.WriteLine("Creating sidecar.");
var filters = new FiltersList(); var filters = new FiltersList();
IFilter filter = filters.GetFilter(outputPath); IFilter filter = filters.GetFilter(_outputPath);
IMediaImage inputPlugin = ImageFormat.Detect(filter); IMediaImage inputPlugin = ImageFormat.Detect(filter);
if(!inputPlugin.Open(filter)) if(!inputPlugin.Open(filter))
StoppingErrorMessage?.Invoke("Could not open created image."); StoppingErrorMessage?.Invoke("Could not open created image.");
DateTime chkStart = DateTime.UtcNow; DateTime chkStart = DateTime.UtcNow;
sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding); _sidecarClass = new Sidecar(inputPlugin, _outputPath, filter.Id, _encoding);
sidecarClass.InitProgressEvent += InitProgress; _sidecarClass.InitProgressEvent += InitProgress;
sidecarClass.UpdateProgressEvent += UpdateProgress; _sidecarClass.UpdateProgressEvent += UpdateProgress;
sidecarClass.EndProgressEvent += EndProgress; _sidecarClass.EndProgressEvent += EndProgress;
sidecarClass.InitProgressEvent2 += InitProgress2; _sidecarClass.InitProgressEvent2 += InitProgress2;
sidecarClass.UpdateProgressEvent2 += UpdateProgress2; _sidecarClass.UpdateProgressEvent2 += UpdateProgress2;
sidecarClass.EndProgressEvent2 += EndProgress2; _sidecarClass.EndProgressEvent2 += EndProgress2;
sidecarClass.UpdateStatusEvent += UpdateStatus; _sidecarClass.UpdateStatusEvent += UpdateStatus;
CICMMetadataType sidecar = sidecarClass.Create(); CICMMetadataType sidecar = _sidecarClass.Create();
if(preSidecar != null) if(_preSidecar != null)
{ {
preSidecar.BlockMedia = sidecar.BlockMedia; _preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = preSidecar; sidecar = _preSidecar;
} }
switch(dev.Type) switch(_dev.Type)
{ {
case DeviceType.MMC: case DeviceType.MMC:
sidecar.BlockMedia[0].MultiMediaCard = new MultiMediaCardType(); sidecar.BlockMedia[0].MultiMediaCard = new MultiMediaCardType();
@@ -592,22 +592,22 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
cidDump = new DumpType cidDump = new DumpType
{ {
Image = outputPath, Size = (ulong)cid.Length, Checksums = Checksum.GetChecksums(cid).ToArray() Image = _outputPath, Size = (ulong)cid.Length, Checksums = Checksum.GetChecksums(cid).ToArray()
}; };
ret = ret =
outputPlugin.WriteMediaTag(cid, _outputPlugin.WriteMediaTag(cid,
dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID _dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID
: MediaTagType.MMC_CID); : MediaTagType.MMC_CID);
// Cannot write CID to image // Cannot write CID to image
if(!ret && if(!ret &&
!force) !_force)
{ {
dumpLog.WriteLine("Cannot write CID to output image."); _dumpLog.WriteLine("Cannot write CID to output image.");
StoppingErrorMessage?.Invoke("Cannot write CID to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write CID to output image." + Environment.NewLine +
outputPlugin.ErrorMessage); _outputPlugin.ErrorMessage);
return; return;
} }
@@ -617,22 +617,22 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
csdDump = new DumpType csdDump = new DumpType
{ {
Image = outputPath, Size = (ulong)csd.Length, Checksums = Checksum.GetChecksums(csd).ToArray() Image = _outputPath, Size = (ulong)csd.Length, Checksums = Checksum.GetChecksums(csd).ToArray()
}; };
ret = ret =
outputPlugin.WriteMediaTag(csd, _outputPlugin.WriteMediaTag(csd,
dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CSD _dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CSD
: MediaTagType.MMC_CSD); : MediaTagType.MMC_CSD);
// Cannot write CSD to image // Cannot write CSD to image
if(!ret && if(!ret &&
!force) !_force)
{ {
dumpLog.WriteLine("Cannot write CSD to output image."); _dumpLog.WriteLine("Cannot write CSD to output image.");
StoppingErrorMessage?.Invoke("Cannot write CSD to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write CSD to output image." + Environment.NewLine +
outputPlugin.ErrorMessage); _outputPlugin.ErrorMessage);
return; return;
} }
@@ -642,20 +642,21 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
sidecar.BlockMedia[0].MultiMediaCard.ExtendedCSD = new DumpType sidecar.BlockMedia[0].MultiMediaCard.ExtendedCSD = new DumpType
{ {
Image = outputPath, Size = (ulong)ecsd.Length, Checksums = Checksum.GetChecksums(ecsd).ToArray() Image = _outputPath, Size = (ulong)ecsd.Length,
Checksums = Checksum.GetChecksums(ecsd).ToArray()
}; };
ret = outputPlugin.WriteMediaTag(ecsd, MediaTagType.MMC_ExtendedCSD); ret = _outputPlugin.WriteMediaTag(ecsd, MediaTagType.MMC_ExtendedCSD);
// Cannot write Extended CSD to image // Cannot write Extended CSD to image
if(!ret && if(!ret &&
!force) !_force)
{ {
dumpLog.WriteLine("Cannot write Extended CSD to output image."); _dumpLog.WriteLine("Cannot write Extended CSD to output image.");
StoppingErrorMessage?.Invoke("Cannot write Extended CSD to output image." + StoppingErrorMessage?.Invoke("Cannot write Extended CSD to output image." +
Environment.NewLine + Environment.NewLine +
outputPlugin.ErrorMessage); _outputPlugin.ErrorMessage);
return; return;
} }
@@ -665,22 +666,22 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
ocrDump = new DumpType ocrDump = new DumpType
{ {
Image = outputPath, Size = (ulong)ocr.Length, Checksums = Checksum.GetChecksums(ocr).ToArray() Image = _outputPath, Size = (ulong)ocr.Length, Checksums = Checksum.GetChecksums(ocr).ToArray()
}; };
ret = ret =
outputPlugin.WriteMediaTag(ocr, _outputPlugin.WriteMediaTag(ocr,
dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_OCR _dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_OCR
: MediaTagType.MMC_OCR); : MediaTagType.MMC_OCR);
// Cannot write OCR to image // Cannot write OCR to image
if(!ret && if(!ret &&
!force) !_force)
{ {
dumpLog.WriteLine("Cannot write OCR to output image."); _dumpLog.WriteLine("Cannot write OCR to output image.");
StoppingErrorMessage?.Invoke("Cannot write OCR to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write OCR to output image." + Environment.NewLine +
outputPlugin.ErrorMessage); _outputPlugin.ErrorMessage);
return; return;
} }
@@ -690,25 +691,25 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
sidecar.BlockMedia[0].SecureDigital.SCR = new DumpType sidecar.BlockMedia[0].SecureDigital.SCR = new DumpType
{ {
Image = outputPath, Size = (ulong)scr.Length, Checksums = Checksum.GetChecksums(scr).ToArray() Image = _outputPath, Size = (ulong)scr.Length, Checksums = Checksum.GetChecksums(scr).ToArray()
}; };
ret = outputPlugin.WriteMediaTag(scr, MediaTagType.SD_SCR); ret = _outputPlugin.WriteMediaTag(scr, MediaTagType.SD_SCR);
// Cannot write SCR to image // Cannot write SCR to image
if(!ret && if(!ret &&
!force) !_force)
{ {
dumpLog.WriteLine("Cannot write SCR to output image."); _dumpLog.WriteLine("Cannot write SCR to output image.");
StoppingErrorMessage?.Invoke("Cannot write SCR to output image." + Environment.NewLine + StoppingErrorMessage?.Invoke("Cannot write SCR to output image." + Environment.NewLine +
outputPlugin.ErrorMessage); _outputPlugin.ErrorMessage);
return; return;
} }
} }
switch(dev.Type) switch(_dev.Type)
{ {
case DeviceType.MMC: case DeviceType.MMC:
sidecar.BlockMedia[0].MultiMediaCard.CID = cidDump; sidecar.BlockMedia[0].MultiMediaCard.CID = cidDump;
@@ -730,20 +731,19 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke($"Sidecar created in {(end - chkStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Sidecar created in {(end - chkStart).TotalSeconds} seconds.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average checksum speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000):F3} KiB/sec."); Invoke($"Average checksum speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (totalChkDuration / 1000):F3} KiB/sec.");
dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); _dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds);
dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", _dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); ((double)blockSize * (double)(blocks + 1)) / 1024 / (totalChkDuration / 1000));
(string type, string subType) xmlType = (null, null); (string type, string subType) xmlType = (null, null);
switch(dev.Type) switch(_dev.Type)
{ {
case DeviceType.MMC: case DeviceType.MMC:
xmlType = xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.MMC);
CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.MMC);
sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(MediaType.MMC); sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(MediaType.MMC);
@@ -762,14 +762,14 @@ namespace DiscImageChef.Core.Devices.Dumping
sidecar.BlockMedia[0].LogicalBlocks = blocks; sidecar.BlockMedia[0].LogicalBlocks = blocks;
sidecar.BlockMedia[0].PhysicalBlockSize = physicalBlockSize > 0 ? physicalBlockSize : blockSize; sidecar.BlockMedia[0].PhysicalBlockSize = physicalBlockSize > 0 ? physicalBlockSize : blockSize;
sidecar.BlockMedia[0].LogicalBlockSize = blockSize; sidecar.BlockMedia[0].LogicalBlockSize = blockSize;
sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer; sidecar.BlockMedia[0].Manufacturer = _dev.Manufacturer;
sidecar.BlockMedia[0].Model = dev.Model; sidecar.BlockMedia[0].Model = _dev.Model;
sidecar.BlockMedia[0].Serial = dev.Serial; sidecar.BlockMedia[0].Serial = _dev.Serial;
sidecar.BlockMedia[0].Size = blocks * blockSize; sidecar.BlockMedia[0].Size = blocks * blockSize;
UpdateStatus?.Invoke("Writing metadata sidecar"); UpdateStatus?.Invoke("Writing metadata sidecar");
var xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); var xmlFs = new FileStream(_outputPrefix + ".cicm.xml", FileMode.Create);
var xmlSer = new XmlSerializer(typeof(CICMMetadataType)); var xmlSer = new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar); xmlSer.Serialize(xmlFs, sidecar);
@@ -782,17 +782,17 @@ namespace DiscImageChef.Core.Devices.Dumping
Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing)."); Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing).");
UpdateStatus?. UpdateStatus?.
Invoke($"Average speed: {(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000):F3} MiB/sec."); Invoke($"Average speed: {((double)blockSize * (double)(blocks + 1)) / 1048576 / (totalDuration / 1000):F3} MiB/sec.");
UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec."); UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec.");
UpdateStatus?.Invoke($"Slowest speed burst: {minSpeed:F3} MiB/sec."); UpdateStatus?.Invoke($"Slowest speed burst: {minSpeed:F3} MiB/sec.");
UpdateStatus?.Invoke($"{resume.BadBlocks.Count} sectors could not be read."); UpdateStatus?.Invoke($"{_resume.BadBlocks.Count} sectors could not be read.");
UpdateStatus?.Invoke(""); UpdateStatus?.Invoke("");
if(resume.BadBlocks.Count > 0) if(_resume.BadBlocks.Count > 0)
resume.BadBlocks.Sort(); _resume.BadBlocks.Sort();
switch(dev.Type) switch(_dev.Type)
{ {
case DeviceType.MMC: case DeviceType.MMC:
Statistics.AddMedia(MediaType.MMC, true); Statistics.AddMedia(MediaType.MMC, true);

File diff suppressed because it is too large Load Diff

View File

@@ -54,16 +54,18 @@ using Schemas;
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo; using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
using MediaType = DiscImageChef.CommonTypes.MediaType; using MediaType = DiscImageChef.CommonTypes.MediaType;
// ReSharper disable UnusedMember.Local
namespace DiscImageChef.Gui.Forms namespace DiscImageChef.Gui.Forms
{ {
public class frmDump : Form public class frmDump : Form
{ {
readonly string devicePath; readonly string _devicePath;
Device dev; Device _dev;
Dump dumper; Dump _dumper;
string outputPrefix; string _outputPrefix;
Resume resume; Resume _resume;
CICMMetadataType sidecar; CICMMetadataType _sidecar;
public frmDump(string devicePath, DeviceInfo deviceInfo, ScsiInfo scsiInfo = null) public frmDump(string devicePath, DeviceInfo deviceInfo, ScsiInfo scsiInfo = null)
{ {
@@ -189,7 +191,7 @@ namespace DiscImageChef.Gui.Forms
break; break;
} }
this.devicePath = devicePath; _devicePath = devicePath;
} }
void OnCmbFormatSelectedIndexChanged(object sender, EventArgs e) void OnCmbFormatSelectedIndexChanged(object sender, EventArgs e)
@@ -318,7 +320,7 @@ namespace DiscImageChef.Gui.Forms
if(result != DialogResult.Ok) if(result != DialogResult.Ok)
{ {
txtDestination.Text = ""; txtDestination.Text = "";
outputPrefix = null; _outputPrefix = null;
return; return;
} }
@@ -328,8 +330,8 @@ namespace DiscImageChef.Gui.Forms
txtDestination.Text = dlgDestination.FileName; txtDestination.Text = dlgDestination.FileName;
outputPrefix = Path.Combine(Path.GetDirectoryName(dlgDestination.FileName), _outputPrefix = Path.Combine(Path.GetDirectoryName(dlgDestination.FileName),
Path.GetFileNameWithoutExtension(dlgDestination.FileName)); Path.GetFileNameWithoutExtension(dlgDestination.FileName));
chkResume.Checked = true; chkResume.Checked = true;
} }
@@ -344,7 +346,7 @@ namespace DiscImageChef.Gui.Forms
{ {
if(chkExistingMetadata.Checked == false) if(chkExistingMetadata.Checked == false)
{ {
sidecar = null; _sidecar = null;
return; return;
} }
@@ -370,7 +372,7 @@ namespace DiscImageChef.Gui.Forms
try try
{ {
var sr = new StreamReader(dlgMetadata.FileName); var sr = new StreamReader(dlgMetadata.FileName);
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr); _sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
sr.Close(); sr.Close();
} }
catch catch
@@ -385,19 +387,19 @@ namespace DiscImageChef.Gui.Forms
if(chkResume.Checked == false) if(chkResume.Checked == false)
return; return;
if(outputPrefix != null) if(_outputPrefix != null)
CheckResumeFile(); CheckResumeFile();
} }
void CheckResumeFile() void CheckResumeFile()
{ {
resume = null; _resume = null;
var xs = new XmlSerializer(typeof(Resume)); var xs = new XmlSerializer(typeof(Resume));
try try
{ {
var sr = new StreamReader(outputPrefix + ".resume.xml"); var sr = new StreamReader(_outputPrefix + ".resume.xml");
resume = (Resume)xs.Deserialize(sr); _resume = (Resume)xs.Deserialize(sr);
sr.Close(); sr.Close();
} }
catch catch
@@ -408,9 +410,9 @@ namespace DiscImageChef.Gui.Forms
return; return;
} }
if(resume == null || if(_resume == null ||
resume.NextBlock <= resume.LastBlock || _resume.NextBlock <= _resume.LastBlock ||
(resume.BadBlocks.Count != 0 && !resume.Tape)) (_resume.BadBlocks.Count != 0 && !_resume.Tape))
return; return;
MessageBox.Show("Media already dumped correctly, please choose another destination...", MessageBox.Show("Media already dumped correctly, please choose another destination...",
@@ -424,7 +426,7 @@ namespace DiscImageChef.Gui.Forms
void OnBtnStopClick(object sender, EventArgs e) void OnBtnStopClick(object sender, EventArgs e)
{ {
btnStop.Enabled = false; btnStop.Enabled = false;
dumper.Abort(); _dumper.Abort();
} }
void OnBtnDumpClick(object sender, EventArgs e) void OnBtnDumpClick(object sender, EventArgs e)
@@ -442,15 +444,15 @@ namespace DiscImageChef.Gui.Forms
try try
{ {
dev = new Device(devicePath); _dev = new Device(_devicePath);
if(dev.IsRemote) if(_dev.IsRemote)
Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem, Statistics.AddRemote(_dev.RemoteApplication, _dev.RemoteVersion, _dev.RemoteOperatingSystem,
dev.RemoteOperatingSystemVersion, dev.RemoteArchitecture); _dev.RemoteOperatingSystemVersion, _dev.RemoteArchitecture);
if(dev.Error) if(_dev.Error)
{ {
StoppingErrorMessage($"Error {dev.LastError} opening device."); StoppingErrorMessage($"Error {_dev.LastError} opening device.");
return; return;
} }
@@ -462,7 +464,7 @@ namespace DiscImageChef.Gui.Forms
return; return;
} }
Statistics.AddDevice(dev); Statistics.AddDevice(_dev);
Statistics.AddCommand("dump-media"); Statistics.AddCommand("dump-media");
if(!(cmbFormat.SelectedValue is IWritableImage outputFormat)) if(!(cmbFormat.SelectedValue is IWritableImage outputFormat))
@@ -515,36 +517,37 @@ namespace DiscImageChef.Gui.Forms
parsedOptions.Add(key, value); parsedOptions.Add(key, value);
} }
var dumpLog = new DumpLog(outputPrefix + ".log", dev); var dumpLog = new DumpLog(_outputPrefix + ".log", _dev);
dumpLog.WriteLine("Output image format: {0}.", outputFormat.Name); dumpLog.WriteLine("Output image format: {0}.", outputFormat.Name);
dumper = new Dump(chkResume.Checked == true, dev, devicePath, outputFormat, (ushort)stpRetries.Value, _dumper = new Dump(chkResume.Checked == true, _dev, _devicePath, outputFormat,
chkForce.Checked == true, false, chkPersistent.Checked == true, (ushort)stpRetries.Value,
chkStopOnError.Checked == true, resume, dumpLog, encoding, outputPrefix, chkForce.Checked == true, false, chkPersistent.Checked == true,
txtDestination.Text, parsedOptions, sidecar, (uint)stpSkipped.Value, chkStopOnError.Checked == true, _resume, dumpLog, encoding, _outputPrefix,
chkExistingMetadata.Checked == false, chkTrim.Checked == false, txtDestination.Text, parsedOptions, _sidecar, (uint)stpSkipped.Value,
chkTrack1Pregap.Checked == true); chkExistingMetadata.Checked == false, chkTrim.Checked == false,
chkTrack1Pregap.Checked == true);
new Thread(DoWork).Start(); new Thread(DoWork).Start();
} }
void DoWork() void DoWork()
{ {
dumper.UpdateStatus += UpdateStatus; _dumper.UpdateStatus += UpdateStatus;
dumper.ErrorMessage += ErrorMessage; _dumper.ErrorMessage += ErrorMessage;
dumper.StoppingErrorMessage += StoppingErrorMessage; _dumper.StoppingErrorMessage += StoppingErrorMessage;
dumper.PulseProgress += PulseProgress; _dumper.PulseProgress += PulseProgress;
dumper.InitProgress += InitProgress; _dumper.InitProgress += InitProgress;
dumper.UpdateProgress += UpdateProgress; _dumper.UpdateProgress += UpdateProgress;
dumper.EndProgress += EndProgress; _dumper.EndProgress += EndProgress;
dumper.InitProgress2 += InitProgress2; _dumper.InitProgress2 += InitProgress2;
dumper.UpdateProgress2 += UpdateProgress2; _dumper.UpdateProgress2 += UpdateProgress2;
dumper.EndProgress2 += EndProgress2; _dumper.EndProgress2 += EndProgress2;
dumper.Start(); _dumper.Start();
dev.Close(); _dev.Close();
WorkFinished(); WorkFinished();
} }
@@ -643,6 +646,7 @@ namespace DiscImageChef.Gui.Forms
} }
#region XAML IDs #region XAML IDs
// ReSharper disable InconsistentNaming
ComboBox cmbFormat; ComboBox cmbFormat;
TextBox txtDestination; TextBox txtDestination;
Button btnDestination; Button btnDestination;
@@ -673,6 +677,8 @@ namespace DiscImageChef.Gui.Forms
Label lblProgress2; Label lblProgress2;
ProgressBar prgProgress2; ProgressBar prgProgress2;
StackLayout stkOptions; StackLayout stkOptions;
// ReSharper restore InconsistentNaming
#endregion #endregion
} }
} }

View File

@@ -190,6 +190,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=certance/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=certance/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=checksumming/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=checksumming/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=checksums/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=checksums/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=cicm/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Claunia/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Claunia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=DDCD/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=DDCD/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drive_0027s/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Drive_0027s/@EntryIndexedValue">True</s:Boolean>

View File

@@ -52,81 +52,77 @@ using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
namespace DiscImageChef.Commands namespace DiscImageChef.Commands
{ {
// TODO: Add raw dumping
internal class DumpMediaCommand : Command internal class DumpMediaCommand : Command
{ {
string cicmXml; string _cicmXml;
string devicePath; string _devicePath;
bool doResume = true; bool _doResume = true;
string encodingName; string _encodingName;
bool firstTrackPregap; bool _firstTrackPregap;
bool force; bool _force;
bool noMetadata; bool _noMetadata;
bool noTrim; bool _noTrim;
string outputFile; string _outputFile;
string outputOptions; string _outputOptions;
bool _persistent;
bool persistent; ushort _retryPasses = 5;
bool _showHelp;
// TODO: Add raw dumping int _skip = 512;
ushort retryPasses = 5; bool _stopOnError;
bool showHelp; string _wantedOutputFormat;
int skip = 512;
bool stopOnError;
string wantedOutputFormat;
public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.") public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.")
{ {
Options = new OptionSet Options = new OptionSet
{ {
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}", $"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [OPTIONS] devicepath outputimage", $"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [OPTIONS] device_path output_image",
"", Help, "", Help,
{ {
"cicm-xml|x=", "Take metadata from existing CICM XML sidecar.", s => cicmXml = s "cicm-xml|x=", "Take metadata from existing CICM XML sidecar.", s => _cicmXml = s
}, },
{ {
"encoding|e=", "Name of character encoding to use.", s => encodingName = s "encoding|e=", "Name of character encoding to use.", s => _encodingName = s
} }
}; };
if(DetectOS.GetRealPlatformID() != PlatformID.FreeBSD) if(DetectOS.GetRealPlatformID() != PlatformID.FreeBSD)
Options.Add("first-pregap", "Try to read first track pregap. Only applicable to CD/DDCD/GD.", Options.Add("first-pregap", "Try to read first track pregap. Only applicable to CD/DDCD/GD.",
b => firstTrackPregap = b != null); b => _firstTrackPregap = b != null);
Options.Add("force|f", "Continue dump whatever happens.", b => force = b != null); Options.Add("force|f", "Continue dump whatever happens.", b => _force = b != null);
Options.Add("format|t=", Options.Add("format|t=",
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.", "Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.",
s => wantedOutputFormat = s); s => _wantedOutputFormat = s);
Options.Add("no-metadata", "Disables creating CICM XML sidecar.", b => noMetadata = b != null); Options.Add("no-metadata", "Disables creating CICM XML sidecar.", b => _noMetadata = b != null);
Options.Add("no-trim", "Disables trimming errored from skipped sectors.", b => noTrim = b != null); Options.Add("no-trim", "Disables trimming errored from skipped sectors.", b => _noTrim = b != null);
Options.Add("options|O=", "Comma separated name=value pairs of options to pass to output image plugin.", Options.Add("options|O=", "Comma separated name=value pairs of options to pass to output image plugin.",
s => outputOptions = s); s => _outputOptions = s);
Options.Add("persistent", "Try to recover partial or incorrect data.", b => persistent = b != null); Options.Add("persistent", "Try to recover partial or incorrect data.", b => _persistent = b != null);
Options.Add("resume|r", "Create/use resume mapfile.", b => _doResume = b != null);
Options.Add("retry-passes|p=", "How many retry passes to do.", (ushort us) => _retryPasses = us);
Options.Add("skip|k=", "When an unreadable sector is found skip this many sectors.", (int i) => _skip = i);
Options.Add("stop-on-error|s", "Stop media dump on first error.", b => _stopOnError = b != null);
Options.Add("help|h|?", "Show this message and exit.", v => _showHelp = v != null);
/* TODO: Disabled temporarily /* TODO: Disabled temporarily
Options.Add("raw|r", "Dump sectors with tags included. For optical media, dump scrambled sectors.", (b) => raw = b != null);*/ Options.Add("raw|r", "Dump sectors with tags included. For optical media, dump scrambled sectors.", (b) => raw = b != null);*/
Options.Add("resume|r", "Create/use resume mapfile.",
b => doResume = b != null);
Options.Add("retry-passes|p=", "How many retry passes to do.", (ushort us) => retryPasses = us);
Options.Add("skip|k=", "When an unreadable sector is found skip this many sectors.", (int i) => skip = i);
Options.Add("stop-on-error|s", "Stop media dump on first error.",
b => stopOnError = b != null);
Options.Add("help|h|?", "Show this message and exit.",
v => showHelp = v != null);
} }
public override int Invoke(IEnumerable<string> arguments) public override int Invoke(IEnumerable<string> arguments)
{ {
List<string> extra = Options.Parse(arguments); List<string> extra = Options.Parse(arguments);
if(showHelp) if(_showHelp)
{ {
Options.WriteOptionDescriptions(CommandSet.Out); Options.WriteOptionDescriptions(CommandSet.Out);
@@ -157,31 +153,31 @@ namespace DiscImageChef.Commands
return(int)ErrorNumber.MissingArgument; return(int)ErrorNumber.MissingArgument;
} }
devicePath = extra[0]; _devicePath = extra[0];
outputFile = extra[1]; _outputFile = extra[1];
DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", cicmXml); DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", _cicmXml);
DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", devicePath); DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", _devicePath);
DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", encodingName); DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", _encodingName);
DicConsole.DebugWriteLine("Dump-Media command", "--first-pregap={0}", firstTrackPregap); DicConsole.DebugWriteLine("Dump-Media command", "--first-pregap={0}", _firstTrackPregap);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force); DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", _force);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force); DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", _force);
DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", wantedOutputFormat); DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", _wantedOutputFormat);
DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", noMetadata); DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", _noMetadata);
DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", Options); DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", Options);
DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", outputFile); DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", _outputFile);
DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", persistent); DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", _persistent);
DicConsole.DebugWriteLine("Dump-Media command", "--resume={0}", _doResume);
DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", _retryPasses);
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", _skip);
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", _stopOnError);
DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", MainClass.Verbose);
// TODO: Disabled temporarily // TODO: Disabled temporarily
//DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw); //DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
DicConsole.DebugWriteLine("Dump-Media command", "--resume={0}", doResume);
DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", retryPasses);
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", skip);
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", stopOnError);
DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", MainClass.Verbose);
Dictionary<string, string> parsedOptions = Core.Options.Parse(outputOptions); Dictionary<string, string> parsedOptions = Core.Options.Parse(_outputOptions);
DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:"); DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");
foreach(KeyValuePair<string, string> parsedOption in parsedOptions) foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
@@ -189,10 +185,10 @@ namespace DiscImageChef.Commands
Encoding encoding = null; Encoding encoding = null;
if(encodingName != null) if(_encodingName != null)
try try
{ {
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName); encoding = Claunia.Encoding.Encoding.GetEncoding(_encodingName);
if(MainClass.Verbose) if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName); DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
@@ -204,17 +200,17 @@ namespace DiscImageChef.Commands
return(int)ErrorNumber.EncodingUnknown; return(int)ErrorNumber.EncodingUnknown;
} }
if(devicePath.Length == 2 && if(_devicePath.Length == 2 &&
devicePath[1] == ':' && _devicePath[1] == ':' &&
devicePath[0] != '/' && _devicePath[0] != '/' &&
char.IsLetter(devicePath[0])) char.IsLetter(_devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':'; _devicePath = "\\\\.\\" + char.ToUpper(_devicePath[0]) + ':';
Device dev; Device dev;
try try
{ {
dev = new Device(devicePath); dev = new Device(_devicePath);
if(dev.IsRemote) if(dev.IsRemote)
Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem, Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem,
@@ -236,13 +232,13 @@ namespace DiscImageChef.Commands
Statistics.AddDevice(dev); Statistics.AddDevice(dev);
string outputPrefix = Path.Combine(Path.GetDirectoryName(outputFile), string outputPrefix = Path.Combine(Path.GetDirectoryName(_outputFile),
Path.GetFileNameWithoutExtension(outputFile)); Path.GetFileNameWithoutExtension(_outputFile));
Resume resume = null; Resume resume = null;
var xs = new XmlSerializer(typeof(Resume)); var xs = new XmlSerializer(typeof(Resume));
if(File.Exists(outputPrefix + ".resume.xml") && doResume) if(File.Exists(outputPrefix + ".resume.xml") && _doResume)
try try
{ {
var sr = new StreamReader(outputPrefix + ".resume.xml"); var sr = new StreamReader(outputPrefix + ".resume.xml");
@@ -269,12 +265,12 @@ namespace DiscImageChef.Commands
CICMMetadataType sidecar = null; CICMMetadataType sidecar = null;
var sidecarXs = new XmlSerializer(typeof(CICMMetadataType)); var sidecarXs = new XmlSerializer(typeof(CICMMetadataType));
if(cicmXml != null) if(_cicmXml != null)
if(File.Exists(cicmXml)) if(File.Exists(_cicmXml))
{ {
try try
{ {
var sr = new StreamReader(cicmXml); var sr = new StreamReader(_cicmXml);
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr); sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
sr.Close(); sr.Close();
} }
@@ -296,18 +292,19 @@ namespace DiscImageChef.Commands
List<IWritableImage> candidates = new List<IWritableImage>(); List<IWritableImage> candidates = new List<IWritableImage>();
// Try extension // Try extension
if(string.IsNullOrEmpty(wantedOutputFormat)) if(string.IsNullOrEmpty(_wantedOutputFormat))
candidates.AddRange(plugins.WritableImages.Values.Where(t => candidates.AddRange(plugins.WritableImages.Values.Where(t =>
t.KnownExtensions. t.KnownExtensions.
Contains(Path.GetExtension(outputFile)))); Contains(Path.
GetExtension(_outputFile))));
// Try Id // Try Id
else if(Guid.TryParse(wantedOutputFormat, out Guid outId)) else if(Guid.TryParse(_wantedOutputFormat, out Guid outId))
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId))); candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
// Try name // Try name
else else
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, wantedOutputFormat, candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, _wantedOutputFormat,
StringComparison. StringComparison.
InvariantCultureIgnoreCase))); InvariantCultureIgnoreCase)));
@@ -340,9 +337,9 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name); DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
} }
var dumper = new Dump(doResume, dev, devicePath, outputFormat, retryPasses, force, false, persistent, var dumper = new Dump(_doResume, dev, _devicePath, outputFormat, _retryPasses, _force, false, _persistent,
stopOnError, resume, dumpLog, encoding, outputPrefix, outputFile, parsedOptions, _stopOnError, resume, dumpLog, encoding, outputPrefix, _outputFile, parsedOptions,
sidecar, (uint)skip, noMetadata, noTrim, firstTrackPregap); sidecar, (uint)_skip, _noMetadata, _noTrim, _firstTrackPregap);
dumper.UpdateStatus += Progress.UpdateStatus; dumper.UpdateStatus += Progress.UpdateStatus;
dumper.ErrorMessage += Progress.ErrorMessage; dumper.ErrorMessage += Progress.ErrorMessage;