Windows: Fix HID and synchronous transfer completion
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>
diff --git a/libusb/os/windows_common.c b/libusb/os/windows_common.c
index a5e2a7c..6e69317 100644
--- a/libusb/os/windows_common.c
+++ b/libusb/os/windows_common.c
@@ -293,15 +293,18 @@
*/
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 */
diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c
index a370ede..e4d194a 100644
--- a/libusb/os/windows_winusb.c
+++ b/libusb/os/windows_winusb.c
@@ -3667,7 +3667,7 @@
{
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 @@
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 @@
*/
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 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 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_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 @@
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 @@
{
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_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_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;
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 4227ce9..e02ad1c 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11599
+#define LIBUSB_NANO 11600