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

hidclass.sys: Use hid_device_xfer_report for IOCTL_HID_SET_OUTPUT_REPORT.

parent a2c902e6
......@@ -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:
......
......@@ -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);
......
......@@ -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);
......
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