[NTOS:KDBG] Fix the display type of GDT TRAPGATE32.
[reactos.git] / ntoskrnl / kdbg / kdb_cli.c
index c40c282..b4d750d 100644 (file)
@@ -18,7 +18,7 @@
  */
 /*
  * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/dbg/kdb_cli.c
+ * FILE:            ntoskrnl/kdbg/kdb_cli.c
  * PURPOSE:         Kernel debugger command line interface
  * PROGRAMMER:      Gregor Anich (blight@blight.eu.org)
  *                  HervĂ© Poussineau
@@ -85,12 +85,19 @@ static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
 static BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
 
 static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]);
+static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[]);
 static BOOLEAN KdbpCmdFilter(ULONG Argc, PCHAR Argv[]);
 static BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]);
 static BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]);
 static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[]);
 
 BOOLEAN ExpKdbgExtPool(ULONG Argc, PCHAR Argv[]);
+BOOLEAN ExpKdbgExtPoolUsed(ULONG Argc, PCHAR Argv[]);
+BOOLEAN ExpKdbgExtPoolFind(ULONG Argc, PCHAR Argv[]);
+BOOLEAN ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[]);
+BOOLEAN ExpKdbgExtDefWrites(ULONG Argc, PCHAR Argv[]);
+BOOLEAN ExpKdbgExtIrpFind(ULONG Argc, PCHAR Argv[]);
+BOOLEAN ExpKdbgExtHandle(ULONG Argc, PCHAR Argv[]);
 
 #ifdef __ROS_DWARF__
 static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
@@ -176,12 +183,19 @@ static const struct
     /* Others */
     { NULL, NULL, "Others", NULL },
     { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck },
+    { "reboot", "reboot", "Reboots the system.", KdbpCmdReboot},
     { "filter", "filter [error|warning|trace|info|level]+|-[componentname|default]", "Enable/disable debug channels", KdbpCmdFilter },
     { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet },
     { "dmesg", "dmesg", "Display debug messages on screen, with navigation on pages.", KdbpCmdDmesg },
     { "kmsg", "kmsg", "Kernel dmesg. Alias for dmesg.", KdbpCmdDmesg },
     { "help", "help", "Display help screen.", KdbpCmdHelp },
-    { "!pool", "!pool [Address [Flags]]", "Display information about pool allocations.", ExpKdbgExtPool }
+    { "!pool", "!pool [Address [Flags]]", "Display information about pool allocations.", ExpKdbgExtPool },
+    { "!poolused", "!poolused [Flags [Tag]]", "Display pool usage.", ExpKdbgExtPoolUsed },
+    { "!poolfind", "!poolfind Tag [Pool]", "Search for pool tag allocations.", ExpKdbgExtPoolFind },
+    { "!filecache", "!filecache", "Display cache usage.", ExpKdbgExtFileCache },
+    { "!defwrites", "!defwrites", "Display cache write values.", ExpKdbgExtDefWrites },
+    { "!irpfind", "!irpfind [Pool [startaddress [criteria data]]]", "Lists IRPs potentially matching criteria", ExpKdbgExtIrpFind },
+    { "!handle", "!handle [Handle]", "Displays info about handles", ExpKdbgExtHandle },
 };
 
 /* FUNCTIONS *****************************************************************/
@@ -208,7 +222,7 @@ KdbpGetComponentId(
     }
     ComponentTable[] =
     {
-        { "DEFAULT", DPFLTR_DEFAULT_ID },
+        { "DEFAULT", MAXULONG },
         { "SYSTEM", DPFLTR_SYSTEM_ID },
         { "SMSS", DPFLTR_SMSS_ID },
         { "SETUP", DPFLTR_SETUP_ID },
@@ -2010,19 +2024,19 @@ KdbpCmdGdtLdtIdt(
             {
                 switch (Type)
                 {
-                    case 1: SegType = "TSS16(Avl)"; break;
-                    case 2: SegType = "LDT"; break;
-                    case 3: SegType = "TSS16(Busy)"; break;
-                    case 4: SegType = "CALLGATE16"; break;
-                    case 5: SegType = "TASKGATE"; break;
-                    case 6: SegType = "INTGATE16"; break;
-                    case 7: SegType = "TRAPGATE16"; break;
-                    case 9: SegType = "TSS32(Avl)"; break;
-                    case 11: SegType = "TSS32(Busy)"; break;
-                    case 12: SegType = "CALLGATE32"; break;
-                    case 14: SegType = "INTGATE32"; break;
-                    case 15: SegType = "INTGATE32"; break;
-                    default: SegType = "UNKNOWN"; break;
+                    case  1: SegType = "TSS16(Avl)";    break;
+                    case  2: SegType = "LDT";           break;
+                    case  3: SegType = "TSS16(Busy)";   break;
+                    case  4: SegType = "CALLGATE16";    break;
+                    case  5: SegType = "TASKGATE";      break;
+                    case  6: SegType = "INTGATE16";     break;
+                    case  7: SegType = "TRAPGATE16";    break;
+                    case  9: SegType = "TSS32(Avl)";    break;
+                    case 11: SegType = "TSS32(Busy)";   break;
+                    case 12: SegType = "CALLGATE32";    break;
+                    case 14: SegType = "INTGATE32";     break;
+                    case 15: SegType = "TRAPGATE32";    break;
+                    default: SegType = "UNKNOWN";       break;
                 }
 
                 if (!(Type >= 1 && Type <= 3) &&
@@ -2047,7 +2061,7 @@ KdbpCmdGdtLdtIdt(
                     SegType = "CODE16";
             }
 
-            if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
+            if ((SegDesc[1] & (1 << 15)) == 0) /* Not present */
             {
                 KdbpPrint("  %03d  0x%04x  %-11s  [NP]        [NP]        %02d   NP\n",
                           i / 8, i | Dpl | ul, SegType, Dpl);
@@ -2110,7 +2124,7 @@ KdbpCmdPcr(
               "  Tib.FiberData/Version:     0x%08x\n"
               "  Tib.ArbitraryUserPointer:  0x%08x\n"
               "  Tib.Self:                  0x%08x\n"
-              "  Self:                      0x%08x\n"
+              "  SelfPcr:                   0x%08x\n"
               "  PCRCB:                     0x%08x\n"
               "  Irql:                      0x%02x\n"
               "  IRR:                       0x%08x\n"
@@ -2131,7 +2145,7 @@ KdbpCmdPcr(
               "  InterruptMode:             0x%08x\n",
               Pcr->NtTib.ExceptionList, Pcr->NtTib.StackBase, Pcr->NtTib.StackLimit,
               Pcr->NtTib.SubSystemTib, Pcr->NtTib.FiberData, Pcr->NtTib.ArbitraryUserPointer,
-              Pcr->NtTib.Self, Pcr->Self, Pcr->Prcb, Pcr->Irql, Pcr->IRR, Pcr->IrrActive,
+              Pcr->NtTib.Self, Pcr->SelfPcr, Pcr->Prcb, Pcr->Irql, Pcr->IRR, Pcr->IrrActive,
               Pcr->IDR, Pcr->KdVersionBlock, Pcr->IDT, Pcr->GDT, Pcr->TSS,
               Pcr->MajorVersion, Pcr->MinorVersion, Pcr->SetMember, Pcr->StallScaleFactor,
               Pcr->Number, Pcr->SecondLevelCacheAssociativity,
@@ -2176,6 +2190,17 @@ KdbpCmdBugCheck(
     return FALSE;
 }
 
+static BOOLEAN
+KdbpCmdReboot(
+    ULONG Argc,
+    PCHAR Argv[])
+{
+    /* Reboot immediately (we do not return) */
+    HalReturnToFirmware(HalRebootRoutine);
+    return FALSE;
+}
+
+
 VOID
 KdbpPager(
     IN PCHAR Buffer,
@@ -2637,15 +2662,16 @@ KdbpPrint(
         {
             while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
             {
+                size_t len = strlen(p2);
                 if (p2[1] == '[')
                 {
                     j = 2;
                     while (!isalpha(p2[j++]));
-                    strcpy(p2, p2 + j);
+                    memmove(p2, p2 + j, len + 1 - j);
                 }
                 else
                 {
-                    strcpy(p2, p2 + 1);
+                    memmove(p2, p2 + 1, len);
                 }
             }
         }
@@ -2982,15 +3008,16 @@ KdbpPager(
         {
             while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
             {
+                size_t len = strlen(p2);
                 if (p2[1] == '[')
                 {
                     j = 2;
                     while (!isalpha(p2[j++]));
-                    strcpy(p2, p2 + j);
+                    memmove(p2, p2 + j, len + 1 - j);
                 }
                 else
                 {
-                    strcpy(p2, p2 + 1);
+                    memmove(p2, p2 + 1, len);
                 }
             }
         }
@@ -3512,7 +3539,7 @@ KdbpCliModuleLoaded(
  * call this function if KdbInitFileBuffer is not NULL.
  */
 VOID
-KdbpCliInterpretInitFile()
+KdbpCliInterpretInitFile(VOID)
 {
     PCHAR p1, p2;
     INT i;
@@ -3558,10 +3585,10 @@ KdbpCliInterpretInitFile()
 
 /*!\brief Called when KDB is initialized
  *
- * Reads the KDBinit file from the SystemRoot\system32\drivers\etc directory and executes it.
+ * Reads the KDBinit file from the SystemRoot\System32\drivers\etc directory and executes it.
  */
 VOID
-KdbpCliInit()
+KdbpCliInit(VOID)
 {
     NTSTATUS Status;
     OBJECT_ATTRIBUTES ObjectAttributes;
@@ -3574,7 +3601,7 @@ KdbpCliInit()
     ULONG OldEflags;
 
     /* Initialize the object attributes */
-    RtlInitUnicodeString(&FileName, L"\\SystemRoot\\system32\\drivers\\etc\\KDBinit");
+    RtlInitUnicodeString(&FileName, L"\\SystemRoot\\System32\\drivers\\etc\\KDBinit");
     InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
 
     /* Open the file */
@@ -3584,7 +3611,7 @@ KdbpCliInit()
                         FILE_NO_INTERMEDIATE_BUFFERING);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT("Could not open \\SystemRoot\\system32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
+        DPRINT("Could not open \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
         return;
     }
 
@@ -3594,7 +3621,7 @@ KdbpCliInit()
     if (!NT_SUCCESS(Status))
     {
         ZwClose(hFile);
-        DPRINT("Could not query size of \\SystemRoot\\system32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
+        DPRINT("Could not query size of \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
         return;
     }
     FileSize = FileStdInfo.EndOfFile.u.LowPart;
@@ -3609,7 +3636,7 @@ KdbpCliInit()
     }
 
     /* Load file into memory */
-    Status = ZwReadFile(hFile, 0, 0, 0, &Iosb, FileBuffer, FileSize, 0, 0);
+    Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb, FileBuffer, FileSize, NULL, NULL);
     ZwClose(hFile);
 
     if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
@@ -3647,17 +3674,67 @@ KdpSerialDebugPrint(
 STRING KdpPromptString = RTL_CONSTANT_STRING("kdb:> ");
 extern KSPIN_LOCK KdpSerialSpinLock;
 
-ULONG
+USHORT
 NTAPI
-KdpPrompt(IN LPSTR InString,
-          IN USHORT InStringLength,
-          OUT LPSTR OutString,
-          IN USHORT OutStringLength)
+KdpPrompt(
+    _In_reads_bytes_(InStringLength) PCHAR UnsafeInString,
+    _In_ USHORT InStringLength,
+    _Out_writes_bytes_(OutStringLength) PCHAR UnsafeOutString,
+    _In_ USHORT OutStringLength,
+    _In_ KPROCESSOR_MODE PreviousMode,
+    _In_ PKTRAP_FRAME TrapFrame,
+    _In_ PKEXCEPTION_FRAME ExceptionFrame)
 {
     USHORT i;
     CHAR Response;
     ULONG DummyScanCode;
     KIRQL OldIrql;
+    PCHAR InString;
+    PCHAR OutString;
+    CHAR InStringBuffer[512];
+    CHAR OutStringBuffer[512];
+
+    /* Normalize the lengths */
+    InStringLength = min(InStringLength,
+                         sizeof(InStringBuffer));
+    OutStringLength = min(OutStringLength,
+                          sizeof(OutStringBuffer));
+
+    /* Check if we need to verify the string */
+    if (PreviousMode != KernelMode)
+    {
+        /* Handle user-mode buffers safely */
+        _SEH2_TRY
+        {
+            /* Probe the prompt */
+            ProbeForRead(UnsafeInString,
+                         InStringLength,
+                         1);
+
+            /* Capture prompt */
+            InString = InStringBuffer;
+            RtlCopyMemory(InString,
+                          UnsafeInString,
+                          InStringLength);
+
+            /* Probe and make room for response */
+            ProbeForWrite(UnsafeOutString,
+                          OutStringLength,
+                          1);
+            OutString = OutStringBuffer;
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Bad string pointer, bail out */
+            _SEH2_YIELD(return 0);
+        }
+        _SEH2_END;
+    }
+    else
+    {
+        InString = UnsafeInString;
+        OutString = UnsafeOutString;
+    }
 
     /* Acquire the printing spinlock without waiting at raised IRQL */
     while (TRUE)
@@ -3745,19 +3822,7 @@ KdpPrompt(IN LPSTR InString,
              * DbgPrompt does not null terminate, but it does
              */
             *(PCHAR)(OutString + i) = 0;
-
-            /* Print a new line */
-            KdPortPutByteEx(&SerialPortInfo, '\r');
-            KdPortPutByteEx(&SerialPortInfo, '\n');
-
-            /* Release spinlock */
-            KiReleaseSpinLock(&KdpSerialSpinLock);
-
-            /* Lower IRQL back */
-            KeLowerIrql(OldIrql);
-
-            /* Return the length  */
-            return OutStringLength + 1;
+            break;
         }
 
         /* Write it back and print it to the log */
@@ -3778,6 +3843,24 @@ KdpPrompt(IN LPSTR InString,
     /* Lower IRQL back */
     KeLowerIrql(OldIrql);
 
+    /* Copy back response if required */
+    if (PreviousMode != KernelMode)
+    {
+        _SEH2_TRY
+        {
+            /* Safely copy back response to user mode */
+            RtlCopyMemory(UnsafeOutString,
+                          OutString,
+                          i);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* String became invalid after we exited, fail */
+            _SEH2_YIELD(return 0);
+        }
+        _SEH2_END;
+    }
+
     /* Return the length  */
-    return OutStringLength;
+    return i;
 }