// 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)); }
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)); }
// This FinishDataXfer is only called by the second XferData method of CyIsocEndPoint // This called when ISO_PKT_INFO data is requested public unsafe virtual bool FinishDataXfer(ref byte[] singleXfer, ref byte[] buffer, ref int len, ref byte[] ov, ref ISO_PKT_INFO[] pktInfo) { // Call the base class' FinishDataXfer to do most of the work bool rResult = FinishDataXfer(ref singleXfer, ref buffer, ref len, ref ov); // Pass-back the Isoc packet info records if (len > 0) { fixed(byte *buf = singleXfer) { SINGLE_TRANSFER *transfer = (SINGLE_TRANSFER *)buf; ISO_PKT_INFO * packets = (ISO_PKT_INFO *)(buf + transfer->IsoPacketOffset); int pktCnt = (int)transfer->IsoPacketLength / Marshal.SizeOf(*packets); for (int i = 0; i < pktCnt; i++) pktInfo[i] = packets[i]; } } }
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); }
// 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); }
// 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)); } }