static int usbdk_do_bulk_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct winfd wfd; TransferResult transferRes; HANDLE sysHandle; transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; transfer_priv->request.BufferLength = transfer->length; transfer_priv->request.EndpointAddress = transfer->endpoint; switch (transfer->type) { case LIBUSB_TRANSFER_TYPE_BULK: transfer_priv->request.TransferType = BulkTransferType; break; case LIBUSB_TRANSFER_TYPE_INTERRUPT: transfer_priv->request.TransferType = IntertuptTransferType; break; default: usbi_err(ctx, "Wrong transfer type (%d) in usbdk_do_bulk_transfer. %s", transfer->type, windows_error_str(0)); return LIBUSB_ERROR_INVALID_PARAM; } transfer_priv->pollable_fd = INVALID_WINFD; sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); wfd = usbi_create_fd(sysHandle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL); // Always use the handle returned from usbi_create_fd (wfd.handle) if (wfd.fd < 0) return LIBUSB_ERROR_NO_MEM; if (IS_XFERIN(transfer)) transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); else transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); switch (transferRes) { case TransferSuccess: wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; break; case TransferSuccessAsync: break; case TransferFailure: usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); usbi_free_fd(&wfd); return LIBUSB_ERROR_IO; } transfer_priv->pollable_fd = wfd; usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, IS_XFERIN(transfer) ? POLLIN : POLLOUT); return LIBUSB_SUCCESS; }
static void wince_clear_transfer_priv(struct usbi_transfer *itransfer) { struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd); // No need to cancel transfer as it is either complete or abandoned wfd.itransfer = NULL; CloseHandle(wfd.handle); usbi_free_fd(&transfer_priv->pollable_fd); }
void windows_clear_transfer_priv(struct usbi_transfer *itransfer) { struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); usbi_free_fd(&transfer_priv->pollable_fd); if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { safe_free(transfer_priv->IsochronousPacketsArray); safe_free(transfer_priv->IsochronousResultsArray); } }
static int usbdk_do_control_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct winfd wfd; ULONG Length; TransferResult transResult; HANDLE sysHandle; sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); wfd = usbi_create_fd(sysHandle, RW_READ, NULL, NULL); // Always use the handle returned from usbi_create_fd (wfd.handle) if (wfd.fd < 0) return LIBUSB_ERROR_NO_MEM; transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; transfer_priv->request.BufferLength = transfer->length; transfer_priv->request.TransferType = ControlTransferType; transfer_priv->pollable_fd = INVALID_WINFD; Length = (ULONG)transfer->length; if (IS_XFERIN(transfer)) transResult = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); else transResult = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); switch (transResult) { case TransferSuccess: wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; wfd.overlapped->InternalHigh = (DWORD)Length; break; case TransferSuccessAsync: break; case TransferFailure: usbi_err(ctx, "ControlTransfer failed: %s", windows_error_str(0)); usbi_free_fd(&wfd); return LIBUSB_ERROR_IO; } // Use priv_transfer to store data needed for async polling transfer_priv->pollable_fd = wfd; usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN); return LIBUSB_SUCCESS; }
static int usbdk_do_iso_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct winfd wfd; TransferResult transferRes; int i; HANDLE sysHandle; transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; transfer_priv->request.BufferLength = transfer->length; transfer_priv->request.EndpointAddress = transfer->endpoint; transfer_priv->request.TransferType = IsochronousTransferType; transfer_priv->request.IsochronousPacketsArraySize = transfer->num_iso_packets; transfer_priv->IsochronousPacketsArray = malloc(transfer->num_iso_packets * sizeof(ULONG64)); transfer_priv->request.IsochronousPacketsArray = (PVOID64)(uintptr_t)transfer_priv->IsochronousPacketsArray; if (!transfer_priv->IsochronousPacketsArray) { usbi_err(ctx, "Allocation of IsochronousPacketsArray is failed, %s", windows_error_str(0)); return LIBUSB_ERROR_IO; } transfer_priv->IsochronousResultsArray = malloc(transfer->num_iso_packets * sizeof(USB_DK_ISO_TRANSFER_RESULT)); transfer_priv->request.Result.IsochronousResultsArray = (PVOID64)(uintptr_t)transfer_priv->IsochronousResultsArray; if (!transfer_priv->IsochronousResultsArray) { usbi_err(ctx, "Allocation of isochronousResultsArray is failed, %s", windows_error_str(0)); free(transfer_priv->IsochronousPacketsArray); return LIBUSB_ERROR_IO; } for (i = 0; i < transfer->num_iso_packets; i++) transfer_priv->IsochronousPacketsArray[i] = transfer->iso_packet_desc[i].length; transfer_priv->pollable_fd = INVALID_WINFD; sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); wfd = usbi_create_fd(sysHandle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL); // Always use the handle returned from usbi_create_fd (wfd.handle) if (wfd.fd < 0) { free(transfer_priv->IsochronousPacketsArray); free(transfer_priv->IsochronousResultsArray); return LIBUSB_ERROR_NO_MEM; } if (IS_XFERIN(transfer)) transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); else transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); switch (transferRes) { case TransferSuccess: wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; break; case TransferSuccessAsync: break; case TransferFailure: usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); usbi_free_fd(&wfd); free(transfer_priv->IsochronousPacketsArray); free(transfer_priv->IsochronousResultsArray); return LIBUSB_ERROR_IO; } transfer_priv->pollable_fd = wfd; usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, IS_XFERIN(transfer) ? POLLIN : POLLOUT); return LIBUSB_SUCCESS; }