[NTOSKRNL] Implement !poolfind command in KDBG
[reactos.git] / ntoskrnl / kdbg / kdb_cli.c
index 168dca0..ef97693 100644 (file)
@@ -92,6 +92,12 @@ 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 PspKdbgIrpFind(ULONG Argc, PCHAR Argv[]);
 
 #ifdef __ROS_DWARF__
 static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
@@ -183,7 +189,12 @@ static const struct
     { "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 [criteria data]", "Lists IRPs potentially matching criteria", PspKdbgIrpFind },
 };
 
 /* FUNCTIONS *****************************************************************/
@@ -2112,7 +2123,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"
@@ -2133,7 +2144,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,
@@ -3622,7 +3633,7 @@ KdbpCliInit(VOID)
     }
 
     /* 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)
@@ -3662,15 +3673,63 @@ extern KSPIN_LOCK KdpSerialSpinLock;
 
 ULONG
 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)
 {
     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)
@@ -3779,6 +3838,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 i;
 }