The QueryDosDevice Explorer

Back To Tips Page

This is a simple program that simply calls the QueryDosDevice API and displays the results.

There are two methods of calling the API. 

A multi-string is a sequence of NUL-terminated strings, where the last string is followed by two NUL characters.

If the input string is empty, I call QueryDosDevice with a NULL parameter (rather than a pointer to an empty string...the API treats these as different cases!) and the output looks like the output belo

Note that the tree elements are expandable.  What I do is call QueryDosDevice on the top-level item and display as a subitem the contents of the multi-string returned.  The code to do this is rather simplistic since the goal was to write this code in a couple hours, and I didn't spend a lot of time writing a fully-general piece of code (I just replicated the code in two subroutines).

If you double-click on a top-level element, that string is copied to the Device field and just the information about that device is retrieved.  The Clear button erases the contents of the Device edit control and will display the complete list.  In the example below, I double-clicked on the I: element.

If a string is typed into the Find edit control, the first matching string after the selection will be searched for.  The search is case-independent and it will find any element that has the string as a substring anywhere in the target string.  Find Next and Find Prev will search for the next or previous element in the list.  The << control moves the selection back to the beginning of the list.

The Expand All button expands all of the elements.  However, note that Find only searches top-level names, not the expanded names.

Note that the dialog is resizable.

Using MultiStrings

First, it is important to understand that multi-strings Do Not Play Well With CString.  Therefore, you will likely end up in Deep Trouble if you use them casually.  When I use a multi-string, I usually have to allocate my own buffer using new.  You can also use smart pointers so you don't have to deal with the issues of freeing a temporary string.

DWORD size = ...determine string buffer size required...;
LPTSTR buffer = new TCHAR[size]; multi-string into buffer
LPTSTR p = buffer;
while(_tcslen(p) > 0)
   { /* has element */
     DoSomething(p);  // DoSomething takes an LPCTSTR
     p += _tcslen(p) + 1;
   } /* has element */

The means of determining the size of the multi-string buffer varies with the API

Dealing with Buffer Too Small

The classic mechanism for dealing with buffers depends on the API.  For some APIs, calling the API with a NULL buffer pointer and a 0 initial length will, either via a DWORD * or as the result of the API, the required length of the buffer.  In other APIs, the length of the buffer is either Big Enough or Too Small.  The QueryDosDevice API simply returns 0 if the buffer is too small (note this is in conflict with its documentation, which appears to be erroneous).  In cases like this, the standard trick is to allocate a buffer of size n and then, if the error code indicates n is too small, doubling the size of n.  For example

DWORD size = 1024;
LPTSTR buffer = NULL;
    { /* issue QueryDosDevice */
     delete buffer;
     buffer = new TCHAR[size];
     DWORD result = ::QueryDosDevice(name, buffer, size);
     if(result == 0)
        { /* error */
          DWORD err = ::GetLastError();
          if(err == ERROR_INSUFFICIENT_BUFFER)
             { /* try again */
              size *= 2;
             } /* try again */
             { /* unrecoverable error */
              return FALSE; // or other action as appropriate
             } /* unrecoverable error
       } /* error */
    } /* issue QueryDosDevice */
 ... use contents of buffer
 delete buffer;
 return TRUE; // or other action as appropriate

    } /* issue QueryDosDevice */

download.gif (1234 bytes)

[Dividing Line Image]

Send mail to with questions or comments about this web site.
Copyright 2008, The Joseph M. Newcomer Co./FlounderCraft Ltd., All Rights Reserved
Last modified: May 14, 2011