From: Zebediah Figura <zfigura(a)codeweavers.com> wineusb enumerates new devices and completes IRPs from the same thread (as if it were an IRQ thread). On the other hand, the Hauppauge cx231xx USB driver performs I/O from within IRP_MN_START_DEVICE. If the wineusb "IRQ" thread is currently trying to report a new device, it won't be able to report I/O completion, resulting in a deadlock. Although wineusb could be modified to use more threads, these tests show that calling IoInvalidateDeviceRelations() should not block in this situation. --- dlls/ntoskrnl.exe/tests/driver_pnp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index a3e7329ae72..4b269f00bfc 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -275,6 +275,8 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp) todo_wine ok(!status, "Failed to wait for child plug event, status %#lx.\n", status); status = ZwSetEvent(device->plug_event2, NULL); ok(!status, "Failed to set event, status %#lx.\n", status); + status = ZwWaitForSingleObject(device->plug_event, TRUE, &wait_time); + todo_wine ok(!status, "Failed to wait for child plug event, status %#lx.\n", status); ret = STATUS_SUCCESS; break; @@ -648,6 +650,10 @@ static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code) ok(!status, "Failed to set event, status %#lx.\n", status); status = ZwWaitForSingleObject(device->plug_event2, TRUE, &wait_time); ok(!status, "Failed to wait for child plug event, status %#lx.\n", status); + /* IoInvalidateDeviceRelations() here shouldn't deadlock either. */ + IoInvalidateDeviceRelations(bus_pdo, BusRelations); + status = ZwSetEvent(device->plug_event, NULL); + ok(!status, "Failed to set event, status %#lx.\n", status); return STATUS_SUCCESS; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/413