#pragma alloc_text(INIT, KiInitializeBugCheck)
#endif
-/* ROS Internal. Please deprecate */
-NTHALAPI
-VOID
-NTAPI
-HalReleaseDisplayOwnership(
- VOID
-);
-
/* GLOBALS *******************************************************************/
-LIST_ENTRY BugcheckCallbackListHead;
-LIST_ENTRY BugcheckReasonCallbackListHead;
+LIST_ENTRY KeBugcheckCallbackListHead;
+LIST_ENTRY KeBugcheckReasonCallbackListHead;
+KSPIN_LOCK BugCheckCallbackLock;
ULONG KeBugCheckActive, KeBugCheckOwner;
LONG KeBugCheckOwnerRecursionCount;
PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages;
{
PLIST_ENTRY current_entry;
PLDR_DATA_TABLE_ENTRY current;
- extern LIST_ENTRY ModuleListHead;
+ extern LIST_ENTRY PsLoadedModuleList;
ULONG_PTR RelativeAddress;
ULONG i = 0;
do
{
- current_entry = ModuleListHead.Flink;
+ current_entry = PsLoadedModuleList.Flink;
- while (current_entry != &ModuleListHead)
+ while (current_entry != &PsLoadedModuleList)
{
current = CONTAINING_RECORD(current_entry,
LDR_DATA_TABLE_ENTRY,
LDR_RESOURCE_INFO ResourceInfo;
PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
NTSTATUS Status;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
- /* Initialize Callbadk Listhead and State */
- InitializeListHead(&BugcheckCallbackListHead);
- InitializeListHead(&BugcheckReasonCallbackListHead);
+ /* Get the kernel entry */
+ LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
/* Cache the Bugcheck Message Strings. Prepare the Lookup Data */
ResourceInfo.Type = 11;
ResourceInfo.Language = 9;
/* Do the lookup. */
- Status = LdrFindResource_U((PVOID)KERNEL_BASE,
+ Status = LdrFindResource_U(LdrEntry->DllBase,
&ResourceInfo,
RESOURCE_DATA_LEVEL,
&ResourceDataEntry);
if (NT_SUCCESS(Status))
{
/* Now actually get a pointer to it */
- Status = LdrAccessResource((PVOID)KERNEL_BASE,
+ Status = LdrAccessResource(LdrEntry->DllBase,
ResourceDataEntry,
(PVOID*)&BugCheckData,
NULL);
OutputString->Length = i + 1;
OutputString->MaximumLength = i + 1;
}
- else
+ else
{
/* Direct Output to Screen */
InbvDisplayString(BugCode);
ULONG_PTR Checksum;
/* First make sure that the list is Initialized... it might not be */
- ListHead = &BugcheckCallbackListHead;
+ ListHead = &KeBugcheckCallbackListHead;
if ((ListHead->Flink) && (ListHead->Blink))
{
/* Loop the list */
PVOID ImageBase, EipBase = NULL;
PLDR_DATA_TABLE_ENTRY Entry;
PLIST_ENTRY ListHead, NextEntry;
- extern LIST_ENTRY ModuleListHead;
+ extern LIST_ENTRY PsLoadedModuleList;
/* Assume no */
*InKernel = FALSE;
/* Set list pointers and make sure it's valid */
- ListHead = &ModuleListHead;
+ ListHead = &PsLoadedModuleList;
NextEntry = ListHead->Flink;
if (NextEntry)
{
{
CHAR AnsiName[75];
- /* FIXMEs: Use inbv to clear, fill and write to screen. */
+ /* Check if bootvid is installed */
+ if (InbvIsBootDriverInstalled())
+ {
+ /* Acquire ownership and reset the display */
+ InbvAcquireDisplayOwnership();
+ InbvResetDisplay();
+
+ /* Display blue screen */
+ InbvSolidColorFill(0, 0, 639, 479, 4);
+ InbvSetTextColor(15);
+ InbvInstallDisplayStringFilter(NULL);
+ InbvEnableDisplayString(TRUE);
+ InbvSetScrollRegion(0, 0, 639, 479);
+ }
/* Check if this is a hard error */
if (IsHardError)
/* Display caption and message */
if (HardErrCaption) InbvDisplayString(HardErrCaption);
if (HardErrMessage) InbvDisplayString(HardErrMessage);
- return;
}
/* Begin the display */
CONTEXT Context;
ULONG MessageId;
CHAR AnsiName[128];
- BOOLEAN IsSystem, IsHardError = FALSE;
+ BOOLEAN IsSystem, IsHardError = FALSE, Reboot = FALSE;
PCHAR HardErrCaption = NULL, HardErrMessage = NULL;
PVOID Eip = NULL, Memory;
PVOID DriverBase;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PULONG_PTR HardErrorParameters;
KIRQL OldIrql;
+#ifdef CONFIG_SMP
+ LONG i = 0;
+#endif
/* Set active bugcheck */
KeBugCheckActive = TRUE;
/* Save the IRQL and set hardware trigger */
Prcb->DebuggerSavedIRQL = KeGetCurrentIrql();
- InterlockedIncrement(&KiHardwareTrigger);
+ InterlockedIncrement((PLONG)&KiHardwareTrigger);
/* Capture the CPU Context */
RtlCaptureContext(&Prcb->ProcessorState.ContextFrame);
+ KiSaveProcessorControlState(&Prcb->ProcessorState);
Context = Prcb->ProcessorState.ContextFrame;
- /* FIXME: Call the Watchdog if it's regsitered */
+ /* FIXME: Call the Watchdog if it's registered */
/* Check which bugcode this is */
switch (BugCheckCode)
case FAT_FILE_SYSTEM:
case NO_MORE_SYSTEM_PTES:
case INACCESSIBLE_BOOT_DEVICE:
- case KMODE_EXCEPTION_NOT_HANDLED:
/* Keep the same code */
MessageId = BugCheckCode;
/* Check if this is a kernel-mode exception */
case KERNEL_MODE_EXCEPTION_NOT_HANDLED:
+ //case SYSTEM_THREAD_EXCEPTION_NOT_HANDLED:
+ case KMODE_EXCEPTION_NOT_HANDLED:
/* Use the generic text message */
MessageId = KMODE_EXCEPTION_NOT_HANDLED;
+ break;
/* File-system errors */
case NTFS_FILE_SYSTEM:
/* Use the generic message for FAT */
MessageId = FAT_FILE_SYSTEM;
+ break;
/* Check if this is a coruption of the Mm's Pool */
case DRIVER_CORRUPTED_MMPOOL:
/* Use generic corruption message */
MessageId = DRIVER_CORRUPTED_EXPOOL;
+ break;
/* Check if this is a signature check failure */
case STATUS_SYSTEM_IMAGE_BAD_SIGNATURE:
/* Use the generic corruption message */
MessageId = BUGCODE_PSS_MESSAGE_SIGNATURE;
+ break;
/* All other codes */
default:
/* Use the default bugcheck message */
MessageId = BUGCODE_PSS_MESSAGE;
+ break;
}
/* Save bugcheck data */
{
/* Get EIP */
Eip = (PVOID)TrapFrame->Eip;
+ KiBugCheckData[3] = (ULONG)Eip;
/* Find out if was in the kernel or drivers */
- DriverBase = KiPcToFileHeader(Eip, &LdrEntry, FALSE, &IsSystem);
+ DriverBase = KiPcToFileHeader(Eip,
+ &LdrEntry,
+ FALSE,
+ &IsSystem);
}
/*
* and update the bugcheck code appropriately.
*/
- /* Check if we had a driver base */
- if (DriverBase)
+ /* Check if we didn't have a driver base */
+ if (!DriverBase)
{
/* Find the driver that unloaded at this address */
KiBugCheckDriver = NULL; // FIXME: ROS can't locate
/* Check if the driver consumed too many PTEs */
case DRIVER_USED_EXCESSIVE_PTES:
- /* Driver base is in parameter 1 */
- DriverBase = (PVOID)BugCheckParameter1;
+ /* Loader entry is in parameter 1 */
+ LdrEntry = (PVOID)BugCheckParameter1;
KiBugCheckDriver = &LdrEntry->BaseDllName;
break;
}
}
- /* FIXME: Check if we need to save the context for KD */
+ /* Check if we need to save the context for KD */
/* Check if a debugger is connected */
if ((BugCheckCode != MANUALLY_INITIATED_CRASH) && (KdDebuggerEnabled))
}
}
- /* Switching back to the blue screen so we print messages on it */
- HalReleaseDisplayOwnership();
-
/* Raise IRQL to HIGH_LEVEL */
- Ke386DisableInterrupts();
+ _disable();
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
- /* Unlock the Kernel Adress Space if we own it */
+ /* ROS HACK: Unlock the Kernel Address Space if we own it */
if (KernelAddressSpaceLock.Owner == KeGetCurrentThread())
{
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
/* Avoid recursion */
- if (!InterlockedDecrement(&KeBugCheckCount))
+ if (!InterlockedDecrement((PLONG)&KeBugCheckCount))
{
+#ifdef CONFIG_SMP
/* Set CPU that is bug checking now */
KeBugCheckOwner = Prcb->Number;
-#ifdef CONFIG_SMP
/* Freeze the other CPUs */
- for (i = 0; i < KeNumberProcessors; i++)
+ for (i = 0; i < KeNumberProcessors; i++)
{
if (i != (LONG)KeGetCurrentProcessorNumber())
{
HardErrMessage,
AnsiName);
- /* FIXME: Enable debugger if it was pending */
-
- /* Print the last line */
- InbvDisplayString("\r\n");
+ /* Check if the debugger is disabled but we can enable it */
+ //if (!(KdDebuggerEnabled) && !(KdPitchDebugger))
+ {
+ /* Enable it */
+ //KdEnableDebuggerWithLock(FALSE);
+ }
+ //else
+ {
+ /* Otherwise, print the last line */
+ InbvDisplayString("\r\n");
+ }
/* Save the context */
Prcb->ProcessorState.ContextFrame = Context;
KiBugCheckData[3],
TrapFrame);
}
-
- /* Increase recursioun count */
- KeBugCheckOwnerRecursionCount++;
- if (KeBugCheckOwnerRecursionCount == 2)
- {
- /* Break in the debugger */
- KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND);
- }
- else if (KeBugCheckOwnerRecursionCount > 2)
+ else
{
- /* Halt the CPU */
- for (;;) Ke386HaltProcessor();
+ /* Increase recursion count */
+ KeBugCheckOwnerRecursionCount++;
+ if (KeBugCheckOwnerRecursionCount == 2)
+ {
+ /* Break in the debugger */
+ KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND);
+ }
+ else if (KeBugCheckOwnerRecursionCount > 2)
+ {
+ /* Halt the CPU */
+ for (;;) Ke386HaltProcessor();
+ }
}
/* Call the Callbacks */
/* FIXME: Call Watchdog if enabled */
+ /* Check if we have to reboot */
+ if (Reboot)
+ {
+ /* Unload symbols */
+ DbgUnLoadImageSymbols(NULL, NtCurrentProcess(), 0);
+ HalReturnToFirmware(HalRebootRoutine);
+ }
+
/* Attempt to break in the debugger (otherwise halt CPU) */
KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND);
}
CallbackRecord->Component = Component;
CallbackRecord->CallbackRoutine = CallbackRoutine;
CallbackRecord->State = BufferInserted;
- InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
+ InsertTailList(&KeBugcheckCallbackListHead, &CallbackRecord->Entry);
Status = TRUE;
}
CallbackRecord->CallbackRoutine = CallbackRoutine;
CallbackRecord->State = BufferInserted;
CallbackRecord->Reason = Reason;
- InsertTailList(&BugcheckReasonCallbackListHead,
+ InsertTailList(&KeBugcheckReasonCallbackListHead,
&CallbackRecord->Entry);
Status = TRUE;
}