197 lines
6.5 KiB
C
197 lines
6.5 KiB
C
|
|
#include "ntiodump.h"
|
|
|
|
//
|
|
// Define the type for a dump control block. This structure is used to
|
|
// describe all of the data, drivers, and memory necessary to dump all of
|
|
// physical memory to the disk after a bugcheck.
|
|
//
|
|
|
|
typedef struct _MINIPORT_NODE {
|
|
LIST_ENTRY ListEntry;
|
|
PKLDR_DATA_TABLE_ENTRY DriverEntry;
|
|
ULONG DriverChecksum;
|
|
} MINIPORT_NODE, *PMINIPORT_NODE;
|
|
|
|
#define IO_TYPE_DCB 0xff
|
|
|
|
#define DCB_DUMP_ENABLED 0x01
|
|
#define DCB_SUMMARY_ENABLED 0x02
|
|
#define DCB_DUMP_HEADER_ENABLED 0x10
|
|
#define DCB_SUMMARY_DUMP_ENABLED 0x20
|
|
#define DCB_TRIAGE_DUMP_ENABLED 0x40
|
|
#define DCB_TRIAGE_DUMP_ACT_UPON_ENABLED 0x80
|
|
|
|
typedef struct _DUMP_CONTROL_BLOCK {
|
|
UCHAR Type;
|
|
CHAR Flags;
|
|
USHORT Size;
|
|
CCHAR NumberProcessors;
|
|
CHAR Reserved;
|
|
USHORT ProcessorArchitecture;
|
|
PDUMP_STACK_CONTEXT DumpStack;
|
|
ULONG MemoryDescriptorLength;
|
|
PLARGE_INTEGER FileDescriptorArray;
|
|
ULONG FileDescriptorSize;
|
|
PULONG HeaderPage;
|
|
PFN_NUMBER HeaderPfn;
|
|
ULONG MajorVersion;
|
|
ULONG MinorVersion;
|
|
ULONG BuildNumber;
|
|
CHAR VersionUser[32];
|
|
ULONG HeaderSize; // Size of dump header includes summary dump.
|
|
LARGE_INTEGER DumpFileSize; // Size of dump file.
|
|
ULONG TriageDumpFlags; // Flags for triage dump.
|
|
PUCHAR TriageDumpBuffer; // Buffer for triage dump.
|
|
ULONG TriageDumpBufferSize; // Size of triage dump buffer.
|
|
} DUMP_CONTROL_BLOCK, *PDUMP_CONTROL_BLOCK;
|
|
|
|
//
|
|
// Processor specific macros.
|
|
//
|
|
|
|
#if defined(_AMD64_)
|
|
|
|
#define PROGRAM_COUNTER(_context) ((ULONG_PTR)(_context)->Rip)
|
|
#define STACK_POINTER(_context) ((ULONG_PTR)(_context)->Rsp)
|
|
#define CURRENT_IMAGE_TYPE() IMAGE_FILE_MACHINE_I386
|
|
#define PaeEnabled() TRUE
|
|
|
|
#elif defined(_X86_)
|
|
|
|
#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))) )
|
|
|
|
#define CRASHDUMP_ERROR DPFLTR_ERROR_LEVEL
|
|
#define CRASHDUMP_WARNING DPFLTR_WARNING_LEVEL
|
|
#define CRASHDUMP_TRACE DPFLTR_TRACE_LEVEL
|
|
#define CRASHDUMP_INFO DPFLTR_INFO_LEVEL
|
|
#define CRASHDUMP_VERBOSE (DPFLTR_INFO_LEVEL + 100)
|
|
|
|
ULONG
|
|
IopGetDumpControlBlockCheck (
|
|
IN PDUMP_CONTROL_BLOCK Dcb
|
|
);
|
|
|
|
|
|
//
|
|
// The remainder of this file verifies that the DUMP_HEADER32, DUMP_HEADER64,
|
|
// MEMORY_DUMP32 and MEMORY_DUMP64 structures have been defined correctly.
|
|
// If you die on one of the asserts, it means you changed on of the crashdump
|
|
// structures without knowing how it affected the rest of the system.
|
|
//
|
|
|
|
//
|
|
// Define dump header longword offset constants. Note: these constants are
|
|
// should no longer be used in accessing the fields. Use the MEMORY_DUMP32
|
|
// and MEMORY_DUMP64 structures instead.
|
|
//
|
|
|
|
#define DHP_PHYSICAL_MEMORY_BLOCK (25)
|
|
#define DHP_CONTEXT_RECORD (200)
|
|
#define DHP_EXCEPTION_RECORD (500)
|
|
#define DHP_DUMP_TYPE (994)
|
|
#define DHP_REQUIRED_DUMP_SPACE (1000)
|
|
#define DHP_CRASH_DUMP_TIMESTAMP (1008)
|
|
#define DHP_SUMMARY_DUMP_RECORD (1024)
|
|
|
|
|
|
//
|
|
// Validate the MEMORY_DUMP32 structure.
|
|
//
|
|
|
|
C_ASSERT ( FIELD_OFFSET (DUMP_HEADER32, PhysicalMemoryBlock) == DHP_PHYSICAL_MEMORY_BLOCK * 4);
|
|
C_ASSERT ( FIELD_OFFSET (DUMP_HEADER32, ContextRecord) == DHP_CONTEXT_RECORD * 4);
|
|
C_ASSERT ( FIELD_OFFSET (DUMP_HEADER32, Exception) == DHP_EXCEPTION_RECORD * 4);
|
|
C_ASSERT ( FIELD_OFFSET (DUMP_HEADER32, DumpType) == DHP_DUMP_TYPE * 4 );
|
|
C_ASSERT ( FIELD_OFFSET (DUMP_HEADER32, RequiredDumpSpace) == DHP_REQUIRED_DUMP_SPACE * 4);
|
|
C_ASSERT ( FIELD_OFFSET (DUMP_HEADER32, SystemTime) == DHP_CRASH_DUMP_TIMESTAMP * 4);
|
|
C_ASSERT ( sizeof (DUMP_HEADER32) == 4096 );
|
|
C_ASSERT ( FIELD_OFFSET (MEMORY_DUMP32, Summary) == 4096);
|
|
|
|
//
|
|
// Verify that the PHYSICAL_MEMORY_RUN and PHYSICAL_MEMORY_DESCRIPTOR
|
|
// structs match up.
|
|
//
|
|
|
|
|
|
#if !defined (_WIN64)
|
|
|
|
C_ASSERT ( sizeof (PHYSICAL_MEMORY_RUN) == sizeof (PHYSICAL_MEMORY_RUN32) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_RUN, BasePage) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_RUN32, BasePage) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_RUN, PageCount) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_RUN32, PageCount) );
|
|
|
|
|
|
C_ASSERT ( sizeof (PHYSICAL_MEMORY_DESCRIPTOR) == sizeof (PHYSICAL_MEMORY_DESCRIPTOR) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR, NumberOfRuns) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR32, NumberOfRuns) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR, NumberOfPages) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR32, NumberOfPages) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR, Run) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR32, Run) );
|
|
|
|
#else // IA64
|
|
|
|
C_ASSERT ( sizeof (PHYSICAL_MEMORY_RUN) == sizeof (PHYSICAL_MEMORY_RUN64) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_RUN, BasePage) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_RUN64, BasePage) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_RUN, PageCount) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_RUN64, PageCount) );
|
|
|
|
|
|
C_ASSERT ( sizeof (PHYSICAL_MEMORY_DESCRIPTOR) == sizeof (PHYSICAL_MEMORY_DESCRIPTOR) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR, NumberOfRuns) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR64, NumberOfRuns) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR, NumberOfPages) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR64, NumberOfPages) &&
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR, Run) ==
|
|
FIELD_OFFSET (PHYSICAL_MEMORY_DESCRIPTOR64, Run) );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//
|
|
// Verify we have enough room for the CONTEXT record.
|
|
//
|
|
|
|
C_ASSERT (sizeof (CONTEXT) <= sizeof ((PDUMP_HEADER)NULL)->ContextRecord);
|
|
|
|
#if defined(_AMD64_)
|
|
C_ASSERT (sizeof (DUMP_HEADER) == (2 * PAGE_SIZE));
|
|
#else
|
|
C_ASSERT (sizeof (DUMP_HEADER) == PAGE_SIZE);
|
|
#endif
|