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

hidclass.sys: Rewrite IOCTL_HID_WRITE_REPORT using hid_device_xfer_report.

parent e653a2e0
......@@ -320,6 +320,10 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP
buffer_len = stack->Parameters.DeviceIoControl.InputBufferLength;
buffer = irp->AssociatedIrp.SystemBuffer;
break;
case IOCTL_HID_WRITE_REPORT:
buffer_len = stack->Parameters.Write.Length;
buffer = irp->AssociatedIrp.SystemBuffer;
break;
}
switch (code)
......@@ -330,6 +334,7 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP
caps_end = caps + preparsed->value_caps_count[HidP_Input];
break;
case IOCTL_HID_SET_OUTPUT_REPORT:
case IOCTL_HID_WRITE_REPORT:
report_len = preparsed->caps.OutputReportByteLength;
caps = HID_OUTPUT_VALUE_CAPS( preparsed );
caps_end = caps + preparsed->value_caps_count[HidP_Output];
......@@ -379,7 +384,9 @@ static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP
break;
case IOCTL_HID_SET_FEATURE:
case IOCTL_HID_SET_OUTPUT_REPORT:
case IOCTL_HID_WRITE_REPORT:
call_minidriver( code, ext->u.pdo.parent_fdo, NULL, sizeof(packet), &packet, 0, &irp->IoStatus );
if (code == IOCTL_HID_WRITE_REPORT && packet.reportId) irp->IoStatus.Information--;
break;
}
}
......@@ -611,70 +618,10 @@ NTSTATUS WINAPI pdo_read(DEVICE_OBJECT *device, IRP *irp)
NTSTATUS WINAPI pdo_write(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;
NTSTATUS status;
ULONG max_len;
BOOL removed;
KIRQL irql;
KeAcquireSpinLock(&ext->u.pdo.lock, &irql);
removed = ext->u.pdo.removed;
KeReleaseSpinLock(&ext->u.pdo.lock, irql);
if (removed)
{
irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_DELETE_PENDING;
}
if (!irpsp->Parameters.Write.Length)
{
irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
IoCompleteRequest( irp, IO_NO_INCREMENT );
return STATUS_INVALID_USER_BUFFER;
}
if (irpsp->Parameters.Write.Length < data->caps.OutputReportByteLength)
{
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest( irp, IO_NO_INCREMENT );
return STATUS_INVALID_PARAMETER;
}
irp->IoStatus.Information = 0;
TRACE_(hid_report)("Device %p Buffer length %i Buffer %p\n", device, irpsp->Parameters.Write.Length, 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.Write.Length - 1;
max_len = data->caps.OutputReportByteLength;
}
else
{
packet.reportBuffer = irp->AssociatedIrp.SystemBuffer;
packet.reportBufferLen = irpsp->Parameters.Write.Length;
max_len = (data->reports[data->reportIdx[HidP_Output][packet.reportId]].bitSize + 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( IOCTL_HID_WRITE_REPORT, ext->u.pdo.parent_fdo, NULL, 0, &packet,
sizeof(packet), &irp->IoStatus );
if (irp->IoStatus.Status == STATUS_SUCCESS)
irp->IoStatus.Information = irpsp->Parameters.Write.Length;
else
irp->IoStatus.Information = 0;
TRACE_(hid_report)( "Result 0x%x wrote %li bytes\n", irp->IoStatus.Status, irp->IoStatus.Information );
hid_device_xfer_report( ext, IOCTL_HID_WRITE_REPORT, irp );
status = irp->IoStatus.Status;
IoCompleteRequest( irp, IO_NO_INCREMENT );
......
......@@ -503,22 +503,14 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
HID_XFER_PACKET *packet = irp->UserBuffer;
ULONG expected_size = 2;
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(packet->reportBufferLen >= expected_size, "got report size %u\n", packet->reportBufferLen);
if (report_id)
{
todo_wine_if(packet->reportBuffer[0] == 0xa5)
ok(packet->reportBuffer[0] == report_id, "got report id %x\n", packet->reportBuffer[0]);
}
else
{
todo_wine
ok(packet->reportBuffer[0] == 0xcd, "got first byte %x\n", packet->reportBuffer[0]);
}
irp->IoStatus.Information = 3;
ret = STATUS_SUCCESS;
......
......@@ -2630,11 +2630,8 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
ret = WriteFile(file, report, caps.OutputReportByteLength * 2, &value, NULL);
if (report_id || broken(!ret) /* w7u */)
{
todo_wine
ok(!ret, "WriteFile succeeded\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER, "WriteFile returned error %u\n", GetLastError());
todo_wine
ok(value == 0, "WriteFile wrote %u\n", value);
SetLastError(0xdeadbeef);
report[0] = report_id;
......@@ -2649,7 +2646,7 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled
else
{
ok(ret, "WriteFile failed, last error %u\n", GetLastError());
todo_wine ok(value == 3, "WriteFile wrote %u\n", value);
ok(value == 3, "WriteFile wrote %u\n", value);
}
......
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