diff options
author | Pete Batard <pbatard@gmail.com> | 2011-02-22 13:57:59 +0000 |
---|---|---|
committer | Pete Batard <pbatard@gmail.com> | 2011-02-22 13:57:59 +0000 |
commit | fcfe54ebbf4c5dae88ab7111301466d239f1e36b (patch) | |
tree | 14a2b9a9d3f75efc6717babc2c1a12d20ae4e98b | |
parent | da53dc50f539ba5210af75134bf4756ef85b7f12 (diff) | |
download | libusb-fcfe54ebbf4c5dae88ab7111301466d239f1e36b.tar.gz |
added LibUSBwK support
-rw-r--r-- | libusb/os/windows_usb.c | 306 | ||||
-rw-r--r-- | libusb/os/windows_usb.h | 27 |
2 files changed, 288 insertions, 45 deletions
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index b51dad0..0533095 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -66,15 +66,18 @@ extern void usbi_fd_notification(struct libusb_context *ctx); static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian); static int windows_clock_gettime(int clk_id, struct timespec *tp); unsigned __stdcall windows_clock_gettime_threaded(void* param); +// Common calls +static int common_configure_endpoints(struct libusb_device_handle *dev_handle, int iface); // HUB (limited) API prototypes static int hub_open(struct libusb_device_handle *dev_handle); static void hub_close(struct libusb_device_handle *dev_handle); -// WinUSB API prototypes +// WinUSB, libusbwK API prototypes static int winusb_init(struct libusb_context *ctx); static int winusb_exit(void); static int winusb_open(struct libusb_device_handle *dev_handle); static void winusb_close(struct libusb_device_handle *dev_handle); static int winusb_configure_endpoints(struct libusb_device_handle *dev_handle, int iface); +static int winusb_configure_endpoints(struct libusb_device_handle *dev_handle, int iface); static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int iface); static int winusb_release_interface(struct libusb_device_handle *dev_handle, int iface); static int winusb_submit_control_transfer(struct usbi_transfer *itransfer); @@ -85,6 +88,23 @@ static int winusb_abort_transfers(struct usbi_transfer *itransfer); static int winusb_abort_control(struct usbi_transfer *itransfer); static int winusb_reset_device(struct libusb_device_handle *dev_handle); static int winusb_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size); +static int libusbk_init(struct libusb_context *ctx); +static int libusbk_exit(void); +static int libusbk_open(struct libusb_device_handle *dev_handle); +static void libusbk_close(struct libusb_device_handle *dev_handle); +static int libusbk_configure_endpoints(struct libusb_device_handle *dev_handle, int iface); +static int libusbk_configure_endpoints(struct libusb_device_handle *dev_handle, int iface); +static int libusbk_claim_interface(struct libusb_device_handle *dev_handle, int iface); +static int libusbk_release_interface(struct libusb_device_handle *dev_handle, int iface); +static int libusbk_submit_control_transfer(struct usbi_transfer *itransfer); +static int libusbk_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting); +static int libusbk_submit_bulk_transfer(struct usbi_transfer *itransfer); +static int libusbk_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint); +static int libusbk_abort_transfers(struct usbi_transfer *itransfer); +static int libusbk_abort_control(struct usbi_transfer *itransfer); +static int libusbk_reset_device(struct libusb_device_handle *dev_handle); +static int libusbk_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size); + // HID API prototypes static int hid_init(struct libusb_context *ctx); static int hid_exit(void); @@ -162,7 +182,9 @@ HANDLE timer_request[2] = { NULL, NULL }; HANDLE timer_response = NULL; // API globals bool api_winusb_available = false; -#define CHECK_WINUSB_AVAILABLE do { if (!api_winusb_available) return LIBUSB_ERROR_ACCESS; } while (0) +bool api_libusbk_available = false; +#define CHECK_WINUSB_AVAILABLE do { if ( ((!k) && (!api_winusb_available)) || ((k) && (!api_libusbk_available)) ) \ + return LIBUSB_ERROR_ACCESS; } while (0) bool api_hid_available = false; #define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0) @@ -641,12 +663,8 @@ static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int } libusb_free_config_descriptor(conf_desc); - // Extra init is required for WinUSB endpoints - if (priv->apib->id == USB_API_WINUSB) { - return winusb_configure_endpoints(dev_handle, iface); - } - - return LIBUSB_SUCCESS; + // Extra init may be required to configure endpoints + return priv->apib->configure_endpoints(dev_handle, iface); } // Lookup for a match in the list of API driver names @@ -690,6 +708,7 @@ static int auto_claim(struct libusb_transfer *transfer, int *interface_number, i switch(api_type) { case USB_API_WINUSB: + case USB_API_LIBUSBK: case USB_API_HID: break; default: @@ -2272,6 +2291,9 @@ static int unsupported_open(struct libusb_device_handle *dev_handle) { static void unsupported_close(struct libusb_device_handle *dev_handle) { usbi_dbg("unsupported API call for 'close'"); } +static int unsupported_configure_endpoints(struct libusb_device_handle *dev_handle, int iface) { + PRINT_UNSUPPORTED_API(configure_endpoints); +} static int unsupported_claim_interface(struct libusb_device_handle *dev_handle, int iface) { PRINT_UNSUPPORTED_API(claim_interface); } @@ -2305,11 +2327,15 @@ static int unsupported_abort_transfers(struct usbi_transfer *itransfer) { static int unsupported_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) { PRINT_UNSUPPORTED_API(copy_transfer_data); } +static int common_configure_endpoints(struct libusb_device_handle *dev_handle, int iface) { + return LIBUSB_SUCCESS; +} // These names must be uppercase const char* hub_driver_names[] = {"USBHUB"}; const char* composite_driver_names[] = {"USBCCGP"}; const char* winusb_driver_names[] = {"WINUSB"}; +const char* libusbK_driver_names[] = {"LIBUSBWK"}; const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"}; const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { { @@ -2322,6 +2348,7 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { unsupported_exit, unsupported_open, unsupported_close, + unsupported_configure_endpoints, unsupported_claim_interface, unsupported_set_interface_altsetting, unsupported_release_interface, @@ -2343,6 +2370,7 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { unsupported_exit, hub_open, hub_close, + unsupported_configure_endpoints, unsupported_claim_interface, unsupported_set_interface_altsetting, unsupported_release_interface, @@ -2364,6 +2392,7 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { composite_exit, composite_open, composite_close, + common_configure_endpoints, composite_claim_interface, composite_set_interface_altsetting, composite_release_interface, @@ -2385,6 +2414,7 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { winusb_exit, winusb_open, winusb_close, + winusb_configure_endpoints, winusb_claim_interface, winusb_set_interface_altsetting, winusb_release_interface, @@ -2397,6 +2427,28 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { winusb_abort_transfers, winusb_copy_transfer_data, }, { + USB_API_LIBUSBK, + "libusbK API", + &CLASS_GUID_LIBUSBK, + libusbK_driver_names, + sizeof(libusbK_driver_names)/sizeof(libusbK_driver_names[0]), + libusbk_init, + libusbk_exit, + libusbk_open, + libusbk_close, + libusbk_configure_endpoints, + libusbk_claim_interface, + libusbk_set_interface_altsetting, + libusbk_release_interface, + libusbk_clear_halt, + libusbk_reset_device, + libusbk_submit_bulk_transfer, + unsupported_submit_iso_transfer, + libusbk_submit_control_transfer, + libusbk_abort_control, + libusbk_abort_transfers, + libusbk_copy_transfer_data, + }, { USB_API_HID, "HID API", &CLASS_GUID_HID, @@ -2406,6 +2458,7 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { hid_exit, hid_open, hid_close, + common_configure_endpoints, hid_claim_interface, hid_set_interface_altsetting, hid_release_interface, @@ -2435,8 +2488,12 @@ static void hub_close(struct libusb_device_handle *dev_handle) } /* - * WinUSB API functions + * WinUSB, libusbK API functions */ + +// TODO: This will break on MSVC6 because of the use of VA_ARGS... +#define _WinUsb(name, ...) (((k) && (LUsbW_##name(__VA_ARGS__))) || ((!k) && (WinUsb_##name(__VA_ARGS__)))) + static int winusb_init(struct libusb_context *ctx) { DLL_LOAD(winusb.dll, WinUsb_Initialize, TRUE); @@ -2466,10 +2523,39 @@ static int winusb_exit(void) return LIBUSB_SUCCESS; } +static int libusbk_init(struct libusb_context *ctx) +{ + DLL_LOAD(libusbwK.dll, LUsbW_Initialize, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_Free, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_GetAssociatedInterface, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_GetDescriptor, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_QueryInterfaceSettings, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_QueryDeviceInformation, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_SetCurrentAlternateSetting, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_GetCurrentAlternateSetting, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_QueryPipe, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_SetPipePolicy, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_GetPipePolicy, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_ReadPipe, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_WritePipe, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_ControlTransfer, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_ResetPipe, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_AbortPipe, TRUE); + DLL_LOAD(libusbwK.dll, LUsbW_FlushPipe, TRUE); + + api_libusbk_available = true; + return LIBUSB_SUCCESS; +} + +static int libusbk_exit(void) +{ + return LIBUSB_SUCCESS; +} + // NB: open and close must ensure that they only handle interface of // the right API type, as these functions can be called wholesale from // composite_open(), with interfaces belonging to different APIs -static int winusb_open(struct libusb_device_handle *dev_handle) +static int _winusb_open(struct libusb_device_handle *dev_handle, bool k) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); struct windows_device_priv *priv = __device_priv(dev_handle->dev); @@ -2483,7 +2569,7 @@ static int winusb_open(struct libusb_device_handle *dev_handle) // WinUSB requires a seperate handle for each interface for (i = 0; i < USB_MAXINTERFACES; i++) { if ( (priv->usb_interface[i].path != NULL) - && (priv->usb_interface[i].apib->id == USB_API_WINUSB) ) { + && ((priv->usb_interface[i].apib->id == USB_API_WINUSB)||(priv->usb_interface[i].apib->id == USB_API_LIBUSBK)) ) { file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (file_handle == INVALID_HANDLE_VALUE) { @@ -2504,18 +2590,31 @@ static int winusb_open(struct libusb_device_handle *dev_handle) return LIBUSB_SUCCESS; } -static void winusb_close(struct libusb_device_handle *dev_handle) +static int winusb_open(struct libusb_device_handle *dev_handle) +{ + return _winusb_open(dev_handle, false); +} + +static int libusbk_open(struct libusb_device_handle *dev_handle) +{ + return _winusb_open(dev_handle, true); +} + +static void _winusb_close(struct libusb_device_handle *dev_handle, bool k) { struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle); struct windows_device_priv *priv = __device_priv(dev_handle->dev); HANDLE file_handle; int i; - if (!api_winusb_available) + if ((!k) && (!api_winusb_available)) + return; + + if ((k) && (!api_libusbk_available)) return; for (i = 0; i < USB_MAXINTERFACES; i++) { - if (priv->usb_interface[i].apib->id == USB_API_WINUSB) { + if ((priv->usb_interface[i].apib->id == USB_API_WINUSB)||(priv->usb_interface[i].apib->id == USB_API_LIBUSBK)) { file_handle = handle_priv->interface_handle[i].dev_handle; if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) { CloseHandle(file_handle); @@ -2524,7 +2623,17 @@ static void winusb_close(struct libusb_device_handle *dev_handle) } } -static int winusb_configure_endpoints(struct libusb_device_handle *dev_handle, int iface) +static void winusb_close(struct libusb_device_handle *dev_handle) +{ + _winusb_close(dev_handle, false); +} + +static void libusbk_close(struct libusb_device_handle *dev_handle) +{ + _winusb_close(dev_handle, true); +} + +static int _winusb_configure_endpoints(struct libusb_device_handle *dev_handle, int iface, bool k) { struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle); struct windows_device_priv *priv = __device_priv(dev_handle->dev); @@ -2540,26 +2649,26 @@ static int winusb_configure_endpoints(struct libusb_device_handle *dev_handle, i // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) { endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i]; - if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, + if (!_WinUsb(SetPipePolicy, winusb_handle, endpoint_address, PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) { usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address); } if (i == -1) continue; // Other policies don't apply to control endpoint policy = false; - if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, + if (!_WinUsb(SetPipePolicy, winusb_handle, endpoint_address, SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) { usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address); } - if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, + if (!_WinUsb(SetPipePolicy, winusb_handle, endpoint_address, IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) { usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address); } - if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, + if (!_WinUsb(SetPipePolicy, winusb_handle, endpoint_address, ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) { usbi_dbg("failed to disable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address); } policy = true; - if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, + if (!_WinUsb(SetPipePolicy, winusb_handle, endpoint_address, AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) { usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address); } @@ -2568,7 +2677,17 @@ static int winusb_configure_endpoints(struct libusb_device_handle *dev_handle, i return LIBUSB_SUCCESS; } -static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int iface) +static int winusb_configure_endpoints(struct libusb_device_handle *dev_handle, int iface) +{ + return _winusb_configure_endpoints(dev_handle, iface, false); +} + +static int libusbk_configure_endpoints(struct libusb_device_handle *dev_handle, int iface) +{ + return _winusb_configure_endpoints(dev_handle, iface, true); +} + +static int _winusb_claim_interface(struct libusb_device_handle *dev_handle, int iface, bool k) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle); @@ -2588,7 +2707,7 @@ static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int i return LIBUSB_ERROR_NOT_FOUND; } - if (!WinUsb_Initialize(file_handle, &winusb_handle)) { + if (!_WinUsb(Initialize, file_handle, &winusb_handle)) { usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0)); handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; @@ -2609,7 +2728,7 @@ static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int i if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) { #if defined(AUTO_CLAIM) file_handle = handle_priv->interface_handle[0].dev_handle; - if (WinUsb_Initialize(file_handle, &winusb_handle)) { + if (_WinUsb(Initialize, file_handle, &winusb_handle)) { handle_priv->interface_handle[0].api_handle = winusb_handle; usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface); } else { @@ -2621,7 +2740,7 @@ static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int i return LIBUSB_ERROR_ACCESS; #endif } - if (!WinUsb_GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1), + if (!_WinUsb(GetAssociatedInterface, winusb_handle, (UCHAR)(iface-1), &handle_priv->interface_handle[iface].api_handle)) { handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; switch(GetLastError()) { @@ -2643,10 +2762,21 @@ static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int i return LIBUSB_SUCCESS; } -static int winusb_release_interface(struct libusb_device_handle *dev_handle, int iface) +static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int iface) +{ + return _winusb_claim_interface(dev_handle, iface, false); +} + +static int libusbk_claim_interface(struct libusb_device_handle *dev_handle, int iface) +{ + return _winusb_claim_interface(dev_handle, iface, true); +} + +static int _winusb_release_interface(struct libusb_device_handle *dev_handle, int iface, bool k) { struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle); HANDLE winusb_handle; + BOOL ignored; CHECK_WINUSB_AVAILABLE; @@ -2655,12 +2785,24 @@ static int winusb_release_interface(struct libusb_device_handle *dev_handle, int return LIBUSB_ERROR_NOT_FOUND; } - WinUsb_Free(winusb_handle); + // http://msdn.microsoft.com/en-us/library/ff540233%28v=vs.85%29.aspx: + // "WinUsb_Free returns TRUE" + ignored = _WinUsb(Free, winusb_handle); handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; return LIBUSB_SUCCESS; } +static int winusb_release_interface(struct libusb_device_handle *dev_handle, int iface) +{ + return _winusb_release_interface(dev_handle, iface, false); +} + +static int libusbk_release_interface(struct libusb_device_handle *dev_handle, int iface) +{ + return _winusb_release_interface(dev_handle, iface, true); +} + /* * Return the first valid interface (of the same API type), for control transfers */ @@ -2710,7 +2852,7 @@ static int interface_by_endpoint(struct windows_device_priv *priv, return -1; } -static int winusb_submit_control_transfer(struct usbi_transfer *itransfer) +static int _winusb_submit_control_transfer(struct usbi_transfer *itransfer, bool k) { struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); @@ -2732,10 +2874,10 @@ static int winusb_submit_control_transfer(struct usbi_transfer *itransfer) if (size > MAX_CTRL_BUFFER_LENGTH) return LIBUSB_ERROR_INVALID_PARAM; - current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSB); + current_interface = get_valid_interface(transfer->dev_handle, k?USB_API_LIBUSBK:USB_API_WINUSB); if (current_interface < 0) { #if defined(AUTO_CLAIM) - if (auto_claim(transfer, ¤t_interface, USB_API_WINUSB) != LIBUSB_SUCCESS) { + if (auto_claim(transfer, ¤t_interface, k?USB_API_LIBUSBK:USB_API_WINUSB) != LIBUSB_SUCCESS) { return LIBUSB_ERROR_NOT_FOUND; } #else @@ -2764,7 +2906,7 @@ static int winusb_submit_control_transfer(struct usbi_transfer *itransfer) wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; wfd.overlapped->InternalHigh = 0; } else { - if (!WinUsb_ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) { + if (!_WinUsb(ControlTransfer, wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) { if(GetLastError() != ERROR_IO_PENDING) { usbi_err(ctx, "WinUsb_ControlTransfer failed: %s", windows_error_str(0)); usbi_free_fd(wfd.fd); @@ -2783,7 +2925,17 @@ static int winusb_submit_control_transfer(struct usbi_transfer *itransfer) return LIBUSB_SUCCESS; } -static int winusb_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) +static int winusb_submit_control_transfer(struct usbi_transfer *itransfer) +{ + return _winusb_submit_control_transfer(itransfer, false); +} + +static int libusbk_submit_control_transfer(struct usbi_transfer *itransfer) +{ + return _winusb_submit_control_transfer(itransfer, true); +} + +static int _winusb_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting, bool k) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle); @@ -2801,7 +2953,7 @@ static int winusb_set_interface_altsetting(struct libusb_device_handle *dev_hand return LIBUSB_ERROR_NOT_FOUND; } - if (!WinUsb_SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) { + if (!_WinUsb(SetCurrentAlternateSetting, winusb_handle, (UCHAR)altsetting)) { usbi_err(ctx, "WinUsb_SetCurrentAlternateSetting failed: %s", windows_error_str(0)); return LIBUSB_ERROR_IO; } @@ -2809,7 +2961,17 @@ static int winusb_set_interface_altsetting(struct libusb_device_handle *dev_hand return LIBUSB_SUCCESS; } -static int winusb_submit_bulk_transfer(struct usbi_transfer *itransfer) +static int winusb_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + return _winusb_set_interface_altsetting(dev_handle, iface, altsetting, false); +} + +static int libusbk_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + return _winusb_set_interface_altsetting(dev_handle, iface, altsetting, true); +} + +static int _winusb_submit_bulk_transfer(struct usbi_transfer *itransfer, bool k) { struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); @@ -2844,10 +3006,16 @@ static int winusb_submit_bulk_transfer(struct usbi_transfer *itransfer) if (direction_in) { usbi_dbg("reading %d bytes", transfer->length); - ret = WinUsb_ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); + if (!k) + ret = WinUsb_ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); + else + ret = LUsbW_ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); } else { usbi_dbg("writing %d bytes", transfer->length); - ret = WinUsb_WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); + if (!k) + ret = WinUsb_WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); + else + ret = LUsbW_WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); } if (!ret) { if(GetLastError() != ERROR_IO_PENDING) { @@ -2866,7 +3034,17 @@ static int winusb_submit_bulk_transfer(struct usbi_transfer *itransfer) return LIBUSB_SUCCESS; } -static int winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) +static int winusb_submit_bulk_transfer(struct usbi_transfer *itransfer) +{ + return _winusb_submit_bulk_transfer(itransfer, false); +} + +static int libusbk_submit_bulk_transfer(struct usbi_transfer *itransfer) +{ + return _winusb_submit_bulk_transfer(itransfer, true); +} + +static int _winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint, bool k) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle); @@ -2885,7 +3063,7 @@ static int winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned c usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface); winusb_handle = handle_priv->interface_handle[current_interface].api_handle; - if (!WinUsb_ResetPipe(winusb_handle, endpoint)) { + if (!_WinUsb(ResetPipe, winusb_handle, endpoint)) { usbi_err(ctx, "WinUsb_ResetPipe failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NO_DEVICE; } @@ -2893,6 +3071,16 @@ static int winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned c return LIBUSB_SUCCESS; } +static int winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + return _winusb_clear_halt(dev_handle, endpoint, false); +} + +static int libusbk_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + return _winusb_clear_halt(dev_handle, endpoint, true); +} + /* * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed * through testing as well): @@ -2905,7 +3093,13 @@ static int winusb_abort_control(struct usbi_transfer *itransfer) return LIBUSB_SUCCESS; } -static int winusb_abort_transfers(struct usbi_transfer *itransfer) +static int libusbk_abort_control(struct usbi_transfer *itransfer) +{ + // Cancelling of the I/O is done in the parent + return LIBUSB_SUCCESS; +} + +static int _winusb_abort_transfers(struct usbi_transfer *itransfer, bool k) { struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); @@ -2925,7 +3119,7 @@ static int winusb_abort_transfers(struct usbi_transfer *itransfer) winusb_handle = handle_priv->interface_handle[current_interface].api_handle; - if (!WinUsb_AbortPipe(winusb_handle, transfer->endpoint)) { + if (!_WinUsb(AbortPipe, winusb_handle, transfer->endpoint)) { usbi_err(ctx, "WinUsb_AbortPipe failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NO_DEVICE; } @@ -2933,6 +3127,16 @@ static int winusb_abort_transfers(struct usbi_transfer *itransfer) return LIBUSB_SUCCESS; } +static int winusb_abort_transfers(struct usbi_transfer *itransfer) +{ + return _winusb_abort_transfers(itransfer, false); +} + +static int libusbk_abort_transfers(struct usbi_transfer *itransfer) +{ + return _winusb_abort_transfers(itransfer, true); +} + /* * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx): @@ -2942,7 +3146,7 @@ static int winusb_abort_transfers(struct usbi_transfer *itransfer) * cycle the pipes (and even then, the control pipe can not be reset using WinUSB) */ // TODO (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?) -static int winusb_reset_device(struct libusb_device_handle *dev_handle) +static int _winusb_reset_device(struct libusb_device_handle *dev_handle, bool k) { struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle); @@ -2967,17 +3171,17 @@ static int winusb_reset_device(struct libusb_device_handle *dev_handle) if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) { for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) { usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]); - if (!WinUsb_AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) { + if (!_WinUsb(AbortPipe, winusb_handle, priv->usb_interface[i].endpoint[j])) { usbi_err(ctx, "WinUsb_AbortPipe (pipe address %02X) failed: %s", priv->usb_interface[i].endpoint[j], windows_error_str(0)); } // FlushPipe seems to fail on OUT pipes if ( (priv->usb_interface[i].endpoint[j] & LIBUSB_ENDPOINT_IN) - && (!WinUsb_FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) { + && (!_WinUsb(FlushPipe, winusb_handle, priv->usb_interface[i].endpoint[j])) ) { usbi_err(ctx, "WinUsb_FlushPipe (pipe address %02X) failed: %s", priv->usb_interface[i].endpoint[j], windows_error_str(0)); } - if (!WinUsb_ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) { + if (!_WinUsb(ResetPipe, winusb_handle, priv->usb_interface[i].endpoint[j])) { usbi_err(ctx, "WinUsb_ResetPipe (pipe address %02X) failed: %s", priv->usb_interface[i].endpoint[j], windows_error_str(0)); } @@ -2988,12 +3192,28 @@ static int winusb_reset_device(struct libusb_device_handle *dev_handle) return LIBUSB_SUCCESS; } +static int winusb_reset_device(struct libusb_device_handle *dev_handle) +{ + return _winusb_reset_device(dev_handle, false); +} + +static int libusbk_reset_device(struct libusb_device_handle *dev_handle) +{ + return _winusb_reset_device(dev_handle, true); +} + static int winusb_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) { itransfer->transferred += io_size; return LIBUSB_TRANSFER_COMPLETED; } +static int libusbk_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) +{ + itransfer->transferred += io_size; + return LIBUSB_TRANSFER_COMPLETED; +} + /* * Internal HID Support functions (from libusb-win32) * Note that functions that complete data transfer synchronously must return diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h index 8851f41..c31f593 100644 --- a/libusb/os/windows_usb.h +++ b/libusb/os/windows_usb.h @@ -118,12 +118,14 @@ const GUID GUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x #define USB_API_HUB 1 #define USB_API_COMPOSITE 2 #define USB_API_WINUSB 3 -#define USB_API_HID 4 -#define USB_API_MAX 5 +#define USB_API_LIBUSBK 4 +#define USB_API_HID 5 +#define USB_API_MAX 6 #define CLASS_GUID_UNSUPPORTED GUID_NULL const GUID CLASS_GUID_HID = { 0x745A17A0, 0x74D3, 0x11D0, {0xB6, 0xFE, 0x00, 0xA0, 0xC9, 0x0F, 0x57, 0xDA} }; const GUID CLASS_GUID_LIBUSB_WINUSB = { 0x78A1C341, 0x4539, 0x11D3, {0xB8, 0x8D, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71} }; +const GUID CLASS_GUID_LIBUSBK = { 0xECFB0CFD, 0x74C4, 0x4F52, {0xBB, 0xF7, 0x34, 0x34, 0x61, 0xCD, 0x72, 0xAC} }; const GUID CLASS_GUID_COMPOSITE = { 0x36FC9E60, 0xC465, 0x11cF, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} }; struct windows_usb_api_backend { @@ -136,6 +138,7 @@ struct windows_usb_api_backend { int (*exit)(void); int (*open)(struct libusb_device_handle *dev_handle); void (*close)(struct libusb_device_handle *dev_handle); + int (*configure_endpoints)(struct libusb_device_handle *dev_handle, int iface); int (*claim_interface)(struct libusb_device_handle *dev_handle, int iface); int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle, int iface, int altsetting); int (*release_interface)(struct libusb_device_handle *dev_handle, int iface); @@ -671,6 +674,7 @@ typedef struct { typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE; +/* WinUSB.dll */ DLL_DECLARE(WINAPI, BOOL, WinUsb_Initialize, (HANDLE, PWINUSB_INTERFACE_HANDLE)); DLL_DECLARE(WINAPI, BOOL, WinUsb_Free, (WINUSB_INTERFACE_HANDLE)); DLL_DECLARE(WINAPI, BOOL, WinUsb_GetAssociatedInterface, (WINUSB_INTERFACE_HANDLE, UCHAR, PWINUSB_INTERFACE_HANDLE)); @@ -689,6 +693,25 @@ DLL_DECLARE(WINAPI, BOOL, WinUsb_ResetPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); DLL_DECLARE(WINAPI, BOOL, WinUsb_AbortPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); DLL_DECLARE(WINAPI, BOOL, WinUsb_FlushPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); +/* libusbwK.dll */ +DLL_DECLARE(WINAPI, BOOL, LUsbW_Initialize, (HANDLE, PWINUSB_INTERFACE_HANDLE)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_Free, (WINUSB_INTERFACE_HANDLE)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_GetAssociatedInterface, (WINUSB_INTERFACE_HANDLE, UCHAR, PWINUSB_INTERFACE_HANDLE)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_GetDescriptor, (WINUSB_INTERFACE_HANDLE, UCHAR, UCHAR, USHORT, PUCHAR, ULONG, PULONG)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_QueryInterfaceSettings, (WINUSB_INTERFACE_HANDLE, UCHAR, PUSB_INTERFACE_DESCRIPTOR)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_QueryDeviceInformation, (WINUSB_INTERFACE_HANDLE, ULONG, PULONG, PVOID)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_SetCurrentAlternateSetting, (WINUSB_INTERFACE_HANDLE, UCHAR)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_GetCurrentAlternateSetting, (WINUSB_INTERFACE_HANDLE, PUCHAR)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_QueryPipe, (WINUSB_INTERFACE_HANDLE, UCHAR, UCHAR, PWINUSB_PIPE_INFORMATION)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_SetPipePolicy, (WINUSB_INTERFACE_HANDLE, UCHAR, ULONG, ULONG, PVOID)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_GetPipePolicy, (WINUSB_INTERFACE_HANDLE, UCHAR, ULONG, PULONG, PVOID)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_ReadPipe, (WINUSB_INTERFACE_HANDLE, UCHAR, PUCHAR, ULONG, PULONG, LPOVERLAPPED)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_WritePipe, (WINUSB_INTERFACE_HANDLE, UCHAR, PUCHAR, ULONG, PULONG, LPOVERLAPPED)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_ControlTransfer, (WINUSB_INTERFACE_HANDLE, WINUSB_SETUP_PACKET, PUCHAR, ULONG, PULONG, LPOVERLAPPED)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_ResetPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_AbortPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); +DLL_DECLARE(WINAPI, BOOL, LUsbW_FlushPipe, (WINUSB_INTERFACE_HANDLE, UCHAR)); + /* hid.dll interface */ #define HIDP_STATUS_SUCCESS 0x110000 |