[PATCH v2 4/6] hidclass.sys: Return STATUS_INVALID_PARAMETER when appropriate.

Rémi Bernon rbernon at codeweavers.com
Tue Aug 3 11:55:20 CDT 2021


Instead of STATUS_BUFFER_TOO_SMALL when input report buffer length is
less than InputReportByteLength.

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

diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 4d34c0d53d9..1ebe44f3f14 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -415,6 +415,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
 {
     IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
     BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
+    const WINE_HIDP_PREPARSED_DATA *data = ext->u.pdo.preparsed_data;
     NTSTATUS status;
     BOOL removed;
     KIRQL irql;
@@ -495,7 +496,8 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
         case IOCTL_HID_GET_INPUT_REPORT:
         {
             HID_XFER_PACKET *packet;
-            UINT packet_size = sizeof(*packet) + irpsp->Parameters.DeviceIoControl.OutputBufferLength;
+            ULONG buffer_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
+            UINT packet_size = sizeof(*packet) + buffer_len;
             BYTE *buffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
             ULONG out_length;
 
@@ -504,9 +506,9 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
                 irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
                 break;
             }
-            if (!irpsp->Parameters.DeviceIoControl.OutputBufferLength)
+            if (buffer_len < data->caps.InputReportByteLength)
             {
-                irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+                irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                 break;
             }
 
@@ -517,13 +519,13 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
             else
                 packet->reportId = 0;
             packet->reportBuffer = (BYTE *)packet + sizeof(*packet);
-            packet->reportBufferLen = irpsp->Parameters.DeviceIoControl.OutputBufferLength - 1;
+            packet->reportBufferLen = buffer_len - 1;
 
             irp->IoStatus.Status = call_minidriver( IOCTL_HID_GET_INPUT_REPORT, ext->u.pdo.parent_fdo, NULL, 0, packet, sizeof(*packet) );
 
             if (irp->IoStatus.Status == STATUS_SUCCESS)
             {
-                irp->IoStatus.Status = copy_packet_into_buffer( packet, buffer, irpsp->Parameters.DeviceIoControl.OutputBufferLength, &out_length );
+                irp->IoStatus.Status = copy_packet_into_buffer( packet, buffer, buffer_len, &out_length );
                 irp->IoStatus.Information = out_length;
             }
             else
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c
index f1289b8a1bb..a45e5f56928 100644
--- a/dlls/ntoskrnl.exe/tests/driver_hid.c
+++ b/dlls/ntoskrnl.exe/tests/driver_hid.c
@@ -535,7 +535,7 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
 
             todo_wine_if(packet->reportId == 0x5a || (polled && report_id && packet->reportId == 0))
             ok(packet->reportId == report_id, "got id %u\n", packet->reportId);
-            todo_wine_if(packet->reportBufferLen == 21 || packet->reportBufferLen == 22)
+            todo_wine_if(packet->reportBufferLen == 22)
             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 3c883edb7c8..91fa7e73c88 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -2445,9 +2445,7 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
 
     SetLastError(0xdeadbeef);
     ret = HidD_GetInputReport(file, report, caps.InputReportByteLength - 1);
-    todo_wine
     ok(!ret, "HidD_GetInputReport succeeded\n");
-    todo_wine
     ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC),
        "HidD_GetInputReport returned error %u\n", GetLastError());
 
-- 
2.32.0




More information about the wine-devel mailing list