[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / kdbg / kdb_cli.c
index a517f96..a0d5135 100644 (file)
@@ -12,9 +12,9 @@
  *  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.
+ *  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.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 /*
  * PROJECT:         ReactOS kernel
@@ -220,8 +220,6 @@ KdbpGetComponentId(
         { "SERIAL", DPFLTR_SERIAL_ID },
         { "SERENUM", DPFLTR_SERENUM_ID },
         { "UHCD", DPFLTR_UHCD_ID },
-        { "BOOTOK", DPFLTR_BOOTOK_ID },
-        { "BOOTVRFY", DPFLTR_BOOTVRFY_ID },
         { "RPCPROXY", DPFLTR_RPCPROXY_ID },
         { "AUTOCHK", DPFLTR_AUTOCHK_ID },
         { "DCOMSS", DPFLTR_DCOMSS_ID },
@@ -272,7 +270,60 @@ KdbpGetComponentId(
         { "STORPORT", DPFLTR_STORPORT_ID },
         { "STORMINIPORT", DPFLTR_STORMINIPORT_ID },
         { "PRINTSPOOLER", DPFLTR_PRINTSPOOLER_ID },
-   };
+        { "VSSDYNDISK", DPFLTR_VSSDYNDISK_ID },
+        { "VERIFIER", DPFLTR_VERIFIER_ID },
+        { "VDS", DPFLTR_VDS_ID },
+        { "VDSBAS", DPFLTR_VDSBAS_ID },
+        { "VDSDYN", DPFLTR_VDSDYN_ID },
+        { "VDSDYNDR", DPFLTR_VDSDYNDR_ID },
+        { "VDSLDR", DPFLTR_VDSLDR_ID },
+        { "VDSUTIL", DPFLTR_VDSUTIL_ID },
+        { "DFRGIFC", DPFLTR_DFRGIFC_ID },
+        { "MM", DPFLTR_MM_ID },
+        { "DFSC", DPFLTR_DFSC_ID },
+        { "WOW64", DPFLTR_WOW64_ID },
+        { "ALPC", DPFLTR_ALPC_ID },
+        { "WDI", DPFLTR_WDI_ID },
+        { "PERFLIB", DPFLTR_PERFLIB_ID },
+        { "KTM", DPFLTR_KTM_ID },
+        { "IOSTRESS", DPFLTR_IOSTRESS_ID },
+        { "HEAP", DPFLTR_HEAP_ID },
+        { "WHEA", DPFLTR_WHEA_ID },
+        { "USERGDI", DPFLTR_USERGDI_ID },
+        { "MMCSS", DPFLTR_MMCSS_ID },
+        { "TPM", DPFLTR_TPM_ID },
+        { "THREADORDER", DPFLTR_THREADORDER_ID },
+        { "ENVIRON", DPFLTR_ENVIRON_ID },
+        { "EMS", DPFLTR_EMS_ID },
+        { "WDT", DPFLTR_WDT_ID },
+        { "FVEVOL", DPFLTR_FVEVOL_ID },
+        { "NDIS", DPFLTR_NDIS_ID },
+        { "NVCTRACE", DPFLTR_NVCTRACE_ID },
+        { "LUAFV", DPFLTR_LUAFV_ID },
+        { "APPCOMPAT", DPFLTR_APPCOMPAT_ID },
+        { "USBSTOR", DPFLTR_USBSTOR_ID },
+        { "SBP2PORT", DPFLTR_SBP2PORT_ID },
+        { "COVERAGE", DPFLTR_COVERAGE_ID },
+        { "CACHEMGR", DPFLTR_CACHEMGR_ID },
+        { "MOUNTMGR", DPFLTR_MOUNTMGR_ID },
+        { "CFR", DPFLTR_CFR_ID },
+        { "TXF", DPFLTR_TXF_ID },
+        { "KSECDD", DPFLTR_KSECDD_ID },
+        { "FLTREGRESS", DPFLTR_FLTREGRESS_ID },
+        { "MPIO", DPFLTR_MPIO_ID },
+        { "MSDSM", DPFLTR_MSDSM_ID },
+        { "UDFS", DPFLTR_UDFS_ID },
+        { "PSHED", DPFLTR_PSHED_ID },
+        { "STORVSP", DPFLTR_STORVSP_ID },
+        { "LSASS", DPFLTR_LSASS_ID },
+        { "SSPICLI", DPFLTR_SSPICLI_ID },
+        { "CNG", DPFLTR_CNG_ID },
+        { "EXFAT", DPFLTR_EXFAT_ID },
+        { "FILETRACE", DPFLTR_FILETRACE_ID },
+        { "XSAVE", DPFLTR_XSAVE_ID },
+        { "SE", DPFLTR_SE_ID },
+        { "DRIVEEXTENDER", DPFLTR_DRIVEEXTENDER_ID },
+    };
 
     for (i = 0; i < sizeof(ComponentTable) / sizeof(ComponentTable[0]); i++)
     {
@@ -527,7 +578,7 @@ KdbpCmdDisassembleX(
             return TRUE;
 
         if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
-            KdbpPrint("Warning: Address %I64x is beeing truncated\n");
+            KdbpPrint("Warning: Address %I64x is beeing truncated\n",Result);
 
         Address = (ULONG_PTR)Result;
     }
@@ -739,7 +790,6 @@ KdbpCmdBackTrace(
     ULONG Argc,
     PCHAR Argv[])
 {
-    ULONG Count;
     ULONG ul;
     ULONGLONG Result = 0;
     ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp;
@@ -755,7 +805,6 @@ KdbpCmdBackTrace(
             ul = strtoul(Argv[Argc-1], NULL, 0);
             if (ul > 0)
             {
-                Count = ul;
                 Argc -= 2;
             }
         }
@@ -764,7 +813,6 @@ KdbpCmdBackTrace(
             ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
             if (ul > 0)
             {
-                Count = ul;
                 Argc--;
             }
         }
@@ -790,7 +838,7 @@ KdbpCmdBackTrace(
                 return TRUE;
 
             if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
-                KdbpPrint("Warning: Address %I64x is beeing truncated\n");
+                KdbpPrint("Warning: Address %I64x is beeing truncated\n",Result);
 
             Frame = (ULONG_PTR)Result;
         }
@@ -823,11 +871,14 @@ KdbpCmdBackTrace(
             break;
         }
 
-        if (!KdbSymPrintAddress((PVOID)Address))
+        /* Print the location of the call instruction */
+        if (!KdbSymPrintAddress((PVOID)(Address - 5)))
             KdbpPrint("<%08x>\n", Address);
         else
             KdbpPrint("\n");
 
+        if (KdbOutputAborted) break;
+
         if (Address == 0)
             break;
 
@@ -1133,7 +1184,7 @@ KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[])
     }
 
     if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
-        KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
+        KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
 
     Address = (ULONG_PTR)Result;
 
@@ -1222,7 +1273,13 @@ KdbpCmdThread(
                 str2 = "";
             }
 
-            if (Thread->Tcb.TrapFrame)
+            if (!Thread->Tcb.InitialStack)
+            {
+                /* Thread has no kernel stack (probably terminated) */
+                Esp = Ebp = NULL;
+                Eip = 0;
+            }
+            else if (Thread->Tcb.TrapFrame)
             {
                 if (Thread->Tcb.TrapFrame->PreviousPreviousMode == KernelMode)
                     Esp = (PULONG)Thread->Tcb.TrapFrame->TempEsp;
@@ -1491,7 +1548,7 @@ KdbpCmdMod(
         }
 
         if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
-            KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
+            KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
 
         Address = (ULONG_PTR)Result;
 
@@ -1788,7 +1845,7 @@ KdbpCmdPcr(
               Pcr->NtTib.Self, Pcr->Self, 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->L2CacheAssociativity,
+              Pcr->Number, Pcr->SecondLevelCacheAssociativity,
               Pcr->VdmAlert, Pcr->SecondLevelCacheSize, Pcr->InterruptMode);
 
     return TRUE;
@@ -2652,6 +2709,7 @@ KdbpCliMainLoop(
 
         /* Call the command */
         Continue = KdbpDoCommand(Command);
+        KdbOutputAborted = FALSE;
     }
     while (Continue);
 }
@@ -2801,3 +2859,142 @@ KdbpCliInit()
 
     ExFreePool(FileBuffer);
 }
+
+VOID
+NTAPI
+KdpSerialDebugPrint(
+    LPSTR Message,
+    ULONG Length
+);
+
+STRING KdpPromptString = RTL_CONSTANT_STRING("kdb:> ");
+extern KSPIN_LOCK KdpSerialSpinLock;
+
+ULONG
+NTAPI
+KdpPrompt(IN LPSTR InString,
+          IN USHORT InStringLength,
+          OUT LPSTR OutString,
+          IN USHORT OutStringLength)
+{
+    USHORT i;
+    CHAR Response;
+    ULONG DummyScanCode;
+    KIRQL OldIrql;
+
+    /* Acquire the printing spinlock without waiting at raised IRQL */
+    while (TRUE)
+    {
+        /* Wait when the spinlock becomes available */
+        while (!KeTestSpinLock(&KdpSerialSpinLock));
+
+        /* Spinlock was free, raise IRQL */
+        KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+        /* Try to get the spinlock */
+        if (KeTryToAcquireSpinLockAtDpcLevel(&KdpSerialSpinLock))
+            break;
+
+        /* Someone else got the spinlock, lower IRQL back */
+        KeLowerIrql(OldIrql);
+    }
+
+    /* Loop the string to send */
+    for (i = 0; i < InStringLength; i++)
+    {
+        /* Print it to serial */
+        KdPortPutByteEx(&SerialPortInfo, *(PCHAR)(InString + i));
+    }
+
+    /* Print a new line for log neatness */
+    KdPortPutByteEx(&SerialPortInfo, '\r');
+    KdPortPutByteEx(&SerialPortInfo, '\n');
+
+    /* Print the kdb prompt */
+    for (i = 0; i < KdpPromptString.Length; i++)
+    {
+        /* Print it to serial */
+        KdPortPutByteEx(&SerialPortInfo,
+                        *(KdpPromptString.Buffer + i));
+    }
+
+    /* Loop the whole string */
+    for (i = 0; i < OutStringLength; i++)
+    {
+        /* Check if this is serial debugging mode */
+        if (KdbDebugState & KD_DEBUG_KDSERIAL)
+        {
+            /* Get the character from serial */
+            do
+            {
+                Response = KdbpTryGetCharSerial(MAXULONG);
+            } while (Response == -1);
+        }
+        else
+        {
+            /* Get the response from the keyboard */
+            do
+            {
+                Response = KdbpTryGetCharKeyboard(&DummyScanCode, MAXULONG);
+            } while (Response == -1);
+        }
+
+        /* Check for return */
+        if (Response == '\r')
+        {
+            /*
+             * We might need to discard the next '\n'.
+             * Wait a bit to make sure we receive it.
+             */
+            KeStallExecutionProcessor(100000);
+
+            /* Check the mode */
+            if (KdbDebugState & KD_DEBUG_KDSERIAL)
+            {
+                /* Read and discard the next character, if any */
+                KdbpTryGetCharSerial(5);
+            }
+            else
+            {
+                /* Read and discard the next character, if any */
+                KdbpTryGetCharKeyboard(&DummyScanCode, 5);
+            }
+
+            /* 
+             * Null terminate the output string -- documentation states that
+             * 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;
+        }
+
+        /* Write it back and print it to the log */
+        *(PCHAR)(OutString + i) = Response;
+        KdPortPutByteEx(&SerialPortInfo, Response);
+    }
+
+    /* Print a new line */
+    KdPortPutByteEx(&SerialPortInfo, '\r');
+    KdPortPutByteEx(&SerialPortInfo, '\n');
+
+    /* Release spinlock */
+    KiReleaseSpinLock(&KdpSerialSpinLock);
+
+    /* Lower IRQL back */
+    KeLowerIrql(OldIrql);
+
+    /* Return the length  */
+    return OutStringLength;
+}