All I/O sent through the crash path is initiated by the Windows kernel (ntoskrnl.exe and variants), whether it be crash or hibernation.  The kernel sets up the crash stack in the pre-initialization phase which occurs during kernel phase 1 initialization (KiInitializeKernel and IoInitSystem) and when a page file is created (NtCreatePagingFile).  In the event of a crash, after the kernel completes the post-initialization phase, it utilizes the crash stack via KeBugCheck2 and IoWriteCrashDump.

The kernel maintains a book-keeping data structure about the crash dump stack.  It uses this structure to control various aspects of the crash and hibernate processes.  This undocumented but exported structure is of type DUMP_STACK_CONTEXT and its definition is displayed below.

typedef struct _DUMP_STACK_CONTEXT {
 LARGE_INTEGER PartitionOffset;
 PVOID DumpPointers;
 ULONG PointersLength;
 PWCHAR ModulePrefix;
 LIST_ENTRY DriverList;
 PVOID FileObject;

Prior to Windows Vista, the kernel contained all of the code to set up and communicate with the dump port driver directly.  It housed an exported variable, nt!IopDumpControlBlock of type DUMP_CONTROL_BLOCK, that contained the DUMP_STACK_CONTEXT structure above.  This variable was passed directly to the dump port driver’s DriverEntry routine during pre-initialization.  The dump port driver populated it with values necessary for completing the crash process.

In Windows Vista and beyond, the kernel has very little involvement in the internal workings of the crash dump stack, as all of the related code was relocated to a new driver, crashdmp.sys.  Since the list of features supported by the crash dump stack was growing drastically (such as crash dump filters, extended hibernation support, and others), this move made sense.

%d bloggers like this: