From 2571eb16ff992136346cdfc84b13b448eba3651e Mon Sep 17 00:00:00 2001 From: Sameeh Jubran Date: Fri, 10 Feb 2017 13:12:23 +0100 Subject: [PATCH] Only use usbdk when installed Check UsbDK availability at run time and activate UsbDk backend when possible. Fall back to current behavior when UsbDK not installed. Signed-off-by: Dmitry Fleytman Signed-off-by: Sameeh Jubran --- Externals/libusb/libusb/Makefile.am | 9 +--- Externals/libusb/libusb/core.c | 41 +++++++++++++++---- Externals/libusb/libusb/libusbi.h | 4 ++ .../libusb/libusb/os/windows_nt_common.c | 17 +++++--- .../libusb/libusb/os/windows_nt_common.h | 18 ++++++-- Externals/libusb/libusb/os/windows_usbdk.c | 25 +++++++---- Externals/libusb/libusb/os/windows_winusb.c | 23 +++++++---- Externals/libusb/libusb_static_2013.vcxproj | 2 + Externals/libusb/msvc/libusb_sources | 1 + 9 files changed, 103 insertions(+), 37 deletions(-) diff --git a/Externals/libusb/libusb/Makefile.am b/Externals/libusb/libusb/Makefile.am index b1b892d9c6..0eca02e857 100644 --- a/Externals/libusb/libusb/Makefile.am +++ b/Externals/libusb/libusb/Makefile.am @@ -15,8 +15,8 @@ NETBSD_USB_SRC = os/netbsd_usb.c SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h WINDOWS_COMMON_SRC = os/windows_nt_common.h os/windows_nt_common.c \ os/windows_common.h libusb-1.0.rc libusb-1.0.def -WINDOWS_USB_SRC = os/windows_winusb.h os/windows_winusb.c -WINDOWS_USBDK_SRC = os/windows_usbdk.h os/windows_usbdk.c +WINDOWS_USB_SRC = os/windows_winusb.h os/windows_winusb.c os/windows_usbdk.h \ + os/windows_usbdk.c $(COMMON_WINDOWS_SRC) WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \ os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp @@ -63,12 +63,7 @@ libusb_1_0_la_LIBADD = libusb_haiku.la endif if OS_WINDOWS - -if USE_USBDK -OS_SRC = $(WINDOWS_USBDK_SRC) $(WINDOWS_COMMON_SRC) -else OS_SRC = $(WINDOWS_USB_SRC) $(WINDOWS_COMMON_SRC) -endif .rc.lo: $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@ diff --git a/Externals/libusb/libusb/core.c b/Externals/libusb/libusb/core.c index 99aab7bb03..5d59210dc5 100644 --- a/Externals/libusb/libusb/core.c +++ b/Externals/libusb/libusb/core.c @@ -53,13 +53,7 @@ const struct usbi_os_backend * const usbi_backend = &openbsd_backend; #elif defined(OS_NETBSD) const struct usbi_os_backend * const usbi_backend = &netbsd_backend; #elif defined(OS_WINDOWS) - -#if defined(USE_USBDK) -const struct usbi_os_backend * const usbi_backend = &usbdk_backend; -#else -const struct usbi_os_backend * const usbi_backend = &windows_backend; -#endif - +const struct usbi_os_backend * usbi_backend; #elif defined(OS_WINCE) const struct usbi_os_backend * const usbi_backend = &wince_backend; #elif defined(OS_HAIKU) @@ -629,6 +623,26 @@ static struct discovered_devs *discovered_devs_alloc(void) return ret; } +#ifdef OS_WINDOWS +static int is_usbdk_driver_installed(void) +{ + int usbdk_installed = 0; + + SC_HANDLE managerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); + if (managerHandle) + { + SC_HANDLE serviceHandle = OpenService(managerHandle, TEXT("UsbDk"), GENERIC_READ); + if (serviceHandle) + { + usbdk_installed = 1; + CloseServiceHandle(serviceHandle); + } + CloseServiceHandle(managerHandle); + } + return usbdk_installed; +} +#endif + static void discovered_devs_free(struct discovered_devs *discdevs) { size_t i; @@ -2067,6 +2081,19 @@ int API_EXPORTED libusb_init(libusb_context **context) static int first_init = 1; int r = 0; +#ifdef OS_WINDOWS + if (is_usbdk_driver_installed()) + { + usbi_backend = &usbdk_backend; + usbi_dbg("libusb will work with UsbDk backend"); + } + else + { + usbi_backend = &windows_backend; + usbi_dbg("libusb will work with windows_backend"); + } +#endif + usbi_mutex_static_lock(&default_context_lock); if (!timestamp_origin.tv_sec) { diff --git a/Externals/libusb/libusb/libusbi.h b/Externals/libusb/libusb/libusbi.h index cc0906c199..dcc996e179 100644 --- a/Externals/libusb/libusb/libusbi.h +++ b/Externals/libusb/libusb/libusbi.h @@ -1132,7 +1132,11 @@ struct usbi_os_backend { size_t transfer_priv_size; }; +#if defined(OS_WINDOWS) +extern const struct usbi_os_backend * usbi_backend; +#else extern const struct usbi_os_backend * const usbi_backend; +#endif extern const struct usbi_os_backend linux_usbfs_backend; extern const struct usbi_os_backend darwin_backend; diff --git a/Externals/libusb/libusb/os/windows_nt_common.c b/Externals/libusb/libusb/os/windows_nt_common.c index 68eb4a7920..1565a4aba9 100644 --- a/Externals/libusb/libusb/os/windows_nt_common.c +++ b/Externals/libusb/libusb/os/windows_nt_common.c @@ -59,6 +59,8 @@ DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT)); DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM)); +win_backend backend_func; + static unsigned __stdcall windows_clock_gettime_threaded(void *param); /* @@ -487,7 +489,7 @@ static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t switch (io_result) { case NO_ERROR: - status = windows_copy_transfer_data(itransfer, io_size); + status = backend_func.copy_transfer_data(itransfer, io_size); break; case ERROR_GEN_FAILURE: usbi_dbg("detected endpoint stall"); @@ -498,7 +500,7 @@ static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t status = LIBUSB_TRANSFER_TIMED_OUT; break; case ERROR_OPERATION_ABORTED: - istatus = windows_copy_transfer_data(itransfer, io_size); + istatus = backend_func.copy_transfer_data(itransfer, io_size); if (istatus != LIBUSB_TRANSFER_COMPLETED) usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus); @@ -510,7 +512,7 @@ static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t status = LIBUSB_TRANSFER_ERROR; break; } - windows_clear_transfer_priv(itransfer); // Cancel polling + backend_func.clear_transfer_priv(itransfer); // Cancel polling if (status == LIBUSB_TRANSFER_CANCELLED) usbi_handle_transfer_cancellation(itransfer); else @@ -560,7 +562,7 @@ int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_N usbi_mutex_lock(&ctx->flying_transfers_lock); found = false; list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { - pollable_fd = windows_get_fd(transfer); + pollable_fd = backend_func.get_fd(transfer); if (pollable_fd->fd == fds[i].fd) { found = true; break; @@ -569,7 +571,7 @@ int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_N usbi_mutex_unlock(&ctx->flying_transfers_lock); if (found) { - windows_get_overlapped_result(transfer, pollable_fd, &io_result, &io_size); + backend_func.get_overlapped_result(transfer, pollable_fd, &io_result, &io_size); usbi_remove_pollfd(ctx, pollable_fd->fd); // let handle_callback free the event using the transfer wfd @@ -608,3 +610,8 @@ void windows_common_exit(void) windows_destroy_clock(); windows_exit_dlls(); } + +void win_nt_init(win_backend *backend) +{ + backend_func = *backend; +} diff --git a/Externals/libusb/libusb/os/windows_nt_common.h b/Externals/libusb/libusb/os/windows_nt_common.h index 9749e00181..22d5256aa5 100644 --- a/Externals/libusb/libusb/os/windows_nt_common.h +++ b/Externals/libusb/libusb/os/windows_nt_common.h @@ -50,10 +50,20 @@ void windows_common_exit(void); unsigned long htab_hash(const char *str); int windows_clock_gettime(int clk_id, struct timespec *tp); -void windows_clear_transfer_priv(struct usbi_transfer *itransfer); -int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size); -struct winfd *windows_get_fd(struct usbi_transfer *transfer); -void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size); +typedef void(*CLEAR_TRANSFER_PRIV)(struct usbi_transfer *itransfer); +typedef int(*COPY_TRANSFER_DATA)(struct usbi_transfer *itransfer, uint32_t io_size); +typedef struct winfd *(*GET_FD)(struct usbi_transfer *transfer); +typedef void(*GET_OVERLAPPED_RESULT)(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size); + +typedef struct win_backend +{ + CLEAR_TRANSFER_PRIV clear_transfer_priv; + COPY_TRANSFER_DATA copy_transfer_data; + GET_FD get_fd; + GET_OVERLAPPED_RESULT get_overlapped_result; +} win_backend; + +void win_nt_init(win_backend *backend); void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size); int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready); diff --git a/Externals/libusb/libusb/os/windows_usbdk.c b/Externals/libusb/libusb/os/windows_usbdk.c index 7cc5793872..a588e51e82 100644 --- a/Externals/libusb/libusb/os/windows_usbdk.c +++ b/Externals/libusb/libusb/os/windows_usbdk.c @@ -23,8 +23,6 @@ #include -#if defined(USE_USBDK) - #include #include #include @@ -66,6 +64,8 @@ typedef int32_t USBD_STATUS; #define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000) #endif +static void backend_init(void); + static int concurrent_usage = -1; struct usbdk_device_priv { @@ -201,6 +201,9 @@ static int usbdk_init(struct libusb_context *ctx) int r; if (++concurrent_usage == 0) { // First init? + + backend_init(); + r = load_usbdk_helper_dll(ctx); if (r) goto init_exit; @@ -533,7 +536,7 @@ static void usbdk_destroy_device(struct libusb_device *dev) usbdk_release_config_descriptors(p, p->info.DeviceDescriptor.bNumConfigurations); } -void windows_clear_transfer_priv(struct usbi_transfer *itransfer) +static void windows_clear_transfer_priv(struct usbi_transfer *itransfer) { struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); @@ -778,13 +781,13 @@ static int usbdk_cancel_transfer(struct usbi_transfer *itransfer) } } -int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) +static int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) { itransfer->transferred += io_size; return LIBUSB_TRANSFER_COMPLETED; } -struct winfd *windows_get_fd(struct usbi_transfer *transfer) +static struct winfd *windows_get_fd(struct usbi_transfer *transfer) { struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(transfer); return &transfer_priv->pollable_fd; @@ -809,7 +812,7 @@ static DWORD usbdk_translate_usbd_status(USBD_STATUS UsbdStatus) } } -void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size) +static void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size) { if (HasOverlappedIoCompletedSync(pollable_fd->overlapped) // Handle async requests that completed synchronously first || GetOverlappedResult(pollable_fd->handle, pollable_fd->overlapped, io_size, false)) { // Regular async overlapped @@ -902,4 +905,12 @@ const struct usbi_os_backend usbdk_backend = { sizeof(struct usbdk_transfer_priv), }; -#endif /* USE_USBDK */ +static void backend_init(void) +{ + win_backend backend; + backend.clear_transfer_priv = windows_clear_transfer_priv; + backend.copy_transfer_data = windows_copy_transfer_data; + backend.get_fd = windows_get_fd; + backend.get_overlapped_result = windows_get_overlapped_result; + win_nt_init(&backend); +} diff --git a/Externals/libusb/libusb/os/windows_winusb.c b/Externals/libusb/libusb/os/windows_winusb.c index d1d2749042..99e866e159 100644 --- a/Externals/libusb/libusb/os/windows_winusb.c +++ b/Externals/libusb/libusb/os/windows_winusb.c @@ -24,8 +24,6 @@ #include -#if !defined(USE_USBDK) - #include #include #include @@ -103,6 +101,7 @@ static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer) static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle); static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); +static void backend_init(void); // Global variables int windows_version = WINDOWS_UNDEFINED; @@ -805,6 +804,8 @@ static int windows_init(struct libusb_context *ctx) goto init_exit; } + backend_init(); + // We need a lock for proper auto-release usbi_mutex_init(&autoclaim_lock); @@ -1897,7 +1898,7 @@ static void windows_destroy_device(struct libusb_device *dev) windows_device_priv_release(dev); } -void windows_clear_transfer_priv(struct usbi_transfer *itransfer) +static void windows_clear_transfer_priv(struct usbi_transfer *itransfer) { struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); @@ -2017,20 +2018,20 @@ static int windows_cancel_transfer(struct usbi_transfer *itransfer) } } -int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) +static int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); return priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size); } -struct winfd *windows_get_fd(struct usbi_transfer *transfer) +static struct winfd *windows_get_fd(struct usbi_transfer *transfer) { struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(transfer); return &transfer_priv->pollable_fd; } -void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size) +static void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size) { if (HasOverlappedIoCompletedSync(pollable_fd->overlapped)) { *io_result = NO_ERROR; @@ -4285,4 +4286,12 @@ static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itran copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size); } -#endif /* !USE_USBDK */ +static void backend_init(void) +{ + win_backend backend; + backend.clear_transfer_priv = windows_clear_transfer_priv; + backend.copy_transfer_data = windows_copy_transfer_data; + backend.get_fd = windows_get_fd; + backend.get_overlapped_result = windows_get_overlapped_result; + win_nt_init(&backend); +} diff --git a/Externals/libusb/libusb_static_2013.vcxproj b/Externals/libusb/libusb_static_2013.vcxproj index 74397eb70d..5ae732700a 100644 --- a/Externals/libusb/libusb_static_2013.vcxproj +++ b/Externals/libusb/libusb_static_2013.vcxproj @@ -53,6 +53,7 @@ + @@ -66,6 +67,7 @@ + diff --git a/Externals/libusb/msvc/libusb_sources b/Externals/libusb/msvc/libusb_sources index 591d7f6136..c527ac7341 100644 --- a/Externals/libusb/msvc/libusb_sources +++ b/Externals/libusb/msvc/libusb_sources @@ -38,6 +38,7 @@ SOURCES=..\core.c \ ..\hotplug.c \ threads_windows.c \ poll_windows.c \ + windows_usbdk.c \ windows_winusb.c \ windows_usbdk.c \ windows_nt_common.c \