From 5c01ce9f00c273a56c6aa0ee7639f3ed1c3f3246 Mon Sep 17 00:00:00 2001 From: HorusGod Date: Thu, 5 Mar 2026 00:59:24 +0200 Subject: [PATCH] add timeouts to remaining infinite waits in pnp.c and fsctl.c The previous commit missed three infinite KeWaitForSingleObject calls: - pnp.c: Ext2PnpRemove and Ext2PnpSurpriseRemove wait forever for the lower driver to complete the PnP IRP after device removal - fsctl.c: Ext2IsMediaWriteProtected waits forever for the write-protect check IRP to complete All three now use 30-second timeouts with IRP cancellation on timeout, matching the pattern used in block.c. --- Ext4Fsd/fsctl.c | 14 +++++++++++--- Ext4Fsd/pnp.c | 35 +++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Ext4Fsd/fsctl.c b/Ext4Fsd/fsctl.c index ef5819f..ca2b18d 100644 --- a/Ext4Fsd/fsctl.c +++ b/Ext4Fsd/fsctl.c @@ -2019,14 +2019,22 @@ Ext2IsMediaWriteProtected ( Status = IoCallDriver(TargetDevice, Irp); if (Status == STATUS_PENDING) { + LARGE_INTEGER Timeout; + Timeout.QuadPart = (LONGLONG)-30 * 10 * 1000 * 1000; /* 30 seconds */ - (VOID) KeWaitForSingleObject( &Event, + Status = KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, - (PLARGE_INTEGER)NULL ); + &Timeout ); - Status = IoStatus.Status; + if (Status == STATUS_TIMEOUT) { + IoCancelIrp(Irp); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = STATUS_IO_TIMEOUT; + } else { + Status = IoStatus.Status; + } } return (BOOLEAN)(Status == STATUS_MEDIA_WRITE_PROTECTED); diff --git a/Ext4Fsd/pnp.c b/Ext4Fsd/pnp.c index 9382422..fc58057 100644 --- a/Ext4Fsd/pnp.c +++ b/Ext4Fsd/pnp.c @@ -198,11 +198,20 @@ Ext2PnpQueryRemove ( IrpContext->Irp); if (Status == STATUS_PENDING) { - KeWaitForSingleObject( &Event, + LARGE_INTEGER Timeout; + Timeout.QuadPart = (LONGLONG)-30 * 10 * 1000 * 1000; /* 30 seconds */ + + Status = KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, - NULL ); + &Timeout ); + + if (Status == STATUS_TIMEOUT) { + IoCancelIrp(IrpContext->Irp); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + } + Status = IrpContext->Irp->IoStatus.Status; } @@ -270,12 +279,19 @@ Ext2PnpRemove ( IrpContext->Irp); if (Status == STATUS_PENDING) { + LARGE_INTEGER Timeout; + Timeout.QuadPart = (LONGLONG)-30 * 10 * 1000 * 1000; /* 30 seconds */ - KeWaitForSingleObject( &Event, + Status = KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, - NULL ); + &Timeout ); + + if (Status == STATUS_TIMEOUT) { + IoCancelIrp(IrpContext->Irp); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + } Status = IrpContext->Irp->IoStatus.Status; } @@ -342,12 +358,19 @@ Ext2PnpSurpriseRemove ( IrpContext->Irp); if (Status == STATUS_PENDING) { + LARGE_INTEGER Timeout; + Timeout.QuadPart = (LONGLONG)-30 * 10 * 1000 * 1000; /* 30 seconds */ - KeWaitForSingleObject( &Event, + Status = KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, - NULL ); + &Timeout ); + + if (Status == STATUS_TIMEOUT) { + IoCancelIrp(IrpContext->Irp); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + } Status = IrpContext->Irp->IoStatus.Status; }