Пример #1
0
VOID
KeDumpMachineState (
    IN PKPROCESSOR_STATE ProcessorState,
    IN PCHAR Buffer,
    IN PULONG BugCheckParameters,
    IN ULONG NumberOfParameters,
    IN PKE_BUGCHECK_UNICODE_TO_ANSI UnicodeToAnsiRoutine
)

/*++

Routine Description:

    This function formats and displays the machine state at the time of the
    to bug check.

Arguments:

    ProcessorState - Supplies a pointer to a processor state record.

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

    BugCheckParameters - Supplies a pointer to an array of additional
        bug check information.

    NumberOfParameters - Suppiles the size of the bug check parameters
        array.

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

Return Value:

    None.

--*/

{

    PCONTEXT ContextRecord;
    ULONG ControlPc;
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    ULONG DisplayColumn;
    ULONG DisplayHeight;
    ULONG DisplayRow;
    ULONG DisplayWidth;
    UNICODE_STRING DllName;
    ULONG EstablisherFrame;
    PRUNTIME_FUNCTION FunctionEntry;
    PVOID ImageBase;
    ULONG Index;
    BOOLEAN InFunction;
    ULONG LastStack;
    PLIST_ENTRY ModuleListHead;
    PLIST_ENTRY NextEntry;
    ULONG NextPc;
    ULONG StackLimit;
    UCHAR AnsiBuffer[ 32 ];
    ULONG DateStamp;

    //
    // Call the HAL to force all external interrupts to be disabled
    // at the interrupt controller. PowerPC optimization does not
    // do this when raising to high level.
    //
    for (Index = 0; Index < MAXIMUM_VECTOR; Index++) {
        HalDisableSystemInterrupt(Index, HIGH_LEVEL);
    }

    //
    // Query display parameters.
    //

    HalQueryDisplayParameters(&DisplayWidth,
                              &DisplayHeight,
                              &DisplayColumn,
                              &DisplayRow);

    //
    // Display any addresses that fall within the range of any module in
    // the loaded module list.
    //

    for (Index = 0; Index < NumberOfParameters; Index += 1) {
        ImageBase = KiPcToFileHeader((PVOID)*BugCheckParameters,
                                     &ImageBase,
                                     &DataTableEntry);

        if (ImageBase != NULL) {
            sprintf(Buffer,
                    "*** %08lX has base at %08lX - %s\n",
                    *BugCheckParameters,
                    ImageBase,
                    (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer )));

            HalDisplayString(Buffer);
        }

        BugCheckParameters += 1;
    }

    //
    // Virtually unwind to the caller of bug check.
    //

    ContextRecord = &ProcessorState->ContextFrame;
    LastStack = ContextRecord->Gpr1;
    ControlPc = ContextRecord->Lr - 4;
    NextPc = ControlPc;
    FunctionEntry = KiLookupFunctionEntry(ControlPc);
    if (FunctionEntry != NULL) {
        NextPc = RtlVirtualUnwind(ControlPc,
                                  FunctionEntry,
                                  ContextRecord,
                                  &InFunction,
                                  &EstablisherFrame,
                                  NULL,
                                  0,
                                  0xffffffff);
    }

    //
    // At this point the context record contains the machine state at the
    // call to bug check.
    //
    // Put out the machine state at the time of the bugcheck.
    //

    sprintf(Buffer,
            "\n Machine State at Call to Bug Check    IAR:%08lX MSR:%08lX\n",
            ContextRecord->Lr,
            ContextRecord->Msr);

    HalDisplayString(Buffer);

    //
    // Format and output the integer registers.
    //

    sprintf(Buffer,
            " R0:%8lX  R1:%8lX  R2:%8lX  R3:%8lX  R4:%8lX  R5:%8lX\n",
            ContextRecord->Gpr0,
            ContextRecord->Gpr1,
            ContextRecord->Gpr2,
            ContextRecord->Gpr3,
            ContextRecord->Gpr4,
            ContextRecord->Gpr5);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            " R6:%8lX  R7:%8lX  R8:%8lX  R9:%8lX R10:%8lX R11:%8lX\n",
            ContextRecord->Gpr6,
            ContextRecord->Gpr7,
            ContextRecord->Gpr8,
            ContextRecord->Gpr9,
            ContextRecord->Gpr10,
            ContextRecord->Gpr11);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            "R12:%8lX R13:%8lX R14:%8lX R15:%8lX R16:%8lX R17:%8lX\n",
            ContextRecord->Gpr12,
            ContextRecord->Gpr13,
            ContextRecord->Gpr14,
            ContextRecord->Gpr15,
            ContextRecord->Gpr16,
            ContextRecord->Gpr17);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            "R18:%8lX R19:%8lX R20:%8lX R21:%8lX R22:%8lX R23:%8lX\n",
            ContextRecord->Gpr18,
            ContextRecord->Gpr19,
            ContextRecord->Gpr20,
            ContextRecord->Gpr21,
            ContextRecord->Gpr22,
            ContextRecord->Gpr23);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            "R24:%8lX R25:%8lX R26:%8lX R27:%8lX R28:%8lX R29:%8lX\n",
            ContextRecord->Gpr24,
            ContextRecord->Gpr25,
            ContextRecord->Gpr26,
            ContextRecord->Gpr27,
            ContextRecord->Gpr28,
            ContextRecord->Gpr29);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            "R30:%8lX R31:%8lX  CR:%8lX CTR:%8lX XER:%8lX\n",
            ContextRecord->Gpr30,
            ContextRecord->Gpr31,
            ContextRecord->Cr,
            ContextRecord->Ctr,
            ContextRecord->Xer);

    HalDisplayString(Buffer);

#if 0

    //
    // I'd much rather see a longer stack trace and skip the floating
    // point stuff when the system crashes.  plj
    //

    //
    // Format and output the floating registers.
    //
    DumpFloat = (PULONG)(&ContextRecord->Fpr0);
    sprintf(Buffer,
            " F0- F3:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr4);
    sprintf(Buffer,
            " F4- F7:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr8);
    sprintf(Buffer,
            " F8-F11:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr12);
    sprintf(Buffer,
            "F12-F15:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr16);
    sprintf(Buffer,
            "F16-F19:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr20);
    sprintf(Buffer,
            "F20-F23:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr24);
    sprintf(Buffer,
            "F24-F27:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr28);
    sprintf(Buffer,
            "F28-F31:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);


    DumpFloat = (PULONG)(&ContextRecord->Fpscr);
    sprintf(Buffer,
            "  FPSCR:%08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat);

    HalDisplayString(Buffer);

#define STAKWALK 4
#else
#define STAKWALK 8
#endif

    //
    // Output short stack back trace with base address.
    //

    DllName.Length = 0;
    DllName.Buffer = L"";
    if (FunctionEntry != NULL) {
        StackLimit = (ULONG)KeGetCurrentThread()->KernelStack;
        HalDisplayString("Callee-Sp Return-Ra  Dll Base - Name\n");
        for (Index = 0; Index < STAKWALK; Index += 1) {
            ImageBase = KiPcToFileHeader((PVOID)ControlPc,
                                         &ImageBase,
                                         &DataTableEntry);

            sprintf(Buffer,
                    " %08lX %08lX : %08lX - %s\n",
                    ContextRecord->Gpr1,
                    NextPc + 4,
                    ImageBase,
                    (*UnicodeToAnsiRoutine)( (ImageBase != NULL) ? &DataTableEntry->BaseDllName : &DllName,
                                             AnsiBuffer, sizeof( AnsiBuffer )));

            HalDisplayString(Buffer);

            if ((NextPc != ControlPc) || (ContextRecord->Gpr1 != LastStack)) {
                ControlPc = NextPc;
                LastStack = ContextRecord->Gpr1;
                FunctionEntry = KiLookupFunctionEntry(ControlPc);
                if ((FunctionEntry != NULL) && (LastStack < StackLimit)) {
                    NextPc = RtlVirtualUnwind(ControlPc,
                                              FunctionEntry,
                                              ContextRecord,
                                              &InFunction,
                                              &EstablisherFrame,
                                              NULL,
                                              0,
                                              0xffffffff);
                } else {
                    NextPc = ContextRecord->Lr;
                }

            } else {
                break;
            }
        }
    }

    //
    // Output the build number and other useful information.
    //

    sprintf(Buffer,
            "\nIRQL : %d, DPC Active : %s, SYSVER 0x%08x\n",
            KeGetCurrentIrql(),
            KeIsExecutingDpc() ? "TRUE" : "FALSE",
            NtBuildNumber);

    HalDisplayString(Buffer);

    //
    // Output the processor id and the primary cache sizes.
    //

    sprintf(Buffer,
            "Processor Id: %d.%d, Icache: %d, Dcache: %d",
            PCR->ProcessorVersion,
            PCR->ProcessorRevision,
            PCR->FirstLevelIcacheSize,
            PCR->FirstLevelDcacheSize);

    HalDisplayString(Buffer);

    //
    // If the display width is greater than 80 + 24 (the size of a DLL
    // name and base address), then display all the modules loaded in
    // the system.
    //

    HalQueryDisplayParameters(&DisplayWidth,
                              &DisplayHeight,
                              &DisplayColumn,
                              &DisplayRow);

    if (DisplayWidth > (80 + 24)) {
        HalDisplayString("\n");
        if (KeLoaderBlock != NULL) {
            ModuleListHead = &KeLoaderBlock->LoadOrderListHead;

        } else {
            ModuleListHead = &PsLoadedModuleList;
        }

        //
        // Output display headers.
        //

        Index = 1;
        KiDisplayString(80, Index, "Dll Base DateStmp - Name");
        NextEntry = ModuleListHead->Flink;
        if (NextEntry != NULL) {

            //
            // Scan the list of loaded modules and display their base
            // address and name.
            //

            while (NextEntry != ModuleListHead) {
                Index += 1;
                DataTableEntry = CONTAINING_RECORD(NextEntry,
                                                   LDR_DATA_TABLE_ENTRY,
                                                   InLoadOrderLinks);

                if (MmDbgReadCheck(DataTableEntry->DllBase) != NULL) {
                    PIMAGE_NT_HEADERS NtHeaders;

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

                } else {
                    DateStamp = 0;
                }
                sprintf(Buffer,
                        "%08lX %08lx - %s",
                        DataTableEntry->DllBase,
                        DateStamp,
                        (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer )));

                KiDisplayString(80, Index, Buffer);
                NextEntry = NextEntry->Flink;
                if (Index > DisplayHeight) {
                    break;
                }
            }
        }
    }

    //
    // Reset the current display position.
    //

    HalSetDisplayParameters(DisplayColumn, DisplayRow);

    //
    // The system has crashed, if we are running without the Kernel
    // debugger attached, attach it now.
    //

    KdInitSystem(NULL, FALSE);

    return;
}
Пример #2
0
VOID
KdpReadIoSpace (
    IN PDBGKD_MANIPULATE_STATE m,
    IN PSTRING AdditionalData,
    IN PCONTEXT Context
    )

/*++

Routine Description:

    This function is called in response of a read io space state
    manipulation message.  Its function is to read system io
    locations.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{
    PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo;
    STRING MessageHeader;
    PUCHAR b;
    PUSHORT s;
    PULONG l;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    ASSERT(AdditionalData->Length == 0);

    m->ReturnStatus = STATUS_SUCCESS;

    //
    // Check Size and Alignment
    //

    switch ( a->DataSize ) {
        case 1:
            b = (PUCHAR)MmDbgReadCheck(a->IoAddress);
            if ( b ) {
                a->DataValue = (ULONG)*b;
            } else {
                m->ReturnStatus = STATUS_ACCESS_VIOLATION;
            }
            break;
        case 2:
            if ((ULONG)a->IoAddress & 1 ) {
                m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
            } else {
                s = (PUSHORT)MmDbgReadCheck(a->IoAddress);
                if ( s ) {
                    a->DataValue = (ULONG)*s;
                } else {
                    m->ReturnStatus = STATUS_ACCESS_VIOLATION;
                }
            }
            break;
        case 4:
            if ((ULONG)a->IoAddress & 3 ) {
                m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
            } else {
                l = (PULONG)MmDbgReadCheck(a->IoAddress);
                if ( l ) {
                    a->DataValue = (ULONG)*l;
                } else {
                    m->ReturnStatus = STATUS_ACCESS_VIOLATION;
                }
            }
            break;
        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
    }

    KdpSendPacket(
        PACKET_TYPE_KD_STATE_MANIPULATE,
        &MessageHeader,
        NULL
        );
}
Пример #3
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;
}
Пример #4
0
PVOID
KiPcToFileHeader(
    IN PVOID PcValue,
    OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry,
    IN LOGICAL DriversOnly,
    OUT PBOOLEAN InKernelOrHal
    )

/*++

Routine Description:

    This function returns the base of an image that contains the
    specified PcValue. An image contains the PcValue if the PcValue
    is within the ImageBase, and the ImageBase plus the size of the
    virtual image.

Arguments:

    PcValue - Supplies a PcValue.

    DataTableEntry - Supplies a pointer to a variable that receives the
        address of the data table entry that describes the image.

    DriversOnly - Supplies TRUE if the kernel and HAL should be skipped.

    InKernelOrHal - Set to TRUE if the PcValue is in the kernel or the HAL.
        This only has meaning if DriversOnly is FALSE.

Return Value:

    NULL - No image was found that contains the PcValue.

    NON-NULL - Returns the base address of the image that contains the
        PcValue.

--*/

{
    ULONG i;
    PLIST_ENTRY ModuleListHead;
    PLDR_DATA_TABLE_ENTRY Entry;
    PLIST_ENTRY Next;
    ULONG_PTR Bounds;
    PVOID ReturnBase, Base;

    //
    // If the module list has been initialized, then scan the list to
    // locate the appropriate entry.
    //

    if (KeLoaderBlock != NULL) {
        ModuleListHead = &KeLoaderBlock->LoadOrderListHead;

    } else {
        ModuleListHead = &PsLoadedModuleList;
    }

    *InKernelOrHal = FALSE;

    ReturnBase = NULL;
    Next = ModuleListHead->Flink;
    if (Next != NULL) {
        i = 0;
        while (Next != ModuleListHead) {
            if (MmDbgReadCheck(Next) == NULL) {
                return NULL;
            }
            i += 1;
            if ((i <= 2) && (DriversOnly == TRUE)) {
                Next = Next->Flink;
                continue;
            }

            Entry = CONTAINING_RECORD(Next,
                                      LDR_DATA_TABLE_ENTRY,
                                      InLoadOrderLinks);

            Next = Next->Flink;
            Base = Entry->DllBase;
            Bounds = (ULONG_PTR)Base + Entry->SizeOfImage;
            if ((ULONG_PTR)PcValue >= (ULONG_PTR)Base && (ULONG_PTR)PcValue < Bounds) {
                *DataTableEntry = Entry;
                ReturnBase = Base;
                if (i <= 2) {
                    *InKernelOrHal = TRUE;
                }
                break;
            }
        }
    }

    return ReturnBase;
}
Пример #5
0
VOID
KiScanBugCheckCallbackList (
    VOID
    )

/*++

Routine Description:

    This function scans the bug check callback list and calls each bug
    check callback routine so it can dump component specific information
    that may identify the cause of the bug check.

    N.B. The scan of the bug check callback list is performed VERY
        carefully. Bug check callback routines are called at HIGH_LEVEL
        and may not acquire ANY resources.

Arguments:

    None.

Return Value:

    None.

--*/

{

    PKBUGCHECK_CALLBACK_RECORD CallbackRecord;
    ULONG_PTR Checksum;
    ULONG Index;
    PLIST_ENTRY LastEntry;
    PLIST_ENTRY ListHead;
    PLIST_ENTRY NextEntry;
    PUCHAR Source;

    //
    // If the bug check callback listhead is not initialized, then the
    // bug check has occured before the system has gotten far enough
    // in the initialization code to enable anyone to register a callback.
    //

    ListHead = &KeBugCheckCallbackListHead;
    if ((ListHead->Flink != NULL) && (ListHead->Blink != NULL)) {

        //
        // Scan the bug check callback list.
        //

        LastEntry = ListHead;
        NextEntry = ListHead->Flink;
        while (NextEntry != ListHead) {

            //
            // The next entry address must be aligned properly, the
            // callback record must be readable, and the callback record
            // must have back link to the last entry.
            //

            if (((ULONG_PTR)NextEntry & (sizeof(ULONG_PTR) - 1)) != 0) {
                return;

            } else {
                CallbackRecord = CONTAINING_RECORD(NextEntry,
                                                   KBUGCHECK_CALLBACK_RECORD,
                                                   Entry);

                Source = (PUCHAR)CallbackRecord;
                for (Index = 0; Index < sizeof(KBUGCHECK_CALLBACK_RECORD); Index += 1) {
                    if (MmDbgReadCheck((PVOID)Source) == NULL) {
                        return;
                    }

                    Source += 1;
                }

                if (CallbackRecord->Entry.Blink != LastEntry) {
                    return;
                }

                //
                // If the callback record has a state of inserted and the
                // computed checksum matches the callback record checksum,
                // then call the specified bug check callback routine.
                //

                Checksum = (ULONG_PTR)CallbackRecord->CallbackRoutine;
                Checksum += (ULONG_PTR)CallbackRecord->Buffer;
                Checksum += CallbackRecord->Length;
                Checksum += (ULONG_PTR)CallbackRecord->Component;
                if ((CallbackRecord->State == BufferInserted) &&
                    (CallbackRecord->Checksum == Checksum)) {

                    //
                    // Call the specified bug check callback routine and
                    // handle any exceptions that occur.
                    //

                    CallbackRecord->State = BufferStarted;
                    try {
                        (CallbackRecord->CallbackRoutine)(CallbackRecord->Buffer,
                                                          CallbackRecord->Length);

                        CallbackRecord->State = BufferFinished;

                    } except(EXCEPTION_EXECUTE_HANDLER) {
                        CallbackRecord->State = BufferIncomplete;
                    }
                }
            }

            LastEntry = NextEntry;
            NextEntry = NextEntry->Flink;
        }
Пример #6
0
ULONG
KdpMoveMemory (
    IN PCHAR Destination,
    IN PCHAR Source,
    IN ULONG Length
    )

/*++

Routine Description:

    This routine moves data to or from the message buffer and returns the
    actual length of the information that was moved. As data is moved, checks
    are made to ensure that the data is resident in memory and a page fault
    will not occur. If a page fault would occur, then the move is truncated.

Arguments:

    Destination  - Supplies a pointer to destination of the move operation.

    Source - Supplies a pointer to the source of the move operation.

    Length - Supplies the length of the move operation.

Return Value:

    The actual length of the move is returned as the fucntion value.

--*/

{

    PVOID Address1;
    PVOID Address2;
    ULONG ActualLength;
    ULONG_PTR Opaque;

    //
    // If the length is greater than the size of the message buffer, then
    // reduce the length to the size of the message buffer.
    //

    if (Length > KDP_MESSAGE_BUFFER_SIZE) {
        Length = KDP_MESSAGE_BUFFER_SIZE;
    }

    //
    // Move the source information to the destination address.
    //

    ActualLength = Length;

    while (((ULONG_PTR)Source & 3) && (Length > 0)) {

    //
    // Check to determine if the move will succeed before actually performing
    // the operation.
    //

        Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
        Address2 = MmDbgReadCheck((PVOID)Source);
        if ((Address1 == NULL) || (Address2 == NULL)) {
            break;
        }
        *(PCHAR)Address1 = *(PCHAR)Address2;
        MmDbgReleaseAddress((PVOID)Destination, Opaque);
        Destination += 1;
        Source += 1;
        Length -= 1;
    }

    while (Length > 3) {

    //
    // Check to determine if the move will succeed before actually performing
    // the operation.
    //

        Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
        Address2 = MmDbgReadCheck((PVOID)Source);
        if ((Address1 == NULL) || (Address2 == NULL)) {
            break;
        }
        *(ULONG UNALIGNED *)Address1 = *(PULONG)Address2;
        MmDbgReleaseAddress((PVOID)Destination, Opaque);
        Destination += 4;
        Source += 4;
        Length -= 4;

    }

    while (Length > 0) {

    //
    // Check to determine if the move will succeed before actually performing
    // the operation.
    //

        Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
        Address2 = MmDbgReadCheck((PVOID)Source);
        if ((Address1 == NULL) || (Address2 == NULL)) {
            break;
        }
        *(PCHAR)Address1 = *(PCHAR)Address2;
        MmDbgReleaseAddress((PVOID)Destination, Opaque);
        Destination += 1;
        Source += 1;
        Length -= 1;
    }

    //
    // Flush the instruction cache in case the write was into the instruction
    // stream.
    //

    KeSweepCurrentIcache();
    return ActualLength - Length;
}