[PATCH v2 3/3] user32: Use HID ioctls directly.

Zebediah Figura zfigura at codeweavers.com
Thu May 19 00:05:30 CDT 2022


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;
     }
 
     SetupDiDestroyDeviceInfoList(set);
@@ -760,12 +765,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;
 
-- 
2.35.1




More information about the wine-devel mailing list