Rémi Bernon : win32u: Fix thread safety when accessing rawinput device data.

Alexandre Julliard julliard at winehq.org
Wed Jul 27 16:17:08 CDT 2022


Module: wine
Branch: master
Commit: 840ec530410c8b78bdc6884b487a31eae7ff146b
URL:    https://gitlab.winehq.org/wine/wine/-/commit/840ec530410c8b78bdc6884b487a31eae7ff146b

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Tue Jul 26 07:32:47 2022 +0200

win32u: Fix thread safety when accessing rawinput device data.

---

 dlls/win32u/rawinput.c | 48 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c
index dd697017953..34accc3c4a0 100644
--- a/dlls/win32u/rawinput.c
+++ b/dlls/win32u/rawinput.c
@@ -206,7 +206,7 @@ struct device
 static struct device *rawinput_devices;
 static unsigned int rawinput_devices_count, rawinput_devices_max;
 
-static pthread_mutex_t rawinput_devices_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t rawinput_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static bool array_reserve( void **elements, unsigned int *capacity, unsigned int count, unsigned int size )
 {
@@ -461,8 +461,6 @@ static void rawinput_update_device_list(void)
 
     TRACE( "\n" );
 
-    pthread_mutex_lock( &rawinput_devices_mutex );
-
     /* destroy previous list */
     for (i = 0; i < rawinput_devices_count; ++i)
     {
@@ -475,8 +473,6 @@ static void rawinput_update_device_list(void)
     enumerate_devices( RIM_TYPEMOUSE, guid_devinterface_mouseW );
     enumerate_devices( RIM_TYPEKEYBOARD, guid_devinterface_keyboardW );
     enumerate_devices( RIM_TYPEHID, guid_devinterface_hidW );
-
-    pthread_mutex_unlock( &rawinput_devices_mutex );
 }
 
 static struct device *find_device_from_handle( HANDLE handle )
@@ -503,14 +499,19 @@ BOOL rawinput_device_get_usages( HANDLE handle, USAGE *usage_page, USAGE *usage
 {
     struct device *device;
 
-    *usage_page = *usage = 0;
+    pthread_mutex_lock( &rawinput_mutex );
+
+    if (!(device = find_device_from_handle( handle )) || device->info.dwType != RIM_TYPEHID)
+        *usage_page = *usage = 0;
+    else
+    {
+        *usage_page = device->info.hid.usUsagePage;
+        *usage = device->info.hid.usUsage;
+    }
 
-    if (!(device = find_device_from_handle( handle ))) return FALSE;
-    if (device->info.dwType != RIM_TYPEHID) return FALSE;
+    pthread_mutex_unlock( &rawinput_mutex );
 
-    *usage_page = device->info.hid.usUsagePage;
-    *usage = device->info.hid.usUsage;
-    return TRUE;
+    return *usage_page || *usage;
 }
 
 /**********************************************************************
@@ -535,12 +536,16 @@ UINT WINAPI NtUserGetRawInputDeviceList( RAWINPUTDEVICELIST *devices, UINT *devi
         return ~0u;
     }
 
+    pthread_mutex_lock( &rawinput_mutex );
+
     if (ticks - last_check > 2000)
     {
         last_check = ticks;
         rawinput_update_device_list();
     }
 
+    pthread_mutex_unlock( &rawinput_mutex );
+
     if (!devices)
     {
         *device_count = rawinput_devices_count;
@@ -580,13 +585,23 @@ UINT WINAPI NtUserGetRawInputDeviceInfo( HANDLE handle, UINT command, void *data
         SetLastError( ERROR_NOACCESS );
         return ~0u;
     }
+    if (command != RIDI_DEVICENAME && command != RIDI_DEVICEINFO && command != RIDI_PREPARSEDDATA)
+    {
+        FIXME( "Command %#x not implemented!\n", command );
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return ~0u;
+    }
+
+    pthread_mutex_lock( &rawinput_mutex );
+
     if (!(device = find_device_from_handle( handle )))
     {
+        pthread_mutex_unlock( &rawinput_mutex );
         SetLastError( ERROR_INVALID_HANDLE );
         return ~0u;
     }
 
-    data_len = *data_size;
+    len = data_len = *data_size;
     switch (command)
     {
     case RIDI_DEVICENAME:
@@ -612,13 +627,10 @@ UINT WINAPI NtUserGetRawInputDeviceInfo( HANDLE handle, UINT command, void *data
             memcpy( data, preparsed, len );
         *data_size = len;
         break;
-
-    default:
-        FIXME( "command %#x not supported\n", command );
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return ~0u;
     }
 
+    pthread_mutex_unlock( &rawinput_mutex );
+
     if (!data)
         return 0;
 
@@ -796,7 +808,9 @@ BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_d
 
     if (msg->message == WM_INPUT_DEVICE_CHANGE)
     {
+        pthread_mutex_lock( &rawinput_mutex );
         rawinput_update_device_list();
+        pthread_mutex_unlock( &rawinput_mutex );
     }
     else
     {




More information about the wine-cvs mailing list