mirror of
https://github.com/RPCS3/libusb.git
synced 2026-07-21 00:16:04 -04:00
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:
+34
-23
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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 @@
|
||||
#define LIBUSB_NANO 11044
|
||||
#define LIBUSB_NANO 11045
|
||||
|
||||
Reference in New Issue
Block a user