mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[NTOS:KDBG] Isolate terminal and input-related routines from the rest of KDBG. (#5188)
This is done in preparation for moving all this functionality in a separate KDTERM "KD Terminal Driver" DLL. Additionally: - Flush the terminal input before sending ANSI escape sequences. - In KDBG pager, always use the correct reading-key function (the same used also for reading keys for a line of user input), and not the simplistic two-call KdbpGetCharSerial + KdbpTryGetCharSerial that would split the \r \n across calls. - Call KdbpGetCommandLineSettings() in KdbInitialize() at BootPhase 0, which is indirectly called by KdDebuggerInitialize0(). And fix its command-line parsing too.
This commit is contained in:
parent
56bf3969cd
commit
35180b3ad2
9 changed files with 407 additions and 266 deletions
|
@ -26,6 +26,11 @@ KdIoPrintf(
|
||||||
_In_ PCSTR Format,
|
_In_ PCSTR Format,
|
||||||
...);
|
...);
|
||||||
|
|
||||||
|
SIZE_T
|
||||||
|
KdIoReadLine(
|
||||||
|
_Out_ PCHAR Buffer,
|
||||||
|
_In_ SIZE_T Size);
|
||||||
|
|
||||||
|
|
||||||
/* INIT ROUTINES *************************************************************/
|
/* INIT ROUTINES *************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -9,14 +9,42 @@
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
#include "kd.h"
|
#include "kd.h"
|
||||||
|
#include "kdterminal.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS *********************************************************/
|
/* PUBLIC FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
KdpGetTerminalSettings(
|
||||||
|
_In_ PCSTR p1)
|
||||||
|
{
|
||||||
|
#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
|
||||||
|
|
||||||
|
while (p1 && *p1)
|
||||||
|
{
|
||||||
|
/* Skip leading whitespace */
|
||||||
|
while (*p1 == ' ') ++p1;
|
||||||
|
|
||||||
|
if (!_strnicmp(p1, "KDSERIAL", CONST_STR_LEN("KDSERIAL")))
|
||||||
|
{
|
||||||
|
p1 += CONST_STR_LEN("KDSERIAL");
|
||||||
|
KdbDebugState |= KD_DEBUG_KDSERIAL;
|
||||||
|
KdpDebugMode.Serial = TRUE;
|
||||||
|
}
|
||||||
|
else if (!_strnicmp(p1, "KDNOECHO", CONST_STR_LEN("KDNOECHO")))
|
||||||
|
{
|
||||||
|
p1 += CONST_STR_LEN("KDNOECHO");
|
||||||
|
KdbDebugState |= KD_DEBUG_KDNOECHO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move on to the next option */
|
||||||
|
p1 = strchr(p1, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static PCHAR
|
static PCHAR
|
||||||
NTAPI
|
|
||||||
KdpGetDebugMode(
|
KdpGetDebugMode(
|
||||||
_In_ PCHAR Currentp2)
|
_In_ PCHAR Currentp2)
|
||||||
{
|
{
|
||||||
|
@ -95,10 +123,8 @@ KdDebuggerInitialize0(
|
||||||
/* Upcase it */
|
/* Upcase it */
|
||||||
_strupr(CommandLine);
|
_strupr(CommandLine);
|
||||||
|
|
||||||
#ifdef KDBG
|
/* Get terminal settings */
|
||||||
/* Get the KDBG Settings */
|
KdpGetTerminalSettings(CommandLine);
|
||||||
KdbpGetCommandLineSettings(CommandLine);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get the port */
|
/* Get the port */
|
||||||
Port = strstr(CommandLine, "DEBUGPORT");
|
Port = strstr(CommandLine, "DEBUGPORT");
|
||||||
|
|
|
@ -36,72 +36,23 @@ KdIoReadLine(
|
||||||
PCHAR Orig = Buffer;
|
PCHAR Orig = Buffer;
|
||||||
ULONG ScanCode = 0;
|
ULONG ScanCode = 0;
|
||||||
CHAR Key;
|
CHAR Key;
|
||||||
static CHAR NextKey = ANSI_NULL;
|
BOOLEAN EchoOn = !(KdbDebugState & KD_DEBUG_KDNOECHO);
|
||||||
BOOLEAN EchoOn;
|
|
||||||
LONG CmdHistIndex = -1; // Start at end of history.
|
LONG CmdHistIndex = -1; // Start at end of history.
|
||||||
|
|
||||||
|
/* Flush the input buffer */
|
||||||
|
KdpFlushTerminalInput();
|
||||||
|
|
||||||
/* Bail out if the buffer is zero-sized */
|
/* Bail out if the buffer is zero-sized */
|
||||||
if (Size == 0)
|
if (Size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
EchoOn = ((KdbDebugState & KD_DEBUG_KDNOECHO) == 0);
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
ScanCode = 0;
|
Key = KdpReadTermKey(&ScanCode);
|
||||||
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
|
||||||
{
|
|
||||||
Key = (!NextKey ? KdbpGetCharSerial() : NextKey);
|
|
||||||
NextKey = ANSI_NULL;
|
|
||||||
if (Key == KEY_ESC) /* ESC */
|
|
||||||
{
|
|
||||||
Key = KdbpGetCharSerial();
|
|
||||||
if (Key == '[')
|
|
||||||
{
|
|
||||||
Key = KdbpGetCharSerial();
|
|
||||||
|
|
||||||
switch (Key)
|
|
||||||
{
|
|
||||||
case 'A':
|
|
||||||
ScanCode = KEY_SCAN_UP;
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
ScanCode = KEY_SCAN_DOWN;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Key = (!NextKey ? KdbpGetCharKeyboard(&ScanCode) : NextKey);
|
|
||||||
NextKey = ANSI_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for return or newline */
|
/* Check for return or newline */
|
||||||
if ((Key == '\r') || (Key == '\n'))
|
if ((Key == '\r') || (Key == '\n'))
|
||||||
{
|
{
|
||||||
if (Key == '\r')
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We might need to discard the next '\n' which most clients
|
|
||||||
* should send after \r. Wait a bit to make sure we receive it.
|
|
||||||
*/
|
|
||||||
KeStallExecutionProcessor(100000);
|
|
||||||
|
|
||||||
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
|
||||||
NextKey = KdbpTryGetCharSerial(5);
|
|
||||||
else
|
|
||||||
NextKey = KdbpTryGetCharKeyboard(&ScanCode, 5);
|
|
||||||
|
|
||||||
if (NextKey == '\n' || NextKey == -1) /* \n or no response at all */
|
|
||||||
NextKey = ANSI_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*Buffer = ANSI_NULL;
|
*Buffer = ANSI_NULL;
|
||||||
KdIoPuts("\n");
|
KdIoPuts("\n");
|
||||||
return (SIZE_T)(Buffer - Orig);
|
return (SIZE_T)(Buffer - Orig);
|
||||||
|
|
276
ntoskrnl/kd/kdterminal.c
Normal file
276
ntoskrnl/kd/kdterminal.c
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS KDBG Kernel Debugger Terminal Driver
|
||||||
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
|
* PURPOSE: KD Terminal Management
|
||||||
|
* COPYRIGHT: Copyright 2005 Gregor Anich <blight@blight.eu.org>
|
||||||
|
* Copyright 2022-2023 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#include "kdterminal.h"
|
||||||
|
|
||||||
|
#define KdbpGetCharKeyboard(ScanCode) KdbpTryGetCharKeyboard((ScanCode), 0)
|
||||||
|
CHAR
|
||||||
|
KdbpTryGetCharKeyboard(PULONG ScanCode, ULONG Retry);
|
||||||
|
|
||||||
|
#define KdbpGetCharSerial() KdbpTryGetCharSerial(0)
|
||||||
|
CHAR
|
||||||
|
KdbpTryGetCharSerial(
|
||||||
|
_In_ ULONG Retry);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KdbpSendCommandSerial(
|
||||||
|
_In_ PCSTR Command);
|
||||||
|
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
/* KD Controlling Terminal */
|
||||||
|
ULONG KdbDebugState = 0; /* KDBG Settings (NOECHO, KDSERIAL) */
|
||||||
|
SIZE KdTermSize = {0,0};
|
||||||
|
BOOLEAN KdTermConnected = FALSE;
|
||||||
|
BOOLEAN KdTermSerial = FALSE;
|
||||||
|
BOOLEAN KdTermReportsSize = TRUE;
|
||||||
|
|
||||||
|
static CHAR KdTermNextKey = ANSI_NULL; /* 1-character input queue buffer */
|
||||||
|
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the controlling terminal.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* TRUE if the controlling terminal is serial and detected
|
||||||
|
* as being connected, or FALSE if not.
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
KdpInitTerminal(VOID)
|
||||||
|
{
|
||||||
|
/* Determine whether the controlling terminal is a serial terminal:
|
||||||
|
* serial output is enabled *and* KDSERIAL is set (i.e. user input
|
||||||
|
* through serial). */
|
||||||
|
KdTermSerial =
|
||||||
|
#if 0
|
||||||
|
// Old logic where KDSERIAL also enables serial output.
|
||||||
|
(KdbDebugState & KD_DEBUG_KDSERIAL) ||
|
||||||
|
(KdpDebugMode.Serial && !KdpDebugMode.Screen);
|
||||||
|
#else
|
||||||
|
// New logic where KDSERIAL does not necessarily enable serial output.
|
||||||
|
KdpDebugMode.Serial &&
|
||||||
|
((KdbDebugState & KD_DEBUG_KDSERIAL) || !KdpDebugMode.Screen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Flush the input buffer */
|
||||||
|
KdpFlushTerminalInput();
|
||||||
|
|
||||||
|
if (KdTermSerial)
|
||||||
|
{
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
|
/* Enable line-wrap */
|
||||||
|
KdbpSendCommandSerial("\x1b[?7h");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query terminal type.
|
||||||
|
* Historically it was done with CTRL-E ('\x05'), however nowadays
|
||||||
|
* terminals respond to it with an empty (or a user-configurable)
|
||||||
|
* string. Instead, use the VT52-compatible 'ESC Z' sequence or the
|
||||||
|
* VT100-compatible 'ESC[c' one.
|
||||||
|
*/
|
||||||
|
KdbpSendCommandSerial("\x1b[c");
|
||||||
|
KeStallExecutionProcessor(100000);
|
||||||
|
|
||||||
|
Length = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
/* Verify we get an answer, but don't care about it */
|
||||||
|
if (KdbpTryGetCharSerial(5000) == -1)
|
||||||
|
break;
|
||||||
|
++Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminal is connected (TRUE) or not connected (FALSE) */
|
||||||
|
KdTermConnected = (Length > 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Terminal is not serial, assume it's *not* connected */
|
||||||
|
KdTermConnected = FALSE;
|
||||||
|
}
|
||||||
|
return KdTermConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
KdpUpdateTerminalSize(
|
||||||
|
_Out_ PSIZE TermSize)
|
||||||
|
{
|
||||||
|
static CHAR Buffer[128];
|
||||||
|
CHAR c;
|
||||||
|
LONG NumberOfCols = -1; // Or initialize to TermSize->cx ??
|
||||||
|
LONG NumberOfRows = -1; // Or initialize to TermSize->cy ??
|
||||||
|
|
||||||
|
/* Retrieve the size of the controlling terminal only when it is serial */
|
||||||
|
if (KdTermConnected && KdTermSerial && KdTermReportsSize)
|
||||||
|
{
|
||||||
|
/* Flush the input buffer */
|
||||||
|
KdpFlushTerminalInput();
|
||||||
|
|
||||||
|
/* Try to query the terminal size. A reply looks like "\x1b[8;24;80t" */
|
||||||
|
KdTermReportsSize = FALSE;
|
||||||
|
KdbpSendCommandSerial("\x1b[18t");
|
||||||
|
KeStallExecutionProcessor(100000);
|
||||||
|
|
||||||
|
c = KdbpTryGetCharSerial(5000);
|
||||||
|
if (c == KEY_ESC)
|
||||||
|
{
|
||||||
|
c = KdbpTryGetCharSerial(5000);
|
||||||
|
if (c == '[')
|
||||||
|
{
|
||||||
|
ULONG Length = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
c = KdbpTryGetCharSerial(5000);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Buffer[Length++] = c;
|
||||||
|
if (isalpha(c) || Length >= (sizeof(Buffer) - 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Buffer[Length] = ANSI_NULL;
|
||||||
|
|
||||||
|
if (Buffer[0] == '8' && Buffer[1] == ';')
|
||||||
|
{
|
||||||
|
SIZE_T i;
|
||||||
|
for (i = 2; (i < Length) && (Buffer[i] != ';'); i++);
|
||||||
|
|
||||||
|
if (Buffer[i] == ';')
|
||||||
|
{
|
||||||
|
Buffer[i++] = ANSI_NULL;
|
||||||
|
|
||||||
|
/* Number of rows is now at Buffer + 2
|
||||||
|
* and number of columns at Buffer + i */
|
||||||
|
NumberOfRows = strtoul(Buffer + 2, NULL, 0);
|
||||||
|
NumberOfCols = strtoul(Buffer + i, NULL, 0);
|
||||||
|
KdTermReportsSize = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Clear further characters */
|
||||||
|
while (KdbpTryGetCharSerial(5000) != -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NumberOfCols <= 0)
|
||||||
|
{
|
||||||
|
/* Set the number of columns to the default */
|
||||||
|
if (KdpDebugMode.Screen && !KdTermSerial)
|
||||||
|
NumberOfCols = (SCREEN_WIDTH / 8 /*BOOTCHAR_WIDTH*/);
|
||||||
|
else
|
||||||
|
NumberOfCols = 80;
|
||||||
|
}
|
||||||
|
if (NumberOfRows <= 0)
|
||||||
|
{
|
||||||
|
/* Set the number of rows to the default */
|
||||||
|
if (KdpDebugMode.Screen && !KdTermSerial)
|
||||||
|
NumberOfRows = (SCREEN_HEIGHT / (13 /*BOOTCHAR_HEIGHT*/ + 1));
|
||||||
|
else
|
||||||
|
NumberOfRows = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
TermSize->cx = NumberOfCols;
|
||||||
|
TermSize->cy = NumberOfRows;
|
||||||
|
|
||||||
|
// KdIoPrintf("Cols/Rows: %dx%d\n", TermSize->cx, TermSize->cy);
|
||||||
|
|
||||||
|
return KdTermReportsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flushes terminal input (either serial or PS/2).
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
KdpFlushTerminalInput(VOID)
|
||||||
|
{
|
||||||
|
KdTermNextKey = ANSI_NULL;
|
||||||
|
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
||||||
|
{
|
||||||
|
while (KdbpTryGetCharSerial(1) != -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ULONG ScanCode;
|
||||||
|
while (KdbpTryGetCharKeyboard(&ScanCode, 1) != -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Reads one character from the terminal. This function returns
|
||||||
|
* a scan code even when reading is done from a serial terminal.
|
||||||
|
**/
|
||||||
|
CHAR
|
||||||
|
KdpReadTermKey(
|
||||||
|
_Out_ PULONG ScanCode)
|
||||||
|
{
|
||||||
|
CHAR Key;
|
||||||
|
|
||||||
|
*ScanCode = 0;
|
||||||
|
|
||||||
|
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
||||||
|
{
|
||||||
|
Key = (!KdTermNextKey ? KdbpGetCharSerial() : KdTermNextKey);
|
||||||
|
KdTermNextKey = ANSI_NULL;
|
||||||
|
if (Key == KEY_ESC) /* ESC */
|
||||||
|
{
|
||||||
|
Key = KdbpGetCharSerial();
|
||||||
|
if (Key == '[')
|
||||||
|
{
|
||||||
|
Key = KdbpGetCharSerial();
|
||||||
|
switch (Key)
|
||||||
|
{
|
||||||
|
case 'A':
|
||||||
|
*ScanCode = KEY_SCAN_UP;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
*ScanCode = KEY_SCAN_DOWN;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Key = (!KdTermNextKey ? KdbpGetCharKeyboard(ScanCode) : KdTermNextKey);
|
||||||
|
KdTermNextKey = ANSI_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for return */
|
||||||
|
if (Key == '\r')
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We might need to discard the next '\n' which most clients
|
||||||
|
* should send after \r. Wait a bit to make sure we receive it.
|
||||||
|
*/
|
||||||
|
KeStallExecutionProcessor(100000);
|
||||||
|
|
||||||
|
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
||||||
|
KdTermNextKey = KdbpTryGetCharSerial(5);
|
||||||
|
else
|
||||||
|
KdTermNextKey = KdbpTryGetCharKeyboard(ScanCode, 5);
|
||||||
|
|
||||||
|
if (KdTermNextKey == '\n' || KdTermNextKey == -1) /* \n or no response at all */
|
||||||
|
KdTermNextKey = ANSI_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -21,9 +21,40 @@
|
||||||
#define KEYSC_HOME 0x0047
|
#define KEYSC_HOME 0x0047
|
||||||
#define KEYSC_ARROWUP 0x0048 // == KEY_SCAN_UP
|
#define KEYSC_ARROWUP 0x0048 // == KEY_SCAN_UP
|
||||||
|
|
||||||
SIZE_T
|
|
||||||
KdIoReadLine(
|
typedef struct _SIZE
|
||||||
_Out_ PCHAR Buffer,
|
{
|
||||||
_In_ SIZE_T Size);
|
LONG cx;
|
||||||
|
LONG cy;
|
||||||
|
} SIZE, *PSIZE;
|
||||||
|
|
||||||
|
/* KD Controlling Terminal */
|
||||||
|
|
||||||
|
/* These values MUST be nonzero, they're used as bit masks */
|
||||||
|
typedef enum _KDB_OUTPUT_SETTINGS
|
||||||
|
{
|
||||||
|
KD_DEBUG_KDSERIAL = 1,
|
||||||
|
KD_DEBUG_KDNOECHO = 2
|
||||||
|
} KDB_OUTPUT_SETTINGS;
|
||||||
|
|
||||||
|
extern ULONG KdbDebugState;
|
||||||
|
extern SIZE KdTermSize;
|
||||||
|
extern BOOLEAN KdTermConnected;
|
||||||
|
extern BOOLEAN KdTermSerial;
|
||||||
|
extern BOOLEAN KdTermReportsSize;
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
KdpInitTerminal(VOID);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
KdpUpdateTerminalSize(
|
||||||
|
_Out_ PSIZE TermSize);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KdpFlushTerminalInput(VOID);
|
||||||
|
|
||||||
|
CHAR
|
||||||
|
KdpReadTermKey(
|
||||||
|
_Out_ PULONG ScanCode);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -49,7 +49,6 @@ static BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleSte
|
||||||
LONG KdbLastBreakPointNr = -1; /* Index of the breakpoint which cause KDB to be entered */
|
LONG KdbLastBreakPointNr = -1; /* Index of the breakpoint which cause KDB to be entered */
|
||||||
ULONG KdbNumSingleSteps = 0; /* How many single steps to do */
|
ULONG KdbNumSingleSteps = 0; /* How many single steps to do */
|
||||||
BOOLEAN KdbSingleStepOver = FALSE; /* Whether to step over calls/reps. */
|
BOOLEAN KdbSingleStepOver = FALSE; /* Whether to step over calls/reps. */
|
||||||
ULONG KdbDebugState = 0; /* KDBG Settings (NOECHO, KDSERIAL) */
|
|
||||||
static BOOLEAN KdbEnteredOnSingleStep = FALSE; /* Set to true when KDB was entered because of single step */
|
static BOOLEAN KdbEnteredOnSingleStep = FALSE; /* Set to true when KDB was entered because of single step */
|
||||||
PEPROCESS KdbCurrentProcess = NULL; /* The current process context in which KDB runs */
|
PEPROCESS KdbCurrentProcess = NULL; /* The current process context in which KDB runs */
|
||||||
PEPROCESS KdbOriginalProcess = NULL; /* The process in whichs context KDB was intered */
|
PEPROCESS KdbOriginalProcess = NULL; /* The process in whichs context KDB was intered */
|
||||||
|
@ -1624,33 +1623,24 @@ continue_execution:
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
|
||||||
KdbpGetCommandLineSettings(
|
KdbpGetCommandLineSettings(
|
||||||
PCHAR p1)
|
_In_ PCSTR p1)
|
||||||
{
|
{
|
||||||
#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
|
#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
|
||||||
|
|
||||||
while (p1 && (p1 = strchr(p1, ' ')))
|
while (p1 && *p1)
|
||||||
{
|
{
|
||||||
/* Skip other spaces */
|
/* Skip leading whitespace */
|
||||||
while (*p1 == ' ') ++p1;
|
while (*p1 == ' ') ++p1;
|
||||||
|
|
||||||
if (!_strnicmp(p1, "KDSERIAL", CONST_STR_LEN("KDSERIAL")))
|
if (!_strnicmp(p1, "FIRSTCHANCE", CONST_STR_LEN("FIRSTCHANCE")))
|
||||||
{
|
|
||||||
p1 += CONST_STR_LEN("KDSERIAL");
|
|
||||||
KdbDebugState |= KD_DEBUG_KDSERIAL;
|
|
||||||
KdpDebugMode.Serial = TRUE;
|
|
||||||
}
|
|
||||||
else if (!_strnicmp(p1, "KDNOECHO", CONST_STR_LEN("KDNOECHO")))
|
|
||||||
{
|
|
||||||
p1 += CONST_STR_LEN("KDNOECHO");
|
|
||||||
KdbDebugState |= KD_DEBUG_KDNOECHO;
|
|
||||||
}
|
|
||||||
else if (!_strnicmp(p1, "FIRSTCHANCE", CONST_STR_LEN("FIRSTCHANCE")))
|
|
||||||
{
|
{
|
||||||
p1 += CONST_STR_LEN("FIRSTCHANCE");
|
p1 += CONST_STR_LEN("FIRSTCHANCE");
|
||||||
KdbpSetEnterCondition(-1, TRUE, KdbEnterAlways);
|
KdbpSetEnterCondition(-1, TRUE, KdbEnterAlways);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Move on to the next option */
|
||||||
|
p1 = strchr(p1, ' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,6 @@ typedef enum _KDB_ENTER_CONDITION
|
||||||
KdbEnterFromUmode
|
KdbEnterFromUmode
|
||||||
} KDB_ENTER_CONDITION;
|
} KDB_ENTER_CONDITION;
|
||||||
|
|
||||||
/* These values MUST be nonzero. They're used as bit masks. */
|
|
||||||
typedef enum _KDB_OUTPUT_SETTINGS
|
|
||||||
{
|
|
||||||
KD_DEBUG_KDSERIAL = 1,
|
|
||||||
KD_DEBUG_KDNOECHO = 2
|
|
||||||
} KDB_OUTPUT_SETTINGS;
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -187,7 +181,6 @@ extern LONG KdbLastBreakPointNr;
|
||||||
extern ULONG KdbNumSingleSteps;
|
extern ULONG KdbNumSingleSteps;
|
||||||
extern BOOLEAN KdbSingleStepOver;
|
extern BOOLEAN KdbSingleStepOver;
|
||||||
extern PKDB_KTRAP_FRAME KdbCurrentTrapFrame;
|
extern PKDB_KTRAP_FRAME KdbCurrentTrapFrame;
|
||||||
extern ULONG KdbDebugState;
|
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
KdbpGetNextBreakPointNr(
|
KdbpGetNextBreakPointNr(
|
||||||
|
@ -252,8 +245,8 @@ KdbpAttachToProcess(
|
||||||
PVOID ProcessId);
|
PVOID ProcessId);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
KdbpGetCommandLineSettings(
|
||||||
KdbpGetCommandLineSettings(PCHAR p1);
|
_In_ PCSTR p1);
|
||||||
|
|
||||||
KD_CONTINUE_TYPE
|
KD_CONTINUE_TYPE
|
||||||
KdbEnterDebuggerException(IN PEXCEPTION_RECORD64 ExceptionRecord,
|
KdbEnterDebuggerException(IN PEXCEPTION_RECORD64 ExceptionRecord,
|
||||||
|
@ -289,19 +282,6 @@ KdbpSafeWriteMemory(OUT PVOID Dest,
|
||||||
IN PVOID Src,
|
IN PVOID Src,
|
||||||
IN ULONG Bytes);
|
IN ULONG Bytes);
|
||||||
|
|
||||||
#define KdbpGetCharKeyboard(ScanCode) KdbpTryGetCharKeyboard((ScanCode), 0)
|
|
||||||
CHAR
|
|
||||||
KdbpTryGetCharKeyboard(PULONG ScanCode, ULONG Retry);
|
|
||||||
|
|
||||||
#define KdbpGetCharSerial() KdbpTryGetCharSerial(0)
|
|
||||||
CHAR
|
|
||||||
KdbpTryGetCharSerial(
|
|
||||||
_In_ ULONG Retry);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
KdbpSendCommandSerial(
|
|
||||||
_In_ PCSTR Command);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KbdDisableMouse(VOID);
|
KbdDisableMouse(VOID);
|
||||||
|
|
||||||
|
|
|
@ -131,8 +131,6 @@ static ULONG KdbNumberOfRowsPrinted = 0;
|
||||||
static ULONG KdbNumberOfColsPrinted = 0;
|
static ULONG KdbNumberOfColsPrinted = 0;
|
||||||
static BOOLEAN KdbOutputAborted = FALSE;
|
static BOOLEAN KdbOutputAborted = FALSE;
|
||||||
static BOOLEAN KdbRepeatLastCommand = FALSE;
|
static BOOLEAN KdbRepeatLastCommand = FALSE;
|
||||||
static LONG KdbNumberOfRowsTerminal = -1;
|
|
||||||
static LONG KdbNumberOfColsTerminal = -1;
|
|
||||||
|
|
||||||
PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
|
PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
|
||||||
BOOLEAN KdbpBugCheckRequested = FALSE;
|
BOOLEAN KdbpBugCheckRequested = FALSE;
|
||||||
|
@ -2786,26 +2784,35 @@ memrchr(const void *s, int c, size_t n)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!\brief Calculate pointer position for N lines upper of current position.
|
/**
|
||||||
|
* @brief Calculate pointer position for N lines above the current position.
|
||||||
*
|
*
|
||||||
* \param Buffer Characters buffer to operate on.
|
* Calculate pointer position for N lines above the current displaying
|
||||||
* \param BufLength Buffer size.
|
* position within the given buffer. Used by KdbpPager().
|
||||||
*
|
*
|
||||||
* \note Calculate pointer position for N lines upper of current displaying
|
* @param[in] Buffer
|
||||||
* position within the given buffer.
|
* Character buffer to operate on.
|
||||||
*
|
*
|
||||||
* Used by KdbpPager().
|
* @param[in] BufLength
|
||||||
* Now N lines count is hardcoded to KdbNumberOfRowsTerminal.
|
* Size of the buffer.
|
||||||
*/
|
*
|
||||||
|
* @param[in] pCurPos
|
||||||
|
* Current position within the buffer.
|
||||||
|
*
|
||||||
|
* @return Beginning of the previous page of text.
|
||||||
|
*
|
||||||
|
* @note N lines count is hardcoded to the terminal's number of rows.
|
||||||
|
**/
|
||||||
static PCHAR
|
static PCHAR
|
||||||
CountOnePageUp(
|
CountOnePageUp(
|
||||||
_In_ PCCH Buffer,
|
_In_ PCCH Buffer,
|
||||||
_In_ ULONG BufLength,
|
_In_ ULONG BufLength,
|
||||||
_In_ PCCH pCurPos)
|
_In_ PCCH pCurPos,
|
||||||
|
_In_ const SIZE* TermSize)
|
||||||
{
|
{
|
||||||
PCCH p;
|
PCCH p;
|
||||||
// p0 is initial guess of Page Start
|
// p0 is initial guess of Page Start
|
||||||
ULONG p0len = KdbNumberOfRowsTerminal * KdbNumberOfColsTerminal;
|
ULONG p0len = TermSize->cx * TermSize->cy;
|
||||||
PCCH p0 = pCurPos - p0len;
|
PCCH p0 = pCurPos - p0len;
|
||||||
PCCH prev_p = p0, p1;
|
PCCH prev_p = p0, p1;
|
||||||
ULONG j;
|
ULONG j;
|
||||||
|
@ -2817,7 +2824,7 @@ CountOnePageUp(
|
||||||
p = memrchr(p0, '\n', p0len);
|
p = memrchr(p0, '\n', p0len);
|
||||||
if (!p)
|
if (!p)
|
||||||
p = p0;
|
p = p0;
|
||||||
for (j = KdbNumberOfRowsTerminal; j--; )
|
for (j = TermSize->cy; j--; )
|
||||||
{
|
{
|
||||||
int linesCnt;
|
int linesCnt;
|
||||||
p1 = memrchr(p0, '\n', p-p0);
|
p1 = memrchr(p0, '\n', p-p0);
|
||||||
|
@ -2830,7 +2837,7 @@ CountOnePageUp(
|
||||||
p = p0;
|
p = p0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
linesCnt = (KdbNumberOfColsTerminal+prev_p-p-2) / KdbNumberOfColsTerminal;
|
linesCnt = (TermSize->cx+prev_p-p-2) / TermSize->cx;
|
||||||
if (linesCnt > 1)
|
if (linesCnt > 1)
|
||||||
j -= linesCnt-1;
|
j -= linesCnt-1;
|
||||||
}
|
}
|
||||||
|
@ -2874,27 +2881,23 @@ KdpFilterEscapes(
|
||||||
* Maximum length of buffer is limited only by memory size.
|
* Maximum length of buffer is limited only by memory size.
|
||||||
* Uses KdpDprintf internally (NOT DbgPrint!). Callers must already hold the debugger lock.
|
* Uses KdpDprintf internally (NOT DbgPrint!). Callers must already hold the debugger lock.
|
||||||
*
|
*
|
||||||
* Note: BufLength should be greater then (KdbNumberOfRowsTerminal * KdbNumberOfColsTerminal).
|
* Note: BufLength should be greater than (KdTermSize.cx * KdTermSize.cy).
|
||||||
*/
|
*/
|
||||||
VOID
|
static VOID
|
||||||
KdbpPagerInternal(
|
KdbpPagerInternal(
|
||||||
_In_ PCHAR Buffer,
|
_In_ PCHAR Buffer,
|
||||||
_In_ ULONG BufLength,
|
_In_ ULONG BufLength,
|
||||||
_In_ BOOLEAN DoPage)
|
_In_ BOOLEAN DoPage)
|
||||||
{
|
{
|
||||||
static CHAR InBuffer[128];
|
|
||||||
static BOOLEAN TerminalInitialized = FALSE;
|
static BOOLEAN TerminalInitialized = FALSE;
|
||||||
static BOOLEAN TerminalConnected = FALSE;
|
|
||||||
static BOOLEAN TerminalReportsSize = TRUE;
|
|
||||||
CHAR c;
|
CHAR c;
|
||||||
ULONG ScanCode;
|
ULONG ScanCode;
|
||||||
PCHAR p;
|
PCHAR p;
|
||||||
ULONG Length;
|
|
||||||
SIZE_T i;
|
SIZE_T i;
|
||||||
LONG RowsPrintedByTerminal;
|
LONG RowsPrintedByTerminal;
|
||||||
|
|
||||||
if (BufLength == 0)
|
if (BufLength == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check if the user has aborted output of the current command */
|
/* Check if the user has aborted output of the current command */
|
||||||
if (KdbOutputAborted)
|
if (KdbOutputAborted)
|
||||||
|
@ -2904,117 +2907,13 @@ KdbpPagerInternal(
|
||||||
if (!TerminalInitialized)
|
if (!TerminalInitialized)
|
||||||
{
|
{
|
||||||
TerminalInitialized = TRUE;
|
TerminalInitialized = TRUE;
|
||||||
|
KdpInitTerminal();
|
||||||
/* Enable line-wrap */
|
|
||||||
KdbpSendCommandSerial("\x1b[?7h");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Query terminal type.
|
|
||||||
* Historically it was done with CTRL-E ('\x05'), however nowadays
|
|
||||||
* terminals respond to it with an empty (or a user-configurable)
|
|
||||||
* string. Instead, use the VT52-compatible 'ESC Z' sequence or the
|
|
||||||
* VT100-compatible 'ESC[c' one.
|
|
||||||
*/
|
|
||||||
KdbpSendCommandSerial("\x1b[c");
|
|
||||||
KeStallExecutionProcessor(100000);
|
|
||||||
|
|
||||||
Length = 0;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
/* Verify we get an answer, but don't care about it */
|
|
||||||
c = KdbpTryGetCharSerial(5000);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
++Length;
|
|
||||||
}
|
|
||||||
if (Length > 0)
|
|
||||||
TerminalConnected = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get number of rows and columns in terminal */
|
/* Refresh terminal size each time when number of rows printed is 0 */
|
||||||
if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
|
if (KdbNumberOfRowsPrinted == 0)
|
||||||
/* Refresh terminal size each time when number of rows printed is 0 */
|
|
||||||
(KdbNumberOfRowsPrinted) == 0)
|
|
||||||
{
|
{
|
||||||
/* Retrieve the size of the serial terminal only when it is the
|
KdpUpdateTerminalSize(&KdTermSize);
|
||||||
* controlling terminal: serial output is enabled *and* KDSERIAL
|
|
||||||
* is set (i.e. user input through serial). */
|
|
||||||
BOOLEAN SerialTerminal =
|
|
||||||
#if 0
|
|
||||||
// Old logic where KDSERIAL also enables serial output.
|
|
||||||
(KdbDebugState & KD_DEBUG_KDSERIAL) ||
|
|
||||||
(KdpDebugMode.Serial && !KdpDebugMode.Screen);
|
|
||||||
#else
|
|
||||||
// New logic where KDSERIAL does not necessarily enable serial output.
|
|
||||||
KdpDebugMode.Serial &&
|
|
||||||
((KdbDebugState & KD_DEBUG_KDSERIAL) || !KdpDebugMode.Screen);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (SerialTerminal && TerminalConnected && TerminalReportsSize)
|
|
||||||
{
|
|
||||||
/* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
|
|
||||||
TerminalReportsSize = FALSE;
|
|
||||||
KdbpSendCommandSerial("\x1b[18t");
|
|
||||||
KeStallExecutionProcessor(100000);
|
|
||||||
|
|
||||||
c = KdbpTryGetCharSerial(5000);
|
|
||||||
if (c == KEY_ESC)
|
|
||||||
{
|
|
||||||
c = KdbpTryGetCharSerial(5000);
|
|
||||||
if (c == '[')
|
|
||||||
{
|
|
||||||
Length = 0;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
c = KdbpTryGetCharSerial(5000);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
InBuffer[Length++] = c;
|
|
||||||
if (isalpha(c) || Length >= (sizeof(InBuffer) - 1))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
InBuffer[Length] = '\0';
|
|
||||||
|
|
||||||
if (InBuffer[0] == '8' && InBuffer[1] == ';')
|
|
||||||
{
|
|
||||||
for (i = 2; (i < Length) && (InBuffer[i] != ';'); i++);
|
|
||||||
|
|
||||||
if (InBuffer[i] == ';')
|
|
||||||
{
|
|
||||||
InBuffer[i++] = '\0';
|
|
||||||
|
|
||||||
/* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */
|
|
||||||
KdbNumberOfRowsTerminal = strtoul(InBuffer + 2, NULL, 0);
|
|
||||||
KdbNumberOfColsTerminal = strtoul(InBuffer + i, NULL, 0);
|
|
||||||
TerminalReportsSize = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Clear further characters */
|
|
||||||
while ((c = KdbpTryGetCharSerial(5000)) != -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (KdbNumberOfRowsTerminal <= 0)
|
|
||||||
{
|
|
||||||
/* Set number of rows to the default */
|
|
||||||
if (KdpDebugMode.Screen && !SerialTerminal)
|
|
||||||
KdbNumberOfRowsTerminal = (SCREEN_HEIGHT / (13 /*BOOTCHAR_HEIGHT*/ + 1));
|
|
||||||
else
|
|
||||||
KdbNumberOfRowsTerminal = 24;
|
|
||||||
}
|
|
||||||
if (KdbNumberOfColsTerminal <= 0)
|
|
||||||
{
|
|
||||||
/* Set number of cols to the default */
|
|
||||||
if (KdpDebugMode.Screen && !SerialTerminal)
|
|
||||||
KdbNumberOfColsTerminal = (SCREEN_WIDTH / 8 /*BOOTCHAR_WIDTH*/);
|
|
||||||
else
|
|
||||||
KdbNumberOfColsTerminal = 80;
|
|
||||||
}
|
|
||||||
|
|
||||||
// KdpDprintf("Cols/Rows: %dx%d\n",
|
|
||||||
// KdbNumberOfColsTerminal, KdbNumberOfRowsTerminal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through the strings */
|
/* Loop through the strings */
|
||||||
|
@ -3041,7 +2940,7 @@ KdbpPagerInternal(
|
||||||
/* Calculate the number of lines which will be printed in
|
/* Calculate the number of lines which will be printed in
|
||||||
* the terminal when outputting the current line. */
|
* the terminal when outputting the current line. */
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdbNumberOfColsTerminal;
|
RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdTermSize.cx;
|
||||||
else
|
else
|
||||||
RowsPrintedByTerminal = 0;
|
RowsPrintedByTerminal = 0;
|
||||||
|
|
||||||
|
@ -3051,9 +2950,10 @@ KdbpPagerInternal(
|
||||||
//KdpDprintf("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);
|
//KdpDprintf("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);
|
||||||
|
|
||||||
/* Display a prompt if we printed one screen full of text */
|
/* Display a prompt if we printed one screen full of text */
|
||||||
if (KdbNumberOfRowsTerminal > 0 &&
|
if (KdTermSize.cy > 0 &&
|
||||||
(LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdbNumberOfRowsTerminal)
|
(LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdTermSize.cy)
|
||||||
{
|
{
|
||||||
|
/* Disable the repetition of previous command with long many-page output */
|
||||||
KdbRepeatLastCommand = FALSE;
|
KdbRepeatLastCommand = FALSE;
|
||||||
|
|
||||||
if (KdbNumberOfColsPrinted > 0)
|
if (KdbNumberOfColsPrinted > 0)
|
||||||
|
@ -3069,21 +2969,7 @@ KdbpPagerInternal(
|
||||||
}
|
}
|
||||||
RowsPrintedByTerminal++;
|
RowsPrintedByTerminal++;
|
||||||
|
|
||||||
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
c = KdpReadTermKey(&ScanCode);
|
||||||
c = KdbpGetCharSerial();
|
|
||||||
else
|
|
||||||
c = KdbpGetCharKeyboard(&ScanCode);
|
|
||||||
|
|
||||||
if (c == '\r')
|
|
||||||
{
|
|
||||||
/* Try to read '\n' which might follow '\r' - if \n is not received here
|
|
||||||
* it will be interpreted as "return" when the next command should be read.
|
|
||||||
*/
|
|
||||||
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
|
||||||
c = KdbpTryGetCharSerial(5);
|
|
||||||
else
|
|
||||||
c = KdbpTryGetCharKeyboard(&ScanCode, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DoPage)
|
if (DoPage)
|
||||||
{
|
{
|
||||||
|
@ -3106,13 +2992,13 @@ KdbpPagerInternal(
|
||||||
if (ScanCode == KEYSC_END || c == 'e')
|
if (ScanCode == KEYSC_END || c == 'e')
|
||||||
{
|
{
|
||||||
PCHAR pBufEnd = Buffer + BufLength;
|
PCHAR pBufEnd = Buffer + BufLength;
|
||||||
p = CountOnePageUp(Buffer, BufLength, pBufEnd);
|
p = CountOnePageUp(Buffer, BufLength, pBufEnd, &KdTermSize);
|
||||||
i = strcspn(p, "\n");
|
i = strcspn(p, "\n");
|
||||||
}
|
}
|
||||||
else if (ScanCode == KEYSC_PAGEUP ||
|
else if (ScanCode == KEYSC_PAGEUP ||
|
||||||
ScanCode == KEYSC_ARROWUP || c == 'u')
|
ScanCode == KEYSC_ARROWUP || c == 'u')
|
||||||
{
|
{
|
||||||
p = CountOnePageUp(Buffer, BufLength, p);
|
p = CountOnePageUp(Buffer, BufLength, p, &KdTermSize);
|
||||||
i = strcspn(p, "\n");
|
i = strcspn(p, "\n");
|
||||||
}
|
}
|
||||||
else if (ScanCode == KEYSC_HOME || c == 'h')
|
else if (ScanCode == KEYSC_HOME || c == 'h')
|
||||||
|
@ -3139,11 +3025,10 @@ KdbpPagerInternal(
|
||||||
|
|
||||||
/* Remove escape sequences from the line if there is no terminal connected */
|
/* Remove escape sequences from the line if there is no terminal connected */
|
||||||
// FIXME: Dangerous operation since we modify the source string!!
|
// FIXME: Dangerous operation since we modify the source string!!
|
||||||
if (!TerminalConnected)
|
if (!KdTermConnected)
|
||||||
KdpFilterEscapes(p);
|
KdpFilterEscapes(p);
|
||||||
|
|
||||||
/* Print the current line */
|
/* Print the current line */
|
||||||
// KdpDprintf(p);
|
|
||||||
KdpDprintf("%s", p);
|
KdpDprintf("%s", p);
|
||||||
|
|
||||||
/* Restore not null char with saved */
|
/* Restore not null char with saved */
|
||||||
|
@ -3178,7 +3063,7 @@ KdbpPagerInternal(
|
||||||
* Maximum length of buffer is limited only by memory size.
|
* Maximum length of buffer is limited only by memory size.
|
||||||
* Uses KdpDprintf internally (NOT DbgPrint!). Callers must already hold the debugger lock.
|
* Uses KdpDprintf internally (NOT DbgPrint!). Callers must already hold the debugger lock.
|
||||||
*
|
*
|
||||||
* Note: BufLength should be greater then (KdbNumberOfRowsTerminal * KdbNumberOfColsTerminal).
|
* Note: BufLength should be greater than (KdTermSize.cx * KdTermSize.cy).
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
KdbpPager(
|
KdbpPager(
|
||||||
|
@ -3408,17 +3293,6 @@ KdbpCliMainLoop(
|
||||||
KdbpPrint("\n");
|
KdbpPrint("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush the input buffer */
|
|
||||||
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
|
||||||
{
|
|
||||||
while (KdbpTryGetCharSerial(1) != -1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ULONG ScanCode;
|
|
||||||
while (KdbpTryGetCharKeyboard(&ScanCode, 1) != -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main loop */
|
/* Main loop */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -3687,6 +3561,13 @@ KdbInitialize(
|
||||||
/* Write out the functions that we support for now */
|
/* Write out the functions that we support for now */
|
||||||
DispatchTable->KdpPrintRoutine = KdbDebugPrint;
|
DispatchTable->KdpPrintRoutine = KdbDebugPrint;
|
||||||
|
|
||||||
|
/* Check if we have a command line */
|
||||||
|
if (KeLoaderBlock && KeLoaderBlock->LoadOptions)
|
||||||
|
{
|
||||||
|
/* Get the KDBG Settings */
|
||||||
|
KdbpGetCommandLineSettings(KeLoaderBlock->LoadOptions);
|
||||||
|
}
|
||||||
|
|
||||||
/* Register for BootPhase 1 initialization and as a Provider */
|
/* Register for BootPhase 1 initialization and as a Provider */
|
||||||
DispatchTable->KdpInitRoutine = KdbInitialize;
|
DispatchTable->KdpInitRoutine = KdbInitialize;
|
||||||
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
|
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
|
||||||
|
|
|
@ -415,7 +415,8 @@ if(NOT _WINKD_)
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdmain.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdmain.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdprompt.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdprompt.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdps2kbd.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdps2kbd.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdserial.c)
|
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdserial.c
|
||||||
|
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdterminal.c)
|
||||||
|
|
||||||
else()
|
else()
|
||||||
add_definitions(-D_WINKD_)
|
add_definitions(-D_WINKD_)
|
||||||
|
|
Loading…
Reference in a new issue