#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