From: Zebediah Figura Subject: [PATCH v2] user32: Also scan for mouse devices in GetRawInputDeviceList(). Message-Id: <20190708163227.8670-1-zfigura@codeweavers.com> Date: Mon, 8 Jul 2019 11:32:27 -0500 Signed-off-by: Zebediah Figura --- 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 d0dc4a8bcf3..78f46bb6bac 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1670,7 +1670,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()); CloseHandle(file); } -- 2.20.1