diff --git a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs index fef2c81ad..b425cf069 100644 --- a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs +++ b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs @@ -57,7 +57,7 @@ namespace DiscImageChef.Core.Devices.Dumping internal class CompactDisc { // TODO: Add support for resume file - internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar, ref MediaType dskType, bool separateSubchannel, ref Resume resume, ref DumpLog dumpLog, Alcohol120 alcohol) + internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar, ref MediaType dskType, bool separateSubchannel, ref Resume resume, ref DumpLog dumpLog, Alcohol120 alcohol, bool dumpLeadIn) { MHDDLog mhddLog; IBGLog ibgLog; @@ -419,87 +419,91 @@ namespace DiscImageChef.Core.Devices.Dumping if(currentTry == null || extents == null) throw new Exception("Could not process resume file, not continuing..."); - DicConsole.WriteLine("Trying to read Lead-In..."); - bool gotLeadIn = false; - int leadInSectorsGood = 0, leadInSectorsTotal = 0; - - dumpFile = new DataFile(outputPrefix + ".leadin.bin"); - dataChk = new Checksum(); - - start = DateTime.UtcNow; - - readBuffer = null; - - dumpLog.WriteLine("Reading Lead-in"); - for(int leadInBlock = -150; leadInBlock < 0 && resume.NextBlock == 0; leadInBlock++) + if(dumpLeadIn) { - if(dev.PlatformID == Interop.PlatformID.FreeBSD) + DicConsole.WriteLine("Trying to read Lead-In..."); + bool gotLeadIn = false; + int leadInSectorsGood = 0, leadInSectorsTotal = 0; + + dumpFile = new DataFile(outputPrefix + ".leadin.bin"); + dataChk = new Checksum(); + + start = DateTime.UtcNow; + + readBuffer = null; + + dumpLog.WriteLine("Reading Lead-in"); + for(int leadInBlock = -150; leadInBlock < 0 && resume.NextBlock == 0; leadInBlock++) { - DicConsole.DebugWriteLine("Dump-Media", "FreeBSD panics when reading CD Lead-in, see upstream bug #224253."); - break; - } - - if(aborted) - { - dumpLog.WriteLine("Aborted!"); - break; - } + if(dev.PlatformID == Interop.PlatformID.FreeBSD) + { + DicConsole.DebugWriteLine("Dump-Media", + "FreeBSD panics when reading CD Lead-in, see upstream bug #224253."); + break; + } + + if(aborted) + { + dumpLog.WriteLine("Aborted!"); + break; + } #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator - if(currentSpeed > maxSpeed && currentSpeed != 0) - maxSpeed = currentSpeed; - if(currentSpeed < minSpeed && currentSpeed != 0) - minSpeed = currentSpeed; + if(currentSpeed > maxSpeed && currentSpeed != 0) maxSpeed = currentSpeed; + if(currentSpeed < minSpeed && currentSpeed != 0) minSpeed = currentSpeed; #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator - DicConsole.Write("\rTrying to read lead-in sector {0} ({1:F3} MiB/sec.)", leadInBlock, currentSpeed); + DicConsole.Write("\rTrying to read lead-in sector {0} ({1:F3} MiB/sec.)", leadInBlock, + currentSpeed); - sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)leadInBlock, blockSize, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, - true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out double cmdDuration); + sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)leadInBlock, blockSize, 1, + MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, + true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, + out double cmdDuration); - if(!sense && !dev.Error) - { - dataChk.Update(readBuffer); - dumpFile.Write(readBuffer); - gotLeadIn = true; - leadInSectorsGood++; - leadInSectorsTotal++; - } - else - { - if(gotLeadIn) + if(!sense && !dev.Error) { - // Write empty data - dataChk.Update(new byte[blockSize]); - dumpFile.Write(new byte[blockSize]); + dataChk.Update(readBuffer); + dumpFile.Write(readBuffer); + gotLeadIn = true; + leadInSectorsGood++; leadInSectorsTotal++; } - } + else + { + if(gotLeadIn) + { + // Write empty data + dataChk.Update(new byte[blockSize]); + dumpFile.Write(new byte[blockSize]); + leadInSectorsTotal++; + } + } #pragma warning disable IDE0004 // Remove Unnecessary Cast - currentSpeed = ((double)blockSize / (double)1048576) / (cmdDuration / (double)1000); + currentSpeed = ((double)blockSize / (double)1048576) / (cmdDuration / (double)1000); #pragma warning restore IDE0004 // Remove Unnecessary Cast - } + } - dumpFile.Close(); - if(leadInSectorsGood > 0) - { - sidecar.OpticalDisc[0].LeadIn = new BorderType[] + dumpFile.Close(); + if(leadInSectorsGood > 0) { - new BorderType - { - Image = outputPrefix + ".leadin.bin", - Checksums = dataChk.End().ToArray(), - Size = leadInSectorsTotal * blockSize - } - }; - } - else - File.Delete(outputPrefix + ".leadin.bin"); + sidecar.OpticalDisc[0].LeadIn = new BorderType[] + { + new BorderType + { + Image = outputPrefix + ".leadin.bin", + Checksums = dataChk.End().ToArray(), + Size = leadInSectorsTotal * blockSize + } + }; + } + else File.Delete(outputPrefix + ".leadin.bin"); - DicConsole.WriteLine(); - DicConsole.WriteLine("Got {0} lead-in sectors.", leadInSectorsGood); - dumpLog.WriteLine("Got {0} Lead-in sectors.", leadInSectorsGood); + DicConsole.WriteLine(); + DicConsole.WriteLine("Got {0} lead-in sectors.", leadInSectorsGood); + dumpLog.WriteLine("Got {0} Lead-in sectors.", leadInSectorsGood); + } while(true) { diff --git a/DiscImageChef.Core/Devices/Dumping/MMC.cs b/DiscImageChef.Core/Devices/Dumping/MMC.cs index 9365620a9..3b23f411a 100644 --- a/DiscImageChef.Core/Devices/Dumping/MMC.cs +++ b/DiscImageChef.Core/Devices/Dumping/MMC.cs @@ -46,7 +46,7 @@ namespace DiscImageChef.Core.Devices.Dumping { internal static class MMC { - internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar, ref MediaType dskType, bool separateSubchannel, ref Metadata.Resume resume, ref DumpLog dumpLog) + internal static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, ref CICMMetadataType sidecar, ref MediaType dskType, bool separateSubchannel, ref Metadata.Resume resume, ref DumpLog dumpLog, bool dumpLeadIn) { byte[] cmdBuf = null; byte[] senseBuf = null; @@ -168,7 +168,7 @@ namespace DiscImageChef.Core.Devices.Dumping if(compactDisc) { - CompactDisc.Dump(dev, devicePath, outputPrefix, retryPasses, force, dumpRaw, persistent, stopOnError, ref sidecar, ref dskType, separateSubchannel, ref resume, ref dumpLog, alcohol); + CompactDisc.Dump(dev, devicePath, outputPrefix, retryPasses, force, dumpRaw, persistent, stopOnError, ref sidecar, ref dskType, separateSubchannel, ref resume, ref dumpLog, alcohol, dumpLeadIn); return; } diff --git a/DiscImageChef.Core/Devices/Dumping/SCSI.cs b/DiscImageChef.Core/Devices/Dumping/SCSI.cs index 86d833acf..1fc901779 100644 --- a/DiscImageChef.Core/Devices/Dumping/SCSI.cs +++ b/DiscImageChef.Core/Devices/Dumping/SCSI.cs @@ -48,7 +48,7 @@ namespace DiscImageChef.Core.Devices.Dumping public class SCSI { // TODO: Get cartridge serial number from Certance vendor EVPD - public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, bool separateSubchannel, ref Metadata.Resume resume, ref DumpLog dumpLog) + public static void Dump(Device dev, string devicePath, string outputPrefix, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, bool separateSubchannel, ref Metadata.Resume resume, ref DumpLog dumpLog, bool dumpLeadIn) { byte[] senseBuf = null; bool sense = false; @@ -183,7 +183,7 @@ namespace DiscImageChef.Core.Devices.Dumping if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice) { - MMC.Dump(dev, devicePath, outputPrefix, retryPasses, force, dumpRaw, persistent, stopOnError, ref sidecar, ref dskType, separateSubchannel, ref resume, ref dumpLog); + MMC.Dump(dev, devicePath, outputPrefix, retryPasses, force, dumpRaw, persistent, stopOnError, ref sidecar, ref dskType, separateSubchannel, ref resume, ref dumpLog, dumpLeadIn); return; } diff --git a/DiscImageChef/Commands/DumpMedia.cs b/DiscImageChef/Commands/DumpMedia.cs index d065474c8..04c35fedb 100644 --- a/DiscImageChef/Commands/DumpMedia.cs +++ b/DiscImageChef/Commands/DumpMedia.cs @@ -121,7 +121,7 @@ namespace DiscImageChef.Commands break; case DeviceType.ATAPI: case DeviceType.SCSI: - SCSI.Dump(dev, options.DevicePath, options.OutputPrefix, options.RetryPasses, options.Force, options.Raw, options.Persistent, options.StopOnError, options.SeparateSubchannel, ref resume, ref dumpLog); + SCSI.Dump(dev, options.DevicePath, options.OutputPrefix, options.RetryPasses, options.Force, options.Raw, options.Persistent, options.StopOnError, options.SeparateSubchannel, ref resume, ref dumpLog, options.LeadIn); break; default: dumpLog.WriteLine("Unknown device type."); diff --git a/DiscImageChef/Options.cs b/DiscImageChef/Options.cs index e7877e6cf..14bd5316b 100644 --- a/DiscImageChef/Options.cs +++ b/DiscImageChef/Options.cs @@ -280,7 +280,7 @@ namespace DiscImageChef public string EncodingName { get; set; } } - // TODO: Add encoding + // TODO: Add encoding, check options [Verb("dump-media", HelpText = "Dumps the media inserted on a device to a media image.")] public class DumpMediaOptions : CommonOptions { @@ -291,7 +291,7 @@ namespace DiscImageChef public string OutputPrefix { get; set; } [Option('r', "raw", Default = false, - HelpText = "Print sectors with tags included.")] + HelpText = "Dump sectors with tags included. For optical media, dump scrambled sectors")] public bool Raw { get; set; } [Option('s', "stop-on-error", Default = false, @@ -317,6 +317,9 @@ namespace DiscImageChef [Option('m', "resume", Default = true, HelpText = "Create/use resume mapfile.")] public bool Resume { get; set; } + + [Option("lead-in", Default = true, HelpText = "Try to read lead-in. Only applicable to CD/DDCD/GD.")] + public bool LeadIn { get; set; } } [Verb("device-report", HelpText = "Tests the device capabilities and creates an XML report of them.")]