mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
hidclass: Combine waits for pending IRP and I/O thread shutdown.
Fixes: 13a4486558
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57158
This commit is contained in:
parent
5834a6efad
commit
2aecb17285
Notes:
Alexandre Julliard
2024-09-12 23:36:48 +02:00
Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6486
3 changed files with 22 additions and 11 deletions
|
@ -321,8 +321,9 @@ DWORD CALLBACK hid_device_thread(void *args)
|
|||
HID_XFER_PACKET *packet;
|
||||
HIDP_DEVICE_DESC *desc;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
BYTE *buffer;
|
||||
DWORD res;
|
||||
IRP *irp;
|
||||
|
||||
for (i = 0; i < ext->u.fdo.device_desc.CollectionDescLength; i++)
|
||||
{
|
||||
|
@ -340,6 +341,9 @@ DWORD CALLBACK hid_device_thread(void *args)
|
|||
|
||||
do
|
||||
{
|
||||
LARGE_INTEGER delay = {.QuadPart = (LONGLONG)ext->u.fdo.poll_interval * -10000};
|
||||
KEVENT irp_event;
|
||||
|
||||
packet->reportId = buffer[0] = report_id;
|
||||
packet->reportBuffer = buffer;
|
||||
packet->reportBufferLen = input_length;
|
||||
|
@ -350,8 +354,15 @@ 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)
|
||||
{
|
||||
void *events[2] = {&irp_event, &ext->u.fdo.halt_event};
|
||||
status = KeWaitForMultipleObjects( 2, events, WaitAny, Executive, KernelMode, FALSE, NULL, NULL );
|
||||
if (status) break;
|
||||
}
|
||||
|
||||
if (io.Status == STATUS_SUCCESS)
|
||||
{
|
||||
|
@ -372,10 +383,11 @@ DWORD CALLBACK hid_device_thread(void *args)
|
|||
}
|
||||
}
|
||||
|
||||
res = WaitForSingleObject( ext->u.fdo.halt_event, ext->u.fdo.poll_interval );
|
||||
} while (res == WAIT_TIMEOUT);
|
||||
status = KeWaitForSingleObject( &ext->u.fdo.halt_event, Executive, KernelMode, FALSE, &delay );
|
||||
} while (status == STATUS_TIMEOUT);
|
||||
|
||||
TRACE( "device thread exiting, res %#lx\n", res );
|
||||
if (status) WARN( "device thread exiting with status %#lx\n", status );
|
||||
else TRACE( "device thread exiting\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue