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:
parent
96e83b5d54
commit
2571eb16ff
|
@ -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 $@
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue