Beispiel #1
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);
Beispiel #2
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);
            }

            ScsiPassThroughDirectAndSenseBuffer 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);
        }