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
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 $@

View File

@ -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) {

View File

@ -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;

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, 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;
}

View File

@ -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);

View File

@ -23,8 +23,6 @@
#include <config.h>
#if defined(USE_USBDK)
#include <windows.h>
#include <cfgmgr32.h>
#include <stdio.h>
@ -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);
}

View File

@ -24,8 +24,6 @@
#include <config.h>
#if !defined(USE_USBDK)
#include <windows.h>
#include <setupapi.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_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);
}

View File

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

View File

@ -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 \