From 20cde7a217ae83952aaa9a9c401e4e0b9e638ee5 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 12 Oct 2015 19:55:00 +0100 Subject: [PATCH] * DiscImageChef.Devices/Enums.cs: * DiscImageChef.Devices/Command.cs: * DiscImageChef.Devices/Device/Commands.cs: * DiscImageChef.Devices/Device/Variables.cs: * DiscImageChef.Devices/Device/Destructor.cs: * DiscImageChef.Devices/Device/Constructor.cs: * DiscImageChef.Devices/DiscImageChef.Devices.csproj: Added device class. * DiscImageChef.Devices/Device/ScsiCommands.cs: Added device class. Added SCSI INQUIRY. --- DiscImageChef.Devices/ChangeLog | 15 +++ DiscImageChef.Devices/Command.cs | 62 ++++++++- DiscImageChef.Devices/Device/Commands.cs | 50 +++++++ DiscImageChef.Devices/Device/Constructor.cs | 76 +++++++++++ DiscImageChef.Devices/Device/Destructor.cs | 62 +++++++++ DiscImageChef.Devices/Device/ScsiCommands.cs | 123 ++++++++++++++++++ DiscImageChef.Devices/Device/Variables.cs | 71 ++++++++++ .../DiscImageChef.Devices.csproj | 6 + DiscImageChef.Devices/Enums.cs | 25 ++++ 9 files changed, 488 insertions(+), 2 deletions(-) create mode 100644 DiscImageChef.Devices/Device/Commands.cs create mode 100644 DiscImageChef.Devices/Device/Constructor.cs create mode 100644 DiscImageChef.Devices/Device/Destructor.cs create mode 100644 DiscImageChef.Devices/Device/ScsiCommands.cs create mode 100644 DiscImageChef.Devices/Device/Variables.cs diff --git a/DiscImageChef.Devices/ChangeLog b/DiscImageChef.Devices/ChangeLog index b3bca912..bd4362bf 100644 --- a/DiscImageChef.Devices/ChangeLog +++ b/DiscImageChef.Devices/ChangeLog @@ -1,3 +1,18 @@ +2015-10-12 Natalia Portillo + + * Enums.cs: + * Command.cs: + * Device/Commands.cs: + * Device/Variables.cs: + * Device/Destructor.cs: + * Device/Constructor.cs: + * DiscImageChef.Devices.csproj: + Added device class. + + * Device/ScsiCommands.cs: + Added device class. + Added SCSI INQUIRY. + 2015-10-12 Natalia Portillo * Enums.cs: diff --git a/DiscImageChef.Devices/Command.cs b/DiscImageChef.Devices/Command.cs index 671660e5..0a03bcc7 100644 --- a/DiscImageChef.Devices/Command.cs +++ b/DiscImageChef.Devices/Command.cs @@ -37,13 +37,71 @@ // //$Id$ using System; +using DiscImageChef.Interop; +using Microsoft.Win32.SafeHandles; namespace DiscImageChef.Devices { - public class Command + public static class Command { - public Command() + public static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, Enums.ScsiDirection direction, out double duration, out bool sense) { + Interop.PlatformID ptID = DetectOS.GetRealPlatformID(); + + return SendScsiCommand(ptID, (SafeFileHandle)fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration, out sense); + } + + public static int SendScsiCommand(Interop.PlatformID ptID, object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, Enums.ScsiDirection direction, out double duration, out bool sense) + { + switch (ptID) + { + case Interop.PlatformID.Win32NT: + { + Windows.ScsiIoctlDirection dir; + + switch (direction) + { + case Enums.ScsiDirection.In: + dir = Windows.ScsiIoctlDirection.In; + break; + case Enums.ScsiDirection.Out: + dir = Windows.ScsiIoctlDirection.Out; + break; + default: + dir = Windows.ScsiIoctlDirection.Unspecified; + break; + } + + return Windows.Command.SendScsiCommand((SafeFileHandle)fd, cdb, ref buffer, out senseBuffer, timeout, dir, out duration, out sense); + } + case Interop.PlatformID.Linux: + { + Linux.ScsiIoctlDirection dir; + + switch (direction) + { + case Enums.ScsiDirection.In: + dir = Linux.ScsiIoctlDirection.In; + break; + case Enums.ScsiDirection.Out: + dir = Linux.ScsiIoctlDirection.Out; + break; + case Enums.ScsiDirection.Bidirectional: + dir = Linux.ScsiIoctlDirection.Unspecified; + break; + case Enums.ScsiDirection.None: + dir = Linux.ScsiIoctlDirection.None; + break; + default: + dir = Linux.ScsiIoctlDirection.Unknown; + break; + } + + return Linux.Command.SendScsiCommand((int)fd, cdb, ref buffer, out senseBuffer, timeout, dir, out duration, out sense); + } + default: + throw new InvalidOperationException(String.Format("Platform {0} not yet supported.", ptID)); + } } } } diff --git a/DiscImageChef.Devices/Device/Commands.cs b/DiscImageChef.Devices/Device/Commands.cs new file mode 100644 index 00000000..f43a13a7 --- /dev/null +++ b/DiscImageChef.Devices/Device/Commands.cs @@ -0,0 +1,50 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Commands.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; + +namespace DiscImageChef.Devices +{ + public partial class Device + { + public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, Enums.ScsiDirection direction, out double duration, out bool sense) + { + return Command.SendScsiCommand(platformID, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration, out sense); + } + } +} + diff --git a/DiscImageChef.Devices/Device/Constructor.cs b/DiscImageChef.Devices/Device/Constructor.cs new file mode 100644 index 00000000..d64b06d7 --- /dev/null +++ b/DiscImageChef.Devices/Device/Constructor.cs @@ -0,0 +1,76 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Device.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 Microsoft.Win32.SafeHandles; + +namespace DiscImageChef.Devices +{ + public partial class Device + { + public Device(string devicePath) + { + platformID = Interop.DetectOS.GetRealPlatformID(); + Timeout = 15; + + switch (platformID) + { + case Interop.PlatformID.Win32NT: + { + fd = Windows.Extern.CreateFile(devicePath, + Windows.FileAccess.GenericRead | Windows.FileAccess.GenericWrite, + Windows.FileShare.Read | Windows.FileShare.Write, + IntPtr.Zero, Windows.FileMode.OpenExisting, + Windows.FileAttributes.Normal, IntPtr.Zero); + + throw new NotImplementedException(); + //break; + } + case Interop.PlatformID.Linux: + { + fd = Linux.Extern.open(devicePath, Linux.FileFlags.ReadWrite); + + throw new NotImplementedException(); + //break; + } + default: + throw new InvalidOperationException(String.Format("Platform {0} not yet supported.", platformID)); + } + } + } +} + diff --git a/DiscImageChef.Devices/Device/Destructor.cs b/DiscImageChef.Devices/Device/Destructor.cs new file mode 100644 index 00000000..db670532 --- /dev/null +++ b/DiscImageChef.Devices/Device/Destructor.cs @@ -0,0 +1,62 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Destructor.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 Microsoft.Win32.SafeHandles; + +namespace DiscImageChef.Devices +{ + public partial class Device + { + ~Device() + { + if (fd != null) + { + switch (platformID) + { + case Interop.PlatformID.Win32NT: + Windows.Extern.CloseHandle((SafeFileHandle)fd); + break; + case Interop.PlatformID.Linux: + Linux.Extern.close((int)fd); + break; + } + } + } + } +} + diff --git a/DiscImageChef.Devices/Device/ScsiCommands.cs b/DiscImageChef.Devices/Device/ScsiCommands.cs new file mode 100644 index 00000000..00b9aa68 --- /dev/null +++ b/DiscImageChef.Devices/Device/ScsiCommands.cs @@ -0,0 +1,123 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ScsiCommands.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; + +namespace DiscImageChef.Devices +{ + public partial class Device + { + public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer) + { + return ScsiInquiry(out buffer, out senseBuffer, Timeout); + } + + public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, out double duration) + { + return ScsiInquiry(out buffer, out senseBuffer, Timeout, out duration); + } + + public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, uint timeout) + { + double duration; + return ScsiInquiry(out buffer, out senseBuffer, timeout, out duration); + } + + public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) + { + buffer = new byte[5]; + senseBuffer = new byte[32]; + 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); + + if (sense) + return true; + + byte pagesLength = (byte)(buffer[4] + 5); + + cdb = new byte[] { (byte)Enums.ScsiCommands.Inquiry, 0, 0, 0, pagesLength, 0 }; + buffer = new byte[pagesLength]; + senseBuffer = new byte[32]; + + SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + + return sense; + } + + public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page) + { + return ScsiInquiry(out buffer, out senseBuffer, page, Timeout); + } + + public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page, out double duration) + { + return ScsiInquiry(out buffer, out senseBuffer, page, Timeout, out duration); + } + + public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page, uint timeout) + { + double duration; + return ScsiInquiry(out buffer, out senseBuffer, page, timeout, out duration); + } + + public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page, uint timeout, out double duration) + { + buffer = new byte[5]; + senseBuffer = new byte[32]; + 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); + + if (sense) + return true; + + byte pagesLength = (byte)(buffer[4] + 5); + + cdb = new byte[] { (byte)Enums.ScsiCommands.Inquiry, 1, page, 0, pagesLength, 0 }; + buffer = new byte[pagesLength]; + senseBuffer = new byte[32]; + + SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, Enums.ScsiDirection.In, out duration, out sense); + + return sense; + } + } +} + diff --git a/DiscImageChef.Devices/Device/Variables.cs b/DiscImageChef.Devices/Device/Variables.cs new file mode 100644 index 00000000..f6859459 --- /dev/null +++ b/DiscImageChef.Devices/Device/Variables.cs @@ -0,0 +1,71 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Variables.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 Microsoft.Win32.SafeHandles; + +namespace DiscImageChef.Devices +{ + public partial class Device + { + Interop.PlatformID platformID; + object fd; + + public Interop.PlatformID PlatformID + { + get + { + return platformID; + } + } + + public object FileHandle + { + get + { + return fd; + } + } + + public uint Timeout + { + get; + set; + } + } +} + diff --git a/DiscImageChef.Devices/DiscImageChef.Devices.csproj b/DiscImageChef.Devices/DiscImageChef.Devices.csproj index dddd62fb..bf29290d 100644 --- a/DiscImageChef.Devices/DiscImageChef.Devices.csproj +++ b/DiscImageChef.Devices/DiscImageChef.Devices.csproj @@ -45,11 +45,17 @@ + + + + + + diff --git a/DiscImageChef.Devices/Enums.cs b/DiscImageChef.Devices/Enums.cs index 47e52ec8..b07de94e 100644 --- a/DiscImageChef.Devices/Enums.cs +++ b/DiscImageChef.Devices/Enums.cs @@ -2346,6 +2346,31 @@ namespace DiscImageChef.Devices VariableSizedCDB = 0x7F } #endregion SCSI Commands + + public enum ScsiDirection + { + /// + /// No data transfer happens + /// + None, + /// + /// From host to device + /// + Out, + /// + /// From device to host + /// + In, + /// + /// Bidirectional device/host + /// + Bidirectional, + /// + /// Unspecified + /// + Unspecified + } + } }