https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bd2a40d57b6c13e76ba465...
commit bd2a40d57b6c13e76ba4659997d9a19cb4e5d8f1 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sat Oct 10 17:41:44 2020 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Sat Oct 17 16:13:05 2020 +0200
[NTOS:IO] Some fixes for IoRaiseHardError(). (#3302) CORE-14037
- Fix buggy retrieval of the current calling Irp->Tail.Overlay.Thread.
- The 4th argument (KernelRoutine) to the KeInitializeApc() is **NOT** optional; however its 5th argument (RundownRoutine) is. So use the mandatory routine for freeing the allocated APC instead. We don't use the rundown routine yet.
- Check whether the ExAllocatePoolWithTag() call failed or not before queueing the allocated APC. --- ntoskrnl/io/iomgr/error.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/ntoskrnl/io/iomgr/error.c b/ntoskrnl/io/iomgr/error.c index 171f02eac80..312b29f942a 100644 --- a/ntoskrnl/io/iomgr/error.c +++ b/ntoskrnl/io/iomgr/error.c @@ -484,14 +484,22 @@ IopLogWorker(IN PVOID Parameter) ExFreePoolWithTag(Message, TAG_IO); }
+static VOID NTAPI -IopFreeApc(IN PKAPC Apc) +IopFreeApc(IN PKAPC Apc, + IN OUT PKNORMAL_ROUTINE* NormalRoutine, + IN OUT PVOID* NormalContext, + IN OUT PVOID* SystemArgument1, + IN OUT PVOID* SystemArgument2) { + PAGED_CODE(); + /* Free the APC */ - ExFreePool(Apc); + ExFreePoolWithTag(Apc, TAG_APC); }
+static VOID NTAPI IopRaiseHardError(IN PVOID NormalContext, @@ -657,7 +665,7 @@ IoRaiseHardError(IN PIRP Irp, IN PVPB Vpb, IN PDEVICE_OBJECT RealDeviceObject) { - PETHREAD Thread = (PETHREAD)&Irp->Tail.Overlay.Thread; + PETHREAD Thread = Irp->Tail.Overlay.Thread; PKAPC ErrorApc;
/* Don't do anything if hard errors are disabled on the thread */ @@ -669,21 +677,29 @@ IoRaiseHardError(IN PIRP Irp, return; }
- /* Setup an APC */ - ErrorApc = ExAllocatePoolWithTag(NonPagedPool, - sizeof(KAPC), - TAG_APC); + // TODO: In case we were called in the context of a paging I/O or for + // a synchronous operation, that happens with APCs disabled, queue the + // hard-error call for later processing (see also IofCompleteRequest). + + /* Setup an APC and queue it to deal with the error (see OSR documentation) */ + ErrorApc = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ErrorApc), TAG_APC); + if (!ErrorApc) + { + /* Fail */ + IoCompleteRequest(Irp, IO_DISK_INCREMENT); + return; + } + KeInitializeApc(ErrorApc, &Thread->Tcb, Irp->ApcEnvironment, - NULL, IopFreeApc, + NULL, IopRaiseHardError, KernelMode, Irp);
- /* Queue an APC to deal with the error (see osr documentation) */ - KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, 0); + KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, IO_NO_INCREMENT); }
/*