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:

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.