diff --git a/DiscImageChef.Decoders/ChangeLog b/DiscImageChef.Decoders/ChangeLog index 95be0c1ff..63aa2caf5 100644 --- a/DiscImageChef.Decoders/ChangeLog +++ b/DiscImageChef.Decoders/ChangeLog @@ -1,3 +1,10 @@ +2015-10-13 Natalia Portillo + + * SCSI.cs: + Correct size miscalculation. + Do not print "Device claims no standard", generates too much + noise. + 2015-10-05 Natalia Portillo * CD.cs: diff --git a/DiscImageChef.Decoders/SCSI.cs b/DiscImageChef.Decoders/SCSI.cs index a331baa73..39a365e60 100644 --- a/DiscImageChef.Decoders/SCSI.cs +++ b/DiscImageChef.Decoders/SCSI.cs @@ -2493,7 +2493,7 @@ namespace DiscImageChef.Decoders return null; } - if (SCSIInquiryResponse.Length != SCSIInquiryResponse[4] + 4) + if (SCSIInquiryResponse.Length != SCSIInquiryResponse[4] + 5) { //if (MainClass.isDebug) Console.WriteLine("DEBUG (SCSI INQUIRY Decoder): INQUIRY response length ({0} bytes) is different than specified in length field ({1} bytes), decoded data can be incorrect, proceeding anyway.", SCSIInquiryResponse.Length, SCSIInquiryResponse[4] + 4); @@ -2873,7 +2873,7 @@ namespace DiscImageChef.Decoders switch (VersionDescriptor & 0x001F) { case 0x00: - sb.AppendLine("Device claims no standard"); + //sb.AppendLine("Device claims no standard"); break; default: sb.AppendFormat("Device claims unknown version 0x{0:X2} of no standard", VersionDescriptor & 0x001F).AppendLine(); diff --git a/DiscImageChef.Devices/ChangeLog b/DiscImageChef.Devices/ChangeLog index 92ed40547..f56ba1ac8 100644 --- a/DiscImageChef.Devices/ChangeLog +++ b/DiscImageChef.Devices/ChangeLog @@ -1,3 +1,17 @@ +2015-10-13 Natalia Portillo + + * Device/Constructor.cs: + Add OS error detection and handling. + On Linux move to opening O_RDONLY and O_NONBLOCK to allow + opening read-only media and removable drives without media. + + * Device/Variables.cs: + * Device/ScsiCommands.cs: + Add OS error detection and handling. + + * DiscImageChef.Devices.csproj: + Downgraded .NET version. + 2015-10-12 Natalia Portillo * Enums.cs: diff --git a/DiscImageChef.Devices/Device/Constructor.cs b/DiscImageChef.Devices/Device/Constructor.cs index 8f102e5ea..af69bfa47 100644 --- a/DiscImageChef.Devices/Device/Constructor.cs +++ b/DiscImageChef.Devices/Device/Constructor.cs @@ -37,6 +37,7 @@ // //$Id$ using System; using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; namespace DiscImageChef.Devices { @@ -50,6 +51,7 @@ namespace DiscImageChef.Devices { platformID = Interop.DetectOS.GetRealPlatformID(); Timeout = 15; + error = false; switch (platformID) { @@ -61,15 +63,27 @@ namespace DiscImageChef.Devices IntPtr.Zero, Windows.FileMode.OpenExisting, Windows.FileAttributes.Normal, IntPtr.Zero); - throw new NotImplementedException(); - //break; + if (((SafeFileHandle)fd).IsInvalid) + { + error = true; + lastError = Marshal.GetLastWin32Error(); + } + + //throw new NotImplementedException(); + break; } case Interop.PlatformID.Linux: { - fd = Linux.Extern.open(devicePath, Linux.FileFlags.ReadWrite); + fd = Linux.Extern.open(devicePath, Linux.FileFlags.Readonly | Linux.FileFlags.NonBlocking); - throw new NotImplementedException(); - //break; + if ((int)fd < 0) + { + error = true; + lastError = Marshal.GetLastWin32Error(); + } + + //throw new NotImplementedException(); + break; } default: throw new InvalidOperationException(String.Format("Platform {0} not yet supported.", platformID)); diff --git a/DiscImageChef.Devices/Device/ScsiCommands.cs b/DiscImageChef.Devices/Device/ScsiCommands.cs index 646edc67f..f62706152 100644 --- a/DiscImageChef.Devices/Device/ScsiCommands.cs +++ b/DiscImageChef.Devices/Device/ScsiCommands.cs @@ -92,7 +92,8 @@ namespace DiscImageChef.Devices byte[] cdb = { (byte)Enums.ScsiCommands.Inquiry, 0, 0, 0, 5, 0 }; bool sense; - SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + error = lastError != 0; if (sense) return true; @@ -103,7 +104,8 @@ namespace DiscImageChef.Devices buffer = new byte[pagesLength]; senseBuffer = new byte[32]; - SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + error = lastError != 0; return sense; } @@ -163,7 +165,8 @@ namespace DiscImageChef.Devices byte[] cdb = { (byte)Enums.ScsiCommands.Inquiry, 1, page, 0, 5, 0 }; bool sense; - SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + error = lastError != 0; if (sense) return true; @@ -174,7 +177,8 @@ namespace DiscImageChef.Devices buffer = new byte[pagesLength]; senseBuffer = new byte[32]; - SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + error = lastError != 0; return sense; } diff --git a/DiscImageChef.Devices/Device/Variables.cs b/DiscImageChef.Devices/Device/Variables.cs index ffa2c04de..7b1c13cfb 100644 --- a/DiscImageChef.Devices/Device/Variables.cs +++ b/DiscImageChef.Devices/Device/Variables.cs @@ -44,6 +44,8 @@ namespace DiscImageChef.Devices { Interop.PlatformID platformID; object fd; + bool error; + int lastError; /// /// Gets the Platform ID for this device @@ -78,6 +80,30 @@ namespace DiscImageChef.Devices get; set; } + + /// + /// Gets a value indicating whether this is in error. + /// + /// true if error; otherwise, false. + public bool Error + { + get + { + return error; + } + } + + /// + /// Gets the last error number. + /// + /// The last error. + public int LastError + { + get + { + return lastError; + } + } } } diff --git a/DiscImageChef.Devices/DiscImageChef.Devices.csproj b/DiscImageChef.Devices/DiscImageChef.Devices.csproj index bf29290d7..a92c2b35d 100644 --- a/DiscImageChef.Devices/DiscImageChef.Devices.csproj +++ b/DiscImageChef.Devices/DiscImageChef.Devices.csproj @@ -9,7 +9,7 @@ Library DiscImageChef.Devices DiscImageChef.Devices - v4.5 + v3.5 2.2 diff --git a/DiscImageChef.Interop/ChangeLog b/DiscImageChef.Interop/ChangeLog index 217df1d88..3b6d4028d 100644 --- a/DiscImageChef.Interop/ChangeLog +++ b/DiscImageChef.Interop/ChangeLog @@ -1,3 +1,8 @@ +2015-10-13 Natalia Portillo + + * DiscImageChef.Interop.csproj: + Downgraded .NET version. + 2015-10-12 Natalia Portillo * DiscImageChef.Interop.csproj: diff --git a/DiscImageChef.Interop/DiscImageChef.Interop.csproj b/DiscImageChef.Interop/DiscImageChef.Interop.csproj index e60e929b3..2e7c81166 100644 --- a/DiscImageChef.Interop/DiscImageChef.Interop.csproj +++ b/DiscImageChef.Interop/DiscImageChef.Interop.csproj @@ -9,7 +9,7 @@ Library DiscImageChef.Interop DiscImageChef.Interop - v4.5 + v3.5 2.2 diff --git a/DiscImageChef/ChangeLog b/DiscImageChef/ChangeLog index 616e53b33..f2c36e320 100644 --- a/DiscImageChef/ChangeLog +++ b/DiscImageChef/ChangeLog @@ -1,3 +1,11 @@ +2015-10-13 Natalia Portillo + + * Main.cs: + * Options.cs: + * DiscImageChef.csproj: + * Commands/DeviceInfo.cs: + Added "device-info" command. + 2015-10-12 Natalia Portillo * DetectImageFormat.cs: diff --git a/DiscImageChef/Commands/DeviceInfo.cs b/DiscImageChef/Commands/DeviceInfo.cs new file mode 100644 index 000000000..67ca46f24 --- /dev/null +++ b/DiscImageChef/Commands/DeviceInfo.cs @@ -0,0 +1,90 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : DeviceInfo.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Devices; +using System.IO; + +namespace DiscImageChef.Commands +{ + public static class DeviceInfo + { + public static void doDeviceInfo(DeviceInfoSubOptions options) + { + if (MainClass.isDebug) + { + Console.WriteLine("--debug={0}", options.Debug); + Console.WriteLine("--verbose={0}", options.Verbose); + Console.WriteLine("--device={0}", options.DevicePath); + } + + if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' && + options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0])) + { + options.DevicePath = "\\\\.\\" + Char.ToUpper(options.DevicePath[0]) + ':'; + } + + Device dev = new Device(options.DevicePath); + + if (dev.Error) + { + Console.WriteLine("Error {0} opening device.", dev.LastError); + return; + } + + byte[] senseBuf; + byte[] inqBuf; + + bool sense = dev.ScsiInquiry(out inqBuf, out senseBuf); + + if(sense) + { + Console.WriteLine("SCSI error. Sense decoding not yet implemented."); + + #if DEBUG + FileStream senseFs = File.Open("sense.bin", FileMode.OpenOrCreate); + senseFs.Write(senseBuf, 0, senseBuf.Length); + #endif + } + else + Console.WriteLine("SCSI OK"); + + Console.WriteLine("{0}", Decoders.SCSI.PrettifySCSIInquiry(inqBuf)); + } + } +} + diff --git a/DiscImageChef/DiscImageChef.csproj b/DiscImageChef/DiscImageChef.csproj index 7286ce3eb..855ae77b3 100644 --- a/DiscImageChef/DiscImageChef.csproj +++ b/DiscImageChef/DiscImageChef.csproj @@ -51,6 +51,7 @@ + @@ -171,5 +172,13 @@ {0BEB3088-B634-4289-AE17-CDF2D25D00D5} DiscImageChef.Decoders + + {57BB2341-AB62-48FD-91B8-46F5A2F9ED51} + DiscImageChef.Devices + + + {9183F2E0-A879-4F23-9EE3-C6908F1332B2} + DiscImageChef.Interop + \ No newline at end of file diff --git a/DiscImageChef/Main.cs b/DiscImageChef/Main.cs index 48ba147ad..be026faa1 100644 --- a/DiscImageChef/Main.cs +++ b/DiscImageChef/Main.cs @@ -129,6 +129,12 @@ namespace DiscImageChef isDebug = FormatsOptions.Debug; Commands.Formats.ListFormats(); break; + case "device-info": + DeviceInfoSubOptions DeviceInfoOptions = (DeviceInfoSubOptions)invokedVerbInstance; + isVerbose = DeviceInfoOptions.Verbose; + isDebug = DeviceInfoOptions.Debug; + Commands.DeviceInfo.doDeviceInfo(DeviceInfoOptions); + break; default: throw new ArgumentException("Should never arrive here!"); } diff --git a/DiscImageChef/Options.cs b/DiscImageChef/Options.cs index a076bd3fe..768db9600 100644 --- a/DiscImageChef/Options.cs +++ b/DiscImageChef/Options.cs @@ -214,6 +214,12 @@ namespace DiscImageChef public string InputFile { get; set; } } + public class DeviceInfoSubOptions : CommonSubOptions + { + [Option('i', "device", Required = true, HelpText = "Device path.")] + public string DevicePath { get; set; } + } + public class FormatsSubOptions : CommonSubOptions { } @@ -230,6 +236,7 @@ namespace DiscImageChef FormatsVerb = new FormatsSubOptions(); PrintHexVerb = new PrintHexSubOptions(); DecodeVerb = new DecodeSubOptions(); + DeviceInfoVerb = new DeviceInfoSubOptions(); } [VerbOption("analyze", HelpText = "Analyzes a disc image and searches for partitions and/or filesystems.")] @@ -256,6 +263,9 @@ namespace DiscImageChef [VerbOption("formats", HelpText = "Lists all supported disc images, partition schemes and file systems.")] public FormatsSubOptions FormatsVerb { get; set; } + [VerbOption("device-info", HelpText = "Gets information about a device.")] + public DeviceInfoSubOptions DeviceInfoVerb { get; set; } + [HelpVerbOption] public string DoHelpForVerb(string verbName) {