Halo: Spartan Strike attempts to discover input devices using rawinput. It expects to be able to open at least one device file with a zero access mask. It does not perform any other operations on the file.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/rawinput.c | 116 +++++++++++++++++++++++--------------- dlls/user32/tests/input.c | 5 +- 2 files changed, 71 insertions(+), 50 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 85ff0c5e809..8d1048beb93 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -37,27 +37,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) { @@ -86,10 +89,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; @@ -127,7 +130,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); @@ -135,19 +139,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; @@ -160,18 +165,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))) @@ -180,9 +185,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"); @@ -190,12 +197,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; + } + + 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; }
- LeaveCriticalSection(&hid_devices_cs); SetupDiDestroyDeviceInfoList(set); + + LeaveCriticalSection(&rawinput_devices_cs); }
/*********************************************************************** @@ -219,18 +242,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; }
@@ -239,13 +262,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; }
/*********************************************************************** @@ -398,7 +421,7 @@ 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}; @@ -406,8 +429,8 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT 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 device *device = handle; RID_DEVICE_INFO info; - struct hid_device *hid_device = device; const void *to_copy; UINT to_copy_bytes, avail_bytes;
@@ -427,20 +450,20 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT case RIDI_DEVICENAME: /* for RIDI_DEVICENAME, data_size is in characters, not bytes */ avail_bytes = *data_size * sizeof(WCHAR); - if (device == WINE_MOUSE_HANDLE) + if (handle == WINE_MOUSE_HANDLE) { *data_size = ARRAY_SIZE(mouse_name); to_copy = mouse_name; } - else if (device == WINE_KEYBOARD_HANDLE) + else if (handle == WINE_KEYBOARD_HANDLE) { *data_size = ARRAY_SIZE(keyboard_name); to_copy = keyboard_name; } else { - *data_size = strlenW(hid_device->path) + 1; - to_copy = hid_device->path; + *data_size = strlenW(device->path) + 1; + to_copy = device->path; } to_copy_bytes = *data_size * sizeof(WCHAR); break; @@ -460,8 +483,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT } else { - info.dwType = RIM_TYPEHID; - info.u.hid = hid_device->info; + info = device->info; } to_copy_bytes = sizeof(info); *data_size = to_copy_bytes; @@ -479,9 +501,9 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT } else { - to_copy_bytes = ((WINE_HIDP_PREPARSED_DATA*)hid_device->data)->dwSize; + to_copy_bytes = ((WINE_HIDP_PREPARSED_DATA *)device->data)->dwSize; *data_size = to_copy_bytes; - to_copy = hid_device->data; + to_copy = device->data; } break;
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index ddaf7541e48..2b6a4974f17 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1689,7 +1689,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(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());
sz = 0; @@ -1719,8 +1719,7 @@ static void test_GetRawInputDeviceList(void) { /* succeeds on hardware, fails in some VMs */ br = HidD_GetPreparsedData(file, &preparsed); - todo_wine - ok(br == TRUE || broken(br == FALSE), "HidD_GetPreparsedData failed\n"); + ok(br == TRUE || broken(br == FALSE), "HidD_GetPreparsedData failed\n"); }
if (br)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=67491
Your paranoid android.
=== debiant (32 bit report) ===
user32: win.c:10089: Test failed: GetForegroundWindow() = 000D0120
=== debiant (32 bit Chinese:China report) ===
user32: msg.c:15837: Test failed: OpenClipboard failed, err=5 msg.c:15837: Test failed: EmptyClipboard failed, err=1418 msg.c:15837: Test failed: CloseClipboard failed, err=1418 msg.c:15848: Test failed: clear clipbd (no viewer, owner=1): 0: the msg sequence is not complete: expected 0307 - actual 0000
=== debiant (64 bit WoW report) ===
user32: clipboard.c:1383: Test failed: gle 5 clipboard.c:1385: Test failed: gle 1418 clipboard.c:1388: Test failed: got 00000000 clipboard.c:1389: Test failed: expected moveable mem 00000000 clipboard.c:1391: Test failed: got 00000000 clipboard.c:1392: Test failed: expected moveable mem 00000000 clipboard.c:1395: Test failed: got 00000000 clipboard.c:1396: Test failed: expected bitmap 00000000 clipboard.c:1398: Test failed: got 00000000 clipboard.c:1399: Test failed: expected bitmap 00000000 clipboard.c:1401: Test failed: got 00000000 clipboard.c:1402: Test failed: expected bitmap 00000000 clipboard.c:1404: Test failed: got 00000000 clipboard.c:1405: Test failed: expected palette 00000000 clipboard.c:1407: Test failed: got 00000000 clipboard.c:1408: Test failed: expected moveable mem 00000000 clipboard.c:1410: Test failed: got 00000000 clipboard.c:1411: Test failed: expected moveable mem 00000000 clipboard.c:1425: Test failed: got 00000000 clipboard.c:1426: Test failed: expected fixed mem 00000000 clipboard.c:1428: Test failed: got 00000000 clipboard.c:1429: Test failed: expected fixed mem 00000000 clipboard.c:1431: Test failed: got 00000000 clipboard.c:1432: Test failed: expected moveable mem 00000000 clipboard.c:1444: Test failed: wrong data 00000000 clipboard.c:1445: Test failed: expected moveable mem 00000000 clipboard.c:1448: Test failed: wrong data 00000000, cf 0000c040 clipboard.c:1449: Test failed: expected moveable mem 00000000 clipboard.c:1452: Test failed: wrong data 00000000 clipboard.c:1453: Test failed: expected moveable mem 00000000 clipboard.c:1456: Test failed: wrong data 00000000 clipboard.c:1457: Test failed: expected moveable mem 00000000 clipboard.c:1460: Test failed: wrong data 00000000 clipboard.c:1461: Test failed: expected fixed mem 00000000 clipboard.c:1464: Test failed: wrong data 00000000 clipboard.c:1465: Test failed: expected fixed mem 00000000 clipboard.c:1468: Test failed: wrong data 00000000 clipboard.c:1469: Test failed: expected moveable mem 00000000 clipboard.c:1475: Test failed: got 00000000 clipboard.c:1476: Test failed: expected moveable mem 00000000 clipboard.c:1477: Test failed: expected freed mem 00BE8522 clipboard.c:1480: Test failed: got 00000000 clipboard.c:1481: Test failed: expected fixed mem 00000000 clipboard.c:1486: Test failed: gle 1418 clipboard.c:1549: Test failed: wrong data 00000000 clipboard.c:1552: Test failed: wrong data 00000000, cf 0000c040 clipboard.c:1555: Test failed: wrong data 00000000 clipboard.c:1558: Test failed: wrong data 00000000 clipboard.c:1561: Test failed: wrong data 00000000 clipboard.c:1564: Test failed: wrong data 00000000 clipboard.c:1567: Test failed: wrong data 00000000 clipboard.c:1574: Test failed: expected fixed mem 00000000 clipboard.c:1576: Test failed: expected fixed mem 00000000 clipboard.c:1578: Test failed: expected fixed mem 00000000 clipboard.c:1580: Test failed: expected bitmap 00000000 clipboard.c:1582: Test failed: expected bitmap 00000000 clipboard.c:1584: Test failed: expected palette 00000000 clipboard.c:1586: Test failed: expected fixed mem 00000000 clipboard.c:1588: Test failed: expected fixed mem 00000000 clipboard.c:1600: Test failed: expected freed mem 00BE9D62 clipboard.c:1601: Test failed: expected freed mem 00BEB12A clipboard.c:1602: Test failed: expected freed mem 00BEC14A clipboard.c:1603: Test failed: expected freed mem 00BEC182 clipboard.c:1604: Test failed: expected freed mem 00BE8A52