diff --git a/Ext4Fsd/block.c b/Ext4Fsd/block.c index e756d66..2891b90 100644 --- a/Ext4Fsd/block.c +++ b/Ext4Fsd/block.c @@ -400,8 +400,15 @@ Ext2ReadWriteBlocks( } if (Ext2CanIWait()) { - KeWaitForSingleObject( &(pContext->Event), - Executive, KernelMode, FALSE, NULL ); + LARGE_INTEGER Timeout; + Timeout.QuadPart = (LONGLONG)-30 * 10 * 1000 * 1000; /* 30 seconds */ + Status = KeWaitForSingleObject( &(pContext->Event), + Executive, KernelMode, FALSE, &Timeout ); + if (Status == STATUS_TIMEOUT) { + /* Device likely removed — unblock and report error */ + MasterIrp->IoStatus.Status = STATUS_IO_TIMEOUT; + MasterIrp->IoStatus.Information = 0; + } KeClearEvent( &(pContext->Event) ); } else { bMasterCompleted = TRUE; @@ -496,15 +503,23 @@ Ext2ReadSync( Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); if (Status == STATUS_PENDING) { - KeWaitForSingleObject( + LARGE_INTEGER Timeout; + Timeout.QuadPart = (LONGLONG)-30 * 10 * 1000 * 1000; /* 30 seconds */ + Status = KeWaitForSingleObject( Event, Suspended, KernelMode, FALSE, - 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; + } } } __finally { @@ -610,8 +625,16 @@ Ext2DiskIoControl ( Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = IoStatus.Status; + LARGE_INTEGER Timeout; + Timeout.QuadPart = (LONGLONG)-30 * 10 * 1000 * 1000; /* 30 seconds */ + Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &Timeout); + if (Status == STATUS_TIMEOUT) { + IoCancelIrp(Irp); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = STATUS_IO_TIMEOUT; + } else { + Status = IoStatus.Status; + } } if (OutputBufferSize) { @@ -644,13 +667,21 @@ Ext2DiskShutDown(PEXT2_VCB Vcb) Status = IoCallDriver(Vcb->TargetDeviceObject, 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); - Status = IoStatus.Status; + if (Status == STATUS_TIMEOUT) { + IoCancelIrp(Irp); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = STATUS_IO_TIMEOUT; + } else { + Status = IoStatus.Status; + } } } else { Status = IoStatus.Status; diff --git a/Ext4Fsd/pnp.c b/Ext4Fsd/pnp.c index 08371a5..9382422 100644 --- a/Ext4Fsd/pnp.c +++ b/Ext4Fsd/pnp.c @@ -249,6 +249,9 @@ Ext2PnpRemove ( Status = Ext2LockVcb(Vcb, IrpContext->FileObject); ExReleaseResourceLite(&Vcb->MainResource); + /* Mark device removed early so concurrent I/O threads fail fast */ + SetLongFlag(Vcb->Flags, VCB_DEVICE_REMOVED); + // // Setup the Irp. We'll send it to the lower disk driver. // @@ -282,7 +285,6 @@ Ext2PnpRemove ( /* dismount volume */ bDeleted = Ext2CheckDismount(IrpContext, Vcb, TRUE); - SetLongFlag(Vcb->Flags, VCB_DEVICE_REMOVED); } __finally { @@ -319,6 +321,9 @@ Ext2PnpSurpriseRemove ( ExReleaseResourceLite(&Vcb->MainResource); + /* Mark device removed early so concurrent I/O threads fail fast */ + SetLongFlag(Vcb->Flags, VCB_DEVICE_REMOVED); + // // Setup the Irp. We'll send it to the lower disk driver. // @@ -352,7 +357,6 @@ Ext2PnpSurpriseRemove ( /* dismount volume */ bDeleted = Ext2CheckDismount(IrpContext, Vcb, TRUE); - SetLongFlag(Vcb->Flags, VCB_DEVICE_REMOVED); } __finally { diff --git a/Ext4Fsd/read.c b/Ext4Fsd/read.c index 1cadba7..788415d 100644 --- a/Ext4Fsd/read.c +++ b/Ext4Fsd/read.c @@ -879,6 +879,12 @@ Ext2Read (IN PEXT2_IRP_CONTEXT IrpContext) FileObject = IrpContext->FileObject; + if (IsFlagOn(Vcb->Flags, VCB_DEVICE_REMOVED)) { + Status = STATUS_NO_SUCH_DEVICE; + bCompleteRequest = TRUE; + __leave; + } + if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) && Vcb->LockFile != FileObject ) { Status = STATUS_ACCESS_DENIED; diff --git a/Ext4Fsd/write.c b/Ext4Fsd/write.c index 669563d..9cad131 100644 --- a/Ext4Fsd/write.c +++ b/Ext4Fsd/write.c @@ -1359,6 +1359,11 @@ Ext2Write (IN PEXT2_IRP_CONTEXT IrpContext) __leave; } + if (IsFlagOn(Vcb->Flags, VCB_DEVICE_REMOVED)) { + Status = STATUS_NO_SUCH_DEVICE; + __leave; + } + if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) && Vcb->LockFile != FileObject ) { Status = STATUS_ACCESS_DENIED;