[PATCH v2 3/3] user32: Use HID ioctls directly.
Rémi Bernon
rbernon at codeweavers.com
Thu May 19 05:48:30 CDT 2022
On 5/19/22 10:42, Rémi Bernon wrote:
> On 5/19/22 07:05, Zebediah Figura wrote:
>> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
>> ---
>> v2: Keep the "preparsed" local variable.
>>
>> dlls/user32/Makefile.in | 2 +-
>> dlls/user32/rawinput.c | 45 +++++++++++++++++++++++------------------
>> 2 files changed, 26 insertions(+), 21 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 518396038d6..b3e83cf9d02 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;
>> @@ -146,7 +146,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);
>> }
>> @@ -177,7 +177,6 @@ void rawinput_update_device_list(void)
>> {
>> SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
>> struct device *device;
>> - HIDD_ATTRIBUTES attr;
>> HDEVINFO set;
>> DWORD idx;
>> @@ -188,7 +187,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);
>> }
>> @@ -198,26 +197,32 @@ void rawinput_update_device_list(void)
>> for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL,
>> &GUID_DEVINTERFACE_HID, idx, &iface); ++idx)
>> {
>> - const struct hid_preparsed_data *preparsed;
>> + HID_COLLECTION_INFORMATION info;
>> + IO_STATUS_BLOCK io;
>> + NTSTATUS status;
>> if (!(device = add_device(set, &iface)))
>> continue;
>> - attr.Size = sizeof(HIDD_ATTRIBUTES);
>> - if (!HidD_GetAttributes(device->file, &attr))
>> - WARN("Failed to get attributes.\n");
>> + status = NtDeviceIoControlFile( device->file, NULL, NULL,
>> NULL, &io, IOCTL_HID_GET_COLLECTION_INFORMATION,
>> + NULL, 0, &info, sizeof(info) );
>> + if (status)
>> + ERR( "Failed to get collection information, status
>> %#x.\n", status );
>> device->info.dwType = RIM_TYPEHID;
>> - device->info.hid.dwVendorId = attr.VendorID;
>> - device->info.hid.dwProductId = attr.ProductID;
>> - device->info.hid.dwVersionNumber = attr.VersionNumber;
>> + device->info.hid.dwVendorId = info.VendorID;
>> + device->info.hid.dwProductId = info.ProductID;
>> + device->info.hid.dwVersionNumber = info.VersionNumber;
>> - if (!HidD_GetPreparsedData(device->file, &device->data))
>> - WARN("Failed to get preparsed data.\n");
>> - preparsed = (struct hid_preparsed_data *)device->data;
>> + device->data = malloc( info.DescriptorSize );
>> - device->info.hid.usUsagePage = preparsed->usage_page;
>> - device->info.hid.usUsage = preparsed->usage;
>> + status = NtDeviceIoControlFile( device->file, NULL, NULL,
>> NULL, &io, IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
>> + NULL, 0, device->data,
>> info.DescriptorSize );
>> + if (status)
>> + ERR( "Failed to get collection descriptor, status
>> %#x.\n", status );
>> +
>> + device->info.hid.usUsagePage = device->data->usage_page;
>> + device->info.hid.usUsage = device->data->usage;
>> }
>
> You lose the checks that HidD_GetPreparsedData was doing here, although
> there wasn't really much error handling in the first place, it now gets
> worse.
>
> If IOCTL_HID_GET_COLLECTION_INFORMATION fails, this calls malloc with
> uninitialized value. Then malloc may also fail, silently now, when it
> was at least printing a warning before.
>
I think something like the attached patches could make error handling a
bit better, before changing the calls.
--
Rémi Bernon <rbernon at codeweavers.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-user32-Use-a-device_path-static-array-in-rawinput-de.patch
Type: text/x-patch
Size: 4583 bytes
Desc: not available
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20220519/7b23e38f/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-user32-Fill-rawinput-device-info-in-add_device.patch
Type: text/x-patch
Size: 6728 bytes
Desc: not available
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20220519/7b23e38f/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-user32-Better-handle-rawinput-add_device-failures.patch
Type: text/x-patch
Size: 2848 bytes
Desc: not available
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20220519/7b23e38f/attachment-0002.bin>
More information about the wine-devel
mailing list