Zebediah Figura : hidclass.sys: Always wait for the lower driver in hid_device_thread().

Alexandre Julliard julliard at winehq.org
Thu Apr 15 16:57:43 CDT 2021


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

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Wed Apr 14 23:22:07 2021 -0500

hidclass.sys: Always wait for the lower driver in hid_device_thread().

Doing otherwise may result in memory corruption. The lower driver should complete its IRPs on device removal anyway.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/hidclass.sys/device.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index fc1dfd07db1..6ca5e39e648 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -288,12 +288,11 @@ static DWORD CALLBACK hid_device_thread(void *args)
     IO_STATUS_BLOCK irp_status;
     HID_XFER_PACKET *packet;
     DWORD rc;
-    HANDLE events[2];
+    HANDLE event;
     NTSTATUS ntrc;
 
     BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
-    events[0] = CreateEventA(NULL, TRUE, FALSE, NULL);
-    events[1] = ext->halt_event;
+    event = CreateEventA(NULL, TRUE, FALSE, NULL);
 
     packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength);
     packet->reportBuffer = (BYTE *)packet + sizeof(*packet);
@@ -302,7 +301,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
     {
         while(1)
         {
-            ResetEvent(events[0]);
+            ResetEvent(event);
 
             packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength;
             packet->reportId = 0;
@@ -311,11 +310,11 @@ static DWORD CALLBACK hid_device_thread(void *args)
                 device, NULL, 0, packet, sizeof(*packet), TRUE, NULL,
                 &irp_status);
 
-            IoSetCompletionRoutine(irp, read_Completion, events[0], TRUE, TRUE, TRUE);
+            IoSetCompletionRoutine(irp, read_Completion, event, TRUE, TRUE, TRUE);
             ntrc = IoCallDriver(device, irp);
 
             if (ntrc == STATUS_PENDING)
-                WaitForMultipleObjects(2, events, FALSE, INFINITE);
+                WaitForSingleObject(event, INFINITE);
 
             if (irp->IoStatus.u.Status == STATUS_SUCCESS)
             {
@@ -339,19 +338,19 @@ static DWORD CALLBACK hid_device_thread(void *args)
 
         while(1)
         {
-            ResetEvent(events[0]);
+            ResetEvent(event);
 
             irp = IoBuildDeviceIoControlRequest(IOCTL_HID_READ_REPORT,
                 device, NULL, 0, packet->reportBuffer,
                 ext->preparseData->caps.InputReportByteLength, TRUE, NULL,
                 &irp_status);
 
-            IoSetCompletionRoutine(irp, read_Completion, events[0], TRUE, TRUE, TRUE);
+            IoSetCompletionRoutine(irp, read_Completion, event, TRUE, TRUE, TRUE);
             ntrc = IoCallDriver(device, irp);
 
             if (ntrc == STATUS_PENDING)
             {
-                WaitForMultipleObjects(2, events, FALSE, INFINITE);
+                WaitForSingleObject(event, INFINITE);
             }
 
             rc = WaitForSingleObject(ext->halt_event, 0);
@@ -376,8 +375,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
         }
     }
 
-    /* FIXME: releasing packet requires IRP cancellation support */
-    CloseHandle(events[0]);
+    CloseHandle(event);
 
     TRACE("Device thread exiting\n");
     return 1;




More information about the wine-cvs mailing list