Ejemplo 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>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
                                            uint timeout, ScsiDirection direction, out double duration, out bool sense)
        {
            PlatformID ptId = DetectOS.GetRealPlatformID();

            return(SendScsiCommand(ptId, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration,
                                   out sense));
        }
Ejemplo n.º 2
0
        /// <summary>Sends a SCSI command to this device</summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <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 command returned non-OK status and <paramref name="senseBuffer" /> contains
        ///     SCSI sense
        /// </param>
        public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
                                   ScsiDirection direction, out double duration, out bool sense)
        {
            if (!(_remote is null))
            {
                return(_remote.SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, direction, out duration,
                                               out sense));
            }

            return(Command.SendScsiCommand(PlatformId, FileHandle, cdb, ref buffer, out senseBuffer, timeout, direction,
                                           out duration, out sense));
        }
Ejemplo n.º 3
0
        /// <summary>Sends a SCSI command</summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <param name="ptId">Platform ID for executing the command</param>
        /// <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>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb, ref byte[] buffer,
                                            out byte[] senseBuffer, uint timeout, ScsiDirection direction,
                                            out double duration, out bool sense)
        {
            switch (ptId)
            {
            case PlatformID.Win32NT:
            {
                ScsiIoctlDirection dir;

                switch (direction)
                {
                case ScsiDirection.In:
                    dir = ScsiIoctlDirection.In;

                    break;

                case ScsiDirection.Out:
                    dir = ScsiIoctlDirection.Out;

                    break;

                default:
                    dir = ScsiIoctlDirection.Unspecified;

                    break;
                }

                return(Windows.Command.SendScsiCommand((SafeFileHandle)fd, cdb, ref buffer, out senseBuffer,
                                                       timeout, dir, out duration, out sense));
            }

            case PlatformID.Linux:
            {
                Linux.ScsiIoctlDirection dir;

                switch (direction)
                {
                case ScsiDirection.In:
                    dir = Linux.ScsiIoctlDirection.In;

                    break;

                case ScsiDirection.Out:
                    dir = Linux.ScsiIoctlDirection.Out;

                    break;

                case ScsiDirection.Bidirectional:
                    dir = Linux.ScsiIoctlDirection.Unspecified;

                    break;

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

            case PlatformID.FreeBSD:
            {
                CcbFlags flags = 0;

                switch (direction)
                {
                case ScsiDirection.In:
                    flags = CcbFlags.CamDirIn;

                    break;

                case ScsiDirection.Out:
                    flags = CcbFlags.CamDirOut;

                    break;

                case ScsiDirection.Bidirectional:
                    flags = CcbFlags.CamDirBoth;

                    break;

                case ScsiDirection.None:
                    flags = CcbFlags.CamDirNone;

                    break;
                }

                return(IntPtr.Size == 8
                               ? FreeBSD.Command.SendScsiCommand64((IntPtr)fd, cdb, ref buffer, out senseBuffer,
                                                                   timeout, flags, out duration, out sense)
                               : FreeBSD.Command.SendScsiCommand((IntPtr)fd, cdb, ref buffer, out senseBuffer, timeout,
                                                                 flags, out duration, out sense));
            }

            default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
            }
        }
Ejemplo n.º 4
0
        public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
                                   ScsiDirection direction, out double duration, out bool sense)
        {
            senseBuffer = null;
            duration    = 0;
            sense       = true;

            var cmdPkt = new AaruPacketCmdScsi
            {
                hdr = new AaruPacketHeader
                {
                    remote_id  = Consts.RemoteId, packet_id = Consts.PacketId, version = Consts.PacketVersion,
                    packetType = AaruPacketType.CommandScsi
                },
                direction = (int)direction, timeout = timeout * 1000
            };

            if (cdb != null)
            {
                cmdPkt.cdb_len = (uint)cdb.Length;
            }

            if (buffer != null)
            {
                cmdPkt.buf_len = (uint)buffer.Length;
            }

            cmdPkt.hdr.len = (uint)(Marshal.SizeOf <AaruPacketCmdScsi>() + cmdPkt.cdb_len + cmdPkt.buf_len);

            byte[] pktBuf = Marshal.StructureToByteArrayLittleEndian(cmdPkt);
            byte[] buf    = new byte[cmdPkt.hdr.len];

            Array.Copy(pktBuf, 0, buf, 0, Marshal.SizeOf <AaruPacketCmdScsi>());

            if (cdb != null)
            {
                Array.Copy(cdb, 0, buf, Marshal.SizeOf <AaruPacketCmdScsi>(), cmdPkt.cdb_len);
            }

            if (buffer != null)
            {
                Array.Copy(buffer, 0, buf, Marshal.SizeOf <AaruPacketCmdScsi>() + cmdPkt.cdb_len, cmdPkt.buf_len);
            }

            int len = _socket.Send(buf, SocketFlags.None);

            if (len != buf.Length)
            {
                AaruConsole.ErrorWriteLine("Could not write to the network...");

                return(-1);
            }

            byte[] hdrBuf = new byte[Marshal.SizeOf <AaruPacketHeader>()];

            len = Receive(_socket, hdrBuf, hdrBuf.Length, SocketFlags.Peek);

            if (len < hdrBuf.Length)
            {
                AaruConsole.ErrorWriteLine("Could not read from the network...");

                return(-1);
            }

            AaruPacketHeader hdr = Marshal.ByteArrayToStructureLittleEndian <AaruPacketHeader>(hdrBuf);

            if (hdr.remote_id != Consts.RemoteId ||
                hdr.packet_id != Consts.PacketId)
            {
                AaruConsole.ErrorWriteLine("Received data is not an Aaru Remote Packet...");

                return(-1);
            }

            if (hdr.packetType != AaruPacketType.ResponseScsi)
            {
                AaruConsole.ErrorWriteLine("Expected SCSI Response Packet, got packet type {0}...", hdr.packetType);

                return(-1);
            }

            buf = new byte[hdr.len];
            len = Receive(_socket, buf, buf.Length, SocketFlags.None);

            if (len < buf.Length)
            {
                AaruConsole.ErrorWriteLine("Could not read from the network...");

                return(-1);
            }

            AaruPacketResScsi res = Marshal.ByteArrayToStructureLittleEndian <AaruPacketResScsi>(buf);

            senseBuffer = new byte[res.sense_len];
            Array.Copy(buf, Marshal.SizeOf <AaruPacketResScsi>(), senseBuffer, 0, res.sense_len);
            buffer = new byte[res.buf_len];
            Array.Copy(buf, Marshal.SizeOf <AaruPacketResScsi>() + res.sense_len, buffer, 0, res.buf_len);
            duration = res.duration;
            sense    = res.sense != 0;

            return((int)res.error_no);
        }
Ejemplo n.º 5
0
 /// <summary>
 ///     Sends a SCSI command to this device
 /// </summary>
 /// <returns>0 if no error occurred, otherwise, errno</returns>
 /// <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 command returned non-OK status and <paramref name="senseBuffer" /> contains
 ///     SCSI sense
 /// </param>
 public int SendScsiCommand(byte[]        cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
                            ScsiDirection direction, out double duration, out bool sense) =>
 Command.SendScsiCommand(PlatformId, FileHandle, cdb, ref buffer, out senseBuffer, timeout, direction,
                         out duration, out sense);