Exemplo n.º 1
0
        /// <summary>Sends a SCSI command</summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <param name="fd">File handle</param>
        /// <param name="cdb">SCSI CDB</param>
        /// <param name="buffer">Buffer for SCSI command response</param>
        /// <param name="senseBuffer">Buffer with the SCSI sense</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="direction">SCSI command transfer direction</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense">
        ///     <c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer" /> contains SCSI
        ///     sense
        /// </param>
        internal static int SendScsiCommand(SafeFileHandle fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
                                            uint timeout, ScsiIoctlDirection direction, out double duration,
                                            out bool sense)
        {
            senseBuffer = null;
            duration    = 0;
            sense       = false;

            if (buffer == null)
            {
                return(-1);
            }

            var sptdSb = new ScsiPassThroughDirectAndSenseBuffer
            {
                SenseBuf = new byte[32], sptd = new ScsiPassThroughDirect
                {
                    Cdb                = new byte[16], CdbLength = (byte)cdb.Length, SenseInfoLength = 32,
                    DataIn             = direction,
                    DataTransferLength = (uint)buffer.Length, TimeOutValue = timeout,
                    DataBuffer         = Marshal.AllocHGlobal(buffer.Length)
                }
            };

            sptdSb.sptd.Length          = (ushort)Marshal.SizeOf(sptdSb.sptd);
            sptdSb.sptd.SenseInfoOffset = (uint)Marshal.SizeOf(sptdSb.sptd);
            Array.Copy(cdb, sptdSb.sptd.Cdb, cdb.Length);

            uint k     = 0;
            int  error = 0;

            Marshal.Copy(buffer, 0, sptdSb.sptd.DataBuffer, buffer.Length);

            DateTime start = DateTime.Now;

            bool hasError = !Extern.DeviceIoControlScsi(fd, WindowsIoctl.IoctlScsiPassThroughDirect, ref sptdSb,
                                                        (uint)Marshal.SizeOf(sptdSb), ref sptdSb,
                                                        (uint)Marshal.SizeOf(sptdSb), ref k, IntPtr.Zero);

            DateTime end = DateTime.Now;

            if (hasError)
            {
                error = Marshal.GetLastWin32Error();
            }

            Marshal.Copy(sptdSb.sptd.DataBuffer, buffer, 0, buffer.Length);

            sense |= sptdSb.sptd.ScsiStatus != 0;

            senseBuffer = new byte[32];
            Array.Copy(sptdSb.SenseBuf, senseBuffer, 32);

            duration = (end - start).TotalMilliseconds;

            Marshal.FreeHGlobal(sptdSb.sptd.DataBuffer);

            return(error);
        }
Exemplo n.º 2
0
 internal static extern bool DeviceIoControlScsi(SafeFileHandle hDevice, WindowsIoctl ioControlCode,
                                                 ref ScsiPassThroughDirectAndSenseBuffer inBuffer,
                                                 uint nInBufferSize,
                                                 ref ScsiPassThroughDirectAndSenseBuffer outBuffer,
                                                 uint nOutBufferSize, ref uint pBytesReturned,
                                                 IntPtr overlapped);