*/
/*
* 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
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[]);
/* 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 *****************************************************************/
}
ComponentTable[] =
{
- { "DEFAULT", DPFLTR_DEFAULT_ID },
+ { "DEFAULT", MAXULONG },
{ "SYSTEM", DPFLTR_SYSTEM_ID },
{ "SMSS", DPFLTR_SMSS_ID },
{ "SETUP", DPFLTR_SETUP_ID },
{
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) &&
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);
" 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"
" 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,
return FALSE;
}
+static BOOLEAN
+KdbpCmdReboot(
+ ULONG Argc,
+ PCHAR Argv[])
+{
+ /* Reboot immediately (we do not return) */
+ HalReturnToFirmware(HalRebootRoutine);
+ return FALSE;
+}
+
+
VOID
KdbpPager(
IN PCHAR Buffer,
{
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);
}
}
}
{
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);
}
}
}
* call this function if KdbInitFileBuffer is not NULL.
*/
VOID
-KdbpCliInterpretInitFile()
+KdbpCliInterpretInitFile(VOID)
{
PCHAR p1, p2;
INT i;
/*!\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;
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 */
- Status = ZwOpenFile(&hFile, FILE_READ_DATA, &ObjectAttributes, &Iosb, 0,
+ Status = ZwOpenFile(&hFile, FILE_READ_DATA | SYNCHRONIZE,
+ &ObjectAttributes, &Iosb, 0,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
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;
}
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;
}
/* 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)
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)
* 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 */
/* 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;
}