Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/tests/input.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 4a9be550bdc..998fcdd1943 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1599,6 +1599,7 @@ static void test_GetRawInputDeviceList(void) char nameA[128]; UINT sz, len; RID_DEVICE_INFO info; + HANDLE file;
/* get required buffer size */ name[0] = '\0'; @@ -1638,6 +1639,11 @@ static void test_GetRawInputDeviceList(void) ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %d\n", err); ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n"); 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) + ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u\n", wine_dbgstr_w(name), GetLastError()); + CloseHandle(file); }
/* check if variable changes from larger to smaller value */
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winebus.sys/main.c | 77 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 3616ebe8152..89ea65bba67 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -33,13 +33,16 @@ #include "setupapi.h" #include "cfgmgr32.h" #include "winioctl.h" +#include "hidusage.h" #include "ddk/wdm.h" #include "ddk/hidport.h" +#include "ddk/hidtypes.h" #include "wine/debug.h" #include "wine/unicode.h" #include "wine/list.h"
#include "bus.h" +#include "controller.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); WINE_DECLARE_DEBUG_CHANNEL(hid_report); @@ -66,6 +69,8 @@ static const WORD PID_XBOX_CONTROLLERS[] = {
static DRIVER_OBJECT *driver_obj;
+static DEVICE_OBJECT *mouse_obj; + HANDLE driver_key;
struct pnp_device @@ -767,6 +772,76 @@ static void WINAPI driver_unload(DRIVER_OBJECT *driver) NtClose(driver_key); }
+static NTSTATUS mouse_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *ret_length) +{ + TRACE("buffer %p, length %u.\n", buffer, length); + + *ret_length = sizeof(REPORT_HEADER) + sizeof(REPORT_TAIL); + if (length < sizeof(REPORT_HEADER) + sizeof(REPORT_TAIL)) + return STATUS_BUFFER_TOO_SMALL; + + memcpy(buffer, REPORT_HEADER, sizeof(REPORT_HEADER)); + memcpy(buffer + sizeof(REPORT_HEADER), REPORT_TAIL, sizeof(REPORT_TAIL)); + buffer[IDX_HEADER_PAGE] = HID_USAGE_PAGE_GENERIC; + buffer[IDX_HEADER_USAGE] = HID_USAGE_GENERIC_MOUSE; + + return STATUS_SUCCESS; +} + +static NTSTATUS mouse_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length) +{ + static const WCHAR nameW[] = {'W','i','n','e',' ','H','I','D',' ','m','o','u','s','e',0}; + if (index != HID_STRING_ID_IPRODUCT) + return STATUS_NOT_IMPLEMENTED; + if (length < ARRAY_SIZE(nameW)) + return STATUS_BUFFER_TOO_SMALL; + strcpyW(buffer, nameW); + return STATUS_SUCCESS; +} + +static NTSTATUS mouse_begin_report_processing(DEVICE_OBJECT *device) +{ + return STATUS_SUCCESS; +} + +static NTSTATUS mouse_set_output_report(DEVICE_OBJECT *device, UCHAR id, BYTE *report, DWORD length, ULONG_PTR *ret_length) +{ + FIXME("id %u, stub!\n", id); + return STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS mouse_get_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE *report, DWORD length, ULONG_PTR *ret_length) +{ + FIXME("id %u, stub!\n", id); + return STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS mouse_set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE *report, DWORD length, ULONG_PTR *ret_length) +{ + FIXME("id %u, stub!\n", id); + return STATUS_NOT_IMPLEMENTED; +} + +static const platform_vtbl mouse_vtbl = +{ + .get_reportdescriptor = mouse_get_reportdescriptor, + .get_string = mouse_get_string, + .begin_report_processing = mouse_begin_report_processing, + .set_output_report = mouse_set_output_report, + .get_feature_report = mouse_get_feature_report, + .set_feature_report = mouse_set_feature_report, +}; + +static void mouse_device_create(void) +{ + static const GUID wine_mouse_class = {0xdfe2580e,0x52fd,0x453d,{0xa2,0xc1,0x33,0x81,0xf2,0x32,0x68,0x4c}}; + static const WCHAR busidW[] = {'W','I','N','E','M','O','U','S','E',0}; + + mouse_obj = bus_create_hid_device(busidW, 0, 0, -1, 0, 0, busidW, FALSE, + &wine_mouse_class, &mouse_vtbl, 0); + IoInvalidateDeviceRelations(mouse_obj, BusRelations); +} + NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) { static const WCHAR SDL_enabledW[] = {'E','n','a','b','l','e',' ','S','D','L',0}; @@ -788,6 +863,8 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = hid_internal_dispatch; driver->DriverUnload = driver_unload;
+ mouse_device_create(); + if (check_bus_option(&SDL_enabled, 1)) { if (sdl_driver_init() == STATUS_SUCCESS)
Zebediah Figura zfigura@codeweavers.com writes:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
dlls/winebus.sys/main.c | 77 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
This breaks the tests:
../../../tools/runtest -q -P wine -T ../../.. -M advapi32.dll -p advapi32_test.exe service && touch service.ok service.c:1727: Test failed: Expected a process id for this running service (winehid) make: *** [Makefile:417: service.ok] Error 1
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- loader/winehid.inf.in | 1 + 1 file changed, 1 insertion(+)
diff --git a/loader/winehid.inf.in b/loader/winehid.inf.in index bd42bceeaac..566448e4a51 100644 --- a/loader/winehid.inf.in +++ b/loader/winehid.inf.in @@ -11,6 +11,7 @@ Wine hidraw device=device_section,HIDRAW Wine IOHID device=device_section,IOHID Wine libevent device=device_section,LNXEV Wine SDL HID device=device_section,SDLJOY +Wine mouse device=device_section,WINEMOUSE
[device_section.Services] AddService = winehid,0x2,svc_section
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- include/ntddmou.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 include/ntddmou.h
diff --git a/include/ntddmou.h b/include/ntddmou.h new file mode 100644 index 00000000000..828a3e30e58 --- /dev/null +++ b/include/ntddmou.h @@ -0,0 +1,24 @@ +/* + * Copyright 2019 Zebediah Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _NTDDMOU_ +#define _NTDDMOU_ + +DEFINE_GUID(GUID_DEVINTERFACE_MOUSE, 0x378de44c, 0x56ef, 0x11d1, 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd); + +#endif
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- An alternative approach is not to go through the HID stack, but rather to create a winemouse.sys directly. In the event that an application ever needs to use the mouse device, this may be easier than implementing translation to and from HID reports. On the other hand, given that evdev and hidraw can already expose mice, implementing mouhid.sys may be worthwhile anyway.
dlls/hidclass.sys/device.c | 9 +++++++++ dlls/hidclass.sys/hid.h | 3 +++ dlls/hidclass.sys/pnp.c | 5 +++++ 3 files changed, 17 insertions(+)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index e96177225ba..60506ec9ce7 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -33,6 +33,7 @@
#include "initguid.h" #include "devguid.h" +#include "ntddmou.h"
WINE_DEFAULT_DEBUG_CHANNEL(hid); WINE_DECLARE_DEBUG_CHANNEL(hid_report); @@ -122,6 +123,14 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device) return status; }
+ /* FIXME: This should probably be done in mouhid.sys. */ + if (ext->preparseData->caps.UsagePage == HID_USAGE_PAGE_GENERIC + && ext->preparseData->caps.Usage == HID_USAGE_GENERIC_MOUSE) + { + if (!IoRegisterDeviceInterface(device, &GUID_DEVINTERFACE_MOUSE, NULL, &ext->mouse_link_name)) + ext->is_mouse = TRUE; + } + return STATUS_SUCCESS;
error: diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index 0f82323dfb5..86d7bdf98f1 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -55,6 +55,9 @@ typedef struct _BASE_DEVICE_EXTENSION { KSPIN_LOCK irp_queue_lock; LIST_ENTRY irp_queue;
+ BOOL is_mouse; + UNICODE_STRING mouse_link_name; + /* Minidriver Specific stuff will end up here */ } BASE_DEVICE_EXTENSION;
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 8265efd9b4e..b5c99870148 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -215,6 +215,9 @@ NTSTATUS PNP_RemoveDevice(minidriver *minidriver, DEVICE_OBJECT *device, IRP *ir return rc; }
+ if (ext->is_mouse) + IoSetDeviceInterfaceState(&ext->mouse_link_name, FALSE); + if (irp) rc = minidriver->PNPDispatch(device, irp); HID_DeleteDevice(device); @@ -294,6 +297,8 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp) rc = minidriver->PNPDispatch(device, irp);
IoSetDeviceInterfaceState(&ext->link_name, TRUE); + if (ext->is_mouse) + IoSetDeviceInterfaceState(&ext->mouse_link_name, TRUE); return rc; } case IRP_MN_REMOVE_DEVICE:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/rawinput.c | 51 ++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 19 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 56ea2497d16..294926400fd 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -58,6 +58,33 @@ static CRITICAL_SECTION_DEBUG hid_devices_cs_debug = }; static CRITICAL_SECTION hid_devices_cs = { &hid_devices_cs_debug, -1, 0, 0, 0, 0 };
+static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size) +{ + unsigned int new_capacity, max_capacity; + void *new_elements; + + if (count <= *capacity) + return TRUE; + + max_capacity = ~(SIZE_T)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(4, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = max_capacity; + + if (!(new_elements = heap_realloc(*elements, new_capacity * size))) + return FALSE; + + *elements = new_elements; + *capacity = new_capacity; + + return TRUE; +} + static void find_hid_devices(void) { static ULONGLONG last_check; @@ -125,26 +152,12 @@ static void find_hid_devices(void) continue; }
- if (didx >= hid_devices_max) + if (!array_reserve((void **)&hid_devices, &hid_devices_max, didx + 1, sizeof(*hid_devices))) { - if (hid_devices) - { - hid_devices_max *= 2; - hid_devices = heap_realloc(hid_devices, - hid_devices_max * sizeof(hid_devices[0])); - } - else - { - hid_devices_max = 8; - hid_devices = heap_alloc(hid_devices_max * sizeof(hid_devices[0])); - } - if (!hid_devices) - { - ERR("Failed to allocate memory.\n"); - CloseHandle(file); - heap_free(path); - goto done; - } + ERR("Failed to allocate memory.\n"); + CloseHandle(file); + heap_free(path); + goto done; }
TRACE("Found HID device %s.\n", debugstr_w(path));
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=54376
Your paranoid android.
=== debian9 (32 bit report) ===
user32: input.c:2218: Test failed: expected WM_NCHITTEST message
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/rawinput.c | 142 +++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 68 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 294926400fd..49cf9f73a0d 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -85,20 +85,73 @@ 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) +{ + SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail; + struct hid_device *device; + HANDLE file; + WCHAR *path; + DWORD size; + + SetupDiGetDeviceInterfaceDetailW(set, iface, NULL, 0, &size, NULL); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + ERR("Failed to get device path, error %#x.\n", GetLastError()); + return FALSE; + } + if (!(detail = heap_alloc(size))) + { + ERR("Failed to allocate memory.\n"); + return FALSE; + } + detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); + SetupDiGetDeviceInterfaceDetailW(set, iface, detail, size, NULL, NULL); + + TRACE("Found HID device %s.\n", debugstr_w(detail->DevicePath)); + + if (!(path = heap_strdupW(detail->DevicePath))) + { + ERR("Failed to allocate memory.\n"); + heap_free(detail); + return NULL; + } + heap_free(detail); + + file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + if (file == INVALID_HANDLE_VALUE) + { + ERR("Failed to open device file %s, error %u.\n", debugstr_w(path), GetLastError()); + heap_free(path); + return NULL; + } + + if (!array_reserve((void **)&hid_devices, &hid_devices_max, hid_devices_count + 1, sizeof(*hid_devices))) + { + ERR("Failed to allocate memory.\n"); + CloseHandle(file); + heap_free(path); + return NULL; + } + + device = &hid_devices[hid_devices_count++]; + device->path = path; + device->file = file; + + return device; +} + static void find_hid_devices(void) { static ULONGLONG last_check;
SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) }; - SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail; - DWORD detail_size, needed; + struct hid_device *device; HIDD_ATTRIBUTES attr; - DWORD idx, didx; HIDP_CAPS caps; GUID hid_guid; HDEVINFO set; - HANDLE file; - WCHAR *path; + DWORD idx;
if (GetTickCount64() - last_check < 2000) return; @@ -108,87 +161,40 @@ static void find_hid_devices(void)
set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
- detail_size = sizeof(*detail) + (MAX_PATH * sizeof(WCHAR)); - if (!(detail = heap_alloc(detail_size))) - return; - detail->cbSize = sizeof(*detail); - EnterCriticalSection(&hid_devices_cs);
/* destroy previous list */ - for (didx = 0; didx < hid_devices_count; ++didx) + for (idx = 0; idx < hid_devices_count; ++idx) { - CloseHandle(hid_devices[didx].file); - heap_free(hid_devices[didx].path); + CloseHandle(hid_devices[idx].file); + heap_free(hid_devices[idx].path); }
- didx = 0; + hid_devices_count = 0; for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &hid_guid, idx, &iface); ++idx) { - if (!SetupDiGetDeviceInterfaceDetailW(set, &iface, detail, detail_size, &needed, NULL)) - { - if (!(detail = heap_realloc(detail, needed))) - { - ERR("Failed to allocate memory.\n"); - goto done; - } - detail_size = needed; - - SetupDiGetDeviceInterfaceDetailW(set, &iface, detail, detail_size, NULL, NULL); - } - - if (!(path = heap_strdupW(detail->DevicePath))) - { - ERR("Failed to allocate memory.\n"); - goto done; - } - - file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); - if (file == INVALID_HANDLE_VALUE) - { - ERR("Failed to open device file %s, error %u.\n", debugstr_w(path), GetLastError()); - heap_free(path); + if (!(device = add_device(set, &iface))) continue; - } - - if (!array_reserve((void **)&hid_devices, &hid_devices_max, didx + 1, sizeof(*hid_devices))) - { - ERR("Failed to allocate memory.\n"); - CloseHandle(file); - heap_free(path); - goto done; - } - - TRACE("Found HID device %s.\n", debugstr_w(path)); - - hid_devices[didx].path = path; - hid_devices[didx].file = file;
attr.Size = sizeof(HIDD_ATTRIBUTES); - if (!HidD_GetAttributes(file, &attr)) - WARN_(rawinput)("Failed to get attributes.\n"); - hid_devices[didx].info.dwVendorId = attr.VendorID; - hid_devices[didx].info.dwProductId = attr.ProductID; - hid_devices[didx].info.dwVersionNumber = attr.VersionNumber; + 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;
- if (!HidD_GetPreparsedData(file, &hid_devices[didx].data)) - WARN_(rawinput)("Failed to get preparsed data.\n"); + if (!HidD_GetPreparsedData(device->file, &device->data)) + WARN("Failed to get preparsed data.\n");
- if (!HidP_GetCaps(hid_devices[didx].data, &caps)) - WARN_(rawinput)("Failed to get caps.\n"); + if (!HidP_GetCaps(device->data, &caps)) + WARN("Failed to get caps.\n");
- hid_devices[didx].info.usUsagePage = caps.UsagePage; - hid_devices[didx].info.usUsage = caps.Usage; - - didx++; + device->info.usUsagePage = caps.UsagePage; + device->info.usUsage = caps.Usage; } - hid_devices_count = didx;
-done: LeaveCriticalSection(&hid_devices_cs); SetupDiDestroyDeviceInfoList(set); - heap_free(detail); }
/***********************************************************************
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@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); }
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=54378
Your paranoid android.
=== wxppro (32 bit report) ===
user32: input.c:1671: Test failed: Failed to open L"\??\Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\ACPI#PNP0303#4&2c5a7332&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\Root#RDP_MOU#0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\HID#Vid_0627&Pid_0001#6&2e2010ad&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\ACPI#PNP0F13#4&2c5a7332&0#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123
=== w2003std (32 bit report) ===
user32: input.c:1671: Test failed: Failed to open L"\??\Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\ACPI#PNP0303#4&2c5a7332&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\Root#RDP_MOU#0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\HID#Vid_0627&Pid_0001#6&2e2010ad&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\ACPI#PNP0F13#4&2c5a7332&0#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123
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=54372
Your paranoid android.
=== wxppro (32 bit report) ===
user32: input.c:1671: Test failed: Failed to open L"\??\Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\ACPI#PNP0303#4&2c5a7332&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\Root#RDP_MOU#0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\HID#Vid_0627&Pid_0001#6&2e2010ad&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\ACPI#PNP0F13#4&2c5a7332&0#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123
=== w2003std (32 bit report) ===
user32: input.c:1671: Test failed: Failed to open L"\??\Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\ACPI#PNP0303#4&2c5a7332&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\Root#RDP_MOU#0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\HID#Vid_0627&Pid_0001#6&2e2010ad&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123 input.c:1671: Test failed: Failed to open L"\??\ACPI#PNP0F13#4&2c5a7332&0#{378de44c-56ef-11d1-bc8c-00a0c91405dd}", error 123