From: Rémi Bernon rbernon@codeweavers.com
Fixes: 13a44865586f7697bb47bb48664ac0a90590a643 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57158 --- dlls/hidclass.sys/device.c | 21 ++++++++++++++------- dlls/hidclass.sys/hid.h | 2 +- dlls/hidclass.sys/pnp.c | 7 +++---- 3 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 440bf4de24c..ef97ab7d0c1 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -322,7 +322,7 @@ DWORD CALLBACK hid_device_thread(void *args) HIDP_DEVICE_DESC *desc; IO_STATUS_BLOCK io; BYTE *buffer; - DWORD res; + IRP *irp;
for (i = 0; i < ext->u.fdo.device_desc.CollectionDescLength; i++) { @@ -340,6 +340,9 @@ DWORD CALLBACK hid_device_thread(void *args)
do { + KEVENT irp_event; + void *events[2] = {&irp_event, &ext->u.fdo.halt_event}; + packet->reportId = buffer[0] = report_id; packet->reportBuffer = buffer; packet->reportBufferLen = input_length; @@ -350,8 +353,13 @@ DWORD CALLBACK hid_device_thread(void *args) packet->reportBufferLen--; }
- call_minidriver( IOCTL_HID_READ_REPORT, device, NULL, 0, - packet->reportBuffer, packet->reportBufferLen, &io ); + KeInitializeEvent( &irp_event, NotificationEvent, FALSE ); + irp = IoBuildDeviceIoControlRequest( IOCTL_HID_READ_REPORT, device, NULL, 0, packet->reportBuffer, + packet->reportBufferLen, TRUE, &irp_event, &io ); + + if (IoCallDriver( device, irp ) == STATUS_PENDING && + KeWaitForMultipleObjects( 2, events, WaitAny, Executive, KernelMode, FALSE, NULL, NULL )) + io.Status = STATUS_DELETE_PENDING;
if (io.Status == STATUS_SUCCESS) { @@ -371,11 +379,10 @@ DWORD CALLBACK hid_device_thread(void *args) hid_device_queue_input( pdo, packet, !!ext->u.fdo.poll_interval ); } } + } while (io.Status == STATUS_SUCCESS);
- res = WaitForSingleObject( ext->u.fdo.halt_event, ext->u.fdo.poll_interval ); - } while (res == WAIT_TIMEOUT); - - TRACE( "device thread exiting, res %#lx\n", res ); + if (io.Status) WARN( "device thread exiting with status %#lx\n", io.Status ); + else TRACE( "device thread exiting\n" ); return 1; }
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index d58143b34b1..3924c72dcc3 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -53,7 +53,7 @@ typedef struct _BASE_DEVICE_EXTENSION WCHAR serial[256];
ULONG poll_interval; - HANDLE halt_event; + KEVENT halt_event; HANDLE thread;
DEVICE_OBJECT **child_pdos; diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index e6ebbb05b32..71fbb8e4205 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -251,7 +251,7 @@ static NTSTATUS initialize_device( minidriver *minidriver, DEVICE_OBJECT *device }
ext->u.fdo.poll_interval = minidriver->minidriver.DevicesArePolled ? DEFAULT_POLL_INTERVAL : 0; - ext->u.fdo.halt_event = CreateEventA(NULL, TRUE, FALSE, NULL); + KeInitializeEvent( &ext->u.fdo.halt_event, NotificationEvent, FALSE ); return STATUS_SUCCESS; }
@@ -377,10 +377,9 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) case IRP_MN_REMOVE_DEVICE: if (ext->u.fdo.thread) { - SetEvent(ext->u.fdo.halt_event); + KeSetEvent( &ext->u.fdo.halt_event, IO_NO_INCREMENT, FALSE ); WaitForSingleObject(ext->u.fdo.thread, INFINITE); } - CloseHandle(ext->u.fdo.halt_event);
status = minidriver->PNPDispatch( device, irp ); HidP_FreeCollectionDescription( &ext->u.fdo.device_desc ); @@ -390,7 +389,7 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) return status;
case IRP_MN_SURPRISE_REMOVAL: - SetEvent(ext->u.fdo.halt_event); + KeSetEvent( &ext->u.fdo.halt_event, IO_NO_INCREMENT, FALSE ); return STATUS_SUCCESS;
default: