[PATCH 8/8] user32: Also scan for mouse devices in GetRawInputDeviceList().

Zebediah Figura zfigura at codeweavers.com
Tue Jul 2 18:08:01 CDT 2019


Halo: Spartan Strike attempts to discover mice using rawinput. It expects to
be able to open the mouse device file with a zero access mask. It does not
perform any other operations on the file.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/user32/rawinput.c    | 124 ++++++++++++++++++++++----------------
 dlls/user32/tests/input.c |   2 +-
 2 files changed, 74 insertions(+), 52 deletions(-)

diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 49cf9f73a0d..e83da29009b 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -36,27 +36,30 @@
 
 #include "user_private.h"
 
+#include "initguid.h"
+#include "ntddmou.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
 
-struct hid_device
+struct device
 {
     WCHAR *path;
     HANDLE file;
-    RID_DEVICE_INFO_HID info;
+    RID_DEVICE_INFO info;
     PHIDP_PREPARSED_DATA data;
 };
 
-static struct hid_device *hid_devices;
-static unsigned int hid_devices_count, hid_devices_max;
+static struct device *rawinput_devices;
+static unsigned int rawinput_devices_count, rawinput_devices_max;
 
-static CRITICAL_SECTION hid_devices_cs;
-static CRITICAL_SECTION_DEBUG hid_devices_cs_debug =
+static CRITICAL_SECTION rawinput_devices_cs;
+static CRITICAL_SECTION_DEBUG rawinput_devices_cs_debug =
 {
-    0, 0, &hid_devices_cs,
-    { &hid_devices_cs_debug.ProcessLocksList, &hid_devices_cs_debug.ProcessLocksList },
-      0, 0, { (DWORD_PTR)(__FILE__ ": hid_devices_cs") }
+    0, 0, &rawinput_devices_cs,
+    { &rawinput_devices_cs_debug.ProcessLocksList, &rawinput_devices_cs_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": rawinput_devices_cs") }
 };
-static CRITICAL_SECTION hid_devices_cs = { &hid_devices_cs_debug, -1, 0, 0, 0, 0 };
+static CRITICAL_SECTION rawinput_devices_cs = { &rawinput_devices_cs_debug, -1, 0, 0, 0, 0 };
 
 static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
 {
@@ -85,10 +88,10 @@ static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int
     return TRUE;
 }
 
-static struct hid_device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
+static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
 {
     SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
-    struct hid_device *device;
+    struct device *device;
     HANDLE file;
     WCHAR *path;
     DWORD size;
@@ -126,7 +129,8 @@ static struct hid_device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *ifa
         return NULL;
     }
 
-    if (!array_reserve((void **)&hid_devices, &hid_devices_max, hid_devices_count + 1, sizeof(*hid_devices)))
+    if (!array_reserve((void **)&rawinput_devices, &rawinput_devices_max,
+            rawinput_devices_count + 1, sizeof(*rawinput_devices)))
     {
         ERR("Failed to allocate memory.\n");
         CloseHandle(file);
@@ -134,19 +138,20 @@ static struct hid_device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *ifa
         return NULL;
     }
 
-    device = &hid_devices[hid_devices_count++];
+    device = &rawinput_devices[rawinput_devices_count++];
     device->path = path;
     device->file = file;
+    device->info.cbSize = sizeof(RID_DEVICE_INFO);
 
     return device;
 }
 
-static void find_hid_devices(void)
+static void find_devices(void)
 {
     static ULONGLONG last_check;
 
     SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
-    struct hid_device *device;
+    struct device *device;
     HIDD_ATTRIBUTES attr;
     HIDP_CAPS caps;
     GUID hid_guid;
@@ -159,18 +164,18 @@ static void find_hid_devices(void)
 
     HidD_GetHidGuid(&hid_guid);
 
-    set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
-
-    EnterCriticalSection(&hid_devices_cs);
+    EnterCriticalSection(&rawinput_devices_cs);
 
     /* destroy previous list */
-    for (idx = 0; idx < hid_devices_count; ++idx)
+    for (idx = 0; idx < rawinput_devices_count; ++idx)
     {
-        CloseHandle(hid_devices[idx].file);
-        heap_free(hid_devices[idx].path);
+        CloseHandle(rawinput_devices[idx].file);
+        heap_free(rawinput_devices[idx].path);
     }
+    rawinput_devices_count = 0;
+
+    set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
 
-    hid_devices_count = 0;
     for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &hid_guid, idx, &iface); ++idx)
     {
         if (!(device = add_device(set, &iface)))
@@ -179,9 +184,11 @@ static void find_hid_devices(void)
         attr.Size = sizeof(HIDD_ATTRIBUTES);
         if (!HidD_GetAttributes(device->file, &attr))
             WARN("Failed to get attributes.\n");
-        device->info.dwVendorId = attr.VendorID;
-        device->info.dwProductId = attr.ProductID;
-        device->info.dwVersionNumber = attr.VersionNumber;
+
+        device->info.dwType = RIM_TYPEHID;
+        device->info.u.hid.dwVendorId = attr.VendorID;
+        device->info.u.hid.dwProductId = attr.ProductID;
+        device->info.u.hid.dwVersionNumber = attr.VersionNumber;
 
         if (!HidD_GetPreparsedData(device->file, &device->data))
             WARN("Failed to get preparsed data.\n");
@@ -189,12 +196,28 @@ static void find_hid_devices(void)
         if (!HidP_GetCaps(device->data, &caps))
             WARN("Failed to get caps.\n");
 
-        device->info.usUsagePage = caps.UsagePage;
-        device->info.usUsage = caps.Usage;
+        device->info.u.hid.usUsagePage = caps.UsagePage;
+        device->info.u.hid.usUsage = caps.Usage;
     }
 
-    LeaveCriticalSection(&hid_devices_cs);
     SetupDiDestroyDeviceInfoList(set);
+
+    set = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_MOUSE, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
+
+    for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_MOUSE, idx, &iface); ++idx)
+    {
+        static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
+
+        if (!(device = add_device(set, &iface)))
+            continue;
+
+        device->info.dwType = RIM_TYPEMOUSE;
+        device->info.u.mouse = mouse_info;
+    }
+
+    SetupDiDestroyDeviceInfoList(set);
+
+    LeaveCriticalSection(&rawinput_devices_cs);
 }
 
 /***********************************************************************
@@ -218,18 +241,18 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
         return ~0U;
     }
 
-    find_hid_devices();
+    find_devices();
 
     if (!devices)
     {
-        *device_count = 2 + hid_devices_count;
+        *device_count = 2 + rawinput_devices_count;
         return 0;
     }
 
-    if (*device_count < 2 + hid_devices_count)
+    if (*device_count < 2 + rawinput_devices_count)
     {
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        *device_count = 2 + hid_devices_count;
+        *device_count = 2 + rawinput_devices_count;
         return ~0U;
     }
 
@@ -238,13 +261,13 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
     devices[1].hDevice = WINE_KEYBOARD_HANDLE;
     devices[1].dwType = RIM_TYPEKEYBOARD;
 
-    for (i = 0; i < hid_devices_count; ++i)
+    for (i = 0; i < rawinput_devices_count; ++i)
     {
-        devices[2 + i].hDevice = &hid_devices[i];
-        devices[2 + i].dwType = RIM_TYPEHID;
+        devices[2 + i].hDevice = &rawinput_devices[i];
+        devices[2 + i].dwType = rawinput_devices[i].info.dwType;
     }
 
-    return 2 + hid_devices_count;
+    return 2 + rawinput_devices_count;
 }
 
 /***********************************************************************
@@ -386,41 +409,41 @@ UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT
 /***********************************************************************
  *              GetRawInputDeviceInfoW   (USER32.@)
  */
-UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT *data_size)
+UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT *data_size)
 {
     /* FIXME: Most of this is made up. */
     static const WCHAR keyboard_name[] = {'\\','\\','?','\\','W','I','N','E','_','K','E','Y','B','O','A','R','D',0};
     static const WCHAR mouse_name[] = {'\\','\\','?','\\','W','I','N','E','_','M','O','U','S','E',0};
     static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101};
     static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
-    struct hid_device *hid_device;
     const WCHAR *name = NULL;
     RID_DEVICE_INFO *info;
+    struct device *device;
     UINT s;
 
-    TRACE("device %p, command %#x, data %p, data_size %p.\n",
-            device, command, data, data_size);
+    TRACE("handle %p, command %#x, data %p, data_size %p.\n",
+            handle, command, data, data_size);
 
     if (!data_size) return ~0U;
 
     switch (command)
     {
     case RIDI_DEVICENAME:
-        if (device == WINE_MOUSE_HANDLE)
+        if (handle == WINE_MOUSE_HANDLE)
         {
             s = ARRAY_SIZE(mouse_name);
             name = mouse_name;
         }
-        else if (device == WINE_KEYBOARD_HANDLE)
+        else if (handle == WINE_KEYBOARD_HANDLE)
         {
             s = ARRAY_SIZE(keyboard_name);
             name = keyboard_name;
         }
         else
         {
-            hid_device = device;
-            s = strlenW(hid_device->path) + 1;
-            name = hid_device->path;
+            device = handle;
+            s = strlenW(device->path) + 1;
+            name = device->path;
         }
         break;
     case RIDI_DEVICEINFO:
@@ -450,21 +473,20 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT
 
     info = data;
     info->cbSize = sizeof(*info);
-    if (device == WINE_MOUSE_HANDLE)
+    if (handle == WINE_MOUSE_HANDLE)
     {
         info->dwType = RIM_TYPEMOUSE;
         info->u.mouse = mouse_info;
     }
-    else if (device == WINE_KEYBOARD_HANDLE)
+    else if (handle == WINE_KEYBOARD_HANDLE)
     {
         info->dwType = RIM_TYPEKEYBOARD;
         info->u.keyboard = keyboard_info;
     }
     else
     {
-        hid_device = device;
-        info->dwType = RIM_TYPEHID;
-        info->u.hid = hid_device->info;
+        device = handle;
+        *info = device->info;
     }
     return s;
 }
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 998fcdd1943..fd18743d659 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -1641,7 +1641,7 @@ static void test_GetRawInputDeviceList(void)
         ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%x\n", info.dwType);
 
         file = CreateFileW(name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
-        todo_wine_if(info.dwType != RIM_TYPEHID)
+        todo_wine_if(i == 0 || i == 1)
             ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u\n", wine_dbgstr_w(name), GetLastError());
         CloseHandle(file);
     }
-- 
2.20.1




More information about the wine-devel mailing list