Debugger commands (!error, .enable_long_status) that makes my life easier

One thing you learn very quickly when writing a driver is that NTSTATUS is used almost everywhere. The consistency is nice, especially compared to user mode where errors can be an HRESULT, LONG, or DWORD (yes they are all the same underlying type, but they have different meanings, particularly for success/failure checks). The problem with any error value that is returned is that you must figure out where it came from and what the value maps to in terms of description and error name.

The first simple tool I use is the .enable_long_status command. By default, all long integers are displayed in decimal, but for some error encoding systems, you want hex instead. In this example, status is an NTSTATUS which is set to STATUS_UNSUCCESSFUL. This works for HRESULT as well since all we are doing is changing the format of the number.

 
0:000> dt status
status = -1073741823
0:000> .enable_long_status 1
0:000> dt status
status = 0xC0000001

I found !error awhile ago and I just refered to it in a comment on another post, so I thought it was a good time to talk about it. !error takes an error value and returns the description for it. As a bonus, it works for win32 error codes as well as NTSTATUS values. Here is the description from the docs:

 Syntax
!error Value [Flags]

Parameters:
Value  Specifies one of the following error codes:
         Win32
         Winsock
         NTSTATUS
         NetAPI

Flags If Flags is set to 1, then the error code is read as an NTSTATUS code. 

And this is what the output looks like for various values:

 Dump out the value as Win32
0:000>  !error 1 
Error code: (Win32) 0x1 (1) - Incorrect function.

Dump out the value as NTSTATUS
0:000> !error 1 1
Error code: (NTSTATUS) 0x1 - STATUS_WAIT_1

Dump out an NTSTATUS value that is not ambiguous with a Win32 value
0:000> !error c0000001
Error code: (NTSTATUS) 0xc0000001 (3221225473) - {Operation Failed}  The requested operation was unsuccessful.

There are others tools and commands that you can use to get error descriptions:

  • net helpmsg
  • WPP format specifiers, %!STATUS! for NTSTATUS. I am sure there are other specifiers for other types as well (I just don't know them offhand).
  • FormatMessage() in user mode
  • Visual Studio will do some automatic interpretation for you. IIRC, in a watch window you can apped ",err" or ",hr" to the variable name to get better error info.
  • ...and I am sure there others...