From 4ecec3373ae03fd496595e634a286005ecdbc4b5 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 24 Oct 2015 04:46:11 +0100 Subject: [PATCH] Implemented SCSI PREVENT ALLOW MEDIUM REMOVAL command. --- DiscImageChef.Devices/ChangeLog | 6 ++ DiscImageChef.Devices/Device/ScsiCommands.cs | 82 ++++++++++++++++++-- DiscImageChef.Devices/Enums.cs | 22 ++++++ 3 files changed, 104 insertions(+), 6 deletions(-) diff --git a/DiscImageChef.Devices/ChangeLog b/DiscImageChef.Devices/ChangeLog index f0189ceb2..8ef671919 100644 --- a/DiscImageChef.Devices/ChangeLog +++ b/DiscImageChef.Devices/ChangeLog @@ -1,3 +1,9 @@ +2015-10-24 Natalia Portillo + + * Enums.cs: + * Device/ScsiCommands.cs: + Implemented SCSI PREVENT ALLOW MEDIUM REMOVAL command. + 2015-10-24 Natalia Portillo * Enums.cs: diff --git a/DiscImageChef.Devices/Device/ScsiCommands.cs b/DiscImageChef.Devices/Device/ScsiCommands.cs index a6c906b05..b9eb3db64 100644 --- a/DiscImageChef.Devices/Device/ScsiCommands.cs +++ b/DiscImageChef.Devices/Device/ScsiCommands.cs @@ -214,7 +214,7 @@ namespace DiscImageChef.Devices /// Sends the SCSI MODE SENSE(6) command to the device as introduced in SCSI-1 /// /// true if the command failed and contains the sense buffer. - /// Buffer where the SCSI INQUIRY response will be stored + /// Buffer where the SCSI MODE SENSE(6) response will be stored /// Sense buffer. /// Timeout in seconds. /// Duration in milliseconds it took for the device to execute the command. @@ -227,7 +227,7 @@ namespace DiscImageChef.Devices /// Sends the SCSI MODE SENSE(6) command to the device as introduced in SCSI-2 /// /// true if the command failed and contains the sense buffer. - /// Buffer where the SCSI INQUIRY response will be stored + /// Buffer where the SCSI MODE SENSE(6) response will be stored /// Sense buffer. /// Timeout in seconds. /// Duration in milliseconds it took for the device to execute the command. @@ -243,7 +243,7 @@ namespace DiscImageChef.Devices /// Sends the SCSI MODE SENSE(6) command to the device as introduced in SCSI-3 SPC-3 /// /// true if the command failed and contains the sense buffer. - /// Buffer where the SCSI INQUIRY response will be stored + /// Buffer where the SCSI MODE SENSE(6) response will be stored /// Sense buffer. /// Timeout in seconds. /// Duration in milliseconds it took for the device to execute the command. @@ -290,7 +290,7 @@ namespace DiscImageChef.Devices /// Sends the SCSI MODE SENSE(10) command to the device as introduced in SCSI-2 /// /// true if the command failed and contains the sense buffer. - /// Buffer where the SCSI INQUIRY response will be stored + /// Buffer where the SCSI MODE SENSE(10) response will be stored /// Sense buffer. /// Timeout in seconds. /// Duration in milliseconds it took for the device to execute the command. @@ -306,7 +306,7 @@ namespace DiscImageChef.Devices /// Sends the SCSI MODE SENSE(10) command to the device as introduced in SCSI-3 SPC-2 /// /// true if the command failed and contains the sense buffer. - /// Buffer where the SCSI INQUIRY response will be stored + /// Buffer where the SCSI MODE SENSE(10) response will be stored /// Sense buffer. /// Timeout in seconds. /// Duration in milliseconds it took for the device to execute the command. @@ -323,7 +323,7 @@ namespace DiscImageChef.Devices /// Sends the SCSI MODE SENSE(10) command to the device as introduced in SCSI-3 SPC-3 /// /// true if the command failed and contains the sense buffer. - /// Buffer where the SCSI INQUIRY response will be stored + /// Buffer where the SCSI MODE SENSE(10) response will be stored /// Sense buffer. /// Timeout in seconds. /// Duration in milliseconds it took for the device to execute the command. @@ -370,6 +370,76 @@ namespace DiscImageChef.Devices return sense; } + + /// + /// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command to prevent medium removal + /// + /// true, if allow medium removal was prevented, false otherwise. + /// true if the command failed and contains the sense buffer. + /// Sense buffer. + /// Timeout in seconds. + /// Duration in milliseconds it took for the device to execute the command. + public bool PreventMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration) + { + return PreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration); + } + + /// + /// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command to allow medium removal + /// + /// true, if allow medium removal was prevented, false otherwise. + /// true if the command failed and contains the sense buffer. + /// Sense buffer. + /// Timeout in seconds. + /// Duration in milliseconds it took for the device to execute the command. + public bool AllowMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration) + { + return PreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration); + } + + /// + /// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command + /// + /// true, if allow medium removal was prevented, false otherwise. + /// true if the command failed and contains the sense buffer. + /// Sense buffer. + /// Timeout in seconds. + /// Duration in milliseconds it took for the device to execute the command. + /// true to prevent medium removal, false to allow it. + public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool prevent, uint timeout, out double duration) + { + if (prevent) + return PreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration); + else + return PreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration); + } + + /// + /// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command + /// + /// true, if allow medium removal was prevented, false otherwise. + /// true if the command failed and contains the sense buffer. + /// Sense buffer. + /// Timeout in seconds. + /// Duration in milliseconds it took for the device to execute the command. + /// Prevention mode. + public bool PreventAllowMediumRemoval(out byte[] senseBuffer, ScsiPreventAllowMode preventMode, uint timeout, out double duration) + { + senseBuffer = new byte[32]; + byte[] cdb = new byte[6]; + bool sense; + byte[] buffer = new byte[0]; + + cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval; + cdb[4] = (byte)((byte)preventMode & 0x03); + + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense); + error = lastError != 0; + + DicConsole.DebugWriteLine("SCSI Device", "PREVENT ALLOW MEDIUM REMOVAL took {0} ms.", duration); + + return sense; + } } } diff --git a/DiscImageChef.Devices/Enums.cs b/DiscImageChef.Devices/Enums.cs index bd55ca516..12f1594af 100644 --- a/DiscImageChef.Devices/Enums.cs +++ b/DiscImageChef.Devices/Enums.cs @@ -2721,5 +2721,27 @@ namespace DiscImageChef.Devices /// Saved = 0xC0 } + + public enum ScsiPreventAllowMode : byte + { + /// + /// Allows medium removal from data transport and from medium changer + /// + Allow = 0x00, + /// + /// Prevents medium removal from data transport but allows it from medium changer + /// + Prevent = 0x01, + /// + /// Allows medium removal from data transport but prevents it from medium changer + /// + [Obsolete] + PreventChanger = 0x02, + /// + /// Prevents medium removal from both data transport and medium changer + /// + [Obsolete] + PreventAll = 0x03 + } }