diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index e2a2e7c39d4..83c0c1159ff 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -315,6 +315,7 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP buffer_len = stack->Parameters.DeviceIoControl.OutputBufferLength; buffer = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority ); break; + case IOCTL_HID_SET_FEATURE: case IOCTL_HID_SET_OUTPUT_REPORT: buffer_len = stack->Parameters.DeviceIoControl.InputBufferLength; buffer = irp->AssociatedIrp.SystemBuffer; @@ -330,6 +331,7 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP report_len = preparsed->caps.OutputReportByteLength; break; case IOCTL_HID_GET_FEATURE: + case IOCTL_HID_SET_FEATURE: report_len = preparsed->caps.FeatureReportByteLength; break; } @@ -362,51 +364,13 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP case IOCTL_HID_GET_INPUT_REPORT: call_minidriver( code, ext->u.pdo.parent_fdo, NULL, 0, &packet, sizeof(packet), &irp->IoStatus ); break; + case IOCTL_HID_SET_FEATURE: case IOCTL_HID_SET_OUTPUT_REPORT: call_minidriver( code, ext->u.pdo.parent_fdo, NULL, sizeof(packet), &packet, 0, &irp->IoStatus ); break; } } -static void HID_set_to_device( 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; - HID_XFER_PACKET packet; - ULONG max_len; - - TRACE_(hid_report)("Device %p Buffer length %i Buffer %p\n", device, irpsp->Parameters.DeviceIoControl.InputBufferLength, irp->AssociatedIrp.SystemBuffer); - packet.reportId = ((BYTE*)irp->AssociatedIrp.SystemBuffer)[0]; - if (packet.reportId == 0) - { - packet.reportBuffer = &((BYTE*)irp->AssociatedIrp.SystemBuffer)[1]; - packet.reportBufferLen = irpsp->Parameters.DeviceIoControl.InputBufferLength - 1; - max_len = data->caps.FeatureReportByteLength; - } - else - { - packet.reportBuffer = irp->AssociatedIrp.SystemBuffer; - packet.reportBufferLen = irpsp->Parameters.DeviceIoControl.InputBufferLength; - max_len = data->reports[data->reportIdx[HidP_Feature][packet.reportId]].bitSize; - max_len = (max_len + 7) / 8; - } - if (packet.reportBufferLen > max_len) - packet.reportBufferLen = max_len; - - TRACE_(hid_report)("(id %i, len %i buffer %p)\n", packet.reportId, packet.reportBufferLen, packet.reportBuffer); - - call_minidriver( irpsp->Parameters.DeviceIoControl.IoControlCode, ext->u.pdo.parent_fdo, NULL, - 0, &packet, sizeof(packet), &irp->IoStatus ); - - if (irp->IoStatus.Status == STATUS_SUCCESS) - irp->IoStatus.Information = irpsp->Parameters.DeviceIoControl.InputBufferLength; - else - irp->IoStatus.Information = 0; - - TRACE_(hid_report)( "Result 0x%x set %li bytes\n", irp->IoStatus.Status, irp->IoStatus.Information ); -} - NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); @@ -515,13 +479,11 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) break; } case IOCTL_HID_GET_FEATURE: + case IOCTL_HID_SET_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: - HID_set_to_device( device, irp ); - break; default: { ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode; diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c index 8ddbfe3850f..4f0a8591299 100644 --- a/dlls/ntoskrnl.exe/tests/driver_hid.c +++ b/dlls/ntoskrnl.exe/tests/driver_hid.c @@ -585,12 +585,11 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) { HID_XFER_PACKET *packet = irp->UserBuffer; ULONG expected_size = 17; - 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); + ok(in_size == sizeof(*packet), "got input size %u\n", in_size); + 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 == 16) 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 43a87add0f9..128a81a5f83 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -2530,14 +2530,12 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled SetLastError(0xdeadbeef); ret = HidD_SetFeature(file, report, 0); - todo_wine ok(!ret, "HidD_SetFeature succeeded\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetFeature returned error %u\n", GetLastError()); + ok(!ret, "HidD_SetFeature succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetFeature returned error %u\n", GetLastError()); SetLastError(0xdeadbeef); ret = HidD_SetFeature(file, report, caps.FeatureReportByteLength - 1); - todo_wine ok(!ret, "HidD_SetFeature succeeded\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), "HidD_SetFeature returned error %u\n", GetLastError()); @@ -2564,13 +2562,13 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled value = caps.FeatureReportByteLength * 2; SetLastError(0xdeadbeef); ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, NULL, 0, report, &value); - todo_wine ok(!ret, "IOCTL_HID_SET_FEATURE succeeded\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "IOCTL_HID_SET_FEATURE returned error %u\n", GetLastError()); + ok(!ret, "IOCTL_HID_SET_FEATURE succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "IOCTL_HID_SET_FEATURE returned error %u\n", GetLastError()); value = 0; SetLastError(0xdeadbeef); ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, report, caps.FeatureReportByteLength * 2, NULL, &value); ok(ret, "IOCTL_HID_SET_FEATURE 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); memset(report, 0xcd, sizeof(report));