summaryrefslogtreecommitdiff
path: root/libusb/os/windows_common.h
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2020-02-07 15:47:55 -0800
committerChris Dickens <christopher.a.dickens@gmail.com>2020-02-07 15:47:55 -0800
commit9c28ad219b654011783a42ec888ca87dbda704a6 (patch)
treeb789d577d5547c0d7b247d165fe52dc96f5014c8 /libusb/os/windows_common.h
parent67e6816264e35a1f22b43a78b4be7481652bc51a (diff)
downloadlibusb-9c28ad219b654011783a42ec888ca87dbda704a6.tar.gz
Windows: Refactoring to consolidate and simplify common code
Both the UsbDk and WinUSB backends perform common steps when handling transfers in order to interact with the poll abstraction, both during submission and when processing transfer completion. With some rearranging of shared structures, this can be yanked from the individual backends and placed in the common area. This allows for several functions to be removed outright from each backend. The cancellation logic can also be simplified by attempting CancelIoEx() at the highest level and delegating to the backend if there are alternatives to try should CancelIoEx() fail. After some analysis of how Windows processes asychronous (OVERLAPPED) requests that the underlying driver completes synchronously, it is now evident that such requests need not be handled in any special fashion. Each function that called a driver function that was expected to complete asynchronously had logic to handle the case of a synchronous completion, so this has all been killed off. This significantly cleans up these call sites as now they must only check for an error condition. Finally, the initialization code for the WinUSB backend has been reworked to load the WinUSB DLL independent of the libusbK DLL. Previously when the libusbK DLL was present, all requests to devices using WinUSB would first be sent through the libusbK DLL where they would then be forwarded to the WinUSB DLL. This is slightly inefficient but is also limiting when using Windows 8.1 or later because support for isochronous transfers through WinUSB will be lost. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
Diffstat (limited to 'libusb/os/windows_common.h')
-rw-r--r--libusb/os/windows_common.h58
1 files changed, 43 insertions, 15 deletions
diff --git a/libusb/os/windows_common.h b/libusb/os/windows_common.h
index 93ea23e..63d3183 100644
--- a/libusb/os/windows_common.h
+++ b/libusb/os/windows_common.h
@@ -68,13 +68,13 @@
#define DLL_HANDLE_NAME(name) __dll_##name##_handle
#define DLL_DECLARE_HANDLE(name) \
- static HMODULE DLL_HANDLE_NAME(name) = NULL
+ static HMODULE DLL_HANDLE_NAME(name)
#define DLL_GET_HANDLE(name) \
do { \
DLL_HANDLE_NAME(name) = DLL_LOAD_LIBRARY(name); \
if (!DLL_HANDLE_NAME(name)) \
- return FALSE; \
+ return false; \
} while (0)
#define DLL_FREE_HANDLE(name) \
@@ -92,7 +92,7 @@
#define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args) \
typedef ret (api * DLL_FUNC_NAME(name))args; \
- static DLL_FUNC_NAME(name) prefixname = NULL
+ static DLL_FUNC_NAME(name) prefixname
#define DLL_DECLARE_FUNC(api, ret, name, args) \
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
@@ -115,7 +115,7 @@
if (prefixname) \
break; \
if (ret_on_failure) \
- return FALSE; \
+ return false; \
} while (0)
#define DLL_LOAD_FUNC(dll, name, ret_on_failure) \
@@ -271,16 +271,13 @@ struct winusb_device_handle_priv {
struct usbdk_transfer_priv {
USB_DK_TRANSFER_REQUEST request;
- struct winfd pollable_fd;
- HANDLE system_handle;
PULONG64 IsochronousPacketsArray;
PUSB_DK_ISO_TRANSFER_RESULT IsochronousResultsArray;
};
struct winusb_transfer_priv {
- struct winfd pollable_fd;
- HANDLE handle;
uint8_t interface_number;
+
uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
uint8_t *hid_dest; // transfer buffer destination, required for HID
size_t hid_expected_size;
@@ -322,10 +319,7 @@ struct windows_backend {
int (*submit_transfer)(struct usbi_transfer *itransfer);
int (*cancel_transfer)(struct usbi_transfer *itransfer);
void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
- int (*copy_transfer_data)(struct usbi_transfer *itransfer, uint32_t io_size);
- int (*get_transfer_fd)(struct usbi_transfer *itransfer);
- void (*get_overlapped_result)(struct usbi_transfer *itransfer,
- DWORD *io_result, DWORD *io_size);
+ enum libusb_transfer_status (*copy_transfer_data)(struct usbi_transfer *itransfer, DWORD length);
};
struct windows_context_priv {
@@ -342,15 +336,49 @@ union windows_device_handle_priv {
struct winusb_device_handle_priv winusb_priv;
};
-union windows_transfer_priv {
- struct usbdk_transfer_priv usbdk_priv;
- struct winusb_transfer_priv winusb_priv;
+struct windows_transfer_priv {
+ struct winfd pollable_fd;
+ HANDLE handle;
+ union {
+ struct usbdk_transfer_priv usbdk_priv;
+ struct winusb_transfer_priv winusb_priv;
+ };
};
+static inline struct windows_transfer_priv *get_transfer_priv(struct usbi_transfer *itransfer)
+{
+ return (struct windows_transfer_priv *)usbi_transfer_get_os_priv(itransfer);
+}
+
+static inline OVERLAPPED *get_transfer_priv_overlapped(struct usbi_transfer *itransfer)
+{
+ struct windows_transfer_priv *transfer_priv = get_transfer_priv(itransfer);
+ return transfer_priv->pollable_fd.overlapped;
+}
+
+static inline void set_transfer_priv_handle(struct usbi_transfer *itransfer, HANDLE handle)
+{
+ struct windows_transfer_priv *transfer_priv = get_transfer_priv(itransfer);
+ transfer_priv->handle = handle;
+}
+
+static inline struct usbdk_transfer_priv *get_usbdk_transfer_priv(struct usbi_transfer *itransfer)
+{
+ struct windows_transfer_priv *transfer_priv = get_transfer_priv(itransfer);
+ return &transfer_priv->usbdk_priv;
+}
+
+static inline struct winusb_transfer_priv *get_winusb_transfer_priv(struct usbi_transfer *itransfer)
+{
+ struct windows_transfer_priv *transfer_priv = get_transfer_priv(itransfer);
+ return &transfer_priv->winusb_priv;
+}
+
extern const struct windows_backend usbdk_backend;
extern const struct windows_backend winusb_backend;
unsigned long htab_hash(const char *str);
+enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_STATUS status);
void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size);
#if defined(ENABLE_LOGGING)