If only for now, this article is specific to 32-bit Windows (i386 or x86).

Bug Check 0x6B

The PROCESS1_INITIALIZATION_FAILED bug check reports a fatal error fairly late in the kernel’s initialisation.

Bug Check Code: PROCESS1_INITIALIZATION_FAILED
1st Argument: NT status code for operation that failed
2nd Argument: 0 any failure of 2nd call to internal routine PsInitSystem
2 error when opening a system DLL
3 error when creating section for system DLL
4 error when accessing section for system DLL
5 error when mapping view of section for system DLL
6 error finding any of one set of functions in system DLL
7 error finding any of second set of functions in system DLL
8 error finding any of third set of functions in system DLL (before 6.0)
error getting section information for system DLL (6.0 and higher)
3rd Argument: index to identify system DLL when 2nd argument is 2 (see below)
4th Argument: zero

Causes

When the 2nd argument is zero, the cause really might be just about anything. Details may be documented here another time. The other cases are all concerned with so-called system DLLs. Though the code provides for more, there is presently only one, and it is of course NTDLL.DLL.

Cases 3 to 8 are known only for 32-bit Windows.

Windows Vista and Higher (32-Bit)

In version 6.0 and higher, the following functions and variables are required as exports from NTDLL to avoid case 6:

Function Applicable Versions
EtwpNotificationThread 6.0 to 6.2
ExpInterlockedPopEntrySListEnd 6.0 and higher
ExpInterlockedPopEntrySListFault 6.0 and higher
ExpInterlockedPopEntrySListResume 6.0 and higher
LdrHotPatchRoutine 6.0 to 6.2
LdrInitializeThunk 6.0 and higher
LdrSystemDllInitBlock 6.2 and higher
KiRaiseUserExceptionDispatcher 6.0 and higher
KiUserApcDispatcher 6.0 and higher
KiUserCallbackDispatcher 6.0 and higher
KiUserExceptionDispatcher 6.0 and higher
RtlUserThreadStart 6.0 and higher
RtlpFreezeTimeBias 6.2 and higher
RtlpWnfNotificationThread 6.2 only

In versions 6.0 and 6.1, the NTDLL exports that are required for avoiding case 7 depend on a CPU feature, specifically support for the SYSENTER and SYSEXIT instructions:

Versions 6.2 and higher require this CPU feature and correspondingly have no need of KiIntSystemCall. Moreover, a change to the mechanism of supporting SYSENTER means that the kernel also doesn’t need KiFastSystemCall, just KiFastSystemCallRet.

Case 8 can occur only for version 6.1 and higher.

Earlier Versions (32-Bit)

In versions before 6.0, the higher-numbered cases concerned with exports from NTDLL are interpreted differently enough that they seem better described separately:

2nd Argument Required Exports
6 LdrInitializeThunk
7 NPXEMULATORTABLE before version 5.1
8 KiRaiseUserExceptionDispatcher
KiUserApcDispatcher
KiUserCallbackDispatcher
KiUserExceptionDispatcher

This arrangement does at least have the merit of emphasising something quite special about NTDLL. It has no entry point for initial execution, as would ordinarily be defined in the executable’s PE header. Instead, NTDLL is started by calling its exported LdrInitializeThunk function.

Documentation Status

This bug check is documented, though with all arguments except the first marked as reserved. The description of possible causes is very broad. This is strange, given the very specific causes that some Microsoft programmer has thought to distinguish through the 2nd argument. It’s not as if the documentation is just taking its time to catch up. This is old code: use of the 2nd argument to elaborate problems with NTDLL.DLL dates from at least Windows NT 4.0. If you delete NTDLL.DLL, which does admittedly take some effort nowadays, then what you get for your pain is precisely this bug check with 2 for its second argument. Instead of talking vaguely about “a missing file from the boot partition”, why not save the poor user some trouble and document that if the second argument is non-zero, then the problem file is necessarily NTDLL.DLL?