Ejemplo n.º 1
0
        // 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));
        }
Ejemplo n.º 2
0
        public unsafe virtual bool FinishDataXfer(ref byte[] singleXfer, ref byte[] buffer, ref int len, ref byte[] ov)
        {
            bool rResult;

            uint[] bytes = new uint[1];

            // DWY fix single variable during call by converting it into an 'array of 1'
            //  and fixing it to a pointer.
            fixed(uint *buf0 = bytes)
            {
                fixed(byte *buf = singleXfer)
                {
                    SINGLE_TRANSFER *transfer = (SINGLE_TRANSFER *)buf;

                    rResult = PInvoke.GetOverlappedResult(_hDevice, ov, ref bytes[0], 0);
                    if (rResult == false)
                    {
                        transfer->NtStatus = PInvoke.GetLastError();
                    }
                }
            }

            len = (int)bytes[0];

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

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

                if ((XferMode == XMODE.BUFFERED) && (len > 0))
                {
                    //len -= (int)transfer->BufferOffset; This is not required becuse we pass the actual data buffer length
                    for (int i = 0; i < len; i++)
                    {
                        buffer[i] = buf[transfer->BufferOffset + i];
                    }
                }
            }

            _bytesWritten = (uint)len;

            return(rResult && (_usbdStatus == 0) && (_ntStatus == 0));
        }
Ejemplo n.º 3
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));
        }
    }