Signed-off-by: Rémi Bernon rbernon@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);