Listing 2: wdjext.h Header file for building debugger extensions
// Include file for WinDbg kernel debugger extensions. // Note that you will typically NOT want to simply include // <wdbgexts.h> in your projects because of dependancies // on some Windows definitions. Include this file instead. // #ifndef _wdjEXTS_H #define _wdjEXTS_H // Include global DDK header #include <ntddk.h> // Include base definitions required by WDBGEXTS.H #include <windef.h> // Some definitions from <winbase.h> that <wdbgexts.h> depends on #define WINBASEAPI DECLSPEC_IMPORT WINBASEAPI HLOCAL WINAPI LocalAlloc(UINT uFlags, UINT uBytes); WINBASEAPI HLOCAL WINAPI LocalFree(HLOCAL hMem); #define LMEM_FIXED 0x0000 #define LMEM_ZEROINIT 0x0040 #define LPTR (LMEM_FIXED | LMEM_ZEROINIT) #define CopyMemory RtlCopyMemory #define ZeroMemory RtlZeroMemory // Include <wdbgexts.h> itself #include <wdbgexts.h> // The following four variables are defined in wdjexts.c extern WINDBG_EXTENSION_APIS ExtensionApis; extern USHORT MjVersion; extern USHORT MnVersion; extern EXT_API_VERSION Version; // The following structures are taken from the source file // ddk\src\krnldbg\kdapis\windbgkd.h. That file could be included // here, but it's hard to specify on the INCLUDE path. // // KPROCESSOR_STATE is the structure of memory accessible with the // ReadControlSpace() API. DBGKD_GET_VERSION is the structure // returned by the IG_GET_KERNEL_VERSION Ioctl(). typedef struct _DESCRIPTOR { WORD Pad; WORD Limit; DWORD Base; } KDESCRIPTOR, *PKDESCRIPTOR; typedef struct _KSPECIAL_REGISTERS { DWORD Cr0; DWORD Cr2; DWORD Cr3; DWORD Cr4; DWORD KernelDr0; DWORD KernelDr1; DWORD KernelDr2; DWORD KernelDr3; DWORD KernelDr6; DWORD KernelDr7; KDESCRIPTOR Gdtr; KDESCRIPTOR Idtr; WORD Tr; WORD Ldtr; DWORD Reserved[6]; } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; typedef struct _KPROCESSOR_STATE { struct _CONTEXT ContextFrame; struct _KSPECIAL_REGISTERS SpecialRegisters; } KPROCESSOR_STATE, *PKPROCESSOR_STATE; typedef struct _DBGKD_GET_VERSION { WORD MajorVersion; // 0xF == Free, 0xC == Checked WORD MinorVersion; // 1381 for NT4.0, 1057 for NT3.51 WORD ProtocolVersion; WORD Flags; // DBGKD_VERS_FLAG_XXX DWORD KernBase; // load address of ntoskrnl.exe DWORD PsLoadedModuleList; WORD MachineType; WORD ThCallbackStack; WORD NextCallback; WORD FramePointer; DWORD KiCallUserMode; DWORD KeUserCallbackDispatcher; DWORD BreakpointWithStatus; DWORD Reserved4; } DBGKD_GET_VERSION, *PDBGKD_GET_VERSION; #define DBGKD_VERS_FLAG_MP 0x0001 // wdjGetContext() and wdjGetSpecialRegisters() provide access // to the information held in control space. __inline VOID wdjGetContext(USHORT Processor, PCONTEXT Context) { // Read the CONTEXT out of control space. ReadControlSpace( Processor, FIELD_OFFSET(KPROCESSOR_STATE, ContextFrame), Context, sizeof(CONTEXT) ); } __inline VOID wdjGetSpecialRegisters( USHORT Processor, PKSPECIAL_REGISTERS Registers) { // Read the KSPECIAL_REGISTERS out of control space. ReadControlSpace( Processor, FIELD_OFFSET(KPROCESSOR_STATE, SpecialRegisters), Registers, sizeof(KSPECIAL_REGISTERS) ); } #if EXT_API_VERSION_NUMBER >= 5 // IG_GET_KERNEL_VERSION is not defined in the version // of WDBGEXTS.H that shipped with VC++ 5.0. __inline ULONG wdjGetKernelVersion(PDBGKD_GET_VERSION VersionInfo) { return Ioctl(IG_GET_KERNEL_VERSION, &VersionInfo, sizeof(DBGKD_GET_VERSION) ); } #endif __inline VOID wdjWriteControlSpace(USHORT processor, ULONG address, PVOID buf, ULONG size) { PREADCONTROLSPACE prc; prc = (PREADCONTROLSPACE)LocalAlloc(LPTR, sizeof(*prc) + size); CopyMemory( prc->Buf, buf, size ); prc->Processor = processor; prc->Address = (ULONG)address; prc->BufLen = size; Ioctl(IG_WRITE_CONTROL_SPACE, (PVOID)prc, sizeof(*prc) + size); LocalFree( prc ); } #endif // _wdjEXT_H //End of File