[PATCH v2 4/4] hidclass.sys: Always read InputReportByteLength bytes when not polling.

Rémi Bernon rbernon at codeweavers.com
Wed Jan 12 10:24:00 CST 2022


This fixes several games (e.g. ICEY) not working well with DS4 gamepad
over bluetooth, as we fixup the input report sizes, and the game expects
them to be longer.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

v2: Fix length in the hid_report allocation.

 dlls/dinput/tests/hid.c    |  1 -
 dlls/hidclass.sys/device.c | 19 +++++++++++--------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/dlls/dinput/tests/hid.c b/dlls/dinput/tests/hid.c
index d6232d578ca..a0fd2f6c660 100644
--- a/dlls/dinput/tests/hid.c
+++ b/dlls/dinput/tests/hid.c
@@ -2314,7 +2314,6 @@ static void test_hidp( HANDLE file, HANDLE async_file, int report_id, BOOL polle
 
         ret = GetOverlappedResult( async_file, &overlapped, &value, TRUE );
         ok( ret, "GetOverlappedResult failed, last error %u\n", GetLastError() );
-        todo_wine_if( report_id )
         ok( value == caps.InputReportByteLength, "got length %u, expected %u\n", value, caps.InputReportByteLength );
 
         CloseHandle( overlapped.hEvent );
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index dd288a82b67..0744865f8f7 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -53,15 +53,16 @@ static void WINAPI read_cancel_routine(DEVICE_OBJECT *device, IRP *irp)
     IoCompleteRequest(irp, IO_NO_INCREMENT);
 }
 
-static struct hid_report *hid_report_create( HID_XFER_PACKET *packet )
+static struct hid_report *hid_report_create( HID_XFER_PACKET *packet, ULONG length )
 {
     struct hid_report *report;
 
-    if (!(report = malloc( offsetof( struct hid_report, buffer[packet->reportBufferLen] ) )))
+    if (!(report = malloc( offsetof( struct hid_report, buffer[length] ) )))
         return NULL;
     report->ref = 1;
-    report->length = packet->reportBufferLen;
-    memcpy( report->buffer, packet->reportBuffer, report->length );
+    report->length = length;
+    memcpy( report->buffer, packet->reportBuffer, packet->reportBufferLen );
+    memset( report->buffer + packet->reportBufferLen, 0, length - packet->reportBufferLen );
 
     return report;
 }
@@ -218,18 +219,19 @@ static struct hid_report *hid_queue_pop_report( struct hid_queue *queue )
 static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *packet )
 {
     BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
+    HIDP_COLLECTION_DESC *desc = ext->u.pdo.device_desc.CollectionDesc;
     const BOOL polled = ext->u.pdo.information.Polled;
+    ULONG size, report_len = polled ? packet->reportBufferLen : desc->InputLength;
     struct hid_report *last_report, *report;
     struct hid_queue *queue;
     LIST_ENTRY completed, *entry;
     RAWINPUT *rawinput;
-    ULONG size;
     KIRQL irql;
     IRP *irp;
 
     if (IsEqualGUID( ext->class_guid, &GUID_DEVINTERFACE_HID ))
     {
-        size = offsetof( RAWINPUT, data.hid.bRawData[packet->reportBufferLen] );
+        size = offsetof( RAWINPUT, data.hid.bRawData[report_len] );
         if (!(rawinput = malloc( size ))) ERR( "Failed to allocate rawinput data!\n" );
         else
         {
@@ -240,8 +242,9 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack
             rawinput->header.hDevice = ULongToHandle( ext->u.pdo.rawinput_handle );
             rawinput->header.wParam = RIM_INPUT;
             rawinput->data.hid.dwCount = 1;
-            rawinput->data.hid.dwSizeHid = packet->reportBufferLen;
+            rawinput->data.hid.dwSizeHid = report_len;
             memcpy( rawinput->data.hid.bRawData, packet->reportBuffer, packet->reportBufferLen );
+            memset( rawinput->data.hid.bRawData + packet->reportBufferLen, 0, report_len - packet->reportBufferLen );
 
             input.type = INPUT_HARDWARE;
             input.hi.uMsg = WM_INPUT;
@@ -253,7 +256,7 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack
         }
     }
 
-    if (!(last_report = hid_report_create( packet )))
+    if (!(last_report = hid_report_create( packet, report_len )))
     {
         ERR( "Failed to allocate hid_report!\n" );
         return;
-- 
2.34.1




More information about the wine-devel mailing list