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!"); }
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); }
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)); } }