mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
* DiscImageChef.Decoders/SCSI/Modes.cs:
* DiscImageChef.Decoders/SCSI/ModesEncoders.cs: * DiscImageChef.Decoders/DiscImageChef.Decoders.csproj: Added encoders for Mode 6 and 10, Mode pages 0x01 and 0x01 for MultiMedia Devices. * commandline: * DiscImageChef.Devices/Device/ScsiCommands/SPC.cs: Added MODE SELECT (6) and MODE SELECT (10) commands. * DiscImageChef.Filesystems/FFS.cs: Corrected array initialization. * DiscImageChef/Commands/Decode.cs: * DiscImageChef/Commands/Verify.cs: * DiscImageChef/Commands/Analyze.cs: * DiscImageChef/Commands/Entropy.cs: * DiscImageChef/Commands/Checksum.cs: * DiscImageChef/Commands/PrintHex.cs: * DiscImageChef/Commands/CreateSidecar.cs: Check if image file exists before proceeding. * DiscImageChef/Commands/MediaInfo.cs: * DiscImageChef/Commands/MediaScan.cs: * DiscImageChef/Commands/DeviceInfo.cs: * DiscImageChef/Commands/DeviceReport.cs: Check if device exists before proceeding. * DiscImageChef/Commands/DumpMedia.cs: Check if device exists before proceeding. Removed unused code. Added error handling procedures for non CDs. * DiscImageChef/Options.cs: Remove unused options. Added options to control dump-media error handling.
This commit is contained in:
@@ -1,3 +1,29 @@
|
||||
2016-02-04 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* Commands/Decode.cs:
|
||||
* Commands/Verify.cs:
|
||||
* Commands/Analyze.cs:
|
||||
* Commands/Entropy.cs:
|
||||
* Commands/Checksum.cs:
|
||||
* Commands/PrintHex.cs:
|
||||
* Commands/CreateSidecar.cs:
|
||||
Check if image file exists before proceeding.
|
||||
|
||||
* Commands/MediaInfo.cs:
|
||||
* Commands/MediaScan.cs:
|
||||
* Commands/DeviceInfo.cs:
|
||||
* Commands/DeviceReport.cs:
|
||||
Check if device exists before proceeding.
|
||||
|
||||
* Commands/DumpMedia.cs:
|
||||
Check if device exists before proceeding.
|
||||
Removed unused code.
|
||||
Added error handling procedures for non CDs.
|
||||
|
||||
* Options.cs:
|
||||
Remove unused options.
|
||||
Added options to control dump-media error handling.
|
||||
|
||||
2016-02-03 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* Commands/Configure.cs:
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace DiscImageChef.Commands
|
||||
|
||||
if (!System.IO.File.Exists(options.InputFile))
|
||||
{
|
||||
DicConsole.WriteLine("Specified file does not exist.");
|
||||
DicConsole.ErrorWriteLine("Specified file does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Checksum command", "--sha512={0}", options.DoSHA512);
|
||||
DicConsole.DebugWriteLine("Checksum command", "--spamsum={0}", options.DoSpamSum);
|
||||
|
||||
if (!System.IO.File.Exists(options.InputFile))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified file does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile);
|
||||
|
||||
if (inputFormat == null)
|
||||
|
||||
@@ -58,6 +58,12 @@ namespace DiscImageChef.Commands
|
||||
plugins.RegisterAllPlugins();
|
||||
ImagePlugin _imageFormat;
|
||||
|
||||
if (!System.IO.File.Exists(options.InputFile))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified file does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_imageFormat = ImageFormat.Detect(options.InputFile);
|
||||
|
||||
@@ -53,6 +53,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Decode command", "--disk-tags={0}", options.DiskTags);
|
||||
DicConsole.DebugWriteLine("Decode command", "--sector-tags={0}", options.SectorTags);
|
||||
|
||||
if (!System.IO.File.Exists(options.InputFile))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified file does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile);
|
||||
|
||||
if (inputFormat == null)
|
||||
|
||||
@@ -53,6 +53,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Device-Info command", "--device={0}", options.DevicePath);
|
||||
DicConsole.DebugWriteLine("Device-Info command", "--output-prefix={0}", options.OutputPrefix);
|
||||
|
||||
if (!System.IO.File.Exists(options.DevicePath))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified device does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' &&
|
||||
options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0]))
|
||||
{
|
||||
|
||||
@@ -52,6 +52,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Device-Report command", "--verbose={0}", options.Verbose);
|
||||
DicConsole.DebugWriteLine("Device-Report command", "--device={0}", options.DevicePath);
|
||||
|
||||
if (!System.IO.File.Exists(options.DevicePath))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified device does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' &&
|
||||
options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0]))
|
||||
{
|
||||
|
||||
@@ -52,7 +52,6 @@ namespace DiscImageChef.Commands
|
||||
static FileStream mhddFs;
|
||||
static FileStream dataFs;
|
||||
// TODO: Implement dump map
|
||||
static FileStream mapFs;
|
||||
|
||||
public static void doDumpMedia(DumpMediaSubOptions options)
|
||||
{
|
||||
@@ -63,7 +62,14 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", options.Raw);
|
||||
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", options.StopOnError);
|
||||
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", options.Force);
|
||||
DicConsole.DebugWriteLine("Dump-Media command", "--reset={0}", options.Reset);
|
||||
DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", options.RetryPasses);
|
||||
DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", options.Persistent);
|
||||
|
||||
if (!System.IO.File.Exists(options.DevicePath))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified device does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' &&
|
||||
options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0]))
|
||||
@@ -123,8 +129,8 @@ namespace DiscImageChef.Commands
|
||||
|
||||
static void doSCSIMediaScan(DumpMediaSubOptions options, Device dev)
|
||||
{
|
||||
byte[] cmdBuf;
|
||||
byte[] senseBuf;
|
||||
byte[] cmdBuf = null;
|
||||
byte[] senseBuf = null;
|
||||
bool sense = false;
|
||||
double duration;
|
||||
ulong blocks = 0;
|
||||
@@ -135,8 +141,6 @@ namespace DiscImageChef.Commands
|
||||
|
||||
if (dev.IsRemovable)
|
||||
{
|
||||
bool deviceReset = false;
|
||||
retryTestReady:
|
||||
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out duration);
|
||||
if (sense)
|
||||
{
|
||||
@@ -1773,6 +1777,200 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.WriteLine();
|
||||
closeMHDDLogFile();
|
||||
|
||||
#region Error handling
|
||||
if (unreadableSectors.Count > 0 && !aborted)
|
||||
{
|
||||
List<ulong> tmpList = new List<ulong>();
|
||||
|
||||
foreach (ulong ur in unreadableSectors)
|
||||
{
|
||||
for (ulong i = ur; i < ur + blocksToRead; i++)
|
||||
tmpList.Add(i);
|
||||
}
|
||||
|
||||
tmpList.Sort();
|
||||
|
||||
int pass = 0;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
|
||||
unreadableSectors = tmpList;
|
||||
|
||||
repeatRetry:
|
||||
ulong [] tmpArray = unreadableSectors.ToArray();
|
||||
foreach (ulong badSector in tmpArray)
|
||||
{
|
||||
if (aborted)
|
||||
break;
|
||||
|
||||
double cmdDuration = 0;
|
||||
|
||||
DicConsole.Write("\rRetrying sector {0}, pass {1}, {3}{2}", badSector, pass + 1, forward ? "forward" : "reverse", runningPersistent ? "recovering partial data, " : "");
|
||||
|
||||
if(readLong16)
|
||||
{
|
||||
sense = dev.ReadLong16(out readBuffer, out senseBuf, false, badSector, blockSize, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(readLong10)
|
||||
{
|
||||
sense = dev.ReadLong10(out readBuffer, out senseBuf, false, false, (uint)badSector, (ushort)blockSize, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(syqReadLong10)
|
||||
{
|
||||
sense = dev.SyQuestReadLong10(out readBuffer, out senseBuf, (uint)badSector, blockSize, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(syqReadLong6)
|
||||
{
|
||||
sense = dev.SyQuestReadLong6(out readBuffer, out senseBuf, (uint)badSector, blockSize, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(hldtstReadRaw)
|
||||
{
|
||||
sense = dev.HlDtStReadRawDvd(out readBuffer, out senseBuf, (uint)badSector, blockSize, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if(plextorReadRaw)
|
||||
{
|
||||
sense = dev.PlextorReadRawDvd(out readBuffer, out senseBuf, (uint)badSector, blockSize, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if (read16)
|
||||
{
|
||||
sense = dev.Read16(out readBuffer, out senseBuf, 0, false, true, false, badSector, blockSize, 0, 1, false, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if (read12)
|
||||
{
|
||||
sense = dev.Read12(out readBuffer, out senseBuf, 0, false, false, false, false, (uint)badSector, blockSize, 0, 1, false, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if (read10)
|
||||
{
|
||||
sense = dev.Read10(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector, blockSize, 0, (ushort)1, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
else if (read6)
|
||||
{
|
||||
sense = dev.Read6(out readBuffer, out senseBuf, (uint)badSector, blockSize, (byte)1, dev.Timeout, out cmdDuration);
|
||||
totalDuration += cmdDuration;
|
||||
}
|
||||
|
||||
if (!sense && !dev.Error)
|
||||
{
|
||||
unreadableSectors.Remove(badSector);
|
||||
writeToDataFileAtPosition(readBuffer, badSector, blockSize);
|
||||
}
|
||||
else if(runningPersistent)
|
||||
writeToDataFileAtPosition(readBuffer, badSector, blockSize);
|
||||
}
|
||||
|
||||
if (pass < options.RetryPasses && !aborted && unreadableSectors.Count > 0)
|
||||
{
|
||||
pass++;
|
||||
forward = !forward;
|
||||
unreadableSectors.Sort();
|
||||
unreadableSectors.Reverse();
|
||||
goto repeatRetry;
|
||||
}
|
||||
|
||||
Decoders.SCSI.Modes.DecodedMode? currentMode = null;
|
||||
Decoders.SCSI.Modes.ModePage? currentModePage = null;
|
||||
byte [] md6 = null;
|
||||
byte [] md10 = null;
|
||||
|
||||
if (!runningPersistent && options.Persistent)
|
||||
{
|
||||
sense = dev.ModeSense6(out readBuffer, out senseBuf, false, ScsiModeSensePageControl.Current, 0x01, dev.Timeout, out duration);
|
||||
if (sense)
|
||||
{
|
||||
sense = dev.ModeSense10(out readBuffer, out senseBuf, false, ScsiModeSensePageControl.Current, 0x01, dev.Timeout, out duration);
|
||||
if (!sense)
|
||||
currentMode = Decoders.SCSI.Modes.DecodeMode10(readBuffer, dev.SCSIType);
|
||||
}
|
||||
else
|
||||
currentMode = Decoders.SCSI.Modes.DecodeMode6(readBuffer, dev.SCSIType);
|
||||
|
||||
if (currentMode.HasValue)
|
||||
currentModePage = currentMode.Value.Pages [0];
|
||||
|
||||
if (dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
|
||||
{
|
||||
Decoders.SCSI.Modes.ModePage_01_MMC pgMMC = new Decoders.SCSI.Modes.ModePage_01_MMC();
|
||||
pgMMC.PS = false;
|
||||
pgMMC.ReadRetryCount = 255;
|
||||
pgMMC.Parameter = 0x20;
|
||||
|
||||
Decoders.SCSI.Modes.DecodedMode md = new Decoders.SCSI.Modes.DecodedMode();
|
||||
md.Header = new Decoders.SCSI.Modes.ModeHeader();
|
||||
md.Pages = new Decoders.SCSI.Modes.ModePage [1];
|
||||
md.Pages [0] = new Decoders.SCSI.Modes.ModePage();
|
||||
md.Pages [0].Page = 0x01;
|
||||
md.Pages [0].Subpage = 0x00;
|
||||
md.Pages [0].PageResponse = Decoders.SCSI.Modes.EncodeModePage_01_MMC(pgMMC);
|
||||
md6 = Decoders.SCSI.Modes.EncodeMode6(md, dev.SCSIType);
|
||||
md10 = Decoders.SCSI.Modes.EncodeMode10(md, dev.SCSIType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Decoders.SCSI.Modes.ModePage_01 pg = new Decoders.SCSI.Modes.ModePage_01();
|
||||
pg.PS = false;
|
||||
pg.AWRE = false;
|
||||
pg.ARRE = false;
|
||||
pg.TB = true;
|
||||
pg.RC = false;
|
||||
pg.EER = true;
|
||||
pg.PER = false;
|
||||
pg.DTE = false;
|
||||
pg.DCR = false;
|
||||
pg.ReadRetryCount = 255;
|
||||
|
||||
Decoders.SCSI.Modes.DecodedMode md = new Decoders.SCSI.Modes.DecodedMode();
|
||||
md.Header = new Decoders.SCSI.Modes.ModeHeader();
|
||||
md.Pages = new Decoders.SCSI.Modes.ModePage [1];
|
||||
md.Pages [0] = new Decoders.SCSI.Modes.ModePage();
|
||||
md.Pages [0].Page = 0x01;
|
||||
md.Pages [0].Subpage = 0x00;
|
||||
md.Pages [0].PageResponse = Decoders.SCSI.Modes.EncodeModePage_01(pg);
|
||||
md6 = Decoders.SCSI.Modes.EncodeMode6(md, dev.SCSIType);
|
||||
md10 = Decoders.SCSI.Modes.EncodeMode10(md, dev.SCSIType);
|
||||
}
|
||||
|
||||
sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out duration);
|
||||
if (sense)
|
||||
{
|
||||
sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out duration);
|
||||
}
|
||||
|
||||
runningPersistent = true;
|
||||
if (!sense && !dev.Error)
|
||||
{
|
||||
pass = 0;
|
||||
goto repeatRetry;
|
||||
}
|
||||
}
|
||||
else if (runningPersistent && options.Persistent && currentModePage.HasValue)
|
||||
{
|
||||
Decoders.SCSI.Modes.DecodedMode md = new Decoders.SCSI.Modes.DecodedMode();
|
||||
md.Header = new Decoders.SCSI.Modes.ModeHeader();
|
||||
md.Pages = new Decoders.SCSI.Modes.ModePage [1];
|
||||
md.Pages [0] = currentModePage.Value;
|
||||
md6 = Decoders.SCSI.Modes.EncodeMode6(md, dev.SCSIType);
|
||||
md10 = Decoders.SCSI.Modes.EncodeMode10(md, dev.SCSIType);
|
||||
|
||||
sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out duration);
|
||||
if (sense)
|
||||
{
|
||||
sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out duration);
|
||||
}
|
||||
}
|
||||
|
||||
DicConsole.WriteLine();
|
||||
}
|
||||
#endregion Error handling
|
||||
|
||||
dataChk = new Core.Checksum();
|
||||
dataFs.Seek(0, SeekOrigin.Begin);
|
||||
blocksToRead = 500;
|
||||
@@ -1917,7 +2115,7 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", (((double)blockSize * (double)(blocks + 1)) / 1048576) / (totalDuration / 1000));
|
||||
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);
|
||||
DicConsole.WriteLine("Slowest speed burst: {0:F3} MiB/sec.", minSpeed);
|
||||
DicConsole.WriteLine("{0} sectors could not be read.", errored);
|
||||
DicConsole.WriteLine("{0} sectors could not be read.", unreadableSectors.Count);
|
||||
if (unreadableSectors.Count > 0)
|
||||
{
|
||||
foreach (ulong bad in unreadableSectors)
|
||||
@@ -2061,6 +2259,12 @@ namespace DiscImageChef.Commands
|
||||
dataFs.Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
static void writeToDataFileAtPosition(byte[] data, ulong block, uint blockSize)
|
||||
{
|
||||
dataFs.Seek((long)(block * blockSize), SeekOrigin.Begin);
|
||||
dataFs.Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
static void closeDataFile()
|
||||
{
|
||||
if (dataFs != null)
|
||||
|
||||
@@ -54,6 +54,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Entropy command", "--input={0}", options.InputFile);
|
||||
DicConsole.DebugWriteLine("Entropy command", "--duplicated-sectors={0}", options.DuplicatedSectors);
|
||||
|
||||
if (!System.IO.File.Exists(options.InputFile))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified file does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile);
|
||||
|
||||
if (inputFormat == null)
|
||||
|
||||
@@ -53,6 +53,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Media-Info command", "--device={0}", options.DevicePath);
|
||||
DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", options.OutputPrefix);
|
||||
|
||||
if (!System.IO.File.Exists(options.DevicePath))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified device does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' &&
|
||||
options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0]))
|
||||
{
|
||||
|
||||
@@ -61,7 +61,6 @@ namespace DiscImageChef.Commands
|
||||
static double ibgIntSpeed;
|
||||
static int ibgSnaps;
|
||||
static ulong ibgIntSector = 0;
|
||||
static double ibgIntTime = 0;
|
||||
static int ibgSampleRate;
|
||||
|
||||
public static void doMediaScan(MediaScanSubOptions options)
|
||||
@@ -72,6 +71,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", options.MHDDLogPath);
|
||||
DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", options.IBGLogPath);
|
||||
|
||||
if (!System.IO.File.Exists(options.DevicePath))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified device does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' &&
|
||||
options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0]))
|
||||
{
|
||||
@@ -881,8 +886,7 @@ namespace DiscImageChef.Commands
|
||||
ibgIntSpeed = 0;
|
||||
ibgSnaps = 0;
|
||||
ibgIntSector = 0;
|
||||
ibgIntTime = 0;
|
||||
|
||||
|
||||
switch (currentProfile)
|
||||
{
|
||||
case 0x0001:
|
||||
|
||||
@@ -53,6 +53,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("PrintHex command", "--long-sectors={0}", options.LongSectors);
|
||||
DicConsole.DebugWriteLine("PrintHex command", "--WidthBytes={0}", options.WidthBytes);
|
||||
|
||||
if (!System.IO.File.Exists(options.InputFile))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified file does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile);
|
||||
|
||||
if (inputFormat == null)
|
||||
|
||||
@@ -52,6 +52,12 @@ namespace DiscImageChef.Commands
|
||||
DicConsole.DebugWriteLine("Verify command", "--verify-disc={0}", options.VerifyDisc);
|
||||
DicConsole.DebugWriteLine("Verify command", "--verify-sectors={0}", options.VerifySectors);
|
||||
|
||||
if (!System.IO.File.Exists(options.InputFile))
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Specified file does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile);
|
||||
|
||||
if (inputFormat == null)
|
||||
|
||||
@@ -263,7 +263,6 @@ namespace DiscImageChef
|
||||
public string InputFile { get; set; }
|
||||
}
|
||||
|
||||
// TODO: Add more options
|
||||
public class DumpMediaSubOptions : CommonSubOptions
|
||||
{
|
||||
[Option('i', "device", Required = true, HelpText = "Device path.")]
|
||||
@@ -277,16 +276,21 @@ namespace DiscImageChef
|
||||
public bool Raw { get; set; }
|
||||
|
||||
[Option('s', "stop-on-error", DefaultValue = false,
|
||||
HelpText = "Print sectors with tags included.")]
|
||||
HelpText = "Stop media dump on first error.")]
|
||||
public bool StopOnError { get; set; }
|
||||
|
||||
[Option('f', "force", DefaultValue = false,
|
||||
HelpText = "Continue dump whatever happens.")]
|
||||
public bool Force { get; set; }
|
||||
|
||||
[Option("reset", DefaultValue = (ushort)0,
|
||||
HelpText = "Reset the device after these many errors. 0 to disable.")]
|
||||
public ushort Reset { get; set; }
|
||||
[Option('p', "retry-passes", DefaultValue = (ushort)5,
|
||||
HelpText = "How many retry passes to do.")]
|
||||
public ushort RetryPasses { get; set; }
|
||||
|
||||
[Option("persistent", DefaultValue = false,
|
||||
HelpText = "Try to recover partial or incorrect data.")]
|
||||
public bool Persistent { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class DeviceReportSubOptions : CommonSubOptions
|
||||
|
||||
Reference in New Issue
Block a user