Rémi Bernon : winebus.sys: Keep a separate report buffer for each input report id.

Alexandre Julliard julliard at winehq.org
Fri Oct 8 14:12:26 CDT 2021


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

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Fri Oct  8 10:01:24 2021 +0200

winebus.sys: Keep a separate report buffer for each input report id.

And use them for IOCTL_HID_GET_INPUT_REPORT ioctls.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51824
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winebus.sys/main.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 541f9052ed3..57a751655cc 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -76,6 +76,7 @@ struct device_extension
     ULONG report_desc_length;
     HIDP_DEVICE_DESC collection_desc;
 
+    BYTE *last_reports[256];
     BYTE *last_report;
     DWORD last_report_size;
     BOOL last_report_read;
@@ -444,6 +445,9 @@ static void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length
     ext->last_report_size = length;
     ext->last_report_read = FALSE;
 
+    if (!ext->collection_desc.ReportIDs[0].ReportID) memcpy(ext->last_reports[0], report, length);
+    else memcpy(ext->last_reports[report[0]], report, length);
+
     if ((irp = pop_pending_read(ext)))
     {
         stack = IoGetCurrentIrpStackLocation(irp);
@@ -815,6 +819,8 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
     struct device_extension *ext = device->DeviceExtension;
     NTSTATUS status = irp->IoStatus.Status;
     IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp);
+    HIDP_REPORT_IDS *reports;
+    ULONG i, size;
 
     TRACE("device %p, irp %p, minor function %#x.\n", device, irp, irpsp->MinorFunction);
 
@@ -849,8 +855,14 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
                     ERR("Failed to parse device %p report descriptor, status %#x\n", device, status);
                 else
                 {
-                    ext->state = DEVICE_STATE_STARTED;
                     status = STATUS_SUCCESS;
+                    reports = ext->collection_desc.ReportIDs;
+                    for (i = 0; i < ext->collection_desc.ReportIDsLength; ++i)
+                    {
+                        if (!(size = reports[i].InputLength)) continue;
+                        if (!(ext->last_reports[reports[i].ReportID] = RtlAllocateHeap(GetProcessHeap(), 0, size))) status = STATUS_NO_MEMORY;
+                    }
+                    if (!status) ext->state = DEVICE_STATE_STARTED;
                 }
             }
             RtlLeaveCriticalSection(&ext->cs);
@@ -878,6 +890,12 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
             irp->IoStatus.Status = STATUS_SUCCESS;
             IoCompleteRequest(irp, IO_NO_INCREMENT);
 
+            reports = ext->collection_desc.ReportIDs;
+            for (i = 0; i < ext->collection_desc.ReportIDsLength; ++i)
+            {
+                if (!reports[i].InputLength) continue;
+                RtlFreeHeap(GetProcessHeap(), 0, ext->last_reports[reports[i].ReportID]);
+            }
             HidP_FreeCollectionDescription(&ext->collection_desc);
             RtlFreeHeap(GetProcessHeap(), 0, ext->report_desc);
 
@@ -1020,14 +1038,10 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
         }
         case IOCTL_HID_GET_INPUT_REPORT:
         {
-            HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
-            TRACE_(hid_report)("IOCTL_HID_GET_INPUT_REPORT\n");
-            irp->IoStatus.Status = deliver_last_report(ext,
-                packet->reportBufferLen, packet->reportBuffer,
-                &irp->IoStatus.Information);
-
-            if (irp->IoStatus.Status == STATUS_SUCCESS)
-                packet->reportBufferLen = irp->IoStatus.Information;
+            HID_XFER_PACKET *packet = (HID_XFER_PACKET *)irp->UserBuffer;
+            memcpy(packet->reportBuffer, ext->last_reports[packet->reportId], packet->reportBufferLen);
+            irp->IoStatus.Information = packet->reportBufferLen;
+            irp->IoStatus.Status = STATUS_SUCCESS;
             break;
         }
         case IOCTL_HID_READ_REPORT:




More information about the wine-cvs mailing list