summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Bolte <matthias.bolte@googlemail.com>2019-12-16 13:38:35 +0100
committerChris Dickens <christopher.a.dickens@gmail.com>2020-01-02 18:52:24 -0800
commitf67f065709c948d2e29150ea2a3d9441a2609f36 (patch)
tree9a36373fa0e2575348fb688dd99227228a9a9de3
parent1e9d26a753a741bfdb0769b4c895697d16edcc27 (diff)
downloadlibusb-f67f065709c948d2e29150ea2a3d9441a2609f36.tar.gz
windows: Fix USBD_STATUS to LIBUSB_TRANSFER_STATUS translation
The MSDN documentaion says that the most significant 4 bits of the USBD_STATUS value indicate success/pending/error state, but then gives them as 2 bit values. The broken translations code assumes these to be the lower 2 bits: 0b0000 for success 0b0001 for pending 0b0010 for error 0b0011 for error But actually it's the higher 2 bits: 0b0000 for success 0b0100 for pending 0b1000 for error 0b1100 for error The USBDK code already deals with USBD_STATUS and gets it correct. Another problem is that the broken translations code then masks off the most significant 4 bits of the USBD_STATUS value, but then compares it to the full 32 bit error codes to figure out the actual error. This switch will always jump to the default case, because all checked error codes have their most significant 2 bits set, but the values they are compared against have those bits masked off. Move the working code from the USBDK backend to the shared header and reuse it in the WinUSB backend too. [dickens] Fixed whitespace, removed unused definitions, add ifdef guard, and retained name as USBD_SUCCESS to match w32api header. Closes #665 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/os/windows_nt_shared_types.h12
-rw-r--r--libusb/os/windows_usbdk.c12
-rw-r--r--libusb/os/windows_winusb.c34
-rw-r--r--libusb/version_nano.h2
4 files changed, 27 insertions, 33 deletions
diff --git a/libusb/os/windows_nt_shared_types.h b/libusb/os/windows_nt_shared_types.h
index d809bfd..79b5b64 100644
--- a/libusb/os/windows_nt_shared_types.h
+++ b/libusb/os/windows_nt_shared_types.h
@@ -34,6 +34,18 @@ typedef struct USB_CONFIGURATION_DESCRIPTOR {
#include <poppack.h>
+// https://msdn.microsoft.com/en-us/library/windows/hardware/ff539136(v=vs.85).aspx
+#if !defined(USBD_SUCCESS)
+typedef LONG USBD_STATUS;
+
+#define USBD_SUCCESS(Status) ((USBD_STATUS)(Status) >= 0)
+
+#define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS)0xC0000030L)
+#define USBD_STATUS_TIMEOUT ((USBD_STATUS)0xC0006000L)
+#define USBD_STATUS_DEVICE_GONE ((USBD_STATUS)0xC0007000L)
+#define USBD_STATUS_CANCELED ((USBD_STATUS)0xC0010000L)
+#endif
+
#define MAX_DEVICE_ID_LEN 200
typedef struct USB_DK_DEVICE_ID {
diff --git a/libusb/os/windows_usbdk.c b/libusb/os/windows_usbdk.c
index 2b4f7e0..f9a967b 100644
--- a/libusb/os/windows_usbdk.c
+++ b/libusb/os/windows_usbdk.c
@@ -44,18 +44,6 @@ typedef LONG NTSTATUS;
#define STATUS_REQUEST_CANCELED ((NTSTATUS)0xC0000703L)
#endif
-#if !defined(USBD_SUCCESS)
-typedef LONG USBD_STATUS;
-#define USBD_SUCCESS(Status) ((USBD_STATUS) (Status) >= 0)
-#define USBD_PENDING(Status) ((ULONG) (Status) >> 30 == 1)
-#define USBD_ERROR(Status) ((USBD_STATUS) (Status) < 0)
-#define USBD_STATUS_STALL_PID ((USBD_STATUS) 0xc0000004)
-#define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS) 0xc0000030)
-#define USBD_STATUS_BAD_START_FRAME ((USBD_STATUS) 0xc0000a00)
-#define USBD_STATUS_TIMEOUT ((USBD_STATUS) 0xc0006000)
-#define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000)
-#endif
-
static inline struct usbdk_device_priv *_usbdk_device_priv(struct libusb_device *dev)
{
return (struct usbdk_device_priv *)dev->os_priv;
diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c
index 1b42d4e..71794c1 100644
--- a/libusb/os/windows_winusb.c
+++ b/libusb/os/windows_winusb.c
@@ -2552,27 +2552,21 @@ static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_ha
static enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS status)
{
- /* Based on https://msdn.microsoft.com/en-us/library/windows/hardware/ff539136(v=vs.85).aspx :
- * USBD_STATUS have the most significant 4 bits indicating overall status and the rest gives the details. */
- switch (status >> 28) {
- case 0x00: /* USBD_STATUS_SUCCESS */
+ if (USBD_SUCCESS(status))
return LIBUSB_TRANSFER_COMPLETED;
- case 0x01: /* USBD_STATUS_PENDING */
- return LIBUSB_TRANSFER_COMPLETED;
- default: /* USBD_STATUS_ERROR */
- switch (status & 0x0fffffff) {
- case 0xC0006000: /* USBD_STATUS_TIMEOUT */
- return LIBUSB_TRANSFER_TIMED_OUT;
- case 0xC0010000: /* USBD_STATUS_CANCELED */
- return LIBUSB_TRANSFER_CANCELLED;
- case 0xC0000030: /* USBD_STATUS_ENDPOINT_HALTED */
- return LIBUSB_TRANSFER_STALL;
- case 0xC0007000: /* USBD_STATUS_DEVICE_GONE */
- return LIBUSB_TRANSFER_NO_DEVICE;
- default:
- usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", status);
- return LIBUSB_TRANSFER_ERROR;
- }
+
+ switch (status) {
+ case USBD_STATUS_TIMEOUT:
+ return LIBUSB_TRANSFER_TIMED_OUT;
+ case USBD_STATUS_CANCELED:
+ return LIBUSB_TRANSFER_CANCELLED;
+ case USBD_STATUS_ENDPOINT_HALTED:
+ return LIBUSB_TRANSFER_STALL;
+ case USBD_STATUS_DEVICE_GONE:
+ return LIBUSB_TRANSFER_NO_DEVICE;
+ default:
+ usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", status);
+ return LIBUSB_TRANSFER_ERROR;
}
}
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index ba3fee6..3b9b7ee 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11416
+#define LIBUSB_NANO 11417