mirror of
https://github.com/RPCS3/libusb.git
synced 2026-01-31 01:25:19 +01:00
Windows: Enable dynamic selection between WinUSB and UsbDk backends
This commit unifies the two Windows backends into a single project and enables the user to switch to the UsbDk backend, if available, using the libusb_set_option() function. All contexts will use the WinUSB backend by default for backwards compatibility. With this change, the UsbDk-specific projects are no longer required. Closes #309 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
This commit is contained in:
@@ -13,10 +13,12 @@ DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
|
||||
OPENBSD_USB_SRC = os/openbsd_usb.c
|
||||
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 = libusb-1.0.def libusb-1.0.rc \
|
||||
os/windows_common.h \
|
||||
os/windows_nt_common.h os/windows_nt_common.c \
|
||||
os/windows_nt_shared_types.h \
|
||||
os/windows_usbdk.h os/windows_usbdk.c \
|
||||
os/windows_winusb.h os/windows_winusb.c
|
||||
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
|
||||
@@ -25,8 +27,8 @@ EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
|
||||
$(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
|
||||
$(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
|
||||
$(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
|
||||
$(WINDOWS_COMMON_SRC) $(WINDOWS_USB_SRC) $(WINDOWS_USBDK_SRC) \
|
||||
$(WINCE_USB_SRC) $(HAIKU_USB_SRC) \
|
||||
$(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
|
||||
$(HAIKU_USB_SRC) \
|
||||
os/linux_udev.c os/linux_netlink.c
|
||||
|
||||
if OS_LINUX
|
||||
@@ -63,12 +65,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
|
||||
OS_SRC = $(WINDOWS_USB_SRC)
|
||||
|
||||
.rc.lo:
|
||||
$(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
|
||||
|
||||
@@ -2065,19 +2065,15 @@ int API_EXPORTED libusb_set_option(libusb_context *ctx,
|
||||
ctx->debug = (enum libusb_log_level)arg;
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* Handle all backend-specific options here */
|
||||
#if 0
|
||||
/* This code is compiled out until the first backend-specific option is
|
||||
* added to the library. When this time comes, remove the #if/#endif
|
||||
* lines and this comment, then replace the case statement with the
|
||||
* valid option name. */
|
||||
case LIBUSB_OPTION_<...>:
|
||||
case LIBUSB_OPTION_USE_USBDK:
|
||||
if (usbi_backend.set_option)
|
||||
r = usbi_backend.set_option(ctx, option, ap);
|
||||
else
|
||||
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
r = LIBUSB_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
@@ -2016,6 +2016,15 @@ enum libusb_option {
|
||||
* does nothing: you'll always get messages from all levels.
|
||||
*/
|
||||
LIBUSB_OPTION_LOG_LEVEL,
|
||||
|
||||
/** Use the UsbDk backend for a specific context, if available.
|
||||
*
|
||||
* This option should be set immediately after calling libusb_init(), otherwise
|
||||
* unspecified behavior may occur.
|
||||
*
|
||||
* Only valid on Windows.
|
||||
*/
|
||||
LIBUSB_OPTION_USE_USBDK,
|
||||
};
|
||||
|
||||
int LIBUSB_CALL libusb_set_option(libusb_context *ctx, enum libusb_option option, ...);
|
||||
|
||||
@@ -41,21 +41,6 @@
|
||||
|
||||
#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2)
|
||||
|
||||
/* Windows versions */
|
||||
enum windows_version {
|
||||
WINDOWS_CE = -2,
|
||||
WINDOWS_UNDEFINED = -1,
|
||||
WINDOWS_UNSUPPORTED = 0,
|
||||
WINDOWS_XP = 0x51,
|
||||
WINDOWS_2003 = 0x52, // Also XP x64
|
||||
WINDOWS_VISTA = 0x60,
|
||||
WINDOWS_7 = 0x61,
|
||||
WINDOWS_8 = 0x62,
|
||||
WINDOWS_8_1_OR_LATER = 0x63,
|
||||
WINDOWS_MAX
|
||||
};
|
||||
extern int windows_version;
|
||||
|
||||
#define MAX_FDS 256
|
||||
|
||||
#define POLLIN 0x0001 /* There is data to read */
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
// Global variables
|
||||
int errno = 0;
|
||||
int windows_version = WINDOWS_CE;
|
||||
static uint64_t hires_frequency, hires_ticks_to_ps;
|
||||
static HANDLE driver_handle = INVALID_HANDLE_VALUE;
|
||||
static int concurrent_usage = -1;
|
||||
@@ -110,7 +109,7 @@ static int translate_driver_error(DWORD error)
|
||||
}
|
||||
}
|
||||
|
||||
static int init_dllimports(void)
|
||||
static BOOL init_dllimports(void)
|
||||
{
|
||||
DLL_GET_HANDLE(ceusbkwrapper);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE);
|
||||
@@ -136,7 +135,7 @@ static int init_dllimports(void)
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE);
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void exit_dllimports(void)
|
||||
@@ -188,7 +187,7 @@ static int wince_init(struct libusb_context *ctx)
|
||||
// exit calls. If init is called more than exit, we will not exit properly
|
||||
if ( ++concurrent_usage == 0 ) { // First init?
|
||||
// Load DLL imports
|
||||
if (init_dllimports() != LIBUSB_SUCCESS) {
|
||||
if (!init_dllimports()) {
|
||||
usbi_err(ctx, "could not resolve DLL functions");
|
||||
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
goto init_exit;
|
||||
|
||||
@@ -68,21 +68,23 @@
|
||||
/*
|
||||
* Macros for handling DLL themselves
|
||||
*/
|
||||
#define DLL_HANDLE_NAME(name) __dll_##name##_handle
|
||||
|
||||
#define DLL_DECLARE_HANDLE(name) \
|
||||
static HMODULE __dll_##name##_handle = NULL
|
||||
static HMODULE DLL_HANDLE_NAME(name) = NULL
|
||||
|
||||
#define DLL_GET_HANDLE(name) \
|
||||
do { \
|
||||
__dll_##name##_handle = DLL_LOAD_LIBRARY(name); \
|
||||
if (!__dll_##name##_handle) \
|
||||
return LIBUSB_ERROR_NOT_FOUND; \
|
||||
DLL_HANDLE_NAME(name) = DLL_LOAD_LIBRARY(name); \
|
||||
if (!DLL_HANDLE_NAME(name)) \
|
||||
return FALSE; \
|
||||
} while (0)
|
||||
|
||||
#define DLL_FREE_HANDLE(name) \
|
||||
do { \
|
||||
if (__dll_##name##_handle) { \
|
||||
FreeLibrary(__dll_##name##_handle); \
|
||||
__dll_##name##_handle = NULL; \
|
||||
if (DLL_HANDLE_NAME(name)) { \
|
||||
FreeLibrary(DLL_HANDLE_NAME(name)); \
|
||||
DLL_HANDLE_NAME(name) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -90,9 +92,11 @@
|
||||
/*
|
||||
* Macros for handling functions within a DLL
|
||||
*/
|
||||
#define DLL_FUNC_NAME(name) __dll_##name##_func_t
|
||||
|
||||
#define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args) \
|
||||
typedef ret (api * __dll_##name##_func_t)args; \
|
||||
static __dll_##name##_func_t prefixname = NULL
|
||||
typedef ret (api * DLL_FUNC_NAME(name))args; \
|
||||
static DLL_FUNC_NAME(name) prefixname = NULL
|
||||
|
||||
#define DLL_DECLARE_FUNC(api, ret, name, args) \
|
||||
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
|
||||
@@ -101,21 +105,21 @@
|
||||
|
||||
#define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
|
||||
do { \
|
||||
HMODULE h = __dll_##dll##_handle; \
|
||||
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
|
||||
HMODULE h = DLL_HANDLE_NAME(dll); \
|
||||
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
|
||||
DLL_STRINGIFY(name)); \
|
||||
if (prefixname) \
|
||||
break; \
|
||||
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
|
||||
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
|
||||
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
|
||||
if (prefixname) \
|
||||
break; \
|
||||
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
|
||||
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
|
||||
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
|
||||
if (prefixname) \
|
||||
break; \
|
||||
if (ret_on_failure) \
|
||||
return LIBUSB_ERROR_NOT_FOUND; \
|
||||
return FALSE; \
|
||||
} while (0)
|
||||
|
||||
#define DLL_LOAD_FUNC(dll, name, ret_on_failure) \
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
|
||||
// Public
|
||||
BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED);
|
||||
enum windows_version windows_version = WINDOWS_UNDEFINED;
|
||||
|
||||
// Global variables for init/exit
|
||||
static unsigned int init_count = 0;
|
||||
static bool usbdk_available = false;
|
||||
|
||||
// Global variables for clock_gettime mechanism
|
||||
static uint64_t hires_ticks_to_ps;
|
||||
@@ -53,6 +58,11 @@ struct timer_request {
|
||||
static HANDLE timer_thread = NULL;
|
||||
static DWORD timer_thread_id = 0;
|
||||
|
||||
/* Kernel32 dependencies */
|
||||
DLL_DECLARE_HANDLE(Kernel32);
|
||||
/* This call is only available from XP SP2 */
|
||||
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
|
||||
|
||||
/* User32 dependencies */
|
||||
DLL_DECLARE_HANDLE(User32);
|
||||
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
|
||||
@@ -114,6 +124,11 @@ const char *windows_error_str(DWORD error_code)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline struct windows_context_priv *_context_priv(struct libusb_context *ctx)
|
||||
{
|
||||
return (struct windows_context_priv *)ctx->os_priv;
|
||||
}
|
||||
|
||||
/* Hash table functions - modified From glibc 2.3.2:
|
||||
[Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
|
||||
[Knuth] The Art of Computer Programming, part 3 (6.4) */
|
||||
@@ -259,15 +274,22 @@ out_unlock:
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int windows_init_dlls(void)
|
||||
/*
|
||||
* Make a transfer complete synchronously
|
||||
*/
|
||||
void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
|
||||
{
|
||||
HMODULE hKernel32 = GetModuleHandleA("KERNEL32");
|
||||
|
||||
if (hKernel32 == NULL)
|
||||
return LIBUSB_ERROR_NOT_FOUND;
|
||||
overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
|
||||
overlapped->InternalHigh = size;
|
||||
SetEvent(overlapped->hEvent);
|
||||
}
|
||||
|
||||
static BOOL windows_init_dlls(void)
|
||||
{
|
||||
DLL_GET_HANDLE(Kernel32);
|
||||
DLL_LOAD_FUNC_PREFIXED(Kernel32, p, IsWow64Process, FALSE);
|
||||
pCancelIoEx = (BOOL (WINAPI *)(HANDLE, LPOVERLAPPED))
|
||||
GetProcAddress(hKernel32, "CancelIoEx");
|
||||
GetProcAddress(DLL_HANDLE_NAME(Kernel32), "CancelIoEx");
|
||||
usbi_dbg("Will use CancelIo%s for I/O cancellation", pCancelIoEx ? "Ex" : "");
|
||||
|
||||
DLL_GET_HANDLE(User32);
|
||||
@@ -275,28 +297,23 @@ static int windows_init_dlls(void)
|
||||
DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
|
||||
DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void windows_exit_dlls(void)
|
||||
{
|
||||
DLL_FREE_HANDLE(Kernel32);
|
||||
DLL_FREE_HANDLE(User32);
|
||||
}
|
||||
|
||||
static bool windows_init_clock(struct libusb_context *ctx)
|
||||
{
|
||||
DWORD_PTR affinity, dummy;
|
||||
HANDLE event = NULL;
|
||||
HANDLE event;
|
||||
LARGE_INTEGER li_frequency;
|
||||
int i;
|
||||
|
||||
if (QueryPerformanceFrequency(&li_frequency)) {
|
||||
// Load DLL imports
|
||||
if (windows_init_dlls() != LIBUSB_SUCCESS) {
|
||||
usbi_err(ctx, "could not resolve DLL functions");
|
||||
return false;
|
||||
}
|
||||
|
||||
// The hires frequency can go as high as 4 GHz, so we'll use a conversion
|
||||
// to picoseconds to compute the tv_nsecs part in clock_gettime
|
||||
hires_frequency = li_frequency.QuadPart;
|
||||
@@ -352,7 +369,7 @@ static bool windows_init_clock(struct libusb_context *ctx)
|
||||
return true;
|
||||
}
|
||||
|
||||
void windows_destroy_clock(void)
|
||||
static void windows_destroy_clock(void)
|
||||
{
|
||||
if (timer_thread) {
|
||||
// actually the signal to quit the thread.
|
||||
@@ -369,6 +386,110 @@ void windows_destroy_clock(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Windows version detection */
|
||||
static BOOL is_x64(void)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
|
||||
// Detect if we're running a 32 or 64 bit system
|
||||
if (sizeof(uintptr_t) < 8) {
|
||||
if (pIsWow64Process != NULL)
|
||||
pIsWow64Process(GetCurrentProcess(), &ret);
|
||||
} else {
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void get_windows_version(void)
|
||||
{
|
||||
OSVERSIONINFOEXA vi, vi2;
|
||||
const char *arch, *w = NULL;
|
||||
unsigned major, minor, version;
|
||||
ULONGLONG major_equal, minor_equal;
|
||||
BOOL ws;
|
||||
|
||||
windows_version = WINDOWS_UNDEFINED;
|
||||
|
||||
memset(&vi, 0, sizeof(vi));
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
|
||||
memset(&vi, 0, sizeof(vi));
|
||||
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
if (!GetVersionExA((OSVERSIONINFOA *)&vi))
|
||||
return;
|
||||
}
|
||||
|
||||
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
return;
|
||||
|
||||
if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
|
||||
// Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
|
||||
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
|
||||
|
||||
major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
||||
for (major = vi.dwMajorVersion; major <= 9; major++) {
|
||||
memset(&vi2, 0, sizeof(vi2));
|
||||
vi2.dwOSVersionInfoSize = sizeof(vi2);
|
||||
vi2.dwMajorVersion = major;
|
||||
if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
|
||||
continue;
|
||||
|
||||
if (vi.dwMajorVersion < major) {
|
||||
vi.dwMajorVersion = major;
|
||||
vi.dwMinorVersion = 0;
|
||||
}
|
||||
|
||||
minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
|
||||
for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
|
||||
memset(&vi2, 0, sizeof(vi2));
|
||||
vi2.dwOSVersionInfoSize = sizeof(vi2);
|
||||
vi2.dwMinorVersion = minor;
|
||||
if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
|
||||
continue;
|
||||
|
||||
vi.dwMinorVersion = minor;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
|
||||
return;
|
||||
|
||||
ws = (vi.wProductType <= VER_NT_WORKSTATION);
|
||||
version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
|
||||
switch (version) {
|
||||
case 0x50: windows_version = WINDOWS_2000; w = "2000"; break;
|
||||
case 0x51: windows_version = WINDOWS_XP; w = "XP"; break;
|
||||
case 0x52: windows_version = WINDOWS_2003; w = "2003"; break;
|
||||
case 0x60: windows_version = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break;
|
||||
case 0x61: windows_version = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break;
|
||||
case 0x62: windows_version = WINDOWS_8; w = (ws ? "8" : "2012"); break;
|
||||
case 0x63: windows_version = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break;
|
||||
case 0x64: windows_version = WINDOWS_10; w = (ws ? "10" : "2016"); break;
|
||||
default:
|
||||
if (version < 0x50) {
|
||||
return;
|
||||
} else {
|
||||
windows_version = WINDOWS_11_OR_LATER;
|
||||
w = "11 or later";
|
||||
}
|
||||
}
|
||||
|
||||
arch = is_x64() ? "64-bit" : "32-bit";
|
||||
|
||||
if (vi.wServicePackMinor)
|
||||
usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
|
||||
else if (vi.wServicePackMajor)
|
||||
usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
|
||||
else
|
||||
usbi_dbg("Windows %s %s", w, arch);
|
||||
}
|
||||
|
||||
/*
|
||||
* Monotonic and real time functions
|
||||
*/
|
||||
@@ -413,7 +534,378 @@ static unsigned __stdcall windows_clock_gettime_threaded(void *param)
|
||||
}
|
||||
}
|
||||
|
||||
int windows_clock_gettime(int clk_id, struct timespec *tp)
|
||||
static void windows_transfer_callback(const struct windows_backend *backend,
|
||||
struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
|
||||
{
|
||||
int status, istatus;
|
||||
|
||||
usbi_dbg("handling I/O completion with errcode %u, size %u", (unsigned int)io_result, (unsigned int)io_size);
|
||||
|
||||
switch (io_result) {
|
||||
case NO_ERROR:
|
||||
status = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
|
||||
break;
|
||||
case ERROR_GEN_FAILURE:
|
||||
usbi_dbg("detected endpoint stall");
|
||||
status = LIBUSB_TRANSFER_STALL;
|
||||
break;
|
||||
case ERROR_SEM_TIMEOUT:
|
||||
usbi_dbg("detected semaphore timeout");
|
||||
status = LIBUSB_TRANSFER_TIMED_OUT;
|
||||
break;
|
||||
case ERROR_OPERATION_ABORTED:
|
||||
istatus = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
|
||||
if (istatus != LIBUSB_TRANSFER_COMPLETED)
|
||||
usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
|
||||
|
||||
usbi_dbg("detected operation aborted");
|
||||
status = LIBUSB_TRANSFER_CANCELLED;
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
usbi_dbg("detected device removed");
|
||||
status = LIBUSB_TRANSFER_NO_DEVICE;
|
||||
break;
|
||||
default:
|
||||
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", (unsigned int)io_result, windows_error_str(io_result));
|
||||
status = LIBUSB_TRANSFER_ERROR;
|
||||
break;
|
||||
}
|
||||
backend->clear_transfer_priv(itransfer); // Cancel polling
|
||||
if (status == LIBUSB_TRANSFER_CANCELLED)
|
||||
usbi_handle_transfer_cancellation(itransfer);
|
||||
else
|
||||
usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
|
||||
}
|
||||
|
||||
static void windows_handle_callback(const struct windows_backend *backend,
|
||||
struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
|
||||
{
|
||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
|
||||
switch (transfer->type) {
|
||||
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
||||
case LIBUSB_TRANSFER_TYPE_BULK:
|
||||
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
||||
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
||||
windows_transfer_callback(backend, itransfer, io_result, io_size);
|
||||
break;
|
||||
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
||||
usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
|
||||
break;
|
||||
default:
|
||||
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
||||
}
|
||||
}
|
||||
|
||||
static int windows_init(struct libusb_context *ctx)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(ctx);
|
||||
HANDLE semaphore;
|
||||
char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
|
||||
int r = LIBUSB_ERROR_OTHER;
|
||||
bool winusb_backend_init = false;
|
||||
|
||||
sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
|
||||
semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
|
||||
if (semaphore == NULL) {
|
||||
usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
// A successful wait brings our semaphore count to 0 (unsignaled)
|
||||
// => any concurent wait stalls until the semaphore's release
|
||||
if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
|
||||
usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
|
||||
CloseHandle(semaphore);
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
// NB: concurrent usage supposes that init calls are equally balanced with
|
||||
// exit calls. If init is called more than exit, we will not exit properly
|
||||
if (++init_count == 1) { // First init?
|
||||
// Load DLL imports
|
||||
if (!windows_init_dlls()) {
|
||||
usbi_err(ctx, "could not resolve DLL functions");
|
||||
goto init_exit;
|
||||
}
|
||||
|
||||
get_windows_version();
|
||||
|
||||
if (windows_version == WINDOWS_UNDEFINED) {
|
||||
usbi_err(ctx, "failed to detect Windows version");
|
||||
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
goto init_exit;
|
||||
}
|
||||
|
||||
if (!windows_init_clock(ctx))
|
||||
goto init_exit;
|
||||
|
||||
if (!htab_create(ctx))
|
||||
goto init_exit;
|
||||
|
||||
r = winusb_backend.init(ctx);
|
||||
if (r != LIBUSB_SUCCESS)
|
||||
goto init_exit;
|
||||
winusb_backend_init = true;
|
||||
|
||||
r = usbdk_backend.init(ctx);
|
||||
if (r == LIBUSB_SUCCESS) {
|
||||
usbi_dbg("UsbDk backend is available");
|
||||
usbdk_available = true;
|
||||
} else {
|
||||
usbi_info(ctx, "UsbDk backend is not available");
|
||||
// Do not report this as an error
|
||||
r = LIBUSB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// By default, new contexts will use the WinUSB backend
|
||||
priv->backend = &winusb_backend;
|
||||
|
||||
r = LIBUSB_SUCCESS;
|
||||
|
||||
init_exit: // Holds semaphore here
|
||||
if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
|
||||
if (winusb_backend_init)
|
||||
winusb_backend.exit(ctx);
|
||||
htab_destroy();
|
||||
windows_destroy_clock();
|
||||
windows_exit_dlls();
|
||||
--init_count;
|
||||
}
|
||||
|
||||
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
|
||||
CloseHandle(semaphore);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void windows_exit(struct libusb_context *ctx)
|
||||
{
|
||||
HANDLE semaphore;
|
||||
char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
|
||||
UNUSED(ctx);
|
||||
|
||||
sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
|
||||
semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
|
||||
if (semaphore == NULL)
|
||||
return;
|
||||
|
||||
// A successful wait brings our semaphore count to 0 (unsignaled)
|
||||
// => any concurent wait stalls until the semaphore release
|
||||
if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
|
||||
CloseHandle(semaphore);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only works if exits and inits are balanced exactly
|
||||
if (--init_count == 0) { // Last exit
|
||||
if (usbdk_available) {
|
||||
usbdk_backend.exit(ctx);
|
||||
usbdk_available = false;
|
||||
}
|
||||
winusb_backend.exit(ctx);
|
||||
htab_destroy();
|
||||
windows_destroy_clock();
|
||||
windows_exit_dlls();
|
||||
}
|
||||
|
||||
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
|
||||
CloseHandle(semaphore);
|
||||
}
|
||||
|
||||
static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(ctx);
|
||||
|
||||
UNUSED(ap);
|
||||
|
||||
switch (option) {
|
||||
case LIBUSB_OPTION_USE_USBDK:
|
||||
if (usbdk_available) {
|
||||
usbi_dbg("switching context %p to use UsbDk backend", ctx);
|
||||
priv->backend = &usbdk_backend;
|
||||
} else {
|
||||
usbi_err(ctx, "UsbDk backend not available");
|
||||
return LIBUSB_ERROR_NOT_FOUND;
|
||||
}
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
return LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(ctx);
|
||||
return priv->backend->get_device_list(ctx, discdevs);
|
||||
}
|
||||
|
||||
static int windows_open(struct libusb_device_handle *dev_handle)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
return priv->backend->open(dev_handle);
|
||||
}
|
||||
|
||||
static void windows_close(struct libusb_device_handle *dev_handle)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
priv->backend->close(dev_handle);
|
||||
}
|
||||
|
||||
static int windows_get_device_descriptor(struct libusb_device *dev,
|
||||
unsigned char *buffer, int *host_endian)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
|
||||
*host_endian = 0;
|
||||
return priv->backend->get_device_descriptor(dev, buffer);
|
||||
}
|
||||
|
||||
static int windows_get_active_config_descriptor(struct libusb_device *dev,
|
||||
unsigned char *buffer, size_t len, int *host_endian)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
|
||||
*host_endian = 0;
|
||||
return priv->backend->get_active_config_descriptor(dev, buffer, len);
|
||||
}
|
||||
|
||||
static int windows_get_config_descriptor(struct libusb_device *dev,
|
||||
uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
|
||||
*host_endian = 0;
|
||||
return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
|
||||
}
|
||||
|
||||
static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
|
||||
uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
|
||||
*host_endian = 0;
|
||||
return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
|
||||
}
|
||||
|
||||
static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
return priv->backend->get_configuration(dev_handle, config);
|
||||
}
|
||||
|
||||
static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
return priv->backend->set_configuration(dev_handle, config);
|
||||
}
|
||||
|
||||
static int windows_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
return priv->backend->claim_interface(dev_handle, interface_number);
|
||||
}
|
||||
|
||||
static int windows_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
return priv->backend->release_interface(dev_handle, interface_number);
|
||||
}
|
||||
|
||||
static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
|
||||
int interface_number, int altsetting)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
|
||||
}
|
||||
|
||||
static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
return priv->backend->clear_halt(dev_handle, endpoint);
|
||||
}
|
||||
|
||||
static int windows_reset_device(struct libusb_device_handle *dev_handle)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
|
||||
return priv->backend->reset_device(dev_handle);
|
||||
}
|
||||
|
||||
static void windows_destroy_device(struct libusb_device *dev)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
|
||||
priv->backend->destroy_device(dev);
|
||||
}
|
||||
|
||||
static int windows_submit_transfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
|
||||
return priv->backend->submit_transfer(itransfer);
|
||||
}
|
||||
|
||||
static int windows_cancel_transfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
|
||||
return priv->backend->cancel_transfer(itransfer);
|
||||
}
|
||||
|
||||
static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
|
||||
priv->backend->clear_transfer_priv(itransfer);
|
||||
}
|
||||
|
||||
static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
|
||||
{
|
||||
struct windows_context_priv *priv = _context_priv(ctx);
|
||||
struct usbi_transfer *itransfer;
|
||||
DWORD io_size, io_result;
|
||||
POLL_NFDS_TYPE i;
|
||||
bool found;
|
||||
int transfer_fd;
|
||||
int r = LIBUSB_SUCCESS;
|
||||
|
||||
usbi_mutex_lock(&ctx->open_devs_lock);
|
||||
for (i = 0; i < nfds && num_ready > 0; i++) {
|
||||
|
||||
usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
|
||||
|
||||
if (!fds[i].revents)
|
||||
continue;
|
||||
|
||||
num_ready--;
|
||||
|
||||
// Because a Windows OVERLAPPED is used for poll emulation,
|
||||
// a pollable fd is created and stored with each transfer
|
||||
found = false;
|
||||
transfer_fd = -1;
|
||||
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
||||
list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
||||
transfer_fd = priv->backend->get_transfer_fd(itransfer);
|
||||
if (transfer_fd == fds[i].fd) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
||||
|
||||
if (found) {
|
||||
priv->backend->get_overlapped_result(itransfer, &io_result, &io_size);
|
||||
|
||||
usbi_remove_pollfd(ctx, transfer_fd);
|
||||
|
||||
// let handle_callback free the event using the transfer wfd
|
||||
// If you don't use the transfer wfd, you run a risk of trying to free a
|
||||
// newly allocated wfd that took the place of the one from the transfer.
|
||||
windows_handle_callback(priv->backend, itransfer, io_result, io_size);
|
||||
} else {
|
||||
usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd);
|
||||
r = LIBUSB_ERROR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int windows_clock_gettime(int clk_id, struct timespec *tp)
|
||||
{
|
||||
struct timer_request request;
|
||||
#if !defined(_MSC_VER) || (_MSC_VER < 1900)
|
||||
@@ -472,147 +964,44 @@ int windows_clock_gettime(int clk_id, struct timespec *tp)
|
||||
}
|
||||
}
|
||||
|
||||
static void windows_transfer_callback(struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
|
||||
{
|
||||
int status, istatus;
|
||||
|
||||
usbi_dbg("handling I/O completion with errcode %u, size %u", (unsigned int)io_result, (unsigned int)io_size);
|
||||
|
||||
switch (io_result) {
|
||||
case NO_ERROR:
|
||||
status = windows_copy_transfer_data(itransfer, (uint32_t)io_size);
|
||||
break;
|
||||
case ERROR_GEN_FAILURE:
|
||||
usbi_dbg("detected endpoint stall");
|
||||
status = LIBUSB_TRANSFER_STALL;
|
||||
break;
|
||||
case ERROR_SEM_TIMEOUT:
|
||||
usbi_dbg("detected semaphore timeout");
|
||||
status = LIBUSB_TRANSFER_TIMED_OUT;
|
||||
break;
|
||||
case ERROR_OPERATION_ABORTED:
|
||||
istatus = windows_copy_transfer_data(itransfer, (uint32_t)io_size);
|
||||
if (istatus != LIBUSB_TRANSFER_COMPLETED)
|
||||
usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
|
||||
|
||||
usbi_dbg("detected operation aborted");
|
||||
status = LIBUSB_TRANSFER_CANCELLED;
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
usbi_dbg("detected device removed");
|
||||
status = LIBUSB_TRANSFER_NO_DEVICE;
|
||||
break;
|
||||
default:
|
||||
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", (unsigned int)io_result, windows_error_str(io_result));
|
||||
status = LIBUSB_TRANSFER_ERROR;
|
||||
break;
|
||||
}
|
||||
windows_clear_transfer_priv(itransfer); // Cancel polling
|
||||
if (status == LIBUSB_TRANSFER_CANCELLED)
|
||||
usbi_handle_transfer_cancellation(itransfer);
|
||||
else
|
||||
usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a transfer complete synchronously
|
||||
*/
|
||||
void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
|
||||
{
|
||||
overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
|
||||
overlapped->InternalHigh = size;
|
||||
SetEvent(overlapped->hEvent);
|
||||
}
|
||||
|
||||
void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
|
||||
{
|
||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
|
||||
switch (transfer->type) {
|
||||
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
||||
case LIBUSB_TRANSFER_TYPE_BULK:
|
||||
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
||||
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
||||
windows_transfer_callback(itransfer, io_result, io_size);
|
||||
break;
|
||||
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
||||
usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
|
||||
break;
|
||||
default:
|
||||
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
||||
}
|
||||
}
|
||||
|
||||
int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
|
||||
{
|
||||
struct usbi_transfer *itransfer;
|
||||
DWORD io_size, io_result;
|
||||
POLL_NFDS_TYPE i;
|
||||
bool found;
|
||||
int transfer_fd = -1;
|
||||
int r = LIBUSB_SUCCESS;
|
||||
|
||||
usbi_mutex_lock(&ctx->open_devs_lock);
|
||||
for (i = 0; i < nfds && num_ready > 0; i++) {
|
||||
|
||||
usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
|
||||
|
||||
if (!fds[i].revents)
|
||||
continue;
|
||||
|
||||
num_ready--;
|
||||
|
||||
// Because a Windows OVERLAPPED is used for poll emulation,
|
||||
// a pollable fd is created and stored with each transfer
|
||||
found = false;
|
||||
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
||||
list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
||||
transfer_fd = windows_get_transfer_fd(itransfer);
|
||||
if (transfer_fd == fds[i].fd) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
||||
|
||||
if (found) {
|
||||
windows_get_overlapped_result(itransfer, &io_result, &io_size);
|
||||
|
||||
usbi_remove_pollfd(ctx, transfer_fd);
|
||||
|
||||
// let handle_callback free the event using the transfer wfd
|
||||
// If you don't use the transfer wfd, you run a risk of trying to free a
|
||||
// newly allocated wfd that took the place of the one from the transfer.
|
||||
windows_handle_callback(itransfer, io_result, io_size);
|
||||
} else {
|
||||
usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
|
||||
r = LIBUSB_ERROR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int windows_common_init(struct libusb_context *ctx)
|
||||
{
|
||||
if (!windows_init_clock(ctx))
|
||||
goto error_roll_back;
|
||||
|
||||
if (!htab_create(ctx))
|
||||
goto error_roll_back;
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
|
||||
error_roll_back:
|
||||
windows_common_exit();
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
void windows_common_exit(void)
|
||||
{
|
||||
htab_destroy();
|
||||
windows_destroy_clock();
|
||||
windows_exit_dlls();
|
||||
}
|
||||
// NB: MSVC6 does not support named initializers.
|
||||
const struct usbi_os_backend usbi_backend = {
|
||||
"Windows",
|
||||
USBI_CAP_HAS_HID_ACCESS,
|
||||
windows_init,
|
||||
windows_exit,
|
||||
windows_set_option,
|
||||
windows_get_device_list,
|
||||
NULL, /* hotplug_poll */
|
||||
windows_open,
|
||||
windows_close,
|
||||
windows_get_device_descriptor,
|
||||
windows_get_active_config_descriptor,
|
||||
windows_get_config_descriptor,
|
||||
windows_get_config_descriptor_by_value,
|
||||
windows_get_configuration,
|
||||
windows_set_configuration,
|
||||
windows_claim_interface,
|
||||
windows_release_interface,
|
||||
windows_set_interface_altsetting,
|
||||
windows_clear_halt,
|
||||
windows_reset_device,
|
||||
NULL, /* alloc_streams */
|
||||
NULL, /* free_streams */
|
||||
NULL, /* dev_mem_alloc */
|
||||
NULL, /* dev_mem_free */
|
||||
NULL, /* kernel_driver_active */
|
||||
NULL, /* detach_kernel_driver */
|
||||
NULL, /* attach_kernel_driver */
|
||||
windows_destroy_device,
|
||||
windows_submit_transfer,
|
||||
windows_cancel_transfer,
|
||||
windows_clear_transfer_priv,
|
||||
windows_handle_events,
|
||||
NULL, /* handle_transfer_completion */
|
||||
windows_clock_gettime,
|
||||
sizeof(struct windows_context_priv),
|
||||
sizeof(union windows_device_priv),
|
||||
sizeof(union windows_device_handle_priv),
|
||||
sizeof(union windows_transfer_priv),
|
||||
};
|
||||
|
||||
@@ -26,45 +26,84 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// Missing from MinGW
|
||||
#if !defined(FACILITY_SETUPAPI)
|
||||
#define FACILITY_SETUPAPI 15
|
||||
#endif
|
||||
#include "windows_nt_shared_types.h"
|
||||
|
||||
#include <pshpack1.h>
|
||||
/* Windows versions */
|
||||
enum windows_version {
|
||||
WINDOWS_UNDEFINED,
|
||||
WINDOWS_2000,
|
||||
WINDOWS_XP,
|
||||
WINDOWS_2003, // Also XP x64
|
||||
WINDOWS_VISTA,
|
||||
WINDOWS_7,
|
||||
WINDOWS_8,
|
||||
WINDOWS_8_1,
|
||||
WINDOWS_10,
|
||||
WINDOWS_11_OR_LATER
|
||||
};
|
||||
|
||||
typedef struct USB_CONFIGURATION_DESCRIPTOR {
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
USHORT wTotalLength;
|
||||
UCHAR bNumInterfaces;
|
||||
UCHAR bConfigurationValue;
|
||||
UCHAR iConfiguration;
|
||||
UCHAR bmAttributes;
|
||||
UCHAR MaxPower;
|
||||
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
|
||||
extern enum windows_version windows_version;
|
||||
|
||||
/* This call is only available from Vista */
|
||||
extern BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED);
|
||||
|
||||
int windows_common_init(struct libusb_context *ctx);
|
||||
void windows_common_exit(void);
|
||||
struct windows_backend {
|
||||
int (*init)(struct libusb_context *ctx);
|
||||
void (*exit)(struct libusb_context *ctx);
|
||||
int (*get_device_list)(struct libusb_context *ctx,
|
||||
struct discovered_devs **discdevs);
|
||||
int (*open)(struct libusb_device_handle *dev_handle);
|
||||
void (*close)(struct libusb_device_handle *dev_handle);
|
||||
int (*get_device_descriptor)(struct libusb_device *device, unsigned char *buffer);
|
||||
int (*get_active_config_descriptor)(struct libusb_device *device,
|
||||
unsigned char *buffer, size_t len);
|
||||
int (*get_config_descriptor)(struct libusb_device *device,
|
||||
uint8_t config_index, unsigned char *buffer, size_t len);
|
||||
int (*get_config_descriptor_by_value)(struct libusb_device *device,
|
||||
uint8_t bConfigurationValue, unsigned char **buffer);
|
||||
int (*get_configuration)(struct libusb_device_handle *dev_handle, int *config);
|
||||
int (*set_configuration)(struct libusb_device_handle *dev_handle, int config);
|
||||
int (*claim_interface)(struct libusb_device_handle *dev_handle, int interface_number);
|
||||
int (*release_interface)(struct libusb_device_handle *dev_handle, int interface_number);
|
||||
int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle,
|
||||
int interface_number, int altsetting);
|
||||
int (*clear_halt)(struct libusb_device_handle *dev_handle,
|
||||
unsigned char endpoint);
|
||||
int (*reset_device)(struct libusb_device_handle *dev_handle);
|
||||
void (*destroy_device)(struct libusb_device *dev);
|
||||
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);
|
||||
};
|
||||
|
||||
struct windows_context_priv {
|
||||
const struct windows_backend *backend;
|
||||
};
|
||||
|
||||
union windows_device_priv {
|
||||
struct usbdk_device_priv usbdk_priv;
|
||||
struct winusb_device_priv winusb_priv;
|
||||
};
|
||||
|
||||
union windows_device_handle_priv {
|
||||
struct usbdk_device_handle_priv usbdk_priv;
|
||||
struct winusb_device_handle_priv winusb_priv;
|
||||
};
|
||||
|
||||
union windows_transfer_priv {
|
||||
struct usbdk_transfer_priv usbdk_priv;
|
||||
struct winusb_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);
|
||||
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);
|
||||
int windows_get_transfer_fd(struct usbi_transfer *itransfer);
|
||||
void windows_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_result, DWORD *io_size);
|
||||
|
||||
void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG 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);
|
||||
|
||||
#if defined(ENABLE_LOGGING)
|
||||
const char *windows_error_str(DWORD error_code);
|
||||
|
||||
137
libusb/os/windows_nt_shared_types.h
Normal file
137
libusb/os/windows_nt_shared_types.h
Normal file
@@ -0,0 +1,137 @@
|
||||
#pragma once
|
||||
|
||||
#include "windows_common.h"
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
typedef struct USB_DEVICE_DESCRIPTOR {
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
USHORT bcdUSB;
|
||||
UCHAR bDeviceClass;
|
||||
UCHAR bDeviceSubClass;
|
||||
UCHAR bDeviceProtocol;
|
||||
UCHAR bMaxPacketSize0;
|
||||
USHORT idVendor;
|
||||
USHORT idProduct;
|
||||
USHORT bcdDevice;
|
||||
UCHAR iManufacturer;
|
||||
UCHAR iProduct;
|
||||
UCHAR iSerialNumber;
|
||||
UCHAR bNumConfigurations;
|
||||
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
|
||||
|
||||
typedef struct USB_CONFIGURATION_DESCRIPTOR {
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
USHORT wTotalLength;
|
||||
UCHAR bNumInterfaces;
|
||||
UCHAR bConfigurationValue;
|
||||
UCHAR iConfiguration;
|
||||
UCHAR bmAttributes;
|
||||
UCHAR MaxPower;
|
||||
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#define MAX_DEVICE_ID_LEN 200
|
||||
|
||||
typedef struct USB_DK_DEVICE_ID {
|
||||
WCHAR DeviceID[MAX_DEVICE_ID_LEN];
|
||||
WCHAR InstanceID[MAX_DEVICE_ID_LEN];
|
||||
} USB_DK_DEVICE_ID, *PUSB_DK_DEVICE_ID;
|
||||
|
||||
typedef struct USB_DK_DEVICE_INFO {
|
||||
USB_DK_DEVICE_ID ID;
|
||||
ULONG64 FilterID;
|
||||
ULONG64 Port;
|
||||
ULONG64 Speed;
|
||||
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
|
||||
} USB_DK_DEVICE_INFO, *PUSB_DK_DEVICE_INFO;
|
||||
|
||||
typedef struct USB_DK_ISO_TRANSFER_RESULT {
|
||||
ULONG64 ActualLength;
|
||||
ULONG64 TransferResult;
|
||||
} USB_DK_ISO_TRANSFER_RESULT, *PUSB_DK_ISO_TRANSFER_RESULT;
|
||||
|
||||
typedef struct USB_DK_GEN_TRANSFER_RESULT {
|
||||
ULONG64 BytesTransferred;
|
||||
ULONG64 UsbdStatus; // USBD_STATUS code
|
||||
} USB_DK_GEN_TRANSFER_RESULT, *PUSB_DK_GEN_TRANSFER_RESULT;
|
||||
|
||||
typedef struct USB_DK_TRANSFER_RESULT {
|
||||
USB_DK_GEN_TRANSFER_RESULT GenResult;
|
||||
PVOID64 IsochronousResultsArray; // array of USB_DK_ISO_TRANSFER_RESULT
|
||||
} USB_DK_TRANSFER_RESULT, *PUSB_DK_TRANSFER_RESULT;
|
||||
|
||||
typedef struct USB_DK_TRANSFER_REQUEST {
|
||||
ULONG64 EndpointAddress;
|
||||
PVOID64 Buffer;
|
||||
ULONG64 BufferLength;
|
||||
ULONG64 TransferType;
|
||||
ULONG64 IsochronousPacketsArraySize;
|
||||
PVOID64 IsochronousPacketsArray;
|
||||
USB_DK_TRANSFER_RESULT Result;
|
||||
} USB_DK_TRANSFER_REQUEST, *PUSB_DK_TRANSFER_REQUEST;
|
||||
|
||||
struct usbdk_device_priv {
|
||||
USB_DK_DEVICE_INFO info;
|
||||
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptors;
|
||||
HANDLE redirector_handle;
|
||||
HANDLE system_handle;
|
||||
uint8_t active_configuration;
|
||||
};
|
||||
|
||||
struct winusb_device_priv {
|
||||
bool initialized;
|
||||
bool root_hub;
|
||||
uint8_t active_config;
|
||||
uint8_t depth; // distance to HCD
|
||||
const struct windows_usb_api_backend *apib;
|
||||
char *dev_id;
|
||||
char *path; // device interface path
|
||||
int sub_api; // for WinUSB-like APIs
|
||||
struct {
|
||||
char *path; // each interface needs a device interface path,
|
||||
const struct windows_usb_api_backend *apib; // an API backend (multiple drivers support),
|
||||
int sub_api;
|
||||
int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
|
||||
uint8_t *endpoint;
|
||||
bool restricted_functionality; // indicates if the interface functionality is restricted
|
||||
// by Windows (eg. HID keyboards or mice cannot do R/W)
|
||||
} usb_interface[USB_MAXINTERFACES];
|
||||
struct hid_device_priv *hid;
|
||||
USB_DEVICE_DESCRIPTOR dev_descriptor;
|
||||
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptor; // list of pointers to the cached config descriptors
|
||||
};
|
||||
|
||||
struct usbdk_device_handle_priv {
|
||||
// Not currently used
|
||||
char dummy;
|
||||
};
|
||||
|
||||
struct winusb_device_handle_priv {
|
||||
int active_interface;
|
||||
struct {
|
||||
HANDLE dev_handle; // WinUSB needs an extra handle for the file
|
||||
HANDLE api_handle; // used by the API to communicate with the device
|
||||
} interface_handle[USB_MAXINTERFACES];
|
||||
int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
@@ -23,19 +23,12 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined(USE_USBDK)
|
||||
|
||||
#include <windows.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libusbi.h"
|
||||
#include "windows_common.h"
|
||||
#include "windows_nt_common.h"
|
||||
|
||||
typedef CONST WCHAR *PCWCHAR;
|
||||
#define wcsncpy_s wcsncpy
|
||||
|
||||
#include "windows_usbdk.h"
|
||||
|
||||
#if !defined(STATUS_SUCCESS)
|
||||
@@ -63,24 +56,6 @@ typedef LONG USBD_STATUS;
|
||||
#define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000)
|
||||
#endif
|
||||
|
||||
static int concurrent_usage = -1;
|
||||
|
||||
struct usbdk_device_priv {
|
||||
USB_DK_DEVICE_INFO info;
|
||||
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptors;
|
||||
HANDLE redirector_handle;
|
||||
HANDLE system_handle;
|
||||
uint8_t active_configuration;
|
||||
};
|
||||
|
||||
struct usbdk_transfer_priv {
|
||||
USB_DK_TRANSFER_REQUEST request;
|
||||
struct winfd pollable_fd;
|
||||
HANDLE system_handle;
|
||||
PULONG64 IsochronousPacketsArray;
|
||||
PUSB_DK_ISO_TRANSFER_RESULT IsochronousResultsArray;
|
||||
};
|
||||
|
||||
static inline struct usbdk_device_priv *_usbdk_device_priv(struct libusb_device *dev)
|
||||
{
|
||||
return (struct usbdk_device_priv *)dev->os_priv;
|
||||
@@ -114,7 +89,7 @@ static FARPROC get_usbdk_proc_addr(struct libusb_context *ctx, LPCSTR api_name)
|
||||
FARPROC api_ptr = GetProcAddress(usbdk_helper.module, api_name);
|
||||
|
||||
if (api_ptr == NULL)
|
||||
usbi_err(ctx, "UsbDkHelper API %s not found, error %d", api_name, GetLastError());
|
||||
usbi_err(ctx, "UsbDkHelper API %s not found: %s", api_name, windows_error_str(0));
|
||||
|
||||
return api_ptr;
|
||||
}
|
||||
@@ -131,7 +106,7 @@ static int load_usbdk_helper_dll(struct libusb_context *ctx)
|
||||
{
|
||||
usbdk_helper.module = LoadLibraryA("UsbDkHelper");
|
||||
if (usbdk_helper.module == NULL) {
|
||||
usbi_err(ctx, "Failed to load UsbDkHelper.dll, error %d", GetLastError());
|
||||
usbi_err(ctx, "Failed to load UsbDkHelper.dll: %s", windows_error_str(0));
|
||||
return LIBUSB_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -197,30 +172,33 @@ error_unload:
|
||||
|
||||
static int usbdk_init(struct libusb_context *ctx)
|
||||
{
|
||||
int r;
|
||||
SC_HANDLE managerHandle;
|
||||
SC_HANDLE serviceHandle;
|
||||
|
||||
if (++concurrent_usage == 0) { // First init?
|
||||
r = load_usbdk_helper_dll(ctx);
|
||||
if (r)
|
||||
goto init_exit;
|
||||
|
||||
r = windows_common_init(ctx);
|
||||
if (r)
|
||||
goto init_exit;
|
||||
}
|
||||
// At this stage, either we went through full init successfully, or didn't need to
|
||||
r = LIBUSB_SUCCESS;
|
||||
|
||||
init_exit:
|
||||
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
|
||||
windows_common_exit();
|
||||
unload_usbdk_helper_dll();
|
||||
managerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
|
||||
if (managerHandle == NULL) {
|
||||
usbi_warn(ctx, "failed to open service control manager: %s", windows_error_str(0));
|
||||
return LIBUSB_ERROR_OTHER;
|
||||
}
|
||||
|
||||
if (r != LIBUSB_SUCCESS)
|
||||
--concurrent_usage; // Not expected to call libusb_exit if we failed.
|
||||
serviceHandle = OpenServiceA(managerHandle, "UsbDk", GENERIC_READ);
|
||||
CloseServiceHandle(managerHandle);
|
||||
|
||||
return r;
|
||||
if (serviceHandle == NULL) {
|
||||
if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
|
||||
usbi_warn(ctx, "failed to open UsbDk service: %s", windows_error_str(0));
|
||||
return LIBUSB_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
CloseServiceHandle(serviceHandle);
|
||||
|
||||
return load_usbdk_helper_dll(ctx);
|
||||
}
|
||||
|
||||
static void usbdk_exit(struct libusb_context *ctx)
|
||||
{
|
||||
UNUSED(ctx);
|
||||
unload_usbdk_helper_dll();
|
||||
}
|
||||
|
||||
static int usbdk_get_session_id_for_device(struct libusb_context *ctx,
|
||||
@@ -296,7 +274,7 @@ static void usbdk_device_init(libusb_device *dev, PUSB_DK_DEVICE_INFO info)
|
||||
dev->device_address = (uint8_t)(info->Port + 1);
|
||||
|
||||
dev->num_configurations = info->DeviceDescriptor.bNumConfigurations;
|
||||
dev->device_descriptor = info->DeviceDescriptor;
|
||||
memcpy(&dev->device_descriptor, &info->DeviceDescriptor, LIBUSB_DT_DEVICE_SIZE);
|
||||
|
||||
switch (info->Speed) {
|
||||
case LowSpeed:
|
||||
@@ -326,7 +304,7 @@ static int usbdk_get_device_list(struct libusb_context *ctx, struct discovered_d
|
||||
ULONG dev_number;
|
||||
PUSB_DK_DEVICE_INFO devices;
|
||||
|
||||
if(!usbdk_helper.GetDevicesList(&devices, &dev_number))
|
||||
if (!usbdk_helper.GetDevicesList(&devices, &dev_number))
|
||||
return LIBUSB_ERROR_OTHER;
|
||||
|
||||
for (i = 0; i < dev_number; i++) {
|
||||
@@ -367,26 +345,16 @@ func_exit:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void usbdk_exit(struct libusb_context *ctx)
|
||||
{
|
||||
UNUSED(ctx);
|
||||
if (--concurrent_usage < 0) {
|
||||
windows_common_exit();
|
||||
unload_usbdk_helper_dll();
|
||||
}
|
||||
}
|
||||
|
||||
static int usbdk_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
|
||||
static int usbdk_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer)
|
||||
{
|
||||
struct usbdk_device_priv *priv = _usbdk_device_priv(dev);
|
||||
|
||||
memcpy(buffer, &priv->info.DeviceDescriptor, DEVICE_DESC_LENGTH);
|
||||
*host_endian = 0;
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
|
||||
static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len)
|
||||
{
|
||||
struct usbdk_device_priv *priv = _usbdk_device_priv(dev);
|
||||
PUSB_CONFIGURATION_DESCRIPTOR config_header;
|
||||
@@ -399,15 +367,13 @@ static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config
|
||||
|
||||
size = min(config_header->wTotalLength, len);
|
||||
memcpy(buffer, config_header, size);
|
||||
*host_endian = 0;
|
||||
|
||||
return (int)size;
|
||||
}
|
||||
|
||||
static inline int usbdk_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
|
||||
static inline int usbdk_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len)
|
||||
{
|
||||
return usbdk_get_config_descriptor(dev, _usbdk_device_priv(dev)->active_configuration,
|
||||
buffer, len, host_endian);
|
||||
buffer, len);
|
||||
}
|
||||
|
||||
static int usbdk_open(struct libusb_device_handle *dev_handle)
|
||||
@@ -508,7 +474,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 usbdk_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);
|
||||
@@ -678,7 +644,7 @@ static int usbdk_do_submit_transfer(struct usbi_transfer *itransfer,
|
||||
r = transfer_fn(itransfer);
|
||||
if (r != LIBUSB_SUCCESS) {
|
||||
usbi_remove_pollfd(ctx, wfd.fd);
|
||||
windows_clear_transfer_priv(itransfer);
|
||||
usbdk_clear_transfer_priv(itransfer);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -758,13 +724,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 usbdk_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size)
|
||||
{
|
||||
itransfer->transferred += io_size;
|
||||
return LIBUSB_TRANSFER_COMPLETED;
|
||||
}
|
||||
|
||||
int windows_get_transfer_fd(struct usbi_transfer *itransfer)
|
||||
static int usbdk_get_transfer_fd(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
|
||||
return transfer_priv->pollable_fd.fd;
|
||||
@@ -785,7 +751,7 @@ static DWORD usbdk_translate_usbd_status(USBD_STATUS UsbdStatus)
|
||||
}
|
||||
}
|
||||
|
||||
void windows_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_result, DWORD *io_size)
|
||||
static void usbdk_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_result, DWORD *io_size)
|
||||
{
|
||||
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
|
||||
struct winfd *pollable_fd = &transfer_priv->pollable_fd;
|
||||
@@ -821,57 +787,28 @@ void windows_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_re
|
||||
}
|
||||
}
|
||||
|
||||
const struct usbi_os_backend usbi_backend = {
|
||||
"Windows",
|
||||
USBI_CAP_HAS_HID_ACCESS,
|
||||
const struct windows_backend usbdk_backend = {
|
||||
usbdk_init,
|
||||
usbdk_exit,
|
||||
NULL, // set_option()
|
||||
|
||||
usbdk_get_device_list,
|
||||
NULL,
|
||||
usbdk_open,
|
||||
usbdk_close,
|
||||
|
||||
usbdk_get_device_descriptor,
|
||||
usbdk_get_active_config_descriptor,
|
||||
usbdk_get_config_descriptor,
|
||||
NULL,
|
||||
|
||||
NULL,//usbdk_get_config_descriptor_by_value,
|
||||
usbdk_get_configuration,
|
||||
usbdk_set_configuration,
|
||||
usbdk_claim_interface,
|
||||
usbdk_release_interface,
|
||||
|
||||
usbdk_set_interface_altsetting,
|
||||
usbdk_clear_halt,
|
||||
usbdk_reset_device,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL, // dev_mem_alloc()
|
||||
NULL, // dev_mem_free()
|
||||
|
||||
NULL, // kernel_driver_active()
|
||||
NULL, // detach_kernel_driver()
|
||||
NULL, // attach_kernel_driver()
|
||||
|
||||
usbdk_destroy_device,
|
||||
|
||||
usbdk_submit_transfer,
|
||||
usbdk_cancel_transfer,
|
||||
windows_clear_transfer_priv,
|
||||
|
||||
windows_handle_events,
|
||||
NULL,
|
||||
|
||||
windows_clock_gettime,
|
||||
|
||||
0,
|
||||
sizeof(struct usbdk_device_priv),
|
||||
0,
|
||||
sizeof(struct usbdk_transfer_priv),
|
||||
usbdk_clear_transfer_priv,
|
||||
usbdk_copy_transfer_data,
|
||||
usbdk_get_transfer_fd,
|
||||
usbdk_get_overlapped_result,
|
||||
};
|
||||
|
||||
#endif /* USE_USBDK */
|
||||
|
||||
@@ -23,56 +23,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct tag_USB_DK_DEVICE_ID {
|
||||
WCHAR DeviceID[MAX_DEVICE_ID_LEN];
|
||||
WCHAR InstanceID[MAX_DEVICE_ID_LEN];
|
||||
} USB_DK_DEVICE_ID, *PUSB_DK_DEVICE_ID;
|
||||
#include "windows_nt_common.h"
|
||||
|
||||
static inline void UsbDkFillIDStruct(USB_DK_DEVICE_ID *ID, PCWCHAR DeviceID, PCWCHAR InstanceID)
|
||||
static inline void UsbDkFillIDStruct(USB_DK_DEVICE_ID *ID, const WCHAR *DeviceID, const WCHAR *InstanceID)
|
||||
{
|
||||
wcsncpy_s(ID->DeviceID, DeviceID, MAX_DEVICE_ID_LEN);
|
||||
wcsncpy_s(ID->InstanceID, InstanceID, MAX_DEVICE_ID_LEN);
|
||||
wcsncpy(ID->DeviceID, DeviceID, MAX_DEVICE_ID_LEN);
|
||||
wcsncpy(ID->InstanceID, InstanceID, MAX_DEVICE_ID_LEN);
|
||||
}
|
||||
|
||||
typedef struct tag_USB_DK_DEVICE_INFO {
|
||||
USB_DK_DEVICE_ID ID;
|
||||
ULONG64 FilterID;
|
||||
ULONG64 Port;
|
||||
ULONG64 Speed;
|
||||
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
|
||||
} USB_DK_DEVICE_INFO, *PUSB_DK_DEVICE_INFO;
|
||||
|
||||
typedef struct tag_USB_DK_CONFIG_DESCRIPTOR_REQUEST {
|
||||
typedef struct USB_DK_CONFIG_DESCRIPTOR_REQUEST {
|
||||
USB_DK_DEVICE_ID ID;
|
||||
ULONG64 Index;
|
||||
} USB_DK_CONFIG_DESCRIPTOR_REQUEST, *PUSB_DK_CONFIG_DESCRIPTOR_REQUEST;
|
||||
|
||||
typedef struct tag_USB_DK_ISO_TRANSFER_RESULT {
|
||||
ULONG64 ActualLength;
|
||||
ULONG64 TransferResult;
|
||||
} USB_DK_ISO_TRANSFER_RESULT, *PUSB_DK_ISO_TRANSFER_RESULT;
|
||||
|
||||
typedef struct tag_USB_DK_GEN_TRANSFER_RESULT {
|
||||
ULONG64 BytesTransferred;
|
||||
ULONG64 UsbdStatus; // USBD_STATUS code
|
||||
} USB_DK_GEN_TRANSFER_RESULT, *PUSB_DK_GEN_TRANSFER_RESULT;
|
||||
|
||||
typedef struct tag_USB_DK_TRANSFER_RESULT {
|
||||
USB_DK_GEN_TRANSFER_RESULT GenResult;
|
||||
PVOID64 IsochronousResultsArray; // array of USB_DK_ISO_TRANSFER_RESULT
|
||||
} USB_DK_TRANSFER_RESULT, *PUSB_DK_TRANSFER_RESULT;
|
||||
|
||||
typedef struct tag_USB_DK_TRANSFER_REQUEST {
|
||||
ULONG64 EndpointAddress;
|
||||
PVOID64 Buffer;
|
||||
ULONG64 BufferLength;
|
||||
ULONG64 TransferType;
|
||||
ULONG64 IsochronousPacketsArraySize;
|
||||
PVOID64 IsochronousPacketsArray;
|
||||
|
||||
USB_DK_TRANSFER_RESULT Result;
|
||||
} USB_DK_TRANSFER_REQUEST, *PUSB_DK_TRANSFER_REQUEST;
|
||||
|
||||
typedef enum {
|
||||
TransferFailure = 0,
|
||||
TransferSuccess,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -195,37 +195,14 @@ struct hid_device_priv {
|
||||
uint8_t string_index[3]; // man, prod, ser
|
||||
};
|
||||
|
||||
struct windows_device_priv {
|
||||
bool initialized;
|
||||
bool root_hub;
|
||||
uint8_t active_config;
|
||||
uint8_t depth;
|
||||
const struct windows_usb_api_backend *apib;
|
||||
char *dev_id;
|
||||
char *path; // device interface path
|
||||
int sub_api; // for WinUSB-like APIs
|
||||
struct {
|
||||
char *path; // each interface needs a device interface path,
|
||||
const struct windows_usb_api_backend *apib; // an API backend (multiple drivers support),
|
||||
int sub_api;
|
||||
int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
|
||||
uint8_t *endpoint;
|
||||
bool restricted_functionality; // indicates if the interface functionality is restricted
|
||||
// by Windows (eg. HID keyboards or mice cannot do R/W)
|
||||
} usb_interface[USB_MAXINTERFACES];
|
||||
struct hid_device_priv *hid;
|
||||
USB_DEVICE_DESCRIPTOR dev_descriptor;
|
||||
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptor; // list of pointers to the cached config descriptors
|
||||
};
|
||||
|
||||
static inline struct windows_device_priv *_device_priv(struct libusb_device *dev)
|
||||
static inline struct winusb_device_priv *_device_priv(struct libusb_device *dev)
|
||||
{
|
||||
return (struct windows_device_priv *)dev->os_priv;
|
||||
return (struct winusb_device_priv *)dev->os_priv;
|
||||
}
|
||||
|
||||
static inline struct windows_device_priv *windows_device_priv_init(struct libusb_device *dev)
|
||||
static inline struct winusb_device_priv *winusb_device_priv_init(struct libusb_device *dev)
|
||||
{
|
||||
struct windows_device_priv *p = _device_priv(dev);
|
||||
struct winusb_device_priv *p = _device_priv(dev);
|
||||
int i;
|
||||
|
||||
p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
|
||||
@@ -238,9 +215,9 @@ static inline struct windows_device_priv *windows_device_priv_init(struct libusb
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void windows_device_priv_release(struct libusb_device *dev)
|
||||
static inline void winusb_device_priv_release(struct libusb_device *dev)
|
||||
{
|
||||
struct windows_device_priv *p = _device_priv(dev);
|
||||
struct winusb_device_priv *p = _device_priv(dev);
|
||||
int i;
|
||||
|
||||
free(p->dev_id);
|
||||
@@ -257,33 +234,12 @@ static inline void windows_device_priv_release(struct libusb_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
struct interface_handle_t {
|
||||
HANDLE dev_handle; // WinUSB needs an extra handle for the file
|
||||
HANDLE api_handle; // used by the API to communicate with the device
|
||||
};
|
||||
|
||||
struct windows_device_handle_priv {
|
||||
int active_interface;
|
||||
struct interface_handle_t interface_handle[USB_MAXINTERFACES];
|
||||
int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
|
||||
};
|
||||
|
||||
static inline struct windows_device_handle_priv *_device_handle_priv(
|
||||
static inline struct winusb_device_handle_priv *_device_handle_priv(
|
||||
struct libusb_device_handle *handle)
|
||||
{
|
||||
return (struct windows_device_handle_priv *)handle->os_priv;
|
||||
return (struct winusb_device_handle_priv *)handle->os_priv;
|
||||
}
|
||||
|
||||
// used for async polling functions
|
||||
struct windows_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;
|
||||
};
|
||||
|
||||
// used to match a device driver (including filter drivers) against a supported API
|
||||
struct driver_lookup {
|
||||
char list[MAX_KEY_LENGTH + 1]; // REG_MULTI_SZ list of services (driver) names
|
||||
@@ -315,11 +271,6 @@ DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
|
||||
DLL_DECLARE_HANDLE(OLE32);
|
||||
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, IIDFromString, (LPCOLESTR, LPIID));
|
||||
|
||||
/* Kernel32 dependencies */
|
||||
DLL_DECLARE_HANDLE(Kernel32);
|
||||
/* This call is only available from XP SP2 */
|
||||
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
|
||||
|
||||
/* SetupAPI dependencies */
|
||||
DLL_DECLARE_HANDLE(SetupAPI);
|
||||
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (LPCGUID, PCSTR, HWND, DWORD));
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define LIBUSB_NANO 11274
|
||||
#define LIBUSB_NANO 11275
|
||||
|
||||
@@ -377,6 +377,10 @@
|
||||
RelativePath="..\libusb\os\windows_nt_common.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_usbdk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_winusb.c"
|
||||
>
|
||||
@@ -427,6 +431,14 @@
|
||||
RelativePath="..\libusb\os\windows_nt_common.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_nt_shared_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_usbdk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_winusb.h"
|
||||
>
|
||||
|
||||
@@ -147,6 +147,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -160,6 +161,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -38,6 +38,12 @@
|
||||
<ClCompile Include="..\libusb\os\threads_windows.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_nt_common.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_usbdk.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_winusb.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -61,12 +67,27 @@
|
||||
<ClInclude Include="..\libusb\os\threads_windows.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h">
|
||||
<ClInclude Include="..\libusb\version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\version_nano.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\libusb\libusb-1.0.def">
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -164,6 +165,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
<ClCompile Include="..\libusb\descriptor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\hotplug.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\io.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -35,10 +38,13 @@
|
||||
<ClCompile Include="..\libusb\os\threads_windows.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_winusb.c">
|
||||
<ClCompile Include="..\libusb\os\windows_nt_common.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\hotplug.c">
|
||||
<ClCompile Include="..\libusb\os\windows_usbdk.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_winusb.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -46,6 +52,9 @@
|
||||
<ClInclude Include=".\config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\hotplug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\libusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -58,16 +67,25 @@
|
||||
<ClInclude Include="..\libusb\os\threads_windows.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\version_nano.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\hotplug.h">
|
||||
<ClInclude Include="..\libusb\os\windows_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -164,6 +165,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -164,6 +165,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -164,6 +165,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -32,13 +32,13 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib
|
||||
|
||||
SOURCES=..\core.c \
|
||||
..\descriptor.c \
|
||||
..\hotplug.c \
|
||||
..\io.c \
|
||||
..\strerror.c \
|
||||
..\sync.c \
|
||||
..\hotplug.c \
|
||||
threads_windows.c \
|
||||
poll_windows.c \
|
||||
windows_winusb.c \
|
||||
windows_usbdk.c \
|
||||
windows_nt_common.c \
|
||||
windows_usbdk.c \
|
||||
windows_winusb.c \
|
||||
..\libusb-1.0.rc
|
||||
|
||||
@@ -317,6 +317,10 @@
|
||||
RelativePath="..\libusb\os\windows_nt_common.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_usbdk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_winusb.c"
|
||||
>
|
||||
@@ -367,6 +371,14 @@
|
||||
RelativePath="..\libusb\os\windows_nt_common.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_nt_shared_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_usbdk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libusb\os\windows_winusb.h"
|
||||
>
|
||||
|
||||
@@ -137,6 +137,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -150,6 +151,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
<ClCompile Include="..\libusb\descriptor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\hotplug.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\io.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -32,10 +35,13 @@
|
||||
<ClCompile Include="..\libusb\os\threads_windows.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_winusb.c">
|
||||
<ClCompile Include="..\libusb\os\windows_nt_common.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\hotplug.c">
|
||||
<ClCompile Include="..\libusb\os\windows_usbdk.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_winusb.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -43,6 +49,9 @@
|
||||
<ClInclude Include=".\config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\hotplug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\libusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -55,19 +64,25 @@
|
||||
<ClInclude Include="..\libusb\os\threads_windows.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_common.h">
|
||||
<ClInclude Include="..\libusb\version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\version_nano.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\version.h">
|
||||
<ClInclude Include="..\libusb\os\windows_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\hotplug.h">
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -141,6 +141,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -154,6 +155,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
<ClCompile Include="..\libusb\descriptor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\hotplug.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\io.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -32,10 +35,13 @@
|
||||
<ClCompile Include="..\libusb\os\threads_windows.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_winusb.c">
|
||||
<ClCompile Include="..\libusb\os\windows_nt_common.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\hotplug.c">
|
||||
<ClCompile Include="..\libusb\os\windows_usbdk.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libusb\os\windows_winusb.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -43,6 +49,9 @@
|
||||
<ClInclude Include=".\config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\hotplug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\libusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -55,19 +64,25 @@
|
||||
<ClInclude Include="..\libusb\os\threads_windows.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_common.h">
|
||||
<ClInclude Include="..\libusb\version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\version_nano.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\version.h">
|
||||
<ClInclude Include="..\libusb\os\windows_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\hotplug.h">
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -141,6 +141,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -154,6 +155,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -158,6 +159,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
<ClCompile Include="..\libusb\sync.c" />
|
||||
<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>
|
||||
@@ -158,6 +159,8 @@
|
||||
<ClInclude Include="..\libusb\version_nano.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="..\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
Reference in New Issue
Block a user