Alex Ionescu <ionucu@videotron.ca>
- Add KeGetCurrentPrcb function and use it where appropriate.
- Fix returning of values in ExGetCurrentProcessorCpuUsage and ExGetCurrentProcessorCounts.
- Move ExIsProcessorFeaturePresent from ex/init.c to ex/sysinfo.c.
Modified: trunk/reactos/ntoskrnl/dbg/kdb_cli.c
Modified: trunk/reactos/ntoskrnl/ex/init.c
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ps.h
Modified: trunk/reactos/ntoskrnl/ke/clock.c
Modified: trunk/reactos/ntoskrnl/ke/i386/fpu.c
Modified: trunk/reactos/ntoskrnl/ke/i386/irq.c
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
Modified: trunk/reactos/ntoskrnl/ke/ipi.c
Modified: trunk/reactos/ntoskrnl/ps/i386/continue.c
Modified: trunk/reactos/ntoskrnl/ps/idle.c
Modified: trunk/reactos/ntoskrnl/ps/kill.c
Modified: trunk/reactos/ntoskrnl/ps/process.c
Modified: trunk/reactos/ntoskrnl/ps/w32call.c

Modified: trunk/reactos/ntoskrnl/dbg/kdb_cli.c
--- trunk/reactos/ntoskrnl/dbg/kdb_cli.c	2005-03-12 09:21:59 UTC (rev 13964)
+++ trunk/reactos/ntoskrnl/dbg/kdb_cli.c	2005-03-12 09:40:07 UTC (rev 13965)
@@ -1,2320 +1,2320 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 2005 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id$
- *
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/dbg/kdb_cli.c
- * PURPOSE:         Kernel debugger command line interface
- * PROGRAMMER:      Gregor Anich (blight@blight.eu.org)
- * UPDATE HISTORY:
- *                  Created 16/01/2005
- */
- 
-/* INCLUDES ******************************************************************/
-
-#include <ntoskrnl.h>
-#include "kdb.h"
-#define NDEBUG
-#include <internal/debug.h>
-
-/* DEFINES *******************************************************************/
-
-#define KEY_BS          8
-#define KEY_ESC         27
-#define KEY_DEL         127
-
-#define KEY_SCAN_UP     72
-#define KEY_SCAN_DOWN   80
-
-#define KDB_ENTER_CONDITION_TO_STRING(cond)                               \
-                   ((cond) == KdbDoNotEnter ? "never" :                   \
-                   ((cond) == KdbEnterAlways ? "always" :                 \
-                   ((cond) == KdbEnterFromKmode ? "kmode" : "umode")))
-
-#define KDB_ACCESS_TYPE_TO_STRING(type)                                   \
-                   ((type) == KdbAccessRead ? "read" :                    \
-                   ((type) == KdbAccessWrite ? "write" :                  \
-                   ((type) == KdbAccessReadWrite ? "rdwr" : "exec")))
-
-#define NPX_STATE_TO_STRING(state)                                        \
-                   ((state) == NPX_STATE_INVALID ? "Invalid" :            \
-                   ((state) == NPX_STATE_VALID ? "Valid" :                \
-                   ((state) == NPX_STATE_DIRTY ? "Dirty" : "Unknown")))
-
-/* PROTOTYPES ****************************************************************/
-
-STATIC BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[]);
-
-STATIC BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[]);
-
-STATIC BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[]);
-
-STATIC BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
-
-STATIC BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]);
-STATIC BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]);
-
-/* GLOBALS *******************************************************************/
-
-STATIC BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
-
-STATIC CHAR KdbCommandHistoryBuffer[2048]; /* Command history string ringbuffer */
-STATIC PCHAR KdbCommandHistory[sizeof(KdbCommandHistoryBuffer) / 8] = { NULL }; /* Command history ringbuffer */
-STATIC LONG KdbCommandHistoryBufferIndex = 0;
-STATIC LONG KdbCommandHistoryIndex = 0;
-
-STATIC ULONG KdbNumberOfRowsPrinted = 0;
-STATIC ULONG KdbNumberOfColsPrinted = 0;
-STATIC BOOLEAN KdbOutputAborted = FALSE;
-STATIC LONG KdbNumberOfRowsTerminal = -1;
-STATIC LONG KdbNumberOfColsTerminal = -1;
-
-PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
-
-STATIC CONST struct
-{
-   PCHAR Name;
-   PCHAR Syntax;
-   PCHAR Help;
-   BOOLEAN (*Fn)(ULONG Argc, PCHAR Argv[]);
-} KdbDebuggerCommands[] = {
-   /* Data */
-   { NULL, NULL, "Data", NULL },
-   { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression },
-   { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
-   { "x", "x [address] [L count]", "Display count dwords, starting at addr.", KdbpCmdDisassembleX },
-   { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
-   { "cregs", "cregs", "Display control registers.", KdbpCmdRegs },
-   { "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
-   { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
-   { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame addr", KdbpCmdBackTrace },
-
-   /* Flow control */
-   { NULL, NULL, "Flow control", NULL },
-   { "cont", "cont", "Continue execution (leave debugger)", KdbpCmdContinue },
-   { "step", "step [count]", "Execute single instructions, stepping into interrupts.", KdbpCmdStep },
-   { "next", "next [count]", "Execute single instructions, skipping calls and reps.", KdbpCmdStep },
-   { "bl", "bl", "List breakpoints.", KdbpCmdBreakPointList },
-   { "be", "be [breakpoint]", "Enable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
-   { "bd", "bd [breakpoint]", "Disable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
-   { "bc", "bc [breakpoint]", "Clear breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
-   { "bpx", "bpx [address] [IF condition]", "Set software execution breakpoint at address.", KdbpCmdBreakPoint },
-   { "bpm", "bpm [r|w|rw|x] [byte|word|dword] [address] [IF condition]", "Set memory breakpoint at address.", KdbpCmdBreakPoint },
-
-   /* Process/Thread */
-   { NULL, NULL, "Process/Thread", NULL },
-   { "thread", "thread [list[ pid]|[attach ]tid]", "List threads in current or specified process, display thread with given id or attach to thread.", KdbpCmdThread },
-   { "proc", "proc [list|[attach ]pid]", "List processes, display process with given id or attach to process.", KdbpCmdProc },
-
-   /* System information */
-   { NULL, NULL, "System info", NULL },
-   { "mod", "mod [address]", "List all modules or the one containing address.", KdbpCmdMod },
-   { "gdt", "gdt", "Display global descriptor table.", KdbpCmdGdtLdtIdt },
-   { "ldt", "ldt", "Display local descriptor table.", KdbpCmdGdtLdtIdt },
-   { "idt", "idt", "Display interrupt descriptor table.", KdbpCmdGdtLdtIdt },
-   { "pcr", "pcr", "Display processor control region.", KdbpCmdPcr },
-   { "tss", "tss", "Display task state segment.", KdbpCmdTss },
-
-   /* Others */
-   { NULL, NULL, "Others", NULL },
-   { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck },
-   { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet },
-   { "help", "help", "Display help screen.", KdbpCmdHelp }
-};
-
-/* FUNCTIONS *****************************************************************/
-
-/*!\brief Evaluates an expression...
- *
- * Much like KdbpRpnEvaluateExpression, but prints the error message (if any)
- * at the given offset.
- *
- * \param Expression  Expression to evaluate.
- * \param ErrOffset   Offset (in characters) to print the error message at.
- * \param Result      Receives the result on success.
- *
- * \retval TRUE   Success.
- * \retval FALSE  Failure.
- */
-STATIC BOOLEAN
-KdbpEvaluateExpression(
-   IN  PCHAR Expression,
-   IN  LONG ErrOffset,
-   OUT PULONGLONG Result)
-{
-   STATIC CHAR ErrMsgBuffer[130] = "^ ";
-   LONG ExpressionErrOffset = -1;
-   PCHAR ErrMsg = ErrMsgBuffer;
-   BOOLEAN Ok;
-
-   Ok = KdbpRpnEvaluateExpression(Expression, KdbCurrentTrapFrame, Result,
-                                  &ExpressionErrOffset, ErrMsgBuffer + 2);
-   if (!Ok)
-   {
-      if (ExpressionErrOffset >= 0)
-         ExpressionErrOffset += ErrOffset;
-      else
-         ErrMsg += 2;
-      KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
-   }
-   
-   return Ok;
-}
-
-/*!\brief Evaluates an expression and displays the result.
- */
-STATIC BOOLEAN
-KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[])
-{
-   INT i, len;
-   ULONGLONG Result = 0;
-   ULONG ul;
-   LONG l = 0;
-   BOOLEAN Ok;
-
-   if (Argc < 2)
-   {
-      KdbpPrint("?: Argument required\n");
-      return TRUE;
-   }
-   
-   /* Put the arguments back together */
-   Argc--;
-   for (i = 1; i < Argc; i++)
-   {
-      len = strlen(Argv[i]);
-      Argv[i][len] = ' ';
-   }
-   
-   /* Evaluate the expression */
-   Ok = KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result);
-   if (Ok)
-   {
-      if (Result > 0x00000000ffffffffLL)
-      {
-         if (Result & 0x8000000000000000LL)
-            KdbpPrint("0x%016I64x  %20I64u  %20I64d\n", Result, Result, Result);
-         else
-            KdbpPrint("0x%016I64x  %20I64u\n", Result, Result);
-      }
-      else
-      {
-         ul = (ULONG)Result;
-         if (ul <= 0xff && ul >= 0x80)
-            l = (LONG)((CHAR)ul);
-         else if (ul <= 0xffff && ul >= 0x8000)
-            l = (LONG)((SHORT)ul);
-         else
-            l = (LONG)ul;
-         if (l < 0)
-            KdbpPrint("0x%08lx  %10lu  %10ld\n", ul, ul, l);
-         else
-            KdbpPrint("0x%08lx  %10lu\n", ul, ul);
-      }
-   }
-   
-   return TRUE;
-}
-
-/*!\brief Disassembles 10 instructions at eip or given address or
- *        displays 16 dwords from memory at given address.
- */
-STATIC BOOLEAN
-KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[])
-{
-   ULONG Count;
-   ULONG ul;
-   INT i;
-   ULONGLONG Result = 0;
-   ULONG_PTR Address = KdbCurrentTrapFrame->Tf.Eip;
-   LONG InstLen;
-
-   if (Argv[0][0] == 'x') /* display memory */
-      Count = 16;
-   else /* disassemble */
-      Count = 10;
-
-   if (Argc >= 2)
-   {
-      /* Check for [L count] part */
-      ul = 0;
-      if (strcmp(Argv[Argc-2], "L") == 0)
-      {
-         ul = strtoul(Argv[Argc-1], NULL, 0);
-         if (ul > 0)
-         {
-            Count = ul;
-            Argc -= 2;
-         }
-      }
-      else if (Argv[Argc-1][0] == 'L')
-      {
-         ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
-         if (ul > 0)
-         {
-            Count = ul;
-            Argc--;
-         }
-      }
-
-      /* Put the remaining arguments back together */
-      Argc--;
-      for (ul = 1; ul < Argc; ul++)
-      {
-         Argv[ul][strlen(Argv[ul])] = ' ';
-      }
-      Argc++;
-   }
-
-   /* Evaluate the expression */
-   if (Argc > 1)
-   {
-      if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
-         return TRUE;
-      if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
-         KdbpPrint("Warning: Address %I64x is beeing truncated\n");
-      Address = (ULONG_PTR)Result;
-   }
-   else if (Argv[0][0] == 'x')
-   {
-      KdbpPrint("x: Address argument required.\n");
-      return TRUE;
-   }
-
-   if (Argv[0][0] == 'x')
-   {
-      /* Display dwords */
-      ul = 0;
-      while (Count > 0)
-      {
-         if (!KdbSymPrintAddress((PVOID)Address))
-            KdbpPrint("<%x>:", Address);
-         else
-            KdbpPrint(":");
-         i = min(4, Count);
-         Count -= i;
-         while (--i >= 0)
-         {
-            if (!NT_SUCCESS(KdbpSafeReadMemory(&ul, (PVOID)Address, sizeof(ul))))
-               KdbpPrint(" ????????");
-            else
-               KdbpPrint(" %08x", ul);
-            Address += sizeof(ul);
-         }
-         KdbpPrint("\n");
-      }
-   }
-   else
-   {
-      /* Disassemble */
-      while (Count-- > 0)
-      {
-         if (!KdbSymPrintAddress((PVOID)Address))
-            KdbpPrint("<%08x>: ", Address);
-         else
-            KdbpPrint(": ");
-         InstLen = KdbpDisassemble(Address, KdbUseIntelSyntax);
-         if (InstLen < 0)
-         {
-            KdbpPrint("<INVALID>\n");
-            return TRUE;
-         }
-         KdbpPrint("\n");
-         Address += InstLen;
-      }
-   }
-
-   return TRUE;
-}
-
-/*!\brief Displays CPU registers.
- */
-STATIC BOOLEAN
-KdbpCmdRegs(ULONG Argc, PCHAR Argv[])
-{
-   PKTRAP_FRAME Tf = &KdbCurrentTrapFrame->Tf;
-   INT i;
-   STATIC CONST PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
-                                         " ZF", " SF", " TF", " IF", " DF", " OF",
-                                         NULL, NULL, " NT", " BIT15", " RF", " VF",
-                                         " AC", " VIF", " VIP", " ID", " BIT22",
-                                         " BIT23", " BIT24", " BIT25", " BIT26",
-                                         " BIT27", " BIT28", " BIT29", " BIT30",
-                                         " BIT31" };
-
-   if (Argv[0][0] == 'r') /* regs */
-   {
-      KdbpPrint("CS:EIP  0x%04x:0x%08x\n"
-                "SS:ESP  0x%04x:0x%08x\n"
-                "   EAX  0x%08x   EBX  0x%08x\n"
-                "   ECX  0x%08x   EDX  0x%08x\n"
-                "   ESI  0x%08x   EDI  0x%08x\n"
-                "   EBP  0x%08x\n",
-                Tf->Cs & 0xFFFF, Tf->Eip,
-                Tf->Ss, Tf->Esp,
-                Tf->Eax, Tf->Ebx,
-                Tf->Ecx, Tf->Edx,
-                Tf->Esi, Tf->Edi,
-                Tf->Ebp);
-      KdbpPrint("EFLAGS  0x%08x ", Tf->Eflags);
-      for (i = 0; i < 32; i++)
-      {
-         if (i == 1)
-         {
-            if ((Tf->Eflags & (1 << 1)) == 0)
-               KdbpPrint(" !BIT1");
-         }
-         else if (i == 12)
-         {
-            KdbpPrint(" IOPL%d", (Tf->Eflags >> 12) & 3);
-         }
-         else if (i == 13)
-         {
-         }
-         else if ((Tf->Eflags & (1 << i)) != 0)
-            KdbpPrint(EflagsBits[i]);
-      }
-      KdbpPrint("\n");
-   }
-   else if (Argv[0][0] == 'c') /* cregs */
-   {
-      ULONG Cr0, Cr2, Cr3, Cr4;
-      struct __attribute__((packed)) {
-         USHORT Limit;
-         ULONG Base;
-      } Gdtr, Ldtr, Idtr;
-      ULONG Tr;
-      STATIC CONST PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL,
-                                         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                         " WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL,
-                                         NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" };
-      STATIC CONST PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE",
-                                         " PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL,
-                                         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-                                         
-      Cr0 = KdbCurrentTrapFrame->Cr0;
-      Cr2 = KdbCurrentTrapFrame->Cr2;
-      Cr3 = KdbCurrentTrapFrame->Cr3;
-      Cr4 = KdbCurrentTrapFrame->Cr4;
-
-      /* Get descriptor table regs */
-      asm volatile("sgdt %0" : : "m"(Gdtr));
-      asm volatile("sldt %0" : : "m"(Ldtr));
-      asm volatile("sidt %0" : : "m"(Idtr));
-
-      /* Get the task register */
-      asm volatile("str %0" : "=g"(Tr));
-      
-      /* Display the control registers */
-      KdbpPrint("CR0  0x%08x ", Cr0);
-      for (i = 0; i < 32; i++)
-      {
-         if (Cr0Bits[i] == NULL)
-            continue;
-         if ((Cr0 & (1 << i)) != 0)
-            KdbpPrint(Cr0Bits[i]);
-      }
-      KdbpPrint("\nCR2  0x%08x\n", Cr2);
-      KdbpPrint("CR3  0x%08x  Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000),
-                (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" );
-      KdbpPrint("CR4  0x%08x ", Cr4);
-      for (i = 0; i < 32; i++)
-      {
-         if (Cr4Bits[i] == NULL)
-            continue;
-         if ((Cr4 & (1 << i)) != 0)
-            KdbpPrint(Cr4Bits[i]);
-      }
-      
-      /* Display the descriptor table regs */
-      KdbpPrint("\nGDTR  Base 0x%08x  Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
-      KdbpPrint("LDTR  Base 0x%08x  Size 0x%04x\n", Ldtr.Base, Ldtr.Limit);
-      KdbpPrint("IDTR  Base 0x%08x  Size 0x%04x\n", Idtr.Base, Idtr.Limit);
-   }
-   else if (Argv[0][0] == 's') /* sregs */
-   {
-      KdbpPrint("CS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
-                Tf->Cs & 0xffff, (Tf->Cs & 0xffff) >> 3,
-                (Tf->Cs & (1 << 2)) ? 'L' : 'G', Tf->Cs & 3);
-      KdbpPrint("DS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
-                Tf->Ds, Tf->Ds >> 3, (Tf->Ds & (1 << 2)) ? 'L' : 'G', Tf->Ds & 3);
-      KdbpPrint("ES  0x%04x  Index 0x%04x  %cDT RPL%d\n",
-                Tf->Es, Tf->Es >> 3, (Tf->Es & (1 << 2)) ? 'L' : 'G', Tf->Es & 3);
-      KdbpPrint("FS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
-                Tf->Fs, Tf->Fs >> 3, (Tf->Fs & (1 << 2)) ? 'L' : 'G', Tf->Fs & 3);
-      KdbpPrint("GS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
-                Tf->Gs, Tf->Gs >> 3, (Tf->Gs & (1 << 2)) ? 'L' : 'G', Tf->Gs & 3);
-      KdbpPrint("SS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
-                Tf->Ss, Tf->Ss >> 3, (Tf->Ss & (1 << 2)) ? 'L' : 'G', Tf->Ss & 3);
-   }
-   else /* dregs */
-   {
-      ASSERT(Argv[0][0] == 'd');
-      KdbpPrint("DR0  0x%08x\n"
-                "DR1  0x%08x\n"
-                "DR2  0x%08x\n"
-                "DR3  0x%08x\n"
-                "DR6  0x%08x\n"
-                "DR7  0x%08x\n",
-                Tf->Dr0, Tf->Dr1, Tf->Dr2, Tf->Dr3,
-                Tf->Dr6, Tf->Dr7);
-   }
-   return TRUE;
-}
-
-/*!\brief Displays a backtrace.
- */
-STATIC BOOLEAN
-KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[])
-{
-   ULONG Count;
-   ULONG ul;
-   ULONGLONG Result = 0;
-   ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp;
-   ULONG_PTR Address;
-
-   if (Argc >= 2)
-   {
-      /* Check for [L count] part */
-      ul = 0;
-      if (strcmp(Argv[Argc-2], "L") == 0)
-      {
-         ul = strtoul(Argv[Argc-1], NULL, 0);
-         if (ul > 0)
-         {
-            Count = ul;
-            Argc -= 2;
-         }
-      }
-      else if (Argv[Argc-1][0] == 'L')
-      {
-         ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
-         if (ul > 0)
-         {
-            Count = ul;
-            Argc--;
-         }
-      }
-
-      /* Put the remaining arguments back together */
-      Argc--;
-      for (ul = 1; ul < Argc; ul++)
-      {
-         Argv[ul][strlen(Argv[ul])] = ' ';
-      }
-      Argc++;
-   }
-
-   /* Check if frame addr or thread id is given. */
-   if (Argc > 1)
-   {
-      if (Argv[1][0] == '*')
-      {
-         Argv[1]++;
-         /* Evaluate the expression */
-         if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
-            return TRUE;
-         if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
-            KdbpPrint("Warning: Address %I64x is beeing truncated\n");
-         Frame = (ULONG_PTR)Result;
-      }
-      else
-      {
-
-         KdbpPrint("Thread backtrace not supported yet!\n");
-         return TRUE;
-      }
-   }
-
-   KdbpPrint("Frames:\n");
-   while (Frame != 0)
-   {
-      if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof (ULONG_PTR))))
-      {
-         KdbpPrint("Couldn't access memory at 0x%x!\n", Frame + sizeof(ULONG_PTR));
-         break;
-      }
-      if (!KdbSymPrintAddress((PVOID)Address))
-         KdbpPrint("<%08x>\n", Address);
-      else
-         KdbpPrint("\n");
-      if (!NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof (ULONG_PTR))))
-      {
-         KdbpPrint("Couldn't access memory at 0x%x!\n", Frame);
-         break;
-      }
-   }
-   
-   return TRUE;
-}
-
-/*!\brief Continues execution of the system/leaves KDB.
- */
-STATIC BOOLEAN
-KdbpCmdContinue(ULONG Argc, PCHAR Argv[])
-{
-   /* Exit the main loop */
-   return FALSE;
-}
-
-/*!\brief Continues execution of the system/leaves KDB.
- */
-STATIC BOOLEAN
-KdbpCmdStep(ULONG Argc, PCHAR Argv[])
-{
-   ULONG Count = 1;
-   
-   if (Argc > 1)
-   {
-      Count = strtoul(Argv[1], NULL, 0);
-      if (Count == 0)
-      {
-         KdbpPrint("%s: Integer argument required\n", Argv[0]);
-         return TRUE;
-      }
-   }
-   
-   if (Argv[0][0] == 'n')
-      KdbSingleStepOver = TRUE;
-   else
-      KdbSingleStepOver = FALSE;
-
-   /* Set the number of single steps and return to the interrupted code. */
-   KdbNumSingleSteps = Count;
-
-   return FALSE;
-}
-
-/*!\brief Lists breakpoints.
- */
-STATIC BOOLEAN
-KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[])
-{
-   LONG l;
-   ULONG_PTR Address = 0;
-   KDB_BREAKPOINT_TYPE Type = 0;
-   KDB_ACCESS_TYPE AccessType = 0;
-   UCHAR Size = 0;
-   UCHAR DebugReg = 0;
-   BOOLEAN Enabled = FALSE;
-   BOOLEAN Global = FALSE;
-   PEPROCESS Process = NULL;
-   PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
-   CHAR Buffer[20];
-
-   l = KdbpGetNextBreakPointNr(0);
-   if (l < 0)
-   {
-      KdbpPrint("No breakpoints.\n");
-      return TRUE;
-   }
-   
-   KdbpPrint("Breakpoints:\n");
-   do
-   {
-      if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
-                                 &Enabled, &Global, &Process, &ConditionExpr))
-      {
-         continue;
-      }
-
-      if (l == KdbLastBreakPointNr)
-      {
-         str1 = "\x1b[1m*";
-         str2 = "\x1b[0m";
-      }
-      else
-      {
-         str1 = " ";
-         str2 = "";
-      }
-
-      if (Global)
-         GlobalOrLocal = "  global";
-      else
-      {
-         GlobalOrLocal = Buffer;
-         sprintf(Buffer, "  PID 0x%08lx",
-                 (ULONG)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
-      }
-
-      if (Type == KdbBreakPointSoftware || Type == KdbBreakPointTemporary)
-      {
-         KdbpPrint(" %s%03d  BPX  0x%08x%s%s%s%s%s\n",
-                   str1, l, Address,
-                   Enabled ? "" : "  disabled",
-                   GlobalOrLocal,
-                   ConditionExpr ? "  IF " : "",
-                   ConditionExpr ? ConditionExpr : "",
-                   str2);
-      }
-      else if (Type == KdbBreakPointHardware)
-      {
-         if (!Enabled)
-         {
-            KdbpPrint(" %s%03d  BPM  0x%08x  %-5s %-5s  disabled%s%s%s%s\n", str1, l, Address,
-                      KDB_ACCESS_TYPE_TO_STRING(AccessType),
-                      Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
-                      GlobalOrLocal,
-                      ConditionExpr ? "  IF " : "",
-                      ConditionExpr ? ConditionExpr : "",
-                      str2);
-         }
-         else
-         {
-            KdbpPrint(" %s%03d  BPM  0x%08x  %-5s %-5s  DR%d%s%s%s%s\n", str1, l, Address,
-                      KDB_ACCESS_TYPE_TO_STRING(AccessType),
-                      Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
-                      DebugReg,
-                      GlobalOrLocal,
-                      ConditionExpr ? "  IF " : "",
-                      ConditionExpr ? ConditionExpr : "",
-                      str2);
-         }
-      }
-   }
-   while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
-
-   return TRUE;
-}
-
-/*!\brief Enables, disables or clears a breakpoint.
- */
-STATIC BOOLEAN
-KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[])
-{
-   PCHAR pend;
-   ULONG BreakPointNr;
-
-   if (Argc < 2)
-   {
-      KdbpPrint("%s: argument required\n", Argv[0]);
-      return TRUE;
-   }
-
-   pend = Argv[1];
-   BreakPointNr = strtoul(Argv[1], &pend, 0);
-   if (pend == Argv[1] || *pend != '\0')
-   {
-      KdbpPrint("%s: integer argument required\n", Argv[0]);
-      return TRUE;
-   }
-
-   if (Argv[0][1] == 'e') /* enable */
-   {
-      KdbpEnableBreakPoint(BreakPointNr, NULL);
-   }
-   else if (Argv [0][1] == 'd') /* disable */
-   {
-      KdbpDisableBreakPoint(BreakPointNr, NULL);
-   }
-   else /* clear */
-   {
-      ASSERT(Argv[0][1] == 'c');
-      KdbpDeleteBreakPoint(BreakPointNr, NULL);
-   }
-
-   return TRUE;
-}
-
-/*!\brief Sets a software or hardware (memory) breakpoint at the given address.
- */
-STATIC BOOLEAN
-KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[])
-{
-   ULONGLONG Result = 0;
-   ULONG_PTR Address;
-   KDB_BREAKPOINT_TYPE Type;
-   UCHAR Size = 0;
-   KDB_ACCESS_TYPE AccessType = 0;
-   INT AddressArgIndex, ConditionArgIndex, i;
-   BOOLEAN Global = TRUE;
-   
-   if (Argv[0][2] == 'x') /* software breakpoint */
-   {
-      if (Argc < 2)
-      {
-         KdbpPrint("bpx: Address argument required.\n");
-         return TRUE;
-      }
-
-      AddressArgIndex = 1;
-      Type = KdbBreakPointSoftware;
-   }
-   else /* memory breakpoint */
-   {
-      ASSERT(Argv[0][2] == 'm');
-      
-      if (Argc < 2)
-      {
-         KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
-         return TRUE;
-      }
-
-      if (_stricmp(Argv[1], "x") == 0)
-         AccessType = KdbAccessExec;
-      else if (_stricmp(Argv[1], "r") == 0)
-         AccessType = KdbAccessRead;
-      else if (_stricmp(Argv[1], "w") == 0)
-         AccessType = KdbAccessWrite;
-      else if (_stricmp(Argv[1], "rw") == 0)
-         AccessType = KdbAccessReadWrite;
-      else
-      {
-         KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
-         return TRUE;
-      }
-      
-      if (Argc < 3)
-      {
-         KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
-         return TRUE;
-      }
-      AddressArgIndex = 3;
-      if (_stricmp(Argv[2], "byte") == 0)
-         Size = 1;
-      else if (_stricmp(Argv[2], "word") == 0)
-         Size = 2;
-      else if (_stricmp(Argv[2], "dword") == 0)
-         Size = 4;
-      else if (AccessType == KdbAccessExec)
-      {
-         Size = 1;
-         AddressArgIndex--;
-      }
-      else
-      {
-         KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
-         return TRUE;
-      }
-      
-      if (Argc <= AddressArgIndex)
-      {
-         KdbpPrint("bpm: Address argument required.\n");
-         return TRUE;
-      }
-
-      Type = KdbBreakPointHardware;
-   }
-   
-   /* Put the arguments back together */
-   ConditionArgIndex = -1;
-   for (i = AddressArgIndex; i < (Argc-1); i++)
-   {
-      if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
-      {
-         ConditionArgIndex = i + 2;
-         if (ConditionArgIndex >= Argc)
-         {
-            KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
-            return TRUE;
-         }
-         for (i = ConditionArgIndex; i < (Argc-1); i++)
-            Argv[i][strlen(Argv[i])] = ' ';
-         break;
-      }
-      Argv[i][strlen(Argv[i])] = ' ';
-   }
-
-   /* Evaluate the address expression */
-   if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
-                               sizeof("kdb:> ")-1 + (Argv[AddressArgIndex]-Argv[0]),
-                               &Result))
-   {
-      return TRUE;
-   }
-   if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
-      KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
-   Address = (ULONG_PTR)Result;
-
-   KdbpInsertBreakPoint(Address, Type, Size, AccessType,
-                        (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
-                        Global, NULL);
-   
-   return TRUE;
-}
-
-/*!\brief Lists threads or switches to another thread context.
- */
-STATIC BOOLEAN
-KdbpCmdThread(ULONG Argc, PCHAR Argv[])
-{
-   PLIST_ENTRY Entry;
-   PETHREAD Thread = NULL;
-   PEPROCESS Process = NULL;
-   PULONG Esp;
-   PULONG Ebp;
-   ULONG Eip;
-   ULONG ul = 0;
-   PCHAR State, pend, str1, str2;
-   STATIC CONST PCHAR ThreadStateToString[THREAD_STATE_MAX] =
-                                          { "Initialized", "Ready", "Running",
-                                            "Suspended", "Frozen", "Terminated1",
-                                            "Terminated2", "Blocked" };
-   ASSERT(KdbCurrentProcess != NULL);
-
-   if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
-   {
-      Process = KdbCurrentProcess;
-      
-      if (Argc >= 3)
-      {
-         ul = strtoul(Argv[2], &pend, 0);
-         if (Argv[2] == pend)
-         {
-            KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
-            return TRUE;
-         }
-         if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process)))
-         {
-            KdbpPrint("thread: Invalid process id!\n");
-            return TRUE;
-         }
-      }
-      
-      Entry = Process->ThreadListHead.Flink;
-      if (Entry == &Process->ThreadListHead)
-      {
-         if (Argc >= 3)
-            KdbpPrint("No threads in process 0x%08x!\n", ul);
-         else
-            KdbpPrint("No threads in current process!\n");
-         return TRUE;
-      }
-
-      KdbpPrint("  TID         State        Prior.  Affinity    EBP         EIP\n");
-      do
-      {
-         Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
-
-         if (Thread == KdbCurrentThread)
-         {
-            str1 = "\x1b[1m*";
-            str2 = "\x1b[0m";
-         }
-         else
-         {
-            str1 = " ";
-            str2 = "";
-         }
-
-         if (Thread->Tcb.TrapFrame != NULL)
-         {
-            Esp = (PULONG)Thread->Tcb.TrapFrame->Esp;
-            Ebp = (PULONG)Thread->Tcb.TrapFrame->Ebp;
-            Eip = Thread->Tcb.TrapFrame->Eip;
-         }
-         else
-         {
-            Esp = (PULONG)Thread->Tcb.KernelStack;
-            Ebp = (PULONG)Esp[4];
-            Eip = 0;
-            if (Ebp != NULL) /* FIXME: Should we attach to the process to read Ebp[1]? */
-               KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof (Eip));;
-         }
-         if (Thread->Tcb.State < THREAD_STATE_MAX)
-            State = ThreadStateToString[Thread->Tcb.State];
-         else
-            State = "Unknown";
-      
-         KdbpPrint(" %s0x%08x  %-11s  %3d     0x%08x  0x%08x  0x%08x%s\n",
-                   str1,
-                   Thread->Cid.UniqueThread,
-                   State,
-                   Thread->Tcb.Priority,
-                   Thread->Tcb.Affinity,
-                   Ebp,
-                   Eip,
-                   str2);
-      
-         Entry = Entry->Flink;
-      }
-      while (Entry != &Process->ThreadListHead);
-   }
-   else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
-   {
-      if (Argc < 3)
-      {
-         KdbpPrint("thread attach: thread id argument required!\n");
-         return TRUE;
-      }
-
-      ul = strtoul(Argv[2], &pend, 0);
-      if (Argv[2] == pend)
-      {
-         KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
-         return TRUE;
-      }
-      if (!KdbpAttachToThread((PVOID)ul))
-      {
-         return TRUE;
-      }
-      KdbpPrint("Attached to thread 0x%08x.\n", ul);
-   }
-   else
-   {
-      Thread = KdbCurrentThread;
-
-      if (Argc >= 2)
-      {
-         ul = strtoul(Argv[1], &pend, 0);
-         if (Argv[1] == pend)
-         {
-            KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
-            return TRUE;
-         }
-         if (!NT_SUCCESS(PsLookupThreadByThreadId((PVOID)ul, &Thread)))
[truncated at 1000 lines; 4259 more skipped]