Code Example: A WinDbg Extension

< BACK  NEXT >
[oR]

This example shows how to write a simple WinDbg extension DLL. The code is contained on the accompanying CD and on the book's web site: http://www.W2KDriverBook.com. The purpose of the extension is to provide one command: !devext that formats and displays the driver's Device Extension data structure.

DBG.C

All the code for this extension resides in a single source file. Of course, the file #includes other files, but they are sourced from elsewhere, such as the driver.

HEADER

This part of the code contains the definitions for the extension DLL.

 // The ordering of #include files is important #include <ntddk.h> #include <windef.h> // The following items are from WINBASE.H // in the Win32 SDK. (WINBASE.H itself can't // coexist with NTDDK.H, yet we need to be // able to get at DDK and driver-defined data // structures and types.) #define LMEM_FIXED          0x0000 #define LMEM_MOVEABLE       0x0002 #define LMEM_NOCOMPACT      0x0010 #define LMEM_NODISCARD      0x0020 #define LMEM_ZEROINIT       0x0040 #define LMEM_MODIFY         0x0080 #define LMEM_DISCARDABLE    0x0F00 #define LMEM_VALID_FLAGS    0x0F72 #define LMEM_INVALID_HANDLE 0x8000 #define LPTR (LMEM_FIXED | LMEM_ZEROINIT) #define WINBASEAPI WINBASEAPI HLOCAL WINAPI LocalAlloc(     UINT uFlags,     UINT uBytes     );      WINBASEAPI HLOCAL WINAPI LocalFree(     HLOCAL hMem     );      #define CopyMemory RtlCopyMemory #define FillMemory RtlFillMemory #define ZeroMemory RtlZeroMemory // Now we can bring in the WINDBG extension // definitions... #include <wdbgexts.h> // Other header files... #include <stdlib.h> #include <string.h> // Driver-specific header file... #include ..\driver\xxdriver.h 
GLOBALS

These global variables are necessary for the proper operation of the extension library.

 // Structure passed back from ExtensionApiVersion static EXT_API_VERSION      ApiVersion = { 3, 5, EXT_API_VERSION_NUMBER, 0 };       // Holds callback function table from WinDbgExtensionDllInit static WINDBG_EXTENSION_APIS ExtensionApis; // Holds Windows 2000 build info - Major & Minor numbers static USHORT SavedMajorVersion; static USHORT SavedMinorVersion; 
REQUIRED FUNCTIONS

These functions perform the required initialization interaction with WinDbg.

 VOID WinDbgExtensionDllInit(     PWINDBG_EXTENSION_APIS lpExtensionApis,     USHORT MajorVersion,     USHORT MinorVersion     ) {     // Save pointer to the table of utility     // functions provided by WinDbg     ExtensionApis = *lpExtensionApis;          // Save information about the version of     // NT that's being debugged    SavedMajorVersion = MajorVersion;    SavedMinorVersion = MinorVersion;        return; } VOID CheckVersion( VOID ) {    // Your version-checking code goes here    //     dprintf(           CheckVersion called... [%1x;%d]\n,           SavedMajorVersion,           SavedMinorVersion           ); } LPEXT_API_VERSION ExtensionApiVersion( VOID ) {         return &ApiVersion; } 
COMMAND ROUTINES

The one command supported by this sample DLL prints the contents of the Device Extension for an associated driver. It illustrates how to access memory on the system being debugged.

 DECLARE_API(devext) {      DWORD dwBytesRead;      DWORD dwAddress;            PDEVICE_OBJECT pDevObj;      PDEVICE_EXTENSION pDevExt;            // Get memory for Device object buffer      if(( pDevObj = (PDEVICE_OBJECT) malloc (                sizeof( DEVICE_OBJECT ))) == NULL )      {           dprintf( "Can't allocate buffer.\n" );           return;      }            // Get address of Device object from command line      dwAddress = GetExpression( args );      if( !ReadMemory(                dwAddress,                pDevObj,                sizeof( DEVICE_OBJECT ),                &dwBytesRead ))     {          dprintf( "Can't get Device object.\n ");          free( pDevObj );          return;     }          // Get memory for Device Extension buffer     if( (pDevExt = (PDEVICE_OBJECT) malloc (                sizeof( DEVICE_EXTENSION ))) == NULL )     {          dprintf( "Can't allocate buffer.\n" );          free( pDevObj );          return;     }     // Use Device object to get Device Extension     if( !ReadMemory(               (DWORD)pDevObj->DeviceExtension,               pDevExt,               sizeof( DEVICE_EXTENSION ),               &dwBytesRead ))     {         dprintf( "Can't get Device Extension.\n ");         free( pDevExt );         free( pDevObj );         return;     }          // Print out interesting values     dprintf(           "BytesRequested: %d\n"           "BytesRemaining: %d\n"           "TimeoutCounter: %d\n"           "DeviceObject: %8x\n",           pDevExt->BytesRequested,           pDevExt->BytesRemaining,           pDevExt->TimeoutCounter,           pDevExt->DeviceObject           );                // Clean up and go     free( pDevExt );     free( pDevObj ); } 
SAMPLE OUTPUT

Here is a sample of the output produced by the DBG extension DLL.

 > !load dbg       ; dbg.DLL must be in the standard DLL ;path for Windows 2000 Debugger extension library [dbg] loaded > !devext ff58bc40 CheckVersion called... [f;2195] BytesRequested: 0 BytesRemaining: 0 TimeoutCounter: 0 DeviceObject: ff58bc40 > !unload dbg > Extension DLL dbg unloaded 
< BACK  NEXT >


The Windows 2000 Device Driver Book(c) A Guide for Programmers
The Windows 2000 Device Driver Book: A Guide for Programmers (2nd Edition)
ISBN: 0130204315
EAN: 2147483647
Year: 2000
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net