[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