测试代码

#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;
}

白盒测试是一种软件测试方法,它基于对被测试代码的内部结构和实现细节的了解来设计测试用例。在Java中进行白盒测试时,可以通过以下几个方面来介绍: 1. 单元测试:单元测试是白盒测试的一种常见形式,它针对代码中的最小单元(如方法、函数)进行测试。在Java中,可以使用JUnit等单元测试框架来编写和执行单元测试用例。 2. 代码覆盖率:代码覆盖率是衡量白盒测试效果的指标之一,它表示被测试代码中被测试到的部分占总代码量的比例。常见的代码覆盖率指标包括语句覆盖率、分支覆盖率和路径覆盖率等。在Java中,可以使用工具如JaCoCo来计算代码覆盖率。 3. 控制流测试:控制流测试是一种白盒测试技术,它通过测试不同的控制流路径来检测代码中的错误和缺陷。在Java中,可以使用条件语句(如if-else、switch)和循环语句(如for、while)来设计控制流测试用例。 4. 数据流测试:数据流测试是一种白盒测试技术,它关注数据在程序中的传递和处理过程。在Java中,可以通过设计测试用例来覆盖不同的数据流路径,包括变量的定义、赋值、使用和传递等。 5. 异常处理测试:异常处理是Java中的重要特性之一,它可以帮助程序在出现错误或异常情况时进行适当的处理。在白盒测试中,可以设计测试用例来验证代码对各种异常情况的处理是否正确。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值