Beispiel #1
1
VOID
NTAPI
PopShutdownHandler(VOID)
{
    PUCHAR Logo1, Logo2;
    ULONG i;

    /* Stop all interrupts */
    KeRaiseIrqlToDpcLevel();
    _disable();

    /* Do we have boot video */
    if (InbvIsBootDriverInstalled())
    {
        /* Yes we do, cleanup for shutdown screen */
        if (!InbvCheckDisplayOwnership()) InbvAcquireDisplayOwnership();
        InbvResetDisplay();
        InbvSolidColorFill(0, 0, 639, 479, 0);
        InbvEnableDisplayString(TRUE);
        InbvSetScrollRegion(0, 0, 639, 479);

        /* Display shutdown logo and message */
        Logo1 = InbvGetResourceAddress(IDB_SHUTDOWN_MSG);
        Logo2 = InbvGetResourceAddress(IDB_DEFAULT_LOGO);
        if ((Logo1) && (Logo2))
        {
            InbvBitBlt(Logo1, 220, 352);
            InbvBitBlt(Logo2, 222, 111);
        }
    }
    else
    {
        /* Do it in text-mode */
        for (i = 0; i < 25; i++) InbvDisplayString("\r\n");
        InbvDisplayString("                       ");
        InbvDisplayString("The system may be powered off now.\r\n");
    }

    /* Hang the system */
    for (;;) HalHaltSystem();
}
Beispiel #2
0
/*
 * @implemented
 */
VOID
NTAPI
HalDisplayString(IN PCH String)
{
    /* Call the Inbv driver */
    InbvDisplayString(String);
}
Beispiel #3
0
BOOLEAN
KeGetBugMessageText(
    IN ULONG MessageId,
    IN PANSI_STRING ReturnedString OPTIONAL
    )
{
    ULONG   i;
    PUCHAR  s;
    PMESSAGE_RESOURCE_BLOCK MessageBlock;
    PUCHAR Buffer;
    BOOLEAN Result;

    Result = FALSE;
    try {
        if (KiBugCodeMessages != NULL) {
            MmMakeKernelResourceSectionWritable ();
            MessageBlock = &KiBugCodeMessages->Blocks[0];
            for (i = KiBugCodeMessages->NumberOfBlocks; i; i -= 1) {
                if (MessageId >= MessageBlock->LowId &&
                    MessageId <= MessageBlock->HighId) {

                    s = (PCHAR)KiBugCodeMessages + MessageBlock->OffsetToEntries;
                    for (i = MessageId - MessageBlock->LowId; i; i -= 1) {
                        s += ((PMESSAGE_RESOURCE_ENTRY)s)->Length;
                    }

                    Buffer = ((PMESSAGE_RESOURCE_ENTRY)s)->Text;

                    i = strlen(Buffer) - 1;
                    while (i > 0 && (Buffer[i] == '\n'  ||
                                     Buffer[i] == '\r'  ||
                                     Buffer[i] == 0
                                    )
                          ) {
                        if (!ARGUMENT_PRESENT( ReturnedString )) {
                            Buffer[i] = 0;
                        }
                        i -= 1;
                    }

                    if (!ARGUMENT_PRESENT( ReturnedString )) {
                        InbvDisplayString(Buffer);
                        }
                    else {
                        ReturnedString->Buffer = Buffer;
                        ReturnedString->Length = (USHORT)(i+1);
                        ReturnedString->MaximumLength = (USHORT)(i+1);
                    }
                    Result = TRUE;
                    break;
                }
                MessageBlock += 1;
            }
        }
    } except ( EXCEPTION_EXECUTE_HANDLER ) {
        ;
    }

    return Result;
}
Beispiel #4
0
NTSTATUS
NTAPI
NtDisplayString(IN PUNICODE_STRING DisplayString)
{
    OEM_STRING OemString;

    /* Convert the string to OEM and display it */
    RtlUnicodeStringToOemString(&OemString, DisplayString, TRUE);
    InbvDisplayString(OemString.Buffer);
    RtlFreeOemString(&OemString);

    /* Return success */
    return STATUS_SUCCESS;
}
Beispiel #5
0
void hal_print(char *format, ...)
{
	char    dbg_msg[MAX_PATH];
	va_list args;

	va_start(args, format);

	_vsnprintf(
		dbg_msg, sizeof(dbg_msg), format, args);

	va_end(args);

	InbvDisplayString(dbg_msg);

	if (KeGetCurrentIrql() < DISPATCH_LEVEL) {
		dc_delay(500);
	}
}
Beispiel #6
0
VOID
KeBugCheckEx (
    IN ULONG BugCheckCode,
    IN ULONG_PTR BugCheckParameter1,
    IN ULONG_PTR BugCheckParameter2,
    IN ULONG_PTR BugCheckParameter3,
    IN ULONG_PTR BugCheckParameter4
    )

/*++

Routine Description:

    This function crashes the system in a controlled manner.

Arguments:

    BugCheckCode - Supplies the reason for the bug check.

    BugCheckParameter1-4 - Supplies additional bug check information

Return Value:

    None.

--*/

{
    UCHAR Buffer[100];
    ULONG_PTR BugCheckParameters[4];
    CONTEXT ContextSave;
    ULONG PssMessage;
    PCHAR HardErrorCaption;
    PCHAR HardErrorMessage;
    KIRQL OldIrql;
    PKTRAP_FRAME TrapInformation;
    PVOID ExecutionAddress;
    PVOID ImageBase;
    PVOID VirtualAddress;
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    UCHAR AnsiBuffer[32];
    PKTHREAD Thread;
    BOOLEAN InKernelOrHal;
    BOOLEAN DontCare;

#if !defined(NT_UP)

    ULONG TargetSet;

#endif
    BOOLEAN hardErrorCalled;

    //
    // Try to simulate a power failure for Cluster testing
    //

    if (BugCheckCode == POWER_FAILURE_SIMULATE) {
        KiScanBugCheckCallbackList();
        HalReturnToFirmware(HalRebootRoutine);
    }

    //
    // Capture the callers context as closely as possible into the debugger's
    // processor state area of the Prcb.
    //
    // N.B. There may be some prologue code that shuffles registers such that
    //      they get destroyed.
    //

#if defined(i386)
    KiSetHardwareTrigger();
#else
    KiHardwareTrigger = 1;
#endif

    RtlCaptureContext(&KeGetCurrentPrcb()->ProcessorState.ContextFrame);
    KiSaveProcessorControlState(&KeGetCurrentPrcb()->ProcessorState);

    //
    // This is necessary on machines where the virtual unwind that happens
    // during KeDumpMachineState() destroys the context record.
    //

    ContextSave = KeGetCurrentPrcb()->ProcessorState.ContextFrame;

    //
    // If we are called by hard error then we don't want to dump the
    // processor state on the machine.
    //
    // We know that we are called by hard error because the bug check
    // code will be FATAL_UNHANDLED_HARD_ERROR.  If this is so then the
    // error status passed to harderr is the first parameter, and a pointer
    // to the parameter array from hard error is passed as the second
    // argument.
    //
    // The third argument is the OemCaption to be printed.
    // The last argument is the OemMessage to be printed.
    //

    if (BugCheckCode == FATAL_UNHANDLED_HARD_ERROR) {

        PULONG_PTR parameterArray;

        hardErrorCalled = TRUE;

        HardErrorCaption = (PCHAR)BugCheckParameter3;
        HardErrorMessage = (PCHAR)BugCheckParameter4;
        parameterArray = (PULONG_PTR)BugCheckParameter2;
        BugCheckCode = (ULONG)BugCheckParameter1;
        BugCheckParameter1 = parameterArray[0];
        BugCheckParameter2 = parameterArray[1];
        BugCheckParameter3 = parameterArray[2];
        BugCheckParameter4 = parameterArray[3];

    } else {

        hardErrorCalled = FALSE;

        switch (BugCheckCode) {

            case IRQL_NOT_LESS_OR_EQUAL:

                ExecutionAddress = (PVOID)BugCheckParameter4;

                if (ExecutionAddress >= ExPoolCodeStart && ExecutionAddress < ExPoolCodeEnd) {
                    BugCheckCode = DRIVER_CORRUPTED_EXPOOL;
                }
                else if (ExecutionAddress >= MmPoolCodeStart && ExecutionAddress < MmPoolCodeEnd) {
                    BugCheckCode = DRIVER_CORRUPTED_MMPOOL;
                }
                else if (ExecutionAddress >= MmPteCodeStart && ExecutionAddress < MmPteCodeEnd) {
                    BugCheckCode = DRIVER_CORRUPTED_SYSPTES;
                }
                else {
                    ImageBase = KiPcToFileHeader (ExecutionAddress,
                                                  &DataTableEntry,
                                                  FALSE,
                                                  &InKernelOrHal);
                    if (InKernelOrHal == TRUE) {

                        //
                        // The kernel faulted at raised IRQL.  Quite often this
                        // is a driver that has unloaded without deleting its
                        // lookaside lists or other resources.  Or its resources
                        // are marked pagable and shouldn't be.  Detect both
                        // cases here and identify the offending driver
                        // whenever possible.
                        //

                        VirtualAddress = (PVOID)BugCheckParameter1;

                        ImageBase = KiPcToFileHeader (VirtualAddress,
                                                      &DataTableEntry,
                                                      TRUE,
                                                      &InKernelOrHal);

                        if (ImageBase != NULL) {
                            KiBugCheckDriver = &DataTableEntry->BaseDllName;
                            BugCheckCode = DRIVER_PORTION_MUST_BE_NONPAGED;
                        }
                        else {
                            KiBugCheckDriver = MmLocateUnloadedDriver (VirtualAddress);
                            if (KiBugCheckDriver != NULL) {
                                BugCheckCode = SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD;
                            }
                        }
                    }
                    else {
                        BugCheckCode = DRIVER_IRQL_NOT_LESS_OR_EQUAL;
                    }
                }
                break;

            case ATTEMPTED_WRITE_TO_READONLY_MEMORY:

                KiBugCheckDriver = NULL;
                TrapInformation = (PKTRAP_FRAME)BugCheckParameter3;

                //
                // Extract the execution address from the trap frame to
                // identify the component.
                //

                if (TrapInformation != NULL) {
                    ExecutionAddress = (PVOID)PROGRAM_COUNTER (TrapInformation);
                    ImageBase = KiPcToFileHeader (ExecutionAddress,
                                                  &DataTableEntry,
                                                  TRUE,
                                                  &InKernelOrHal);

                    if (ImageBase != NULL) {
                        KiBugCheckDriver = &DataTableEntry->BaseDllName;
                    }
                }

                break;

            case DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS:

                ExecutionAddress = (PVOID)BugCheckParameter1;

                ImageBase = KiPcToFileHeader (ExecutionAddress,
                                              &DataTableEntry,
                                              TRUE,
                                              &InKernelOrHal);

                if (ImageBase != NULL) {
                    KiBugCheckDriver = &DataTableEntry->BaseDllName;
                }
                else {
                    KiBugCheckDriver = MmLocateUnloadedDriver (ExecutionAddress);
                }

                BugCheckParameter4 = (ULONG_PTR)KiBugCheckDriver;

                break;

            case DRIVER_USED_EXCESSIVE_PTES:

                DataTableEntry = (PLDR_DATA_TABLE_ENTRY)BugCheckParameter1;
                KiBugCheckDriver = &DataTableEntry->BaseDllName;

                break;

            case PAGE_FAULT_IN_NONPAGED_AREA:

                ExecutionAddress = NULL;
                KiBugCheckDriver = NULL;

                VirtualAddress = (PVOID)BugCheckParameter1;

                TrapInformation = (PKTRAP_FRAME)BugCheckParameter3;

                //
                // Extract the execution address from the trap frame to
                // identify the component.
                //

                if (TrapInformation != NULL) {

                    ExecutionAddress = (PVOID)PROGRAM_COUNTER (TrapInformation);
                    BugCheckParameter3 = (ULONG_PTR)ExecutionAddress;

                    KiPcToFileHeader (ExecutionAddress,
                                      &DataTableEntry,
                                      FALSE,
                                      &InKernelOrHal);

                    ImageBase = KiPcToFileHeader (ExecutionAddress,
                                                  &DataTableEntry,
                                                  TRUE,
                                                  &DontCare);

                    if (ImageBase != NULL) {
                        KiBugCheckDriver = &DataTableEntry->BaseDllName;
                    }
                }
                else {

                    //
                    // No trap frame, so no execution address either.
                    //

                    BugCheckParameter3 = 0;
                }

                Thread = KeGetCurrentThread();

                if ((VirtualAddress >= MmSpecialPoolStart) &&
                    (VirtualAddress < MmSpecialPoolEnd)) {

                    //
                    // Update the bugcheck number so the administrator gets
                    // useful feedback that enabling special pool has enabled
                    // the system to locate the corruptor.
                    //

                    if (MmIsSpecialPoolAddressFree (VirtualAddress) == TRUE) {
                        if (InKernelOrHal == TRUE) {
                            BugCheckCode = PAGE_FAULT_IN_FREED_SPECIAL_POOL;
                        }
                        else {
                            BugCheckCode = DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL;
                        }
                    }
                    else {
                        if (InKernelOrHal == TRUE) {
                            BugCheckCode = PAGE_FAULT_BEYOND_END_OF_ALLOCATION;
                        }
                        else {
                            BugCheckCode = DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION;
                        }
                    }
                }
                else if ((ExecutionAddress == VirtualAddress) &&
                        (MmIsHydraAddress (VirtualAddress) == TRUE) &&
                        ((Thread->Teb == NULL) || (IS_SYSTEM_ADDRESS(Thread->Teb)))) {
                    //
                    // This is a driver reference to session space from a
                    // worker thread.  Since the system process has no session
                    // space this is illegal and the driver must be fixed.
                    //

                    BugCheckCode = TERMINAL_SERVER_DRIVER_MADE_INCORRECT_MEMORY_REFERENCE;
                }
                else {
                    KiBugCheckDriver = MmLocateUnloadedDriver (VirtualAddress);
                    if (KiBugCheckDriver != NULL) {
                        BugCheckCode = DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS;
                    }
                }

                break;

            default:
                break;
        }
    }

    if (KiBugCheckDriver != NULL) {
        KeBugCheckUnicodeToAnsi (KiBugCheckDriver,
                                 AnsiBuffer,
                                 sizeof (AnsiBuffer));
    }

    KiBugCheckData[0] = BugCheckCode;
    KiBugCheckData[1] = BugCheckParameter1;
    KiBugCheckData[2] = BugCheckParameter2;
    KiBugCheckData[3] = BugCheckParameter3;
    KiBugCheckData[4] = BugCheckParameter4;

    BugCheckParameters[0] = BugCheckParameter1;
    BugCheckParameters[1] = BugCheckParameter2;
    BugCheckParameters[2] = BugCheckParameter3;
    BugCheckParameters[3] = BugCheckParameter4;

    if (KdPitchDebugger == FALSE ) {
        KdDebuggerDataBlock.SavedContext = (ULONG_PTR) &ContextSave;
    }

    //
    // If the user manually crashed the machine, skips the DbgPrints and
    // go to the crashdump.
    // Trying to do DbgPrint causes us to reeeter the debugger which causes
    // some problems.
    //
    // Otherwise, if the debugger is enabled, print out the information and
    // stop.
    //

    if ((BugCheckCode != MANUALLY_INITIATED_CRASH) &&
        (KdDebuggerEnabled)) {

        DbgPrint("\n*** Fatal System Error: 0x%08lx\n"
                 "                       (0x%p,0x%p,0x%p,0x%p)\n\n",
                 BugCheckCode,
                 BugCheckParameter1,
                 BugCheckParameter2,
                 BugCheckParameter3,
                 BugCheckParameter4);

        //
        // If the debugger is not actually connected, or the user manually
        // crashed the machine by typing .crash in the debugger, proceed to
        // "blue screen" the system.
        //
        // The call to DbgPrint above will have set the state of
        // KdDebuggerNotPresent if the debugger has become disconnected
        // since the system was booted.
        //

        if (KdDebuggerNotPresent == FALSE) {

            if (KiBugCheckDriver != NULL) {
                DbgPrint("The %s driver may be at fault.\n", AnsiBuffer);
            }

            if (hardErrorCalled != FALSE) {
                if (HardErrorCaption) {
                    DbgPrint(HardErrorCaption);
                }
                if (HardErrorMessage) {
                    DbgPrint(HardErrorMessage);
                }
            }

            KiBugCheckDebugBreak (DBG_STATUS_BUGCHECK_FIRST);
        }
    }

    //
    // Freeze execution of the system by disabling interrupts and looping.
    //

    KiDisableInterrupts();
    KeRaiseIrql(HIGH_LEVEL, &OldIrql);

    //
    // Don't attempt to display message more than once.
    //

    if (InterlockedDecrement (&KeBugCheckCount) == 0) {

#if !defined(NT_UP)

        //
        // Attempt to get the other processors frozen now, but don't wait
        // for them to freeze (in case someone is stuck).
        //

        TargetSet = KeActiveProcessors & ~KeGetCurrentPrcb()->SetMember;
        if (TargetSet != 0) {
            KiIpiSend((KAFFINITY) TargetSet, IPI_FREEZE);

            //
            // Give the other processors one second to flush their data caches.
            //
            // N.B. This cannot be synchronized since the reason for the bug
            //      may be one of the other processors failed.
            //

            KeStallExecutionProcessor(1000 * 1000);
        }

#endif

        //
        // Enable InbvDisplayString calls to make it through to bootvid driver.
        //

        if (InbvIsBootDriverInstalled()) {

            InbvAcquireDisplayOwnership();

            InbvResetDisplay();
            InbvSolidColorFill(0,0,639,479,4); // make the screen blue
            InbvSetTextColor(15);
            InbvInstallDisplayStringFilter((INBV_DISPLAY_STRING_FILTER)NULL);
            InbvEnableDisplayString(TRUE);     // enable display string
            InbvSetScrollRegion(0,0,639,479);  // set to use entire screen
        }

        if (!hardErrorCalled) {
            sprintf((char *)Buffer,
                    "\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\n",
                    BugCheckCode,
                    BugCheckParameter1,
                    BugCheckParameter2,
                    BugCheckParameter3,
                    BugCheckParameter4
                    );
            InbvDisplayString((char *)Buffer);

            KeGetBugMessageText(BugCheckCode, NULL);
            InbvDisplayString("\n");

            if (KiBugCheckDriver != NULL) {

                //
                // Output the driver name.
                //

                KeGetBugMessageText(BUGCODE_ID_DRIVER, NULL);
                InbvDisplayString(AnsiBuffer);
                InbvDisplayString("\n");
            }

        } else {
            if (HardErrorCaption) {
                InbvDisplayString(HardErrorCaption);
            }
            if (HardErrorMessage) {
                InbvDisplayString(HardErrorMessage);
            }
        }

        //
        // Process the bug check callback list.
        //

        KiScanBugCheckCallbackList();

        //
        // If the debugger is not enabled, then dump the machine state and
        // attempt to enable the debugger.
        //

        if (!hardErrorCalled) {

            KiDumpParameterImages(
                (char *)Buffer,
                BugCheckParameters,
                4,
                KeBugCheckUnicodeToAnsi);

        }

        if (KdDebuggerEnabled == FALSE && KdPitchDebugger == FALSE ) {
            KdInitSystem(NULL, FALSE);

        } else {
            InbvDisplayString("\n");
        }

        //
        // Write a crash dump and optionally reboot if the system has been
        // so configured.
        //

        KeGetCurrentPrcb()->ProcessorState.ContextFrame = ContextSave;

        if (!IoWriteCrashDump(BugCheckCode,
                              BugCheckParameter1,
                              BugCheckParameter2,
                              BugCheckParameter3,
                              BugCheckParameter4,
                              &ContextSave
                              )) {
            //
            // If no crashdump take, display the PSS message.
            //

            switch ( BugCheckCode ) {

                case IRQL_NOT_LESS_OR_EQUAL:
                case DRIVER_IRQL_NOT_LESS_OR_EQUAL:
                case DRIVER_CORRUPTED_EXPOOL:
                case DRIVER_CORRUPTED_MMPOOL:
                case DRIVER_PORTION_MUST_BE_NONPAGED:
                case SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD:
                    PssMessage = BUGCODE_PSS_MESSAGE_A;
                    break;

                case KMODE_EXCEPTION_NOT_HANDLED:
                    PssMessage = BUGCODE_PSS_MESSAGE_1E;
                    break;

                case FAT_FILE_SYSTEM:
                case NTFS_FILE_SYSTEM:
                    PssMessage = BUGCODE_PSS_MESSAGE_23;
                    break;

                case DATA_BUS_ERROR:
                    PssMessage = BUGCODE_PSS_MESSAGE_2E;
                    break;

                case NO_MORE_SYSTEM_PTES:
                    PssMessage = BUGCODE_PSS_MESSAGE_3F;
                    break;

                case INACCESSIBLE_BOOT_DEVICE:
                    PssMessage = BUGCODE_PSS_MESSAGE_7B;
                    break;

                case UNEXPECTED_KERNEL_MODE_TRAP:
                    PssMessage = BUGCODE_PSS_MESSAGE_7F;
                    break;

                case STATUS_SYSTEM_IMAGE_BAD_SIGNATURE:
                    PssMessage = BUGCODE_PSS_MESSAGE_SIGNATURE;
                    break;

                case ACPI_BIOS_ERROR:
                    PssMessage = BUGCODE_PSS_MESSAGE_A5;
                    break;

                case ACPI_BIOS_FATAL_ERROR:
                    PssMessage = ACPI_BIOS_FATAL_ERROR;
                    break;

                default:
                    PssMessage = BUGCODE_PSS_MESSAGE;
                    break;
                }

            KeGetBugMessageText(PssMessage, NULL);
        }
    }

    //
    // Attempt to enter the kernel debugger.
    //

    KiBugCheckDebugBreak (DBG_STATUS_BUGCHECK_SECOND);
    return;
}
Beispiel #7
0
VOID
KiDumpParameterImages(
    IN PCHAR Buffer,
    IN PULONG_PTR BugCheckParameters,
    IN ULONG NumberOfParameters,
    IN PKE_BUGCHECK_UNICODE_TO_ANSI UnicodeToAnsiRoutine
    )

/*++

Routine Description:

    This function formats and displays the image names of boogcheck parameters
    that happen to match an address in an image.

Arguments:

    Buffer - Supplies a pointer to a buffer to be used to output machine
        state information.

    BugCheckParameters - Supplies additional bugcheck information.

    NumberOfParameters - sizeof BugCheckParameters array.

    UnicodeToAnsiRoutine - Supplies a pointer to a routine to convert Unicode
        strings to Ansi strings without touching paged translation tables.

Return Value:

    None.

--*/

{
    PUNICODE_STRING BugCheckDriver;
    PLIST_ENTRY ModuleListHead;
    PLIST_ENTRY Next;
    ULONG i;
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    PVOID ImageBase;
    UCHAR AnsiBuffer[ 32 ];
    ULONG DateStamp;
    PIMAGE_NT_HEADERS NtHeaders;
    BOOLEAN FirstPrint = TRUE;
    BOOLEAN InKernelOrHal;

    //
    // At this point the context record contains the machine state at the
    // call to bug check.
    //
    // Put out the system version and the title line with the PSR and FSR.
    //

    //
    // Check to see if any BugCheckParameters are valid code addresses.
    // If so, print them for the user.
    //

    for (i = 0; i < NumberOfParameters; i += 1) {
        ImageBase = KiPcToFileHeader((PVOID) BugCheckParameters[i],
                                     &DataTableEntry,
                                     FALSE,
                                     &InKernelOrHal);
        if (ImageBase == NULL) {
            BugCheckDriver = MmLocateUnloadedDriver ((PVOID)BugCheckParameters[i]);
            if (BugCheckDriver == NULL) {
                continue;
            }
            ImageBase = (PVOID)BugCheckParameters[i];
            DateStamp = 0;
            (*UnicodeToAnsiRoutine) (BugCheckDriver,
                                     AnsiBuffer,
                                     sizeof (AnsiBuffer));
        }
        else {
            if (MmDbgReadCheck(DataTableEntry->DllBase) != NULL) {

                NtHeaders = RtlImageNtHeader(DataTableEntry->DllBase);
                DateStamp = NtHeaders->FileHeader.TimeDateStamp;

            } else {
                DateStamp = 0;
            }
            (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName,
                                     AnsiBuffer,
                                     sizeof( AnsiBuffer ));
        }

        sprintf (Buffer, "%s** Address %p base at %p, DateStamp %08lx - %-12.12s\n",
            FirstPrint ? "\n*":"*",
                BugCheckParameters[i],
                ImageBase,
                DateStamp,
                AnsiBuffer);

        InbvDisplayString(Buffer);
        FirstPrint = FALSE;
    }

    return;
}
Beispiel #8
0
VOID
NTAPI
KeBugCheckWithTf(IN ULONG BugCheckCode,
                 IN ULONG_PTR BugCheckParameter1,
                 IN ULONG_PTR BugCheckParameter2,
                 IN ULONG_PTR BugCheckParameter3,
                 IN ULONG_PTR BugCheckParameter4,
                 IN PKTRAP_FRAME TrapFrame)
{
    PKPRCB Prcb = KeGetCurrentPrcb();
    CONTEXT Context;
    ULONG MessageId;
    CHAR AnsiName[128];
    BOOLEAN IsSystem, IsHardError = FALSE, Reboot = FALSE;
    PCHAR HardErrCaption = NULL, HardErrMessage = NULL;
    PVOID Pc = 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;
    KiBugCheckDriver = NULL;

    /* Check if this is power failure simulation */
    if (BugCheckCode == POWER_FAILURE_SIMULATE)
    {
        /* Call the Callbacks and reboot */
        KiDoBugCheckCallbacks();
        HalReturnToFirmware(HalRebootRoutine);
    }

    /* Save the IRQL and set hardware trigger */
    Prcb->DebuggerSavedIRQL = KeGetCurrentIrql();
    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 registered */

    /* Check which bugcode this is */
    switch (BugCheckCode)
    {
        /* These bug checks already have detailed messages, keep them */
        case UNEXPECTED_KERNEL_MODE_TRAP:
        case DRIVER_CORRUPTED_EXPOOL:
        case ACPI_BIOS_ERROR:
        case ACPI_BIOS_FATAL_ERROR:
        case THREAD_STUCK_IN_DEVICE_DRIVER:
        case DATA_BUS_ERROR:
        case FAT_FILE_SYSTEM:
        case NO_MORE_SYSTEM_PTES:
        case INACCESSIBLE_BOOT_DEVICE:

            /* Keep the same code */
            MessageId = BugCheckCode;
            break;

        /* 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 */
    KiBugCheckData[0] = BugCheckCode;
    KiBugCheckData[1] = BugCheckParameter1;
    KiBugCheckData[2] = BugCheckParameter2;
    KiBugCheckData[3] = BugCheckParameter3;
    KiBugCheckData[4] = BugCheckParameter4;

    /* Now check what bugcheck this is */
    switch (BugCheckCode)
    {
        /* Invalid access to R/O memory or Unhandled KM Exception */
        case KERNEL_MODE_EXCEPTION_NOT_HANDLED:
        case ATTEMPTED_WRITE_TO_READONLY_MEMORY:
        case ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY:

            /* Check if we have a trap frame */
            if (!TrapFrame)
            {
                /* Use parameter 3 as a trap frame, if it exists */
                if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3;
            }

            /* Check if we got one now and if we need to get the Program Counter */
            if ((TrapFrame) &&
                (BugCheckCode != KERNEL_MODE_EXCEPTION_NOT_HANDLED))
            {
                /* Get the Program Counter */
                Pc = (PVOID)KeGetTrapFramePc(TrapFrame);
            }
            break;

        /* Wrong IRQL */
        case IRQL_NOT_LESS_OR_EQUAL:

            /*
             * The NT kernel has 3 special sections:
             * MISYSPTE, POOLMI and POOLCODE. The bug check code can
             * determine in which of these sections this bugcode happened
             * and provide a more detailed analysis. For now, we don't.
             */

            /* Program Counter is in parameter 4 */
            Pc = (PVOID)BugCheckParameter4;

            /* Get the driver base */
            DriverBase = KiPcToFileHeader(Pc,
                                          &LdrEntry,
                                          FALSE,
                                          &IsSystem);
            if (IsSystem)
            {
                /*
                 * The error happened inside the kernel or HAL.
                 * Get the memory address that was being referenced.
                 */
                Memory = (PVOID)BugCheckParameter1;

                /* Find to which driver it belongs */
                DriverBase = KiPcToFileHeader(Memory,
                                              &LdrEntry,
                                              TRUE,
                                              &IsSystem);
                if (DriverBase)
                {
                    /* Get the driver name and update the bug code */
                    KiBugCheckDriver = &LdrEntry->BaseDllName;
                    KiBugCheckData[0] = DRIVER_PORTION_MUST_BE_NONPAGED;
                }
                else
                {
                    /* Find the driver that unloaded at this address */
                    KiBugCheckDriver = NULL; // FIXME: ROS can't locate

                    /* Check if the cause was an unloaded driver */
                    if (KiBugCheckDriver)
                    {
                        /* Update bug check code */
                        KiBugCheckData[0] =
                            SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD;
                    }
                }
            }
            else
            {
                /* Update the bug check code */
                KiBugCheckData[0] = DRIVER_IRQL_NOT_LESS_OR_EQUAL;
            }

            /* Clear Pc so we don't look it up later */
            Pc = NULL;
            break;

        /* Hard error */
        case FATAL_UNHANDLED_HARD_ERROR:

            /* Copy bug check data from hard error */
            HardErrorParameters = (PULONG_PTR)BugCheckParameter2;
            KiBugCheckData[0] = BugCheckParameter1;
            KiBugCheckData[1] = HardErrorParameters[0];
            KiBugCheckData[2] = HardErrorParameters[1];
            KiBugCheckData[3] = HardErrorParameters[2];
            KiBugCheckData[4] = HardErrorParameters[3];

            /* Remember that this is hard error and set the caption/message */
            IsHardError = TRUE;
            HardErrCaption = (PCHAR)BugCheckParameter3;
            HardErrMessage = (PCHAR)BugCheckParameter4;
            break;

        /* Page fault */
        case PAGE_FAULT_IN_NONPAGED_AREA:

            /* Assume no driver */
            DriverBase = NULL;

            /* Check if we have a trap frame */
            if (!TrapFrame)
            {
                /* We don't, use parameter 3 if possible */
                if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3;
            }

            /* Check if we have a frame now */
            if (TrapFrame)
            {
                /* Get the Program Counter */
                Pc = (PVOID)KeGetTrapFramePc(TrapFrame);
                KiBugCheckData[3] = (ULONG_PTR)Pc;

                /* Find out if was in the kernel or drivers */
                DriverBase = KiPcToFileHeader(Pc,
                                              &LdrEntry,
                                              FALSE,
                                              &IsSystem);
            }
            else
            {
                /* Can't blame a driver, assume system */
                IsSystem = TRUE;
            }

            /* FIXME: Check for session pool in addition to special pool */

            /* Special pool has its own bug check codes */
            if (MmIsSpecialPoolAddress((PVOID)BugCheckParameter1))
            {
                if (MmIsSpecialPoolAddressFree((PVOID)BugCheckParameter1))
                {
                    KiBugCheckData[0] = IsSystem
                        ? PAGE_FAULT_IN_FREED_SPECIAL_POOL
                        : DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL;
                }
                else
                {
                    KiBugCheckData[0] = IsSystem
                        ? PAGE_FAULT_BEYOND_END_OF_ALLOCATION
                        : DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION;
                }
            }
            else if (!DriverBase)
            {
                /* Find the driver that unloaded at this address */
                KiBugCheckDriver = NULL; // FIXME: ROS can't locate

                /* Check if the cause was an unloaded driver */
                if (KiBugCheckDriver)
                {
                    KiBugCheckData[0] =
                        DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS;
                }
            }
            break;

        /* Check if the driver forgot to unlock pages */
        case DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS:

            /* Program Counter is in parameter 1 */
            Pc = (PVOID)BugCheckParameter1;
            break;

        /* Check if the driver consumed too many PTEs */
        case DRIVER_USED_EXCESSIVE_PTES:

            /* Loader entry is in parameter 1 */
            LdrEntry = (PVOID)BugCheckParameter1;
            KiBugCheckDriver = &LdrEntry->BaseDllName;
            break;

        /* Check if the driver has a stuck thread */
        case THREAD_STUCK_IN_DEVICE_DRIVER:

            /* The name is in Parameter 3 */
            KiBugCheckDriver = (PVOID)BugCheckParameter3;
            break;

        /* Anything else */
        default:
            break;
    }

    /* Do we have a driver name? */
    if (KiBugCheckDriver)
    {
        /* Convert it to ANSI */
        KeBugCheckUnicodeToAnsi(KiBugCheckDriver, AnsiName, sizeof(AnsiName));
    }
    else
    {
        /* Do we have a Program Counter? */
        if (Pc)
        {
            /* Dump image name */
            KiDumpParameterImages(AnsiName,
                                  (PULONG_PTR)&Pc,
                                  1,
                                  KeBugCheckUnicodeToAnsi);
        }
    }

    /* Check if we need to save the context for KD */
#ifdef _WINKD_
    if (!KdPitchDebugger) KdDebuggerDataBlock.SavedContext = (ULONG_PTR)&Context;
#endif

    /* Check if a debugger is connected */
    if ((BugCheckCode != MANUALLY_INITIATED_CRASH) && (KdDebuggerEnabled))
    {
        /* Crash on the debugger console */
        DbgPrint("\n*** Fatal System Error: 0x%08lx\n"
                 "                       (0x%p,0x%p,0x%p,0x%p)\n\n",
                 KiBugCheckData[0],
                 KiBugCheckData[1],
                 KiBugCheckData[2],
                 KiBugCheckData[3],
                 KiBugCheckData[4]);

        /* Check if the debugger isn't currently connected */
        if (!KdDebuggerNotPresent)
        {
            /* Check if we have a driver to blame */
            if (KiBugCheckDriver)
            {
                /* Dump it */
                DbgPrint("Driver at fault: %s.\n", AnsiName);
            }

            /* Check if this was a hard error */
            if (IsHardError)
            {
                /* Print caption and message */
                if (HardErrCaption) DbgPrint(HardErrCaption);
                if (HardErrMessage) DbgPrint(HardErrMessage);
            }

            /* Break in the debugger */
            KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_FIRST);
        }
        else
        {
            /*
             * ROS HACK.
             * Ok, so debugging is enabled, but KDBG isn't there.
             * We'll manually dump the stack for the user.
             */
            KeRosDumpStackFrames(NULL, 0);

            /* ROS HACK 2: Generate something useful for Bugzilla */
            KeRosDumpTriageForBugZillaReport();
        }
    }

    /* Raise IRQL to HIGH_LEVEL */
    _disable();
    KeRaiseIrql(HIGH_LEVEL, &OldIrql);

    /* Avoid recursion */
    if (!InterlockedDecrement((PLONG)&KeBugCheckCount))
    {
#ifdef CONFIG_SMP
        /* Set CPU that is bug checking now */
        KeBugCheckOwner = Prcb->Number;

        /* Freeze the other CPUs */
        for (i = 0; i < KeNumberProcessors; i++)
        {
            if (i != (LONG)KeGetCurrentProcessorNumber())
            {
                /* Send the IPI and give them one second to catch up */
                KiIpiSend(1 << i, IPI_FREEZE);
                KeStallExecutionProcessor(1000000);
            }
        }
#endif

        /* Display the BSOD */
        KiDisplayBlueScreen(MessageId,
                            IsHardError,
                            HardErrCaption,
                            HardErrMessage,
                            AnsiName);

        /* Check if the debugger is disabled but we can enable it */
        if (!(KdDebuggerEnabled) && !(KdPitchDebugger))
        {
            /* Enable it */
#ifdef _WINKD_
            KdEnableDebuggerWithLock(FALSE);
#endif
        }
        else
        {
            /* Otherwise, print the last line */
            InbvDisplayString("\r\n");
        }

        /* Save the context */
        Prcb->ProcessorState.ContextFrame = Context;

        /* FIXME: Support Triage Dump */

        /* FIXME: Write the crash dump */
    }
    else
    {
        /* Increase recursion count */
        KeBugCheckOwnerRecursionCount++;
        if (KeBugCheckOwnerRecursionCount == 2)
        {
            /* Break in the debugger */
            KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND);
        }
        else if (KeBugCheckOwnerRecursionCount > 2)
        {
            /* Halt execution */
            while (TRUE);
        }
    }

    /* Call the Callbacks */
    KiDoBugCheckCallbacks();

    /* FIXME: Call Watchdog if enabled */

    /* Check if we have to reboot */
    if (Reboot)
    {
        /* Unload symbols */
        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 */
    ASSERT(FALSE);
    while (TRUE);
}
Beispiel #9
0
VOID
NTAPI
KiDisplayBlueScreen(IN ULONG MessageId,
                    IN BOOLEAN IsHardError,
                    IN PCHAR HardErrCaption OPTIONAL,
                    IN PCHAR HardErrMessage OPTIONAL,
                    IN PCHAR Message)
{
    CHAR AnsiName[75];

    /* 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);
    }

    /* Begin the display */
    InbvDisplayString("\r\n");

    /* Print out initial message */
    KeGetBugMessageText(BUGCHECK_MESSAGE_INTRO, NULL);
    InbvDisplayString("\r\n\r\n");

    /* Check if we have a driver */
    if (KiBugCheckDriver)
    {
        /* Print out into to driver name */
        KeGetBugMessageText(BUGCODE_ID_DRIVER, NULL);

        /* Convert and print out driver name */
        KeBugCheckUnicodeToAnsi(KiBugCheckDriver, AnsiName, sizeof(AnsiName));
        InbvDisplayString(" ");
        InbvDisplayString(AnsiName);
        InbvDisplayString("\r\n\r\n");
    }

    /* Check if this is the generic message */
    if (MessageId == BUGCODE_PSS_MESSAGE)
    {
        /* It is, so get the bug code string as well */
        KeGetBugMessageText((ULONG)KiBugCheckData[0], NULL);
        InbvDisplayString("\r\n\r\n");
    }

    /* Print second introduction message */
    KeGetBugMessageText(PSS_MESSAGE_INTRO, NULL);
    InbvDisplayString("\r\n\r\n");

    /* Get the bug code string */
    KeGetBugMessageText(MessageId, NULL);
    InbvDisplayString("\r\n\r\n");

    /* Print message for technical information */
    KeGetBugMessageText(BUGCHECK_TECH_INFO, NULL);

    /* Show the technical Data */
    sprintf(AnsiName,
            "\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],
            (PVOID)KiBugCheckData[4]);
    InbvDisplayString(AnsiName);

    /* Check if we have a driver*/
    if (KiBugCheckDriver)
    {
        /* Display technical driver data */
        InbvDisplayString(Message);
    }
    else
    {
        /* Dump parameter information */
        KiDumpParameterImages(Message,
                              (PVOID)&KiBugCheckData[1],
                              4,
                              KeBugCheckUnicodeToAnsi);
    }
}
Beispiel #10
0
VOID
NTAPI
KiDumpParameterImages(IN PCHAR Message,
                      IN PULONG_PTR Parameters,
                      IN ULONG ParameterCount,
                      IN PKE_BUGCHECK_UNICODE_TO_ANSI ConversionRoutine)
{
    ULONG i;
    BOOLEAN InSystem;
    PLDR_DATA_TABLE_ENTRY LdrEntry;
    PVOID ImageBase;
    PUNICODE_STRING DriverName;
    CHAR AnsiName[32];
    PIMAGE_NT_HEADERS NtHeader;
    ULONG TimeStamp;
    BOOLEAN FirstRun = TRUE;

    /* Loop parameters */
    for (i = 0; i < ParameterCount; i++)
    {
        /* Get the base for this parameter */
        ImageBase = KiPcToFileHeader((PVOID)Parameters[i],
                                     &LdrEntry,
                                     FALSE,
                                     &InSystem);
        if (!ImageBase)
        {
            /* FIXME: Add code to check for unloaded drivers */
            DPRINT1("Potentially unloaded driver!\n");
            continue;
        }
        else
        {
            /* Get the NT Headers and Timestamp */
            NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
            TimeStamp = NtHeader->FileHeader.TimeDateStamp;

            /* Convert the driver name */
            DriverName = &LdrEntry->BaseDllName;
            ConversionRoutine(&LdrEntry->BaseDllName,
                              AnsiName,
                              sizeof(AnsiName));
        }

        /* Format driver name */
        sprintf(Message,
                "%s**  %12s - Address %p base at %p, DateStamp %08lx\r\n",
                FirstRun ? "\r\n*":"*",
                AnsiName,
                (PVOID)Parameters[i],
                ImageBase,
                TimeStamp);

        /* Check if we only had one parameter */
        if (ParameterCount <= 1)
        {
            /* Then just save the name */
            KiBugCheckDriver = DriverName;
        }
        else
        {
            /* Otherwise, display the message */
            InbvDisplayString(Message);
        }

        /* Loop again */
        FirstRun = FALSE;
    }
}
Beispiel #11
0
BOOLEAN
NTAPI
KeGetBugMessageText(IN ULONG BugCheckCode,
                    OUT PANSI_STRING OutputString OPTIONAL)
{
    ULONG i, j;
    ULONG IdOffset;
    ULONG_PTR MessageEntry;
    PCHAR BugCode;
    BOOLEAN Result = FALSE;
    USHORT Length;

    /* Make sure we're not bugchecking too early */
    if (!KiBugCodeMessages) return Result;

    /* Find the message. This code is based on RtlFindMesssage */
    for (i = 0; i < KiBugCodeMessages->NumberOfBlocks; i++)
    {
        /* Check if the ID Matches */
        if ((BugCheckCode >= KiBugCodeMessages->Blocks[i].LowId) &&
            (BugCheckCode <= KiBugCodeMessages->Blocks[i].HighId))
        {
            /* Get Offset to Entry */
            MessageEntry = KiBugCodeMessages->Blocks[i].OffsetToEntries +
                           (ULONG_PTR)KiBugCodeMessages;
            IdOffset = BugCheckCode - KiBugCodeMessages->Blocks[i].LowId;

            /* Get offset to ID */
            for (j = 0; j < IdOffset; j++)
            {
                /* Advance in the Entries */
                MessageEntry += ((PMESSAGE_RESOURCE_ENTRY)MessageEntry)->
                                Length;
            }

            /* Get the final Code */
            BugCode = (PCHAR)((PMESSAGE_RESOURCE_ENTRY)MessageEntry)->Text;
            Length = (USHORT)strlen(BugCode);

            /* Handle trailing newlines */
            while ((Length > 0) && ((BugCode[Length] == '\n') ||
                                    (BugCode[Length] == '\r') ||
                                    (BugCode[Length] == ANSI_NULL)))
            {
                /* Check if we have a string to return */
                if (!OutputString) BugCode[Length] = ANSI_NULL;
                Length--;
            }

            /* Check if caller wants an output string */
            if (OutputString)
            {
                /* Return it in the OutputString */
                OutputString->Buffer = BugCode;
                OutputString->Length = Length + 1;
                OutputString->MaximumLength = Length + 1;
            }
            else
            {
                /* Direct Output to Screen */
                InbvDisplayString(BugCode);
                InbvDisplayString("\r");
            }

            /* We're done */
            Result = TRUE;
            break;
        }
    }

    /* Return the result */
    return Result;
}