测试代码

来源:互联网 发布:qq网络营销软件 编辑:程序博客网 时间:2024/05/30 07:13
#include "iop.h"
#include 
"ntddft.h"
#include 
<inbv.h>
#include 
<windef.h>

//
// Processor specific macros.
//

#if defined (i386)

#define PROGRAM_COUNTER(_context)   ((_context)->Eip)
#define STACK_POINTER(_context)     ((_context)->Esp)
#define CURRENT_IMAGE_TYPE()        IMAGE_FILE_MACHINE_I386
#define PaeEnabled() X86PaeEnabled()

#elif defined (ALPHA)

#define PROGRAM_COUNTER(_context)   ((_context)->Fir)
#define STACK_POINTER(_context)     ((_context)->IntSp)
#define CURRENT_IMAGE_TYPE()        IMAGE_FILE_MACHINE_ALPHA
#define PaeEnabled() (FALSE)

#elif defined (_IA64_)

#define PROGRAM_COUNTER(_context)   ((_context)->StIIP)
#define STACK_POINTER(_context)     ((_context)->IntSp)
#define CURRENT_IMAGE_TYPE()        IMAGE_FILE_MACHINE_IA64
#define PaeEnabled() (FALSE)

#else

#error ("unknown processor type")

#endif

//
// min3(_a,_b,_c)
//
// Same as min() but takes 3 parameters.
//

#define min3(_a,_b,_c) ( min ( min ((_a), (_b)), min ((_a), (_c))) )


//
// Global variables
//

extern PVOID MmPfnDatabase;
extern PFN_NUMBER MmHighestPossiblePhysicalPage;

NTSTATUS IopFinalCrashDumpStatus         
= -1;
ULONG    IopCrashDumpStateChange         
=  0;
BOOLEAN  IopDumpFileContainsNewDump      
= FALSE;

//
// Max dump transfer sizes
//

#define IO_DUMP_MAXIMUM_TRANSFER_SIZE   ( 1024 * 64 )
#define IO_DUMP_MINIMUM_TRANSFER_SIZE   ( 1024 * 32 )
#define IO_DUMP_MINIMUM_FILE_SIZE       ( PAGE_SIZE * 256 )
#define MAX_UNICODE_LENGTH              ( 512 )

#define DEFAULT_DRIVER_PATH             L"\\SystemRoot\\System32\\Drivers\\"
#define DEFAULT_DUMP_DRIVER             L"\\SystemRoot\\System32\\Drivers\\diskdump.sys"
#define SCSIPORT_DRIVER_NAME            L"scsiport.sys"
#define MAX_TRIAGE_STACK_SIZE           ( 16 * 1024 )
#define DEFAULT_TRIAGE_DUMP_FLAGS (0xFFFFFFFF)


//
// Function prototypes
//


NTSTATUS
IopWriteTriageDump(
    IN ULONG FieldsToWrite,
    IN PDUMP_DRIVER_WRITE WriteRoutine,
    IN OUT PLARGE_INTEGER Mcb,
    IN OUT PMDL Mdl,
    IN ULONG DiverTransferSize,
    IN PCONTEXT Context,
    IN LPBYTE Buffer,
    IN ULONG BufferSize,
    IN ULONG ServicePackBuild,
    IN ULONG TriageOptions
    );

NTSTATUS
IopWriteSummaryDump(
    IN PRTL_BITMAP PageMap,
    IN PDUMP_DRIVER_WRITE WriteRoutine,
    IN PANSI_STRING ProgressMessage,
    IN PUCHAR MessageBuffer,
    IN OUT PLARGE_INTEGER Mcb,
    IN ULONG DiverTransferSize
    );

NTSTATUS
IopWriteToDisk(
    IN PVOID Buffer,
    IN ULONG WriteLength,
    IN PDUMP_DRIVER_WRITE DriverWriteRoutine,
    IN OUT PLARGE_INTEGER 
* Mcb,
    IN OUT PMDL Mdl,
    IN ULONG DriverTransferSize
    );
    
VOID
IopMapPhysicalMemory(
    IN OUT PMDL Mdl,
    IN ULONG_PTR MemoryAddress,
    IN PPHYSICAL_MEMORY_RUN PhysicalMemoryRun,
    IN ULONG Length
    );

NTSTATUS
IopLoadDumpDriver (
    IN OUT PDUMP_STACK_CONTEXT  DumpStack,
    IN PWCHAR DriverNameString,
    IN PWCHAR NewBaseNameString
    );

NTSTATUS
IoSetCrashDumpState(
    IN SYSTEM_CRASH_STATE_INFORMATION 
*pDumpState
    );

PSUMMARY_DUMP_HEADER
IopInitializeSummaryDump(
    IN PDUMP_CONTROL_BLOCK pDcb
    );

NTSTATUS
IopWriteSummaryHeader(
    IN PSUMMARY_DUMP_HEADER    pSummaryHeader,
    IN PDUMP_DRIVER_WRITE      pfWrite,
    IN OUT PLARGE_INTEGER 
*    pMcbBuffer,
    IN OUT PMDL                pMdl,
    IN ULONG                   dwWriteSize,
    IN ULONG                   dwLength
    );

VOID
IopMapVirtualToPhysicalMdl(
    IN OUT PMDL pMdl,
    IN ULONG_PTR dwMemoryAddress,
    IN ULONG    dwLength
    );

ULONG
IopCreateSummaryDump (
    IN PSUMMARY_DUMP_HEADER pHeader
    );

VOID
IopDeleteNonExistentMemory(
    PSUMMARY_DUMP_HEADER        pHeader,
    PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock
    );


NTSTATUS
IopGetDumpStack (
    IN PWCHAR                         ModulePrefix,
    OUT PDUMP_STACK_CONTEXT           
*pDumpStack,
    IN PUNICODE_STRING                pUniDeviceName,
    IN PWSTR                          pDumpDriverName,
    IN DEVICE_USAGE_NOTIFICATION_TYPE UsageType,
    IN ULONG                          IgnoreDeviceUsageFailure
    );

BOOLEAN
IopInitializeDCB(
    );

LARGE_INTEGER
IopCalculateRequiredDumpSpace(
    IN ULONG            dwDmpFlags,
    IN ULONG            dwHeaderSize,
    IN PFN_NUMBER       dwMaxPages,
    IN PFN_NUMBER       dwMaxSummaryPages
    );

NTSTATUS
IopCompleteDumpInitialization(
    IN HANDLE     FileHandle
    );

#if DBG

VOID
IopDebugPrint(
    ULONG  DebugPrintLevel,
    PCCHAR DebugMessage,
    
    );

#define IoDebugPrint(X) IopDebugPrint X

#else

#define IoDebugPrint(X)

#endif //DBG


#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,IoGetDumpStack)
#pragma alloc_text(PAGE,IopLoadDumpDriver)
#pragma alloc_text(PAGE,IoFreeDumpStack)
#pragma alloc_text(PAGE,IoGetCrashDumpInformation)
#pragma alloc_text(PAGE,IoGetCrashDumpStateInformation)
#pragma alloc_text(PAGE,IoSetCrashDumpState)
#endif


#if defined (i386)

//
// Functions 
//

 
BOOL
X86PaeEnabled(
    )

/*++

Routine Description:

    Is PAE currently enabled?
    
Return Values:

    Return TRUE if PAE is enabled in the CR4 register, FALSE otherwise.

--
*/

    
{
    ULONG Reg_Cr4;
    
    _asm {
        _emit 0Fh
        _emit 20h
        _emit 0E0h  ;; mov eax, cr4
        mov Reg_Cr4, eax
    }


    return (Reg_Cr4 & CR4_PAE ? TRUE : FALSE);
}


#endif

        
 
BOOLEAN
IopIsAddressRangeValid(
    IN PVOID VirtualAddress,
    IN SIZE_T Length
    )

/*++

Routine Description:

    Validate a range of addresses.

Arguments:

    Virtual Address - Beginning of of memory block to validate.

    Length - Length of memory block to validate.

Return Value:

    TRUE - Address range is valid.

    FALSE - Address range is not valid.

--
*/


{
    UINT_PTR Va;
    ULONG Pages;

    Va = (UINT_PTR) PAGE_ALIGN (VirtualAddress);
    Pages = COMPUTE_PAGES_SPANNED (VirtualAddress, Length);

    while (Pages) {

        if (!MmIsAddressValid ( (LPVOID) Va)) {
            return FALSE;
        }


        Va += PAGE_SIZE;
        Pages--;
    }


    return TRUE;
}

    

 
NTSTATUS
IoGetDumpStack (
    IN PWCHAR                          ModulePrefix,
    OUT PDUMP_STACK_CONTEXT          
* pDumpStack,
    IN  DEVICE_USAGE_NOTIFICATION_TYPE UsageType,
    IN  ULONG                          IgnoreDeviceUsageFailure
    )
/*++

Routine Description:

    This routine loads a dump stack instance and returns an allocated
    context structure to track the loaded dumps stack.

Arguments:

    ModePrefix      - The prefix to prepent to BaseName during the load
                      operation.  This allows loading the same drivers
                      multiple times with different virtual names and
                      linkages.

    pDumpStack      - The returned dump stack context structure

    UsageType       - The Device Notification Usage Type for this file, that
                      this routine will send as to the device object once the
                      file has been successfully created and initialized.

    IgnoreDeviceUsageFailure - If the Device Usage Notification Irp fails, allow
                      this to succeed anyway.

Return Value:

    Status

--
*/

{

    PAGED_CODE();
    return IopGetDumpStack(ModulePrefix,
                           pDumpStack,
                           &IoArcBootDeviceName,
                           DEFAULT_DUMP_DRIVER,
                           UsageType,
                           IgnoreDeviceUsageFailure
                           );
}



 
NTSTATUS
IopGetDumpStack (
    IN PWCHAR                         ModulePrefix,
    OUT PDUMP_STACK_CONTEXT         
* pDumpStack,
    IN PUNICODE_STRING                pUniDeviceName,
    IN PWCHAR                         pDumpDriverName,
    IN DEVICE_USAGE_NOTIFICATION_TYPE UsageType,
    IN ULONG                          IgnoreDeviceUsageFailure
    )
/*++

Routine Description:

    This routine loads a dump stack instance and returns an allocated
    context structure to track the loaded dumps stack.

Arguments:

    ModePrefix      - The prefix to prepent to BaseName during the load
                      operation.  This allows loading the same drivers
                      multiple times with different virtual names and
                      linkages.

    pDumpStack      - The returned dump stack context structure

    pDeviceName     - The name of the target dump device

    pDumpDriverName - The name of the target dump driver

    UsageType       - The Device Notification Usage Type for this file, that
                      this routine will send as to the device object once the
                      file has been successfully created and initialized.

    IgnoreDeviceUsageFailure - If the Device Usage Notification Irp fails, allow
                      this to succeed anyway.

Return Value:

    Status

--
*/

{
    PDUMP_STACK_CONTEXT         DumpStack;
    PUCHAR                      Buffer;
    PUCHAR                      PartitionName;
    ANSI_STRING                 AnsiString;
    UNICODE_STRING              TempName;
    OBJECT_ATTRIBUTES           ObjectAttributes;
    NTSTATUS                    Status;
    HANDLE                      DeviceHandle;
    SCSI_ADDRESS                ScsiAddress;
    BOOLEAN                     ScsiDump;
    PARTITION_INFORMATION       PartitionInfo;
    PFILE_OBJECT                FileObject;
    PDEVICE_OBJECT              DeviceObject;
    PINITIALIZATION_CONTEXT     DumpInit;
    PDUMP_POINTERS              DumpPointers;
    UNICODE_STRING              DriverName;
    PDRIVER_OBJECT              DriverObject;
    PIRP                        Irp;
    PIO_STACK_LOCATION          IrpSp;
    IO_STATUS_BLOCK             IoStatus;
    PWCHAR                      DumpName, NameOffset;
    KEVENT                      Event;
    PVOID                       p1;
    PHYSICAL_ADDRESS            pa;
    ULONG                       i;
    IO_STACK_LOCATION           irpSp;
    ULONG                       information;

    IoDebugPrint((2,"IopGetDumpStack: Prefix:%ws stk: %x device:%ws driver:%ws\n",
                ModulePrefix, pDumpStack, pUniDeviceName->Buffer,pDumpDriverName));

    ASSERT (DeviceUsageTypeUndefined != UsageType);

    DumpStack = ExAllocatePoolWithTag (
                    NonPagedPool,
                    sizeof (DUMP_STACK_CONTEXT) + sizeof (DUMP_POINTERS),
                    'pmuD'
                    );

    if (!DumpStack) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }


    RtlZeroMemory(DumpStack, sizeof(DUMP_STACK_CONTEXT)+sizeof(DUMP_POINTERS));
    DumpInit = &DumpStack->Init;
    DumpPointers = (PDUMP_POINTERS) (DumpStack + 1);
    DumpStack->DumpPointers = DumpPointers;
    InitializeListHead (&DumpStack->DriverList);
    DumpName = NULL;

    //
    
// Allocate scratch buffer
    
//

    Buffer = ExAllocatePoolWithTag (PagedPool, PAGE_SIZE, 'pmuD');
    if (!Buffer) {
        ExFreePool (DumpStack);
        return STATUS_INSUFFICIENT_RESOURCES;
    }


    if (!KeGetBugMessageText(BUGCODE_PSS_CRASH_INIT, &DumpStack->InitMsg) ||
        !KeGetBugMessageText(BUGCODE_PSS_CRASH_PROGRESS, &DumpStack->ProgMsg) ||
        !KeGetBugMessageText(BUGCODE_PSS_CRASH_DONE, &DumpStack->DoneMsg)) {
            Status = STATUS_UNSUCCESSFUL;
            goto Done;
    }


    InitializeObjectAttributes(
        &ObjectAttributes,
        pUniDeviceName,
        0,
        NULL,
        NULL
        );

    Status = ZwOpenFile(
              &DeviceHandle,
              FILE_READ_DATA | SYNCHRONIZE,
              &ObjectAttributes,
              &IoStatus,
              FILE_SHARE_READ | FILE_SHARE_WRITE,
              FILE_NON_DIRECTORY_FILE
              );

    if (!NT_SUCCESS(Status)) {
        IoDebugPrint ((0,
                       "IODUMP: Could not open boot device partition, %s\n",
                       Buffer
                       ));
        goto Done;
    }


    //
    
// Check to see whether or not the system was booted from a SCSI device.
    
//

    Status = ZwDeviceIoControlFile (
                    DeviceHandle,
                    NULL,
                    NULL,
                    NULL,
                    &IoStatus,
                    IOCTL_SCSI_GET_ADDRESS,
                    NULL,
                    0,
                    &ScsiAddress,
                    sizeof( SCSI_ADDRESS )
                    );

    if (Status == STATUS_PENDING) {
        ZwWaitForSingleObject (
            DeviceHandle,
            FALSE,
            NULL
            );

        Status = IoStatus.Status;
    }


    ScsiDump = (BOOLEAN) (NT_SUCCESS(Status));

    //
    
// If SCSI then allocate storage to contain the target address information.
    
//

    DumpInit->TargetAddress = NULL;

    if (ScsiDump) {

        DumpInit->TargetAddress = ExAllocatePoolWithTag (
                                    NonPagedPool,
                                    sizeof (SCSI_ADDRESS),
                                    'pmuD'
                                    );
        //
        
// It is ok If the allocation fails. The scsi dump driver will scan
        
// all devices if the targetaddress information does not exist
        
//

        if (DumpInit->TargetAddress) {
            RtlCopyMemory(DumpInit->TargetAddress,&ScsiAddress,sizeof(SCSI_ADDRESS));
        }

    }


    //
    
// Determine the disk signature for the device from which the system was
    
// booted and get the partition offset.
    
//

    Status = ZwDeviceIoControlFile(
                    DeviceHandle,
                    NULL,
                    NULL,
                    NULL,
                    &IoStatus,
                    IOCTL_DISK_GET_PARTITION_INFO,
                    NULL,
                    0,
                    &PartitionInfo,
                    sizeof( PARTITION_INFORMATION )
                    );

    if (Status == STATUS_PENDING) {
        ZwWaitForSingleObject (
            DeviceHandle,
            FALSE,
            NULL
            );

        Status = IoStatus.Status;
    }


    IoDebugPrint((2,"Partition Type = %x\n",PartitionInfo.PartitionType));
    IoDebugPrint((2,"Boot Indicator = %x\n",PartitionInfo.BootIndicator));

    Status = ZwDeviceIoControlFile(
                    DeviceHandle,
                    NULL,
                    NULL,
                    NULL,
                    &IoStatus,
                    IOCTL_DISK_GET_DRIVE_LAYOUT,
                    NULL,
                    0,
                    Buffer,
                    PAGE_SIZE
                    );

    if (Status == STATUS_PENDING) {
        ZwWaitForSingleObject (
            DeviceHandle,
            FALSE,
            NULL
            );

        Status = IoStatus.Status;
    }


    DumpInit->DiskSignature = ((PDRIVE_LAYOUT_INFORMATION) Buffer)->Signature;

    //
    
// Get the adapter object and base mapping registers for the disk from
    
// the disk driver.  These will be used to call the HAL once the system
    
// system has crashed, since it is not possible at that point to recreate
    
// them from scratch.
    
//

    ObReferenceObjectByHandle (
            DeviceHandle,
            0,
            IoFileObjectType,
            KernelMode,
            (PVOID *) &FileObject,
            NULL
            );


    DeviceObject = IoGetRelatedDeviceObject (FileObject);

    KeInitializeEvent( &Event, NotificationEvent, FALSE );

    Irp = IoBuildDeviceIoControlRequest(
                IOCTL_SCSI_GET_DUMP_POINTERS,
                DeviceObject,
                NULL,
                0,
                DumpPointers,
                sizeof (DUMP_POINTERS),
                FALSE,
                &Event,
                &IoStatus
                );

    if (!Irp) {
        ObDereferenceObject (FileObject);
        ZwClose (DeviceHandle);
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Done;
    }


    IrpSp = IoGetNextIrpStackLocation (Irp);

    IrpSp->FileObject = FileObject;

    Status = IoCallDriver( DeviceObject, Irp );

    if (Status == STATUS_PENDING) {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        Status = IoStatus.Status;
    }


    if (!NT_SUCCESS(Status)  ||  IoStatus.Information < FIELD_OFFSET(DUMP_POINTERS, DeviceObject)) {

        IoDebugPrint ((0,
                       "IODUMP: Could not get dump pointers; error = %x, length %x\n",
                        Status,
                        IoStatus.Information
                        ));
        ObDereferenceObject (FileObject);
//      NtClose (DeviceHandle);
        ZwClose (DeviceHandle);
        goto Done;
    }

    DumpStack->PointersLength = (ULONG) IoStatus.Information;

    //
    
// If the driver returned a pointer to a device object, that is the
    
// object for the dump driver  (non-scsi case)
    
//

    DeviceObject = (PDEVICE_OBJECT) DumpPointers->DeviceObject;
    if (DeviceObject) {
        DriverObject = DeviceObject->DriverObject;

        //
        
// Loop through the name of the driver looking for the end of the name,
        
// which is the name of the dump image.
        
//

        DumpName = DriverObject->DriverName.Buffer;
        while ( NameOffset = wcsstr( DumpName, L"\\" )) {
            DumpName = ++NameOffset;
        }


        ScsiDump = FALSE;
    }


    //
    
// Release the handle, but keep the reference to the file object as it
    
// will be needed at free dump dump driver time
    
//

    DumpStack->FileObject = FileObject;
    ZwClose (DeviceHandle);

    //
    
// Fill in some DumpInit results
    
//

    DumpInit->Length             = sizeof (INITIALIZATION_CONTEXT);
    DumpInit->StallRoutine       = &KeStallExecutionProcessor;
    DumpInit->AdapterObject      = DumpPointers->AdapterObject;
    DumpInit->MappedRegisterBase = DumpPointers->MappedRegisterBase;
    DumpInit->PortConfiguration  = DumpPointers->DumpData;

    DumpStack->ModulePrefix      = ModulePrefix;
    DumpStack->PartitionOffset   = PartitionInfo.StartingOffset;
    DumpStack->UsageType         = DeviceUsageTypeUndefined;

    //
    
// The minimum common buffer size is IO_DUMP_COMMON_BUFFER_SIZE (compatability)
    
// This is used by the dump driver for SRB extension, CachedExtension, and sense buffer
    
//
    if (DumpPointers->CommonBufferSize < IO_DUMP_COMMON_BUFFER_SIZE) {
        DumpPointers->CommonBufferSize = IO_DUMP_COMMON_BUFFER_SIZE;
    }

    DumpInit->CommonBufferSize    = DumpPointers->CommonBufferSize;

    //
    
// Allocate the required common buffers
    
//

    if (DumpPointers->AllocateCommonBuffers) {
        pa.QuadPart = 0x1000000 - 1;
        for (i=0; i < 2; i++) {
            if (DumpInit->AdapterObject) {

#if !defined(NO_LEGACY_DRIVERS)
                p1 = HalAllocateCommonBuffer(
                    DumpInit->AdapterObject,
                    DumpPointers->CommonBufferSize,
                    &pa,
                    FALSE
                    );
                
#else
                p1 = (*((PDMA_ADAPTER)DumpInit->AdapterObject)->DmaOperations->
                      AllocateCommonBuffer)(
                          (PDMA_ADAPTER)DumpInit->AdapterObject,
                          DumpPointers->CommonBufferSize,
                          &pa,
                          FALSE
                          );
                
#endif // NO_LEGACY_DRIVERS
                        
            }
 else {
                p1 = MmAllocateContiguousMemory (
                        DumpPointers->CommonBufferSize,
                        pa
                        );

                if (!p1) {
                    p1 = MmAllocateNonCachedMemory (DumpPointers->CommonBufferSize);
                }

                pa = MmGetPhysicalAddress(p1);
            }


            if (!p1) {
                IoDebugPrint ((0, "IODUMP: Could not allocate common buffers for dump\n"));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto Done;
            }


            DumpInit->CommonBuffer[i] = p1;
            DumpInit->PhysicalAddress[i] = pa;
        }

    }


    //
    
// Determine whether or not the system booted from SCSI.
    
//

    if (ScsiDump) {

        //
        
// Load the boot disk and port driver to be used by the various
        
// miniports for writing memory to the disk.
        
//

        Status = IopLoadDumpDriver (
                        DumpStack,
                        pDumpDriverName,
                        SCSIPORT_DRIVER_NAME
                        );

        if (!NT_SUCCESS(Status)) {

            IopLogErrorEvent(0,9,STATUS_SUCCESS,IO_DUMP_DRIVER_LOAD_FAILURE,0,NULL,0,NULL);
            goto Done;
        }


        //
        
// The disk and port dump driver has been loaded.  Load the appropriate
        
// miniport driver as well so that the boot device can be accessed.
        
//

        DriverName.Length = 0;
        DriverName.Buffer = (PVOID) Buffer;
        DriverName.MaximumLength = PAGE_SIZE;


        //
        
// The system was booted from SCSI. Get the name of the appropriate
        
// miniport driver and load it.
        
//

        sprintf(Buffer, "\\Device\\ScsiPort%d", ScsiAddress.PortNumber );
        RtlInitAnsiString( &AnsiString, Buffer );
        RtlAnsiStringToUnicodeString( &TempName, &AnsiString, TRUE );
        InitializeObjectAttributes(
                    &ObjectAttributes,
                    &TempName,
                    0,
                    NULL,
                    NULL
                    );

        Status = ZwOpenFile(
                    &DeviceHandle,
                    FILE_READ_ATTRIBUTES,
                    &ObjectAttributes,
                    &IoStatus,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    FILE_NON_DIRECTORY_FILE
                    );

        RtlFreeUnicodeString( &TempName );
        if (!NT_SUCCESS( Status )) {
            IoDebugPrint ((0,
                           "IODUMP: Could not open SCSI port %d, error = %x\n",
                           ScsiAddress.PortNumber,
                           Status
                           ));
            goto Done;
        }


        //
        
// Convert the file handle into a pointer to the device object, and
        
// get the name of the driver from its driver object.
        
//

        ObReferenceObjectByHandle(
                    DeviceHandle,
                    0,
                    IoFileObjectType,
                    KernelMode,
                    (PVOID *) &FileObject,
                    NULL
                    );

        DriverObject = FileObject->DeviceObject->DriverObject;
        ObDereferenceObject( FileObject );
        ZwClose( DeviceHandle );
        //
        
// Loop through the name of the driver looking for the end of the name,
        
// which is the name of the miniport image.
        
//

        DumpName = DriverObject->DriverName.Buffer;
        while ( NameOffset = wcsstr( DumpName, L"\\" )) {
            DumpName = ++NameOffset;
        }

    }


    //
    
// Load the dump driver
    
//

    if (!DumpName) {
        Status = STATUS_NOT_SUPPORTED;
        goto Done;
    }


    swprintf ((PWCHAR) Buffer, L"\\SystemRoot\\System32\\Drivers\\%s.sys", DumpName);
    Status = IopLoadDumpDriver (
                    DumpStack,
                    (PWCHAR) Buffer,
                    NULL
                    );
    if (!NT_SUCCESS(Status)) {

        IopLogErrorEvent(0,10,STATUS_SUCCESS,IO_DUMP_DRIVER_LOAD_FAILURE,0,NULL,0,NULL);
        goto Done;
    }


    //
    
// Claim the file as part of specific device usage path.
    
//

    FileObject = DumpStack->FileObject;
    DeviceObject = IoGetRelatedDeviceObject (FileObject);

    RtlZeroMemory (&irpSp, sizeof (IO_STACK_LOCATION));

    irpSp.MajorFunction = IRP_MJ_PNP;
    irpSp.MinorFunction = IRP_MN_DEVICE_USAGE_NOTIFICATION;
    irpSp.Parameters.UsageNotification.Type = UsageType;
    irpSp.Parameters.UsageNotification.InPath = TRUE;
    irpSp.FileObject = FileObject;

    Status = IopSynchronousCall (DeviceObject, &irpSp, (VOID **) &information);
    ASSERT (0 == information);

    if (!NT_SUCCESS(Status) && IgnoreDeviceUsageFailure) {
        IoDebugPrint ((0,
                       "IopGetDumpStack: DEVICE_USAGE_NOTIFICATION "
                       "Error ignored (%x)\n",
                       Status));
        Status = STATUS_SUCCESS;
    }


    if (NT_SUCCESS(Status)) {
        DumpStack->UsageType         = UsageType;
    }


Done:
    if (NT_SUCCESS(Status)) {
        *pDumpStack = DumpStack;
    }
 else {
        IoFreeDumpStack (DumpStack);
    }

    ExFreePool (Buffer);
    return Status;
}



 
NTSTATUS
IopLoadDumpDriver (
    IN OUT PDUMP_STACK_CONTEXT  DumpStack,
    IN PWCHAR DriverNameString,
    IN PWCHAR NewBaseNameString OPTIONAL
    )
/*++

Routine Description:

    Worker function for IoGetDumpStack to load a particular driver into
    the current DumpStack being created

Arguments:

    DumpStack           - Dump driver stack being built

    DriverNameString    - The string name of the driver to load

    NewBaseNameString   - The modified basename of the driver once loaded

Return Value:

    Status

--
*/

{
    NTSTATUS                Status;
    PDUMP_STACK_IMAGE       DumpImage;
    PLDR_DATA_TABLE_ENTRY   ImageLdrInfo;
    UNICODE_STRING          DriverName;
    UNICODE_STRING          BaseName;
    UNICODE_STRING          Prefix;
    PUNICODE_STRING         LoadBaseName;

    //
    
// Allocate space to track this dump driver
    
//

    DumpImage = ExAllocatePoolWithTag (
                        NonPagedPool,
                        sizeof (DUMP_STACK_IMAGE),
                        'pmuD'
                        );

    if (!DumpImage) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }


    //
    
// Load the system image
    
//

    RtlInitUnicodeString (&DriverName, DriverNameString);
    RtlInitUnicodeString (&Prefix, DumpStack->ModulePrefix);
    LoadBaseName = NULL;
    if (NewBaseNameString) {
        LoadBaseName = &BaseName;
        RtlInitUnicodeString (&BaseName, NewBaseNameString);
        BaseName.MaximumLength = Prefix.Length + BaseName.Length;
        BaseName.Buffer = ExAllocatePoolWithTag (
                            NonPagedPool,
                            BaseName.MaximumLength,
                            'pmuD'
                            );


        if (!BaseName.Buffer) {
            ExFreePool (DumpImage);
            return STATUS_INSUFFICIENT_RESOURCES;
        }


        BaseName.Length = 0;
        RtlAppendUnicodeStringToString (&BaseName, &Prefix);
        RtlAppendUnicodeToString (&BaseName, NewBaseNameString);
    }


    Status = MmLoadAndLockSystemImage(
                &DriverName,
                &Prefix,
                LoadBaseName,
                &DumpImage->Image,
                &DumpImage->ImageBase
                );

    if (NewBaseNameString) {
        ExFreePool (BaseName.Buffer);
    }


    if (!NT_SUCCESS (Status)) {
        IoDebugPrint ((0,
                       "IODUMP: Could not load %wZ; error = %x\n",
                       &DriverName,
                       Status));
        ExFreePool (DumpImage);
        return Status;
    }


    //
    
// Put this driver on the list of drivers to be processed at crash time
    
//

    DumpImage->SizeOfImage = DumpImage->Image->SizeOfImage;
    InsertTailList (&DumpStack->DriverList, &DumpImage->Link);
    return STATUS_SUCCESS;
}


 
ULONG
IopGetDumpControlBlockCheck (
    IN PDUMP_CONTROL_BLOCK  Dcb
    )
/*++

Routine Description:

    Return the current checksum total for the Dcb

Arguments:

    DumpStack           - Dump driver stack to checksum

Return Value:

    Checksum value

--
*/

{
    ULONG                   Check;
    PLIST_ENTRY             Link;
    PDUMP_STACK_IMAGE       DumpImage;
    PMAPPED_ADDRESS         MappedAddress;
    PDUMP_STACK_CONTEXT     DumpStack;


    //
    
// Check the DCB, memory descriptor array, and the FileDescriptorArray
    
//

    Check = PoSimpleCheck(0, Dcb, sizeof(DUMP_CONTROL_BLOCK));
    Check = PoSimpleCheck(
                Check,
                Dcb->MemoryDescriptor,
                Dcb->MemoryDescriptorLength
                );

    Check = PoSimpleCheck(Check, Dcb->FileDescriptorArray, Dcb->FileDescriptorSize);

    DumpStack = Dcb->DumpStack;
    if (DumpStack) {

        //
        
// Include the dump stack context structure, and dump driver images
        
//

        Check = PoSimpleCheck(Check, DumpStack, sizeof(DUMP_STACK_CONTEXT));
        Check = PoSimpleCheck(Check, DumpStack->DumpPointers, DumpStack->PointersLength);

        for (Link = DumpStack->DriverList.Flink;
             Link != &DumpStack->DriverList;
             Link = Link->Flink) {

            DumpImage = CONTAINING_RECORD(Link, DUMP_STACK_IMAGE, Link);
            Check = PoSimpleCheck(Check, DumpImage, sizeof(DUMP_STACK_IMAGE));
            Check = PoSimpleCheck(Check, DumpImage->ImageBase, DumpImage->SizeOfImage);
        }


        //
        
// Include the mapped addresses
        
//
        
// If this is non-null it is treated as a PMAPPED_ADDRESS * (see scsiport and atdisk)
        
//
        if (DumpStack->Init.MappedRegisterBase != NULL) {
            MappedAddress = *(PMAPPED_ADDRESS *)DumpStack->Init.MappedRegisterBase;
        }
 else {
            MappedAddress = NULL;
        }


        while (MappedAddress) {
            Check = PoSimpleCheck (Check, MappedAddress, sizeof(MAPPED_ADDRESS));
            MappedAddress = MappedAddress->NextMappedAddress;
        }

    }


    return Check;
}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 如果我过户了原来的积分怎么办? 英雄联盟安装到了一半卡住了怎么办 微信登录不上怎么办一直在转圈 lol老是忘了放装备技能怎么办 英雄联盟屏幕出现红框锁定了怎么办 钢三开局修改对电脑有用怎么办 我的世界为什么一直黑屏闪退怎么办 苹果6plus玩游戏闪退怎么办 电脑重置开机黑屏了怎么办才好? 龟头有一小块和鱼鳞一样脱皮怎么办 海盗来了赠送碎片密码忘了怎么办 王者荣耀还差几百金币买英雄怎么办 英雄联盟更新后画面突然很卡怎么办 苹果手机微信登陆没反应怎么办 谷歌商店注册短信一直验证怎么办 英雄联盟开游戏退出来进不去怎么办 忘记了路由器和网关的密码怎么办 逆战无尽塔防71关没怪了怎么办 看香的师傅要钱特别多怎么办 电商企业有收入支出没发票怎么办 洗衣液没稀释把衣服染褪色了怎么办 衣服被洗衣液洗褪色了怎么办 b站不小心点了差评怎么办 c盘文件目录损坏且无法读取怎么办 打印发票时发票上的字体变大怎么办 淘宝店铺食品违法遇到打假人怎么办 搜狗输入法说我没有权限安装怎么办 申请移民美国期间护照到期了怎么办 自己申请的qq号账号忘了怎么办 苹果手机下完游戏找不到在哪怎么办 苹果四下游戏的密码忘了怎么办 qq斗地主老自动发消息怎么办 微信小程序斗地主被限制了怎么办 台式电脑玩斗地主总黑屏怎么办 玩斗地主屏幕出现一半玩不了怎么办 电脑qq文件破损或部分丢失怎么办 华为平板电脑开机密码忘记了怎么办 微信被太多人投诉被限制登录怎么办 微信账号被永久封号里面的钱怎么办 乱世王者领礼包时账号异常怎么办 qq填写资料见证号格式错误怎么办