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 <dfleytma@...>
Signed-off-by: Sameeh Jubran <sameeh@...>
This commit is contained in:
Sameeh Jubran 2017-02-10 13:12:23 +01:00 committed by Léo Lam
parent 96e83b5d54
commit 2571eb16ff
9 changed files with 103 additions and 37 deletions

View File

@ -15,8 +15,8 @@ NETBSD_USB_SRC = os/netbsd_usb.c
SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h
WINDOWS_COMMON_SRC = os/windows_nt_common.h os/windows_nt_common.c \ 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 os/windows_common.h libusb-1.0.rc libusb-1.0.def
WINDOWS_USB_SRC = os/windows_winusb.h os/windows_winusb.c WINDOWS_USB_SRC = os/windows_winusb.h os/windows_winusb.c os/windows_usbdk.h \
WINDOWS_USBDK_SRC = os/windows_usbdk.h os/windows_usbdk.c os/windows_usbdk.c $(COMMON_WINDOWS_SRC)
WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \ 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 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 endif
if OS_WINDOWS if OS_WINDOWS
if USE_USBDK
OS_SRC = $(WINDOWS_USBDK_SRC) $(WINDOWS_COMMON_SRC)
else
OS_SRC = $(WINDOWS_USB_SRC) $(WINDOWS_COMMON_SRC) OS_SRC = $(WINDOWS_USB_SRC) $(WINDOWS_COMMON_SRC)
endif
.rc.lo: .rc.lo:
$(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@

View File

@ -53,13 +53,7 @@ const struct usbi_os_backend * const usbi_backend = &openbsd_backend;
#elif defined(OS_NETBSD) #elif defined(OS_NETBSD)
const struct usbi_os_backend * const usbi_backend = &netbsd_backend; const struct usbi_os_backend * const usbi_backend = &netbsd_backend;
#elif defined(OS_WINDOWS) #elif defined(OS_WINDOWS)
const struct usbi_os_backend * usbi_backend;
#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
#elif defined(OS_WINCE) #elif defined(OS_WINCE)
const struct usbi_os_backend * const usbi_backend = &wince_backend; const struct usbi_os_backend * const usbi_backend = &wince_backend;
#elif defined(OS_HAIKU) #elif defined(OS_HAIKU)
@ -629,6 +623,26 @@ static struct discovered_devs *discovered_devs_alloc(void)
return ret; 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) static void discovered_devs_free(struct discovered_devs *discdevs)
{ {
size_t i; size_t i;
@ -2067,6 +2081,19 @@ int API_EXPORTED libusb_init(libusb_context **context)
static int first_init = 1; static int first_init = 1;
int r = 0; 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); usbi_mutex_static_lock(&default_context_lock);
if (!timestamp_origin.tv_sec) { if (!timestamp_origin.tv_sec) {

View File

@ -1132,7 +1132,11 @@ struct usbi_os_backend {
size_t transfer_priv_size; 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; 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 linux_usbfs_backend;
extern const struct usbi_os_backend darwin_backend; extern const struct usbi_os_backend darwin_backend;

View File

@ -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, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM)); 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); 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) { switch (io_result) {
case NO_ERROR: case NO_ERROR:
status = windows_copy_transfer_data(itransfer, io_size); status = backend_func.copy_transfer_data(itransfer, io_size);
break; break;
case ERROR_GEN_FAILURE: case ERROR_GEN_FAILURE:
usbi_dbg("detected endpoint stall"); 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; status = LIBUSB_TRANSFER_TIMED_OUT;
break; break;
case ERROR_OPERATION_ABORTED: 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) if (istatus != LIBUSB_TRANSFER_COMPLETED)
usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus); 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; status = LIBUSB_TRANSFER_ERROR;
break; break;
} }
windows_clear_transfer_priv(itransfer); // Cancel polling backend_func.clear_transfer_priv(itransfer); // Cancel polling
if (status == LIBUSB_TRANSFER_CANCELLED) if (status == LIBUSB_TRANSFER_CANCELLED)
usbi_handle_transfer_cancellation(itransfer); usbi_handle_transfer_cancellation(itransfer);
else 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); usbi_mutex_lock(&ctx->flying_transfers_lock);
found = false; found = false;
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { 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) { if (pollable_fd->fd == fds[i].fd) {
found = true; found = true;
break; 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); usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (found) { 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); usbi_remove_pollfd(ctx, pollable_fd->fd);
// let handle_callback free the event using the transfer wfd // let handle_callback free the event using the transfer wfd
@ -608,3 +610,8 @@ void windows_common_exit(void)
windows_destroy_clock(); windows_destroy_clock();
windows_exit_dlls(); windows_exit_dlls();
} }
void win_nt_init(win_backend *backend)
{
backend_func = *backend;
}

View File

@ -50,10 +50,20 @@ void windows_common_exit(void);
unsigned long htab_hash(const char *str); unsigned long htab_hash(const char *str);
int windows_clock_gettime(int clk_id, struct timespec *tp); int windows_clock_gettime(int clk_id, struct timespec *tp);
void windows_clear_transfer_priv(struct usbi_transfer *itransfer); typedef void(*CLEAR_TRANSFER_PRIV)(struct usbi_transfer *itransfer);
int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size); typedef int(*COPY_TRANSFER_DATA)(struct usbi_transfer *itransfer, uint32_t io_size);
struct winfd *windows_get_fd(struct usbi_transfer *transfer); typedef struct winfd *(*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(*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); 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); int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);

View File

@ -23,8 +23,6 @@
#include <config.h> #include <config.h>
#if defined(USE_USBDK)
#include <windows.h> #include <windows.h>
#include <cfgmgr32.h> #include <cfgmgr32.h>
#include <stdio.h> #include <stdio.h>
@ -66,6 +64,8 @@ typedef int32_t USBD_STATUS;
#define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000) #define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000)
#endif #endif
static void backend_init(void);
static int concurrent_usage = -1; static int concurrent_usage = -1;
struct usbdk_device_priv { struct usbdk_device_priv {
@ -201,6 +201,9 @@ static int usbdk_init(struct libusb_context *ctx)
int r; int r;
if (++concurrent_usage == 0) { // First init? if (++concurrent_usage == 0) { // First init?
backend_init();
r = load_usbdk_helper_dll(ctx); r = load_usbdk_helper_dll(ctx);
if (r) if (r)
goto init_exit; 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); 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 usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(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; itransfer->transferred += io_size;
return LIBUSB_TRANSFER_COMPLETED; 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); struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(transfer);
return &transfer_priv->pollable_fd; 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 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 || 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), 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);
}

View File

@ -24,8 +24,6 @@
#include <config.h> #include <config.h>
#if !defined(USE_USBDK)
#include <windows.h> #include <windows.h>
#include <setupapi.h> #include <setupapi.h>
#include <ctype.h> #include <ctype.h>
@ -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_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 int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
static void backend_init(void);
// Global variables // Global variables
int windows_version = WINDOWS_UNDEFINED; int windows_version = WINDOWS_UNDEFINED;
@ -805,6 +804,8 @@ static int windows_init(struct libusb_context *ctx)
goto init_exit; goto init_exit;
} }
backend_init();
// We need a lock for proper auto-release // We need a lock for proper auto-release
usbi_mutex_init(&autoclaim_lock); usbi_mutex_init(&autoclaim_lock);
@ -1897,7 +1898,7 @@ static void windows_destroy_device(struct libusb_device *dev)
windows_device_priv_release(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); 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 libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
return priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size); 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); struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(transfer);
return &transfer_priv->pollable_fd; 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)) { if (HasOverlappedIoCompletedSync(pollable_fd->overlapped)) {
*io_result = NO_ERROR; *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); 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);
}

View File

@ -53,6 +53,7 @@
<ClCompile Include="libusb\os\threads_windows.c" /> <ClCompile Include="libusb\os\threads_windows.c" />
<ClCompile Include="libusb\os\windows_nt_common.c" /> <ClCompile Include="libusb\os\windows_nt_common.c" />
<ClCompile Include="libusb\os\windows_usbdk.c" /> <ClCompile Include="libusb\os\windows_usbdk.c" />
<ClCompile Include="libusb\os\windows_winusb.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="msvc\config.h" /> <ClInclude Include="msvc\config.h" />
@ -66,6 +67,7 @@
<ClInclude Include="libusb\os\windows_common.h" /> <ClInclude Include="libusb\os\windows_common.h" />
<ClInclude Include="libusb\os\windows_nt_common.h" /> <ClInclude Include="libusb\os\windows_nt_common.h" />
<ClInclude Include="libusb\os\windows_usbdk.h" /> <ClInclude Include="libusb\os\windows_usbdk.h" />
<ClInclude Include="libusb\os\windows_winusb.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -38,6 +38,7 @@ SOURCES=..\core.c \
..\hotplug.c \ ..\hotplug.c \
threads_windows.c \ threads_windows.c \
poll_windows.c \ poll_windows.c \
windows_usbdk.c \
windows_winusb.c \ windows_winusb.c \
windows_usbdk.c \ windows_usbdk.c \
windows_nt_common.c \ windows_nt_common.c \