From a8ab0fe08f02edd52432bb8f2440a47c7ad6ccbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Tue, 3 Aug 2021 18:55:20 +0200 Subject: [PATCH] hidclass.sys: Return STATUS_INVALID_PARAMETER when appropriate. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of STATUS_BUFFER_TOO_SMALL when input report buffer length is less than InputReportByteLength. Signed-off-by: RĂ©mi Bernon Signed-off-by: Alexandre Julliard --- 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());