Commit a8ab0fe0 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

hidclass.sys: Return STATUS_INVALID_PARAMETER when appropriate.

Instead of STATUS_BUFFER_TOO_SMALL when input report buffer length is less than InputReportByteLength. Signed-off-by: 's avatarRémi Bernon <rbernon@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 9c5ab964
...@@ -415,6 +415,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) ...@@ -415,6 +415,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
{ {
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
const WINE_HIDP_PREPARSED_DATA *data = ext->u.pdo.preparsed_data;
NTSTATUS status; NTSTATUS status;
BOOL removed; BOOL removed;
KIRQL irql; KIRQL irql;
...@@ -495,7 +496,8 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) ...@@ -495,7 +496,8 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
case IOCTL_HID_GET_INPUT_REPORT: case IOCTL_HID_GET_INPUT_REPORT:
{ {
HID_XFER_PACKET *packet; 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); BYTE *buffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
ULONG out_length; ULONG out_length;
...@@ -504,9 +506,9 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) ...@@ -504,9 +506,9 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER; irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
break; 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; break;
} }
...@@ -517,13 +519,13 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) ...@@ -517,13 +519,13 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
else else
packet->reportId = 0; packet->reportId = 0;
packet->reportBuffer = (BYTE *)packet + sizeof(*packet); 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) ); 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) 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; irp->IoStatus.Information = out_length;
} }
else else
......
...@@ -535,7 +535,7 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) ...@@ -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)) todo_wine_if(packet->reportId == 0x5a || (polled && report_id && packet->reportId == 0))
ok(packet->reportId == report_id, "got id %u\n", packet->reportId); 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->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen);
ok(!!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer); ok(!!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer);
......
...@@ -2445,9 +2445,7 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled ...@@ -2445,9 +2445,7 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = HidD_GetInputReport(file, report, caps.InputReportByteLength - 1); ret = HidD_GetInputReport(file, report, caps.InputReportByteLength - 1);
todo_wine
ok(!ret, "HidD_GetInputReport succeeded\n"); ok(!ret, "HidD_GetInputReport succeeded\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC),
"HidD_GetInputReport returned error %u\n", GetLastError()); "HidD_GetInputReport returned error %u\n", GetLastError());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment