private unsafe void PipeIOCallback(uint errorCode, uint numBytes, NativeOverlapped *pOverlapped) { try { Exception error = null; if (errorCode != 0) { error = APIException.Win32("Asynchronous operation on WinUSB device failed.", (int)errorCode); } Overlapped overlapped = Overlapped.Unpack(pOverlapped); USBAsyncResult result = (USBAsyncResult)overlapped.AsyncResult; Overlapped.Free(pOverlapped); pOverlapped = null; result.OnCompletion(false, error, (int)numBytes, true); } finally { if (pOverlapped != null) { Overlapped.Unpack(pOverlapped); Overlapped.Free(pOverlapped); } } }
internal void WaitForCompletion() { if (asyncResult == null) { throw new ScopeIOException("Can't wait for command's completion before executing command"); } try { if (endPoint.IsOut) { endPoint.EndWrite(asyncResult); } else if (endPoint.IsIn) { endPoint.EndRead(asyncResult); } else { throw new ScopeIOException("Unknown endpoint type"); } } catch (Exception e) { throw new ScopeIOException("USB Error occurred: " + e.Message); } USBAsyncResult usbresult = (USBAsyncResult)asyncResult; if (usbresult.Error != null) { throw new ScopeIOException("USB Error occurred: " + usbresult.Error.Message); } if (usbresult.BytesTransfered != length) { throw new ScopeIOException(String.Format("Only transferred {0:d} out of {1:d} bytes", usbresult.BytesTransfered, length)); } }
public void ControlTransferOverlapped(byte requestType, byte request, ushort value, ushort index, ushort length, byte[] data, USBAsyncResult result) { uint bytesReturned = 0; WINUSB_SETUP_PACKET setupPacket; setupPacket.RequestType = requestType; setupPacket.Request = request; setupPacket.Value = value; setupPacket.Index = index; setupPacket.Length = length; Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = result; unsafe { NativeOverlapped *pOverlapped = null; pOverlapped = overlapped.Pack(PipeIOCallback, data); bool success = WinUsb_ControlTransfer(_winUsbHandle, setupPacket, data, length, ref bytesReturned, pOverlapped); HandleOverlappedAPI(success, "Asynchronous control transfer on WinUSB device failed.", pOverlapped, result, (int)bytesReturned); } }
public void WriteOverlapped(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToWrite, USBAsyncResult result) { Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = result; unsafe { NativeOverlapped *pOverlapped = null; uint bytesWritten; pOverlapped = overlapped.Pack(PipeIOCallback, buffer); bool success; // Buffer is pinned already by overlapped.Pack fixed(byte *pBuffer = buffer) { success = WinUsb_WritePipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)bytesToWrite, out bytesWritten, pOverlapped); } HandleOverlappedAPI(success, "Failed to asynchronously write pipe on WinUSB device.", pOverlapped, result, (int)bytesWritten); } }
private unsafe void HandleOverlappedAPI(bool success, string errorMessage, NativeOverlapped *pOverlapped, USBAsyncResult result, int bytesTransfered) { if (!success) { if (Marshal.GetLastWin32Error() != FileIO.ERROR_IO_PENDING) { Overlapped.Unpack(pOverlapped); Overlapped.Free(pOverlapped); throw APIException.Win32(errorMessage); } } else { // Immediate success! Overlapped.Unpack(pOverlapped); Overlapped.Free(pOverlapped); result.OnCompletion(true, null, bytesTransfered, false); // is the callback still called in this case?? todo } }
public void ControlTransferOverlapped(byte requestType, byte request, ushort value, ushort index, ushort length, byte[] data, USBAsyncResult result) { uint bytesReturned = 0; WINUSB_SETUP_PACKET setupPacket; setupPacket.RequestType = requestType; setupPacket.Request = request; setupPacket.Value = value; setupPacket.Index = index; setupPacket.Length = length; Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = result; unsafe { NativeOverlapped* pOverlapped = null; pOverlapped = overlapped.Pack(PipeIOCallback, data); bool success = WinUsb_ControlTransfer(_winUsbHandle, setupPacket, data, length, ref bytesReturned, pOverlapped); HandleOverlappedAPI(success, "Asynchronous control transfer on WinUSB device failed.", pOverlapped, result, (int)bytesReturned); } }
private unsafe void HandleOverlappedAPI(bool success, string errorMessage, NativeOverlapped* pOverlapped, USBAsyncResult result, int bytesTransfered) { if (!success) { if (Marshal.GetLastWin32Error() != FileIO.ERROR_IO_PENDING) { Overlapped.Unpack(pOverlapped); Overlapped.Free(pOverlapped); throw APIException.Win32(errorMessage); } } else { // Immediate success! Overlapped.Unpack(pOverlapped); Overlapped.Free(pOverlapped); result.OnCompletion(true, null, bytesTransfered, false); // is the callback still called in this case?? todo } }
public void WriteOverlapped(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToWrite, USBAsyncResult result) { Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = result; unsafe { NativeOverlapped* pOverlapped = null; uint bytesWritten; pOverlapped = overlapped.Pack(PipeIOCallback, buffer); bool success; // Buffer is pinned already by overlapped.Pack fixed (byte* pBuffer = buffer) { success = WinUsb_WritePipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)bytesToWrite, out bytesWritten, pOverlapped); } HandleOverlappedAPI(success, "Failed to asynchronously write pipe on WinUSB device.", pOverlapped, result, (int)bytesWritten); } }