summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2011-02-22 13:57:59 +0000
committerPete Batard <pbatard@gmail.com>2011-02-22 13:57:59 +0000
commitfcfe54ebbf4c5dae88ab7111301466d239f1e36b (patch)
tree14a2b9a9d3f75efc6717babc2c1a12d20ae4e98b
parentda53dc50f539ba5210af75134bf4756ef85b7f12 (diff)
downloadlibusb-fcfe54ebbf4c5dae88ab7111301466d239f1e36b.tar.gz
added LibUSBwK support
-rw-r--r--libusb/os/windows_usb.c306
-rw-r--r--libusb/os/windows_usb.h27
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, &current_interface, USB_API_WINUSB) != LIBUSB_SUCCESS) {
+ if (auto_claim(transfer, &current_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