ReactOS 0.4.16-dev-2528-g7139e57
kdmain.c File Reference
#include <ntoskrnl.h>
#include "kd.h"
#include "kdterminal.h"
#include <cportlib/uartinfo.h>
#include <debug.h>
Include dependency graph for kdmain.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define CONST_STR_LEN(x)   (sizeof(x)/sizeof(x[0]) - 1)
 

Functions

static VOID KdpGetTerminalSettings (_In_ PCSTR p1)
 
static PSTR KdpGetDebugMode (_In_ PCSTR DebugPort)
 
NTSTATUS NTAPI KdDebuggerInitialize0 (_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
 
static VOID NTAPI KdpDriverReinit (_In_ PDRIVER_OBJECT DriverObject, _In_opt_ PVOID Context, _In_ ULONG Count)
 Reinitialization routine. DRIVER_REINITIALIZE.
 
static NTSTATUS NTAPI KdpDriverEntry (_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
 Entry point for the auxiliary driver. DRIVER_INITIALIZE.
 
static NTSTATUS NTAPI KdpInitDriver (VOID)
 HalInitPnpDriver() callback hook installed by KdDebuggerInitialize1().
 
NTSTATUS NTAPI KdDebuggerInitialize1 (_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI KdD0Transition (VOID)
 
NTSTATUS NTAPI KdD3Transition (VOID)
 
NTSTATUS NTAPI KdSave (_In_ BOOLEAN SleepTransition)
 
NTSTATUS NTAPI KdRestore (_In_ BOOLEAN SleepTransition)
 

Variables

static pHalInitPnpDriver orgHalInitPnpDriver = NULL
 Hooked HalInitPnpDriver() callback. It is initially set by the HAL when HalInitSystem(0, ...) is called earlier on.
 

Macro Definition Documentation

◆ CONST_STR_LEN

#define CONST_STR_LEN (   x)    (sizeof(x)/sizeof(x[0]) - 1)

Definition at line 25 of file kdmain.c.

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file kdmain.c.

Function Documentation

◆ KdD0Transition()

NTSTATUS NTAPI KdD0Transition ( VOID  )

Definition at line 471 of file kdmain.c.

472{
473 /* Nothing to do */
474 return STATUS_SUCCESS;
475}
#define STATUS_SUCCESS
Definition: shellext.h:65

◆ KdD3Transition()

NTSTATUS NTAPI KdD3Transition ( VOID  )

Definition at line 479 of file kdmain.c.

480{
481 /* Nothing to do */
482 return STATUS_SUCCESS;
483}

◆ KdDebuggerInitialize0()

NTSTATUS NTAPI KdDebuggerInitialize0 ( _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock  )

Definition at line 114 of file kdmain.c.

116{
117 PSTR CommandLine, Port = NULL, BaudRate = NULL;
118 ULONG i;
120
121 if (LoaderBlock)
122 {
123 /* Check if we have a command line */
124 CommandLine = LoaderBlock->LoadOptions;
125 if (CommandLine)
126 {
127 /* Upcase it */
128 _strupr(CommandLine);
129
130 /* Get terminal settings */
131 KdpGetTerminalSettings(CommandLine);
132
133 /* Get the port and baud rate */
134 Port = strstr(CommandLine, "DEBUGPORT");
135 BaudRate = strstr(CommandLine, "BAUDRATE");
136 }
137 }
138
139 /* Check if we got DEBUGPORT parameters */
140 while (Port)
141 {
142 /* Move past the actual string and any spaces */
143 Port += CONST_STR_LEN("DEBUGPORT");
144 while (*Port == ' ') ++Port;
145 /* Skip the equals sign */
146 if (*Port) ++Port;
147
148 /* Get the debug mode and wrapper */
150 Port = strstr(Port, "DEBUGPORT");
151 }
152
153 /* If no debug port was set, fall back to serial port debugging */
154 if (KdpDebugMode.Value == 0)
156
157 /* Check if we got a baud rate */
158 if (BaudRate)
159 {
160 /* Move past the actual string and any spaces */
161 BaudRate += CONST_STR_LEN("BAUDRATE");
162 while (*BaudRate == ' ') ++BaudRate;
163
164 /* Make sure we have a rate */
165 if (*BaudRate)
166 {
167 /* Read and set it */
168 ULONG Value = (ULONG)atol(BaudRate + 1);
170 }
171 }
172
173 /* Call the providers at Phase 0 */
174 for (i = 0; i < RTL_NUMBER_OF(DispatchTable); i++)
175 {
176 DispatchTable[i].InitStatus = InitRoutines[i](&DispatchTable[i], 0);
177 Success = (Success || NT_SUCCESS(DispatchTable[i].InitStatus));
178 }
179
180 /* Return success if at least one of the providers succeeded */
182}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
unsigned char BOOLEAN
Definition: actypes.h:127
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_ACRTIMP __msvcrt_long __cdecl atol(const char *)
Definition: string.c:1782
_ACRTIMP char *__cdecl strstr(const char *, const char *)
Definition: string.c:3415
@ Success
Definition: eventcreate.c:712
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
CPPORT Port[4]
Definition: headless.c:38
KDP_DEBUG_MODE KdpDebugMode
Definition: kdio.c:47
PKDP_INIT_ROUTINE InitRoutines[KdMax]
Definition: kdio.c:51
CPPORT SerialPortInfo
Definition: kdio.c:41
static VOID KdpGetTerminalSettings(_In_ PCSTR p1)
Definition: kdmain.c:28
#define CONST_STR_LEN(x)
Definition: kdmain.c:25
static PSTR KdpGetDebugMode(_In_ PCSTR DebugPort)
Definition: kdmain.c:54
_strupr
Definition: string.h:453
ULONG BaudRate
Definition: cportlib.h:29
UCHAR Serial
Definition: kd.h:99
ULONG Value
Definition: kd.h:104
char * PSTR
Definition: typedefs.h:51
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_ PWDFDEVICE_INIT _In_ PWDF_PDO_EVENT_CALLBACKS DispatchTable
Definition: wdfpdo.h:248
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

◆ KdDebuggerInitialize1()

NTSTATUS NTAPI KdDebuggerInitialize1 ( _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock  )

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.

Definition at line 343 of file kdmain.c.

345{
346 PLIST_ENTRY CurrentEntry;
347 PKD_DISPATCH_TABLE CurrentTable;
348 PKDP_INIT_ROUTINE KdpInitRoutine;
350 BOOLEAN ReinitForPhase2 = FALSE;
351
352 /* Make space for the displayed providers' signons */
353 HalDisplayString("\r\n");
354
355 /* Call the registered providers */
356 for (CurrentEntry = KdProviders.Flink;
357 CurrentEntry != &KdProviders; NOTHING)
358 {
359 /* Get the provider */
360 CurrentTable = CONTAINING_RECORD(CurrentEntry,
362 KdProvidersList);
363 /* Go to the next entry (the Init routine may unlink us) */
364 CurrentEntry = CurrentEntry->Flink;
365
366 /* Get the initialization routine and reset it */
367 ASSERT(CurrentTable->KdpInitRoutine);
368 KdpInitRoutine = CurrentTable->KdpInitRoutine;
369 CurrentTable->KdpInitRoutine = NULL;
370
371 /* Call it */
372 CurrentTable->InitStatus = KdpInitRoutine(CurrentTable, 1);
373
374 /* Check whether it needs to be reinitialized for Phase 2 */
375 Success = (Success || NT_SUCCESS(CurrentTable->InitStatus));
376 ReinitForPhase2 = (ReinitForPhase2 || CurrentTable->KdpInitRoutine);
377 }
378
379 /* Make space for the displayed providers' signons */
380 HalDisplayString("\r\n");
381
383
384 /* If we don't need to reinitialize providers for Phase 2, we are done */
385 if (!ReinitForPhase2)
386 {
387 /* Return success if at least one of them succeeded */
389 }
390
466 return STATUS_SUCCESS;
467}
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define FLG_STOP_ON_EXCEPTION
Definition: pstypes.h:56
#define NOTHING
Definition: input_list.c:10
LIST_ENTRY KdProviders
Definition: kdio.c:48
NTSTATUS(NTAPI * PKDP_INIT_ROUTINE)(_In_ struct _KD_DISPATCH_TABLE *DispatchTable, _In_ ULONG BootPhase)
Definition: kd.h:9
static pHalInitPnpDriver orgHalInitPnpDriver
Hooked HalInitPnpDriver() callback. It is initially set by the HAL when HalInitSystem(0,...
Definition: kdmain.c:303
static NTSTATUS NTAPI KdpInitDriver(VOID)
HalInitPnpDriver() callback hook installed by KdDebuggerInitialize1().
Definition: kdmain.c:317
#define ASSERT(a)
Definition: mode.c:44
ULONG NtGlobalFlag
Definition: init.c:54
PKDP_INIT_ROUTINE KdpInitRoutine
Definition: kd.h:112
NTSTATUS InitStatus
Definition: kd.h:114
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define HalInitPnpDriver
Definition: haltypes.h:310

◆ KdpDriverEntry()

static NTSTATUS NTAPI KdpDriverEntry ( _In_ PDRIVER_OBJECT  DriverObject,
_In_ PUNICODE_STRING  RegistryPath 
)
static

Entry point for the auxiliary driver. DRIVER_INITIALIZE.

Definition at line 282 of file kdmain.c.

285{
287
288 /* Register for reinitialization after the other drivers are loaded */
291 (PVOID)FALSE);
292
293 /* Set the driver as initialized */
295 return STATUS_SUCCESS;
296}
static VOID NTAPI KdpDriverReinit(_In_ PDRIVER_OBJECT DriverObject, _In_opt_ PVOID Context, _In_ ULONG Count)
Reinitialization routine. DRIVER_REINITIALIZE.
Definition: kdmain.c:194
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
VOID NTAPI IoRegisterBootDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1780
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define DRVO_INITIALIZED
Definition: iotypes.h:4473

Referenced by KdpInitDriver().

◆ KdpDriverReinit()

static VOID NTAPI KdpDriverReinit ( _In_ PDRIVER_OBJECT  DriverObject,
_In_opt_ PVOID  Context,
_In_ ULONG  Count 
)
static

Reinitialization routine. DRIVER_REINITIALIZE.

Calls each registered provider for reinitialization at Phase >= 2. I/O is now set up for disk access, at different phases.

Definition at line 194 of file kdmain.c.

198{
199 PLIST_ENTRY CurrentEntry;
200 PKD_DISPATCH_TABLE CurrentTable;
201 PKDP_INIT_ROUTINE KdpInitRoutine;
202 ULONG BootPhase = (Count + 1); // Do BootPhase >= 2
203 BOOLEAN ScheduleReinit = FALSE;
204
206
207 DPRINT("*** KD %sREINITIALIZATION - Phase %d ***\n",
208 Context ? "" : "BOOT ", BootPhase);
209
210 /* Call the registered providers */
211 for (CurrentEntry = KdProviders.Flink;
212 CurrentEntry != &KdProviders; NOTHING)
213 {
214 /* Get the provider */
215 CurrentTable = CONTAINING_RECORD(CurrentEntry,
217 KdProvidersList);
218 /* Go to the next entry (the Init routine may unlink us) */
219 CurrentEntry = CurrentEntry->Flink;
220
221 /* Call it if it requires a reinitialization */
222 if (CurrentTable->KdpInitRoutine)
223 {
224 /* Get the initialization routine and reset it */
225 KdpInitRoutine = CurrentTable->KdpInitRoutine;
226 CurrentTable->KdpInitRoutine = NULL;
227 CurrentTable->InitStatus = KdpInitRoutine(CurrentTable, BootPhase);
228 DPRINT("KdpInitRoutine(%p) returned 0x%08lx\n",
229 CurrentTable, CurrentTable->InitStatus);
230
231 /* Check whether it needs to be reinitialized again */
232 ScheduleReinit = (ScheduleReinit || CurrentTable->KdpInitRoutine);
233 }
234 }
235
236 DPRINT("ScheduleReinit: %s\n", ScheduleReinit ? "TRUE" : "FALSE");
237 if (ScheduleReinit)
238 {
239 /*
240 * Determine when to reinitialize.
241 * If Context == NULL, we are doing a boot-driver reinitialization.
242 * It is initially done once (Count == 1), and is rescheduled once
243 * after all other boot drivers get loaded (Count == 2).
244 * If further reinitialization is needed, switch to system-driver
245 * reinitialization and do it again, not more than twice.
246 */
247 if (Count <= 1)
248 {
251 (PVOID)FALSE);
252 }
253 else if (Count <= 3)
254 {
257 (PVOID)TRUE);
258 }
259 else
260 {
261 /* Too late, no more reinitializations! */
262 DPRINT("Cannot reinitialize anymore!\n");
263 ScheduleReinit = FALSE;
264 }
265 }
266
267 if (!ScheduleReinit)
268 {
269 /* All the necessary reinitializations are done,
270 * the driver object is not needed anymore. */
273 }
274}
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
int Count
Definition: noreturn.cpp:7
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1809
VOID NTAPI IoDeleteDriver(_In_ PDRIVER_OBJECT DriverObject)
Definition: driver.c:1768
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1449
#define DPRINT
Definition: sndvol32.h:73
_In_ PVOID Context
Definition: storport.h:2269

Referenced by KdpDriverEntry(), and KdpDriverReinit().

◆ KdpGetDebugMode()

static PSTR KdpGetDebugMode ( _In_ PCSTR  DebugPort)
static

Definition at line 54 of file kdmain.c.

56{
57 PCSTR p2 = DebugPort;
59
60 /* Check for Screen Debugging */
61 if (!_strnicmp(p2, "SCREEN", CONST_STR_LEN("SCREEN")))
62 {
63 /* Enable it */
64 p2 += CONST_STR_LEN("SCREEN");
66 }
67 /* Check for Serial Debugging */
68 else if (!_strnicmp(p2, "COM", CONST_STR_LEN("COM")))
69 {
70 /* Check for a valid serial port */
71 p2 += CONST_STR_LEN("COM");
72 if (*p2 != ':')
73 {
74 Value = (ULONG)atol(p2);
75 if (Value > 0 && Value <= MAX_COM_PORTS)
76 {
77 /* Valid port found, enable it and set the port to use */
80 }
81 }
82 else
83 {
84 Value = strtoul(p2 + 1, NULL, 0);
85 if (Value)
86 {
87 /* Valid port found, enable it and set its address */
91 }
92 }
93 }
94 /* Check for Debug Log Debugging */
95 else if (!_strnicmp(p2, "FILE", CONST_STR_LEN("FILE")))
96 {
97 /* Enable it */
98 p2 += CONST_STR_LEN("FILE");
100 if (*p2 == ':')
101 {
102 PCSTR p1 = ++p2;
103 while (*p2 && *p2 != ' ') ++p2;
106 }
107 }
108
109 return (PSTR)p2;
110}
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
_ACRTIMP __msvcrt_ulong __cdecl strtoul(const char *, char **, int)
Definition: string.c:1859
#define UlongToPtr(u)
Definition: config.h:106
ULONG SerialPortNumber
Definition: kdio.c:40
ANSI_STRING KdpLogFileName
Definition: kdio.c:37
#define MAX_COM_PORTS
Definition: machpc.c:29
USHORT MaximumLength
Definition: env_spec_w32.h:377
PUCHAR Address
Definition: cportlib.h:28
UCHAR File
Definition: kd.h:100
UCHAR Screen
Definition: kd.h:98
const char * PCSTR
Definition: typedefs.h:52

Referenced by KdDebuggerInitialize0().

◆ KdpGetTerminalSettings()

static VOID KdpGetTerminalSettings ( _In_ PCSTR  p1)
static

Definition at line 28 of file kdmain.c.

30{
31 while (p1 && *p1)
32 {
33 /* Skip leading whitespace */
34 while (*p1 == ' ') ++p1;
35
36 if (!_strnicmp(p1, "KDSERIAL", CONST_STR_LEN("KDSERIAL")))
37 {
38 p1 += CONST_STR_LEN("KDSERIAL");
41 }
42 else if (!_strnicmp(p1, "KDNOECHO", CONST_STR_LEN("KDNOECHO")))
43 {
44 p1 += CONST_STR_LEN("KDNOECHO");
46 }
47
48 /* Move on to the next option */
49 p1 = strchr(p1, ' ');
50 }
51}
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3286
ULONG KdbDebugState
Definition: kdterminal.c:32
@ KD_DEBUG_KDSERIAL
Definition: kdterminal.h:36
@ KD_DEBUG_KDNOECHO
Definition: kdterminal.h:37

Referenced by KdDebuggerInitialize0().

◆ KdpInitDriver()

static NTSTATUS NTAPI KdpInitDriver ( VOID  )
static

HalInitPnpDriver() callback hook installed by KdDebuggerInitialize1().

It is called during initialization of the I/O manager and is where the auxiliary driver is created. This driver is needed for receiving reinitialization callbacks in KdpDriverReinit() later. This hook must always call the original HalInitPnpDriver() function and return its returned value, or return STATUS_SUCCESS.

Definition at line 317 of file kdmain.c.

318{
319 static BOOLEAN InitCalled = FALSE;
321 UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"\\Driver\\KdDriver");
322
324
325 /* Ensure we are not called more than once */
326 if (_InterlockedCompareExchange8((char*)&InitCalled, TRUE, FALSE) != FALSE)
327 return STATUS_SUCCESS;
328
329 /* Create the driver */
330 Status = IoCreateDriver(&DriverName, KdpDriverEntry);
331 if (!NT_SUCCESS(Status))
332 DPRINT1("IoCreateDriver failed: 0x%08lx\n", Status);
333 /* Ignore any failure from IoCreateDriver(). If it fails, no I/O-related
334 * initialization will happen (no file log debugging, etc.). */
335
336 /* Finally, restore and call the original HalInitPnpDriver() */
339}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define L(x)
Definition: resources.c:13
Status
Definition: gdiplustypes.h:25
static NTSTATUS NTAPI KdpDriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
Entry point for the auxiliary driver. DRIVER_INITIALIZE.
Definition: kdmain.c:282
NTSTATUS NTAPI IoCreateDriver(_In_opt_ PUNICODE_STRING DriverName, _In_ PDRIVER_INITIALIZE InitializationFunction)
Definition: driver.c:1588
char _InterlockedCompareExchange8(_Interlocked_operand_ char volatile *_Destination, char _Exchange, char _Comparand)

Referenced by KdDebuggerInitialize1().

◆ KdRestore()

NTSTATUS NTAPI KdRestore ( _In_ BOOLEAN  SleepTransition)

Definition at line 496 of file kdmain.c.

498{
499 /* Nothing to do */
500 return STATUS_SUCCESS;
501}

◆ KdSave()

NTSTATUS NTAPI KdSave ( _In_ BOOLEAN  SleepTransition)

Definition at line 487 of file kdmain.c.

489{
490 /* Nothing to do */
491 return STATUS_SUCCESS;
492}

Variable Documentation

◆ orgHalInitPnpDriver

pHalInitPnpDriver orgHalInitPnpDriver = NULL
static

Hooked HalInitPnpDriver() callback. It is initially set by the HAL when HalInitSystem(0, ...) is called earlier on.

Definition at line 303 of file kdmain.c.

Referenced by KdDebuggerInitialize1(), and KdpInitDriver().