https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9337ea6a3c6b93837a02c…
commit 9337ea6a3c6b93837a02ca83dd2d8899d40d7072
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Nov 21 16:35:47 2022 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Nov 22 02:10:54 2022 +0100
[NTOS:KDBG] Deduplicate code between KdbpPrint() and KdbpPager().
---
ntoskrnl/kdbg/kdb.h | 9 +-
ntoskrnl/kdbg/kdb_cli.c | 548 ++++++++++++++++++------------------------------
2 files changed, 207 insertions(+), 350 deletions(-)
diff --git a/ntoskrnl/kdbg/kdb.h b/ntoskrnl/kdbg/kdb.h
index 542cc398f11..d78e2696cdd 100644
--- a/ntoskrnl/kdbg/kdb.h
+++ b/ntoskrnl/kdbg/kdb.h
@@ -98,10 +98,15 @@ KdbpCliMainLoop(
VOID
KdbpCliInterpretInitFile(VOID);
+VOID
+KdbpPager(
+ _In_ PCHAR Buffer,
+ _In_ ULONG BufLength);
+
VOID
KdbpPrint(
- IN PCHAR Format,
- IN ... OPTIONAL);
+ _In_ PSTR Format,
+ _In_ ...);
VOID
KdbpPrintUnicodeString(
diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c
index e044572691d..806ace30fb2 100644
--- a/ntoskrnl/kdbg/kdb_cli.c
+++ b/ntoskrnl/kdbg/kdb_cli.c
@@ -2526,12 +2526,6 @@ KdbpCmdReboot(
return FALSE;
}
-
-VOID
-KdbpPager(
- IN PCHAR Buffer,
- IN ULONG BufLength);
-
/*!\brief Display debug messages on screen, with paging.
*
* Keys for per-page view: Home, End, PageUp, Arrow Up, PageDown,
@@ -2787,266 +2781,9 @@ KdbpCmdHelp(
return TRUE;
}
-/*!\brief Prints the given string with printf-like formatting.
- *
- * \param Format Format of the string/arguments.
- * \param ... Variable number of arguments matching the format specified in \a
Format.
- *
- * \note Doesn't correctly handle \\t and terminal escape sequences when calculating
the
- * number of lines required to print a single line from the Buffer in the
terminal.
- * Prints maximum 4096 chars, because of its buffer size.
- * Uses KdpDPrintf internally (NOT DbgPrint!). Callers must already hold the
debugger lock.
- */
-VOID
-KdbpPrint(
- IN PCHAR Format,
- IN ... OPTIONAL)
-{
- static CHAR Buffer[4096];
- static BOOLEAN TerminalInitialized = FALSE;
- static BOOLEAN TerminalConnected = FALSE;
- static BOOLEAN TerminalReportsSize = TRUE;
- CHAR c = '\0';
- PCHAR p, p2;
- ULONG Length;
- SIZE_T i, j;
- LONG RowsPrintedByTerminal;
- ULONG ScanCode;
- va_list ap;
-
- /* Check if the user has aborted output of the current command */
- if (KdbOutputAborted)
- return;
-
- /* Initialize the terminal */
- if (!TerminalInitialized)
- {
- KdpDprintf("\x1b[7h"); /* Enable linewrap */
-
- /* Query terminal type */
- /*DbgPrint("\x1b[Z");*/
- KdpDprintf("\x05");
-
- TerminalInitialized = TRUE;
- Length = 0;
- KeStallExecutionProcessor(100000);
-
- for (;;)
- {
- c = KdbpTryGetCharSerial(5000);
- if (c == -1)
- break;
-
- Buffer[Length++] = c;
- if (Length >= (sizeof(Buffer) - 1))
- break;
- }
-
- Buffer[Length] = '\0';
- if (Length > 0)
- TerminalConnected = TRUE;
- }
-
- /* Get number of rows and columns in terminal */
- if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
- (KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of
rows printed is 0 */
- {
- if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected
&& TerminalReportsSize)
- {
- /* Try to query number of rows from terminal. A reply looks like
"\x1b[8;24;80t" */
- TerminalReportsSize = FALSE;
- KeStallExecutionProcessor(100000);
- KdpDprintf("\x1b[18t");
- c = KdbpTryGetCharSerial(5000);
-
- if (c == KEY_ESC)
- {
- c = KdbpTryGetCharSerial(5000);
- if (c == '[')
- {
- Length = 0;
-
- for (;;)
- {
- c = KdbpTryGetCharSerial(5000);
- if (c == -1)
- break;
-
- Buffer[Length++] = c;
- if (isalpha(c) || Length >= (sizeof(Buffer) - 1))
- break;
- }
-
- Buffer[Length] = '\0';
- if (Buffer[0] == '8' && Buffer[1] == ';')
- {
- for (i = 2; (i < Length) && (Buffer[i] !=
';'); i++);
-
- if (Buffer[i] == ';')
- {
- Buffer[i++] = '\0';
-
- /* Number of rows is now at Buffer + 2 and number of cols at
Buffer + i */
- KdbNumberOfRowsTerminal = strtoul(Buffer + 2, NULL, 0);
- KdbNumberOfColsTerminal = strtoul(Buffer + i, NULL, 0);
- TerminalReportsSize = TRUE;
- }
- }
- }
- /* Clear further characters */
- while ((c = KdbpTryGetCharSerial(5000)) != -1);
- }
- }
-
- if (KdbNumberOfRowsTerminal <= 0)
- {
- /* Set number of rows to the default. */
- KdbNumberOfRowsTerminal = 23; //24; //Mna.: 23 for SCREEN debugport
- }
- else if (KdbNumberOfColsTerminal <= 0)
- {
- /* Set number of cols to the default. */
- KdbNumberOfColsTerminal = 75; //80; //Mna.: 75 for SCREEN debugport
- }
- }
-
- /* Get the string */
- va_start(ap, Format);
- Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
- Buffer[Length] = '\0';
- va_end(ap);
-
- p = Buffer;
- while (p[0] != '\0')
- {
- i = strcspn(p, "\n");
-
- /* Calculate the number of lines which will be printed in the terminal
- * when outputting the current line
- */
- if (i > 0)
- RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) /
KdbNumberOfColsTerminal;
- else
- RowsPrintedByTerminal = 0;
-
- if (p[i] == '\n')
- RowsPrintedByTerminal++;
-
- /*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted,
KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
-
- /* Display a prompt if we printed one screen full of text */
- if (KdbNumberOfRowsTerminal > 0 &&
- (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >=
KdbNumberOfRowsTerminal)
- {
- KdbRepeatLastCommand = FALSE;
-
- if (KdbNumberOfColsPrinted > 0)
- KdpDprintf("\n");
-
- KdpDprintf("--- Press q to abort, any other key to continue ---");
- RowsPrintedByTerminal++; /* added by Mna. */
-
- if (KdbDebugState & KD_DEBUG_KDSERIAL)
- 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);
- }
-
- KdpDprintf("\n");
- if (c == 'q')
- {
- KdbOutputAborted = TRUE;
- return;
- }
-
- KdbNumberOfRowsPrinted = 0;
- KdbNumberOfColsPrinted = 0;
- }
-
- /* Insert a NUL after the line and print only the current line. */
- if (p[i] == '\n' && p[i + 1] != '\0')
- {
- c = p[i + 1];
- p[i + 1] = '\0';
- }
- else
- {
- c = '\0';
- }
-
- /* Remove escape sequences from the line if there's no terminal connected */
- if (!TerminalConnected)
- {
- while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
- {
- size_t len = strlen(p2);
- if (p2[1] == '[')
- {
- j = 2;
- while (!isalpha(p2[j++]));
- memmove(p2, p2 + j, len + 1 - j);
- }
- else
- {
- memmove(p2, p2 + 1, len);
- }
- }
- }
-
- KdpDprintf("%s", p);
-
- if (c != '\0')
- p[i + 1] = c;
-
- /* Set p to the start of the next line and
- * remember the number of rows/cols printed
- */
- p += i;
- if (p[0] == '\n')
- {
- p++;
- KdbNumberOfColsPrinted = 0;
- }
- else
- {
- ASSERT(p[0] == '\0');
- KdbNumberOfColsPrinted += i;
- }
-
- KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
- }
-}
-
-VOID
-KdbpPrintUnicodeString(
- _In_ PCUNICODE_STRING String)
-{
- ULONG i;
-
- if ((String == NULL) || (String->Buffer == NULL))
- {
- KdbpPrint("<NULL>");
- return;
- }
-
- for (i = 0; i < String->Length / sizeof(WCHAR); i++)
- {
- KdbpPrint("%c", (CHAR)String->Buffer[i]);
- }
-}
-/** memrchr(), explicitly defined, since was absent in MinGW of RosBE. */
/*
+ * memrchr(), explicitly defined, since absent in the CRT.
* Reverse memchr()
* Find the last occurrence of 'c' in the buffer 's' of size
'n'.
*/
@@ -3078,14 +2815,17 @@ memrchr(const void *s, int c, size_t n)
* Used by KdbpPager().
* Now N lines count is hardcoded to KdbNumberOfRowsTerminal.
*/
-PCHAR
-CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
+static PCHAR
+CountOnePageUp(
+ _In_ PCCH Buffer,
+ _In_ ULONG BufLength,
+ _In_ PCCH pCurPos)
{
- PCHAR p;
+ PCCH p;
// p0 is initial guess of Page Start
ULONG p0len = KdbNumberOfRowsTerminal * KdbNumberOfColsTerminal;
- PCHAR p0 = pCurPos - p0len;
- PCHAR prev_p = p0, p1;
+ PCCH p0 = pCurPos - p0len;
+ PCCH prev_p = p0, p1;
ULONG j;
if (pCurPos < Buffer)
@@ -3093,7 +2833,7 @@ CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
ASSERT(pCurPos <= Buffer + BufLength);
p = memrchr(p0, '\n', p0len);
- if (NULL == p)
+ if (!p)
p = p0;
for (j = KdbNumberOfRowsTerminal; j--; )
{
@@ -3101,10 +2841,10 @@ CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
p1 = memrchr(p0, '\n', p-p0);
prev_p = p;
p = p1;
- if (NULL == p)
+ if (!p)
{
p = prev_p;
- if (NULL == p)
+ if (!p)
p = p0;
break;
}
@@ -3113,9 +2853,33 @@ CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
j -= linesCnt-1;
}
- ASSERT(p != 0);
+ ASSERT(p != NULL);
++p;
- return p;
+ return (PCHAR)p;
+}
+
+static VOID
+KdpFilterEscapes(
+ _Inout_ PSTR String)
+{
+ PCHAR p;
+ SIZE_T i;
+ size_t len;
+
+ while ((p = strrchr(String, '\x1b'))) /* Look for escape character */
+ {
+ len = strlen(p);
+ if (p[1] == '[')
+ {
+ i = 2;
+ while (!isalpha(p[i++]));
+ memmove(p, p + i, len + 1 - i);
+ }
+ else
+ {
+ memmove(p, p + 1, len);
+ }
+ }
}
/*!\brief Prints the given string with, page by page.
@@ -3126,27 +2890,28 @@ CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
* \note Doesn't correctly handle \\t and terminal escape sequences when calculating
the
* number of lines required to print a single line from the Buffer in the
terminal.
* Maximum length of buffer is limited only by memory size.
+ * Uses KdpDprintf internally (NOT DbgPrint!). Callers must already hold the
debugger lock.
*
* Note: BufLength should be greater then (KdbNumberOfRowsTerminal *
KdbNumberOfColsTerminal).
- *
*/
VOID
-KdbpPager(
- IN PCHAR Buffer,
- IN ULONG BufLength)
+KdbpPagerInternal(
+ _In_ PCHAR Buffer,
+ _In_ ULONG BufLength,
+ _In_ BOOLEAN DoPage)
{
- static CHAR InBuffer[4096];
+ static CHAR InBuffer[128];
static BOOLEAN TerminalInitialized = FALSE;
static BOOLEAN TerminalConnected = FALSE;
static BOOLEAN TerminalReportsSize = TRUE;
- CHAR c = '\0';
- PCHAR p, p2;
+ CHAR c;
+ ULONG ScanCode;
+ PCHAR p;
ULONG Length;
- SIZE_T i, j;
+ SIZE_T i;
LONG RowsPrintedByTerminal;
- ULONG ScanCode;
- if( BufLength == 0)
+ if (BufLength == 0)
return;
/* Check if the user has aborted output of the current command */
@@ -3156,13 +2921,14 @@ KdbpPager(
/* Initialize the terminal */
if (!TerminalInitialized)
{
+ TerminalInitialized = TRUE;
+
KdpDprintf("\x1b[7h"); /* Enable linewrap */
/* Query terminal type */
/*DbgPrint("\x1b[Z");*/
KdpDprintf("\x05");
- TerminalInitialized = TRUE;
Length = 0;
KeStallExecutionProcessor(100000);
@@ -3184,7 +2950,8 @@ KdbpPager(
/* Get number of rows and columns in terminal */
if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
- (KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of
rows printed is 0 */
+ /* Refresh terminal size each time when number of rows printed is 0 */
+ (KdbNumberOfRowsPrinted) == 0)
{
if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected
&& TerminalReportsSize)
{
@@ -3235,36 +3002,45 @@ KdbpPager(
if (KdbNumberOfRowsTerminal <= 0)
{
- /* Set number of rows to the default. */
- KdbNumberOfRowsTerminal = 24;
+ /* Set number of rows to the default */
+ if (!DoPage)
+ KdbNumberOfRowsTerminal = 23; //Mna.: for SCREEN debugport
+ else
+ KdbNumberOfRowsTerminal = 24;
}
else if (KdbNumberOfColsTerminal <= 0)
{
- /* Set number of cols to the default. */
- KdbNumberOfColsTerminal = 80;
+ /* Set number of cols to the default */
+ if (!DoPage)
+ KdbNumberOfColsTerminal = 75; //Mna.: for SCREEN debugport
+ else
+ KdbNumberOfColsTerminal = 80;
}
}
- /* Get the string */
+ /* Loop through the strings */
p = Buffer;
-
while (p[0] != '\0')
{
- if ( p > Buffer+BufLength)
+ if (DoPage)
{
- KdpDprintf("Dmesg: error, p > Buffer+BufLength,d=%d", p -
(Buffer+BufLength));
- return;
+ if (p > Buffer + BufLength)
+ {
+ KdpDprintf("Dmesg: error, p > Buffer+BufLength,d=%d", p -
(Buffer + BufLength));
+ return;
+ }
}
i = strcspn(p, "\n");
- // Are we out of buffer?
- if (p + i > Buffer + BufLength)
- // Leaving pager function:
- break;
+ if (DoPage)
+ {
+ /* Are we out of buffer? */
+ if (p + i > Buffer + BufLength)
+ break; // Leaving pager function
+ }
- /* Calculate the number of lines which will be printed in the terminal
- * when outputting the current line.
- */
+ /* Calculate the number of lines which will be printed in
+ * the terminal when outputting the current line. */
if (i > 0)
RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) /
KdbNumberOfColsTerminal;
else
@@ -3273,7 +3049,7 @@ KdbpPager(
if (p[i] == '\n')
RowsPrintedByTerminal++;
- /*DbgPrint("!%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 */
if (KdbNumberOfRowsTerminal > 0 &&
@@ -3284,7 +3060,14 @@ KdbpPager(
if (KdbNumberOfColsPrinted > 0)
KdpDprintf("\n");
- KdpDprintf("--- Press q to abort, e/End,h/Home,u/PgUp, other key/PgDn
---");
+ if (DoPage)
+ {
+ KdpDprintf("--- Press q to abort, e/End,h/Home,u/PgUp, other
key/PgDn ---");
+ }
+ else
+ {
+ KdpDprintf("--- Press q to abort, any other key to continue
---");
+ }
RowsPrintedByTerminal++;
if (KdbDebugState & KD_DEBUG_KDSERIAL)
@@ -3303,41 +3086,52 @@ KdbpPager(
c = KdbpTryGetCharKeyboard(&ScanCode, 5);
}
- //DbgPrint("\n"); //Consize version: don't show pressed key
- KdpDprintf(" '%c'/scan=%04x\n", c, ScanCode); // Shows
pressed key
-
- if (c == 'q')
- {
- KdbOutputAborted = TRUE;
- return;
- }
- if ( ScanCode == KEYSC_END || c=='e')
+ if (DoPage)
{
- PCHAR pBufEnd = Buffer + BufLength;
- p = CountOnePageUp(Buffer, BufLength, pBufEnd);
- i = strcspn(p, "\n");
+ //KdpDprintf("\n"); // Concise version: don't show pressed
key
+ KdpDprintf(" '%c'/scan=%04x\n", c, ScanCode); // Shows
pressed key
}
- else if (ScanCode == KEYSC_PAGEUP || c=='u')
+ else
{
- p = CountOnePageUp(Buffer, BufLength, p);
- i = strcspn(p, "\n");
+ KdpDprintf("\n");
}
- else if (ScanCode == KEYSC_HOME || c=='h')
+
+ if (c == 'q')
{
- p = Buffer;
- i = strcspn(p, "\n");
+ KdbOutputAborted = TRUE;
+ return;
}
- else if (ScanCode == KEYSC_ARROWUP)
+
+ if (DoPage)
{
- p = CountOnePageUp(Buffer, BufLength, p);
- i = strcspn(p, "\n");
+ if (ScanCode == KEYSC_END || c == 'e')
+ {
+ PCHAR pBufEnd = Buffer + BufLength;
+ p = CountOnePageUp(Buffer, BufLength, pBufEnd);
+ i = strcspn(p, "\n");
+ }
+ else if (ScanCode == KEYSC_PAGEUP || c == 'u')
+ {
+ p = CountOnePageUp(Buffer, BufLength, p);
+ i = strcspn(p, "\n");
+ }
+ else if (ScanCode == KEYSC_HOME || c == 'h')
+ {
+ p = Buffer;
+ i = strcspn(p, "\n");
+ }
+ else if (ScanCode == KEYSC_ARROWUP)
+ {
+ p = CountOnePageUp(Buffer, BufLength, p);
+ i = strcspn(p, "\n");
+ }
}
KdbNumberOfRowsPrinted = 0;
KdbNumberOfColsPrinted = 0;
}
- /* Insert a NUL after the line and print only the current line. */
+ /* Insert a NUL after the line and print only the current line */
if (p[i] == '\n' && p[i + 1] != '\0')
{
c = p[i + 1];
@@ -3348,35 +3142,21 @@ KdbpPager(
c = '\0';
}
- /* Remove escape sequences from the line if there's no terminal connected */
+ /* Remove escape sequences from the line if there is no terminal connected */
+ // FIXME: Dangerous operation since we modify the source string!!
if (!TerminalConnected)
- {
- while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
- {
- size_t len = strlen(p2);
- if (p2[1] == '[')
- {
- j = 2;
- while (!isalpha(p2[j++]));
- memmove(p2, p2 + j, len + 1 - j);
- }
- else
- {
- memmove(p2, p2 + 1, len);
- }
- }
- }
+ KdpFilterEscapes(p);
- // The main printing of the current line:
- KdpDprintf(p);
+ /* Print the current line */
+ // KdpDprintf(p);
+ KdpDprintf("%s", p);
- // restore not null char with saved:
+ /* Restore not null char with saved */
if (c != '\0')
p[i + 1] = c;
/* Set p to the start of the next line and
- * remember the number of rows/cols printed
- */
+ * remember the number of rows/cols printed */
p += i;
if (p[0] == '\n')
{
@@ -3393,6 +3173,78 @@ KdbpPager(
}
}
+/*!\brief Prints the given string with, page by page.
+ *
+ * \param Buffer Characters buffer to print.
+ * \param BufferLen Buffer size.
+ *
+ * \note Doesn't correctly handle \\t and terminal escape sequences when calculating
the
+ * number of lines required to print a single line from the Buffer in the
terminal.
+ * Maximum length of buffer is limited only by memory size.
+ * Uses KdpDprintf internally (NOT DbgPrint!). Callers must already hold the
debugger lock.
+ *
+ * Note: BufLength should be greater then (KdbNumberOfRowsTerminal *
KdbNumberOfColsTerminal).
+ */
+VOID
+KdbpPager(
+ _In_ PCHAR Buffer,
+ _In_ ULONG BufLength)
+{
+ /* Call the internal function */
+ KdbpPagerInternal(Buffer, BufLength, TRUE);
+}
+
+/*!\brief Prints the given string with printf-like formatting.
+ *
+ * \param Format Format of the string/arguments.
+ * \param ... Variable number of arguments matching the format specified in \a
Format.
+ *
+ * \note Doesn't correctly handle \\t and terminal escape sequences when calculating
the
+ * number of lines required to print a single line from the Buffer in the
terminal.
+ * Prints maximum 4096 chars, because of its buffer size.
+ */
+VOID
+KdbpPrint(
+ _In_ PSTR Format,
+ _In_ ...)
+{
+ static CHAR Buffer[4096];
+ ULONG Length;
+ va_list ap;
+
+ /* Check if the user has aborted output of the current command */
+ if (KdbOutputAborted)
+ return;
+
+ /* Build the string */
+ va_start(ap, Format);
+ Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
+ Buffer[Length] = '\0';
+ va_end(ap);
+
+ /* Actually print it */
+ KdbpPagerInternal(Buffer, Length, FALSE);
+}
+
+VOID
+KdbpPrintUnicodeString(
+ _In_ PCUNICODE_STRING String)
+{
+ ULONG i;
+
+ if ((String == NULL) || (String->Buffer == NULL))
+ {
+ KdbpPrint("<NULL>");
+ return;
+ }
+
+ for (i = 0; i < String->Length / sizeof(WCHAR); i++)
+ {
+ KdbpPrint("%c", (CHAR)String->Buffer[i]);
+ }
+}
+
+
/*!\brief Appends a command to the command history
*
* \param Command Pointer to the command to append to the history.