Пример #1
0
        private unsafe bool UnsafeAbort()
        {
            int[] dwBytes = new int[1];
            dwBytes[0] = 0;
            byte[] buffer = new byte[1];
            buffer[0] = Address;

            fixed(byte *lpInBuffer = buffer)
            {
                fixed(int *lpBytesXfered = dwBytes)
                {
                    return(PInvoke.DeviceIoControl(_hDevice, CyConst.IOCTL_ADAPT_ABORT_PIPE,
                                                   (IntPtr)lpInBuffer, 1, (IntPtr)null, 0,
                                                   (IntPtr)lpBytesXfered, (IntPtr)null));
                }
            }
        }
Пример #2
0
        public unsafe override bool BeginDataXfer(ref byte[] singleXfer, ref byte[] buffer, ref int len, ref byte[] ov)
        {
            if (_hDevice == CyConst.INVALID_HANDLE)
            {
                return(false);
            }

            int pktBlockSize = GetPktBlockSize(len);
            int cmdLen       = singleXfer.Length;

            fixed(byte *buf = singleXfer)
            {
                SINGLE_TRANSFER *transfer = (SINGLE_TRANSFER *)buf;

                transfer->WaitForever       = 0;
                transfer->ucEndpointAddress = Address;
                transfer->IsoPacketOffset   = CyConst.SINGLE_XFER_LEN;
                transfer->IsoPacketLength   = (uint)pktBlockSize;

                int[] Xferred = new int[1];
                Xferred[0] = 0;

                uint IOCTL;

                if (XferMode == XMODE.BUFFERED)
                {
                    transfer->BufferOffset = (uint)(CyConst.SINGLE_XFER_LEN + pktBlockSize);
                    transfer->BufferLength = (uint)len;

                    IOCTL = CyConst.IOCTL_ADAPT_SEND_NON_EP0_TRANSFER;

                    for (int i = 0; i < len; i++)
                        buf[CyConst.SINGLE_XFER_LEN + pktBlockSize + i] = buffer[i];

                    fixed(byte *lpInBuffer = singleXfer)
                    {
                        fixed(byte *lpOutBuffer = singleXfer)
                        {
                            fixed(byte *lpOv = ov)
                            {
                                fixed(int *lpBytesXfered = Xferred)
                                {
                                    PInvoke.DeviceIoControl(_hDevice, IOCTL,
                                                            (IntPtr)lpInBuffer, cmdLen, (IntPtr)lpOutBuffer, cmdLen,
                                                            (IntPtr)lpBytesXfered, (IntPtr)lpOv);
                                }
                            }
                        }
                    }
                }
                else
                {
                    transfer->BufferOffset = 0;
                    transfer->BufferLength = 0;

                    IOCTL = CyConst.IOCTL_ADAPT_SEND_NON_EP0_DIRECT;

                    fixed(byte *lpInBuffer = singleXfer)
                    {
                        fixed(byte *lpOutBuffer = buffer)
                        {
                            fixed(byte *lpOv = ov)
                            {
                                fixed(int *lpBytesXfered = Xferred)
                                {
                                    PInvoke.DeviceIoControl(_hDevice, IOCTL,
                                                            (IntPtr)lpInBuffer, cmdLen, (IntPtr)lpOutBuffer, len,
                                                            (IntPtr)lpBytesXfered, (IntPtr)lpOv);
                                }
                            }
                        }
                    }
                }

                if (Xferred[0] > 0)
                {
                    len = Xferred[0];
                }

                _usbdStatus = transfer->UsbdStatus;
                _ntStatus   = transfer->NtStatus;
            }

            _lastError = (uint)Marshal.GetLastWin32Error();

            return(true);
        }
Пример #3
0
        // Control Endpoints don't support the Begin/Wait/Finish advanced technique from the
        // app level.  So, these methods are declared private.
        unsafe bool BeginDataXfer(ref byte[] buffer, ref Int32 len, ref byte[] ov)
        {
            bool bRetVal = false;

            if (_hDevice == CyConst.INVALID_HANDLE)
            {
                return(false);
            }

            uint tmo = ((TimeOut > 0) && (TimeOut < 1000)) ? 1 : TimeOut / 1000;

            _bIn = (Direction == CyConst.DIR_FROM_DEVICE);

            int bufSz = len + CyConst.SINGLE_XFER_LEN;

            fixed(byte *buf = buffer)
            {
                SINGLE_TRANSFER *transfer = (SINGLE_TRANSFER *)buf;

                transfer->SetupPacket.bmRequest = (byte)(Target | ReqType | Direction);
                transfer->SetupPacket.bRequest  = ReqCode;
                transfer->SetupPacket.wValue    = Value;
                transfer->SetupPacket.wLength   = (ushort)len;
                transfer->SetupPacket.wIndex    = Index;
                transfer->SetupPacket.dwTimeOut = tmo;
                transfer->WaitForever           = 0;
                transfer->ucEndpointAddress     = 0x00;                    // control pipe
                transfer->IsoPacketLength       = 0;
                transfer->BufferOffset          = CyConst.SINGLE_XFER_LEN; // size of the SINGLE_TRANSFER part
                transfer->BufferLength          = (uint)len;

                int[] Xferred = new int[1];
                Xferred[0] = 0;

                fixed(byte *lpInBuffer = buffer)
                {
                    fixed(byte *lpOutBuffer = buffer)
                    {
                        fixed(byte *lpOv = ov)
                        {
                            fixed(int *lpBytesXfered = Xferred)
                            {
                                bRetVal = PInvoke.DeviceIoControl(_hDevice,
                                                                  CyConst.IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER,
                                                                  (IntPtr)lpInBuffer, bufSz, (IntPtr)lpOutBuffer, bufSz,
                                                                  (IntPtr)lpBytesXfered, (IntPtr)lpOv);
                            }
                        }
                    }
                }

                len = Xferred[0];

                _usbdStatus = transfer->UsbdStatus;
                _ntStatus   = transfer->NtStatus;
            }

            _lastError = (uint)Marshal.GetLastWin32Error();

            return(bRetVal);
        }
Пример #4
0
        private unsafe bool SendScsiCmd32(byte cmd, byte op, byte lun, byte dirIn, int bank, int lba, int bytes, byte[] data)
        {
            SCSI_PASS_THROUGH_WITH_BUFFERS32 sptB = new SCSI_PASS_THROUGH_WITH_BUFFERS32();
            int len = Marshal.SizeOf(sptB) + bytes;             // total size of buffer

            byte[] buffer = new byte[len];


            fixed(byte *buf = buffer)
            {
                SCSI_PASS_THROUGH_WITH_BUFFERS32 *sptBuf = (SCSI_PASS_THROUGH_WITH_BUFFERS32 *)buf;
                SCSI_PASS_THROUGH32 *spt = (SCSI_PASS_THROUGH32 *)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);
            }
        }
Пример #5
0
        // Control endpoint uses the BUFFERED xfer method.  So that it
        // doesn't collide with the base class' XferData, we declare it 'new'
        public new unsafe bool XferData(ref byte[] buf, ref int len)
        {
            byte[] ovLap = new byte[sizeof(OVERLAPPED)];

            fixed(byte *tmp0 = ovLap)
            {
                OVERLAPPED *ovLapStatus = (OVERLAPPED *)tmp0;

                ovLapStatus->hEvent = PInvoke.CreateEvent(0, 0, 0, 0);

                bool bResult, wResult, fResult;

                // Create a temporary buffer that will contain a SINGLE_TRANSFER structure
                // followed by the actual data.
                byte[] tmpBuf = new byte[CyConst.SINGLE_XFER_LEN + len];
                for (int i = 0; i < len; i++)
                {
                    tmpBuf[CyConst.SINGLE_XFER_LEN + i] = buf[i];

                    fixed(byte *tmp1 = tmpBuf)
                    {
                        bResult = BeginDataXfer(ref tmpBuf, ref len, ref ovLap);
                        wResult = WaitForIO(ovLapStatus->hEvent);
                        fResult = FinishDataXfer(ref buf, ref tmpBuf, ref len, ref ovLap);
                    }

                    PInvoke.CloseHandle(ovLapStatus->hEvent);

                    return(wResult && fResult);
            }
        }

        // Control Endpoints don't support the Begin/Wait/Finish advanced technique from the
        // app level.  So, these methods are declared private.
        unsafe bool BeginDataXfer(ref byte[] buffer, ref Int32 len, ref byte[] ov)
        {
            bool bRetVal = false;

            if (_hDevice == CyConst.INVALID_HANDLE)
            {
                return(false);
            }

            uint tmo = ((TimeOut > 0) && (TimeOut < 1000)) ? 1 : TimeOut / 1000;

            _bIn = (Direction == CyConst.DIR_FROM_DEVICE);

            int bufSz = len + CyConst.SINGLE_XFER_LEN;

            fixed(byte *buf = buffer)
            {
                SINGLE_TRANSFER *transfer = (SINGLE_TRANSFER *)buf;

                transfer->SetupPacket.bmRequest = (byte)(Target | ReqType | Direction);
                transfer->SetupPacket.bRequest  = ReqCode;
                transfer->SetupPacket.wValue    = Value;
                transfer->SetupPacket.wLength   = (ushort)len;
                transfer->SetupPacket.wIndex    = Index;
                transfer->SetupPacket.dwTimeOut = tmo;
                transfer->WaitForever           = 0;
                transfer->ucEndpointAddress     = 0x00;                    // control pipe
                transfer->IsoPacketLength       = 0;
                transfer->BufferOffset          = CyConst.SINGLE_XFER_LEN; // size of the SINGLE_TRANSFER part
                transfer->BufferLength          = (uint)len;

                int[] Xferred = new int[1];
                Xferred[0] = 0;

                fixed(byte *lpInBuffer = buffer)
                {
                    fixed(byte *lpOutBuffer = buffer)
                    {
                        fixed(byte *lpOv = ov)
                        {
                            fixed(int *lpBytesXfered = Xferred)
                            {
                                bRetVal = PInvoke.DeviceIoControl(_hDevice,
                                                                  CyConst.IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER,
                                                                  (IntPtr)lpInBuffer, bufSz, (IntPtr)lpOutBuffer, bufSz,
                                                                  (IntPtr)lpBytesXfered, (IntPtr)lpOv);
                            }
                        }
                    }
                }

                len = Xferred[0];

                _usbdStatus = transfer->UsbdStatus;
                _ntStatus   = transfer->NtStatus;
            }

            _lastError = (uint)Marshal.GetLastWin32Error();

            return(bRetVal);
        }

        // This is a BUFFERED xfer method - specific version of FinishDataXfer.  So that it
        // doesn't collide with the base class' FinishDataXfer, we declare it 'new'
        new unsafe bool FinishDataXfer(ref byte[] userBuf, ref byte[] xferBuf, ref int len, ref byte[] ov)
        {
            uint bytes   = 0;
            bool rResult = PInvoke.GetOverlappedResult(_hDevice, ov, ref bytes, 0);

            uint dataOffset;

            fixed(byte *buf = xferBuf)
            {
                SINGLE_TRANSFER *transfer = (SINGLE_TRANSFER *)buf;

                len           = (bytes > CyConst.SINGLE_XFER_LEN) ? (int)bytes - (int)transfer->BufferOffset : 0;
                _bytesWritten = (uint)len;

                dataOffset  = transfer->BufferOffset;
                _usbdStatus = transfer->UsbdStatus;
                _ntStatus   = transfer->NtStatus;
            }

            // Extract the acquired data and move from xferBuf to userBuf
            if (bIn)
            {
                for (int i = 0; i < len; i++)
                    userBuf[i] = xferBuf[dataOffset + i]; }
            }

            return(rResult && (_usbdStatus == 0) && (_ntStatus == 0));
        }
    }