Windows: Fix HID and synchronous transfer completion
authorChris Dickens <christopher.a.dickens@gmail.com>
Mon, 1 Feb 2021 23:12:17 +0000 (15:12 -0800)
committerChris Dickens <christopher.a.dickens@gmail.com>
Mon, 1 Feb 2021 23:12:17 +0000 (15:12 -0800)
Commit b51c743e42 ("Windows: Filter out non-libusb I/O completions")
causes problems with the HID backend functions and synchronous transfer
completions. Address these by fetching the correct pointer in the HID
functions and posting an I/O completion for synchronous transfers.

Closes #863

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
libusb/os/windows_common.c
libusb/os/windows_winusb.c
libusb/version_nano.h

index a5e2a7c..6e69317 100644 (file)
@@ -293,15 +293,18 @@ enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS st
  */
 void windows_force_sync_completion(struct usbi_transfer *itransfer, ULONG size)
 {
+       struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+       struct windows_context_priv *priv = usbi_get_context_priv(TRANSFER_CTX(transfer));
        struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
        OVERLAPPED *overlapped = &transfer_priv->overlapped;
 
-       usbi_dbg("transfer %p, length %lu", USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(size));
+       usbi_dbg("transfer %p, length %lu", transfer, ULONG_CAST(size));
 
        overlapped->Internal = (ULONG_PTR)STATUS_SUCCESS;
        overlapped->InternalHigh = (ULONG_PTR)size;
 
-       usbi_signal_transfer_completion(itransfer);
+       if (!PostQueuedCompletionStatus(priv->completion_port, (DWORD)size, (ULONG_PTR)transfer->dev_handle, overlapped))
+               usbi_err(TRANSFER_CTX(transfer), "failed to post I/O completion: %s", windows_error_str(0));
 }
 
 /* Windows version detection */
index a370ede..e4d194a 100644 (file)
@@ -3667,7 +3667,7 @@ static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
 {
        struct libusb_device *dev = dev_handle->dev;
        struct winusb_device_priv *priv = usbi_get_device_priv(dev);
-       struct winusb_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
+       struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
        HIDD_ATTRIBUTES hid_attributes;
        PHIDP_PREPARSED_DATA preparsed_data = NULL;
        HIDP_CAPS capabilities;
@@ -3692,7 +3692,7 @@ static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
        for (i = 0; i < USB_MAXINTERFACES; i++) {
                if ((priv->usb_interface[i].path != NULL)
                                && (priv->usb_interface[i].apib->id == USB_API_HID)) {
-                       hid_handle = windows_open(dev, priv->usb_interface[i].path, GENERIC_READ | GENERIC_WRITE);
+                       hid_handle = windows_open(dev_handle, priv->usb_interface[i].path, GENERIC_READ | GENERIC_WRITE);
                        /*
                         * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
                         * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
@@ -3702,7 +3702,7 @@ static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
                         */
                        if (hid_handle == INVALID_HANDLE_VALUE) {
                                usbi_warn(HANDLE_CTX(dev_handle), "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
-                               hid_handle = windows_open(dev, priv->usb_interface[i].path, 0);
+                               hid_handle = windows_open(dev_handle, priv->usb_interface[i].path, 0);
                                if (hid_handle == INVALID_HANDLE_VALUE) {
                                        usbi_err(HANDLE_CTX(dev_handle), "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
                                        switch (GetLastError()) {
@@ -3816,7 +3816,7 @@ static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
 static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
 {
        struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
-       struct winusb_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
+       struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
        HANDLE file_handle;
        int i;
 
@@ -3836,7 +3836,7 @@ static void hid_close(int sub_api, struct libusb_device_handle *dev_handle)
 
 static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
 {
-       struct winusb_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
+       struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
        struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
 
        UNUSED(sub_api);
@@ -3860,7 +3860,7 @@ static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_han
 
 static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, uint8_t iface)
 {
-       struct winusb_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
+       struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
        struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
 
        UNUSED(sub_api);
@@ -3897,7 +3897,7 @@ static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itrans
        struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
        struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
        struct libusb_device_handle *dev_handle = transfer->dev_handle;
-       struct winusb_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
+       struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
        struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
        WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer;
        HANDLE hid_handle;
@@ -3995,7 +3995,7 @@ static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer
 {
        struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
        struct winusb_transfer_priv *transfer_priv = get_winusb_transfer_priv(itransfer);
-       struct winusb_device_handle_priv *handle_priv = usbi_get_device_handle_priv(transfer->dev_handle);
+       struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(transfer->dev_handle);
        struct winusb_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
        HANDLE hid_handle;
        OVERLAPPED *overlapped;
@@ -4064,7 +4064,7 @@ static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer
 
 static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
 {
-       struct winusb_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
+       struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
        HANDLE hid_handle;
        int current_interface;
 
@@ -4083,7 +4083,7 @@ static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle
 
 static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint)
 {
-       struct winusb_device_handle_priv *handle_priv = usbi_get_device_handle_priv(dev_handle);
+       struct winusb_device_handle_priv *handle_priv = get_winusb_device_handle_priv(dev_handle);
        struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
        HANDLE hid_handle;
        int current_interface;
index 4227ce9..e02ad1c 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 11599
+#define LIBUSB_NANO 11600