2003-08-11 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / ntoskrnl / ke / bug.c
index 804fd64..df3bc16 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
- *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: bug.c,v 1.16 2001/03/14 00:21:22 dwelch Exp $
+/* $Id: bug.c,v 1.35 2003/08/11 18:50:12 chorns Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/bug.c
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
+#include <roskrnl.h>
+#include <ntos/bootvid.h>
+#include <internal/kd.h>
 #include <internal/ke.h>
 #include <internal/ps.h>
 
 #include <internal/debug.h>
 
+#include "../../hal/halx86/include/hal.h"
+
 /* GLOBALS ******************************************************************/
 
 static LIST_ENTRY BugcheckCallbackListHead = {NULL,NULL};
@@ -45,40 +49,126 @@ VOID PsDumpThreads(VOID);
 
 /* FUNCTIONS *****************************************************************/
 
-VOID 
+VOID
 KeInitializeBugCheck(VOID)
 {
-   InitializeListHead(&BugcheckCallbackListHead);
-   InBugCheck = 0;
+  InitializeListHead(&BugcheckCallbackListHead);
+  InBugCheck = 0;
 }
 
+/*
+ * @unimplemented
+ */
 BOOLEAN STDCALL
-KeDeregisterBugCheckCallback (PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
+KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
 {
   UNIMPLEMENTED;
+  return FALSE;
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN STDCALL
-KeRegisterBugCheckCallback (PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
-                           PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine,
-                           PVOID                               Buffer,
-                           ULONG                               Length,
-                           PUCHAR                              Component)
+KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
+                          PKBUGCHECK_CALLBACK_ROUTINE  CallbackRoutine,
+                          PVOID Buffer,
+                          ULONG Length,
+                          PUCHAR Component)
 {
-  InsertTailList(&BugcheckCallbackListHead,&CallbackRecord->Entry);
-  CallbackRecord->Length=Length;
-  CallbackRecord->Buffer=Buffer;
-  CallbackRecord->Component=Component;
-  CallbackRecord->CallbackRoutine=CallbackRoutine;
+  InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
+  CallbackRecord->Length = Length;
+  CallbackRecord->Buffer = Buffer;
+  CallbackRecord->Component = Component;
+  CallbackRecord->CallbackRoutine = CallbackRoutine;
   return(TRUE);
 }
 
 VOID STDCALL
-KeBugCheckEx (ULONG    BugCheckCode,
-             ULONG     BugCheckParameter1,
-             ULONG     BugCheckParameter2,
-             ULONG     BugCheckParameter3,
-             ULONG     BugCheckParameter4)
+KeBugCheckWithTf(ULONG BugCheckCode,        
+                ULONG BugCheckParameter1,
+                ULONG BugCheckParameter2,
+                ULONG BugCheckParameter3,
+                ULONG BugCheckParameter4,
+                PKTRAP_FRAME Tf)
+{
+  PRTL_MESSAGE_RESOURCE_ENTRY Message;
+  NTSTATUS Status;
+
+  /*
+   * The bug check may have happened while the bootscreen image was displayed.
+   * If this happened, switch back to text mode.
+   */
+  if (InbvIsBootDriverInstalled())
+    {
+      InbvEnableBootDriver(FALSE);
+    }
+
+  /* Make sure we're switching back to the blue screen and print messages on it */
+  HalReleaseDisplayOwnership();  
+  KdDebugState |= KD_DEBUG_SCREEN;
+
+  __asm__("cli\n\t");
+  DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
+          BugCheckCode,
+          BugCheckParameter1,
+          BugCheckParameter2,
+          BugCheckParameter3,
+          BugCheckParameter4);
+
+  Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
+                         11, //RT_MESSAGETABLE,
+                         0x09, //0x409,
+                         BugCheckCode,
+                         &Message);
+  if (NT_SUCCESS(Status))
+    {
+      if (Message->Flags == 0)
+       DbgPrint("  %s\n", Message->Text);
+      else
+       DbgPrint("  %S\n", (PWSTR)Message->Text);
+    }
+  else
+    {
+      DbgPrint("  No message text found!\n\n");
+    }
+
+  if (InBugCheck == 1)
+    {
+      DbgPrint("Recursive bug check halting now\n");
+      for (;;)
+       {
+         __asm__ ("hlt\n\t");
+       }
+    }
+  InBugCheck = 1;
+  KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
+  MmDumpToPagingFile(BugCheckCode, BugCheckParameter1, 
+                    BugCheckParameter2, BugCheckParameter3,
+                    BugCheckParameter4, Tf);
+
+  if (KdDebuggerEnabled)
+    {
+      __asm__("sti\n\t");
+      DbgBreakPoint();
+      __asm__("cli\n\t");
+    }
+
+  for (;;)
+    {
+      __asm__("hlt\n\t");
+    }
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+KeBugCheckEx(ULONG BugCheckCode,
+            ULONG BugCheckParameter1,
+            ULONG BugCheckParameter2,
+            ULONG BugCheckParameter3,
+            ULONG BugCheckParameter4)
 /*
  * FUNCTION: Brings the system down in a controlled manner when an 
  * inconsistency that might otherwise cause corruption has been detected
@@ -88,38 +178,90 @@ KeBugCheckEx (ULONG        BugCheckCode,
  * RETURNS: Doesn't
  */
 {
-  /* PJS: disable interrupts first, then do the rest */
-  __asm__("cli\n\t");      
-   DbgPrint("Bug detected (code %x param %x %x %x %x)\n",BugCheckCode,
-         BugCheckParameter1,BugCheckParameter2,BugCheckParameter3,
-         BugCheckParameter4);
-   if (PsGetCurrentProcess() != NULL)
-     {
-       DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
-       DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
-     }
-   if (PsGetCurrentThread() != NULL)
-     {
-       DbgPrint("Thrd: %x Tid: %x\n",
-                PsGetCurrentThread(),
-                PsGetCurrentThread()->Cid.UniqueThread);
-     }
-//   PsDumpThreads();
-   KeDumpStackFrames(&((&BugCheckCode)[-1]),64);
-   
-#if 1
-   for(;;)
-     {
-       /* PJS: use HLT instruction, rather than busy wait */
-       __asm__("hlt\n\t");     
-     }
-#else
-   for(;;);
-#endif   
+  PRTL_MESSAGE_RESOURCE_ENTRY Message;
+  NTSTATUS Status;
+
+  /*
+   * The bug check may have happened while the bootscreen image was displayed.
+   * If this happened, switch back to text mode.
+   */
+  if (InbvIsBootDriverInstalled())
+    {
+      InbvEnableBootDriver(FALSE);
+    }
+  
+  /* Make sure we're switching back to the blue screen and print messages on it */
+  HalReleaseDisplayOwnership();  
+  KdDebugState |= KD_DEBUG_SCREEN;
+
+  __asm__("cli\n\t");
+  DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
+          BugCheckCode,
+          BugCheckParameter1,
+          BugCheckParameter2,
+          BugCheckParameter3,
+          BugCheckParameter4);
+
+  Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
+                         11, //RT_MESSAGETABLE,
+                         0x09, //0x409,
+                         BugCheckCode,
+                         &Message);
+  if (NT_SUCCESS(Status))
+    {
+      if (Message->Flags == 0)
+       DbgPrint("  %s\n", Message->Text);
+      else
+       DbgPrint("  %S\n", (PWSTR)Message->Text);
+    }
+  else
+    {
+      DbgPrint("  No message text found!\n\n");
+    }
+
+  if (InBugCheck == 1)
+    {
+      DbgPrint("Recursive bug check halting now\n");
+      for (;;)
+       {
+         __asm__("hlt\n\t");
+       }
+    }
+  InBugCheck = 1;
+  if (PsGetCurrentProcess() != NULL)
+    {
+      DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
+      DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
+    }
+  if (PsGetCurrentThread() != NULL)
+    {
+      DbgPrint("Thrd: %x Tid: %x\n",
+              PsGetCurrentThread(),
+              PsGetCurrentThread()->Cid.UniqueThread);
+    }
+  KeDumpStackFrames((PULONG)__builtin_frame_address(0));
+  MmDumpToPagingFile(BugCheckCode, BugCheckParameter1, 
+                    BugCheckParameter2, BugCheckParameter3,
+                    BugCheckParameter4, NULL);
+
+  if (KdDebuggerEnabled)
+    {
+      __asm__("sti\n\t");
+      DbgBreakPoint();
+      __asm__("cli\n\t");
+    }
+
+  for (;;)
+    {
+      __asm__("hlt\n\t");
+    }
 }
 
+/*
+ * @implemented
+ */
 VOID STDCALL
-KeBugCheck (ULONG      BugCheckCode)
+KeBugCheck(ULONG BugCheckCode)
 /*
  * FUNCTION: Brings the system down in a controlled manner when an 
  * inconsistency that might otherwise cause corruption has been detected
@@ -128,35 +270,7 @@ KeBugCheck (ULONG  BugCheckCode)
  * RETURNS: Doesn't
  */
 {
-   __asm__("cli\n\t");
-   DbgPrint("Bug detected (code %x)\n", BugCheckCode);
-   if (InBugCheck == 1)
-     {
-       DbgPrint("Recursive bug check halting now\n");
-       for(;;);
-     }
-   InBugCheck = 1;
-   if (PsGetCurrentProcess() != NULL)
-     {
-       DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
-       DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
-     }
-   if (PsGetCurrentThread() != NULL)
-     {
-       DbgPrint("Thrd: %x Tid: %x\n",
-                PsGetCurrentThread(),
-                PsGetCurrentThread()->Cid.UniqueThread);
-     }
-//   PsDumpThreads();
-   KeDumpStackFrames(&((&BugCheckCode)[-1]), 80);
-#if 1
-   for(;;)
-     {
-       __asm__("hlt\n\t");
-     }
-#else
-   for(;;);
-#endif
+  KeBugCheckEx(BugCheckCode, 0, 0, 0, 0);
 }
 
 /* EOF */