diff options
author | Chris Dickens <christopher.a.dickens@gmail.com> | 2016-01-28 00:29:58 -0800 |
---|---|---|
committer | Chris Dickens <christopher.a.dickens@gmail.com> | 2016-01-28 00:55:10 -0800 |
commit | 57cfbb444e03179a4e4eafba18416209f0db1d1c (patch) | |
tree | 1e63642a0c82491d9e771aa9780be0ca0145d30a | |
parent | 452e7bd68383c43b75e6b12791f5721fbaea4697 (diff) | |
download | libusb-57cfbb444e03179a4e4eafba18416209f0db1d1c.tar.gz |
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>
-rw-r--r-- | libusb/os/wince_usb.c | 59 | ||||
-rw-r--r-- | libusb/os/wince_usb.h | 45 | ||||
-rw-r--r-- | libusb/os/windows_common.h | 95 | ||||
-rw-r--r-- | libusb/os/windows_nt_common.c | 20 | ||||
-rw-r--r-- | libusb/os/windows_winusb.c | 112 | ||||
-rw-r--r-- | libusb/os/windows_winusb.h | 73 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
7 files changed, 246 insertions, 160 deletions
diff --git a/libusb/os/wince_usb.c b/libusb/os/wince_usb.c index 96cad67..fc95e9c 100644 --- a/libusb/os/wince_usb.c +++ b/libusb/os/wince_usb.c @@ -109,33 +109,40 @@ static int translate_driver_error(DWORD error) } } -static int init_dllimports() -{ - 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); +static int init_dllimports(void) +{ + 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) { diff --git a/libusb/os/wince_usb.h b/libusb/os/wince_usb.h index b3403db..edcb9fc 100644 --- a/libusb/os/wince_usb.h +++ b/libusb/os/wince_usb.h @@ -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 diff --git a/libusb/os/windows_common.h b/libusb/os/windows_common.h index 45c59af..0149e11 100644 --- a/libusb/os/windows_common.h +++ b/libusb/os/windows_common.h @@ -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) + + +/* + * 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_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) +#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) diff --git a/libusb/os/windows_nt_common.c b/libusb/os/windows_nt_common.c index 55b6818..650e2fa 100644 --- a/libusb/os/windows_nt_common.c +++ b/libusb/os/windows_nt_common.c @@ -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(); } diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index 5bf35a2..f790736 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -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; } diff --git a/libusb/os/windows_winusb.h b/libusb/os/windows_winusb.h index 8f53c4a..047f2e2 100644 --- a/libusb/os/windows_winusb.h +++ b/libusb/os/windows_winusb.h @@ -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));
\ No newline at end of file diff --git a/libusb/version_nano.h b/libusb/version_nano.h index a3f68ad..b505204 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11044 +#define LIBUSB_NANO 11045 |