For low-level hooks, which don't need it. Passing a module handle will make set_windows_hook call GetModuleFileNameW which requires the loader lock.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263 Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This is a bit longer than I'd like and I don't like very much the idea of the thread timeout, but I don't see any other solution.
Maybe a finer grained loader locking could solve the underlying problem, but it's not going to be there soon.
dlls/dinput/dinput_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index a62d4d2ea3d..980edeba817 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1317,7 +1317,7 @@ static DWORD WINAPI dinput_thread_proc( void *params ) LeaveCriticalSection( &dinput_hook_crit );
if (kbd_cnt && !kbd_hook) - kbd_hook = SetWindowsHookExW( WH_KEYBOARD_LL, LL_hook_proc, DINPUT_instance, 0 ); + kbd_hook = SetWindowsHookExW( WH_KEYBOARD_LL, LL_hook_proc, NULL, 0 ); else if (!kbd_cnt && kbd_hook) { UnhookWindowsHookEx( kbd_hook ); @@ -1325,7 +1325,7 @@ static DWORD WINAPI dinput_thread_proc( void *params ) }
if (mice_cnt && !mouse_hook) - mouse_hook = SetWindowsHookExW( WH_MOUSE_LL, LL_hook_proc, DINPUT_instance, 0 ); + mouse_hook = SetWindowsHookExW( WH_MOUSE_LL, LL_hook_proc, NULL, 0 ); else if (!mice_cnt && mouse_hook) { UnhookWindowsHookEx( mouse_hook );
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 980edeba817..e2fabfc75f0 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1275,9 +1275,10 @@ static DWORD WINAPI dinput_thread_proc( void *params ) { UINT kbd_cnt = 0, mice_cnt = 0;
+ EnterCriticalSection( &dinput_hook_crit ); + if (ret < events_count) { - EnterCriticalSection( &dinput_hook_crit ); LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_device_list, struct dinput_device, entry ) { if (impl->read_event == events[ret]) @@ -1287,7 +1288,6 @@ static DWORD WINAPI dinput_thread_proc( void *params ) break; } } - LeaveCriticalSection( &dinput_hook_crit ); }
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) @@ -1308,13 +1308,12 @@ static DWORD WINAPI dinput_thread_proc( void *params ) if (kbd_hook) UnhookWindowsHookEx( kbd_hook ); if (mouse_hook) UnhookWindowsHookEx( mouse_hook ); kbd_hook = mouse_hook = NULL; + LeaveCriticalSection( &dinput_hook_crit ); goto done; }
- EnterCriticalSection( &dinput_hook_crit ); kbd_cnt = list_count( &acquired_keyboard_list ); mice_cnt = list_count( &acquired_mouse_list ); - LeaveCriticalSection( &dinput_hook_crit );
if (kbd_cnt && !kbd_hook) kbd_hook = SetWindowsHookExW( WH_KEYBOARD_LL, LL_hook_proc, NULL, 0 ); @@ -1336,13 +1335,13 @@ static DWORD WINAPI dinput_thread_proc( void *params ) }
events_count = 0; - EnterCriticalSection( &dinput_hook_crit ); LIST_FOR_EACH_ENTRY( impl, &acquired_device_list, struct dinput_device, entry ) { if (!impl->read_event || !impl->vtbl->read) continue; if (events_count >= ARRAY_SIZE(events)) break; events[events_count++] = impl->read_event; } + LeaveCriticalSection( &dinput_hook_crit ); }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 72 +++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 33 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index e2fabfc75f0..c4b41b7b945 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1204,9 +1204,46 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam ) return skip ? 1 : CallNextHookEx( 0, code, wparam, lparam ); }
-static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam ) +static void dinput_unacquire_window_devices( HWND window ) { struct dinput_device *impl, *next; + + LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_device_list, struct dinput_device, entry ) + { + if (window == impl->win) + { + TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); + dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); + } + } + LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_mouse_list, struct dinput_device, entry ) + { + if (window == impl->win) + { + TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); + dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); + } + } + LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_rawmouse_list, struct dinput_device, entry ) + { + if (window == impl->win) + { + TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); + dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); + } + } + LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_keyboard_list, struct dinput_device, entry ) + { + if (window == impl->win) + { + TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); + dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); + } + } +} + +static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam ) +{ CWPSTRUCT *msg = (CWPSTRUCT *)lparam; HWND foreground;
@@ -1217,38 +1254,7 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam foreground = GetForegroundWindow();
EnterCriticalSection( &dinput_hook_crit ); - LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_device_list, struct dinput_device, entry ) - { - if (msg->hwnd == impl->win && msg->hwnd != foreground) - { - TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); - dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); - } - } - LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_mouse_list, struct dinput_device, entry ) - { - if (msg->hwnd == impl->win && msg->hwnd != foreground) - { - TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); - dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); - } - } - LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_rawmouse_list, struct dinput_device, entry ) - { - if (msg->hwnd == impl->win && msg->hwnd != foreground) - { - TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); - dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); - } - } - LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_keyboard_list, struct dinput_device, entry ) - { - if (msg->hwnd == impl->win && msg->hwnd != foreground) - { - TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); - dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); - } - } + if (msg->hwnd != foreground) dinput_unacquire_window_devices( msg->hwnd ); LeaveCriticalSection( &dinput_hook_crit );
return CallNextHookEx( 0, code, wparam, lparam );
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index c4b41b7b945..69a38f9ce65 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1204,13 +1204,13 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam ) return skip ? 1 : CallNextHookEx( 0, code, wparam, lparam ); }
-static void dinput_unacquire_window_devices( HWND window ) +static void dinput_unacquire_window_devices( HWND window, BOOL all ) { struct dinput_device *impl, *next;
LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_device_list, struct dinput_device, entry ) { - if (window == impl->win) + if (all || window == impl->win) { TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); @@ -1218,7 +1218,7 @@ static void dinput_unacquire_window_devices( HWND window ) } LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_mouse_list, struct dinput_device, entry ) { - if (window == impl->win) + if (all || window == impl->win) { TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); @@ -1226,7 +1226,7 @@ static void dinput_unacquire_window_devices( HWND window ) } LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_rawmouse_list, struct dinput_device, entry ) { - if (window == impl->win) + if (all || window == impl->win) { TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); @@ -1234,7 +1234,7 @@ static void dinput_unacquire_window_devices( HWND window ) } LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_keyboard_list, struct dinput_device, entry ) { - if (window == impl->win) + if (all || window == impl->win) { TRACE( "%p window is not foreground - unacquiring %p\n", impl->win, impl ); dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface ); @@ -1254,7 +1254,7 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam foreground = GetForegroundWindow();
EnterCriticalSection( &dinput_hook_crit ); - if (msg->hwnd != foreground) dinput_unacquire_window_devices( msg->hwnd ); + if (msg->hwnd != foreground) dinput_unacquire_window_devices( msg->hwnd, FALSE ); LeaveCriticalSection( &dinput_hook_crit );
return CallNextHookEx( 0, code, wparam, lparam ); @@ -1351,7 +1351,14 @@ static DWORD WINAPI dinput_thread_proc( void *params ) LeaveCriticalSection( &dinput_hook_crit ); }
- if (ret != events_count) ERR("Unexpected termination, ret %#x\n", ret); + ERR("Unexpected termination, ret %#x\n", ret); + + EnterCriticalSection( &dinput_hook_crit ); + dinput_unacquire_window_devices( 0, TRUE ); + if (kbd_hook) UnhookWindowsHookEx( kbd_hook ); + if (mouse_hook) UnhookWindowsHookEx( mouse_hook ); + kbd_hook = mouse_hook = NULL; + LeaveCriticalSection( &dinput_hook_crit );
done: DestroyWindow( di_em_win );
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 69a38f9ce65..5ba959e8414 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -79,7 +79,6 @@ HINSTANCE DINPUT_instance; static HWND di_em_win;
static HANDLE dinput_thread; -static DWORD dinput_thread_id;
static CRITICAL_SECTION dinput_hook_crit; static CRITICAL_SECTION_DEBUG dinput_critsect_debug = @@ -1373,7 +1372,7 @@ static BOOL WINAPI dinput_thread_start_once( INIT_ONCE *once, void *param, void start_event = CreateEventW( NULL, FALSE, FALSE, NULL ); if (!start_event) ERR( "failed to create start event, error %u\n", GetLastError() );
- dinput_thread = CreateThread( NULL, 0, dinput_thread_proc, start_event, 0, &dinput_thread_id ); + dinput_thread = CreateThread( NULL, 0, dinput_thread_proc, start_event, 0, NULL ); if (!dinput_thread) ERR( "failed to create internal thread, error %u\n", GetLastError() );
WaitForSingleObject( start_event, INFINITE ); @@ -1390,7 +1389,7 @@ static void dinput_thread_start(void)
static void dinput_thread_stop(void) { - PostThreadMessageW( dinput_thread_id, WM_USER + 0x10, 0, 0 ); + PostMessageW( di_em_win, WM_USER + 0x10, 0, 0 ); WaitForSingleObject( dinput_thread, INFINITE ); CloseHandle( dinput_thread ); } @@ -1449,7 +1448,7 @@ void check_dinput_hooks( IDirectInputDevice8W *iface, BOOL acquired ) }
hook_change_finished_event = CreateEventW( NULL, FALSE, FALSE, NULL ); - PostThreadMessageW( dinput_thread_id, WM_USER + 0x10, 1, (LPARAM)hook_change_finished_event ); + PostMessageW( di_em_win, WM_USER + 0x10, 1, (LPARAM)hook_change_finished_event );
LeaveCriticalSection(&dinput_hook_crit);
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 62 +++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 28 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 5ba959e8414..9903a02c42f 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1262,15 +1262,19 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam static DWORD WINAPI dinput_thread_proc( void *params ) { HANDLE events[128], start_event = params; - static HHOOK kbd_hook, mouse_hook; + HHOOK kbd_hook = NULL, mouse_hook = NULL; struct dinput_device *impl, *next; SIZE_T events_count = 0; HANDLE finished_event; HRESULT hr; DWORD ret; + HWND hwnd; MSG msg;
- di_em_win = CreateWindowW( L"DIEmWin", L"DIEmWin", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, DINPUT_instance, NULL ); + TRACE( "starting internal thread\n" ); + + hwnd = CreateWindowW( L"DIEmWin", L"DIEmWin", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, DINPUT_instance, NULL ); + di_em_win = hwnd;
/* Force creation of the message queue */ PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ); @@ -1312,7 +1316,7 @@ static DWORD WINAPI dinput_thread_proc( void *params ) { if (kbd_hook) UnhookWindowsHookEx( kbd_hook ); if (mouse_hook) UnhookWindowsHookEx( mouse_hook ); - kbd_hook = mouse_hook = NULL; + di_em_win = 0; LeaveCriticalSection( &dinput_hook_crit ); goto done; } @@ -1356,42 +1360,44 @@ static DWORD WINAPI dinput_thread_proc( void *params ) dinput_unacquire_window_devices( 0, TRUE ); if (kbd_hook) UnhookWindowsHookEx( kbd_hook ); if (mouse_hook) UnhookWindowsHookEx( mouse_hook ); - kbd_hook = mouse_hook = NULL; + di_em_win = 0; LeaveCriticalSection( &dinput_hook_crit );
done: - DestroyWindow( di_em_win ); - di_em_win = NULL; + DestroyWindow( hwnd ); + + TRACE( "exiting internal thread\n" ); return 0; }
-static BOOL WINAPI dinput_thread_start_once( INIT_ONCE *once, void *param, void **context ) -{ - HANDLE start_event; - - start_event = CreateEventW( NULL, FALSE, FALSE, NULL ); - if (!start_event) ERR( "failed to create start event, error %u\n", GetLastError() ); - - dinput_thread = CreateThread( NULL, 0, dinput_thread_proc, start_event, 0, NULL ); - if (!dinput_thread) ERR( "failed to create internal thread, error %u\n", GetLastError() ); - - WaitForSingleObject( start_event, INFINITE ); - CloseHandle( start_event ); - - return TRUE; -} - static void dinput_thread_start(void) { - static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; - InitOnceExecuteOnce( &init_once, dinput_thread_start_once, NULL, NULL ); + HANDLE start_event, thread; + + start_event = CreateEventW( NULL, FALSE, FALSE, NULL ); + if (!start_event) ERR( "failed to create start event, error %u\n", GetLastError() ); + + thread = CreateThread( NULL, 0, dinput_thread_proc, start_event, 0, NULL ); + if (!thread) ERR( "failed to create internal thread, error %u\n", GetLastError() ); + else WaitForSingleObject( start_event, INFINITE ); + CloseHandle( start_event ); + + CloseHandle( dinput_thread ); + dinput_thread = thread; }
static void dinput_thread_stop(void) { + HANDLE thread = NULL; + + EnterCriticalSection( &dinput_hook_crit ); PostMessageW( di_em_win, WM_USER + 0x10, 0, 0 ); - WaitForSingleObject( dinput_thread, INFINITE ); - CloseHandle( dinput_thread ); + thread = dinput_thread; + dinput_thread = NULL; + LeaveCriticalSection( &dinput_hook_crit ); + + WaitForSingleObject( thread, INFINITE ); + CloseHandle( thread ); }
void check_dinput_hooks( IDirectInputDevice8W *iface, BOOL acquired ) @@ -1401,10 +1407,10 @@ void check_dinput_hooks( IDirectInputDevice8W *iface, BOOL acquired ) struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); HANDLE hook_change_finished_event = NULL;
- dinput_thread_start(); - EnterCriticalSection(&dinput_hook_crit);
+ if (!di_em_win) dinput_thread_start(); + if (impl->dwCoopLevel & DISCL_FOREGROUND) { if (acquired)
And after a 1s timeout, so that the message window used for rawinput device registration stays alive for a while even when no devices are acquired. This is required for some of the tests to pass.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 9903a02c42f..764eada6762 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1264,6 +1264,7 @@ static DWORD WINAPI dinput_thread_proc( void *params ) HANDLE events[128], start_event = params; HHOOK kbd_hook = NULL, mouse_hook = NULL; struct dinput_device *impl, *next; + DWORD timeout = INFINITE; SIZE_T events_count = 0; HANDLE finished_event; HRESULT hr; @@ -1280,7 +1281,8 @@ static DWORD WINAPI dinput_thread_proc( void *params ) PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ); SetEvent( start_event );
- while ((ret = MsgWaitForMultipleObjectsEx( events_count, events, INFINITE, QS_ALLINPUT, 0 )) <= events_count) + while ((ret = MsgWaitForMultipleObjectsEx( events_count, events, timeout, QS_ALLINPUT, 0 )) <= events_count || + ret == WAIT_TIMEOUT) { UINT kbd_cnt = 0, mice_cnt = 0;
@@ -1351,6 +1353,17 @@ static DWORD WINAPI dinput_thread_proc( void *params ) events[events_count++] = impl->read_event; }
+ if (!list_empty( &acquired_device_list ) || !list_empty( &acquired_rawmouse_list ) || + !list_empty( &acquired_mouse_list ) || !list_empty( &acquired_keyboard_list )) + timeout = INFINITE; + else if (ret == WAIT_TIMEOUT) + { + di_em_win = 0; + LeaveCriticalSection( &dinput_hook_crit ); + goto done; + } + else timeout = 1000; + LeaveCriticalSection( &dinput_hook_crit ); }
Instead of waiting for the thread on process detach.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 764eada6762..dfa7712ac09 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -78,8 +78,6 @@ HINSTANCE DINPUT_instance;
static HWND di_em_win;
-static HANDLE dinput_thread; - static CRITICAL_SECTION dinput_hook_crit; static CRITICAL_SECTION_DEBUG dinput_critsect_debug = { @@ -1314,15 +1312,6 @@ static DWORD WINAPI dinput_thread_proc( void *params )
TRACE( "Processing hook change notification wp:%ld lp:%#lx\n", msg.wParam, msg.lParam );
- if (!msg.wParam) - { - if (kbd_hook) UnhookWindowsHookEx( kbd_hook ); - if (mouse_hook) UnhookWindowsHookEx( mouse_hook ); - di_em_win = 0; - LeaveCriticalSection( &dinput_hook_crit ); - goto done; - } - kbd_cnt = list_count( &acquired_keyboard_list ); mice_cnt = list_count( &acquired_mouse_list );
@@ -1380,12 +1369,15 @@ done: DestroyWindow( hwnd );
TRACE( "exiting internal thread\n" ); - return 0; + FreeLibraryAndExitThread( DINPUT_instance, 0 ); }
static void dinput_thread_start(void) { HANDLE start_event, thread; + HMODULE module; + + GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const WCHAR *)DINPUT_instance, &module );
start_event = CreateEventW( NULL, FALSE, FALSE, NULL ); if (!start_event) ERR( "failed to create start event, error %u\n", GetLastError() ); @@ -1395,21 +1387,7 @@ static void dinput_thread_start(void) else WaitForSingleObject( start_event, INFINITE ); CloseHandle( start_event );
- CloseHandle( dinput_thread ); - dinput_thread = thread; -} - -static void dinput_thread_stop(void) -{ - HANDLE thread = NULL; - - EnterCriticalSection( &dinput_hook_crit ); - PostMessageW( di_em_win, WM_USER + 0x10, 0, 0 ); - thread = dinput_thread; - dinput_thread = NULL; - LeaveCriticalSection( &dinput_hook_crit ); - - WaitForSingleObject( thread, INFINITE ); + if (!thread) FreeLibrary( module ); CloseHandle( thread ); }
@@ -1502,7 +1480,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved) break; case DLL_PROCESS_DETACH: if (reserved) break; - dinput_thread_stop(); unregister_di_em_win_class(); DeleteCriticalSection(&dinput_hook_crit); break;
Speaking of thread timeout, now that I think about it, maybe a simpler a more acceptable short term solution (less risky but ugly) would be to add a timeout to the module process detach thread wait?