Windows/WinCE: Improve the run-time dynamic linking scheme

Prior to this commit, the Windows and WinCE backends had a specific
shortcoming when loading DLLs, that being that once loaded they were
never unloaded. This commit improves this by providing a means to
unload the DLLs during cleanup.

Note that the use of GetModuleHandle() has been removed in favor of
the exclusive use of LoadLibrary(). This was done to ensure that a
reference count is taken against the loaded DLL, which guards against
some other part of the application unloading the DLL that libusb
is currently using.

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
This commit is contained in:
Chris Dickens
2016-01-28 00:29:58 -08:00
parent 452e7bd683
commit 57cfbb444e
7 changed files with 245 additions and 159 deletions
+34 -23
View File
@@ -109,33 +109,40 @@ static int translate_driver_error(DWORD error)
}
}
static int init_dllimports()
static int init_dllimports(void)
{
DLL_LOAD(ceusbkwrapper.dll, UkwOpenDriver, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceList, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwReleaseDeviceList, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceAddress, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceDescriptor, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetConfigDescriptor, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwCloseDriver, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwCancelTransfer, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwIssueControlTransfer, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwClaimInterface, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwReleaseInterface, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwSetInterfaceAlternateSetting, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwClearHaltHost, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwClearHaltDevice, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetConfig, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwSetConfig, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwResetDevice, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwKernelDriverActive, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwAttachKernelDriver, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwDetachKernelDriver, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwIssueBulkTransfer, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwIsPipeHalted, TRUE);
DLL_GET_HANDLE(ceusbkwrapper);
DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceList, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseDeviceList, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceAddress, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceDescriptor, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfigDescriptor, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwCloseDriver, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwCancelTransfer, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueControlTransfer, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwClaimInterface, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseInterface, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwSetInterfaceAlternateSetting, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltHost, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltDevice, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfig, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwSetConfig, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwResetDevice, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwKernelDriverActive, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwAttachKernelDriver, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwDetachKernelDriver, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE);
return LIBUSB_SUCCESS;
}
static void exit_dllimports(void)
{
DLL_FREE_HANDLE(ceusbkwrapper);
}
static int init_device(
struct libusb_device *dev, UKW_DEVICE drv_dev,
unsigned char bus_addr, unsigned char dev_addr)
@@ -215,6 +222,9 @@ static int wince_init(struct libusb_context *ctx)
init_exit: // Holds semaphore here.
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
exit_dllimports();
exit_polling();
if (driver_handle != INVALID_HANDLE_VALUE) {
UkwCloseDriver(driver_handle);
driver_handle = INVALID_HANDLE_VALUE;
@@ -248,6 +258,7 @@ static void wince_exit(void)
// Only works if exits and inits are balanced exactly
if (--concurrent_usage < 0) { // Last exit
exit_dllimports();
exit_polling();
if (driver_handle != INVALID_HANDLE_VALUE) {
+23 -22
View File
@@ -87,28 +87,29 @@ typedef struct {
* to specify the currently active configuration for the device. */
#define UKW_ACTIVE_CONFIGURATION -1
DLL_DECLARE(WINAPI, HANDLE, UkwOpenDriver, ());
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, void, UkwCloseDriver, (HANDLE));
DLL_DECLARE(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
DLL_DECLARE(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
DLL_DECLARE(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL));
DLL_DECLARE_HANDLE(ceusbkwrapper);
DLL_DECLARE_FUNC(WINAPI, HANDLE, UkwOpenDriver, ());
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
DLL_DECLARE_FUNC(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
DLL_DECLARE_FUNC(WINAPI, void, UkwCloseDriver, (HANDLE));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL));
// Used to determine if an endpoint status really is halted on a failed transfer.
#define STATUS_HALT_FLAG 0x1
+60 -35
View File
@@ -62,45 +62,70 @@
/*
* API macros - from libusb-win32 1.x
* API macros - leveraged from libusb-win32 1.x
*/
#define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \
typedef ret (api * __dll_##name##_t)args; \
static __dll_##name##_t prefixname = NULL
#ifndef _WIN32_WCE
#define DLL_STRINGIFY(dll) #dll
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandleA(DLL_STRINGIFY(dll))
#define DLL_LOAD_LIBRARY(dll) LoadLibraryA(DLL_STRINGIFY(dll))
#define DLL_STRINGIFY(s) #s
#define DLL_LOAD_LIBRARY(name) LoadLibraryA(DLL_STRINGIFY(name))
#else
#define DLL_STRINGIFY(dll) L#dll
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandle(DLL_STRINGIFY(dll))
#define DLL_LOAD_LIBRARY(dll) LoadLibrary(DLL_STRINGIFY(dll))
#define DLL_STRINGIFY(s) L#s
#define DLL_LOAD_LIBRARY(name) LoadLibrary(DLL_STRINGIFY(name))
#endif
#define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = DLL_GET_MODULE_HANDLE(dll); \
if (!h) \
h = DLL_LOAD_LIBRARY(dll); \
if (!h) { \
if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
else { break; } \
} \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
if (prefixname) break; \
if(ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \
/*
* Macros for handling DLL themselves
*/
#define DLL_DECLARE_HANDLE(name) \
static HMODULE __dll_##name##_handle = NULL
#define DLL_GET_HANDLE(name) \
do { \
__dll_##name##_handle = DLL_LOAD_LIBRARY(name); \
if (!__dll_##name##_handle) \
return LIBUSB_ERROR_OTHER; \
} while (0)
#define DLL_FREE_HANDLE(name) \
do { \
if (__dll_##name##_handle) { \
FreeLibrary(__dll_##name##_handle); \
__dll_##name##_handle = NULL; \
} \
} while(0)
#define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args)
#define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure)
#define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args)
#define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
/*
* Macros for handling functions within a DLL
*/
#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
#define DLL_DECLARE_FUNC(api, ret, name, args) \
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
#define DLL_DECLARE_FUNC_PREFIXED(api, ret, prefix, name, args) \
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefix##name, name, args)
#define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = __dll_##dll##_handle; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
DLL_STRINGIFY(name)); \
if (prefixname) \
break; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
if (prefixname) \
break; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
if (prefixname) \
break; \
if (ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \
} while(0)
#define DLL_LOAD_FUNC(dll, name, ret_on_failure) \
DLL_LOAD_FUNC_PREFIXNAME(dll, name, name, ret_on_failure)
#define DLL_LOAD_FUNC_PREFIXED(dll, prefix, name, ret_on_failure) \
DLL_LOAD_FUNC_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
+14 -6
View File
@@ -54,9 +54,10 @@ static HANDLE timer_thread = NULL;
static DWORD timer_thread_id = 0;
/* User32 dependencies */
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM));
DLL_DECLARE_HANDLE(User32);
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));
static unsigned __stdcall windows_clock_gettime_threaded(void *param);
@@ -282,13 +283,19 @@ unsigned long htab_hash(const char *str)
static int windows_init_dlls(void)
{
DLL_LOAD_PREFIXED(User32.dll, p, GetMessageA, TRUE);
DLL_LOAD_PREFIXED(User32.dll, p, PeekMessageA, TRUE);
DLL_LOAD_PREFIXED(User32.dll, p, PostThreadMessageA, TRUE);
DLL_GET_HANDLE(User32);
DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE);
DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
return LIBUSB_SUCCESS;
}
static void windows_exit_dlls(void)
{
DLL_FREE_HANDLE(User32);
}
static bool windows_init_clock(struct libusb_context *ctx)
{
DWORD_PTR affinity, dummy;
@@ -601,4 +608,5 @@ void windows_common_exit(void)
{
htab_destroy();
windows_destroy_clock();
windows_exit_dlls();
}
+72 -40
View File
@@ -124,8 +124,10 @@ static usbi_mutex_t autoclaim_lock;
return LIBUSB_ERROR_ACCESS; \
} while(0)
static HMODULE WinUSBX_handle = NULL;
static struct winusb_interface WinUSBX[SUB_API_MAX];
static const char *sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES;
static bool api_hid_available = false;
#define CHECK_HID_AVAILABLE \
do { \
@@ -207,25 +209,45 @@ static char *sanitize_path(const char *path)
*/
static int init_dlls(void)
{
DLL_LOAD(Cfgmgr32.dll, CM_Get_Parent, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Get_Child, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE);
DLL_GET_HANDLE(Cfgmgr32);
DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Parent, TRUE);
DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Child, TRUE);
DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Sibling, TRUE);
DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Device_IDA, TRUE);
// Prefixed to avoid conflict with header files
DLL_LOAD_PREFIXED(OLE32.dll, p, CLSIDFromString, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
DLL_GET_HANDLE(AdvAPI32);
DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegQueryValueExW, TRUE);
DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegCloseKey, TRUE);
DLL_GET_HANDLE(Kernel32);
DLL_LOAD_FUNC_PREFIXED(Kernel32, p, IsWow64Process, FALSE);
DLL_GET_HANDLE(OLE32);
DLL_LOAD_FUNC_PREFIXED(OLE32, p, CLSIDFromString, TRUE);
DLL_GET_HANDLE(SetupAPI);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetClassDevsA, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInfo, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInterfaces, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiDestroyDeviceInfoList, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDevRegKey, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
return LIBUSB_SUCCESS;
}
static void exit_dlls(void)
{
DLL_FREE_HANDLE(Cfgmgr32);
DLL_FREE_HANDLE(AdvAPI32);
DLL_FREE_HANDLE(Kernel32);
DLL_FREE_HANDLE(OLE32);
DLL_FREE_HANDLE(SetupAPI);
}
/*
* enumerate interfaces for the whole USB class
*
@@ -647,9 +669,8 @@ static BOOL is_x64(void)
// Detect if we're running a 32 or 64 bit system
if (sizeof(uintptr_t) < 8) {
DLL_LOAD_PREFIXED(Kernel32.dll, p, IsWow64Process, FALSE);
if (pIsWow64Process != NULL)
(*pIsWow64Process)(GetCurrentProcess(), &ret);
pIsWow64Process(GetCurrentProcess(), &ret);
} else {
ret = TRUE;
}
@@ -816,6 +837,7 @@ init_exit: // Holds semaphore here.
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
for (i = 0; i < USB_API_MAX; i++)
usb_api_backend[i].exit(SUBAPI_NOT_SET);
exit_dlls();
exit_polling();
windows_common_exit();
usbi_mutex_destroy(&autoclaim_lock);
@@ -1644,6 +1666,7 @@ static void windows_exit(void)
if (--concurrent_usage < 0) { // Last exit
for (i = 0; i < USB_API_MAX; i++)
usb_api_backend[i].exit(SUB_API_NOTSET);
exit_dlls();
exit_polling();
windows_common_exit();
usbi_mutex_destroy(&autoclaim_lock);
@@ -2241,7 +2264,7 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
#define WinUSBX_Set(fn) \
do { \
if (native_winusb) \
WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \
WinUSBX[i].fn = (WinUsb_##fn##_t)GetProcAddress(h, "WinUsb_" #fn); \
else \
pLibK_GetProcAddress((PVOID *)&WinUSBX[i].fn, i, KUSB_FNID_##fn); \
} while (0)
@@ -2255,15 +2278,11 @@ static int winusbx_init(int sub_api, struct libusb_context *ctx)
LibK_GetProcAddress_t pLibK_GetProcAddress = NULL;
LibK_GetVersion_t pLibK_GetVersion;
h = GetModuleHandleA("libusbK");
if (h == NULL)
h = LoadLibraryA("libusbK");
h = LoadLibraryA("libusbK");
if (h == NULL) {
usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
h = GetModuleHandleA("WinUSB");
if (h == NULL)
h = LoadLibraryA("WinUSB");
h = LoadLibraryA("WinUSB");
if (h == NULL) {
usbi_warn(ctx, "WinUSB DLL is not available either, "
@@ -2281,6 +2300,7 @@ static int winusbx_init(int sub_api, struct libusb_context *ctx)
pLibK_GetProcAddress = (LibK_GetProcAddress_t)GetProcAddress(h, "LibK_GetProcAddress");
if (pLibK_GetProcAddress == NULL) {
usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL");
FreeLibrary(h);
return LIBUSB_ERROR_NOT_FOUND;
}
}
@@ -2319,11 +2339,20 @@ static int winusbx_init(int sub_api, struct libusb_context *ctx)
}
}
WinUSBX_handle = h;
return LIBUSB_SUCCESS;
}
static int winusbx_exit(int sub_api)
{
if (WinUSBX_handle != NULL) {
FreeLibrary(WinUSBX_handle);
WinUSBX_handle = NULL;
/* Reset the WinUSBX API structures */
memset(&WinUSBX, 0, sizeof(WinUSBX));
}
return LIBUSB_SUCCESS;
}
@@ -3368,22 +3397,23 @@ static int _hid_class_request(struct hid_device_priv *dev, HANDLE hid_handle, in
*/
static int hid_init(int sub_api, struct libusb_context *ctx)
{
DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
DLL_GET_HANDLE(hid);
DLL_LOAD_FUNC(hid, HidD_GetAttributes, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetHidGuid, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetPreparsedData, TRUE);
DLL_LOAD_FUNC(hid, HidD_FreePreparsedData, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetManufacturerString, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetProductString, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetSerialNumberString, TRUE);
DLL_LOAD_FUNC(hid, HidP_GetCaps, TRUE);
DLL_LOAD_FUNC(hid, HidD_SetNumInputBuffers, TRUE);
DLL_LOAD_FUNC(hid, HidD_SetFeature, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetFeature, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetPhysicalDescriptor, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetInputReport, FALSE);
DLL_LOAD_FUNC(hid, HidD_SetOutputReport, FALSE);
DLL_LOAD_FUNC(hid, HidD_FlushQueue, TRUE);
DLL_LOAD_FUNC(hid, HidP_GetValueCaps, TRUE);
api_hid_available = true;
return LIBUSB_SUCCESS;
@@ -3391,6 +3421,8 @@ static int hid_init(int sub_api, struct libusb_context *ctx)
static int hid_exit(int sub_api)
{
DLL_FREE_HANDLE(hid);
return LIBUSB_SUCCESS;
}
+41 -32
View File
@@ -314,25 +314,32 @@ struct driver_lookup {
};
/* OLE32 dependency */
DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
DLL_DECLARE_HANDLE(OLE32);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
/* Kernel32 dependencies */
DLL_DECLARE_HANDLE(Kernel32);
/* This call is only available from XP SP2 */
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
/* SetupAPI dependencies */
DLL_DECLARE_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
DLL_DECLARE_HANDLE(SetupAPI);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD));
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD));
/* AdvAPI32 dependencies */
DLL_DECLARE_HANDLE(AdvAPI32);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
/*
* Windows DDK API definitions. Most of it copied from MinGW's includes
@@ -413,10 +420,11 @@ typedef enum USB_HUB_NODE {
} USB_HUB_NODE;
/* Cfgmgr32.dll interface */
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
DLL_DECLARE_HANDLE(Cfgmgr32);
DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
#define IOCTL_USB_GET_HUB_CAPABILITIES_EX \
CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
@@ -934,19 +942,20 @@ typedef struct _HIDP_VALUE_CAPS {
} u;
} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
DLL_DECLARE(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
DLL_DECLARE(WINAPI, VOID, HidD_GetHidGuid, (LPGUID));
DLL_DECLARE(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *));
DLL_DECLARE(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA));
DLL_DECLARE(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetProductString, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetSerialNumberString, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, LONG, HidP_GetCaps, (PHIDP_PREPARSED_DATA, PHIDP_CAPS));
DLL_DECLARE(WINAPI, BOOL, HidD_SetNumInputBuffers, (HANDLE, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_SetFeature, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetFeature, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetInputReport, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_SetOutputReport, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_FlushQueue, (HANDLE));
DLL_DECLARE(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA));
DLL_DECLARE_HANDLE(hid);
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
DLL_DECLARE_FUNC(WINAPI, VOID, HidD_GetHidGuid, (LPGUID));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetProductString, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetSerialNumberString, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, LONG, HidP_GetCaps, (PHIDP_PREPARSED_DATA, PHIDP_CAPS));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_SetNumInputBuffers, (HANDLE, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_SetFeature, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetFeature, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetInputReport, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_SetOutputReport, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_FlushQueue, (HANDLE));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA));
+1 -1
View File
@@ -1 +1 @@
#define LIBUSB_NANO 11044
#define LIBUSB_NANO 11045