예제 #1
0
        // Call this one if you want the PacketInfo data passed-back
        public unsafe bool XferData(ref byte[] buf, ref int len, ref ISO_PKT_INFO[] pktInfos)
        {
            byte[] ovLap = new byte[OverlapSignalAllocSize];

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

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

                // This SINGLE_TRANSFER buffer must be allocated at this level.
                int bufSz = CyConst.SINGLE_XFER_LEN + GetPktBlockSize(len) + ((XferMode == XMODE.DIRECT) ? 0 : len);

                byte[] cmdBuf = new byte[bufSz];

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

                    PInvoke.CloseHandle(ovLapStatus->hEvent);

                    return(wResult && fResult);
                }
            }
        }
예제 #2
0
        // These used by both BULK and INTERRUPT endpoints
        public unsafe virtual bool XferData(ref byte[] buf, ref int len)
        {
            byte[] ovLap = new byte[OverlapSignalAllocSize];

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

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

                // This SINGLE_TRANSFER buffer must be allocated at this level.
                int bufSz = CyConst.SINGLE_XFER_LEN + ((XferMode == XMODE.DIRECT) ? 0 : len);

                byte[] cmdBuf = new byte[bufSz];

                // These nested fixed blocks ensure that the buffers don't move in memory
                // While we're doing the asynchronous IO - Begin/Wait/Finish
                fixed(byte *tmp1 = cmdBuf, tmp2 = buf)
                {
                    bool bResult = BeginDataXfer(ref cmdBuf, ref buf, ref len, ref ovLap);
                    //
                    //  This waits for driver to call IoRequestComplete on the IRP
                    //  we just sent.
                    //
                    bool wResult = WaitForIO(ovLapStatus->hEvent);
                    bool fResult = FinishDataXfer(ref cmdBuf, ref buf, ref len, ref ovLap);

                    PInvoke.CloseHandle(ovLapStatus->hEvent);

                    return(wResult && fResult);
                }
            }
        }
예제 #3
0
        internal void Close()
        {
            if (_alreadyDisposed)
            {
                throw new ObjectDisposedException("");
            }

            if (_hDevice != CyConst.INVALID_HANDLE)
            {
                PInvoke.CloseHandle(_hDevice);
            }
            _hDevice = CyConst.INVALID_HANDLE;

            if (_hHndNotification != IntPtr.Zero)
            {
                PInvoke.UnregisterDeviceNotification(_hHndNotification);
            }
        }
예제 #4
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];
                }

                GCHandle bufSingleTransfer = GCHandle.Alloc(tmpBuf, GCHandleType.Pinned);
                GCHandle bufDataAllocation = GCHandle.Alloc(buf, GCHandleType.Pinned);

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

                PInvoke.CloseHandle(ovLapStatus->hEvent);
                bufSingleTransfer.Free();
                bufDataAllocation.Free();

                return(wResult && fResult);
            }
        }
예제 #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));
        }
    }