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>
public void Ata()
{
if(dumpRaw)
if(_dumpRaw)
{
if(force)
if(_force)
ErrorMessage?.Invoke("Raw dumping not yet supported in ATA devices, continuing...");
else
{
@@ -70,8 +70,8 @@ namespace DiscImageChef.Core.Devices.Dumping
double imageWriteDuration = 0;
UpdateStatus?.Invoke("Requesting ATA IDENTIFY DEVICE.");
dumpLog.WriteLine("Requesting ATA IDENTIFY DEVICE.");
bool sense = dev.AtaIdentify(out byte[] cmdBuf, out _);
_dumpLog.WriteLine("Requesting ATA IDENTIFY DEVICE.");
bool sense = _dev.AtaIdentify(out byte[] cmdBuf, out _);
if(!sense &&
Identify.Decode(cmdBuf).HasValue)
@@ -93,8 +93,8 @@ namespace DiscImageChef.Core.Devices.Dumping
// Initializate reader
UpdateStatus?.Invoke("Initializing reader.");
dumpLog.WriteLine("Initializing reader.");
var ataReader = new Reader(dev, TIMEOUT, ataIdentify);
_dumpLog.WriteLine("Initializing reader.");
var ataReader = new Reader(_dev, TIMEOUT, ataIdentify);
// Fill reader blocks
ulong blocks = ataReader.GetDeviceBlocks();
@@ -102,7 +102,7 @@ namespace DiscImageChef.Core.Devices.Dumping
// Check block sizes
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);
return;
@@ -113,7 +113,7 @@ namespace DiscImageChef.Core.Devices.Dumping
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);
return;
@@ -122,7 +122,7 @@ namespace DiscImageChef.Core.Devices.Dumping
// Check how many blocks to read, if error show and return
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);
return;
@@ -141,23 +141,23 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time.");
UpdateStatus?.Invoke($"Device reports {blockSize} bytes per logical 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,
sectors);
_dumpLog.WriteLine("Device reports {0} cylinders {1} heads {2} sectors per track.", cylinders,
heads, sectors);
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 physical block.", physicalsectorsize);
_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 physical block.", physicalsectorsize);
bool removable = !dev.IsCompactFlash &&
bool removable = !_dev.IsCompactFlash &&
ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable);
DumpHardwareType currentTry = null;
ExtentsULong extents = null;
ResumeSupport.Process(ataReader.IsLba, removable, blocks, dev.Manufacturer, dev.Model, dev.Serial,
dev.PlatformId, ref resume, ref currentTry, ref extents);
ResumeSupport.Process(ataReader.IsLba, removable, blocks, _dev.Manufacturer, _dev.Model,
_dev.Serial, _dev.PlatformId, ref _resume, ref currentTry, ref extents);
if(currentTry == null ||
extents == null)
@@ -173,36 +173,36 @@ namespace DiscImageChef.Core.Devices.Dumping
bool ret = true;
if(dev.IsUsb &&
dev.UsbDescriptors != null &&
!outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors))
if(_dev.IsUsb &&
_dev.UsbDescriptors != null &&
!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors))
{
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.");
}
if(dev.IsPcmcia &&
dev.Cis != null &&
!outputPlugin.SupportedMediaTags.Contains(MediaTagType.PCMCIA_CIS))
if(_dev.IsPcmcia &&
_dev.Cis != null &&
!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.PCMCIA_CIS))
{
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.");
}
if(!outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
if(!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
{
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.");
}
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...");
else
{
@@ -212,40 +212,40 @@ namespace DiscImageChef.Core.Devices.Dumping
}
}
ret = outputPlugin.Create(outputPath,
dev.IsCompactFlash ? MediaType.CompactFlash : MediaType.GENERIC_HDD,
formatOptions, blocks, blockSize);
ret = _outputPlugin.Create(_outputPath,
_dev.IsCompactFlash ? MediaType.CompactFlash : MediaType.GENERIC_HDD,
_formatOptions, blocks, blockSize);
// Cannot create image
if(!ret)
{
dumpLog.WriteLine("Error creating output image, not continuing.");
dumpLog.WriteLine(outputPlugin.ErrorMessage);
_dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." +
Environment.NewLine +
outputPlugin.ErrorMessage);
_outputPlugin.ErrorMessage);
return;
}
// Setting geometry
outputPlugin.SetGeometry(cylinders, heads, sectors);
_outputPlugin.SetGeometry(cylinders, heads, sectors);
if(ataReader.IsLba)
{
UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");
if(skip < blocksToRead)
skip = blocksToRead;
if(_skip < blocksToRead)
_skip = blocksToRead;
mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(outputPrefix + ".ibg", ATA_PROFILE);
mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(_outputPrefix + ".ibg", ATA_PROFILE);
if(resume.NextBlock > 0)
if(_resume.NextBlock > 0)
{
UpdateStatus?.Invoke($"Resuming from block {resume.NextBlock}.");
dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
UpdateStatus?.Invoke($"Resuming from block {_resume.NextBlock}.");
_dumpLog.WriteLine("Resuming from block {0}.", _resume.NextBlock);
}
bool newTrim = false;
@@ -255,13 +255,13 @@ namespace DiscImageChef.Core.Devices.Dumping
ulong sectorSpeedStart = 0;
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);
UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!");
_dumpLog.WriteLine("Aborted!");
break;
}
@@ -289,38 +289,38 @@ namespace DiscImageChef.Core.Devices.Dumping
mhddLog.Write(i, duration);
ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(cmdBuf, i, blocksToRead);
_outputPlugin.WriteSectors(cmdBuf, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true);
}
else
{
if(i + skip > blocks)
skip = (uint)(blocks - i);
if(i + _skip > blocks)
_skip = (uint)(blocks - i);
for(ulong b = i; b < i + skip; b++)
resume.BadBlocks.Add(b);
for(ulong b = i; b < i + _skip; b++)
_resume.BadBlocks.Add(b);
mhddLog.Write(i, duration < 500 ? 65535 : duration);
ibgLog.Write(i, 0);
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;
dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i);
i += skip - blocksToRead;
_dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
i += _skip - blocksToRead;
newTrim = true;
}
sectorSpeedStart += blocksToRead;
resume.NextBlock = i + blocksToRead;
_resume.NextBlock = i + blocksToRead;
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
if(elapsed < 1)
continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow;
}
@@ -329,46 +329,46 @@ namespace DiscImageChef.Core.Devices.Dumping
EndProgress?.Invoke();
mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 /
(totalDuration / 1000), devicePath);
ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
(blockSize * (double)(blocks + 1)) / 1024 /
(totalDuration / 1000), _devicePath);
UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");
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?.
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.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
_dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000));
dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration);
_dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration);
#region Trimming
if(resume.BadBlocks.Count > 0 &&
!aborted &&
!notrim &&
if(_resume.BadBlocks.Count > 0 &&
!_aborted &&
!_notrim &&
newTrim)
{
start = DateTime.UtcNow;
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();
foreach(ulong badSector in tmpArray)
{
if(aborted)
if(_aborted)
{
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!");
_dumpLog.WriteLine("Aborted!");
break;
}
@@ -382,44 +382,44 @@ namespace DiscImageChef.Core.Devices.Dumping
if(error)
continue;
resume.BadBlocks.Remove(badSector);
_resume.BadBlocks.Remove(badSector);
extents.Add(badSector);
outputPlugin.WriteSector(cmdBuf, badSector);
_outputPlugin.WriteSector(cmdBuf, badSector);
}
EndProgress?.Invoke();
end = DateTime.UtcNow;
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
#region Error handling
if(resume.BadBlocks.Count > 0 &&
!aborted &&
retryPasses > 0)
if(_resume.BadBlocks.Count > 0 &&
!_aborted &&
_retryPasses > 0)
{
int pass = 1;
bool forward = true;
InitProgress?.Invoke();
repeatRetryLba:
ulong[] tmpArray = resume.BadBlocks.ToArray();
ulong[] tmpArray = _resume.BadBlocks.ToArray();
foreach(ulong badSector in tmpArray)
{
if(aborted)
if(_aborted)
{
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!");
_dumpLog.WriteLine("Aborted!");
break;
}
PulseProgress?.Invoke(string.Format("Retrying sector {0}, pass {1}, {3}{2}", badSector,
pass, forward ? "forward" : "reverse",
persistent ? "recovering partial data, " : ""));
_persistent ? "recovering partial data, " : ""));
bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration);
@@ -427,24 +427,24 @@ namespace DiscImageChef.Core.Devices.Dumping
if(!error)
{
resume.BadBlocks.Remove(badSector);
_resume.BadBlocks.Remove(badSector);
extents.Add(badSector);
outputPlugin.WriteSector(cmdBuf, badSector);
_outputPlugin.WriteSector(cmdBuf, badSector);
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)
outputPlugin.WriteSector(cmdBuf, badSector);
else if(_persistent)
_outputPlugin.WriteSector(cmdBuf, badSector);
}
if(pass < retryPasses &&
!aborted &&
resume.BadBlocks.Count > 0)
if(pass < _retryPasses &&
!_aborted &&
_resume.BadBlocks.Count > 0)
{
pass++;
forward = !forward;
resume.BadBlocks.Sort();
resume.BadBlocks.Reverse();
_resume.BadBlocks.Sort();
_resume.BadBlocks.Reverse();
goto repeatRetryLba;
}
@@ -457,8 +457,8 @@ namespace DiscImageChef.Core.Devices.Dumping
}
else
{
mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(outputPrefix + ".ibg", ATA_PROFILE);
mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(_outputPrefix + ".ibg", ATA_PROFILE);
ulong currentBlock = 0;
blocks = (ulong)(cylinders * heads * sectors);
@@ -473,11 +473,11 @@ namespace DiscImageChef.Core.Devices.Dumping
{
for(byte sc = 1; sc < sectors; sc++)
{
if(aborted)
if(_aborted)
{
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!");
_dumpLog.WriteLine("Aborted!");
break;
}
@@ -505,25 +505,25 @@ namespace DiscImageChef.Core.Devices.Dumping
ibgLog.Write(currentBlock, currentSpeed * 1024);
DateTime writeStart = DateTime.Now;
outputPlugin.WriteSector(cmdBuf,
(ulong)((cy * heads + hd) * sectors + (sc - 1)));
_outputPlugin.WriteSector(cmdBuf,
(ulong)((((cy * heads) + hd) * sectors) + (sc - 1)));
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
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);
}
else
{
resume.BadBlocks.Add(currentBlock);
_resume.BadBlocks.Add(currentBlock);
mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration);
ibgLog.Write(currentBlock, 0);
DateTime writeStart = DateTime.Now;
outputPlugin.WriteSector(new byte[blockSize],
(ulong)((cy * heads + hd) * sectors + (sc - 1)));
_outputPlugin.WriteSector(new byte[blockSize],
(ulong)((((cy * heads) + hd) * sectors) + (sc - 1)));
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
}
@@ -536,7 +536,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(elapsed < 1)
continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow;
}
@@ -547,47 +547,47 @@ namespace DiscImageChef.Core.Devices.Dumping
EndProgress?.Invoke();
mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 /
(totalDuration / 1000), devicePath);
ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
(blockSize * (double)(blocks + 1)) / 1024 /
(totalDuration / 1000), _devicePath);
UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");
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?.
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.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
_dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000));
dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 /
_dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
((double)blockSize * (double)(blocks + 1)) / 1024 /
(imageWriteDuration / 1000));
}
foreach(ulong bad in resume.BadBlocks)
dumpLog.WriteLine("Sector {0} could not be read.", bad);
foreach(ulong bad in _resume.BadBlocks)
_dumpLog.WriteLine("Sector {0} could not be read.", bad);
outputPlugin.SetDumpHardware(resume.Tries);
_outputPlugin.SetDumpHardware(_resume.Tries);
if(preSidecar != null)
outputPlugin.SetCicmMetadata(preSidecar);
if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar);
dumpLog.WriteLine("Closing output file.");
_dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now;
outputPlugin.Close();
_outputPlugin.Close();
DateTime closeEnd = DateTime.Now;
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!");
return;
@@ -595,12 +595,12 @@ namespace DiscImageChef.Core.Devices.Dumping
double totalChkDuration = 0;
if(!nometadata)
if(!_nometadata)
{
dumpLog.WriteLine("Creating sidecar.");
_dumpLog.WriteLine("Creating sidecar.");
UpdateStatus?.Invoke("Creating sidecar.");
var filters = new FiltersList();
IFilter filter = filters.GetFilter(outputPath);
IFilter filter = filters.GetFilter(_outputPath);
IMediaImage inputPlugin = ImageFormat.Detect(filter);
if(!inputPlugin.Open(filter))
@@ -611,60 +611,64 @@ namespace DiscImageChef.Core.Devices.Dumping
}
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;
sidecar = preSidecar;
_preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = _preSidecar;
}
if(dev.IsUsb &&
dev.UsbDescriptors != null)
if(_dev.IsUsb &&
_dev.UsbDescriptors != null)
{
dumpLog.WriteLine("Reading USB descriptors.");
_dumpLog.WriteLine("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)
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 &&
dev.Cis != null)
if(_dev.IsPcmcia &&
_dev.Cis != null)
{
dumpLog.WriteLine("Reading PCMCIA CIS.");
_dumpLog.WriteLine("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)
sidecar.BlockMedia[0].PCMCIA = new PCMCIAType
{
CIS = new DumpType
{
Image = outputPath, Size = (ulong)dev.Cis.Length,
Checksums = Checksum.GetChecksums(dev.Cis).ToArray()
Image = _outputPath, Size = (ulong)_dev.Cis.Length,
Checksums = Checksum.GetChecksums(_dev.Cis).ToArray()
}
};
dumpLog.WriteLine("Decoding PCMCIA CIS.");
_dumpLog.WriteLine("Decoding PCMCIA CIS.");
UpdateStatus?.Invoke("Decoding PCMCIA CIS.");
Tuple[] tuples = CIS.GetTuples(dev.Cis);
Tuple[] tuples = CIS.GetTuples(_dev.Cis);
if(tuples != null)
foreach(Tuple tuple in tuples)
@@ -676,8 +680,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(manfid != null)
{
sidecar.BlockMedia[0].PCMCIA.ManufacturerCode =
manfid.ManufacturerID;
sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = manfid.ManufacturerID;
sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID;
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)
sidecar.BlockMedia[0].ATA = new ATAType
{
Identify = new DumpType
{
Image = outputPath, Size = (ulong)cmdBuf.Length,
Image = _outputPath, Size = (ulong)cmdBuf.Length,
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($"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.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000));
_dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
((double)blockSize * (double)(blocks + 1)) / 1024 /
(totalChkDuration / 1000));
List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>();
@@ -746,15 +750,15 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.
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);
}
(string type, string subType) xmlType;
if(dev.IsCompactFlash)
if(_dev.IsCompactFlash)
xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.CompactFlash);
else if(dev.IsPcmcia)
else if(_dev.IsPcmcia)
xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.PCCardTypeI);
else
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].PhysicalBlockSize = physicalsectorsize;
sidecar.BlockMedia[0].LogicalBlockSize = blockSize;
sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer;
sidecar.BlockMedia[0].Model = dev.Model;
sidecar.BlockMedia[0].Serial = dev.Serial;
sidecar.BlockMedia[0].Manufacturer = _dev.Manufacturer;
sidecar.BlockMedia[0].Model = _dev.Model;
sidecar.BlockMedia[0].Serial = _dev.Serial;
sidecar.BlockMedia[0].Size = blocks * blockSize;
if(cylinders > 0 &&
@@ -784,7 +788,7 @@ namespace DiscImageChef.Core.Devices.Dumping
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));
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).");
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($"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)
resume.BadBlocks.Sort();
if(_resume.BadBlocks.Count > 0)
_resume.BadBlocks.Sort();
UpdateStatus?.Invoke("");
}
if(dev.IsCompactFlash)
if(_dev.IsCompactFlash)
Statistics.AddMedia(MediaType.CompactFlash, true);
else if(dev.IsPcmcia)
else if(_dev.IsPcmcia)
Statistics.AddMedia(MediaType.PCCardTypeI, true);
else
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
{
readonly Device dev;
readonly string devicePath;
readonly bool doResume;
readonly DumpLog dumpLog;
readonly bool dumpRaw;
readonly Encoding encoding;
readonly bool force;
readonly Dictionary<string, string> formatOptions;
readonly bool nometadata;
readonly bool notrim;
readonly string outputPath;
readonly IWritableImage outputPlugin;
readonly string outputPrefix;
readonly bool persistent;
readonly CICMMetadataType preSidecar;
readonly ushort retryPasses;
readonly bool stopOnError;
bool aborted;
bool dumpFirstTrackPregap;
Resume resume;
Sidecar sidecarClass;
uint skip;
readonly Device _dev;
readonly string _devicePath;
readonly bool _doResume;
readonly DumpLog _dumpLog;
readonly bool _dumpRaw;
readonly Encoding _encoding;
readonly bool _force;
readonly Dictionary<string, string> _formatOptions;
readonly bool _nometadata;
readonly bool _notrim;
readonly string _outputPath;
readonly IWritableImage _outputPlugin;
readonly string _outputPrefix;
readonly bool _persistent;
readonly CICMMetadataType _preSidecar;
readonly ushort _retryPasses;
readonly bool _stopOnError;
bool _aborted;
bool _dumpFirstTrackPregap;
Resume _resume;
Sidecar _sidecarClass;
uint _skip;
/// <summary>
/// Initializes dumpers
/// </summary>
/// <summary>Initializes dumpers</summary>
/// <param name="doResume">Should resume?</param>
/// <param name="dev">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="skip">How many sectors to skip reading on error</param>
/// <param name="nometadata">Create metadata sidecar after dump?</param>
public Dump(bool doResume, Device dev, string devicePath,
IWritableImage outputPlugin, ushort retryPasses,
bool force, bool dumpRaw, bool persistent,
bool stopOnError, Resume resume, DumpLog dumpLog,
Encoding encoding, string outputPrefix, string outputPath,
Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar, uint skip, bool nometadata,
bool notrim, bool dumpFirstTrackPregap)
public Dump(bool doResume, Device dev, string devicePath, IWritableImage outputPlugin, ushort retryPasses,
bool force, bool dumpRaw, bool persistent, bool stopOnError, Resume resume, DumpLog dumpLog,
Encoding encoding, string outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar, uint skip, bool nometadata, bool notrim, bool dumpFirstTrackPregap)
{
this.doResume = doResume;
this.dev = dev;
this.devicePath = devicePath;
this.outputPlugin = outputPlugin;
this.retryPasses = retryPasses;
this.force = force;
this.dumpRaw = dumpRaw;
this.persistent = persistent;
this.stopOnError = stopOnError;
this.resume = resume;
this.dumpLog = dumpLog;
this.encoding = encoding;
this.outputPrefix = outputPrefix;
this.outputPath = outputPath;
this.formatOptions = formatOptions;
this.preSidecar = preSidecar;
this.skip = skip;
this.nometadata = nometadata;
this.notrim = notrim;
this.dumpFirstTrackPregap = dumpFirstTrackPregap;
aborted = false;
_doResume = doResume;
_dev = dev;
_devicePath = devicePath;
_outputPlugin = outputPlugin;
_retryPasses = retryPasses;
_force = force;
_dumpRaw = dumpRaw;
_persistent = persistent;
_stopOnError = stopOnError;
_resume = resume;
_dumpLog = dumpLog;
_encoding = encoding;
_outputPrefix = outputPrefix;
_outputPath = outputPath;
_formatOptions = formatOptions;
_preSidecar = preSidecar;
_skip = skip;
_nometadata = nometadata;
_notrim = notrim;
_dumpFirstTrackPregap = dumpFirstTrackPregap;
_aborted = false;
}
/// <summary>
/// Starts dumping with the stablished fields and autodetecting the device type
/// </summary>
/// <summary>Starts dumping with the stablished fields and autodetecting the device type</summary>
public void Start()
{
if(dev.IsUsb && dev.UsbVendorId == 0x054C &&
(dev.UsbProductId == 0x01C8 || dev.UsbProductId == 0x01C9 || dev.UsbProductId == 0x02D2))
if(_dev.IsUsb &&
_dev.UsbVendorId == 0x054C &&
(_dev.UsbProductId == 0x01C8 || _dev.UsbProductId == 0x01C9 || _dev.UsbProductId == 0x02D2))
PlayStationPortable();
else
switch(dev.Type)
switch(_dev.Type)
{
case DeviceType.ATA:
Ata();
break;
case DeviceType.MMC:
case DeviceType.SecureDigital:
SecureDigital();
break;
case DeviceType.NVMe:
NVMe();
break;
case DeviceType.ATAPI:
case DeviceType.SCSI:
Scsi();
break;
default:
dumpLog.WriteLine("Unknown device type.");
dumpLog.Close();
_dumpLog.WriteLine("Unknown device type.");
_dumpLog.Close();
StoppingErrorMessage?.Invoke("Unknown device type.");
return;
}
dumpLog.Close();
_dumpLog.Close();
if(resume == null || !doResume) return;
if(_resume == null ||
!_doResume)
return;
resume.LastWriteDate = DateTime.UtcNow;
resume.BadBlocks.Sort();
_resume.LastWriteDate = DateTime.UtcNow;
_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);
XmlSerializer xs = new XmlSerializer(resume.GetType());
xs.Serialize(fs, resume);
var fs = new FileStream(_outputPrefix + ".resume.xml", FileMode.Create, FileAccess.ReadWrite);
var xs = new XmlSerializer(_resume.GetType());
xs.Serialize(fs, _resume);
fs.Close();
}
public void Abort()
{
aborted = true;
sidecarClass?.Abort();
_aborted = true;
_sidecarClass?.Abort();
}
/// <summary>
/// Event raised when the progress bar is not longer needed
/// </summary>
/// <summary>Event raised when the progress bar is not longer needed</summary>
public event EndProgressHandler EndProgress;
/// <summary>
/// Event raised when a progress bar is needed
/// </summary>
/// <summary>Event raised when a progress bar is needed</summary>
public event InitProgressHandler InitProgress;
/// <summary>
/// Event raised to report status updates
/// </summary>
/// <summary>Event raised to report status updates</summary>
public event UpdateStatusHandler UpdateStatus;
/// <summary>
/// Event raised to report a non-fatal error
/// </summary>
/// <summary>Event raised to report a non-fatal error</summary>
public event ErrorMessageHandler ErrorMessage;
/// <summary>
/// Event raised to report a fatal error that stops the dumping operation and should call user's attention
/// </summary>
/// <summary>Event raised to report a fatal error that stops the dumping operation and should call user's attention</summary>
public event ErrorMessageHandler StoppingErrorMessage;
/// <summary>
/// Event raised to update the values of a determinate progress bar
/// </summary>
/// <summary>Event raised to update the values of a determinate progress bar</summary>
public event UpdateProgressHandler UpdateProgress;
/// <summary>
/// Event raised to update the status of an undeterminate progress bar
/// </summary>
/// <summary>Event raised to update the status of an undeterminate progress bar</summary>
public event PulseProgressHandler PulseProgress;
/// <summary>
/// Event raised when the progress bar is not longer needed
/// </summary>
/// <summary>Event raised when the progress bar is not longer needed</summary>
public event EndProgressHandler2 EndProgress2;
/// <summary>
/// Event raised when a progress bar is needed
/// </summary>
/// <summary>Event raised when a progress bar is needed</summary>
public event InitProgressHandler2 InitProgress2;
/// <summary>
/// Event raised to update the values of a determinate progress bar
/// </summary>
/// <summary>Event raised to update the values of a determinate progress bar</summary>
public event UpdateProgressHandler2 UpdateProgress2;
}
}

View File

@@ -58,13 +58,13 @@ namespace DiscImageChef.Core.Devices.Dumping
bool isXbox = false;
// 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 _);
if(!sense)
{
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)
{
@@ -176,9 +176,9 @@ namespace DiscImageChef.Core.Devices.Dumping
return;
}
var scsiReader = new Reader(dev, dev.Timeout, null, dumpRaw);
var scsiReader = new Reader(_dev, _dev.Timeout, null, _dumpRaw);
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[]>();
if(dskType == MediaType.PD650)
@@ -208,10 +208,10 @@ namespace DiscImageChef.Core.Devices.Dumping
switch(dskType)
{
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,
MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _);
if(!sense)
{
@@ -221,7 +221,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(nintendoPfi.Value.DiskCategory == DiskCategory.Nintendo &&
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?.
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.HDDVDRW:
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,
MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _);
if(!sense)
if(PFI.Decode(cmdBuf).HasValue)
@@ -326,10 +326,10 @@ 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,
MmcDiscStructureFormat.DiscManufacturingInformation, 0, dev.Timeout,
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DiscManufacturingInformation, 0, _dev.Timeout,
out _);
if(!sense)
@@ -352,13 +352,13 @@ namespace DiscImageChef.Core.Devices.Dumping
dskType = MediaType.XGD3;
}
sense = dev.ScsiInquiry(out byte[] inqBuf, out _);
sense = _dev.ScsiInquiry(out byte[] inqBuf, out _);
if(sense ||
!Inquiry.Decode(inqBuf).HasValue ||
(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?.
Invoke("Dumping Xbox Game Discs requires a drive with Kreon firmware.");
@@ -366,7 +366,7 @@ namespace DiscImageChef.Core.Devices.Dumping
return;
}
if(dumpRaw && !force)
if(_dumpRaw && !_force)
{
StoppingErrorMessage?.
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 ||
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,
MmcDiscStructureFormat.CopyrightInformation, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.CopyrightInformation, 0, _dev.Timeout, out _);
if(!sense)
if(CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue)
@@ -418,10 +418,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.DVDDownload:
case MediaType.DVDROM:
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,
MmcDiscStructureFormat.BurstCuttingArea, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.BurstCuttingArea, 0, _dev.Timeout, out _);
if(!sense)
{
@@ -436,10 +436,10 @@ namespace DiscImageChef.Core.Devices.Dumping
#region DVD-RAM and HD DVD-RAM
case MediaType.DVDRAM:
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,
MmcDiscStructureFormat.DvdramDds, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdramDds, 0, _dev.Timeout, out _);
if(!sense)
if(DDS.Decode(cmdBuf).HasValue)
@@ -449,10 +449,10 @@ namespace DiscImageChef.Core.Devices.Dumping
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,
MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, dev.Timeout,
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, _dev.Timeout,
out _);
if(!sense)
@@ -469,10 +469,10 @@ namespace DiscImageChef.Core.Devices.Dumping
#region DVD-R and DVD-RW
case MediaType.DVDR:
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,
MmcDiscStructureFormat.PreRecordedInfo, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PreRecordedInfo, 0, _dev.Timeout, out _);
if(!sense)
{
@@ -491,10 +491,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.DVDR:
case MediaType.DVDRW:
case MediaType.HDDVDR:
dumpLog.WriteLine("Reading Media Identifier.");
_dumpLog.WriteLine("Reading Media Identifier.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdrMediaIdentifier, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdrMediaIdentifier, 0, _dev.Timeout, out _);
if(!sense)
{
@@ -503,10 +503,10 @@ namespace DiscImageChef.Core.Devices.Dumping
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,
MmcDiscStructureFormat.DvdrPhysicalInformation, 0, dev.Timeout,
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DvdrPhysicalInformation, 0, _dev.Timeout,
out _);
if(!sense)
@@ -524,10 +524,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.DVDPRDL:
case MediaType.DVDPRW:
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,
MmcDiscStructureFormat.Adip, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.Adip, 0, _dev.Timeout, out _);
if(!sense)
{
@@ -536,10 +536,10 @@ namespace DiscImageChef.Core.Devices.Dumping
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,
MmcDiscStructureFormat.Dcb, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.Dcb, 0, _dev.Timeout, out _);
if(!sense)
{
@@ -553,10 +553,10 @@ namespace DiscImageChef.Core.Devices.Dumping
#region HD DVD-ROM
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,
MmcDiscStructureFormat.HddvdCopyrightInformation, 0, dev.Timeout,
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.HddvdCopyrightInformation, 0, _dev.Timeout,
out _);
if(!sense)
@@ -575,10 +575,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.BDROM:
case MediaType.BDRXL:
case MediaType.BDREXL:
dumpLog.WriteLine("Reading Disc Information.");
_dumpLog.WriteLine("Reading Disc Information.");
sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.DiscInformation, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.DiscInformation, 0, _dev.Timeout, out _);
if(!sense)
if(DI.Decode(cmdBuf).HasValue)
@@ -607,10 +607,10 @@ namespace DiscImageChef.Core.Devices.Dumping
{
#region BD-ROM only
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,
MmcDiscStructureFormat.BdBurstCuttingArea, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.BdBurstCuttingArea, 0, _dev.Timeout, out _);
if(!sense)
{
@@ -627,10 +627,10 @@ namespace DiscImageChef.Core.Devices.Dumping
case MediaType.BDRE:
case MediaType.BDRXL:
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,
MmcDiscStructureFormat.BdDds, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.BdDds, 0, _dev.Timeout, out _);
if(!sense)
{
@@ -639,10 +639,11 @@ namespace DiscImageChef.Core.Devices.Dumping
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,
MmcDiscStructureFormat.BdSpareAreaInformation, 0, dev.Timeout, out _);
sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
MmcDiscStructureFormat.BdSpareAreaInformation, 0, _dev.Timeout,
out _);
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
{
/// <summary>
/// Implements dumping SCSI and ATAPI devices
/// </summary>
/// <summary>Implements dumping SCSI and ATAPI devices</summary>
public partial class Dump
{
// TODO: Get cartridge serial number from Certance vendor EVPD
/// <summary>
/// Dumps a SCSI Block Commands device or a Reduced Block Commands devices
/// </summary>
/// <summary>Dumps a SCSI Block Commands device or a Reduced Block Commands devices</summary>
public void Scsi()
{
MediaType dskType = MediaType.Unknown;
int resets = 0;
if(dev.IsRemovable)
if(_dev.IsRemovable)
{
InitProgress?.Invoke();
deviceGotReset:
bool sense = dev.ScsiTestUnitReady(out byte[] senseBuf, dev.Timeout, out _);
bool sense = _dev.ScsiTestUnitReady(out byte[] senseBuf, _dev.Timeout, out _);
if(sense)
{
FixedSense? decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue)
{
ErrorMessage
?.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",
ErrorMessage?.
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);
// Just retry, for 5 times
if(decSense.Value.ASC == 0x29)
{
resets++;
if(resets < 5) goto deviceGotReset;
if(resets < 5)
goto deviceGotReset;
}
if(decSense.Value.ASC == 0x3A)
{
int leftRetries = 5;
while(leftRetries > 0)
{
PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
if(!sense) break;
sense = _dev.ScsiTestUnitReady(out senseBuf, _dev.Timeout, out _);
if(!sense)
break;
decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue)
{
ErrorMessage
?.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);
ErrorMessage?.
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);
}
leftRetries--;
@@ -98,26 +105,34 @@ namespace DiscImageChef.Core.Devices.Dumping
if(sense)
{
StoppingErrorMessage?.Invoke("Please insert media in drive");
return;
}
}
else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01)
else if(decSense.Value.ASC == 0x04 &&
decSense.Value.ASCQ == 0x01)
{
int leftRetries = 50;
while(leftRetries > 0)
{
PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
if(!sense) break;
sense = _dev.ScsiTestUnitReady(out senseBuf, _dev.Timeout, out _);
if(!sense)
break;
decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue)
{
ErrorMessage
?.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);
ErrorMessage?.
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);
}
leftRetries--;
@@ -125,8 +140,9 @@ namespace DiscImageChef.Core.Devices.Dumping
if(sense)
{
StoppingErrorMessage
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
StoppingErrorMessage?.
Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return;
}
}
@@ -147,20 +163,26 @@ namespace DiscImageChef.Core.Devices.Dumping
else if(decSense.Value.ASC == 0x28)
{
int leftRetries = 10;
while(leftRetries > 0)
{
PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
if(!sense) break;
sense = _dev.ScsiTestUnitReady(out senseBuf, _dev.Timeout, out _);
if(!sense)
break;
decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue)
{
ErrorMessage
?.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);
ErrorMessage?.
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);
}
leftRetries--;
@@ -168,21 +190,24 @@ namespace DiscImageChef.Core.Devices.Dumping
if(sense)
{
StoppingErrorMessage
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
StoppingErrorMessage?.
Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return;
}
}
else
{
StoppingErrorMessage
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
StoppingErrorMessage?.
Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return;
}
}
else
{
StoppingErrorMessage?.Invoke("Unknown testing unit was ready.");
return;
}
}
@@ -190,28 +215,34 @@ namespace DiscImageChef.Core.Devices.Dumping
EndProgress?.Invoke();
}
switch(dev.ScsiType)
switch(_dev.ScsiType)
{
case PeripheralDeviceTypes.SequentialAccess:
if(dumpRaw)
if(_dumpRaw)
{
StoppingErrorMessage?.Invoke("Tapes cannot be dumped raw.");
return;
}
if(outputPlugin is IWritableTapeImage) Ssc();
if(_outputPlugin is IWritableTapeImage)
Ssc();
else
StoppingErrorMessage
?.Invoke("The specified plugin does not support storing streaming tape images.");
StoppingErrorMessage?.
Invoke("The specified plugin does not support storing streaming tape images.");
return;
case PeripheralDeviceTypes.MultiMediaDevice:
if(outputPlugin is IWritableOpticalImage) Mmc(ref dskType);
if(_outputPlugin is IWritableOpticalImage)
Mmc(ref dskType);
else
StoppingErrorMessage
?.Invoke("The specified plugin does not support storing optical disc images.");
StoppingErrorMessage?.
Invoke("The specified plugin does not support storing optical disc images.");
return;
default:
Sbc(null, ref dskType, false);
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>
public void SecureDigital()
{
if(dumpRaw)
if(_dumpRaw)
{
if(force)
if(_force)
ErrorMessage?.
Invoke("Raw dumping is not supported in MultiMediaCard or SecureDigital devices. Continuing...");
else
@@ -84,13 +84,13 @@ namespace DiscImageChef.Core.Devices.Dumping
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>();
switch(dev.Type)
switch(_dev.Type)
{
case DeviceType.MMC:
{
UpdateStatus?.Invoke("Reading Extended CSD");
dumpLog.WriteLine("Reading Extended CSD");
sense = dev.ReadExtendedCsd(out ecsd, out _, TIMEOUT, out duration);
_dumpLog.WriteLine("Reading Extended CSD");
sense = _dev.ReadExtendedCsd(out ecsd, out _, TIMEOUT, out duration);
if(!sense)
{
@@ -112,8 +112,8 @@ namespace DiscImageChef.Core.Devices.Dumping
ecsd = null;
UpdateStatus?.Invoke("Reading CSD");
dumpLog.WriteLine("Reading CSD");
sense = dev.ReadCsd(out csd, out _, TIMEOUT, out duration);
_dumpLog.WriteLine("Reading CSD");
sense = _dev.ReadCsd(out csd, out _, TIMEOUT, out duration);
if(!sense)
{
@@ -130,8 +130,8 @@ namespace DiscImageChef.Core.Devices.Dumping
csd = null;
UpdateStatus?.Invoke("Reading OCR");
dumpLog.WriteLine("Reading OCR");
sense = dev.ReadOcr(out ocr, out _, TIMEOUT, out duration);
_dumpLog.WriteLine("Reading OCR");
sense = _dev.ReadOcr(out ocr, out _, TIMEOUT, out duration);
if(sense)
ocr = null;
@@ -144,8 +144,8 @@ namespace DiscImageChef.Core.Devices.Dumping
case DeviceType.SecureDigital:
{
UpdateStatus?.Invoke("Reading CSD");
dumpLog.WriteLine("Reading CSD");
sense = dev.ReadCsd(out csd, out _, TIMEOUT, out duration);
_dumpLog.WriteLine("Reading CSD");
sense = _dev.ReadCsd(out csd, out _, TIMEOUT, out duration);
if(!sense)
{
@@ -165,8 +165,8 @@ namespace DiscImageChef.Core.Devices.Dumping
csd = null;
UpdateStatus?.Invoke("Reading OCR");
dumpLog.WriteLine("Reading OCR");
sense = dev.ReadSdocr(out ocr, out _, TIMEOUT, out duration);
_dumpLog.WriteLine("Reading OCR");
sense = _dev.ReadSdocr(out ocr, out _, TIMEOUT, out duration);
if(sense)
ocr = null;
@@ -174,8 +174,8 @@ namespace DiscImageChef.Core.Devices.Dumping
mediaTags.Add(MediaTagType.SD_OCR, null);
UpdateStatus?.Invoke("Reading SCR");
dumpLog.WriteLine("Reading SCR");
sense = dev.ReadScr(out scr, out _, TIMEOUT, out duration);
_dumpLog.WriteLine("Reading SCR");
sense = _dev.ReadScr(out scr, out _, TIMEOUT, out duration);
if(sense)
scr = null;
@@ -187,13 +187,13 @@ namespace DiscImageChef.Core.Devices.Dumping
}
UpdateStatus?.Invoke("Reading CID");
dumpLog.WriteLine("Reading CID");
sense = dev.ReadCid(out byte[] cid, out _, TIMEOUT, out duration);
_dumpLog.WriteLine("Reading CID");
sense = _dev.ReadCid(out byte[] cid, out _, TIMEOUT, out duration);
if(sense)
cid = null;
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 end;
@@ -204,21 +204,21 @@ namespace DiscImageChef.Core.Devices.Dumping
if(blocks == 0)
{
dumpLog.WriteLine("Unable to get device size.");
_dumpLog.WriteLine("Unable to get device size.");
StoppingErrorMessage?.Invoke("Unable to get device size.");
return;
}
UpdateStatus?.Invoke($"Device reports {blocks} blocks.");
dumpLog.WriteLine("Device reports {0} blocks.", blocks);
_dumpLog.WriteLine("Device reports {0} blocks.", blocks);
byte[] cmdBuf;
bool error;
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)
blocksToRead /= 2;
@@ -230,23 +230,23 @@ namespace DiscImageChef.Core.Devices.Dumping
if(error)
{
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.");
_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.");
return;
}
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)
skip = blocksToRead;
if(_skip < blocksToRead)
_skip = blocksToRead;
DumpHardwareType currentTry = null;
ExtentsULong extents = null;
ResumeSupport.Process(true, false, blocks, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformId,
ref resume, ref currentTry, ref extents);
ResumeSupport.Process(true, false, blocks, _dev.Manufacturer, _dev.Model, _dev.Serial, _dev.PlatformId,
ref _resume, ref currentTry, ref extents);
if(currentTry == null ||
extents == null)
@@ -260,53 +260,53 @@ namespace DiscImageChef.Core.Devices.Dumping
foreach(MediaTagType tag in mediaTags.Keys)
{
if(outputPlugin.SupportedMediaTags.Contains(tag))
if(_outputPlugin.SupportedMediaTags.Contains(tag))
continue;
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}.");
}
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...");
}
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...");
return;
}
}
var mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
var ibgLog = new IbgLog(outputPrefix + ".ibg", SD_PROFILE);
var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead);
var ibgLog = new IbgLog(_outputPrefix + ".ibg", SD_PROFILE);
ret = outputPlugin.Create(outputPath,
dev.Type == DeviceType.SecureDigital ? MediaType.SecureDigital : MediaType.MMC,
formatOptions, blocks, blockSize);
ret = _outputPlugin.Create(_outputPath,
_dev.Type == DeviceType.SecureDigital ? MediaType.SecureDigital : MediaType.MMC,
_formatOptions, blocks, blockSize);
// Cannot create image
if(!ret)
{
dumpLog.WriteLine("Error creating output image, not continuing.");
dumpLog.WriteLine(outputPlugin.ErrorMessage);
_dumpLog.WriteLine("Error creating output image, not continuing.");
_dumpLog.WriteLine(_outputPlugin.ErrorMessage);
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
outputPlugin.ErrorMessage);
_outputPlugin.ErrorMessage);
return;
}
if(resume.NextBlock > 0)
if(_resume.NextBlock > 0)
{
UpdateStatus?.Invoke($"Resuming from block {resume.NextBlock}.");
dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
UpdateStatus?.Invoke($"Resuming from block {_resume.NextBlock}.");
_dumpLog.WriteLine("Resuming from block {0}.", _resume.NextBlock);
}
start = DateTime.UtcNow;
@@ -317,13 +317,13 @@ namespace DiscImageChef.Core.Devices.Dumping
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);
UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!");
_dumpLog.WriteLine("Aborted!");
break;
}
@@ -344,7 +344,7 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
(long)blocks);
error = dev.Read(out cmdBuf, out _, (uint)i, blockSize, blocksToRead, byteAddressed, TIMEOUT,
error = _dev.Read(out cmdBuf, out _, (uint)i, blockSize, blocksToRead, byteAddressed, TIMEOUT,
out duration);
if(!error)
@@ -352,38 +352,38 @@ namespace DiscImageChef.Core.Devices.Dumping
mhddLog.Write(i, duration);
ibgLog.Write(i, currentSpeed * 1024);
DateTime writeStart = DateTime.Now;
outputPlugin.WriteSectors(cmdBuf, i, blocksToRead);
_outputPlugin.WriteSectors(cmdBuf, i, blocksToRead);
imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
extents.Add(i, blocksToRead, true);
}
else
{
if(i + skip > blocks)
skip = (uint)(blocks - i);
if(i + _skip > blocks)
_skip = (uint)(blocks - i);
for(ulong b = i; b < i + skip; b++)
resume.BadBlocks.Add(b);
for(ulong b = i; b < i + _skip; b++)
_resume.BadBlocks.Add(b);
mhddLog.Write(i, duration < 500 ? 65535 : duration);
ibgLog.Write(i, 0);
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;
dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i);
i += skip - blocksToRead;
_dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
i += _skip - blocksToRead;
newTrim = true;
}
sectorSpeedStart += blocksToRead;
resume.NextBlock = i + blocksToRead;
_resume.NextBlock = i + blocksToRead;
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
if(elapsed < 1)
continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow;
}
@@ -392,53 +392,53 @@ namespace DiscImageChef.Core.Devices.Dumping
EndProgress?.Invoke();
mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000),
devicePath);
ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
(blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000),
_devicePath);
UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");
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?.
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.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
_dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000));
dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration);
_dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration);
#region Trimming
if(resume.BadBlocks.Count > 0 &&
!aborted &&
!notrim &&
if(_resume.BadBlocks.Count > 0 &&
!_aborted &&
!_notrim &&
newTrim)
{
start = DateTime.UtcNow;
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();
foreach(ulong badSector in tmpArray)
{
if(aborted)
if(_aborted)
{
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!");
_dumpLog.WriteLine("Aborted!");
break;
}
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);
totalDuration += duration;
@@ -446,22 +446,22 @@ namespace DiscImageChef.Core.Devices.Dumping
if(error)
continue;
resume.BadBlocks.Remove(badSector);
_resume.BadBlocks.Remove(badSector);
extents.Add(badSector);
outputPlugin.WriteSector(cmdBuf, badSector);
_outputPlugin.WriteSector(cmdBuf, badSector);
}
EndProgress?.Invoke();
end = DateTime.UtcNow;
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
#region Error handling
if(resume.BadBlocks.Count > 0 &&
!aborted &&
retryPasses > 0)
if(_resume.BadBlocks.Count > 0 &&
!_aborted &&
_retryPasses > 0)
{
int pass = 1;
bool forward = true;
@@ -469,15 +469,15 @@ namespace DiscImageChef.Core.Devices.Dumping
InitProgress?.Invoke();
repeatRetryLba:
ulong[] tmpArray = resume.BadBlocks.ToArray();
ulong[] tmpArray = _resume.BadBlocks.ToArray();
foreach(ulong badSector in tmpArray)
{
if(aborted)
if(_aborted)
{
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
UpdateStatus?.Invoke("Aborted!");
dumpLog.WriteLine("Aborted!");
_dumpLog.WriteLine("Aborted!");
break;
}
@@ -486,31 +486,31 @@ namespace DiscImageChef.Core.Devices.Dumping
forward ? "forward" : "reverse",
runningPersistent ? "recovering partial data, " : ""));
error = dev.Read(out cmdBuf, out _, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT,
error = _dev.Read(out cmdBuf, out _, (uint)badSector, blockSize, 1, byteAddressed, TIMEOUT,
out duration);
totalDuration += duration;
if(!error)
{
resume.BadBlocks.Remove(badSector);
_resume.BadBlocks.Remove(badSector);
extents.Add(badSector);
outputPlugin.WriteSector(cmdBuf, badSector);
_outputPlugin.WriteSector(cmdBuf, badSector);
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)
outputPlugin.WriteSector(cmdBuf, badSector);
_outputPlugin.WriteSector(cmdBuf, badSector);
}
if(pass < retryPasses &&
!aborted &&
resume.BadBlocks.Count > 0)
if(pass < _retryPasses &&
!_aborted &&
_resume.BadBlocks.Count > 0)
{
pass++;
forward = !forward;
resume.BadBlocks.Sort();
resume.BadBlocks.Reverse();
_resume.BadBlocks.Sort();
_resume.BadBlocks.Reverse();
goto repeatRetryLba;
}
@@ -521,58 +521,58 @@ namespace DiscImageChef.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
outputPlugin.SetDumpHardware(resume.Tries);
_outputPlugin.SetDumpHardware(_resume.Tries);
if(preSidecar != null)
outputPlugin.SetCicmMetadata(preSidecar);
if(_preSidecar != null)
_outputPlugin.SetCicmMetadata(_preSidecar);
dumpLog.WriteLine("Closing output file.");
_dumpLog.WriteLine("Closing output file.");
UpdateStatus?.Invoke("Closing output file.");
DateTime closeStart = DateTime.Now;
outputPlugin.Close();
_outputPlugin.Close();
DateTime closeEnd = DateTime.Now;
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!");
dumpLog.WriteLine("Aborted!");
_dumpLog.WriteLine("Aborted!");
return;
}
double totalChkDuration = 0;
if(!nometadata)
if(!_nometadata)
{
UpdateStatus?.Invoke("Creating sidecar.");
dumpLog.WriteLine("Creating sidecar.");
_dumpLog.WriteLine("Creating sidecar.");
var filters = new FiltersList();
IFilter filter = filters.GetFilter(outputPath);
IFilter filter = filters.GetFilter(_outputPath);
IMediaImage inputPlugin = ImageFormat.Detect(filter);
if(!inputPlugin.Open(filter))
StoppingErrorMessage?.Invoke("Could not open created image.");
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();
_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)
if(_preSidecar != null)
{
preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = preSidecar;
_preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = _preSidecar;
}
switch(dev.Type)
switch(_dev.Type)
{
case DeviceType.MMC:
sidecar.BlockMedia[0].MultiMediaCard = new MultiMediaCardType();
@@ -592,22 +592,22 @@ namespace DiscImageChef.Core.Devices.Dumping
{
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 =
outputPlugin.WriteMediaTag(cid,
dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID
_outputPlugin.WriteMediaTag(cid,
_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CID
: MediaTagType.MMC_CID);
// Cannot write CID to image
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 +
outputPlugin.ErrorMessage);
_outputPlugin.ErrorMessage);
return;
}
@@ -617,22 +617,22 @@ namespace DiscImageChef.Core.Devices.Dumping
{
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 =
outputPlugin.WriteMediaTag(csd,
dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CSD
_outputPlugin.WriteMediaTag(csd,
_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_CSD
: MediaTagType.MMC_CSD);
// Cannot write CSD to image
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 +
outputPlugin.ErrorMessage);
_outputPlugin.ErrorMessage);
return;
}
@@ -642,20 +642,21 @@ namespace DiscImageChef.Core.Devices.Dumping
{
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
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." +
Environment.NewLine +
outputPlugin.ErrorMessage);
_outputPlugin.ErrorMessage);
return;
}
@@ -665,22 +666,22 @@ namespace DiscImageChef.Core.Devices.Dumping
{
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 =
outputPlugin.WriteMediaTag(ocr,
dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_OCR
_outputPlugin.WriteMediaTag(ocr,
_dev.Type == DeviceType.SecureDigital ? MediaTagType.SD_OCR
: MediaTagType.MMC_OCR);
// Cannot write OCR to image
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 +
outputPlugin.ErrorMessage);
_outputPlugin.ErrorMessage);
return;
}
@@ -690,25 +691,25 @@ namespace DiscImageChef.Core.Devices.Dumping
{
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
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 +
outputPlugin.ErrorMessage);
_outputPlugin.ErrorMessage);
return;
}
}
switch(dev.Type)
switch(_dev.Type)
{
case DeviceType.MMC:
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($"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.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000));
_dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
((double)blockSize * (double)(blocks + 1)) / 1024 / (totalChkDuration / 1000));
(string type, string subType) xmlType = (null, null);
switch(dev.Type)
switch(_dev.Type)
{
case DeviceType.MMC:
xmlType =
CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.MMC);
xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(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].PhysicalBlockSize = physicalBlockSize > 0 ? physicalBlockSize : blockSize;
sidecar.BlockMedia[0].LogicalBlockSize = blockSize;
sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer;
sidecar.BlockMedia[0].Model = dev.Model;
sidecar.BlockMedia[0].Serial = dev.Serial;
sidecar.BlockMedia[0].Manufacturer = _dev.Manufacturer;
sidecar.BlockMedia[0].Model = _dev.Model;
sidecar.BlockMedia[0].Serial = _dev.Serial;
sidecar.BlockMedia[0].Size = blocks * blockSize;
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));
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).");
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($"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("");
if(resume.BadBlocks.Count > 0)
resume.BadBlocks.Sort();
if(_resume.BadBlocks.Count > 0)
_resume.BadBlocks.Sort();
switch(dev.Type)
switch(_dev.Type)
{
case DeviceType.MMC:
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 MediaType = DiscImageChef.CommonTypes.MediaType;
// ReSharper disable UnusedMember.Local
namespace DiscImageChef.Gui.Forms
{
public class frmDump : Form
{
readonly string devicePath;
Device dev;
Dump dumper;
string outputPrefix;
Resume resume;
CICMMetadataType sidecar;
readonly string _devicePath;
Device _dev;
Dump _dumper;
string _outputPrefix;
Resume _resume;
CICMMetadataType _sidecar;
public frmDump(string devicePath, DeviceInfo deviceInfo, ScsiInfo scsiInfo = null)
{
@@ -189,7 +191,7 @@ namespace DiscImageChef.Gui.Forms
break;
}
this.devicePath = devicePath;
_devicePath = devicePath;
}
void OnCmbFormatSelectedIndexChanged(object sender, EventArgs e)
@@ -318,7 +320,7 @@ namespace DiscImageChef.Gui.Forms
if(result != DialogResult.Ok)
{
txtDestination.Text = "";
outputPrefix = null;
_outputPrefix = null;
return;
}
@@ -328,7 +330,7 @@ namespace DiscImageChef.Gui.Forms
txtDestination.Text = dlgDestination.FileName;
outputPrefix = Path.Combine(Path.GetDirectoryName(dlgDestination.FileName),
_outputPrefix = Path.Combine(Path.GetDirectoryName(dlgDestination.FileName),
Path.GetFileNameWithoutExtension(dlgDestination.FileName));
chkResume.Checked = true;
@@ -344,7 +346,7 @@ namespace DiscImageChef.Gui.Forms
{
if(chkExistingMetadata.Checked == false)
{
sidecar = null;
_sidecar = null;
return;
}
@@ -370,7 +372,7 @@ namespace DiscImageChef.Gui.Forms
try
{
var sr = new StreamReader(dlgMetadata.FileName);
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
_sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
sr.Close();
}
catch
@@ -385,19 +387,19 @@ namespace DiscImageChef.Gui.Forms
if(chkResume.Checked == false)
return;
if(outputPrefix != null)
if(_outputPrefix != null)
CheckResumeFile();
}
void CheckResumeFile()
{
resume = null;
_resume = null;
var xs = new XmlSerializer(typeof(Resume));
try
{
var sr = new StreamReader(outputPrefix + ".resume.xml");
resume = (Resume)xs.Deserialize(sr);
var sr = new StreamReader(_outputPrefix + ".resume.xml");
_resume = (Resume)xs.Deserialize(sr);
sr.Close();
}
catch
@@ -408,9 +410,9 @@ namespace DiscImageChef.Gui.Forms
return;
}
if(resume == null ||
resume.NextBlock <= resume.LastBlock ||
(resume.BadBlocks.Count != 0 && !resume.Tape))
if(_resume == null ||
_resume.NextBlock <= _resume.LastBlock ||
(_resume.BadBlocks.Count != 0 && !_resume.Tape))
return;
MessageBox.Show("Media already dumped correctly, please choose another destination...",
@@ -424,7 +426,7 @@ namespace DiscImageChef.Gui.Forms
void OnBtnStopClick(object sender, EventArgs e)
{
btnStop.Enabled = false;
dumper.Abort();
_dumper.Abort();
}
void OnBtnDumpClick(object sender, EventArgs e)
@@ -442,15 +444,15 @@ namespace DiscImageChef.Gui.Forms
try
{
dev = new Device(devicePath);
_dev = new Device(_devicePath);
if(dev.IsRemote)
Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem,
dev.RemoteOperatingSystemVersion, dev.RemoteArchitecture);
if(_dev.IsRemote)
Statistics.AddRemote(_dev.RemoteApplication, _dev.RemoteVersion, _dev.RemoteOperatingSystem,
_dev.RemoteOperatingSystemVersion, _dev.RemoteArchitecture);
if(dev.Error)
if(_dev.Error)
{
StoppingErrorMessage($"Error {dev.LastError} opening device.");
StoppingErrorMessage($"Error {_dev.LastError} opening device.");
return;
}
@@ -462,7 +464,7 @@ namespace DiscImageChef.Gui.Forms
return;
}
Statistics.AddDevice(dev);
Statistics.AddDevice(_dev);
Statistics.AddCommand("dump-media");
if(!(cmbFormat.SelectedValue is IWritableImage outputFormat))
@@ -515,14 +517,15 @@ namespace DiscImageChef.Gui.Forms
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);
dumper = new Dump(chkResume.Checked == true, dev, devicePath, outputFormat, (ushort)stpRetries.Value,
_dumper = new Dump(chkResume.Checked == true, _dev, _devicePath, outputFormat,
(ushort)stpRetries.Value,
chkForce.Checked == true, false, chkPersistent.Checked == true,
chkStopOnError.Checked == true, resume, dumpLog, encoding, outputPrefix,
txtDestination.Text, parsedOptions, sidecar, (uint)stpSkipped.Value,
chkStopOnError.Checked == true, _resume, dumpLog, encoding, _outputPrefix,
txtDestination.Text, parsedOptions, _sidecar, (uint)stpSkipped.Value,
chkExistingMetadata.Checked == false, chkTrim.Checked == false,
chkTrack1Pregap.Checked == true);
@@ -531,20 +534,20 @@ namespace DiscImageChef.Gui.Forms
void DoWork()
{
dumper.UpdateStatus += UpdateStatus;
dumper.ErrorMessage += ErrorMessage;
dumper.StoppingErrorMessage += StoppingErrorMessage;
dumper.PulseProgress += PulseProgress;
dumper.InitProgress += InitProgress;
dumper.UpdateProgress += UpdateProgress;
dumper.EndProgress += EndProgress;
dumper.InitProgress2 += InitProgress2;
dumper.UpdateProgress2 += UpdateProgress2;
dumper.EndProgress2 += EndProgress2;
_dumper.UpdateStatus += UpdateStatus;
_dumper.ErrorMessage += ErrorMessage;
_dumper.StoppingErrorMessage += StoppingErrorMessage;
_dumper.PulseProgress += PulseProgress;
_dumper.InitProgress += InitProgress;
_dumper.UpdateProgress += UpdateProgress;
_dumper.EndProgress += EndProgress;
_dumper.InitProgress2 += InitProgress2;
_dumper.UpdateProgress2 += UpdateProgress2;
_dumper.EndProgress2 += EndProgress2;
dumper.Start();
_dumper.Start();
dev.Close();
_dev.Close();
WorkFinished();
}
@@ -643,6 +646,7 @@ namespace DiscImageChef.Gui.Forms
}
#region XAML IDs
// ReSharper disable InconsistentNaming
ComboBox cmbFormat;
TextBox txtDestination;
Button btnDestination;
@@ -673,6 +677,8 @@ namespace DiscImageChef.Gui.Forms
Label lblProgress2;
ProgressBar prgProgress2;
StackLayout stkOptions;
// ReSharper restore InconsistentNaming
#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/=checksumming/@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/=DDCD/@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
{
// TODO: Add raw dumping
internal class DumpMediaCommand : Command
{
string cicmXml;
string devicePath;
bool doResume = true;
string encodingName;
bool firstTrackPregap;
bool force;
bool noMetadata;
bool noTrim;
string outputFile;
string outputOptions;
bool persistent;
// TODO: Add raw dumping
ushort retryPasses = 5;
bool showHelp;
int skip = 512;
bool stopOnError;
string wantedOutputFormat;
string _cicmXml;
string _devicePath;
bool _doResume = true;
string _encodingName;
bool _firstTrackPregap;
bool _force;
bool _noMetadata;
bool _noTrim;
string _outputFile;
string _outputOptions;
bool _persistent;
ushort _retryPasses = 5;
bool _showHelp;
int _skip = 512;
bool _stopOnError;
string _wantedOutputFormat;
public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [OPTIONS] devicepath outputimage",
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [OPTIONS] device_path output_image",
"", 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)
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=",
"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-trim", "Disables trimming errored from skipped sectors.", b => noTrim = 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("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
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)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
if(_showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
@@ -157,31 +153,31 @@ namespace DiscImageChef.Commands
return(int)ErrorNumber.MissingArgument;
}
devicePath = extra[0];
outputFile = extra[1];
_devicePath = extra[0];
_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", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", encodingName);
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", "--format={0}", wantedOutputFormat);
DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", noMetadata);
DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", _devicePath);
DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", _encodingName);
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", "--format={0}", _wantedOutputFormat);
DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", _noMetadata);
DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", Options);
DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", outputFile);
DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", persistent);
DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", _outputFile);
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
//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:");
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
@@ -189,10 +185,10 @@ namespace DiscImageChef.Commands
Encoding encoding = null;
if(encodingName != null)
if(_encodingName != null)
try
{
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
encoding = Claunia.Encoding.Encoding.GetEncoding(_encodingName);
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
@@ -204,17 +200,17 @@ namespace DiscImageChef.Commands
return(int)ErrorNumber.EncodingUnknown;
}
if(devicePath.Length == 2 &&
devicePath[1] == ':' &&
devicePath[0] != '/' &&
char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
if(_devicePath.Length == 2 &&
_devicePath[1] == ':' &&
_devicePath[0] != '/' &&
char.IsLetter(_devicePath[0]))
_devicePath = "\\\\.\\" + char.ToUpper(_devicePath[0]) + ':';
Device dev;
try
{
dev = new Device(devicePath);
dev = new Device(_devicePath);
if(dev.IsRemote)
Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem,
@@ -236,13 +232,13 @@ namespace DiscImageChef.Commands
Statistics.AddDevice(dev);
string outputPrefix = Path.Combine(Path.GetDirectoryName(outputFile),
Path.GetFileNameWithoutExtension(outputFile));
string outputPrefix = Path.Combine(Path.GetDirectoryName(_outputFile),
Path.GetFileNameWithoutExtension(_outputFile));
Resume resume = null;
var xs = new XmlSerializer(typeof(Resume));
if(File.Exists(outputPrefix + ".resume.xml") && doResume)
if(File.Exists(outputPrefix + ".resume.xml") && _doResume)
try
{
var sr = new StreamReader(outputPrefix + ".resume.xml");
@@ -269,12 +265,12 @@ namespace DiscImageChef.Commands
CICMMetadataType sidecar = null;
var sidecarXs = new XmlSerializer(typeof(CICMMetadataType));
if(cicmXml != null)
if(File.Exists(cicmXml))
if(_cicmXml != null)
if(File.Exists(_cicmXml))
{
try
{
var sr = new StreamReader(cicmXml);
var sr = new StreamReader(_cicmXml);
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
sr.Close();
}
@@ -296,18 +292,19 @@ namespace DiscImageChef.Commands
List<IWritableImage> candidates = new List<IWritableImage>();
// Try extension
if(string.IsNullOrEmpty(wantedOutputFormat))
if(string.IsNullOrEmpty(_wantedOutputFormat))
candidates.AddRange(plugins.WritableImages.Values.Where(t =>
t.KnownExtensions.
Contains(Path.GetExtension(outputFile))));
Contains(Path.
GetExtension(_outputFile))));
// 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)));
// Try name
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.
InvariantCultureIgnoreCase)));
@@ -340,9 +337,9 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
}
var dumper = new Dump(doResume, dev, devicePath, outputFormat, retryPasses, force, false, persistent,
stopOnError, resume, dumpLog, encoding, outputPrefix, outputFile, parsedOptions,
sidecar, (uint)skip, noMetadata, noTrim, firstTrackPregap);
var dumper = new Dump(_doResume, dev, _devicePath, outputFormat, _retryPasses, _force, false, _persistent,
_stopOnError, resume, dumpLog, encoding, outputPrefix, _outputFile, parsedOptions,
sidecar, (uint)_skip, _noMetadata, _noTrim, _firstTrackPregap);
dumper.UpdateStatus += Progress.UpdateStatus;
dumper.ErrorMessage += Progress.ErrorMessage;