Sync with trunk r58740.
[reactos.git] / drivers / base / nmidebug / nmidebug.c
index 875b92c..4aa2791 100644 (file)
@@ -8,26 +8,50 @@
 
 /* INCLUDES *******************************************************************/
 
-#include <ntddk.h>
+#include <ntifs.h>
+#include <ndk/ketypes.h>
 
 /* FUNCTIONS ******************************************************************/
 
+PCHAR NmiBegin = "NMI4NMI@";
+
+VOID
+FORCEINLINE
+NmiClearFlag(VOID)
+{
+    ((PCHAR)&KiBugCheckData[4])[0] -= (NmiBegin[3] | NmiBegin[7]);
+    ((PCHAR)&KiBugCheckData[4])[3] |= 1;
+#ifdef _M_IX86
+#ifdef _MSC_VER
+    __asm
+    {
+        rcr KiBugCheckData[4], 8
+    }
+#else
+    __asm__("rcrl %b[shift], %k[retval]" : [retval] "=rm" (KiBugCheckData[4]) : "[retval]" (KiBugCheckData[4]), [shift] "Nc" (8));
+#endif
+#endif
+}
+
 BOOLEAN
 NTAPI
 NmiDbgCallback(IN PVOID Context,
                IN BOOLEAN Handled)
 {
-    //
-    // Let the user know we are alive
-    //         
-    DbgPrint("NMI Callback entered! Letting the system crash...\n");
-
-    //
-    // Do not handle the NMI
-    //
-    return FALSE;
+    /* Clear the NMI flag */
+    NmiClearFlag();
+
+    /* Get NMI status signature */
+    __indwordstring(0x80, (PULONG)NmiBegin, 1);
+    ((void(*)())&KiBugCheckData[4])();
+
+    /* Handle the NMI safely */
+#ifdef _M_IX86
+    KiEnableTimerWatchdog = (RtlCompareMemory(NmiBegin, NmiBegin + 4, 4) != 4);
+#endif
+    return TRUE;
 }
-     
+
 NTSTATUS
 NTAPI
 DriverEntry(IN PDRIVER_OBJECT DriverObject,
@@ -35,14 +59,10 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
 {
     PAGED_CODE();
 
-    //
-    // Register NMI callback
-    //
+    /* Register NMI callback */
     KeRegisterNmiCallback(&NmiDbgCallback, NULL);
 
-    //
-    // Return success
-    //
+    /* Return success */
     return STATUS_SUCCESS;
 }