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