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.")
{ {
@@ -69,7 +69,7 @@ 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)
{ {
@@ -104,11 +104,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]) + ':';
Device dev = new Device(devicePath); Device dev;
try
{
dev = new Device(devicePath);
if (dev.Error) if (dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); 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;
} }
@@ -142,9 +151,9 @@ namespace DiscImageChef.Commands
{ {
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:
@@ -204,7 +213,7 @@ namespace DiscImageChef.Commands
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)
{ {
@@ -242,7 +251,7 @@ namespace DiscImageChef.Commands
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);
} }
@@ -266,7 +275,7 @@ namespace DiscImageChef.Commands
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));
@@ -451,7 +460,7 @@ namespace DiscImageChef.Commands
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);
@@ -460,7 +469,7 @@ namespace DiscImageChef.Commands
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);
@@ -647,9 +656,11 @@ 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)
{ {
@@ -695,12 +706,14 @@ namespace DiscImageChef.Commands
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(
"Selected PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)",
devInfo.PlextorFeatures.PoweRecSelected, devInfo.PlextorFeatures.PoweRecSelected,
devInfo.PlextorFeatures.PoweRecSelected / 177); devInfo.PlextorFeatures.PoweRecSelected / 177);
if (devInfo.PlextorFeatures.PoweRecMax > 0) if (devInfo.PlextorFeatures.PoweRecMax > 0)
DicConsole DicConsole
.WriteLine("Maximum PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)", .WriteLine(
"Maximum PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)",
devInfo.PlextorFeatures.PoweRecMax, devInfo.PlextorFeatures.PoweRecMax,
devInfo.PlextorFeatures.PoweRecMax / 177); devInfo.PlextorFeatures.PoweRecMax / 177);
if (devInfo.PlextorFeatures.PoweRecLast > 0) if (devInfo.PlextorFeatures.PoweRecLast > 0)
@@ -833,7 +846,7 @@ namespace DiscImageChef.Commands
{ {
case DeviceType.MMC: case DeviceType.MMC:
{ {
bool noInfo = true; var noInfo = true;
if (devInfo.CID != null) if (devInfo.CID != null)
{ {
@@ -869,7 +882,7 @@ namespace DiscImageChef.Commands
break; break;
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
{ {
bool noInfo = true; var noInfo = true;
if (devInfo.CID != null) if (devInfo.CID != null)
{ {

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
{
dev = new Device(devicePath);
if (dev.Error) if (dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); 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.")
{ {
@@ -116,7 +117,7 @@ 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)
{ {
@@ -164,9 +165,9 @@ namespace DiscImageChef.Commands
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;
@@ -175,7 +176,8 @@ namespace DiscImageChef.Commands
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)
{ {
@@ -186,25 +188,34 @@ 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]) + ':';
Device dev = new Device(devicePath); Device dev;
try
{
dev = new Device(devicePath);
if (dev.Error) if (dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); 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;
} }
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();
} }
@@ -221,12 +232,13 @@ namespace DiscImageChef.Commands
} }
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();
} }
@@ -235,14 +247,15 @@ namespace DiscImageChef.Commands
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))
@@ -250,7 +263,7 @@ namespace DiscImageChef.Commands
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
@@ -270,9 +283,9 @@ namespace DiscImageChef.Commands
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)
{ {
@@ -285,7 +298,7 @@ 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;

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,7 +79,7 @@ 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)
{ {
@@ -114,11 +114,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]) + ':';
Device dev = new Device(devicePath); Device dev;
try
{
dev = new Device(devicePath);
if (dev.Error) if (dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); 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;
} }
@@ -146,24 +155,24 @@ namespace DiscImageChef.Commands
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;
@@ -465,7 +474,7 @@ namespace DiscImageChef.Commands
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)
@@ -493,7 +502,7 @@ namespace DiscImageChef.Commands
"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.")
{ {
@@ -65,7 +65,7 @@ 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)
{ {
@@ -101,17 +101,26 @@ 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]) + ':';
Device dev = new Device(devicePath); Device dev;
try
{
dev = new Device(devicePath);
if (dev.Error) if (dev.Error)
{ {
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError); 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;
} }
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;
@@ -123,7 +132,7 @@ namespace DiscImageChef.Commands
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);
@@ -140,7 +149,7 @@ namespace DiscImageChef.Commands
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();
@@ -148,7 +157,8 @@ namespace DiscImageChef.Commands
#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(
"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); results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000);
dev.Close(); dev.Close();