Catch and print exceptions from device constructor.

This commit is contained in:
2019-11-02 01:15:49 +00:00
parent bdc55dd648
commit 438fa1c9a2
11 changed files with 754 additions and 565 deletions

View File

@@ -267,6 +267,7 @@
<e p="DiscImageChef.Core.csproj" t="IncludeRecursive" /> <e p="DiscImageChef.Core.csproj" t="IncludeRecursive" />
<e p="DiscImageChef.Core.csproj.DotSettings" t="Include" /> <e p="DiscImageChef.Core.csproj.DotSettings" t="Include" />
<e p="Entropy.cs" t="Include" /> <e p="Entropy.cs" t="Include" />
<e p="Error.cs" t="Include" />
<e p="Filesystems.cs" t="Include" /> <e p="Filesystems.cs" t="Include" />
<e p="GetPluginBase.cs" t="Include" /> <e p="GetPluginBase.cs" t="Include" />
<e p="ImageFormat.cs" t="Include" /> <e p="ImageFormat.cs" t="Include" />
@@ -571,6 +572,7 @@
<e p="Commands.cs" t="Include" /> <e p="Commands.cs" t="Include" />
<e p="Constructor.cs" t="Include" /> <e p="Constructor.cs" t="Include" />
<e p="Destructor.cs" t="Include" /> <e p="Destructor.cs" t="Include" />
<e p="DeviceException.cs" t="Include" />
<e p="List.cs" t="Include" /> <e p="List.cs" t="Include" />
<e p="MmcCommands" t="Include"> <e p="MmcCommands" t="Include">
<e p="MMC.cs" t="Include" /> <e p="MMC.cs" t="Include" />

View File

@@ -65,6 +65,7 @@
<Compile Include="Media\Info\XgdInfo.cs" /> <Compile Include="Media\Info\XgdInfo.cs" />
<Compile Include="Options.cs" /> <Compile Include="Options.cs" />
<Compile Include="ImageFormat.cs" /> <Compile Include="ImageFormat.cs" />
<Compile Include="Error.cs" />
<Compile Include="PrintScsiModePages.cs" /> <Compile Include="PrintScsiModePages.cs" />
<Compile Include="Sidecar\Files.cs" /> <Compile Include="Sidecar\Files.cs" />
<Compile Include="Statistics.cs" /> <Compile Include="Statistics.cs" />

106
DiscImageChef.Core/Error.cs Normal file
View File

@@ -0,0 +1,106 @@
using System;
using DiscImageChef.CommonTypes.Interop;
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
namespace DiscImageChef.Core
{
public static class Error
{
public static string Print(int errno)
{
switch (DetectOS.GetRealPlatformID())
{
case PlatformID.Win32S:
case PlatformID.Win32Windows:
case PlatformID.Win32NT:
case PlatformID.WinCE:
case PlatformID.WindowsPhone:
case PlatformID.Xbox:
return PrintWin32Error(errno);
case PlatformID.Unix:
case PlatformID.MacOSX:
case PlatformID.iOS:
case PlatformID.Linux:
case PlatformID.Solaris:
case PlatformID.NetBSD:
case PlatformID.OpenBSD:
case PlatformID.FreeBSD:
case PlatformID.DragonFly:
case PlatformID.Android:
case PlatformID.Tizen:
case PlatformID.Hurd:
case PlatformID.Haiku:
case PlatformID.HPUX:
case PlatformID.AIX:
case PlatformID.OS400:
case PlatformID.IRIX:
case PlatformID.Minix:
case PlatformID.QNX:
case PlatformID.SINIX:
case PlatformID.Tru64:
case PlatformID.Ultrix:
case PlatformID.OpenServer:
case PlatformID.UnixWare:
case PlatformID.zOS:
return PrintUnixError(errno);
case PlatformID.Wii:
return $"Unknown error code {errno}";
case PlatformID.WiiU:
return $"Unknown error code {errno}";
case PlatformID.PlayStation3:
return $"Unknown error code {errno}";
case PlatformID.PlayStation4:
return $"Unknown error code {errno}";
case PlatformID.NonStop:
return $"Unknown error code {errno}";
case PlatformID.Unknown:
return $"Unknown error code {errno}";
default:
return $"Unknown error code {errno}";
}
throw new Exception("Arrived an unexpected place");
}
private static string PrintUnixError(int errno)
{
switch (errno)
{
case 2: // ENOENT
case 19: // ENODEV
return "The specified device cannot be found.";
case 13: // EACCESS
return "Not enough permissions to open the device.";
case 16: // EBUSY
return "The specified device is in use by another process.";
case 30: // EROFS
return "Cannot open the device in writable mode, as needed by some commands.";
default:
return $"Unknown error code {errno}";
}
}
private static string PrintWin32Error(int errno)
{
switch (errno)
{
case 2: // ERROR_FILE_NOT_FOUND
case 3: // ERROR_PATH_NOT_FOUND
return "The specified device cannot be found.";
case 5: // ERROR_ACCESS_DENIED
return "Not enough permissions to open the device.";
case 19: // ERROR_WRITE_PROTECT
return "Cannot open the device in writable mode, as needed by some commands.";
case 32: // ERROR_SHARING_VIOLATION
case 33: // ERROR_LOCK_VIOLATION
case 108: // ERROR_DRIVE_LOCKED
case 170: // ERROR_BUSY
return "The specified device is in use by another process.";
case 130: // ERROR_DIRECT_ACCESS_HANDLE
return "Tried to open a file instead of a device.";
default:
return $"Unknown error code {errno}";
}
}
}
}

View File

@@ -141,16 +141,16 @@ namespace DiscImageChef.Devices
if (StringHandlers.CToString(camDevice.SimName) == "ata") if (StringHandlers.CToString(camDevice.SimName) == "ata")
throw new throw new
InvalidOperationException( DeviceException(
"Parallel ATA devices are not supported on FreeBSD due to upstream bug #224250."); "Parallel ATA devices are not supported on FreeBSD due to upstream bug #224250.");
break; break;
} }
default: throw new InvalidOperationException($"Platform {PlatformId} not yet supported."); default: throw new DeviceException($"Platform {PlatformId} not yet supported.");
} }
} }
if (Error) throw new SystemException($"Error {LastError} opening device."); if (Error) throw new DeviceException(LastError);
Type = DeviceType.Unknown; Type = DeviceType.Unknown;
ScsiType = PeripheralDeviceTypes.UnknownDevice; ScsiType = PeripheralDeviceTypes.UnknownDevice;
@@ -158,7 +158,7 @@ namespace DiscImageChef.Devices
byte[] ataBuf; byte[] ataBuf;
byte[] inqBuf = null; byte[] inqBuf = null;
if (Error) throw new SystemException($"Error {LastError} trying device."); if (Error) throw new DeviceException(LastError);
var scsiSense = true; var scsiSense = true;

View File

@@ -0,0 +1,24 @@
using System;
namespace DiscImageChef.Devices
{
/// <summary>
/// Exception to be returned by the device constructor
/// </summary>
public class DeviceException : Exception
{
internal DeviceException(string message) : base(message)
{
}
internal DeviceException(int lastError)
{
LastError = lastError;
}
/// <summary>
/// Last error sent by the operating systen
/// </summary>
public int LastError { get; }
}
}

View File

@@ -48,6 +48,7 @@
<Reference Include="System.Management" /> <Reference Include="System.Management" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Device\DeviceException.cs" />
<Compile Include="FreeBSD\ListDevices.cs" /> <Compile Include="FreeBSD\ListDevices.cs" />
<Compile Include="Linux\Extern.cs" /> <Compile Include="Linux\Extern.cs" />
<Compile Include="Linux\Structs.cs" /> <Compile Include="Linux\Structs.cs" />

View File

@@ -45,12 +45,12 @@ using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
namespace DiscImageChef.Commands namespace DiscImageChef.Commands
{ {
class DeviceInfoCommand : Command internal class DeviceInfoCommand : Command
{ {
string devicePath; private string devicePath;
string outputPrefix; private string outputPrefix;
bool showHelp; private bool showHelp;
public DeviceInfoCommand() : base("device-info", "Gets information about a device.") public DeviceInfoCommand() : base("device-info", "Gets information about a device.")
{ {
@@ -63,89 +63,98 @@ namespace DiscImageChef.Commands
"", "",
Help, Help,
{"output-prefix|w=", "Name of character encoding to use.", s => outputPrefix = s}, {"output-prefix|w=", "Name of character encoding to use.", s => outputPrefix = s},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null} {"help|h|?", "Show this message and exit.", v => showHelp = v != null}
}; };
} }
public override int Invoke(IEnumerable<string> arguments) public override int Invoke(IEnumerable<string> arguments)
{ {
List<string> extra = Options.Parse(arguments); var extra = Options.Parse(arguments);
if(showHelp) if (showHelp)
{ {
Options.WriteOptionDescriptions(CommandSet.Out); Options.WriteOptionDescriptions(CommandSet.Out);
return (int)ErrorNumber.HelpRequested; return (int) ErrorNumber.HelpRequested;
} }
MainClass.PrintCopyright(); MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; if (MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; if (MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
Statistics.AddCommand("device-info"); Statistics.AddCommand("device-info");
if(extra.Count > 1) if (extra.Count > 1)
{ {
DicConsole.ErrorWriteLine("Too many arguments."); DicConsole.ErrorWriteLine("Too many arguments.");
return (int)ErrorNumber.UnexpectedArgumentCount; return (int) ErrorNumber.UnexpectedArgumentCount;
} }
if(extra.Count == 0) if (extra.Count == 0)
{ {
DicConsole.ErrorWriteLine("Missing device path."); DicConsole.ErrorWriteLine("Missing device path.");
return (int)ErrorNumber.MissingArgument; return (int) ErrorNumber.MissingArgument;
} }
devicePath = extra[0]; devicePath = extra[0];
DicConsole.DebugWriteLine("Device-Info command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Device-Info command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Device-Info command", "--device={0}", devicePath); DicConsole.DebugWriteLine("Device-Info command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Device-Info command", "--output-prefix={0}", outputPrefix); DicConsole.DebugWriteLine("Device-Info command", "--output-prefix={0}", outputPrefix);
DicConsole.DebugWriteLine("Device-Info command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Device-Info command", "--verbose={0}", MainClass.Verbose);
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0])) if (devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':'; devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(devicePath); Device dev;
try
if(dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); dev = new Device(devicePath);
return (int)ErrorNumber.CannotOpenDevice;
if (dev.Error)
{
DicConsole.ErrorWriteLine(Error.Print(dev.LastError));
return (int) ErrorNumber.CannotOpenDevice;
}
}
catch (DeviceException e)
{
DicConsole.ErrorWriteLine(e.Message ?? Error.Print(e.LastError));
return (int) ErrorNumber.CannotOpenDevice;
} }
Statistics.AddDevice(dev); Statistics.AddDevice(dev);
if(dev.IsUsb) if (dev.IsUsb)
{ {
DicConsole.WriteLine("USB device"); DicConsole.WriteLine("USB device");
if(dev.UsbDescriptors != null) if (dev.UsbDescriptors != null)
DicConsole.WriteLine("USB descriptor is {0} bytes", dev.UsbDescriptors.Length); DicConsole.WriteLine("USB descriptor is {0} bytes", dev.UsbDescriptors.Length);
DicConsole.WriteLine("USB Vendor ID: {0:X4}", dev.UsbVendorId); DicConsole.WriteLine("USB Vendor ID: {0:X4}", dev.UsbVendorId);
DicConsole.WriteLine("USB Product ID: {0:X4}", dev.UsbProductId); DicConsole.WriteLine("USB Product ID: {0:X4}", dev.UsbProductId);
DicConsole.WriteLine("USB Manufacturer: {0}", dev.UsbManufacturerString); DicConsole.WriteLine("USB Manufacturer: {0}", dev.UsbManufacturerString);
DicConsole.WriteLine("USB Product: {0}", dev.UsbProductString); DicConsole.WriteLine("USB Product: {0}", dev.UsbProductString);
DicConsole.WriteLine("USB Serial number: {0}", dev.UsbSerialString); DicConsole.WriteLine("USB Serial number: {0}", dev.UsbSerialString);
DicConsole.WriteLine(); DicConsole.WriteLine();
} }
if(dev.IsFireWire) if (dev.IsFireWire)
{ {
DicConsole.WriteLine("FireWire device"); DicConsole.WriteLine("FireWire device");
DicConsole.WriteLine("FireWire Vendor ID: {0:X6}", dev.FireWireVendor); DicConsole.WriteLine("FireWire Vendor ID: {0:X6}", dev.FireWireVendor);
DicConsole.WriteLine("FireWire Model ID: {0:X6}", dev.FireWireModel); DicConsole.WriteLine("FireWire Model ID: {0:X6}", dev.FireWireModel);
DicConsole.WriteLine("FireWire Manufacturer: {0}", dev.FireWireVendorName); DicConsole.WriteLine("FireWire Manufacturer: {0}", dev.FireWireVendorName);
DicConsole.WriteLine("FireWire Model: {0}", dev.FireWireModelName); DicConsole.WriteLine("FireWire Model: {0}", dev.FireWireModelName);
DicConsole.WriteLine("FireWire GUID: {0:X16}", dev.FireWireGuid); DicConsole.WriteLine("FireWire GUID: {0:X16}", dev.FireWireGuid);
DicConsole.WriteLine(); DicConsole.WriteLine();
} }
if(dev.IsPcmcia) if (dev.IsPcmcia)
{ {
DicConsole.WriteLine("PCMCIA device"); DicConsole.WriteLine("PCMCIA device");
DicConsole.WriteLine("PCMCIA CIS is {0} bytes", dev.Cis.Length); DicConsole.WriteLine("PCMCIA CIS is {0} bytes", dev.Cis.Length);
Tuple[] tuples = CIS.GetTuples(dev.Cis); var tuples = CIS.GetTuples(dev.Cis);
if(tuples != null) if (tuples != null)
foreach(Tuple tuple in tuples) foreach (var tuple in tuples)
switch(tuple.Code) switch (tuple.Code)
{ {
case TupleCodes.CISTPL_NULL: case TupleCodes.CISTPL_NULL:
case TupleCodes.CISTPL_END: break; case TupleCodes.CISTPL_END: break;
@@ -194,29 +203,29 @@ namespace DiscImageChef.Commands
case TupleCodes.CISTPL_SWIL: case TupleCodes.CISTPL_SWIL:
case TupleCodes.CISTPL_VERS_2: case TupleCodes.CISTPL_VERS_2:
DicConsole.DebugWriteLine("Device-Info command", "Found undecoded tuple ID {0}", DicConsole.DebugWriteLine("Device-Info command", "Found undecoded tuple ID {0}",
tuple.Code); tuple.Code);
break; break;
default: default:
DicConsole.DebugWriteLine("Device-Info command", "Found unknown tuple ID 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "Found unknown tuple ID 0x{0:X2}",
(byte)tuple.Code); (byte) tuple.Code);
break; break;
} }
else DicConsole.DebugWriteLine("Device-Info command", "Could not get tuples"); else DicConsole.DebugWriteLine("Device-Info command", "Could not get tuples");
} }
DeviceInfo devInfo = new DeviceInfo(dev); var devInfo = new DeviceInfo(dev);
if(devInfo.AtaIdentify != null) if (devInfo.AtaIdentify != null)
{ {
DataFile.WriteTo("Device-Info command", outputPrefix, "_ata_identify.bin", "ATA IDENTIFY", DataFile.WriteTo("Device-Info command", outputPrefix, "_ata_identify.bin", "ATA IDENTIFY",
devInfo.AtaIdentify); devInfo.AtaIdentify);
DicConsole.WriteLine(Identify.Prettify(devInfo.AtaIdentify)); DicConsole.WriteLine(Identify.Prettify(devInfo.AtaIdentify));
if(devInfo.AtaMcptError.HasValue) if (devInfo.AtaMcptError.HasValue)
{ {
DicConsole.WriteLine("Device supports the Media Card Pass Through Command Set"); DicConsole.WriteLine("Device supports the Media Card Pass Through Command Set");
switch(devInfo.AtaMcptError.Value.DeviceHead & 0x7) switch (devInfo.AtaMcptError.Value.DeviceHead & 0x7)
{ {
case 0: case 0:
DicConsole.WriteLine("Device reports incorrect media card type"); DicConsole.WriteLine("Device reports incorrect media card type");
@@ -235,236 +244,236 @@ namespace DiscImageChef.Commands
break; break;
default: default:
DicConsole.WriteLine("Device contains unknown media card type {0}", DicConsole.WriteLine("Device contains unknown media card type {0}",
devInfo.AtaMcptError.Value.DeviceHead & 0x07); devInfo.AtaMcptError.Value.DeviceHead & 0x07);
break; break;
} }
if((devInfo.AtaMcptError.Value.DeviceHead & 0x08) == 0x08) if ((devInfo.AtaMcptError.Value.DeviceHead & 0x08) == 0x08)
DicConsole.WriteLine("Media card is write protected"); DicConsole.WriteLine("Media card is write protected");
ushort specificData = (ushort)(devInfo.AtaMcptError.Value.CylinderHigh * 0x100 + var specificData = (ushort) (devInfo.AtaMcptError.Value.CylinderHigh * 0x100 +
devInfo.AtaMcptError.Value.CylinderLow); devInfo.AtaMcptError.Value.CylinderLow);
if(specificData != 0) DicConsole.WriteLine("Card specific data: 0x{0:X4}", specificData); if (specificData != 0) DicConsole.WriteLine("Card specific data: 0x{0:X4}", specificData);
} }
} }
if(devInfo.AtapiIdentify != null) if (devInfo.AtapiIdentify != null)
{ {
DataFile.WriteTo("Device-Info command", outputPrefix, "_atapi_identify.bin", "ATAPI IDENTIFY", DataFile.WriteTo("Device-Info command", outputPrefix, "_atapi_identify.bin", "ATAPI IDENTIFY",
devInfo.AtapiIdentify); devInfo.AtapiIdentify);
DicConsole.WriteLine(Identify.Prettify(devInfo.AtapiIdentify)); DicConsole.WriteLine(Identify.Prettify(devInfo.AtapiIdentify));
} }
if(devInfo.ScsiInquiry != null) if (devInfo.ScsiInquiry != null)
{ {
if(dev.Type != DeviceType.ATAPI) DicConsole.WriteLine("SCSI device"); if (dev.Type != DeviceType.ATAPI) DicConsole.WriteLine("SCSI device");
DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY", DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY",
devInfo.ScsiInquiryData); devInfo.ScsiInquiryData);
DicConsole.WriteLine(Inquiry.Prettify(devInfo.ScsiInquiry)); DicConsole.WriteLine(Inquiry.Prettify(devInfo.ScsiInquiry));
if(devInfo.ScsiEvpdPages != null) if (devInfo.ScsiEvpdPages != null)
foreach(KeyValuePair<byte, byte[]> page in devInfo.ScsiEvpdPages) foreach (var page in devInfo.ScsiEvpdPages)
if(page.Key >= 0x01 && page.Key <= 0x7F) if (page.Key >= 0x01 && page.Key <= 0x7F)
{ {
DicConsole.WriteLine("ASCII Page {0:X2}h: {1}", page.Key, EVPD.DecodeASCIIPage(page.Value)); DicConsole.WriteLine("ASCII Page {0:X2}h: {1}", page.Key, EVPD.DecodeASCIIPage(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, page.Value); DataFile.WriteTo("Device-Info command", outputPrefix, page.Value);
} }
else if(page.Key == 0x80) else if (page.Key == 0x80)
{ {
DicConsole.WriteLine("Unit Serial Number: {0}", EVPD.DecodePage80(page.Value)); DicConsole.WriteLine("Unit Serial Number: {0}", EVPD.DecodePage80(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0x81) else if (page.Key == 0x81)
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_81(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_81(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0x82) else if (page.Key == 0x82)
{ {
DicConsole.WriteLine("ASCII implemented operating definitions: {0}", DicConsole.WriteLine("ASCII implemented operating definitions: {0}",
EVPD.DecodePage82(page.Value)); EVPD.DecodePage82(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0x83) else if (page.Key == 0x83)
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_83(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_83(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0x84) else if (page.Key == 0x84)
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_84(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_84(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0x85) else if (page.Key == 0x85)
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_85(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_85(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0x86) else if (page.Key == 0x86)
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_86(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_86(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0x89) else if (page.Key == 0x89)
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_89(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_89(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xB0) else if (page.Key == 0xB0)
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_B0(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_B0(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xB1) else if (page.Key == 0xB1)
{ {
DicConsole.WriteLine("Manufacturer-assigned Serial Number: {0}", DicConsole.WriteLine("Manufacturer-assigned Serial Number: {0}",
EVPD.DecodePageB1(page.Value)); EVPD.DecodePageB1(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xB2) else if (page.Key == 0xB2)
{ {
DicConsole.WriteLine("TapeAlert Supported Flags Bitmap: 0x{0:X16}", DicConsole.WriteLine("TapeAlert Supported Flags Bitmap: 0x{0:X16}",
EVPD.DecodePageB2(page.Value)); EVPD.DecodePageB2(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xB3) else if (page.Key == 0xB3)
{ {
DicConsole.WriteLine("Automation Device Serial Number: {0}", EVPD.DecodePageB3(page.Value)); DicConsole.WriteLine("Automation Device Serial Number: {0}", EVPD.DecodePageB3(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xB4) else if (page.Key == 0xB4)
{ {
DicConsole.WriteLine("Data Transfer Device Element Address: 0x{0}", DicConsole.WriteLine("Data Transfer Device Element Address: 0x{0}",
EVPD.DecodePageB4(page.Value)); EVPD.DecodePageB4(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xC0 && else if (page.Key == 0xC0 &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification) StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "quantum") .ToLowerInvariant().Trim() == "quantum")
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Quantum(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Quantum(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xC0 && else if (page.Key == 0xC0 &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification) StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "seagate") .ToLowerInvariant().Trim() == "seagate")
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Seagate(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Seagate(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xC0 && else if (page.Key == 0xC0 &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification) StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "ibm") .ToLowerInvariant().Trim() == "ibm")
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_IBM(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_IBM(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xC1 && else if (page.Key == 0xC1 &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification) StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "ibm") .ToLowerInvariant().Trim() == "ibm")
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C1_IBM(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C1_IBM(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if((page.Key == 0xC0 || page.Key == 0xC1) && else if ((page.Key == 0xC0 || page.Key == 0xC1) &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification) StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "certance") .ToLowerInvariant().Trim() == "certance")
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_C1_Certance(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_C1_Certance(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if((page.Key == 0xC2 || page.Key == 0xC3 || page.Key == 0xC4 || page.Key == 0xC5 || else if ((page.Key == 0xC2 || page.Key == 0xC3 || page.Key == 0xC4 || page.Key == 0xC5 ||
page.Key == 0xC6) && page.Key == 0xC6) &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification) StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "certance") .ToLowerInvariant().Trim() == "certance")
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C2_C3_C4_C5_C6_Certance(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C2_C3_C4_C5_C6_Certance(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if((page.Key == 0xC0 || page.Key == 0xC1 || page.Key == 0xC2 || page.Key == 0xC3 || else if ((page.Key == 0xC0 || page.Key == 0xC1 || page.Key == 0xC2 || page.Key == 0xC3 ||
page.Key == 0xC4 || page.Key == 0xC5) && StringHandlers page.Key == 0xC4 || page.Key == 0xC5) && StringHandlers
.CToString(devInfo.ScsiInquiry.Value .CToString(devInfo.ScsiInquiry.Value
.VendorIdentification) .VendorIdentification)
.ToLowerInvariant().Trim() == "hp") .ToLowerInvariant().Trim() == "hp")
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_to_C5_HP(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_to_C5_HP(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else if(page.Key == 0xDF && else if (page.Key == 0xDF &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification) StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "certance") .ToLowerInvariant().Trim() == "certance")
{ {
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_DF_Certance(page.Value)); DicConsole.WriteLine("{0}", EVPD.PrettifyPage_DF_Certance(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
else else
{ {
if(page.Key == 0x00) continue; if (page.Key == 0x00) continue;
DicConsole.DebugWriteLine("Device-Info command", "Found undecoded SCSI VPD page 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "Found undecoded SCSI VPD page 0x{0:X2}",
page.Key); page.Key);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
} }
if(devInfo.ScsiModeSense6 != null) if (devInfo.ScsiModeSense6 != null)
DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE", DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE",
devInfo.ScsiModeSense6); devInfo.ScsiModeSense6);
if(devInfo.ScsiModeSense10 != null) if (devInfo.ScsiModeSense10 != null)
DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE", DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE",
devInfo.ScsiModeSense10); devInfo.ScsiModeSense10);
if(devInfo.ScsiMode.HasValue) if (devInfo.ScsiMode.HasValue)
PrintScsiModePages.Print(devInfo.ScsiMode.Value, PrintScsiModePages.Print(devInfo.ScsiMode.Value,
(PeripheralDeviceTypes)devInfo.ScsiInquiry.Value.PeripheralDeviceType, (PeripheralDeviceTypes) devInfo.ScsiInquiry.Value.PeripheralDeviceType,
devInfo.ScsiInquiry.Value.VendorIdentification); devInfo.ScsiInquiry.Value.VendorIdentification);
if(devInfo.MmcConfiguration != null) if (devInfo.MmcConfiguration != null)
{ {
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_getconfiguration.bin", DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_getconfiguration.bin",
"MMC GET CONFIGURATION", devInfo.MmcConfiguration); "MMC GET CONFIGURATION", devInfo.MmcConfiguration);
Features.SeparatedFeatures ftr = Features.Separate(devInfo.MmcConfiguration); var ftr = Features.Separate(devInfo.MmcConfiguration);
DicConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION length is {0} bytes", DicConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION length is {0} bytes",
ftr.DataLength); ftr.DataLength);
DicConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION current profile is {0:X4}h", DicConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION current profile is {0:X4}h",
ftr.CurrentProfile); ftr.CurrentProfile);
if(ftr.Descriptors != null) if (ftr.Descriptors != null)
{ {
DicConsole.WriteLine("SCSI MMC GET CONFIGURATION Features:"); DicConsole.WriteLine("SCSI MMC GET CONFIGURATION Features:");
foreach(Features.FeatureDescriptor desc in ftr.Descriptors) foreach (var desc in ftr.Descriptors)
{ {
DicConsole.DebugWriteLine("Device-Info command", "Feature {0:X4}h", desc.Code); DicConsole.DebugWriteLine("Device-Info command", "Feature {0:X4}h", desc.Code);
switch(desc.Code) switch (desc.Code)
{ {
case 0x0000: case 0x0000:
DicConsole.WriteLine(Features.Prettify_0000(desc.Data)); DicConsole.WriteLine(Features.Prettify_0000(desc.Data));
@@ -647,66 +656,70 @@ namespace DiscImageChef.Commands
} }
} }
else else
{
DicConsole.DebugWriteLine("Device-Info command", DicConsole.DebugWriteLine("Device-Info command",
"GET CONFIGURATION returned no feature descriptors"); "GET CONFIGURATION returned no feature descriptors");
}
} }
if(devInfo.PlextorFeatures != null) if (devInfo.PlextorFeatures != null)
{ {
if(devInfo.PlextorFeatures.Eeprom != null) if (devInfo.PlextorFeatures.Eeprom != null)
{ {
DataFile.WriteTo("Device-Info command", outputPrefix, "_plextor_eeprom.bin", DataFile.WriteTo("Device-Info command", outputPrefix, "_plextor_eeprom.bin",
"PLEXTOR READ EEPROM", devInfo.PlextorFeatures.Eeprom); "PLEXTOR READ EEPROM", devInfo.PlextorFeatures.Eeprom);
DicConsole.WriteLine("Drive has loaded a total of {0} discs", devInfo.PlextorFeatures.Discs); DicConsole.WriteLine("Drive has loaded a total of {0} discs", devInfo.PlextorFeatures.Discs);
DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading CDs", DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading CDs",
devInfo.PlextorFeatures.CdReadTime / 3600, devInfo.PlextorFeatures.CdReadTime / 3600,
devInfo.PlextorFeatures.CdReadTime / 60 % 60, devInfo.PlextorFeatures.CdReadTime / 60 % 60,
devInfo.PlextorFeatures.CdReadTime % 60); devInfo.PlextorFeatures.CdReadTime % 60);
DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing CDs", DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing CDs",
devInfo.PlextorFeatures.CdWriteTime / 3600, devInfo.PlextorFeatures.CdWriteTime / 3600,
devInfo.PlextorFeatures.CdWriteTime / 60 % 60, devInfo.PlextorFeatures.CdWriteTime / 60 % 60,
devInfo.PlextorFeatures.CdWriteTime % 60); devInfo.PlextorFeatures.CdWriteTime % 60);
if(devInfo.PlextorFeatures.IsDvd) if (devInfo.PlextorFeatures.IsDvd)
{ {
DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading DVDs", DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading DVDs",
devInfo.PlextorFeatures.DvdReadTime / 3600, devInfo.PlextorFeatures.DvdReadTime / 3600,
devInfo.PlextorFeatures.DvdReadTime / 60 % 60, devInfo.PlextorFeatures.DvdReadTime / 60 % 60,
devInfo.PlextorFeatures.DvdReadTime % 60); devInfo.PlextorFeatures.DvdReadTime % 60);
DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing DVDs", DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing DVDs",
devInfo.PlextorFeatures.DvdWriteTime / 3600, devInfo.PlextorFeatures.DvdWriteTime / 3600,
devInfo.PlextorFeatures.DvdWriteTime / 60 % 60, devInfo.PlextorFeatures.DvdWriteTime / 60 % 60,
devInfo.PlextorFeatures.DvdWriteTime % 60); devInfo.PlextorFeatures.DvdWriteTime % 60);
} }
} }
if(devInfo.PlextorFeatures.PoweRec) if (devInfo.PlextorFeatures.PoweRec)
{ {
DicConsole.Write("Drive supports PoweRec"); DicConsole.Write("Drive supports PoweRec");
if(devInfo.PlextorFeatures.PoweRecEnabled) if (devInfo.PlextorFeatures.PoweRecEnabled)
{ {
DicConsole.Write(", has it enabled"); DicConsole.Write(", has it enabled");
if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0) if (devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0)
DicConsole.WriteLine(" and recommends {0} Kb/sec.", DicConsole.WriteLine(" and recommends {0} Kb/sec.",
devInfo.PlextorFeatures.PoweRecRecommendedSpeed); devInfo.PlextorFeatures.PoweRecRecommendedSpeed);
else DicConsole.WriteLine("."); else DicConsole.WriteLine(".");
if(devInfo.PlextorFeatures.PoweRecSelected > 0) if (devInfo.PlextorFeatures.PoweRecSelected > 0)
DicConsole DicConsole
.WriteLine("Selected PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)", .WriteLine(
devInfo.PlextorFeatures.PoweRecSelected, "Selected PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)",
devInfo.PlextorFeatures.PoweRecSelected / 177); devInfo.PlextorFeatures.PoweRecSelected,
if(devInfo.PlextorFeatures.PoweRecMax > 0) devInfo.PlextorFeatures.PoweRecSelected / 177);
if (devInfo.PlextorFeatures.PoweRecMax > 0)
DicConsole DicConsole
.WriteLine("Maximum PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)", .WriteLine(
devInfo.PlextorFeatures.PoweRecMax, "Maximum PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)",
devInfo.PlextorFeatures.PoweRecMax / 177); devInfo.PlextorFeatures.PoweRecMax,
if(devInfo.PlextorFeatures.PoweRecLast > 0) devInfo.PlextorFeatures.PoweRecMax / 177);
if (devInfo.PlextorFeatures.PoweRecLast > 0)
DicConsole.WriteLine("Last used PoweRec was {0} Kb/sec ({1}x)", DicConsole.WriteLine("Last used PoweRec was {0} Kb/sec ({1}x)",
devInfo.PlextorFeatures.PoweRecLast, devInfo.PlextorFeatures.PoweRecLast,
devInfo.PlextorFeatures.PoweRecLast / 177); devInfo.PlextorFeatures.PoweRecLast / 177);
} }
else else
{ {
@@ -715,111 +728,111 @@ namespace DiscImageChef.Commands
} }
} }
if(devInfo.PlextorFeatures.SilentMode) if (devInfo.PlextorFeatures.SilentMode)
{ {
DicConsole.WriteLine("Drive supports Plextor SilentMode"); DicConsole.WriteLine("Drive supports Plextor SilentMode");
if(devInfo.PlextorFeatures.SilentModeEnabled) if (devInfo.PlextorFeatures.SilentModeEnabled)
{ {
DicConsole.WriteLine("Plextor SilentMode is enabled:"); DicConsole.WriteLine("Plextor SilentMode is enabled:");
DicConsole.WriteLine(devInfo.PlextorFeatures.AccessTimeLimit == 2 DicConsole.WriteLine(devInfo.PlextorFeatures.AccessTimeLimit == 2
? "\tAccess time is slow" ? "\tAccess time is slow"
: "\tAccess time is fast"); : "\tAccess time is fast");
if(devInfo.PlextorFeatures.CdReadSpeedLimit > 0) if (devInfo.PlextorFeatures.CdReadSpeedLimit > 0)
DicConsole.WriteLine("\tCD read speed limited to {0}x", DicConsole.WriteLine("\tCD read speed limited to {0}x",
devInfo.PlextorFeatures.CdReadSpeedLimit); devInfo.PlextorFeatures.CdReadSpeedLimit);
if(devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 && devInfo.PlextorFeatures.IsDvd) if (devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 && devInfo.PlextorFeatures.IsDvd)
DicConsole.WriteLine("\tDVD read speed limited to {0}x", DicConsole.WriteLine("\tDVD read speed limited to {0}x",
devInfo.PlextorFeatures.DvdReadSpeedLimit); devInfo.PlextorFeatures.DvdReadSpeedLimit);
if(devInfo.PlextorFeatures.CdWriteSpeedLimit > 0) if (devInfo.PlextorFeatures.CdWriteSpeedLimit > 0)
DicConsole.WriteLine("\tCD write speed limited to {0}x", DicConsole.WriteLine("\tCD write speed limited to {0}x",
devInfo.PlextorFeatures.CdWriteSpeedLimit); devInfo.PlextorFeatures.CdWriteSpeedLimit);
} }
} }
if(devInfo.PlextorFeatures.GigaRec) DicConsole.WriteLine("Drive supports Plextor GigaRec"); if (devInfo.PlextorFeatures.GigaRec) DicConsole.WriteLine("Drive supports Plextor GigaRec");
if(devInfo.PlextorFeatures.SecuRec) DicConsole.WriteLine("Drive supports Plextor SecuRec"); if (devInfo.PlextorFeatures.SecuRec) DicConsole.WriteLine("Drive supports Plextor SecuRec");
if(devInfo.PlextorFeatures.SpeedRead) if (devInfo.PlextorFeatures.SpeedRead)
{ {
DicConsole.Write("Drive supports Plextor SpeedRead"); DicConsole.Write("Drive supports Plextor SpeedRead");
if(devInfo.PlextorFeatures.SpeedReadEnabled) DicConsole.WriteLine("and has it enabled"); if (devInfo.PlextorFeatures.SpeedReadEnabled) DicConsole.WriteLine("and has it enabled");
else DicConsole.WriteLine(); else DicConsole.WriteLine();
} }
if(devInfo.PlextorFeatures.Hiding) if (devInfo.PlextorFeatures.Hiding)
{ {
DicConsole.WriteLine("Drive supports hiding CD-Rs and forcing single session"); DicConsole.WriteLine("Drive supports hiding CD-Rs and forcing single session");
if(devInfo.PlextorFeatures.HidesRecordables) if (devInfo.PlextorFeatures.HidesRecordables)
DicConsole.WriteLine("Drive currently hides CD-Rs"); DicConsole.WriteLine("Drive currently hides CD-Rs");
if(devInfo.PlextorFeatures.HidesSessions) if (devInfo.PlextorFeatures.HidesSessions)
DicConsole.WriteLine("Drive currently forces single session"); DicConsole.WriteLine("Drive currently forces single session");
} }
if(devInfo.PlextorFeatures.VariRec) DicConsole.WriteLine("Drive supports Plextor VariRec"); if (devInfo.PlextorFeatures.VariRec) DicConsole.WriteLine("Drive supports Plextor VariRec");
if(devInfo.PlextorFeatures.IsDvd) if (devInfo.PlextorFeatures.IsDvd)
{ {
if(devInfo.PlextorFeatures.VariRecDvd) if (devInfo.PlextorFeatures.VariRecDvd)
DicConsole.WriteLine("Drive supports Plextor VariRec for DVDs"); DicConsole.WriteLine("Drive supports Plextor VariRec for DVDs");
if(devInfo.PlextorFeatures.BitSetting) if (devInfo.PlextorFeatures.BitSetting)
DicConsole.WriteLine("Drive supports bitsetting DVD+R book type"); DicConsole.WriteLine("Drive supports bitsetting DVD+R book type");
if(devInfo.PlextorFeatures.BitSettingDl) if (devInfo.PlextorFeatures.BitSettingDl)
DicConsole.WriteLine("Drive supports bitsetting DVD+R DL book type"); DicConsole.WriteLine("Drive supports bitsetting DVD+R DL book type");
if(devInfo.PlextorFeatures.DvdPlusWriteTest) if (devInfo.PlextorFeatures.DvdPlusWriteTest)
DicConsole.WriteLine("Drive supports test writing DVD+"); DicConsole.WriteLine("Drive supports test writing DVD+");
} }
} }
if(devInfo.ScsiInquiry.Value.KreonPresent) if (devInfo.ScsiInquiry.Value.KreonPresent)
{ {
DicConsole.WriteLine("Drive has kreon firmware:"); DicConsole.WriteLine("Drive has kreon firmware:");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse))
DicConsole.WriteLine("\tCan do challenge/response with Xbox discs"); DicConsole.WriteLine("\tCan do challenge/response with Xbox discs");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs))
DicConsole.WriteLine("\tCan read and descrypt SS from Xbox discs"); DicConsole.WriteLine("\tCan read and descrypt SS from Xbox discs");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock))
DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox discs"); DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox discs");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock))
DicConsole.WriteLine("\tCan set wxripper unlock state with Xbox discs"); DicConsole.WriteLine("\tCan set wxripper unlock state with Xbox discs");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse360)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse360))
DicConsole.WriteLine("\tCan do challenge/response with Xbox 360 discs"); DicConsole.WriteLine("\tCan do challenge/response with Xbox 360 discs");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360))
DicConsole.WriteLine("\tCan read and descrypt SS from Xbox 360 discs"); DicConsole.WriteLine("\tCan read and descrypt SS from Xbox 360 discs");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360))
DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox 360 discs"); DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox 360 discs");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock360)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock360))
DicConsole.WriteLine("\tCan set wxripper unlock state with Xbox 360 discs"); DicConsole.WriteLine("\tCan set wxripper unlock state with Xbox 360 discs");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.Lock)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.Lock))
DicConsole.WriteLine("\tCan set locked state"); DicConsole.WriteLine("\tCan set locked state");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ErrorSkipping)) if (devInfo.KreonFeatures.HasFlag(KreonFeatures.ErrorSkipping))
DicConsole.WriteLine("\tCan skip read errors"); DicConsole.WriteLine("\tCan skip read errors");
} }
if(devInfo.BlockLimits != null) if (devInfo.BlockLimits != null)
{ {
DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_readblocklimits.bin", DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_readblocklimits.bin",
"SSC READ BLOCK LIMITS", devInfo.BlockLimits); "SSC READ BLOCK LIMITS", devInfo.BlockLimits);
DicConsole.WriteLine("Block limits for device:"); DicConsole.WriteLine("Block limits for device:");
DicConsole.WriteLine(BlockLimits.Prettify(devInfo.BlockLimits)); DicConsole.WriteLine(BlockLimits.Prettify(devInfo.BlockLimits));
} }
if(devInfo.DensitySupport != null) if (devInfo.DensitySupport != null)
{ {
DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_reportdensitysupport.bin", DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_reportdensitysupport.bin",
"SSC REPORT DENSITY SUPPORT", devInfo.DensitySupport); "SSC REPORT DENSITY SUPPORT", devInfo.DensitySupport);
if(devInfo.DensitySupportHeader.HasValue) if (devInfo.DensitySupportHeader.HasValue)
{ {
DicConsole.WriteLine("Densities supported by device:"); DicConsole.WriteLine("Densities supported by device:");
DicConsole.WriteLine(DensitySupport.PrettifyDensity(devInfo.DensitySupportHeader)); DicConsole.WriteLine(DensitySupport.PrettifyDensity(devInfo.DensitySupportHeader));
} }
} }
if(devInfo.MediumDensitySupport != null) if (devInfo.MediumDensitySupport != null)
{ {
DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_reportdensitysupport_medium.bin", DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_reportdensitysupport_medium.bin",
"SSC REPORT DENSITY SUPPORT (MEDIUM)", devInfo.MediumDensitySupport); "SSC REPORT DENSITY SUPPORT (MEDIUM)", devInfo.MediumDensitySupport);
if(devInfo.MediaTypeSupportHeader.HasValue) if (devInfo.MediaTypeSupportHeader.HasValue)
{ {
DicConsole.WriteLine("Medium types supported by device:"); DicConsole.WriteLine("Medium types supported by device:");
DicConsole.WriteLine(DensitySupport.PrettifyMediumType(devInfo.MediaTypeSupportHeader)); DicConsole.WriteLine(DensitySupport.PrettifyMediumType(devInfo.MediaTypeSupportHeader));
@@ -829,87 +842,87 @@ namespace DiscImageChef.Commands
} }
} }
switch(dev.Type) switch (dev.Type)
{ {
case DeviceType.MMC: case DeviceType.MMC:
{ {
bool noInfo = true; var noInfo = true;
if(devInfo.CID != null) if (devInfo.CID != null)
{ {
noInfo = false; noInfo = false;
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_cid.bin", "MMC CID", devInfo.CID); DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_cid.bin", "MMC CID", devInfo.CID);
DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCID(devInfo.CID)); DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCID(devInfo.CID));
} }
if(devInfo.CSD != null) if (devInfo.CSD != null)
{ {
noInfo = false; noInfo = false;
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_csd.bin", "MMC CSD", devInfo.CSD); DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_csd.bin", "MMC CSD", devInfo.CSD);
DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCSD(devInfo.CSD)); DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCSD(devInfo.CSD));
} }
if(devInfo.OCR != null) if (devInfo.OCR != null)
{ {
noInfo = false; noInfo = false;
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_ocr.bin", "MMC OCR", devInfo.OCR); DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_ocr.bin", "MMC OCR", devInfo.OCR);
DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyOCR(devInfo.OCR)); DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyOCR(devInfo.OCR));
} }
if(devInfo.ExtendedCSD != null) if (devInfo.ExtendedCSD != null)
{ {
noInfo = false; noInfo = false;
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_ecsd.bin", "MMC Extended CSD", DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_ecsd.bin", "MMC Extended CSD",
devInfo.ExtendedCSD); devInfo.ExtendedCSD);
DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyExtendedCSD(devInfo.ExtendedCSD)); DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyExtendedCSD(devInfo.ExtendedCSD));
} }
if(noInfo) DicConsole.WriteLine("Could not get any kind of information from the device !!!"); if (noInfo) DicConsole.WriteLine("Could not get any kind of information from the device !!!");
} }
break; break;
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
{ {
bool noInfo = true; var noInfo = true;
if(devInfo.CID != null) if (devInfo.CID != null)
{ {
noInfo = false; noInfo = false;
DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_cid.bin", "SecureDigital CID", DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_cid.bin", "SecureDigital CID",
devInfo.CID); devInfo.CID);
DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCID(devInfo.CID)); DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCID(devInfo.CID));
} }
if(devInfo.CSD != null) if (devInfo.CSD != null)
{ {
noInfo = false; noInfo = false;
DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_csd.bin", "SecureDigital CSD", DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_csd.bin", "SecureDigital CSD",
devInfo.CSD); devInfo.CSD);
DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCSD(devInfo.CSD)); DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCSD(devInfo.CSD));
} }
if(devInfo.OCR != null) if (devInfo.OCR != null)
{ {
noInfo = false; noInfo = false;
DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_ocr.bin", "SecureDigital OCR", DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_ocr.bin", "SecureDigital OCR",
devInfo.OCR); devInfo.OCR);
DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyOCR(devInfo.OCR)); DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyOCR(devInfo.OCR));
} }
if(devInfo.SCR != null) if (devInfo.SCR != null)
{ {
noInfo = false; noInfo = false;
DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_scr.bin", "SecureDigital SCR", DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_scr.bin", "SecureDigital SCR",
devInfo.SCR); devInfo.SCR);
DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifySCR(devInfo.SCR)); DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifySCR(devInfo.SCR));
} }
if(noInfo) DicConsole.WriteLine("Could not get any kind of information from the device !!!"); if (noInfo) DicConsole.WriteLine("Could not get any kind of information from the device !!!");
} }
break; break;
} }
dev.Close(); dev.Close();
return (int)ErrorNumber.NoError; return (int) ErrorNumber.NoError;
} }
} }
} }

View File

@@ -43,6 +43,7 @@ using DiscImageChef.Database;
using DiscImageChef.Database.Models; using DiscImageChef.Database.Models;
using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices;
using Mono.Options; using Mono.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
using Command = Mono.Options.Command; using Command = Mono.Options.Command;
@@ -108,11 +109,20 @@ namespace DiscImageChef.Commands
if (devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0])) if (devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':'; devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
var dev = new Device(devicePath); Device dev;
try
if (dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); dev = new Device(devicePath);
if (dev.Error)
{
DicConsole.ErrorWriteLine(Error.Print(dev.LastError));
return (int) ErrorNumber.CannotOpenDevice;
}
}
catch (DeviceException e)
{
DicConsole.ErrorWriteLine(e.Message ?? Error.Print(e.LastError));
return (int) ErrorNumber.CannotOpenDevice; return (int) ErrorNumber.CannotOpenDevice;
} }

View File

@@ -36,7 +36,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Xml.Serialization; using System.Xml.Serialization;
using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Interop; using DiscImageChef.CommonTypes.Interop;
@@ -52,26 +51,28 @@ using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
namespace DiscImageChef.Commands namespace DiscImageChef.Commands
{ {
class DumpMediaCommand : Command internal class DumpMediaCommand : Command
{ {
string cicmXml; private string cicmXml;
string devicePath; private string devicePath;
bool doResume = true; private bool doResume = true;
string encodingName; private string encodingName;
bool firstTrackPregap; private bool firstTrackPregap;
bool force; private bool force;
bool noMetadata; private bool noMetadata;
bool noTrim; private bool noTrim;
string outputFile; private string outputFile;
string outputOptions; private string outputOptions;
bool persistent;
private bool persistent;
// TODO: Disabled temporarily // TODO: Disabled temporarily
bool raw = false; private bool raw = false;
ushort retryPasses = 5; private ushort retryPasses = 5;
bool showHelp; private bool showHelp;
int skip = 512; private int skip = 512;
bool stopOnError; private bool stopOnError;
string wanteOutputFormat; private string wanteOutputFormat;
public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.") public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.")
{ {
@@ -84,197 +85,209 @@ namespace DiscImageChef.Commands
"", "",
Help, Help,
{"cicm-xml|x=", "Take metadata from existing CICM XML sidecar.", s => cicmXml = s}, {"cicm-xml|x=", "Take metadata from existing CICM XML sidecar.", s => cicmXml = s},
{"encoding|e=", "Name of character encoding to use.", s => encodingName = s} {"encoding|e=", "Name of character encoding to use.", s => encodingName = s}
}; };
if(DetectOS.GetRealPlatformID() != PlatformID.FreeBSD) if (DetectOS.GetRealPlatformID() != PlatformID.FreeBSD)
Options.Add("first-pregap", "Try to read first track pregap. Only applicable to CD/DDCD/GD.", Options.Add("first-pregap", "Try to read first track pregap. Only applicable to CD/DDCD/GD.",
b => firstTrackPregap = b != null); b => firstTrackPregap = b != null);
Options.Add("force|f", "Continue dump whatever happens.", b => force = b != null); Options.Add("force|f", "Continue dump whatever happens.", b => force = b != null);
Options.Add("format|t=", Options.Add("format|t=",
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.", "Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.",
s => wanteOutputFormat = s); s => wanteOutputFormat = s);
Options.Add("no-metadata", "Disables creating CICM XML sidecar.", b => noMetadata = b != null); Options.Add("no-metadata", "Disables creating CICM XML sidecar.", b => noMetadata = b != null);
Options.Add("no-trim", "Disables trimming errored from skipped sectors.", b => noTrim = b != null); Options.Add("no-trim", "Disables trimming errored from skipped sectors.", b => noTrim = b != null);
Options.Add("options|O=", "Comma separated name=value pairs of options to pass to output image plugin.", Options.Add("options|O=", "Comma separated name=value pairs of options to pass to output image plugin.",
s => outputOptions = s); s => outputOptions = s);
Options.Add("persistent", "Try to recover partial or incorrect data.", b => persistent = b != null); Options.Add("persistent", "Try to recover partial or incorrect data.", b => persistent = b != null);
/* TODO: Disabled temporarily /* TODO: Disabled temporarily
Options.Add("raw|r", "Dump sectors with tags included. For optical media, dump scrambled sectors.", (b) => raw = b != null);*/ Options.Add("raw|r", "Dump sectors with tags included. For optical media, dump scrambled sectors.", (b) => raw = b != null);*/
Options.Add("resume|r", "Create/use resume mapfile.", Options.Add("resume|r", "Create/use resume mapfile.",
b => doResume = b != null); b => doResume = b != null);
Options.Add("retry-passes|p=", "How many retry passes to do.", Options.Add("retry-passes|p=", "How many retry passes to do.",
(ushort us) => retryPasses = us); (ushort us) => retryPasses = us);
Options.Add("skip|k=", "When an unreadable sector is found skip this many sectors.", Options.Add("skip|k=", "When an unreadable sector is found skip this many sectors.",
(int i) => skip = i); (int i) => skip = i);
Options.Add("stop-on-error|s", "Stop media dump on first error.", Options.Add("stop-on-error|s", "Stop media dump on first error.",
b => stopOnError = b != null); b => stopOnError = b != null);
Options.Add("help|h|?", "Show this message and exit.", Options.Add("help|h|?", "Show this message and exit.",
v => showHelp = v != null); v => showHelp = v != null);
} }
public override int Invoke(IEnumerable<string> arguments) public override int Invoke(IEnumerable<string> arguments)
{ {
List<string> extra = Options.Parse(arguments); var extra = Options.Parse(arguments);
if(showHelp) if (showHelp)
{ {
Options.WriteOptionDescriptions(CommandSet.Out); Options.WriteOptionDescriptions(CommandSet.Out);
return (int)ErrorNumber.HelpRequested; return (int) ErrorNumber.HelpRequested;
} }
MainClass.PrintCopyright(); MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; if (MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; if (MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
Statistics.AddCommand("dump-media"); Statistics.AddCommand("dump-media");
if(extra.Count > 2) if (extra.Count > 2)
{ {
DicConsole.ErrorWriteLine("Too many arguments."); DicConsole.ErrorWriteLine("Too many arguments.");
return (int)ErrorNumber.UnexpectedArgumentCount; return (int) ErrorNumber.UnexpectedArgumentCount;
} }
if(extra.Count <= 1) if (extra.Count <= 1)
{ {
DicConsole.ErrorWriteLine("Missing paths."); DicConsole.ErrorWriteLine("Missing paths.");
return (int)ErrorNumber.MissingArgument; return (int) ErrorNumber.MissingArgument;
} }
devicePath = extra[0]; devicePath = extra[0];
outputFile = extra[1]; outputFile = extra[1];
DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", cicmXml); DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", cicmXml);
DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", devicePath); DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", encodingName); DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", encodingName);
DicConsole.DebugWriteLine("Dump-Media command", "--first-pregap={0}", firstTrackPregap); DicConsole.DebugWriteLine("Dump-Media command", "--first-pregap={0}", firstTrackPregap);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force); DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force); DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force);
DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", wanteOutputFormat); DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", wanteOutputFormat);
DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", noMetadata); DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", noMetadata);
DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", Options); DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", Options);
DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", outputFile); DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", outputFile);
DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", persistent); DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", persistent);
// TODO: Disabled temporarily // TODO: Disabled temporarily
//DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw); //DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
DicConsole.DebugWriteLine("Dump-Media command", "--resume={0}", doResume); DicConsole.DebugWriteLine("Dump-Media command", "--resume={0}", doResume);
DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", retryPasses); DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", retryPasses);
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", skip); DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", skip);
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", stopOnError); DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", stopOnError);
DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", MainClass.Verbose);
Dictionary<string, string> parsedOptions = Core.Options.Parse(outputOptions); var parsedOptions = Core.Options.Parse(outputOptions);
DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:"); DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");
foreach(KeyValuePair<string, string> parsedOption in parsedOptions) foreach (var parsedOption in parsedOptions)
DicConsole.DebugWriteLine("Dump-Media command", "{0} = {1}", parsedOption.Key, parsedOption.Value); DicConsole.DebugWriteLine("Dump-Media command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
Encoding encoding = null; Encoding encoding = null;
if(encodingName != null) if (encodingName != null)
try try
{ {
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName); encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName); if (MainClass.Verbose)
DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
} }
catch(ArgumentException) catch (ArgumentException)
{ {
DicConsole.ErrorWriteLine("Specified encoding is not supported."); DicConsole.ErrorWriteLine("Specified encoding is not supported.");
return (int)ErrorNumber.EncodingUnknown; return (int) ErrorNumber.EncodingUnknown;
} }
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0])) if (devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':'; devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(devicePath); Device dev;
try
if(dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); dev = new Device(devicePath);
return (int)ErrorNumber.CannotOpenDevice;
if (dev.Error)
{
DicConsole.ErrorWriteLine(Error.Print(dev.LastError));
return (int) ErrorNumber.CannotOpenDevice;
}
}
catch (DeviceException e)
{
DicConsole.ErrorWriteLine(e.Message ?? Error.Print(e.LastError));
return (int) ErrorNumber.CannotOpenDevice;
} }
Statistics.AddDevice(dev); Statistics.AddDevice(dev);
string outputPrefix = Path.Combine(Path.GetDirectoryName(outputFile), var outputPrefix = Path.Combine(Path.GetDirectoryName(outputFile),
Path.GetFileNameWithoutExtension(outputFile)); Path.GetFileNameWithoutExtension(outputFile));
Resume resume = null; Resume resume = null;
XmlSerializer xs = new XmlSerializer(typeof(Resume)); var xs = new XmlSerializer(typeof(Resume));
if(File.Exists(outputPrefix + ".resume.xml") && doResume) if (File.Exists(outputPrefix + ".resume.xml") && doResume)
try try
{ {
StreamReader sr = new StreamReader(outputPrefix + ".resume.xml"); var sr = new StreamReader(outputPrefix + ".resume.xml");
resume = (Resume)xs.Deserialize(sr); resume = (Resume) xs.Deserialize(sr);
sr.Close(); sr.Close();
} }
catch catch
{ {
DicConsole.ErrorWriteLine("Incorrect resume file, not continuing..."); DicConsole.ErrorWriteLine("Incorrect resume file, not continuing...");
return (int)ErrorNumber.InvalidResume; return (int) ErrorNumber.InvalidResume;
} }
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)
{ {
DicConsole.WriteLine("Media already dumped correctly, not continuing..."); DicConsole.WriteLine("Media already dumped correctly, not continuing...");
return (int)ErrorNumber.AlreadyDumped; return (int) ErrorNumber.AlreadyDumped;
} }
CICMMetadataType sidecar = null; CICMMetadataType sidecar = null;
XmlSerializer sidecarXs = new XmlSerializer(typeof(CICMMetadataType)); var sidecarXs = new XmlSerializer(typeof(CICMMetadataType));
if(cicmXml != null) if (cicmXml != null)
if(File.Exists(cicmXml)) if (File.Exists(cicmXml))
{
try try
{ {
StreamReader sr = new StreamReader(cicmXml); var sr = new StreamReader(cicmXml);
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr); sidecar = (CICMMetadataType) sidecarXs.Deserialize(sr);
sr.Close(); sr.Close();
} }
catch catch
{ {
DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing..."); DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing...");
return (int)ErrorNumber.InvalidSidecar; return (int) ErrorNumber.InvalidSidecar;
} }
}
else else
{ {
DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing..."); DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing...");
return (int)ErrorNumber.FileNotFound; return (int) ErrorNumber.FileNotFound;
} }
PluginBase plugins = GetPluginBase.Instance; var plugins = GetPluginBase.Instance;
List<IWritableImage> candidates = new List<IWritableImage>(); var candidates = new List<IWritableImage>();
// Try extension // Try extension
if(string.IsNullOrEmpty(wanteOutputFormat)) if (string.IsNullOrEmpty(wanteOutputFormat))
candidates.AddRange(plugins.WritableImages.Values.Where(t => candidates.AddRange(plugins.WritableImages.Values.Where(t =>
t.KnownExtensions t.KnownExtensions
.Contains(Path.GetExtension(outputFile)))); .Contains(Path.GetExtension(outputFile))));
// Try Id // Try Id
else if(Guid.TryParse(wanteOutputFormat, out Guid outId)) else if (Guid.TryParse(wanteOutputFormat, out var outId))
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId))); candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
// Try name // Try name
else else
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, wanteOutputFormat, candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, wanteOutputFormat,
StringComparison StringComparison
.InvariantCultureIgnoreCase))); .InvariantCultureIgnoreCase)));
if(candidates.Count == 0) if (candidates.Count == 0)
{ {
DicConsole.WriteLine("No plugin supports requested extension."); DicConsole.WriteLine("No plugin supports requested extension.");
return (int)ErrorNumber.FormatNotFound; return (int) ErrorNumber.FormatNotFound;
} }
if(candidates.Count > 1) if (candidates.Count > 1)
{ {
DicConsole.WriteLine("More than one plugin supports requested extension."); DicConsole.WriteLine("More than one plugin supports requested extension.");
return (int)ErrorNumber.TooManyFormats; return (int) ErrorNumber.TooManyFormats;
} }
IWritableImage outputFormat = candidates[0]; var outputFormat = candidates[0];
DumpLog dumpLog = new DumpLog(outputPrefix + ".log", dev); var dumpLog = new DumpLog(outputPrefix + ".log", dev);
if(MainClass.Verbose) if (MainClass.Verbose)
{ {
dumpLog.WriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id); dumpLog.WriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id); DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
@@ -285,19 +298,19 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name); DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
} }
Dump dumper = new Dump(doResume, dev, devicePath, outputFormat, retryPasses, force, false, persistent, var dumper = new Dump(doResume, dev, devicePath, outputFormat, retryPasses, force, false, persistent,
stopOnError, resume, dumpLog, encoding, outputPrefix, outputFile, parsedOptions, stopOnError, resume, dumpLog, encoding, outputPrefix, outputFile, parsedOptions,
sidecar, (uint)skip, noMetadata, noTrim, firstTrackPregap); sidecar, (uint) skip, noMetadata, noTrim, firstTrackPregap);
dumper.UpdateStatus += Progress.UpdateStatus; dumper.UpdateStatus += Progress.UpdateStatus;
dumper.ErrorMessage += Progress.ErrorMessage; dumper.ErrorMessage += Progress.ErrorMessage;
dumper.StoppingErrorMessage += Progress.ErrorMessage; dumper.StoppingErrorMessage += Progress.ErrorMessage;
dumper.UpdateProgress += Progress.UpdateProgress; dumper.UpdateProgress += Progress.UpdateProgress;
dumper.PulseProgress += Progress.PulseProgress; dumper.PulseProgress += Progress.PulseProgress;
dumper.InitProgress += Progress.InitProgress; dumper.InitProgress += Progress.InitProgress;
dumper.EndProgress += Progress.EndProgress; dumper.EndProgress += Progress.EndProgress;
dumper.InitProgress2 += Progress.InitProgress2; dumper.InitProgress2 += Progress.InitProgress2;
dumper.EndProgress2 += Progress.EndProgress2; dumper.EndProgress2 += Progress.EndProgress2;
dumper.UpdateProgress2 += Progress.UpdateProgress2; dumper.UpdateProgress2 += Progress.UpdateProgress2;
System.Console.CancelKeyPress += (sender, e) => System.Console.CancelKeyPress += (sender, e) =>
{ {
e.Cancel = true; e.Cancel = true;
@@ -307,7 +320,7 @@ namespace DiscImageChef.Commands
dumper.Start(); dumper.Start();
dev.Close(); dev.Close();
return (int)ErrorNumber.NoError; return (int) ErrorNumber.NoError;
} }
} }
} }

View File

@@ -53,11 +53,11 @@ using Spare = DiscImageChef.Decoders.DVD.Spare;
namespace DiscImageChef.Commands namespace DiscImageChef.Commands
{ {
class MediaInfoCommand : Command internal class MediaInfoCommand : Command
{ {
string devicePath; private string devicePath;
string outputPrefix; private string outputPrefix;
bool showHelp; private bool showHelp;
public MediaInfoCommand() : base("media-info", "Gets information about the media inserted on a device.") public MediaInfoCommand() : base("media-info", "Gets information about the media inserted on a device.")
{ {
@@ -79,52 +79,61 @@ namespace DiscImageChef.Commands
public override int Invoke(IEnumerable<string> arguments) public override int Invoke(IEnumerable<string> arguments)
{ {
List<string> extra = Options.Parse(arguments); var extra = Options.Parse(arguments);
if(showHelp) if (showHelp)
{ {
Options.WriteOptionDescriptions(CommandSet.Out); Options.WriteOptionDescriptions(CommandSet.Out);
return (int)ErrorNumber.HelpRequested; return (int) ErrorNumber.HelpRequested;
} }
MainClass.PrintCopyright(); MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; if (MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; if (MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
Statistics.AddCommand("media-info"); Statistics.AddCommand("media-info");
if(extra.Count > 1) if (extra.Count > 1)
{ {
DicConsole.ErrorWriteLine("Too many arguments."); DicConsole.ErrorWriteLine("Too many arguments.");
return (int)ErrorNumber.UnexpectedArgumentCount; return (int) ErrorNumber.UnexpectedArgumentCount;
} }
if(extra.Count == 0) if (extra.Count == 0)
{ {
DicConsole.ErrorWriteLine("Missing device path."); DicConsole.ErrorWriteLine("Missing device path.");
return (int)ErrorNumber.MissingArgument; return (int) ErrorNumber.MissingArgument;
} }
devicePath = extra[0]; devicePath = extra[0];
DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Media-Info command", "--device={0}", devicePath); DicConsole.DebugWriteLine("Media-Info command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", outputPrefix); DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", outputPrefix);
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", MainClass.Verbose);
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0])) if (devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':'; devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(devicePath); Device dev;
try
if(dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); dev = new Device(devicePath);
return (int)ErrorNumber.CannotOpenDevice;
if (dev.Error)
{
DicConsole.ErrorWriteLine(Error.Print(dev.LastError));
return (int) ErrorNumber.CannotOpenDevice;
}
}
catch (DeviceException e)
{
DicConsole.ErrorWriteLine(e.Message ?? Error.Print(e.LastError));
return (int) ErrorNumber.CannotOpenDevice;
} }
Statistics.AddDevice(dev); Statistics.AddDevice(dev);
switch(dev.Type) switch (dev.Type)
{ {
case DeviceType.ATA: case DeviceType.ATA:
DoAtaMediaInfo(); DoAtaMediaInfo();
@@ -143,38 +152,38 @@ namespace DiscImageChef.Commands
default: throw new NotSupportedException("Unknown device type."); default: throw new NotSupportedException("Unknown device type.");
} }
return (int)ErrorNumber.NoError; return (int) ErrorNumber.NoError;
} }
static void DoAtaMediaInfo() private static void DoAtaMediaInfo()
{ {
DicConsole.ErrorWriteLine("Please use device-info command for ATA devices."); DicConsole.ErrorWriteLine("Please use device-info command for ATA devices.");
} }
static void DoNvmeMediaInfo(string outputPrefix, Device dev) private static void DoNvmeMediaInfo(string outputPrefix, Device dev)
{ {
throw new NotImplementedException("NVMe devices not yet supported."); throw new NotImplementedException("NVMe devices not yet supported.");
} }
static void DoSdMediaInfo() private static void DoSdMediaInfo()
{ {
DicConsole.ErrorWriteLine("Please use device-info command for MMC/SD devices."); DicConsole.ErrorWriteLine("Please use device-info command for MMC/SD devices.");
} }
static void DoScsiMediaInfo(string outputPrefix, Device dev) private static void DoScsiMediaInfo(string outputPrefix, Device dev)
{ {
ScsiInfo scsiInfo = new ScsiInfo(dev); var scsiInfo = new ScsiInfo(dev);
if(!scsiInfo.MediaInserted) return; if (!scsiInfo.MediaInserted) return;
if(scsiInfo.DeviceInfo.ScsiModeSense6 != null) if (scsiInfo.DeviceInfo.ScsiModeSense6 != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE (6)", DataFile.WriteTo("Media-Info command", outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE (6)",
scsiInfo.DeviceInfo.ScsiModeSense6); scsiInfo.DeviceInfo.ScsiModeSense6);
if(scsiInfo.DeviceInfo.ScsiModeSense10 != null) if (scsiInfo.DeviceInfo.ScsiModeSense10 != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE (10)", DataFile.WriteTo("Media-Info command", outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE (10)",
scsiInfo.DeviceInfo.ScsiModeSense10); scsiInfo.DeviceInfo.ScsiModeSense10);
switch(dev.ScsiType) switch (dev.ScsiType)
{ {
case PeripheralDeviceTypes.DirectAccess: case PeripheralDeviceTypes.DirectAccess:
case PeripheralDeviceTypes.MultiMediaDevice: case PeripheralDeviceTypes.MultiMediaDevice:
@@ -182,37 +191,37 @@ namespace DiscImageChef.Commands
case PeripheralDeviceTypes.OpticalDevice: case PeripheralDeviceTypes.OpticalDevice:
case PeripheralDeviceTypes.SimplifiedDevice: case PeripheralDeviceTypes.SimplifiedDevice:
case PeripheralDeviceTypes.WriteOnceDevice: case PeripheralDeviceTypes.WriteOnceDevice:
if(scsiInfo.ReadCapacity != null) if (scsiInfo.ReadCapacity != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readcapacity.bin", "SCSI READ CAPACITY", DataFile.WriteTo("Media-Info command", outputPrefix, "_readcapacity.bin", "SCSI READ CAPACITY",
scsiInfo.ReadCapacity); scsiInfo.ReadCapacity);
if(scsiInfo.ReadCapacity16 != null) if (scsiInfo.ReadCapacity16 != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readcapacity16.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readcapacity16.bin",
"SCSI READ CAPACITY(16)", scsiInfo.ReadCapacity16); "SCSI READ CAPACITY(16)", scsiInfo.ReadCapacity16);
if(scsiInfo.Blocks != 0 && scsiInfo.BlockSize != 0) if (scsiInfo.Blocks != 0 && scsiInfo.BlockSize != 0)
DicConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2} bytes)", DicConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2} bytes)",
scsiInfo.Blocks, scsiInfo.BlockSize, scsiInfo.Blocks * scsiInfo.BlockSize); scsiInfo.Blocks, scsiInfo.BlockSize, scsiInfo.Blocks * scsiInfo.BlockSize);
break; break;
case PeripheralDeviceTypes.SequentialAccess: case PeripheralDeviceTypes.SequentialAccess:
if(scsiInfo.DensitySupport != null) if (scsiInfo.DensitySupport != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_ssc_reportdensitysupport_media.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_ssc_reportdensitysupport_media.bin",
"SSC REPORT DENSITY SUPPORT (MEDIA)", scsiInfo.DensitySupport); "SSC REPORT DENSITY SUPPORT (MEDIA)", scsiInfo.DensitySupport);
if(scsiInfo.DensitySupportHeader.HasValue) if (scsiInfo.DensitySupportHeader.HasValue)
{ {
DicConsole.WriteLine("Densities supported by currently inserted media:"); DicConsole.WriteLine("Densities supported by currently inserted media:");
DicConsole.WriteLine(DensitySupport.PrettifyDensity(scsiInfo.DensitySupportHeader)); DicConsole.WriteLine(DensitySupport.PrettifyDensity(scsiInfo.DensitySupportHeader));
} }
} }
if(scsiInfo.MediaTypeSupport != null) if (scsiInfo.MediaTypeSupport != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, DataFile.WriteTo("Media-Info command", outputPrefix,
"_ssc_reportdensitysupport_medium_media.bin", "_ssc_reportdensitysupport_medium_media.bin",
"SSC REPORT DENSITY SUPPORT (MEDIUM & MEDIA)", scsiInfo.MediaTypeSupport); "SSC REPORT DENSITY SUPPORT (MEDIUM & MEDIA)", scsiInfo.MediaTypeSupport);
if(scsiInfo.MediaTypeSupportHeader.HasValue) if (scsiInfo.MediaTypeSupportHeader.HasValue)
{ {
DicConsole.WriteLine("Medium types currently inserted in device:"); DicConsole.WriteLine("Medium types currently inserted in device:");
DicConsole.WriteLine(DensitySupport.PrettifyMediumType(scsiInfo.MediaTypeSupportHeader)); DicConsole.WriteLine(DensitySupport.PrettifyMediumType(scsiInfo.MediaTypeSupportHeader));
@@ -224,276 +233,276 @@ namespace DiscImageChef.Commands
break; break;
} }
if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice) if (dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
{ {
if(scsiInfo.MmcConfiguration != null) if (scsiInfo.MmcConfiguration != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_getconfiguration_current.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_getconfiguration_current.bin",
"SCSI GET CONFIGURATION", scsiInfo.MmcConfiguration); "SCSI GET CONFIGURATION", scsiInfo.MmcConfiguration);
if(scsiInfo.RecognizedFormatLayers != null) if (scsiInfo.RecognizedFormatLayers != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_formatlayers.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_formatlayers.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.RecognizedFormatLayers); "SCSI READ DISC STRUCTURE", scsiInfo.RecognizedFormatLayers);
if(scsiInfo.WriteProtectionStatus != null) if (scsiInfo.WriteProtectionStatus != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_writeprotection.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_writeprotection.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.WriteProtectionStatus); "SCSI READ DISC STRUCTURE", scsiInfo.WriteProtectionStatus);
if(scsiInfo.DvdPfi != null) if (scsiInfo.DvdPfi != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_pfi.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_pfi.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdPfi); "SCSI READ DISC STRUCTURE", scsiInfo.DvdPfi);
if(scsiInfo.DecodedPfi.HasValue) if (scsiInfo.DecodedPfi.HasValue)
DicConsole.WriteLine("PFI:\n{0}", PFI.Prettify(scsiInfo.DecodedPfi)); DicConsole.WriteLine("PFI:\n{0}", PFI.Prettify(scsiInfo.DecodedPfi));
} }
if(scsiInfo.DvdDmi != null) if (scsiInfo.DvdDmi != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_dmi.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_dmi.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdDmi); "SCSI READ DISC STRUCTURE", scsiInfo.DvdDmi);
if(DMI.IsXbox(scsiInfo.DvdDmi)) if (DMI.IsXbox(scsiInfo.DvdDmi))
DicConsole.WriteLine("Xbox DMI:\n{0}", DMI.PrettifyXbox(scsiInfo.DvdDmi)); DicConsole.WriteLine("Xbox DMI:\n{0}", DMI.PrettifyXbox(scsiInfo.DvdDmi));
else if(DMI.IsXbox360(scsiInfo.DvdDmi)) else if (DMI.IsXbox360(scsiInfo.DvdDmi))
DicConsole.WriteLine("Xbox 360 DMI:\n{0}", DMI.PrettifyXbox360(scsiInfo.DvdDmi)); DicConsole.WriteLine("Xbox 360 DMI:\n{0}", DMI.PrettifyXbox360(scsiInfo.DvdDmi));
} }
if(scsiInfo.DvdCmi != null) if (scsiInfo.DvdCmi != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_cmi.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_cmi.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdCmi); "SCSI READ DISC STRUCTURE", scsiInfo.DvdCmi);
DicConsole.WriteLine("Lead-In CMI:\n{0}", CSS_CPRM.PrettifyLeadInCopyright(scsiInfo.DvdCmi)); DicConsole.WriteLine("Lead-In CMI:\n{0}", CSS_CPRM.PrettifyLeadInCopyright(scsiInfo.DvdCmi));
} }
if(scsiInfo.DvdBca != null) if (scsiInfo.DvdBca != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_bca.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_bca.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdBca); "SCSI READ DISC STRUCTURE", scsiInfo.DvdBca);
if(scsiInfo.DvdAacs != null) if (scsiInfo.DvdAacs != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_aacs.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_aacs.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdAacs); "SCSI READ DISC STRUCTURE", scsiInfo.DvdAacs);
if(scsiInfo.DvdRamDds != null) if (scsiInfo.DvdRamDds != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_dds.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_dds.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdRamDds); "SCSI READ DISC STRUCTURE", scsiInfo.DvdRamDds);
DicConsole.WriteLine("Disc Definition Structure:\n{0}", DDS.Prettify(scsiInfo.DvdRamDds)); DicConsole.WriteLine("Disc Definition Structure:\n{0}", DDS.Prettify(scsiInfo.DvdRamDds));
} }
if(scsiInfo.DvdRamCartridgeStatus != null) if (scsiInfo.DvdRamCartridgeStatus != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_status.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_status.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdRamCartridgeStatus); "SCSI READ DISC STRUCTURE", scsiInfo.DvdRamCartridgeStatus);
DicConsole.WriteLine("Medium Status:\n{0}", Cartridge.Prettify(scsiInfo.DvdRamCartridgeStatus)); DicConsole.WriteLine("Medium Status:\n{0}", Cartridge.Prettify(scsiInfo.DvdRamCartridgeStatus));
} }
if(scsiInfo.DvdRamSpareArea != null) if (scsiInfo.DvdRamSpareArea != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_spare.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_spare.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdRamSpareArea); "SCSI READ DISC STRUCTURE", scsiInfo.DvdRamSpareArea);
DicConsole.WriteLine("Spare Area Information:\n{0}", Spare.Prettify(scsiInfo.DvdRamSpareArea)); DicConsole.WriteLine("Spare Area Information:\n{0}", Spare.Prettify(scsiInfo.DvdRamSpareArea));
} }
if(scsiInfo.LastBorderOutRmd != null) if (scsiInfo.LastBorderOutRmd != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_lastrmd.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_lastrmd.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.LastBorderOutRmd); "SCSI READ DISC STRUCTURE", scsiInfo.LastBorderOutRmd);
if(scsiInfo.DvdPreRecordedInfo != null) if (scsiInfo.DvdPreRecordedInfo != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_pri.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_pri.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdPreRecordedInfo); "SCSI READ DISC STRUCTURE", scsiInfo.DvdPreRecordedInfo);
if(scsiInfo.DvdrMediaIdentifier != null) if (scsiInfo.DvdrMediaIdentifier != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdr_mediaid.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdr_mediaid.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrMediaIdentifier); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrMediaIdentifier);
if(scsiInfo.DvdrPhysicalInformation != null) if (scsiInfo.DvdrPhysicalInformation != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdr_pfi.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdr_pfi.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrPhysicalInformation); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrPhysicalInformation);
if(scsiInfo.DvdPlusAdip != null) if (scsiInfo.DvdPlusAdip != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd+_adip.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd+_adip.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdPlusAdip); "SCSI READ DISC STRUCTURE", scsiInfo.DvdPlusAdip);
if(scsiInfo.DvdPlusDcb != null) if (scsiInfo.DvdPlusDcb != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd+_dcb.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd+_dcb.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdPlusDcb); "SCSI READ DISC STRUCTURE", scsiInfo.DvdPlusDcb);
if(scsiInfo.HddvdCopyrightInformation != null) if (scsiInfo.HddvdCopyrightInformation != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_hddvd_cmi.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_hddvd_cmi.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.HddvdCopyrightInformation); "SCSI READ DISC STRUCTURE", scsiInfo.HddvdCopyrightInformation);
if(scsiInfo.HddvdrMediumStatus != null) if (scsiInfo.HddvdrMediumStatus != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_hddvdr_status.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_hddvdr_status.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.HddvdrMediumStatus); "SCSI READ DISC STRUCTURE", scsiInfo.HddvdrMediumStatus);
if(scsiInfo.HddvdrLastRmd != null) if (scsiInfo.HddvdrLastRmd != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_hddvdr_lastrmd.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_hddvdr_lastrmd.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.HddvdrLastRmd); "SCSI READ DISC STRUCTURE", scsiInfo.HddvdrLastRmd);
if(scsiInfo.DvdrLayerCapacity != null) if (scsiInfo.DvdrLayerCapacity != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdr_layercap.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdr_layercap.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrLayerCapacity); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrLayerCapacity);
if(scsiInfo.DvdrDlMiddleZoneStart != null) if (scsiInfo.DvdrDlMiddleZoneStart != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_mzs.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_mzs.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlMiddleZoneStart); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlMiddleZoneStart);
if(scsiInfo.DvdrDlJumpIntervalSize != null) if (scsiInfo.DvdrDlJumpIntervalSize != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_jis.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_jis.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlJumpIntervalSize); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlJumpIntervalSize);
if(scsiInfo.DvdrDlManualLayerJumpStartLba != null) if (scsiInfo.DvdrDlManualLayerJumpStartLba != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_manuallj.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_manuallj.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlManualLayerJumpStartLba); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlManualLayerJumpStartLba);
if(scsiInfo.DvdrDlRemapAnchorPoint != null) if (scsiInfo.DvdrDlRemapAnchorPoint != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_remapanchor.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_remapanchor.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlRemapAnchorPoint); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlRemapAnchorPoint);
if(scsiInfo.BlurayDiscInformation != null) if (scsiInfo.BlurayDiscInformation != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_di.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_di.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayDiscInformation); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayDiscInformation);
DicConsole.WriteLine("Blu-ray Disc Information:\n{0}", DI.Prettify(scsiInfo.BlurayDiscInformation)); DicConsole.WriteLine("Blu-ray Disc Information:\n{0}", DI.Prettify(scsiInfo.BlurayDiscInformation));
} }
if(scsiInfo.BlurayPac != null) if (scsiInfo.BlurayPac != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_pac.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_pac.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayPac); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayPac);
if(scsiInfo.BlurayBurstCuttingArea != null) if (scsiInfo.BlurayBurstCuttingArea != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_bca.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_bca.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayBurstCuttingArea); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayBurstCuttingArea);
DicConsole.WriteLine("Blu-ray Burst Cutting Area:\n{0}", DicConsole.WriteLine("Blu-ray Burst Cutting Area:\n{0}",
BCA.Prettify(scsiInfo.BlurayBurstCuttingArea)); BCA.Prettify(scsiInfo.BlurayBurstCuttingArea));
} }
if(scsiInfo.BlurayDds != null) if (scsiInfo.BlurayDds != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_dds.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_dds.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayDds); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayDds);
DicConsole.WriteLine("Blu-ray Disc Definition Structure:\n{0}", DicConsole.WriteLine("Blu-ray Disc Definition Structure:\n{0}",
Decoders.Bluray.DDS.Prettify(scsiInfo.BlurayDds)); Decoders.Bluray.DDS.Prettify(scsiInfo.BlurayDds));
} }
if(scsiInfo.BlurayCartridgeStatus != null) if (scsiInfo.BlurayCartridgeStatus != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_cartstatus.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_cartstatus.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayCartridgeStatus); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayCartridgeStatus);
DicConsole.WriteLine("Blu-ray Cartridge Status:\n{0}", DicConsole.WriteLine("Blu-ray Cartridge Status:\n{0}",
Decoders.Bluray.Cartridge.Prettify(scsiInfo.BlurayCartridgeStatus)); Decoders.Bluray.Cartridge.Prettify(scsiInfo.BlurayCartridgeStatus));
} }
if(scsiInfo.BluraySpareAreaInformation != null) if (scsiInfo.BluraySpareAreaInformation != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_spare.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_spare.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BluraySpareAreaInformation); "SCSI READ DISC STRUCTURE", scsiInfo.BluraySpareAreaInformation);
DicConsole.WriteLine("Blu-ray Spare Area Information:\n{0}", DicConsole.WriteLine("Blu-ray Spare Area Information:\n{0}",
Decoders.Bluray.Spare.Prettify(scsiInfo.BluraySpareAreaInformation)); Decoders.Bluray.Spare.Prettify(scsiInfo.BluraySpareAreaInformation));
} }
if(scsiInfo.BlurayRawDfl != null) if (scsiInfo.BlurayRawDfl != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_dfl.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_dfl.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayRawDfl); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayRawDfl);
if(scsiInfo.BlurayTrackResources != null) if (scsiInfo.BlurayTrackResources != null)
{ {
DicConsole.WriteLine("Track Resources Information:\n{0}", DicConsole.WriteLine("Track Resources Information:\n{0}",
DiscInformation.Prettify(scsiInfo.BlurayTrackResources)); DiscInformation.Prettify(scsiInfo.BlurayTrackResources));
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_001b.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_001b.bin",
"SCSI READ DISC INFORMATION", scsiInfo.BlurayTrackResources); "SCSI READ DISC INFORMATION", scsiInfo.BlurayTrackResources);
} }
if(scsiInfo.BlurayPowResources != null) if (scsiInfo.BlurayPowResources != null)
{ {
DicConsole.WriteLine("POW Resources Information:\n{0}", DicConsole.WriteLine("POW Resources Information:\n{0}",
DiscInformation.Prettify(scsiInfo.BlurayPowResources)); DiscInformation.Prettify(scsiInfo.BlurayPowResources));
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_010b.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_010b.bin",
"SCSI READ DISC INFORMATION", scsiInfo.BlurayPowResources); "SCSI READ DISC INFORMATION", scsiInfo.BlurayPowResources);
} }
if(scsiInfo.Toc != null) if (scsiInfo.Toc != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_toc.bin", "SCSI READ TOC/PMA/ATIP", DataFile.WriteTo("Media-Info command", outputPrefix, "_toc.bin", "SCSI READ TOC/PMA/ATIP",
scsiInfo.Toc); scsiInfo.Toc);
if(scsiInfo.DecodedToc.HasValue) if (scsiInfo.DecodedToc.HasValue)
DicConsole.WriteLine("TOC:\n{0}", TOC.Prettify(scsiInfo.DecodedToc)); DicConsole.WriteLine("TOC:\n{0}", TOC.Prettify(scsiInfo.DecodedToc));
} }
if(scsiInfo.Atip != null) if (scsiInfo.Atip != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_atip.bin", "SCSI READ TOC/PMA/ATIP", DataFile.WriteTo("Media-Info command", outputPrefix, "_atip.bin", "SCSI READ TOC/PMA/ATIP",
scsiInfo.Atip); scsiInfo.Atip);
if(scsiInfo.DecodedAtip.HasValue) if (scsiInfo.DecodedAtip.HasValue)
DicConsole.WriteLine("ATIP:\n{0}", ATIP.Prettify(scsiInfo.DecodedAtip)); DicConsole.WriteLine("ATIP:\n{0}", ATIP.Prettify(scsiInfo.DecodedAtip));
} }
if(scsiInfo.CompactDiscInformation != null) if (scsiInfo.CompactDiscInformation != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_000b.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_000b.bin",
"SCSI READ DISC INFORMATION", scsiInfo.CompactDiscInformation); "SCSI READ DISC INFORMATION", scsiInfo.CompactDiscInformation);
if(scsiInfo.DecodedCompactDiscInformation.HasValue) if (scsiInfo.DecodedCompactDiscInformation.HasValue)
DicConsole.WriteLine("Standard Disc Information:\n{0}", DicConsole.WriteLine("Standard Disc Information:\n{0}",
DiscInformation.Prettify000b(scsiInfo.DecodedCompactDiscInformation)); DiscInformation.Prettify000b(scsiInfo.DecodedCompactDiscInformation));
} }
if(scsiInfo.Session != null) if (scsiInfo.Session != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_session.bin", "SCSI READ TOC/PMA/ATIP", DataFile.WriteTo("Media-Info command", outputPrefix, "_session.bin", "SCSI READ TOC/PMA/ATIP",
scsiInfo.Session); scsiInfo.Session);
if(scsiInfo.DecodedSession.HasValue) if (scsiInfo.DecodedSession.HasValue)
DicConsole.WriteLine("Session information:\n{0}", Session.Prettify(scsiInfo.DecodedSession)); DicConsole.WriteLine("Session information:\n{0}", Session.Prettify(scsiInfo.DecodedSession));
} }
if(scsiInfo.RawToc != null) if (scsiInfo.RawToc != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_rawtoc.bin", "SCSI READ TOC/PMA/ATIP", DataFile.WriteTo("Media-Info command", outputPrefix, "_rawtoc.bin", "SCSI READ TOC/PMA/ATIP",
scsiInfo.RawToc); scsiInfo.RawToc);
if(scsiInfo.FullToc.HasValue) if (scsiInfo.FullToc.HasValue)
DicConsole.WriteLine("Raw TOC:\n{0}", FullTOC.Prettify(scsiInfo.RawToc)); DicConsole.WriteLine("Raw TOC:\n{0}", FullTOC.Prettify(scsiInfo.RawToc));
} }
if(scsiInfo.Pma != null) if (scsiInfo.Pma != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_pma.bin", "SCSI READ TOC/PMA/ATIP", DataFile.WriteTo("Media-Info command", outputPrefix, "_pma.bin", "SCSI READ TOC/PMA/ATIP",
scsiInfo.Pma); scsiInfo.Pma);
DicConsole.WriteLine("PMA:\n{0}", PMA.Prettify(scsiInfo.Pma)); DicConsole.WriteLine("PMA:\n{0}", PMA.Prettify(scsiInfo.Pma));
} }
if(scsiInfo.CdTextLeadIn != null) if (scsiInfo.CdTextLeadIn != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_cdtext.bin", "SCSI READ TOC/PMA/ATIP", DataFile.WriteTo("Media-Info command", outputPrefix, "_cdtext.bin", "SCSI READ TOC/PMA/ATIP",
scsiInfo.CdTextLeadIn); scsiInfo.CdTextLeadIn);
if(scsiInfo.DecodedCdTextLeadIn.HasValue) if (scsiInfo.DecodedCdTextLeadIn.HasValue)
DicConsole.WriteLine("CD-TEXT on Lead-In:\n{0}", DicConsole.WriteLine("CD-TEXT on Lead-In:\n{0}",
CDTextOnLeadIn.Prettify(scsiInfo.DecodedCdTextLeadIn)); CDTextOnLeadIn.Prettify(scsiInfo.DecodedCdTextLeadIn));
} }
if(!string.IsNullOrEmpty(scsiInfo.Mcn)) DicConsole.WriteLine("MCN: {0}", scsiInfo.Mcn); if (!string.IsNullOrEmpty(scsiInfo.Mcn)) DicConsole.WriteLine("MCN: {0}", scsiInfo.Mcn);
if(scsiInfo.Isrcs != null) if (scsiInfo.Isrcs != null)
foreach(KeyValuePair<byte, string> isrc in scsiInfo.Isrcs) foreach (var isrc in scsiInfo.Isrcs)
DicConsole.WriteLine("Track's {0} ISRC: {1}", isrc.Key, isrc.Value); DicConsole.WriteLine("Track's {0} ISRC: {1}", isrc.Key, isrc.Value);
if(scsiInfo.XboxSecuritySector != null) if (scsiInfo.XboxSecuritySector != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_xbox_ss.bin", "KREON EXTRACT SS", DataFile.WriteTo("Media-Info command", outputPrefix, "_xbox_ss.bin", "KREON EXTRACT SS",
scsiInfo.XboxSecuritySector); scsiInfo.XboxSecuritySector);
if(scsiInfo.DecodedXboxSecuritySector.HasValue) if (scsiInfo.DecodedXboxSecuritySector.HasValue)
DicConsole.WriteLine("Xbox Security Sector:\n{0}", SS.Prettify(scsiInfo.DecodedXboxSecuritySector)); DicConsole.WriteLine("Xbox Security Sector:\n{0}", SS.Prettify(scsiInfo.DecodedXboxSecuritySector));
if(scsiInfo.XgdInfo != null) if (scsiInfo.XgdInfo != null)
{ {
DicConsole.WriteLine("Video layer 0 size: {0} sectors", scsiInfo.XgdInfo.L0Video); DicConsole.WriteLine("Video layer 0 size: {0} sectors", scsiInfo.XgdInfo.L0Video);
DicConsole.WriteLine("Video layer 1 size: {0} sectors", scsiInfo.XgdInfo.L1Video); DicConsole.WriteLine("Video layer 1 size: {0} sectors", scsiInfo.XgdInfo.L1Video);
DicConsole.WriteLine("Middle zone size: {0} sectors", scsiInfo.XgdInfo.MiddleZone); DicConsole.WriteLine("Middle zone size: {0} sectors", scsiInfo.XgdInfo.MiddleZone);
DicConsole.WriteLine("Game data size: {0} sectors", scsiInfo.XgdInfo.GameSize); DicConsole.WriteLine("Game data size: {0} sectors", scsiInfo.XgdInfo.GameSize);
DicConsole.WriteLine("Total size: {0} sectors", scsiInfo.XgdInfo.TotalSize); DicConsole.WriteLine("Total size: {0} sectors", scsiInfo.XgdInfo.TotalSize);
DicConsole.WriteLine("Real layer break: {0}", scsiInfo.XgdInfo.LayerBreak); DicConsole.WriteLine("Real layer break: {0}", scsiInfo.XgdInfo.LayerBreak);
DicConsole.WriteLine(); DicConsole.WriteLine();
} }
} }
if(scsiInfo.MediaSerialNumber != null) if (scsiInfo.MediaSerialNumber != null)
{ {
DataFile.WriteTo("Media-Info command", outputPrefix, "_mediaserialnumber.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_mediaserialnumber.bin",
"SCSI READ MEDIA SERIAL NUMBER", scsiInfo.MediaSerialNumber); "SCSI READ MEDIA SERIAL NUMBER", scsiInfo.MediaSerialNumber);
DicConsole.Write("Media Serial Number: "); DicConsole.Write("Media Serial Number: ");
for(int i = 4; i < scsiInfo.MediaSerialNumber.Length; i++) for (var i = 4; i < scsiInfo.MediaSerialNumber.Length; i++)
DicConsole.Write("{0:X2}", scsiInfo.MediaSerialNumber[i]); DicConsole.Write("{0:X2}", scsiInfo.MediaSerialNumber[i]);
DicConsole.WriteLine(); DicConsole.WriteLine();

View File

@@ -40,12 +40,12 @@ using Mono.Options;
namespace DiscImageChef.Commands namespace DiscImageChef.Commands
{ {
class MediaScanCommand : Command internal class MediaScanCommand : Command
{ {
string devicePath; private string devicePath;
string ibgLogPath; private string ibgLogPath;
string mhddLogPath; private string mhddLogPath;
bool showHelp; private bool showHelp;
public MediaScanCommand() : base("media-scan", "Scans the media inserted on a device.") public MediaScanCommand() : base("media-scan", "Scans the media inserted on a device.")
{ {
@@ -59,100 +59,110 @@ namespace DiscImageChef.Commands
Help, Help,
{"mhdd-log|mw=", "Write a log of the scan in the format used by MHDD.", s => mhddLogPath = s}, {"mhdd-log|mw=", "Write a log of the scan in the format used by MHDD.", s => mhddLogPath = s},
{"ibg-log|b=", "Write a log of the scan in the format used by ImgBurn.", s => ibgLogPath = s}, {"ibg-log|b=", "Write a log of the scan in the format used by ImgBurn.", s => ibgLogPath = s},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null} {"help|h|?", "Show this message and exit.", v => showHelp = v != null}
}; };
} }
public override int Invoke(IEnumerable<string> arguments) public override int Invoke(IEnumerable<string> arguments)
{ {
List<string> extra = Options.Parse(arguments); var extra = Options.Parse(arguments);
if(showHelp) if (showHelp)
{ {
Options.WriteOptionDescriptions(CommandSet.Out); Options.WriteOptionDescriptions(CommandSet.Out);
return (int)ErrorNumber.HelpRequested; return (int) ErrorNumber.HelpRequested;
} }
MainClass.PrintCopyright(); MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; if (MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; if (MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
Statistics.AddCommand("media-scan"); Statistics.AddCommand("media-scan");
if(extra.Count > 1) if (extra.Count > 1)
{ {
DicConsole.ErrorWriteLine("Too many arguments."); DicConsole.ErrorWriteLine("Too many arguments.");
return (int)ErrorNumber.UnexpectedArgumentCount; return (int) ErrorNumber.UnexpectedArgumentCount;
} }
if(extra.Count == 0) if (extra.Count == 0)
{ {
DicConsole.ErrorWriteLine("Missing device path."); DicConsole.ErrorWriteLine("Missing device path.");
return (int)ErrorNumber.MissingArgument; return (int) ErrorNumber.MissingArgument;
} }
devicePath = extra[0]; devicePath = extra[0];
DicConsole.DebugWriteLine("Media-Scan command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Media-Scan command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Media-Scan command", "--device={0}", devicePath); DicConsole.DebugWriteLine("Media-Scan command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", ibgLogPath); DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", ibgLogPath);
DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", mhddLogPath); DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", mhddLogPath);
DicConsole.DebugWriteLine("Media-Scan command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Media-Scan command", "--verbose={0}", MainClass.Verbose);
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0])) if (devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':'; devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(devicePath); Device dev;
try
if(dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); dev = new Device(devicePath);
return (int)ErrorNumber.CannotOpenDevice;
if (dev.Error)
{
DicConsole.ErrorWriteLine(Error.Print(dev.LastError));
return (int) ErrorNumber.CannotOpenDevice;
}
}
catch (DeviceException e)
{
DicConsole.ErrorWriteLine(e.Message ?? Error.Print(e.LastError));
return (int) ErrorNumber.CannotOpenDevice;
} }
Statistics.AddDevice(dev); Statistics.AddDevice(dev);
MediaScan scanner = new MediaScan(mhddLogPath, ibgLogPath, devicePath, dev); var scanner = new MediaScan(mhddLogPath, ibgLogPath, devicePath, dev);
scanner.UpdateStatus += Progress.UpdateStatus; scanner.UpdateStatus += Progress.UpdateStatus;
scanner.StoppingErrorMessage += Progress.ErrorMessage; scanner.StoppingErrorMessage += Progress.ErrorMessage;
scanner.UpdateProgress += Progress.UpdateProgress; scanner.UpdateProgress += Progress.UpdateProgress;
scanner.PulseProgress += Progress.PulseProgress; scanner.PulseProgress += Progress.PulseProgress;
scanner.InitProgress += Progress.InitProgress; scanner.InitProgress += Progress.InitProgress;
scanner.EndProgress += Progress.EndProgress; scanner.EndProgress += Progress.EndProgress;
System.Console.CancelKeyPress += (sender, e) => System.Console.CancelKeyPress += (sender, e) =>
{ {
e.Cancel = true; e.Cancel = true;
scanner.Abort(); scanner.Abort();
}; };
ScanResults results = scanner.Scan(); var results = scanner.Scan();
DicConsole.WriteLine("Took a total of {0} seconds ({1} processing commands).", results.TotalTime, DicConsole.WriteLine("Took a total of {0} seconds ({1} processing commands).", results.TotalTime,
results.ProcessingTime); results.ProcessingTime);
DicConsole.WriteLine("Average speed: {0:F3} MiB/sec.", results.AvgSpeed); DicConsole.WriteLine("Average speed: {0:F3} MiB/sec.", results.AvgSpeed);
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", results.MaxSpeed); DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", results.MaxSpeed);
DicConsole.WriteLine("Slowest speed burst: {0:F3} MiB/sec.", results.MinSpeed); DicConsole.WriteLine("Slowest speed burst: {0:F3} MiB/sec.", results.MinSpeed);
DicConsole.WriteLine("Summary:"); DicConsole.WriteLine("Summary:");
DicConsole.WriteLine("{0} sectors took less than 3 ms.", results.A); DicConsole.WriteLine("{0} sectors took less than 3 ms.", results.A);
DicConsole.WriteLine("{0} sectors took less than 10 ms but more than 3 ms.", results.B); DicConsole.WriteLine("{0} sectors took less than 10 ms but more than 3 ms.", results.B);
DicConsole.WriteLine("{0} sectors took less than 50 ms but more than 10 ms.", results.C); DicConsole.WriteLine("{0} sectors took less than 50 ms but more than 10 ms.", results.C);
DicConsole.WriteLine("{0} sectors took less than 150 ms but more than 50 ms.", results.D); DicConsole.WriteLine("{0} sectors took less than 150 ms but more than 50 ms.", results.D);
DicConsole.WriteLine("{0} sectors took less than 500 ms but more than 150 ms.", results.E); DicConsole.WriteLine("{0} sectors took less than 500 ms but more than 150 ms.", results.E);
DicConsole.WriteLine("{0} sectors took more than 500 ms.", results.F); DicConsole.WriteLine("{0} sectors took more than 500 ms.", results.F);
DicConsole.WriteLine("{0} sectors could not be read.", DicConsole.WriteLine("{0} sectors could not be read.",
results.UnreadableSectors.Count); results.UnreadableSectors.Count);
if(results.UnreadableSectors.Count > 0) if (results.UnreadableSectors.Count > 0)
foreach(ulong bad in results.UnreadableSectors) foreach (var bad in results.UnreadableSectors)
DicConsole.WriteLine("Sector {0} could not be read", bad); DicConsole.WriteLine("Sector {0} could not be read", bad);
DicConsole.WriteLine(); DicConsole.WriteLine();
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(results.SeekTotal != 0 || results.SeekMin != double.MaxValue || results.SeekMax != double.MinValue) if (results.SeekTotal != 0 || results.SeekMin != double.MaxValue || results.SeekMax != double.MinValue)
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
DicConsole.WriteLine("Testing {0} seeks, longest seek took {1:F3} ms, fastest one took {2:F3} ms. ({3:F3} ms average)", DicConsole.WriteLine(
results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000); "Testing {0} seeks, longest seek took {1:F3} ms, fastest one took {2:F3} ms. ({3:F3} ms average)",
results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000);
dev.Close(); dev.Close();
return (int)ErrorNumber.NoError; return (int) ErrorNumber.NoError;
} }
} }
} }