From 770f884ae86caceefae36b4f3137b8fd00f410bd Mon Sep 17 00:00:00 2001 From: d3xMachina <16732772+d3xMachina@users.noreply.github.com> Date: Sat, 10 Aug 2024 21:00:12 +0200 Subject: [PATCH 1/7] thread local error messages --- windows/hid.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 9 deletions(-) diff --git a/windows/hid.c b/windows/hid.c index 35c2de04..1c58dacf 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -78,6 +78,16 @@ typedef LONG NTSTATUS; #define MAX_STRING_WCHARS_USB 126 +#if defined(__GNUC__) +#define thread_local __thread +#elif __STDC_VERSION__ >= 201112L +#define thread_local _Thread_local +#elif defined(_MSC_VER) +#define thread_local __declspec(thread) +#else +#error Cannot define thread_local +#endif + static struct hid_api_version api_version = { .major = HID_API_VERSION_MAJOR, .minor = HID_API_VERSION_MINOR, @@ -180,6 +190,16 @@ static int lookup_functions() #endif /* HIDAPI_USE_DDK */ +struct hid_device_error +{ + HANDLE device_handle; + wchar_t *last_error_str; + + struct hid_device_error *next; +}; + +static thread_local struct hid_device_error *global_device_error = NULL; + struct hid_device_ { HANDLE device_handle; BOOL blocking; @@ -188,7 +208,6 @@ struct hid_device_ { size_t input_report_length; USHORT feature_report_length; unsigned char *feature_buf; - wchar_t *last_error_str; BOOL read_pending; char *read_buf; OVERLAPPED ol; @@ -211,7 +230,6 @@ static hid_device *new_hid_device() dev->input_report_length = 0; dev->feature_report_length = 0; dev->feature_buf = NULL; - dev->last_error_str = NULL; dev->read_pending = FALSE; dev->read_buf = NULL; memset(&dev->ol, 0, sizeof(dev->ol)); @@ -223,13 +241,40 @@ static hid_device *new_hid_device() return dev; } +static void free_error_buffer(hid_device *dev) +{ + struct hid_device_error *current = global_device_error; + struct hid_device_error *prev = NULL; + + while (current) + { + if (dev->device_handle == current->device_handle) + { + if (prev) + { + prev->next = current->next; + } + else + { + global_device_error = current->next; + } + + free(current->last_error_str); + free(current); + return; + } + + prev = current; + current = current->next; + } +} + static void free_hid_device(hid_device *dev) { CloseHandle(dev->ol.hEvent); CloseHandle(dev->write_ol.hEvent); CloseHandle(dev->device_handle); - free(dev->last_error_str); - dev->last_error_str = NULL; + free_error_buffer(dev); free(dev->write_buf); free(dev->feature_buf); free(dev->read_buf); @@ -316,17 +361,79 @@ static void register_string_error_to_buffer(wchar_t **error_buffer, const WCHAR # pragma GCC diagnostic pop #endif +static wchar_t** get_error_buffer(hid_device *dev) +{ + if (dev == NULL) + { + return NULL; + } + + struct hid_device_error *current = global_device_error; + struct hid_device_error *prev = NULL; + + while (current) + { + if (dev->device_handle == current->device_handle) + { + return ¤t->last_error_str; + } + + prev = current; + current = current->next; + } + + struct hid_device_error *device_error = (struct hid_device_error*) malloc(sizeof(struct hid_device_error)); + device_error->device_handle = dev->device_handle; + device_error->last_error_str = NULL; + device_error->next = NULL; + + if (prev) + { + prev->next = device_error; + } + else + { + global_device_error = device_error; + } + + return &device_error->last_error_str; +} + +static wchar_t* get_error_str(hid_device *dev) +{ + if (dev == NULL) + { + return NULL; + } + + struct hid_device_error *current = global_device_error; + + while (current) + { + if (dev->device_handle == current->device_handle) + { + return current->last_error_str; + } + + current = current->next; + } + + return NULL; +} + static void register_winapi_error(hid_device *dev, const WCHAR *op) { - register_winapi_error_to_buffer(&dev->last_error_str, op); + wchar_t **error_buffer = get_error_buffer(dev); + register_winapi_error_to_buffer(error_buffer, op); } static void register_string_error(hid_device *dev, const WCHAR *string_error) { - register_string_error_to_buffer(&dev->last_error_str, string_error); + wchar_t **error_buffer = get_error_buffer(dev); + register_string_error_to_buffer(error_buffer, string_error); } -static wchar_t *last_global_error_str = NULL; +static thread_local wchar_t *last_global_error_str = NULL; static void register_global_winapi_error(const WCHAR *op) { @@ -1530,9 +1637,10 @@ int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) { if (dev) { - if (dev->last_error_str == NULL) + wchar_t *error_str = get_error_str(dev); + if (error_str == NULL) return L"Success"; - return (wchar_t*)dev->last_error_str; + return (wchar_t*)error_str; } if (last_global_error_str == NULL) From cc4ce4cbf8e6eb36cf6d676e6aad83a2e0939f9a Mon Sep 17 00:00:00 2001 From: d3xMachina <16732772+d3xMachina@users.noreply.github.com> Date: Sun, 18 Aug 2024 17:57:26 +0200 Subject: [PATCH 2/7] fix memory leaks from the tls implementation --- windows/hid.c | 260 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 210 insertions(+), 50 deletions(-) diff --git a/windows/hid.c b/windows/hid.c index 1c58dacf..f15d17d2 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -190,15 +190,39 @@ static int lookup_functions() #endif /* HIDAPI_USE_DDK */ -struct hid_device_error +typedef void (*tls_destructor)(void *data, hid_device *dev, BOOLEAN all); + +struct tls_allocation +{ + void *data; + DWORD thread_id; + tls_destructor destructor; + + struct tls_allocation *next; +}; + +struct device_error { HANDLE device_handle; wchar_t *last_error_str; - struct hid_device_error *next; + struct device_error *next; +}; + +struct tls_context +{ + struct tls_allocation *allocated; + CRITICAL_SECTION critical_section; + BOOLEAN critical_section_ready; +}; + +static struct tls_context tls_context = { + .allocated = NULL, + .critical_section_ready = FALSE }; -static thread_local struct hid_device_error *global_device_error = NULL; +// Use a NULL device handle for the global error +static thread_local struct device_error *device_error = NULL; struct hid_device_ { HANDLE device_handle; @@ -241,14 +265,77 @@ static hid_device *new_hid_device() return dev; } -static void free_error_buffer(hid_device *dev) +static void tls_init() +{ + if (!tls_context.critical_section_ready) + { + InitializeCriticalSection(&tls_context.critical_section); + tls_context.critical_section_ready = TRUE; + } +} + +static void tls_register(void* data, tls_destructor destructor) { - struct hid_device_error *current = global_device_error; - struct hid_device_error *prev = NULL; + if (!tls_context.critical_section_ready) + { + return; + } + + DWORD thread_id = GetCurrentThreadId(); + + EnterCriticalSection(&tls_context.critical_section); + + struct tls_allocation *current = tls_context.allocated; + struct tls_allocation *prev = NULL; while (current) { - if (dev->device_handle == current->device_handle) + prev = current; + current = current->next; + } + + struct tls_allocation *tls = (struct tls_allocation*) malloc(sizeof(struct tls_allocation)); + tls->data = data; + tls->thread_id = thread_id; + tls->destructor = destructor; + tls->next = NULL; + + if (prev) + { + prev->next = tls; + } + else + { + tls_context.allocated = tls; + } + + LeaveCriticalSection(&tls_context.critical_section); +} + +static void tls_free(DWORD thread_id, hid_device *dev, BOOLEAN all_devices) +{ + if (!tls_context.critical_section_ready) + { + return; + } + + EnterCriticalSection(&tls_context.critical_section); + + struct tls_allocation *current = tls_context.allocated; + struct tls_allocation *prev = NULL; + + while (current) + { + if (thread_id != 0 && thread_id != current->thread_id) + { + prev = current; + current = current->next; + continue; + } + + current->destructor(¤t->data, dev, all_devices); + + if (current->data == NULL) { if (prev) { @@ -256,16 +343,87 @@ static void free_error_buffer(hid_device *dev) } else { - global_device_error = current->next; + tls_context.allocated = current->next; } - free(current->last_error_str); - free(current); - return; + struct tls_allocation *current_tmp = current; + current = current->next; + free(current_tmp); } + else + { + prev = current; + current = current->next; + } + } - prev = current; - current = current->next; + LeaveCriticalSection(&tls_context.critical_section); +} + +static void tls_free_all_threads(hid_device *dev, BOOLEAN all_devices) +{ + tls_free(0, dev, all_devices); +} + +static void tls_exit() +{ + if (!tls_context.critical_section_ready) + { + return; + } + + tls_free_all_threads(NULL, TRUE); + DeleteCriticalSection(&tls_context.critical_section); + tls_context.critical_section_ready = FALSE; +} + +static void free_error_buffer(struct device_error **error, hid_device *dev, BOOLEAN all_devices) +{ + if (error == NULL) + { + return; + } + + struct device_error *current = *error; + + if (all_devices) + { + while (current) + { + struct device_error *current_tmp = current; + current = current->next; + free(current_tmp->last_error_str); + free(current_tmp); + } + + *error = NULL; + } + else + { + struct device_error *prev = NULL; + + while (current) + { + if ((dev == NULL && current->device_handle == NULL) || + (dev != NULL && dev->device_handle == current->device_handle)) + { + if (prev) + { + prev->next = current->next; + } + else + { + *error = current->next; + } + + free(current->last_error_str); + free(current); + break; + } + + prev = current; + current = current->next; + } } } @@ -274,7 +432,7 @@ static void free_hid_device(hid_device *dev) CloseHandle(dev->ol.hEvent); CloseHandle(dev->write_ol.hEvent); CloseHandle(dev->device_handle); - free_error_buffer(dev); + tls_free_all_threads(dev, FALSE); free(dev->write_buf); free(dev->feature_buf); free(dev->read_buf); @@ -363,17 +521,13 @@ static void register_string_error_to_buffer(wchar_t **error_buffer, const WCHAR static wchar_t** get_error_buffer(hid_device *dev) { - if (dev == NULL) - { - return NULL; - } - - struct hid_device_error *current = global_device_error; - struct hid_device_error *prev = NULL; + struct device_error *current = device_error; + struct device_error *prev = NULL; while (current) { - if (dev->device_handle == current->device_handle) + if ((dev == NULL && current->device_handle == NULL) || + (dev != NULL && dev->device_handle == current->device_handle)) { return ¤t->last_error_str; } @@ -382,35 +536,32 @@ static wchar_t** get_error_buffer(hid_device *dev) current = current->next; } - struct hid_device_error *device_error = (struct hid_device_error*) malloc(sizeof(struct hid_device_error)); - device_error->device_handle = dev->device_handle; - device_error->last_error_str = NULL; - device_error->next = NULL; + struct device_error *error = (struct device_error*) malloc(sizeof(struct device_error)); + error->device_handle = dev != NULL ? dev->device_handle : NULL; + error->last_error_str = NULL; + error->next = NULL; if (prev) { - prev->next = device_error; + prev->next = error; } else { - global_device_error = device_error; + device_error = error; + tls_register(device_error, (tls_destructor)&free_error_buffer); } - return &device_error->last_error_str; + return &error->last_error_str; } static wchar_t* get_error_str(hid_device *dev) { - if (dev == NULL) - { - return NULL; - } - - struct hid_device_error *current = global_device_error; + struct device_error *current = device_error; while (current) { - if (dev->device_handle == current->device_handle) + if ((dev == NULL && current->device_handle == NULL) || + (dev != NULL && dev->device_handle == current->device_handle)) { return current->last_error_str; } @@ -433,16 +584,16 @@ static void register_string_error(hid_device *dev, const WCHAR *string_error) register_string_error_to_buffer(error_buffer, string_error); } -static thread_local wchar_t *last_global_error_str = NULL; - static void register_global_winapi_error(const WCHAR *op) { - register_winapi_error_to_buffer(&last_global_error_str, op); + wchar_t **error_buffer = get_error_buffer(NULL); + register_winapi_error_to_buffer(error_buffer, op); } static void register_global_error(const WCHAR *string_error) { - register_string_error_to_buffer(&last_global_error_str, string_error); + wchar_t **error_buffer = get_error_buffer(NULL); + register_string_error_to_buffer(error_buffer, string_error); } static HANDLE open_device(const wchar_t *path, BOOL open_rw) @@ -472,8 +623,23 @@ HID_API_EXPORT const char* HID_API_CALL hid_version_str(void) return HID_API_VERSION_STR; } +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) +{ + switch (reason) + { + case DLL_THREAD_DETACH: + { + DWORD thread_id = GetCurrentThreadId(); + tls_free(thread_id, NULL, TRUE); + break; + } + } + return TRUE; +} + int HID_API_EXPORT hid_init(void) { + tls_init(); register_global_error(NULL); #ifndef HIDAPI_USE_DDK if (!hidapi_initialized) { @@ -493,7 +659,7 @@ int HID_API_EXPORT hid_exit(void) free_library_handles(); hidapi_initialized = FALSE; #endif - register_global_error(NULL); + tls_exit(); return 0; } @@ -1636,16 +1802,10 @@ int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) { - if (dev) { - wchar_t *error_str = get_error_str(dev); - if (error_str == NULL) - return L"Success"; - return (wchar_t*)error_str; - } - - if (last_global_error_str == NULL) + wchar_t *error_str = get_error_str(dev); + if (error_str == NULL) return L"Success"; - return last_global_error_str; + return error_str; } #ifndef hidapi_winapi_EXPORTS From e417c3bcb7e75b757b2cdddc5339d9ddd1022281 Mon Sep 17 00:00:00 2001 From: d3xMachina <16732772+d3xMachina@users.noreply.github.com> Date: Wed, 21 Aug 2024 03:35:48 +0200 Subject: [PATCH 3/7] formatting --- windows/hid.c | 93 +++++++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 62 deletions(-) diff --git a/windows/hid.c b/windows/hid.c index f15d17d2..f056f4ea 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -192,8 +192,7 @@ static int lookup_functions() typedef void (*tls_destructor)(void *data, hid_device *dev, BOOLEAN all); -struct tls_allocation -{ +struct tls_allocation { void *data; DWORD thread_id; tls_destructor destructor; @@ -201,16 +200,14 @@ struct tls_allocation struct tls_allocation *next; }; -struct device_error -{ +struct device_error { HANDLE device_handle; wchar_t *last_error_str; struct device_error *next; }; -struct tls_context -{ +struct tls_context { struct tls_allocation *allocated; CRITICAL_SECTION critical_section; BOOLEAN critical_section_ready; @@ -267,8 +264,7 @@ static hid_device *new_hid_device() static void tls_init() { - if (!tls_context.critical_section_ready) - { + if (!tls_context.critical_section_ready) { InitializeCriticalSection(&tls_context.critical_section); tls_context.critical_section_ready = TRUE; } @@ -276,8 +272,7 @@ static void tls_init() static void tls_register(void* data, tls_destructor destructor) { - if (!tls_context.critical_section_ready) - { + if (!tls_context.critical_section_ready) { return; } @@ -288,8 +283,7 @@ static void tls_register(void* data, tls_destructor destructor) struct tls_allocation *current = tls_context.allocated; struct tls_allocation *prev = NULL; - while (current) - { + while (current) { prev = current; current = current->next; } @@ -300,12 +294,10 @@ static void tls_register(void* data, tls_destructor destructor) tls->destructor = destructor; tls->next = NULL; - if (prev) - { + if (prev) { prev->next = tls; } - else - { + else { tls_context.allocated = tls; } @@ -314,8 +306,7 @@ static void tls_register(void* data, tls_destructor destructor) static void tls_free(DWORD thread_id, hid_device *dev, BOOLEAN all_devices) { - if (!tls_context.critical_section_ready) - { + if (!tls_context.critical_section_ready) { return; } @@ -324,10 +315,8 @@ static void tls_free(DWORD thread_id, hid_device *dev, BOOLEAN all_devices) struct tls_allocation *current = tls_context.allocated; struct tls_allocation *prev = NULL; - while (current) - { - if (thread_id != 0 && thread_id != current->thread_id) - { + while (current) { + if (thread_id != 0 && thread_id != current->thread_id) { prev = current; current = current->next; continue; @@ -335,14 +324,11 @@ static void tls_free(DWORD thread_id, hid_device *dev, BOOLEAN all_devices) current->destructor(¤t->data, dev, all_devices); - if (current->data == NULL) - { - if (prev) - { + if (current->data == NULL) { + if (prev) { prev->next = current->next; } - else - { + else { tls_context.allocated = current->next; } @@ -350,8 +336,7 @@ static void tls_free(DWORD thread_id, hid_device *dev, BOOLEAN all_devices) current = current->next; free(current_tmp); } - else - { + else { prev = current; current = current->next; } @@ -367,8 +352,7 @@ static void tls_free_all_threads(hid_device *dev, BOOLEAN all_devices) static void tls_exit() { - if (!tls_context.critical_section_ready) - { + if (!tls_context.critical_section_ready) { return; } @@ -379,17 +363,14 @@ static void tls_exit() static void free_error_buffer(struct device_error **error, hid_device *dev, BOOLEAN all_devices) { - if (error == NULL) - { + if (error == NULL) { return; } struct device_error *current = *error; - if (all_devices) - { - while (current) - { + if (all_devices) { + while (current) { struct device_error *current_tmp = current; current = current->next; free(current_tmp->last_error_str); @@ -402,17 +383,13 @@ static void free_error_buffer(struct device_error **error, hid_device *dev, BOOL { struct device_error *prev = NULL; - while (current) - { + while (current) { if ((dev == NULL && current->device_handle == NULL) || - (dev != NULL && dev->device_handle == current->device_handle)) - { - if (prev) - { + (dev != NULL && dev->device_handle == current->device_handle)) { + if (prev) { prev->next = current->next; } - else - { + else { *error = current->next; } @@ -524,11 +501,9 @@ static wchar_t** get_error_buffer(hid_device *dev) struct device_error *current = device_error; struct device_error *prev = NULL; - while (current) - { + while (current) { if ((dev == NULL && current->device_handle == NULL) || - (dev != NULL && dev->device_handle == current->device_handle)) - { + (dev != NULL && dev->device_handle == current->device_handle)) { return ¤t->last_error_str; } @@ -541,12 +516,10 @@ static wchar_t** get_error_buffer(hid_device *dev) error->last_error_str = NULL; error->next = NULL; - if (prev) - { + if (prev) { prev->next = error; } - else - { + else { device_error = error; tls_register(device_error, (tls_destructor)&free_error_buffer); } @@ -558,11 +531,9 @@ static wchar_t* get_error_str(hid_device *dev) { struct device_error *current = device_error; - while (current) - { + while (current) { if ((dev == NULL && current->device_handle == NULL) || - (dev != NULL && dev->device_handle == current->device_handle)) - { + (dev != NULL && dev->device_handle == current->device_handle)) { return current->last_error_str; } @@ -625,10 +596,8 @@ HID_API_EXPORT const char* HID_API_CALL hid_version_str(void) BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { - switch (reason) - { - case DLL_THREAD_DETACH: - { + switch (reason) { + case DLL_THREAD_DETACH: { DWORD thread_id = GetCurrentThreadId(); tls_free(thread_id, NULL, TRUE); break; From 2afbafa2e1ff82529119700f1d144a692a8caed1 Mon Sep 17 00:00:00 2001 From: d3xMachina <16732772+d3xMachina@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:40:19 +0200 Subject: [PATCH 4/7] fix mem leak when hid_init is not called --- windows/hid.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/windows/hid.c b/windows/hid.c index f056f4ea..38cc9c8e 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -262,7 +262,7 @@ static hid_device *new_hid_device() return dev; } -static void tls_init() +static void tls_init_context() { if (!tls_context.critical_section_ready) { InitializeCriticalSection(&tls_context.critical_section); @@ -270,6 +270,14 @@ static void tls_init() } } +static void tls_exit_context() +{ + if (tls_context.critical_section_ready) { + DeleteCriticalSection(&tls_context.critical_section); + tls_context.critical_section_ready = FALSE; + } +} + static void tls_register(void* data, tls_destructor destructor) { if (!tls_context.critical_section_ready) { @@ -350,17 +358,6 @@ static void tls_free_all_threads(hid_device *dev, BOOLEAN all_devices) tls_free(0, dev, all_devices); } -static void tls_exit() -{ - if (!tls_context.critical_section_ready) { - return; - } - - tls_free_all_threads(NULL, TRUE); - DeleteCriticalSection(&tls_context.critical_section); - tls_context.critical_section_ready = FALSE; -} - static void free_error_buffer(struct device_error **error, hid_device *dev, BOOLEAN all_devices) { if (error == NULL) { @@ -597,18 +594,25 @@ HID_API_EXPORT const char* HID_API_CALL hid_version_str(void) BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) { - case DLL_THREAD_DETACH: { - DWORD thread_id = GetCurrentThreadId(); - tls_free(thread_id, NULL, TRUE); - break; - } + case DLL_PROCESS_ATTACH: + tls_init_context(); + break; + + case DLL_PROCESS_DETACH: + tls_exit_context(); + break; + + case DLL_THREAD_DETACH: { + DWORD thread_id = GetCurrentThreadId(); + tls_free(thread_id, NULL, TRUE); + break; + } } return TRUE; } int HID_API_EXPORT hid_init(void) { - tls_init(); register_global_error(NULL); #ifndef HIDAPI_USE_DDK if (!hidapi_initialized) { @@ -628,7 +632,7 @@ int HID_API_EXPORT hid_exit(void) free_library_handles(); hidapi_initialized = FALSE; #endif - tls_exit(); + tls_free_all_threads(NULL, TRUE); return 0; } From 962612e87969ac67840301195f35352c2a9e815b Mon Sep 17 00:00:00 2001 From: d3xMachina <16732772+d3xMachina@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:49:01 +0200 Subject: [PATCH 5/7] fix indentation --- windows/hid.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/windows/hid.c b/windows/hid.c index 38cc9c8e..9db88315 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -593,7 +593,7 @@ HID_API_EXPORT const char* HID_API_CALL hid_version_str(void) BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { - switch (reason) { + switch (reason) { case DLL_PROCESS_ATTACH: tls_init_context(); break; @@ -602,13 +602,13 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) tls_exit_context(); break; - case DLL_THREAD_DETACH: { + case DLL_THREAD_DETACH: { DWORD thread_id = GetCurrentThreadId(); tls_free(thread_id, NULL, TRUE); break; } - } - return TRUE; + } + return TRUE; } int HID_API_EXPORT hid_init(void) From fec6ea33fd8eb17cf13adf95ef85910324ba8f01 Mon Sep 17 00:00:00 2001 From: d3xMachina <16732772+d3xMachina@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:57:11 +0200 Subject: [PATCH 6/7] fix compilation --- windows/hid.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/windows/hid.c b/windows/hid.c index 9db88315..2ff0b583 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -593,6 +593,9 @@ HID_API_EXPORT const char* HID_API_CALL hid_version_str(void) BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { + (void)instance; + (void)reserved; + switch (reason) { case DLL_PROCESS_ATTACH: tls_init_context(); From 5c53c1cc008d78fd1c54aeac6d6e7f870a9094e4 Mon Sep 17 00:00:00 2001 From: d3xMachina <16732772+d3xMachina@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:59:24 +0200 Subject: [PATCH 7/7] nitpicking --- windows/hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/hid.c b/windows/hid.c index 2ff0b583..782b5dbf 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -190,7 +190,7 @@ static int lookup_functions() #endif /* HIDAPI_USE_DDK */ -typedef void (*tls_destructor)(void *data, hid_device *dev, BOOLEAN all); +typedef void (*tls_destructor)(void **data, hid_device *dev, BOOLEAN all_devices); struct tls_allocation { void *data;