Commit 3708bae0 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_FEATURE.

parent 25409b89
...@@ -315,6 +315,7 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP ...@@ -315,6 +315,7 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP
buffer_len = stack->Parameters.DeviceIoControl.OutputBufferLength; buffer_len = stack->Parameters.DeviceIoControl.OutputBufferLength;
buffer = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority ); buffer = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority );
break; break;
case IOCTL_HID_SET_FEATURE:
case IOCTL_HID_SET_OUTPUT_REPORT: case IOCTL_HID_SET_OUTPUT_REPORT:
buffer_len = stack->Parameters.DeviceIoControl.InputBufferLength; buffer_len = stack->Parameters.DeviceIoControl.InputBufferLength;
buffer = irp->AssociatedIrp.SystemBuffer; buffer = irp->AssociatedIrp.SystemBuffer;
...@@ -330,6 +331,7 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP ...@@ -330,6 +331,7 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP
report_len = preparsed->caps.OutputReportByteLength; report_len = preparsed->caps.OutputReportByteLength;
break; break;
case IOCTL_HID_GET_FEATURE: case IOCTL_HID_GET_FEATURE:
case IOCTL_HID_SET_FEATURE:
report_len = preparsed->caps.FeatureReportByteLength; report_len = preparsed->caps.FeatureReportByteLength;
break; break;
} }
...@@ -362,51 +364,13 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP ...@@ -362,51 +364,13 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP
case IOCTL_HID_GET_INPUT_REPORT: case IOCTL_HID_GET_INPUT_REPORT:
call_minidriver( code, ext->u.pdo.parent_fdo, NULL, 0, &packet, sizeof(packet), &irp->IoStatus ); call_minidriver( code, ext->u.pdo.parent_fdo, NULL, 0, &packet, sizeof(packet), &irp->IoStatus );
break; break;
case IOCTL_HID_SET_FEATURE:
case IOCTL_HID_SET_OUTPUT_REPORT: case IOCTL_HID_SET_OUTPUT_REPORT:
call_minidriver( code, ext->u.pdo.parent_fdo, NULL, sizeof(packet), &packet, 0, &irp->IoStatus ); call_minidriver( code, ext->u.pdo.parent_fdo, NULL, sizeof(packet), &packet, 0, &irp->IoStatus );
break; 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) NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
{ {
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
...@@ -515,13 +479,11 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) ...@@ -515,13 +479,11 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
break; break;
} }
case IOCTL_HID_GET_FEATURE: case IOCTL_HID_GET_FEATURE:
case IOCTL_HID_SET_FEATURE:
case IOCTL_HID_GET_INPUT_REPORT: case IOCTL_HID_GET_INPUT_REPORT:
case IOCTL_HID_SET_OUTPUT_REPORT: case IOCTL_HID_SET_OUTPUT_REPORT:
hid_device_xfer_report( ext, code, irp ); hid_device_xfer_report( ext, code, irp );
break; break;
case IOCTL_HID_SET_FEATURE:
HID_set_to_device( device, irp );
break;
default: default:
{ {
ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode; ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode;
......
...@@ -585,12 +585,11 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) ...@@ -585,12 +585,11 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
{ {
HID_XFER_PACKET *packet = irp->UserBuffer; HID_XFER_PACKET *packet = irp->UserBuffer;
ULONG expected_size = 17; ULONG expected_size = 17;
todo_wine ok(in_size == sizeof(*packet), "got input size %u\n", in_size); 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(!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); 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->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);
......
...@@ -2530,14 +2530,12 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled ...@@ -2530,14 +2530,12 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = HidD_SetFeature(file, report, 0); ret = HidD_SetFeature(file, report, 0);
todo_wine ok(!ret, "HidD_SetFeature succeeded\n"); ok(!ret, "HidD_SetFeature succeeded\n");
todo_wine ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetFeature returned error %u\n", GetLastError()); ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetFeature returned error %u\n", GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = HidD_SetFeature(file, report, caps.FeatureReportByteLength - 1); ret = HidD_SetFeature(file, report, caps.FeatureReportByteLength - 1);
todo_wine
ok(!ret, "HidD_SetFeature succeeded\n"); ok(!ret, "HidD_SetFeature succeeded\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC),
"HidD_SetFeature returned error %u\n", GetLastError()); "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 ...@@ -2564,13 +2562,13 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
value = caps.FeatureReportByteLength * 2; value = caps.FeatureReportByteLength * 2;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, NULL, 0, report, &value); ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, NULL, 0, report, &value);
todo_wine ok(!ret, "IOCTL_HID_SET_FEATURE succeeded\n"); 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(GetLastError() == ERROR_INVALID_USER_BUFFER, "IOCTL_HID_SET_FEATURE returned error %u\n", GetLastError());
value = 0; value = 0;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, report, caps.FeatureReportByteLength * 2, NULL, &value); 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()); 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)); memset(report, 0xcd, sizeof(report));
......
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