[PATCH 2/5] hidclass.sys: Use hid_device_xfer_report for IOCTL_HID_SET_OUTPUT_REPORT.

Rémi Bernon rbernon at codeweavers.com
Fri Aug 6 02:49:34 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/hidclass.sys/device.c           | 32 ++++++++++++++++++----------
 dlls/ntoskrnl.exe/tests/driver_hid.c |  3 +--
 dlls/ntoskrnl.exe/tests/ntoskrnl.c   |  8 +++----
 3 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 81ddd7e6d7e..8a57516d5d5 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -303,16 +303,32 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP
 {
     const WINE_HIDP_PREPARSED_DATA *preparsed = ext->u.pdo.preparsed_data;
     IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
-    ULONG report_len = 0, buffer_len = stack->Parameters.DeviceIoControl.OutputBufferLength;
-    BYTE *buffer = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority );
     BYTE report_id = HID_INPUT_VALUE_CAPS( preparsed )->report_id;
+    ULONG report_len = 0, buffer_len = 0;
     HID_XFER_PACKET packet;
+    BYTE *buffer = NULL;
+
+    switch (code)
+    {
+    case IOCTL_HID_GET_FEATURE:
+    case IOCTL_HID_GET_INPUT_REPORT:
+        buffer_len = stack->Parameters.DeviceIoControl.OutputBufferLength;
+        buffer = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority );
+        break;
+    case IOCTL_HID_SET_OUTPUT_REPORT:
+        buffer_len = stack->Parameters.DeviceIoControl.InputBufferLength;
+        buffer = irp->AssociatedIrp.SystemBuffer;
+        break;
+    }
 
     switch (code)
     {
     case IOCTL_HID_GET_INPUT_REPORT:
         report_len = preparsed->caps.InputReportByteLength;
         break;
+    case IOCTL_HID_SET_OUTPUT_REPORT:
+        report_len = preparsed->caps.OutputReportByteLength;
+        break;
     case IOCTL_HID_GET_FEATURE:
         report_len = preparsed->caps.FeatureReportByteLength;
         break;
@@ -357,19 +373,13 @@ static void HID_set_to_device( DEVICE_OBJECT *device, IRP *irp )
     {
         packet.reportBuffer = &((BYTE*)irp->AssociatedIrp.SystemBuffer)[1];
         packet.reportBufferLen = irpsp->Parameters.DeviceIoControl.InputBufferLength - 1;
-        if (irpsp->Parameters.DeviceIoControl.IoControlCode == IOCTL_HID_SET_FEATURE)
-            max_len = data->caps.FeatureReportByteLength;
-        else
-            max_len = data->caps.OutputReportByteLength;
+        max_len = data->caps.FeatureReportByteLength;
     }
     else
     {
         packet.reportBuffer = irp->AssociatedIrp.SystemBuffer;
         packet.reportBufferLen = irpsp->Parameters.DeviceIoControl.InputBufferLength;
-        if (irpsp->Parameters.DeviceIoControl.IoControlCode == IOCTL_HID_SET_FEATURE)
-            max_len = data->reports[data->reportIdx[HidP_Feature][packet.reportId]].bitSize;
-        else
-            max_len = data->reports[data->reportIdx[HidP_Output][packet.reportId]].bitSize;
+        max_len = data->reports[data->reportIdx[HidP_Feature][packet.reportId]].bitSize;
         max_len = (max_len + 7) / 8;
     }
     if (packet.reportBufferLen > max_len)
@@ -497,10 +507,10 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
         }
         case IOCTL_HID_GET_FEATURE:
         case IOCTL_HID_GET_INPUT_REPORT:
+        case IOCTL_HID_SET_OUTPUT_REPORT:
             hid_device_xfer_report( ext, code, irp );
             break;
         case IOCTL_HID_SET_FEATURE:
-        case IOCTL_HID_SET_OUTPUT_REPORT:
             HID_set_to_device( device, irp );
             break;
         default:
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c
index d268b62d288..422b9b74daa 100644
--- a/dlls/ntoskrnl.exe/tests/driver_hid.c
+++ b/dlls/ntoskrnl.exe/tests/driver_hid.c
@@ -552,9 +552,8 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
             todo_wine ok(in_size == sizeof(*packet), "got input size %u\n", in_size);
             todo_wine ok(!out_size, "got output size %u\n", out_size);
 
-            todo_wine_if(packet->reportId != report_id)
+            todo_wine_if(packet->reportId == 0x5a)
             ok(packet->reportId == report_id, "got id %u\n", packet->reportId);
-            todo_wine_if(packet->reportBufferLen == 0 || packet->reportBufferLen == 1)
             ok(packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen);
             ok(!!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer);
 
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 6c4dacf3a2d..b2b918001fe 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -2581,14 +2581,12 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
 
     SetLastError(0xdeadbeef);
     ret = HidD_SetOutputReport(file, report, 0);
-    todo_wine ok(!ret, "HidD_SetOutputReport succeeded\n");
+    ok(!ret, "HidD_SetOutputReport succeeded\n");
     todo_wine ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetOutputReport returned error %u\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = HidD_SetOutputReport(file, report, caps.OutputReportByteLength - 1);
-    todo_wine
     ok(!ret, "HidD_SetOutputReport succeeded\n");
-    todo_wine
     ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC),
        "HidD_SetOutputReport returned error %u\n", GetLastError());
 
@@ -2615,13 +2613,13 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
     value = caps.OutputReportByteLength * 2;
     SetLastError(0xdeadbeef);
     ret = sync_ioctl(file, IOCTL_HID_SET_OUTPUT_REPORT, NULL, 0, report, &value);
-    todo_wine ok(!ret, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n");
+    ok(!ret, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n");
     todo_wine ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "IOCTL_HID_SET_OUTPUT_REPORT returned error %u\n", GetLastError());
     value = 0;
     SetLastError(0xdeadbeef);
     ret = sync_ioctl(file, IOCTL_HID_SET_OUTPUT_REPORT, report, caps.OutputReportByteLength * 2, NULL, &value);
     ok(ret, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %u\n", GetLastError());
-    todo_wine ok(value == 3, "got length %u, expected 3\n", value);
+    ok(value == 3, "got length %u, expected 3\n", value);
 
 
     SetLastError(0xdeadbeef);
-- 
2.32.0




More information about the wine-devel mailing list