Merge 36852, 37322, 37333, 37334, 43428, 43451, 44259, 46404 from amd64 branch.
[reactos.git] / reactos / ntoskrnl / ke / bug.c
index f9cc43e..0484093 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;
@@ -227,13 +229,13 @@ KeRosCaptureUserStackBackTrace(IN ULONG FramesToSkip,
     return (USHORT)i;
 }
 
+
 VOID
 FASTCALL
 KeRosDumpStackFrameArray(IN PULONG_PTR Frames,
                          IN ULONG FrameCount)
 {
-    ULONG i;
-    ULONG_PTR Addr;
+    ULONG i, Addr;
     BOOLEAN InSystem;
     PVOID p;
 
@@ -319,7 +321,6 @@ KeRosDumpStackFrames(IN PULONG_PTR Frame OPTIONAL,
     }
 }
 
-
 VOID
 NTAPI
 KeRosDumpTriageForBugZillaReport(VOID)
@@ -393,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;
@@ -457,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 */
@@ -740,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],
@@ -831,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 */
@@ -1209,6 +1210,32 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
     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 **********************************************************/
 
 /*
@@ -1281,17 +1308,6 @@ KeDeregisterBugCheckReasonCallback(
     return Status;
 }
 
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-KeDeregisterNmiCallback(PVOID Handle)
-{
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
-}
-
 /*
  * @implemented
  */
@@ -1363,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((PVOID*)&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;
 }
 
 /*