reactos/ntoskrnl/include/internal
Hermès Bélusca-Maïto 4ce819ca5a
[NTOS:KD][KDBG] Rework the BootPhase >= 2 initialization of the KD/KDBG kernel debugger. (#4892)
CORE-17470

+ KdpDebugLogInit: Add resources cleanup in failure code paths.

Fix, in an NT-compatible manner, how (and when) the KD/KDBG BootPhase >=2
initialization steps are performed.
These are necessary for any functionality KDBG needs, that would depend
on the NT I/O Manager and the storage and filesystem stacks to be running.
This includes, creating the debug log file, and for KDBG, loading its
KDBinit initialization file.

As a result, file debug logging is fixed.

The old ReactOS-specific (NT-incompatible) callback we did in the middle
of IoInitSystem() is removed, in favor of a runtime mechanism that should
work on Windows as well.

The idea for this new mechanism is loosely inspired by the TDL4 rootkit,
see http://blog.w4kfu.com/public/tdl4_article/draft_tdl4article.html
but contrary to it, a specific hook is used instead, as well as the
technique of driver reinitialization:
https://web.archive.org/web/20211021050515/https://driverentry.com.br/en/blog/?p=261

Its rationale is as follows:

We want to be able to perform I/O-related initialization (starting a
logger thread for file log debugging, loading KDBinit file for KDBG,
etc.). A good place for this would be as early as possible, once the
I/O Manager has started the storage and the boot filesystem drivers.

Here is an overview of the initialization steps of the NT Kernel and
Executive:
----
KiSystemStartup(KeLoaderBlock)
    if (Cpu == 0) KdInitSystem(0, KeLoaderBlock);
    KiSwitchToBootStack() -> KiSystemStartupBootStack()
    -> KiInitializeKernel() -> ExpInitializeExecutive(Cpu, KeLoaderBlock)

(NOTE: Any unexpected debugger break will call KdInitSystem(0, NULL); )
KdInitSystem(0, LoaderBlock) -> KdDebuggerInitialize0(LoaderBlock);

ExpInitializeExecutive(Cpu == 0):    ExpInitializationPhase = 0;
    HalInitSystem(0, KeLoaderBlock); <-- Sets HalInitPnpDriver callback.
    ...
    PsInitSystem(LoaderBlock)
        PsCreateSystemThread(Phase1Initialization)

Phase1Initialization(Discard):       ExpInitializationPhase = 1;
    HalInitSystem(1, KeLoaderBlock);
    ...
    Early initialization of Ob, Ex, Ke.
    KdInitSystem(1, KeLoaderBlock);
    ...
    KdDebuggerInitialize1(LoaderBlock);
    ...
    IoInitSystem(LoaderBlock);
    ...
----
As we can see, KdDebuggerInitialize1() is the last KD initialization
routine the kernel calls, and is called *before* the I/O Manager starts.
Thus, direct Nt/ZwCreateFile ... calls done there would fail. Also,
we want to do the I/O initialization as soon as possible. There does
not seem to be any exported way to be notified about the I/O manager
initialization steps... that is, unless we somehow become a driver and
insert ourselves in the flow!

Since we are not a regular driver, we need to invoke IoCreateDriver()
to create one. However, remember that we are currently running *before*
IoInitSystem(), the I/O subsystem is not initialized yet. Due to this,
calling IoCreateDriver(), much like any other IO functions, would lead
to a crash, because it calls
ObCreateObject(..., IoDriverObjectType, ...), and IoDriverObjectType
is non-initialized yet (it's NULL).

The chosen solution is to hook a "known" exported callback: namely, the
HalInitPnpDriver() callback (it initializes the "HAL Root Bus Driver").
It is set very early on by the HAL via the HalInitSystem(0, ...) call,
and is called early on by IoInitSystem() before any driver is loaded,
but after the I/O Manager has been minimally set up so that new drivers
can be created.
When the hook: KdpInitDriver() is called, we create our driver with
IoCreateDriver(), specifying its entrypoint KdpDriverEntry(), then
restore and call the original HalInitPnpDriver() callback.

Another possible unexplored alternative, could be to insert ourselves
in the KeLoaderBlock->LoadOrderListHead boot modules list, or in the
KeLoaderBlock->BootDriverListHead boot-driver list. (Note that while
we may be able to do this, because boot-drivers are resident in memory,
much like we are, we cannot insert ourselves in the system-driver list
however, since those drivers are expected to come from PE image files.)

Once the KdpDriverEntry() driver entrypoint is called, we register
KdpDriverReinit() for re-initialization with the I/O Manager, in order
to provide more initialization points. KdpDriverReinit() calls the KD
providers at BootPhase >= 2, and schedules further reinitializations
(at most 3 more) if any of the providers request so.
2023-03-11 01:22:19 +01:00
..
amd64 [NTOSKRNL] Print boot cycles on x64 just like on x86 2022-11-24 21:17:58 +02:00
arch Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
arm [NTOS:Mm] Rewrite MiWriteProtectSystemImage (#749) 2019-01-18 22:11:43 +01:00
i386 [NTOS:KE] Implement the internal FPU state context structure 2022-05-24 18:39:45 +02:00
cc.h [NTOS:CC] CcRosFlushVacb(): Fix Iosb annotation 2021-06-22 10:33:45 +02:00
cm.h [CMLIB][NTOS:CM] Deduplicate other common definitions between CMLIB and the NTOS CM 2022-07-10 14:35:53 +02:00
cm_x.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
cmboot.h [NTOS:CM] Adapt cmboot.c for usage in NT/ReactOS bootloader. 2022-04-16 18:37:45 +02:00
dbgk.h [REACTOS] Addendum to 5c7ce4475e - Fix MSVC 2015 build 2021-05-12 11:04:29 +02:00
ex.h [NTOS:EX] Initialize ExpTimeRefreshLock 2022-12-01 20:17:40 +02:00
fsrtl.h [NTOS] Properly implement and use FsRtlAcquireFileForModWriteEx 2022-11-02 19:41:04 +01:00
hal.h [FSTUB] Fix bugs from 8d2fe54188 2020-12-07 19:50:51 +03:00
hdl.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
icif.h [NTOSKRNL] Force a probe against ReturnLength on query & Misc ICIF stuff 2022-06-12 11:05:05 +02:00
inbv.h [NTOS:INBV] Code refactoring: Move all the boot animation-specific code out of inbv.c and into the new bootanim.c file. 2022-02-13 21:29:14 +01:00
io.h [NTOS:PNP] Halfplement IoInvalidateDeviceState 2022-04-27 02:42:20 +03:00
io_i.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
io_x.h [NTOS:IO] Use a guarded region in IopQueueIrpToThread. 2021-11-20 14:58:51 -05:00
kd.h [NTOS:KD][KDBG] Rework the BootPhase >= 2 initialization of the KD/KDBG kernel debugger. (#4892) 2023-03-11 01:22:19 +01:00
kd64.h [NTOS:KD64] Implement KdLogDbgPrint() for the WinDbg !dbgprint command. 2022-11-24 01:18:18 +01:00
ke.h [NTOS:KE] Unconditionally check IRQL when acquiring & releasing spinlock at DISPATCH_LEVEL 2021-06-29 11:49:20 +02:00
ke_x.h [NTOS:IO] Use a guarded region in IopQueueIrpToThread. 2021-11-20 14:58:51 -05:00
ldr.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
lpc.h [REACTOS] Addendum to 5c7ce4475e - Fix MSVC 2015 build 2021-05-12 11:04:29 +02:00
lpc_x.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
mm.h [NTOS] Add some sanity checks when synchronizing PDEs 2022-09-17 13:48:56 +02:00
napi.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
ntoskrnl.h [NTOSKRNL] Move the ICIF related code and stuff into a separate header file 2021-05-02 20:49:06 +02:00
ob.h [NTOS:OB] Add a system process quota block macro 2022-01-11 10:11:09 +01:00
ob_x.h [NTOS:OB] Clarify and fix the usage of the Obp*DirectoryLock*() and ObpReleaseLookupContextObject() functions. 2021-09-25 00:47:43 +02:00
po.h [REACTOS] Addendum to 5c7ce4475e - Fix MSVC 2015 build 2021-05-12 11:04:29 +02:00
probe.h [NTOSKRNL] Force a probe against ReturnLength on query & Misc ICIF stuff 2022-06-12 11:05:05 +02:00
ps.h [NTOS:PS] Declare some prototypes and annotate the quota functions with SAL 2022-01-11 10:11:09 +01:00
ps_i.h [NTOS:PS] Support using QUOTA_LIMITS_EX in NtSetInformationProcess(ProcessQuotaLimits) 2021-07-15 19:33:45 +02:00
ps_x.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
rtl.h [NTOS:PS] On x64 don't fail in NtSetInformationProcess with ProcessUserModeIOPL information class, instead just don't do anything. 2020-09-20 23:08:17 +02:00
se.h [NTOS:SE] Do not allocate memory pool just for the access rights 2023-03-07 17:50:39 +01:00
spinlock.h [NTOS:KE] Test spinlock ownership on both UP & MP build 2021-06-29 11:49:20 +02:00
tag.h [NTOS:SE] Do not allocate memory pool just for the access rights 2023-03-07 17:50:39 +01:00
test.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00
vdm.h Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys. 2017-10-03 07:45:34 +00:00