private unsafe bool SendScsiCmd64(byte cmd, byte op, byte lun, byte dirIn, int bank, int lba, int bytes, byte[] data) { SCSI_PASS_THROUGH_WITH_BUFFERS sptB = new SCSI_PASS_THROUGH_WITH_BUFFERS(); int len = Marshal.SizeOf(sptB) + bytes; // total size of buffer byte[] buffer = new byte[len]; fixed (byte* buf = buffer) { SCSI_PASS_THROUGH_WITH_BUFFERS* sptBuf = (SCSI_PASS_THROUGH_WITH_BUFFERS*)buf; SCSI_PASS_THROUGH* spt = (SCSI_PASS_THROUGH*)buf; CDB10* cdb = (CDB10*)&(spt->Cdb); bool bRetVal; sptBuf->totalSize = (uint)len; spt->Length = (ushort)Marshal.SizeOf(*spt); spt->Lun = lun; spt->CdbLength = 10; spt->SenseInfoLength = 18; spt->DataIn = dirIn; spt->DataTransferLength = (uint)bytes; spt->TimeOutValue = _TimeOut; spt->SenseInfoOffset = (uint)Marshal.SizeOf(*spt) + 4; spt->DataBufferOffset = (uint)Marshal.SizeOf(sptB); cdb->Cmd = cmd; cdb->OpCode = op; cdb->LBA = (uint)lba; cdb->Bank = (byte)bank; Util.ReverseBytes((byte*)&(cdb->LBA), 4); cdb->Blocks = (ushort)(bytes / _BlockSize); Util.ReverseBytes((byte*)&(cdb->Blocks), 2); if ((dirIn == 0) && (data != null)) Marshal.Copy(data, 0, (IntPtr)(buf + Marshal.SizeOf(sptB)), bytes); int[] BytesXfered = new int[1]; BytesXfered[0] = 0; fixed (byte* lpInBuffer = buffer) { fixed (byte* lpOutBuffer = buffer) { fixed (int* lpBytesXferred = BytesXfered) { bRetVal = PInvoke.DeviceIoControl(_hDevice, CyConst.IOCTL_SCSI_PASS_THROUGH, (IntPtr)lpInBuffer, len, (IntPtr)lpOutBuffer, len, (IntPtr)lpBytesXferred, (IntPtr)null); } } } int error = Marshal.GetLastWin32Error(); if (dirIn == 1) Marshal.Copy((IntPtr)(buf + Marshal.SizeOf(sptB)), data, 0, bytes); return bRetVal; } }
private unsafe bool SendScsiCmd64(byte cmd, byte op, byte lun, byte dirIn, int bank, int lba, int bytes, byte[] data) { SCSI_PASS_THROUGH_WITH_BUFFERS sptB = new SCSI_PASS_THROUGH_WITH_BUFFERS(); int len = Marshal.SizeOf(sptB) + bytes; // total size of buffer byte[] buffer = new byte[len]; fixed(byte *buf = buffer) { SCSI_PASS_THROUGH_WITH_BUFFERS *sptBuf = (SCSI_PASS_THROUGH_WITH_BUFFERS *)buf; SCSI_PASS_THROUGH *spt = (SCSI_PASS_THROUGH *)buf; CDB10 * cdb = (CDB10 *)&(spt->Cdb); bool bRetVal; sptBuf->totalSize = (uint)len; spt->Length = (ushort)Marshal.SizeOf(*spt); spt->Lun = lun; spt->CdbLength = 10; spt->SenseInfoLength = 18; spt->DataIn = dirIn; spt->DataTransferLength = (uint)bytes; spt->TimeOutValue = _TimeOut; spt->SenseInfoOffset = (uint)Marshal.SizeOf(*spt) + 4; spt->DataBufferOffset = (uint)Marshal.SizeOf(sptB); cdb->Cmd = cmd; cdb->OpCode = op; cdb->LBA = (uint)lba; cdb->Bank = (byte)bank; Util.ReverseBytes((byte *)&(cdb->LBA), 4); cdb->Blocks = (ushort)(bytes / _BlockSize); Util.ReverseBytes((byte *)&(cdb->Blocks), 2); if ((dirIn == 0) && (data != null)) { Marshal.Copy(data, 0, (IntPtr)(buf + Marshal.SizeOf(sptB)), bytes); } int[] BytesXfered = new int[1]; BytesXfered[0] = 0; fixed(byte *lpInBuffer = buffer) { fixed(byte *lpOutBuffer = buffer) { fixed(int *lpBytesXferred = BytesXfered) { bRetVal = PInvoke.DeviceIoControl(_hDevice, CyConst.IOCTL_SCSI_PASS_THROUGH, (IntPtr)lpInBuffer, len, (IntPtr)lpOutBuffer, len, (IntPtr)lpBytesXferred, (IntPtr)null); } } } int error = Marshal.GetLastWin32Error(); if (dirIn == 1) { Marshal.Copy((IntPtr)(buf + Marshal.SizeOf(sptB)), data, 0, bytes); } return(bRetVal); } }