[NTOS]: I am sorry, this is embarssing. Fix build again.
[reactos.git] / reactos / ntoskrnl / ke / bug.c
index c1d6e2d..642c9a2 100644 (file)
@@ -23,11 +23,13 @@ LIST_ENTRY KeBugcheckReasonCallbackListHead;
 KSPIN_LOCK BugCheckCallbackLock;
 ULONG KeBugCheckActive, KeBugCheckOwner;
 LONG KeBugCheckOwnerRecursionCount;
-PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages;
+PMESSAGE_RESOURCE_DATA KiBugCodeMessages;
 ULONG KeBugCheckCount = 1;
 ULONG KiHardwareTrigger;
 PUNICODE_STRING KiBugCheckDriver;
 ULONG_PTR KiBugCheckData[5];
+PKNMI_HANDLER_CALLBACK KiNmiCallbackListHead;
+KSPIN_LOCK KiNmiCallbackListLock;
 
 /* Bugzilla Reporting */
 UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion;
@@ -37,13 +39,13 @@ UNICODE_STRING KeRosVideoBiosDate, KeRosVideoBiosVersion;
 
 PVOID
 NTAPI
-KiPcToFileHeader(IN PVOID Eip,
+KiPcToFileHeader(IN PVOID Pc,
                  OUT PLDR_DATA_TABLE_ENTRY *LdrEntry,
                  IN BOOLEAN DriversOnly,
                  OUT PBOOLEAN InKernel)
 {
     ULONG i = 0;
-    PVOID ImageBase, EipBase = NULL;
+    PVOID ImageBase, PcBase = NULL;
     PLDR_DATA_TABLE_ENTRY Entry;
     PLIST_ENTRY ListHead, NextEntry;
 
@@ -82,12 +84,12 @@ KiPcToFileHeader(IN PVOID Eip,
             ImageBase = Entry->DllBase;
 
             /* Check if this is the right one */
-            if (((ULONG_PTR)Eip >= (ULONG_PTR)Entry->DllBase) &&
-                ((ULONG_PTR)Eip < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
+            if (((ULONG_PTR)Pc >= (ULONG_PTR)Entry->DllBase) &&
+                ((ULONG_PTR)Pc < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
             {
                 /* Return this entry */
                 *LdrEntry = Entry;
-                EipBase = ImageBase;
+                PcBase = ImageBase;
 
                 /* Check if this was a kernel or HAL entry */
                 if (i <= 2) *InKernel = TRUE;
@@ -97,7 +99,7 @@ KiPcToFileHeader(IN PVOID Eip,
     }
 
     /* Return the base address */
-    return EipBase;
+    return PcBase;
 }
 
 BOOLEAN
@@ -138,10 +140,10 @@ KiRosPrintAddress(PVOID address)
 
 PVOID
 NTAPI
-KiRosPcToUserFileHeader(IN PVOID Eip,
+KiRosPcToUserFileHeader(IN PVOID Pc,
                         OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
 {
-    PVOID ImageBase, EipBase = NULL;
+    PVOID ImageBase, PcBase = NULL;
     PLDR_DATA_TABLE_ENTRY Entry;
     PLIST_ENTRY ListHead, NextEntry;
 
@@ -170,19 +172,19 @@ KiRosPcToUserFileHeader(IN PVOID Eip,
             ImageBase = Entry->DllBase;
 
             /* Check if this is the right one */
-            if (((ULONG_PTR)Eip >= (ULONG_PTR)Entry->DllBase) &&
-                ((ULONG_PTR)Eip < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
+            if (((ULONG_PTR)Pc >= (ULONG_PTR)Entry->DllBase) &&
+                ((ULONG_PTR)Pc < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
             {
                 /* Return this entry */
                 *LdrEntry = Entry;
-                EipBase = ImageBase;
+                PcBase = ImageBase;
                 break;
             }
         }
     }
 
     /* Return the base address */
-    return EipBase;
+    return PcBase;
 }
 
 USHORT
@@ -227,7 +229,7 @@ KeRosCaptureUserStackBackTrace(IN ULONG FramesToSkip,
     return (USHORT)i;
 }
 
-#ifndef _M_AMD64
+
 VOID
 FASTCALL
 KeRosDumpStackFrameArray(IN PULONG Frames,
@@ -236,7 +238,9 @@ KeRosDumpStackFrameArray(IN PULONG Frames,
     ULONG i, Addr;
     BOOLEAN InSystem;
     PVOID p;
-    PLDR_DATA_TABLE_ENTRY LdrEntry;
+
+    /* GCC complaints that it may be used uninitialized */
+    PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
 
     /* Loop them */
     for (i = 0; i < FrameCount; i++)
@@ -316,7 +320,6 @@ KeRosDumpStackFrames(IN PULONG Frame OPTIONAL,
         }
     }
 }
-#endif
 
 VOID
 NTAPI
@@ -391,7 +394,7 @@ INIT_FUNCTION
 NTAPI
 KiInitializeBugCheck(VOID)
 {
-    PRTL_MESSAGE_RESOURCE_DATA BugCheckData;
+    PMESSAGE_RESOURCE_DATA BugCheckData;
     LDR_RESOURCE_INFO ResourceInfo;
     PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
     NTSTATUS Status;
@@ -455,12 +458,12 @@ KeGetBugMessageText(IN ULONG BugCheckCode,
             for (i = 0; i < IdOffset; i++)
             {
                 /* Advance in the Entries */
-                MessageEntry += ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->
+                MessageEntry += ((PMESSAGE_RESOURCE_ENTRY)MessageEntry)->
                                 Length;
             }
 
             /* Get the final Code */
-            BugCode = ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Text;
+            BugCode = (PCHAR)((PMESSAGE_RESOURCE_ENTRY)MessageEntry)->Text;
             i = strlen(BugCode);
 
             /* Handle newlines */
@@ -549,9 +552,25 @@ VOID
 NTAPI
 KiBugCheckDebugBreak(IN ULONG StatusCode)
 {
-    /* If KDBG isn't connected, freeze the CPU, otherwise, break */
-    if (KdDebuggerNotPresent) for (;;) KeArchHaltProcessor();
-    DbgBreakPointWithStatus(StatusCode);
+    /*
+     * Wrap this in SEH so we don't crash if
+     * there is no debugger or if it disconnected
+     */
+DoBreak:
+    _SEH2_TRY
+    {
+        /* Breakpoint */
+        DbgBreakPointWithStatus(StatusCode);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* No debugger, halt the CPU */
+        HalHaltSystem();
+    }
+    _SEH2_END;
+
+    /* Break again if this wasn't first try */
+    if (StatusCode != DBG_STATUS_BUGCHECK_FIRST) goto DoBreak;
 }
 
 PCHAR
@@ -605,13 +624,9 @@ KiDumpParameterImages(IN PCHAR Message,
                                      &InSystem);
         if (!ImageBase)
         {
-            /* Driver wasn't found, check for unloaded driver */
-            DriverName = NULL; // FIXME: ROS can't
-            if (!DriverName) continue;
-
-            /* Convert the driver name */
-            ImageBase = (PVOID)Parameters[i];
-            ConversionRoutine(DriverName, AnsiName, sizeof(AnsiName));
+            /* FIXME: Add code to check for unloaded drivers */
+            DPRINT1("Potentially unloaded driver!\n");
+            continue;
         }
         else
         {
@@ -726,8 +741,8 @@ KiDisplayBlueScreen(IN ULONG MessageId,
 
     /* Show the technical Data */
     sprintf(AnsiName,
-            "\r\n\r\n*** STOP: 0x%p (0x%p,0x%p,0x%p,0x%p)\r\n\r\n",
-            (PVOID)KiBugCheckData[0],
+            "\r\n\r\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\r\n\r\n",
+            KiBugCheckData[0],
             (PVOID)KiBugCheckData[1],
             (PVOID)KiBugCheckData[2],
             (PVOID)KiBugCheckData[3],
@@ -765,7 +780,7 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
     CHAR AnsiName[128];
     BOOLEAN IsSystem, IsHardError = FALSE, Reboot = FALSE;
     PCHAR HardErrCaption = NULL, HardErrMessage = NULL;
-    PVOID Eip = NULL, Memory;
+    PVOID Pc = NULL, Memory;
     PVOID DriverBase;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     PULONG_PTR HardErrorParameters;
@@ -817,7 +832,7 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
 
         /* Check if this is a kernel-mode exception */
         case KERNEL_MODE_EXCEPTION_NOT_HANDLED:
-        //case SYSTEM_THREAD_EXCEPTION_NOT_HANDLED:
+        case SYSTEM_THREAD_EXCEPTION_NOT_HANDLED:
         case KMODE_EXCEPTION_NOT_HANDLED:
 
             /* Use the generic text message */
@@ -875,16 +890,12 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
                 if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3;
             }
 
-            /* Check if we got one now and if we need to get EIP */
+            /* Check if we got one now and if we need to get the Program Counter */
             if ((TrapFrame) &&
                 (BugCheckCode != KERNEL_MODE_EXCEPTION_NOT_HANDLED))
             {
-#ifdef _M_IX86
-                /* Get EIP */
-                Eip = (PVOID)TrapFrame->Eip;
-#elif defined(_M_PPC)
-                Eip = (PVOID)TrapFrame->Dr0; /* srr0 */
-#endif
+                /* Get the Program Counter */
+                Pc = (PVOID)KeGetTrapFramePc(TrapFrame);
             }
             break;
 
@@ -898,11 +909,14 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
              * and provide a more detailed analysis. For now, we don't.
              */
 
-            /* Eip is in parameter 4 */
-            Eip = (PVOID)BugCheckParameter4;
+            /* Program Counter is in parameter 4 */
+            Pc = (PVOID)BugCheckParameter4;
 
             /* Get the driver base */
-            DriverBase = KiPcToFileHeader(Eip, &LdrEntry, FALSE, &IsSystem);
+            DriverBase = KiPcToFileHeader(Pc,
+                                          &LdrEntry,
+                                          FALSE,
+                                          &IsSystem);
             if (IsSystem)
             {
                 /*
@@ -942,8 +956,8 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
                 KiBugCheckData[0] = DRIVER_IRQL_NOT_LESS_OR_EQUAL;
             }
 
-            /* Clear EIP so we don't look it up later */
-            Eip = NULL;
+            /* Clear Pc so we don't look it up later */
+            Pc = NULL;
             break;
 
         /* Hard error */
@@ -979,17 +993,12 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
             /* Check if we have a frame now */
             if (TrapFrame)
             {
-#ifdef _M_IX86
-                /* Get EIP */
-                Eip = (PVOID)TrapFrame->Eip;
-                KiBugCheckData[3] = (ULONG)Eip;
-#elif defined(_M_PPC)
-                Eip = (PVOID)TrapFrame->Dr0; /* srr0 */
-                KiBugCheckData[3] = (ULONG)Eip;
-#endif
+                /* Get the Program Counter */
+                Pc = (PVOID)KeGetTrapFramePc(TrapFrame);
+                KiBugCheckData[3] = (ULONG_PTR)Pc;
 
                 /* Find out if was in the kernel or drivers */
-                DriverBase = KiPcToFileHeader(Eip,
+                DriverBase = KiPcToFileHeader(Pc,
                                               &LdrEntry,
                                               FALSE,
                                               &IsSystem);
@@ -1019,8 +1028,8 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
         /* Check if the driver forgot to unlock pages */
         case DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS:
 
-            /* EIP is in parameter 1 */
-            Eip = (PVOID)BugCheckParameter1;
+            /* Program Counter is in parameter 1 */
+            Pc = (PVOID)BugCheckParameter1;
             break;
 
         /* Check if the driver consumed too many PTEs */
@@ -1051,12 +1060,12 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
     }
     else
     {
-        /* Do we have an EIP? */
-        if (Eip)
+        /* Do we have a Program Counter? */
+        if (Pc)
         {
             /* Dump image name */
             KiDumpParameterImages(AnsiName,
-                                  (PULONG_PTR)&Eip,
+                                  (PULONG_PTR)&Pc,
                                   1,
                                   KeBugCheckUnicodeToAnsi);
         }
@@ -1064,7 +1073,7 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
 
     /* Check if we need to save the context for KD */
 #ifdef _WINKD_
-    if (!KdPitchDebugger) KdDebuggerDataBlock.SavedContext = (ULONG)&Context;
+    if (!KdPitchDebugger) KdDebuggerDataBlock.SavedContext = (ULONG_PTR)&Context;
 #endif
 
     /* Check if a debugger is connected */
@@ -1131,20 +1140,18 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
             if (i != (LONG)KeGetCurrentProcessorNumber())
             {
                 /* Send the IPI and give them one second to catch up */
-                KiIpiSendRequest(1 << i, IPI_FREEZE);
+                KiIpiSend(1 << i, IPI_FREEZE);
                 KeStallExecutionProcessor(1000000);
             }
         }
 #endif
 
         /* Display the BSOD */
-        KeLowerIrql(APC_LEVEL); // This is a nastier hack than any ever before
         KiDisplayBlueScreen(MessageId,
                             IsHardError,
                             HardErrCaption,
                             HardErrMessage,
                             AnsiName);
-        KeRaiseIrql(HIGH_LEVEL, &OldIrql);
 
         /* Check if the debugger is disabled but we can enable it */
         if (!(KdDebuggerEnabled) && !(KdPitchDebugger))
@@ -1165,13 +1172,7 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
 
         /* FIXME: Support Triage Dump */
 
-        /* Write the crash dump */
-        MmDumpToPagingFile(KiBugCheckData[4],
-                           KiBugCheckData[0],
-                           KiBugCheckData[1],
-                           KiBugCheckData[2],
-                           KiBugCheckData[3],
-                           TrapFrame);
+        /* FIXME: Write the crash dump */
     }
     else
     {
@@ -1184,8 +1185,8 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
         }
         else if (KeBugCheckOwnerRecursionCount > 2)
         {
-            /* Halt the CPU */
-            for (;;) KeArchHaltProcessor();
+            /* Halt execution */
+            while (TRUE);
         }
     }
 
@@ -1198,12 +1199,41 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
     if (Reboot)
     {
         /* Unload symbols */
-        DbgUnLoadImageSymbols(NULL, NtCurrentProcess(), 0);
+        DbgUnLoadImageSymbols(NULL, (PVOID)MAXULONG_PTR, 0);
         HalReturnToFirmware(HalRebootRoutine);
     }
 
     /* Attempt to break in the debugger (otherwise halt CPU) */
     KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND);
+
+    /* Shouldn't get here */
+    while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+KiHandleNmi(VOID)
+{
+    BOOLEAN Handled = FALSE;
+    PKNMI_HANDLER_CALLBACK NmiData;
+
+    //
+    // Parse the list of callbacks
+    //
+    NmiData = KiNmiCallbackListHead;
+    while (NmiData)
+    {
+        //
+        // Save if this callback has handled it -- all it takes is one
+        //
+        Handled |= NmiData->Callback(NmiData->Context, Handled);
+        NmiData = NmiData->Next;
+    }
+
+    //
+    // Has anyone handled this?
+    //
+    return Handled;
 }
 
 /* PUBLIC FUNCTIONS **********************************************************/
@@ -1278,17 +1308,6 @@ KeDeregisterBugCheckReasonCallback(
     return Status;
 }
 
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-KeDeregisterNmiCallback(PVOID Handle)
-{
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
-}
-
 /*
  * @implemented
  */
@@ -1360,15 +1379,58 @@ KeRegisterBugCheckReasonCallback(
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 PVOID
 NTAPI
 KeRegisterNmiCallback(IN PNMI_CALLBACK CallbackRoutine,
                       IN PVOID Context)
 {
+    KIRQL OldIrql;
+    PKNMI_HANDLER_CALLBACK NmiData, Next;
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+
+    //
+    // Allocate NMI callback data
+    //
+    NmiData = ExAllocatePoolWithTag(NonPagedPool,
+                                    sizeof(KNMI_HANDLER_CALLBACK),
+                                    'IMNK');
+    if (!NmiData) return NULL;
+
+    //
+    // Fill in the information
+    //
+    NmiData->Callback = CallbackRoutine;
+    NmiData->Context = Context;
+    NmiData->Handle = NmiData;
+
+    //
+    // Insert it into NMI callback list
+    //
+    KiAcquireNmiListLock(&OldIrql);
+    NmiData->Next = KiNmiCallbackListHead;
+    Next = InterlockedCompareExchangePointer(&KiNmiCallbackListHead,
+                                             NmiData,
+                                             NmiData->Next);
+    ASSERT(Next == NmiData->Next);
+    KiReleaseNmiListLock(OldIrql);
+
+    //
+    // Return the opaque "handle"
+    //
+    return NmiData->Handle;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+KeDeregisterNmiCallback(PVOID Handle)
+{      
     UNIMPLEMENTED;
-    return NULL;
+    return STATUS_UNSUCCESSFUL;
 }
 
 /*
@@ -1424,7 +1486,7 @@ KeEnterKernelDebugger(VOID)
         }
     }
 
-    /* Bugcheck */
+    /* Break in the debugger */
     KiBugCheckDebugBreak(DBG_STATUS_FATAL);
 }