[PATCH 4/8] dinput: Unacquire all devices on internal thread error.

Rémi Bernon rbernon at codeweavers.com
Wed Jan 5 07:58:38 CST 2022


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52263
Signed-off-by: Rémi Bernon <rbernon at 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 );
-- 
2.34.1




More information about the wine-devel mailing list