diff --git a/src/sys/driver.h b/src/sys/driver.h index 05dc5bd4..b67ffcab 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -353,6 +353,7 @@ VOID FspQueueDelayedWorkItem(FSP_DELAYED_WORK_ITEM *DelayedWorkItem, LARGE_INTEG /* I/O queue */ #define FspIoqTimeout ((PIRP)1) +#define FspIoqCancelled ((PIRP)2) #define FspIoqPostIrp(Q, I, R) FspIoqPostIrpEx(Q, I, FALSE, R) #define FspIoqPostIrpBestEffort(Q, I, R)FspIoqPostIrpEx(Q, I, TRUE, R) typedef struct @@ -376,7 +377,8 @@ VOID FspIoqStop(FSP_IOQ *Ioq); BOOLEAN FspIoqStopped(FSP_IOQ *Ioq); VOID FspIoqRemoveExpired(FSP_IOQ *Ioq); BOOLEAN FspIoqPostIrpEx(FSP_IOQ *Ioq, PIRP Irp, BOOLEAN BestEffort, NTSTATUS *PResult); -PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout); +PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout, + PIRP CancellableIrp); BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint); BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp, NTSTATUS *PResult); diff --git a/src/sys/ioq.c b/src/sys/ioq.c index 37b931d1..aa6d53b9 100644 --- a/src/sys/ioq.c +++ b/src/sys/ioq.c @@ -477,17 +477,20 @@ BOOLEAN FspIoqPostIrpEx(FSP_IOQ *Ioq, PIRP Irp, BOOLEAN BestEffort, NTSTATUS *PR } } -PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout) +PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout, + PIRP CancellableIrp) { /* timeout of 0 normally means infinite wait; for us it means do not do any wait at all! */ if (0 != Timeout) { NTSTATUS Result; - Result = KeWaitForSingleObject(&Ioq->PendingIrpEvent, Executive, KernelMode, FALSE, - Timeout); - ASSERT(STATUS_SUCCESS == Result || STATUS_TIMEOUT == Result); + Result = FsRtlCancellableWaitForSingleObject(&Ioq->PendingIrpEvent, Timeout, + CancellableIrp); if (STATUS_TIMEOUT == Result) return FspIoqTimeout; + if (STATUS_CANCELLED == Result || STATUS_THREAD_IS_TERMINATING == Result) + return FspIoqCancelled; + ASSERT(STATUS_SUCCESS == Result); } FSP_IOQ_PEEK_CONTEXT PeekContext; PeekContext.IrpHint = 0 != BoundaryIrp ? BoundaryIrp : (PVOID)1; diff --git a/src/sys/volume.c b/src/sys/volume.c index 51f8d059..54772f9e 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -590,7 +590,7 @@ NTSTATUS FspVolumeTransact( KeQuerySystemTime(&Timeout); Timeout.QuadPart += FsvolDeviceExtension->VolumeParams.TransactTimeout * 10000ULL; /* convert millis to nanos and add to absolute time */ - while (0 == (PendingIrp = FspIoqNextPendingIrp(FsvolDeviceExtension->Ioq, 0, &Timeout))) + while (0 == (PendingIrp = FspIoqNextPendingIrp(FsvolDeviceExtension->Ioq, 0, &Timeout, Irp))) { if (FspIoqStopped(FsvolDeviceExtension->Ioq)) { @@ -598,10 +598,10 @@ NTSTATUS FspVolumeTransact( goto exit; } } - if (FspIoqTimeout == PendingIrp) + if (FspIoqTimeout == PendingIrp || FspIoqCancelled == PendingIrp) { Irp->IoStatus.Information = 0; - Result = STATUS_SUCCESS; + Result = FspIoqTimeout == PendingIrp ? STATUS_SUCCESS : STATUS_CANCELLED; goto exit; } @@ -651,7 +651,7 @@ NTSTATUS FspVolumeTransact( } /* get the next pending IRP, but do not go beyond the first reposted IRP! */ - PendingIrp = FspIoqNextPendingIrp(FsvolDeviceExtension->Ioq, RepostedIrp, 0); + PendingIrp = FspIoqNextPendingIrp(FsvolDeviceExtension->Ioq, RepostedIrp, 0, Irp); if (0 == PendingIrp) break; }