Rémi Bernon : hidclass.sys: Rewrite IOCTL_HID_WRITE_REPORT using hid_device_xfer_report.

Alexandre Julliard julliard at winehq.org
Mon Aug 9 16:21:43 CDT 2021


Module: wine
Branch: master
Commit: 94e59451022b7f468e3b51e3dda3680bcdcbe37c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=94e59451022b7f468e3b51e3dda3680bcdcbe37c

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Mon Aug  9 10:32:40 2021 +0200

hidclass.sys: Rewrite IOCTL_HID_WRITE_REPORT using hid_device_xfer_report.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/hidclass.sys/device.c           | 69 +++++-------------------------------
 dlls/ntoskrnl.exe/tests/driver_hid.c |  8 -----
 dlls/ntoskrnl.exe/tests/ntoskrnl.c   |  5 +--
 3 files changed, 9 insertions(+), 73 deletions(-)

diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 44965e118a2..8c0883bbec4 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -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 );
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c
index 83f546aa972..8111af23c06 100644
--- a/dlls/ntoskrnl.exe/tests/driver_hid.c
+++ b/dlls/ntoskrnl.exe/tests/driver_hid.c
@@ -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;
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 4909ab202a6..d49f6fe3c7e 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -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);
     }
 
 




More information about the wine-cvs mailing list