GetProcessImageFileName/QueryDosDevice trivia

If you’ve ever used GetProcessImageFileName, you’d have been a little stunned to see filenames like \Device\HarddiskVolume1\Program Files\Abc.exe – though when you think of it, it’s not all that surprising, because these are the real paths as far as the OS is concerned, all that kiddy-type C-drive, D-drive usage is mere eye-candy for us non-kernel-programmer types. Anyway, you can’t get a DOS drive name directly from this sort of path, instead you’d have to use QueryDosDevice with each drive letter from A to Z and if what it returns matches the path you have, you’ve got your drive letter. Here’s a little copy/paste-able function you can use :-

/*
    lpDevicePath - should be something like "\Device\HarddiskVolume1",
        "\Device\Floppy0" or "\Device\CdRom0"
*/
TCHAR GetDriveLetter(LPCTSTR lpDevicePath)
{
    TCHAR d = _T('A');
    while(d < = _T('Z'))
    {
        TCHAR szDeviceName[3] = {d,_T(':'),_T('\0')};
        TCHAR szTarget[512] = {0};
        if(QueryDosDevice(szDeviceName, szTarget, 511) != 0)
            if(_tcscmp(lpDevicePath, szTarget) == 0)
                return d;
        d++;
    }
    return NULL;
}

10 thoughts on “GetProcessImageFileName/QueryDosDevice trivia

  1. char szTemImageName[512];
    GetModuleFileNameEx(hProcess,NULL, szTemImageName, 512);

    2nd param null, so processpath ….

  2. @Nish: thanks! I translated this snippet to Python using ctypes and it works like a charm:)

    @Chris: for some reason GetModuleFileNameEx is not always working for me… maybe it has something to do with this (from MSDN):

    “If the module list in the target process is not yet initialized, or if the module list changes during the function call as a result of DLLs being loaded or unloaded, GetModuleFileNameEx may fail or return incorrect information. ”

    http://msdn.microsoft.com/en-us/library/ms683198(VS.85).aspx

  3. You can use GetLogicalDriveStrings() instead of looping the from A-Z. This returns the drive letters on the local system.

  4. Thank you, Nish.

    Warning: this code needs some tweaking if you start application from a network drive. If application is started over the network (\\myserver\test.exe) then GetProcessImageFileName returns something like \Device\…\myserver\test.exe, and QueryDosDevice won’t help.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s