4.3.3.3  Sample Print Macros

In addition to the ASSERT macros, a number of the sample kernel-mode drivers define a print macro that uses a global debugging-level variable to control the level of interaction with WinDbg. The macros differ for different drivers, but they have a number of features in common:

·As with the ASSERT macros, these macros are conditionally compiled.

·Each macro’s arguments include the message to print and a level parameter that indicates the severity of the error.

·The level parameter and the global debugging level determine the action taken by the macro. The actions range from doing nothing, to printing the message string, to executing an ASSERT macro.

For example, the ATDISK driver defines an AtDebugLevel global variable whose default value is 0, and it defines an AtDump macro as follows:

#if DBG

extern ULONG AtDebugLevel;

#define ATBUGCHECK      ((ULONG)0x80000000)

#define ATDIAG1       ((ULONG)0x00000001)

#define ATDIAG2       ((ULONG)0x00000002)

#define ATERRORS       ((ULONG)0x00000004)

#define ATINIT        ((ULONG)0x00000008)

#define AtDump(LEVEL,STRING) \

  do { \

    ULONG _level = (LEVEL); \

    if (AtDebugLevel & _level) { \

      DbgPrint STRING; \

    } \

    if (_level == ATBUGCHECK) { \

      ASSERT(FALSE); \

    } \

  } while (0)

#else

#define AtDump(LEVEL,STRING) do {NOTHING;} while (0)

#endif

 

Using this macro, you could insert statements like the following into your code:

if (SomeVariable == -1)

AtDump(ATERRORS, ("Bad value for SomeVariable") );

 

If AtDebugLevel is 0, the message is not displayed. To enable the display of certain levels of error messages, you can assign a hard-coded value to AtDebugLevel and recompile. To set the variable at run time, you can use the ed command of WinDbg to modify the value of AtDebugLevel or have the driver obtain the debugging-level from a registry parameter for the driver.