From: Zebediah Figura zfigura@codeweavers.com
--- dlls/user32/rawinput.c | 93 +++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 37 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index a014066f988..98f9f4ed313 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -94,15 +94,17 @@ static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int return TRUE; }
-static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface) +static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, DWORD type ) { SP_DEVINFO_DATA device_data = {sizeof(device_data)}; + PHIDP_PREPARSED_DATA preparsed_data = NULL; SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail; struct device *device = NULL; + RID_DEVICE_INFO info; UINT32 handle; + DWORD i, size; HANDLE file; WCHAR *pos; - DWORD i, size, type;
SetupDiGetDeviceInterfaceDetailW(set, iface, NULL, 0, &size, &device_data); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) @@ -138,6 +140,53 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface) return NULL; }
+ memset( &info, 0, sizeof(info) ); + info.cbSize = sizeof(info); + info.dwType = type; + + switch (type) + { + case RIM_TYPEHID: + { + HIDD_ATTRIBUTES attr; + HIDP_CAPS caps; + + attr.Size = sizeof(HIDD_ATTRIBUTES); + if (!HidD_GetAttributes( device->file, &attr )) + WARN("Failed to get attributes.\n"); + + info.hid.dwVendorId = attr.VendorID; + info.hid.dwProductId = attr.ProductID; + info.hid.dwVersionNumber = attr.VersionNumber; + + if (!HidD_GetPreparsedData( file, &preparsed_data )) + WARN("Failed to get preparsed data.\n"); + + if (!HidP_GetCaps( preparsed_data, &caps )) + WARN("Failed to get caps.\n"); + + info.hid.usUsagePage = caps.UsagePage; + info.hid.usUsage = caps.Usage; + break; + } + + case RIM_TYPEMOUSE: + { + static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE}; + + info.mouse = mouse_info; + break; + } + + case RIM_TYPEKEYBOARD: + { + static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101}; + + info.keyboard = keyboard_info; + break; + } + } + for (i = 0; i < rawinput_devices_count && !device; ++i) if (rawinput_devices[i].handle == UlongToHandle(handle)) device = rawinput_devices + i; @@ -166,8 +215,8 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface) device->detail = detail; device->file = file; device->handle = ULongToHandle(handle); - device->info.cbSize = sizeof(RID_DEVICE_INFO); - device->data = NULL; + device->info = info; + device->data = preparsed_data;
return device; } @@ -176,8 +225,6 @@ void rawinput_update_device_list(void) { SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) }; struct device *device; - HIDD_ATTRIBUTES attr; - HIDP_CAPS caps; GUID hid_guid; HDEVINFO set; DWORD idx; @@ -201,26 +248,8 @@ void rawinput_update_device_list(void)
for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &hid_guid, idx, &iface); ++idx) { - if (!(device = add_device(set, &iface))) + if (!(device = add_device( set, &iface, RIM_TYPEHID ))) continue; - - attr.Size = sizeof(HIDD_ATTRIBUTES); - if (!HidD_GetAttributes(device->file, &attr)) - WARN("Failed to get attributes.\n"); - - device->info.dwType = RIM_TYPEHID; - device->info.hid.dwVendorId = attr.VendorID; - device->info.hid.dwProductId = attr.ProductID; - device->info.hid.dwVersionNumber = attr.VersionNumber; - - if (!HidD_GetPreparsedData(device->file, &device->data)) - WARN("Failed to get preparsed data.\n"); - - if (!HidP_GetCaps(device->data, &caps)) - WARN("Failed to get caps.\n"); - - device->info.hid.usUsagePage = caps.UsagePage; - device->info.hid.usUsage = caps.Usage; }
SetupDiDestroyDeviceInfoList(set); @@ -229,13 +258,8 @@ void rawinput_update_device_list(void)
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))) + if (!(device = add_device( set, &iface, RIM_TYPEMOUSE ))) continue; - - device->info.dwType = RIM_TYPEMOUSE; - device->info.mouse = mouse_info; }
SetupDiDestroyDeviceInfoList(set); @@ -244,13 +268,8 @@ void rawinput_update_device_list(void)
for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_KEYBOARD, idx, &iface); ++idx) { - static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101}; - - if (!(device = add_device(set, &iface))) + if (!(device = add_device( set, &iface, RIM_TYPEHID ))) continue; - - device->info.dwType = RIM_TYPEKEYBOARD; - device->info.keyboard = keyboard_info; }
SetupDiDestroyDeviceInfoList(set);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/user32/rawinput.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 98f9f4ed313..08c2601181d 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -153,17 +153,26 @@ static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface,
attr.Size = sizeof(HIDD_ATTRIBUTES); if (!HidD_GetAttributes( device->file, &attr )) - WARN("Failed to get attributes.\n"); + { + ERR( "Failed to get attributes.\n" ); + goto fail; + }
info.hid.dwVendorId = attr.VendorID; info.hid.dwProductId = attr.ProductID; info.hid.dwVersionNumber = attr.VersionNumber;
if (!HidD_GetPreparsedData( file, &preparsed_data )) - WARN("Failed to get preparsed data.\n"); + { + ERR( "Failed to get preparsed data.\n" ); + goto fail; + }
if (!HidP_GetCaps( preparsed_data, &caps )) - WARN("Failed to get caps.\n"); + { + ERR( "Failed to get caps.\n" ); + goto fail; + }
info.hid.usUsagePage = caps.UsagePage; info.hid.usUsage = caps.Usage; @@ -207,9 +216,7 @@ static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, else { ERR("Failed to allocate memory.\n"); - CloseHandle(file); - free(detail); - return NULL; + goto fail; }
device->detail = detail; @@ -219,6 +226,12 @@ static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, device->data = preparsed_data;
return device; + +fail: + free( preparsed_data ); + CloseHandle( file ); + free( detail ); + return NULL; }
void rawinput_update_device_list(void)
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/rawinput.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 08c2601181d..34197701c24 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -148,8 +148,8 @@ static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, { case RIM_TYPEHID: { + const struct hid_preparsed_data *preparsed; HIDD_ATTRIBUTES attr; - HIDP_CAPS caps;
attr.Size = sizeof(HIDD_ATTRIBUTES); if (!HidD_GetAttributes( device->file, &attr )) @@ -167,15 +167,10 @@ static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, ERR( "Failed to get preparsed data.\n" ); goto fail; } + preparsed = (struct hid_preparsed_data *)preparsed_data;
- if (!HidP_GetCaps( preparsed_data, &caps )) - { - ERR( "Failed to get caps.\n" ); - goto fail; - } - - info.hid.usUsagePage = caps.UsagePage; - info.hid.usUsage = caps.Usage; + info.hid.usUsagePage = preparsed->usage_page; + info.hid.usUsage = preparsed->usage; break; }
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/rawinput.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 34197701c24..86f011579bf 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -38,6 +38,7 @@ #include "user_private.h"
#include "initguid.h" +#include "ddk/hidclass.h" #include "devpkey.h" #include "ntddmou.h" #include "ntddkbd.h" @@ -233,14 +234,11 @@ void rawinput_update_device_list(void) { SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) }; struct device *device; - GUID hid_guid; HDEVINFO set; DWORD idx;
TRACE("\n");
- HidD_GetHidGuid(&hid_guid); - EnterCriticalSection(&rawinput_devices_cs);
/* destroy previous list */ @@ -252,9 +250,9 @@ void rawinput_update_device_list(void) } rawinput_devices_count = 0;
- set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + set = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
- for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &hid_guid, idx, &iface); ++idx) + for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_HID, idx, &iface); ++idx) { if (!(device = add_device( set, &iface, RIM_TYPEHID ))) continue;
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/Makefile.in | 2 +- dlls/user32/rawinput.c | 55 ++++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in index 4a413746de7..c266d90c045 100644 --- a/dlls/user32/Makefile.in +++ b/dlls/user32/Makefile.in @@ -3,7 +3,7 @@ MODULE = user32.dll IMPORTLIB = user32 IMPORTS = $(PNG_PE_LIBS) gdi32 version sechost advapi32 kernelbase win32u EXTRAINCL = $(PNG_PE_CFLAGS) -DELAYIMPORTS = hid setupapi imm32 +DELAYIMPORTS = setupapi imm32
C_SRCS = \ button.c \ diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 86f011579bf..5dd3e01751b 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -26,11 +26,11 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winioctl.h" #include "winnls.h" #include "winreg.h" #include "winuser.h" #include "setupapi.h" -#include "ddk/hidsdi.h" #include "wine/debug.h" #include "wine/server.h" #include "wine/hid.h" @@ -53,7 +53,7 @@ struct device HANDLE file; HANDLE handle; RID_DEVICE_INFO info; - PHIDP_PREPARSED_DATA data; + struct hid_preparsed_data *data; };
static struct device *rawinput_devices; @@ -98,7 +98,7 @@ static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, DWORD type ) { SP_DEVINFO_DATA device_data = {sizeof(device_data)}; - PHIDP_PREPARSED_DATA preparsed_data = NULL; + struct hid_preparsed_data *preparsed_data = NULL; SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail; struct device *device = NULL; RID_DEVICE_INFO info; @@ -149,29 +149,40 @@ static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, { case RIM_TYPEHID: { - const struct hid_preparsed_data *preparsed; - HIDD_ATTRIBUTES attr; - - attr.Size = sizeof(HIDD_ATTRIBUTES); - if (!HidD_GetAttributes( device->file, &attr )) + HID_COLLECTION_INFORMATION hid_info; + IO_STATUS_BLOCK io; + NTSTATUS status; + + status = NtDeviceIoControlFile( device->file, NULL, NULL, NULL, &io, + IOCTL_HID_GET_COLLECTION_INFORMATION, + NULL, 0, &hid_info, sizeof(hid_info) ); + if (status) { - ERR( "Failed to get attributes.\n" ); + ERR( "Failed to get collection information, status %#x.\n", status ); goto fail; }
- info.hid.dwVendorId = attr.VendorID; - info.hid.dwProductId = attr.ProductID; - info.hid.dwVersionNumber = attr.VersionNumber; + info.hid.dwVendorId = hid_info.VendorID; + info.hid.dwProductId = hid_info.ProductID; + info.hid.dwVersionNumber = hid_info.VersionNumber; + + if (!(preparsed_data = malloc( hid_info.DescriptorSize ))) + { + ERR( "Failed to allocate memory.\n" ); + goto fail; + }
- if (!HidD_GetPreparsedData( file, &preparsed_data )) + status = NtDeviceIoControlFile( device->file, NULL, NULL, NULL, &io, + IOCTL_HID_GET_COLLECTION_DESCRIPTOR, + NULL, 0, preparsed_data, hid_info.DescriptorSize ); + if (status) { - ERR( "Failed to get preparsed data.\n" ); + ERR( "Failed to get collection descriptor, status %#x.\n", status ); goto fail; } - preparsed = (struct hid_preparsed_data *)preparsed_data;
- info.hid.usUsagePage = preparsed->usage_page; - info.hid.usUsage = preparsed->usage; + info.hid.usUsagePage = preparsed_data->usage_page; + info.hid.usUsage = preparsed_data->usage; break; }
@@ -199,7 +210,7 @@ static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, if (device) { TRACE("Updating device %x / %s.\n", handle, debugstr_w(detail->DevicePath)); - HidD_FreePreparsedData(device->data); + free(device->data); CloseHandle(device->file); free(device->detail); } @@ -244,7 +255,7 @@ void rawinput_update_device_list(void) /* destroy previous list */ for (idx = 0; idx < rawinput_devices_count; ++idx) { - HidD_FreePreparsedData(rawinput_devices[idx].data); + free(rawinput_devices[idx].data); CloseHandle(rawinput_devices[idx].file); free(rawinput_devices[idx].detail); } @@ -788,12 +799,12 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT break;
case RIDI_PREPARSEDDATA: - if (!(preparsed = (struct hid_preparsed_data *)device->data)) len = 0; + if (!(preparsed = device->data)) len = 0; else len = preparsed->caps_size + FIELD_OFFSET(struct hid_preparsed_data, value_caps[0]) + preparsed->number_link_collection_nodes * sizeof(struct hid_collection_node);
- if (device->data && len <= data_len && data) - memcpy(data, device->data, len); + if (preparsed && len <= data_len && data) + memcpy(data, preparsed, len); *data_size = len; break;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/user32/rawinput.c | 49 +++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 32 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 5dd3e01751b..8f393c6b330 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -241,13 +241,24 @@ fail: return NULL; }
-void rawinput_update_device_list(void) +static void enumerate_devices( DWORD type, const GUID *guid ) { - SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) }; - struct device *device; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; HDEVINFO set; DWORD idx;
+ set = SetupDiGetClassDevsW( guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT ); + + for (idx = 0; SetupDiEnumDeviceInterfaces( set, NULL, &GUID_DEVINTERFACE_HID, idx, &iface); ++idx ) + add_device( set, &iface, type ); + + SetupDiDestroyDeviceInfoList( set ); +} + +void rawinput_update_device_list(void) +{ + DWORD idx; + TRACE("\n");
EnterCriticalSection(&rawinput_devices_cs); @@ -261,35 +272,9 @@ void rawinput_update_device_list(void) } rawinput_devices_count = 0;
- set = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); - - for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_HID, idx, &iface); ++idx) - { - if (!(device = add_device( set, &iface, RIM_TYPEHID ))) - continue; - } - - 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) - { - if (!(device = add_device( set, &iface, RIM_TYPEMOUSE ))) - continue; - } - - SetupDiDestroyDeviceInfoList(set); - - set = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_KEYBOARD, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); - - for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_KEYBOARD, idx, &iface); ++idx) - { - if (!(device = add_device( set, &iface, RIM_TYPEHID ))) - continue; - } - - SetupDiDestroyDeviceInfoList(set); + enumerate_devices( RIM_TYPEHID, &GUID_DEVINTERFACE_HID ); + enumerate_devices( RIM_TYPEMOUSE, &GUID_DEVINTERFACE_MOUSE ); + enumerate_devices( RIM_TYPEKEYBOARD, &GUID_DEVINTERFACE_KEYBOARD );
LeaveCriticalSection(&rawinput_devices_cs); }
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=115518
Your paranoid android.
=== debian11 (64 bit WoW report) ===
user32: win.c:10976: Test failed: Expected foreground window 0, got 0000000001390054 win.c:10982: Test failed: Expected foreground window 00000000001A0124, got 0000000001390054
Rémi Bernon (@rbernon) commented about dlls/user32/rawinput.c:
case RIM_TYPEMOUSE:
{
static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
info.mouse = mouse_info;
break;
}
case RIM_TYPEKEYBOARD:
{
static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101};
info.keyboard = keyboard_info;
break;
}
You're missing the sign-off on some of the commits.
I also think that it'd be best to take that occasion to make the style used in this file more consistent with the rest of the module (and the file), so not indenting case statements. More of a nitpick, the mouse and keyboard cases could waste less vertical space with static declarations on top and single line cases.