예제 #1
0
        public static uint GetDeviceReadTransferLength(byte[] commandBytes, PeripheralDeviceType deviceType, uint blockSize)
        {
            if (deviceType == PeripheralDeviceType.DirectAccessBlockDevice ||
                deviceType == PeripheralDeviceType.CDRomDevice)
            {
                return(GetBlockDeviceReadTransferLength(commandBytes, blockSize));
            }
            else if (deviceType == PeripheralDeviceType.SequentialAccessDevice)
            {
                return(SCSICommandParser.GetSequentialAccessDeviceReadTransferLength(commandBytes, blockSize));
            }

            throw new NotSupportedException("Device Type Not Supported!");
        }
예제 #2
0
        private SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER BuildSCSIPassThroughStructure(byte[] commandBytes, LogicalUnit logicalUnit, byte[] data)
        {
            SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER scsi = null;

            scsi               = new SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER();
            scsi.Spt.Length    = (ushort)Marshal.SizeOf(scsi.Spt);
            scsi.Spt.PathId    = logicalUnit.PathId;
            scsi.Spt.TargetId  = logicalUnit.TargetId;
            scsi.Spt.Lun       = logicalUnit.TargetLun;
            scsi.Spt.CdbLength = (byte)commandBytes.Length;
            scsi.Spt.Cdb       = commandBytes;

            if (data != null && data.Length > 0)
            {
                // DATA OUT (from initiator to target, WRITE)
                scsi.Spt.DataIn             = (byte)SCSIDataDirection.Out;
                scsi.Spt.DataTransferLength = (uint)data.Length;
                scsi.Spt.DataBuffer         = Marshal.AllocHGlobal((int)scsi.Spt.DataTransferLength);
                Marshal.Copy(data, 0, scsi.Spt.DataBuffer, data.Length);
            }
            else
            {
                // DATA IN (to initiator from target, READ)
                scsi.Spt.DataIn = (byte)SCSICommandParser.GetDataDirection(commandBytes);
                if ((SCSIDataDirection)scsi.Spt.DataIn == SCSIDataDirection.In)
                {
                    scsi.Spt.DataTransferLength = GetDataInTransferLength(commandBytes, logicalUnit);
                    scsi.Spt.DataBuffer         = Marshal.AllocHGlobal((int)scsi.Spt.DataTransferLength);
                }
                else
                {
                    scsi.Spt.DataTransferLength = 0; // No data!
                    scsi.Spt.DataBuffer         = IntPtr.Zero;
                }
            }
            Log(Severity.Verbose, "SCSI Command: {0}, Data Length: {1}, Transfer Direction: {2}, Transfer Length: {3}, LUN: {4}", (SCSIOpCodeName)commandBytes[0], data.Length, (SCSIDataDirection)scsi.Spt.DataIn, scsi.Spt.DataTransferLength, logicalUnit.AssociatedLun);
            scsi.Spt.TimeOutValue    = SCSI_TIMEOUT;
            scsi.Spt.SenseInfoOffset = (uint)Marshal.OffsetOf(typeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), "Sense");
            scsi.Spt.SenseInfoLength = (byte)scsi.Sense.Length;

            return(scsi);
        }
예제 #3
0
        private uint GetDataInTransferLength(byte[] commandBytes, LogicalUnit logicalUnit)
        {
            switch ((SCSIOpCodeName)commandBytes[0])
            {
            case SCSIOpCodeName.Read16:                            // DATA_IN (12-14)
            case SCSIOpCodeName.ReadReverse16:                     // DATA_IN (12-14)
            case SCSIOpCodeName.Read6:                             // DATA_IN (2-4)
            case SCSIOpCodeName.ReadReverse6:                      // DATA_IN (2-4)
            case SCSIOpCodeName.Read10:                            // DATA_IN (7-8)
            case SCSIOpCodeName.Read12:                            // DATA_IN (6-9)
            {
                if (logicalUnit.BlockSize == null)
                {
                    throw new NotSupportedException("Command Sequence Not Supported!");
                }
                return(SCSICommandParser.GetDeviceReadTransferLength(commandBytes, logicalUnit.DeviceType, logicalUnit.BlockSize.Value));
            }

            default:
                return(SCSICommandParser.GetCDBTransferLength(commandBytes, logicalUnit.DeviceType));
            }
        }