int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev, unsigned char endpoint) { struct libusb_config_descriptor *config; const struct libusb_endpoint_descriptor *ep; enum libusb_transfer_type ep_type; uint16_t val; int r; r = libusb_get_active_config_descriptor(dev, &config); if (r < 0) { usbi_err(DEVICE_CTX(dev), "could not retrieve active config descriptor"); return LIBUSB_ERROR_OTHER; } ep = find_endpoint(config, endpoint); if (!ep) return LIBUSB_ERROR_NOT_FOUND; val = ep->wMaxPacketSize; ep_type = ep->bmAttributes & 0x3; libusb_free_config_descriptor(config); r = val & 0x07ff; if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS || ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT) r *= (1 + ((val >> 11) & 3)); return r; }
static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) { struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); *host_endian = 0; return priv->backend->get_config_descriptor(dev, config_index, buffer, len); }
static int windows_get_config_descriptor_by_value(struct libusb_device *dev, uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian) { struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); *host_endian = 0; return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer); }
static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) { struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); *host_endian = 0; return priv->backend->get_device_descriptor(dev, buffer); }
static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); BOOL direction_in, ret; struct winfd wfd; DWORD flags; HANDLE eventHandle; PUKW_CONTROL_HEADER setup = NULL; const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL; transfer_priv->pollable_fd = INVALID_WINFD; if (control_transfer) { setup = (PUKW_CONTROL_HEADER) transfer->buffer; direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN; } else { direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN; } flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER; flags |= UKW_TF_SHORT_TRANSFER_OK; eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); if (eventHandle == NULL) { usbi_err(ctx, "Failed to create event for async transfer"); return LIBUSB_ERROR_NO_MEM; } wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer); if (wfd.fd < 0) { CloseHandle(eventHandle); return LIBUSB_ERROR_NO_MEM; } transfer_priv->pollable_fd = wfd; if (control_transfer) { // Split out control setup header and data buffer DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER); PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)]; ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped); } else { ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer, transfer->length, &transfer->actual_length, wfd.overlapped); } if (!ret) { int libusbErr = translate_driver_error(GetLastError()); usbi_err(ctx, "UkwIssue%sTransfer failed: error %d", control_transfer ? "Control" : "Bulk", GetLastError()); wince_clear_transfer_priv(itransfer); return libusbErr; } usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT); itransfer->flags |= USBI_TRANSFER_UPDATED_FDS; return LIBUSB_SUCCESS; }
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 usbdk_close(struct libusb_device_handle *dev_handle) { struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); if (!usbdk_helper.StopRedirect(priv->redirector_handle)) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); usbi_err(ctx, "Redirector shutdown failed"); } }
static int usbdk_reset_device(struct libusb_device_handle *dev_handle) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); if (!usbdk_helper.ResetDevice(priv->redirector_handle)) { usbi_err(ctx, "ResetDevice failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NO_DEVICE; } return LIBUSB_SUCCESS; }
static int usbdk_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); if (!usbdk_helper.ResetPipe(priv->redirector_handle, endpoint)) { usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NO_DEVICE; } return LIBUSB_SUCCESS; }
static int usbdk_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); if (!usbdk_helper.SetAltsetting(priv->redirector_handle, iface, altsetting)) { usbi_err(ctx, "SetAltsetting failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NO_DEVICE; } return LIBUSB_SUCCESS; }
static int usbdk_open(struct libusb_device_handle *dev_handle) { struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); priv->redirector_handle = usbdk_helper.StartRedirect(&priv->info.ID); if (priv->redirector_handle == INVALID_HANDLE_VALUE) { usbi_err(DEVICE_CTX(dev_handle->dev), "Redirector startup failed"); return LIBUSB_ERROR_OTHER; } return LIBUSB_SUCCESS; }
static int usbdk_abort_transfers(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); if (!usbdk_helper.AbortPipe(priv->redirector_handle, transfer->endpoint)) { usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NO_DEVICE; } return LIBUSB_SUCCESS; }
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 haiku_get_config_descriptor(struct libusb_device *device, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) { USBDevice *dev = *((USBDevice**)(device->os_priv)); const usb_configuration_descriptor* config = dev->ConfigurationDescriptor(config_index); if(config==NULL) { usbi_err(DEVICE_CTX(device),"failed getting configuration descriptor"); return LIBUSB_ERROR_INVALID_PARAM; } if(len>config->total_length) len=config->total_length; memcpy(buffer,(unsigned char*)config,len); *host_endian=0; return len; }
int usbi_sanitize_device(struct libusb_device *dev) { int r; uint8_t num_configurations; r = usbi_device_cache_descriptor(dev); if (r < 0) return r; num_configurations = dev->device_descriptor.bNumConfigurations; if (num_configurations > USB_MAXCONFIG) { usbi_err(DEVICE_CTX(dev), "too many configurations"); return LIBUSB_ERROR_IO; } else if (0 == num_configurations) usbi_dbg("zero configurations, maybe an unauthorized device"); dev->num_configurations = num_configurations; return 0; }
int API_EXPORTED libusb_open(libusb_device *dev, libusb_device_handle **handle) { struct libusb_context *ctx = DEVICE_CTX(dev); struct libusb_device_handle *_handle; size_t priv_size = usbi_backend->device_handle_priv_size; int r; usbi_dbg("open %d.%d", dev->bus_number, dev->device_address); _handle = malloc(sizeof(*_handle) + priv_size); if (!_handle) return LIBUSB_ERROR_NO_MEM; r = usbi_mutex_init(&_handle->lock, NULL); if (r) { free(_handle); return LIBUSB_ERROR_OTHER; } _handle->dev = libusb_ref_device(dev); _handle->claimed_interfaces = 0; memset(&_handle->os_priv, 0, priv_size); r = usbi_backend->open(_handle); if (r < 0) { usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r); libusb_unref_device(dev); usbi_mutex_destroy(&_handle->lock); free(_handle); return r; } usbi_mutex_lock(&ctx->open_devs_lock); list_add(&_handle->list, &ctx->open_devs); usbi_mutex_unlock(&ctx->open_devs_lock); *handle = _handle; usbi_fd_notification(ctx); return 0; }
int usbi_sanitize_device(struct libusb_device *dev) { int r; unsigned char raw_desc[DEVICE_DESC_LENGTH]; uint8_t num_configurations; int host_endian; r = usbi_backend->get_device_descriptor(dev, raw_desc, &host_endian); if (r < 0) return r; num_configurations = raw_desc[DEVICE_DESC_LENGTH - 1]; if (num_configurations > USB_MAXCONFIG) { usbi_err(DEVICE_CTX(dev), "too many configurations"); return LIBUSB_ERROR_IO; } else if (0 == num_configurations) usbi_dbg("zero configurations, maybe an unauthorized device"); dev->num_configurations = num_configurations; return 0; }
void usbi_connect_device(struct libusb_device *dev) { libusb_hotplug_message message; ssize_t ret; memset(&message, 0, sizeof(message)); message.event = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED; message.device = dev; dev->attached = 1; usbi_mutex_lock(&dev->ctx->usb_devs_lock); list_add(&dev->list, &dev->ctx->usb_devs); usbi_mutex_unlock(&dev->ctx->usb_devs_lock); if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_pipe[1] > 0) { ret = usbi_write(dev->ctx->hotplug_pipe[1], &message, sizeof(message)); if (sizeof (message) != ret) { usbi_err(DEVICE_CTX(dev), "error writing hotplug message"); } } }
int API_EXPORTED libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint) { struct libusb_config_descriptor *config; const struct libusb_endpoint_descriptor *ep; int r; r = libusb_get_active_config_descriptor(dev, &config); if (r < 0) { usbi_err(DEVICE_CTX(dev), "could not retrieve active config descriptor"); return LIBUSB_ERROR_OTHER; } ep = find_endpoint(config, endpoint); if (!ep) return LIBUSB_ERROR_NOT_FOUND; r = ep->wMaxPacketSize; libusb_free_config_descriptor(config); return r; }
static void windows_destroy_device(struct libusb_device *dev) { struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); priv->backend->destroy_device(dev); }
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; }