[PATCH 4/5] user32: Use rawinput device handles to identify devices.

Rémi Bernon rbernon at codeweavers.com
Mon Apr 26 05:38:02 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/user32/rawinput.c    | 32 +++++++++++++++++++++++++++++---
 dlls/user32/tests/input.c |  2 +-
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index ad93517ae8a..a2cf5769fcc 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -50,6 +50,7 @@ struct device
 {
     SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
     HANDLE file;
+    HANDLE handle;
     RID_DEVICE_INFO info;
     PHIDP_PREPARSED_DATA data;
 };
@@ -100,7 +101,7 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
     struct device *device;
     UINT32 handle;
     HANDLE file;
-    DWORD size, type;
+    DWORD i, size, type;
 
     SetupDiGetDeviceInterfaceDetailW(set, iface, NULL, 0, &size, &device_data);
     if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
@@ -116,6 +117,15 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
         return NULL;
     }
 
+    for (i = 0; i < rawinput_devices_count; ++i)
+    {
+        if (rawinput_devices[i].handle == UlongToHandle(handle))
+        {
+            TRACE("Updating device %x / %s\n", handle, debugstr_w(rawinput_devices[i].detail->DevicePath));
+            return rawinput_devices + i;
+        }
+    }
+
     if (!(detail = malloc(size)))
     {
         ERR("Failed to allocate memory.\n");
@@ -147,6 +157,7 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
     device = &rawinput_devices[rawinput_devices_count++];
     device->detail = detail;
     device->file = file;
+    device->handle = ULongToHandle(handle);
     device->info.cbSize = sizeof(RID_DEVICE_INFO);
     device->data = NULL;
 
@@ -244,6 +255,20 @@ static void find_devices(void)
 }
 
 
+static struct device *find_device_from_handle(HANDLE handle)
+{
+    UINT i;
+    for (i = 0; i < rawinput_devices_count; ++i)
+        if (rawinput_devices[i].handle == handle)
+            return rawinput_devices + i;
+    find_devices();
+    for (i = 0; i < rawinput_devices_count; ++i)
+        if (rawinput_devices[i].handle == handle)
+            return rawinput_devices + i;
+    return NULL;
+}
+
+
 struct rawinput_thread_data *rawinput_thread_data(void)
 {
     struct user_thread_info *thread_info = get_user_thread_info();
@@ -401,7 +426,7 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
 
     for (i = 0; i < rawinput_devices_count; ++i)
     {
-        devices[2 + i].hDevice = &rawinput_devices[i];
+        devices[2 + i].hDevice = rawinput_devices[i].handle;
         devices[2 + i].dwType = rawinput_devices[i].info.dwType;
     }
 
@@ -671,7 +696,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
     static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
 
     RID_DEVICE_INFO info;
-    struct device *device = handle;
+    struct device *device;
     const void *to_copy;
     UINT to_copy_bytes, avail_bytes;
 
@@ -679,6 +704,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
             handle, command, data, data_size);
 
     if (!data_size) return ~0U;
+    if (!(device = find_device_from_handle(handle))) return ~0U;
 
     /* each case below must set:
      *     *data_size: length (meaning defined by command) of data we want to copy
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 2397b4104e4..b86194e6d0d 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -1885,7 +1885,7 @@ static void test_GetRawInputDeviceList(void)
          * understand that; so use the \\?\ prefix instead */
         name[1] = '\\';
         file = CreateFileW(name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
-        todo_wine_if(i == 0 || i == 1)
+        todo_wine_if(info.dwType == RIM_TYPEMOUSE || info.dwType == RIM_TYPEKEYBOARD)
             ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u\n", wine_dbgstr_w(name), GetLastError());
 
         sz = 0;
-- 
2.31.0




More information about the wine-devel mailing list