Displaying Volume Path Names

The following example displays the various path names for the specified volume.

#include <windows.h>
#include <stdio.h>

VOID
DisplayVolumePathNames(
    __in PWCHAR VolumeName
    )
{
    DWORD  Chars   = 0;
    DWORD  Error   = ERROR_SUCCESS;
    PWCHAR Names   = NULL;
    PWCHAR NameIdx = NULL;
    BOOL   Status  = FALSE;

    Chars = MAX_PATH + 1;

    for (;;) 
    {
        //
        // Allocate a buffer to hold the path names
        //
        Names = (PWCHAR) new BYTE [Chars * sizeof(WCHAR)];

        if (!Names) 
        {
            Error = ERROR_NO_SYSTEM_RESOURCES;
            goto Cleanup;
        }

        //
        // Obtain all of the path
        // names  for this volume
        //
        Status = GetVolumePathNamesForVolumeNameW(VolumeName, Names, Chars, &Chars);

        if (Status) 
        {
            break;
        }

        Error = GetLastError();

        if (Error != ERROR_MORE_DATA) 
        {
            goto Cleanup;
        }

        //
        // Try again with the
        // new suggested size
        //
        delete [] Names;
        Names = NULL;

        Error = ERROR_SUCCESS;
    }

    //
    // Display the various path names
    //
    for (NameIdx = Names; NameIdx[0] != L'\0'; NameIdx += wcslen(NameIdx) + 1) 
    {
        wprintf(L"    %s\n", NameIdx);
    }

Cleanup:

    if (Names) 
    {
        delete [] Names;
        Names = NULL;
    }

    return;
}


VOID
__cdecl wmain(
    __in int argc,
    __in PWCHAR argv[]
    )
{
    DWORD  Chars                = 0;
    WCHAR  DeviceName[MAX_PATH] = L"";
    DWORD  Error                = ERROR_SUCCESS;
    HANDLE FindHandle           = INVALID_HANDLE_VALUE;
    BOOL   Found                = FALSE;
    DWORD  Index                = 0;
    BOOL   Status               = FALSE;
    WCHAR  VolumeName[MAX_PATH] = L"";

    //
    // Ensure that all parameters are present
    //
    if (argc != 2 || ((argv[1][0] == L'-' || argv[1][0] == L'/') &&
                       argv[1][1] == L'?')) 
    {
        wprintf(L"\nDisplays path names for the specified volume.\n");
        wprintf(L"\n\t%s [device name]\n\n", argv[0]);
        wprintf(L"For example, %s \\Device\\HarddiskVolume1\n", argv[0]);
        goto Cleanup;
    }

    //
    // Enumerate all volumes in the system
    //
    FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));

    if (FindHandle == INVALID_HANDLE_VALUE)
    {
        Error = GetLastError();
        wprintf(L"FindFirstVolumeW failed with error code %d\n", Error);
        goto Cleanup;
    }

    for (;;)
    {
        //
        // Skip the \\?\ prefix and remove the trailing backslash
        //
        Index = wcslen(VolumeName) - 1;

        if (VolumeName[0]     != L'\\' ||
            VolumeName[1]     != L'\\' ||
            VolumeName[2]     != L'?'  ||
            VolumeName[3]     != L'\\' ||
            VolumeName[Index] != L'\\') 
        {
            Error = ERROR_BAD_PATHNAME;
            wprintf(L"FindFirstVolumeW/FindNextVolumeW returned a bad path: %s\n", VolumeName);
            goto Cleanup;
        }

        VolumeName[Index] = L'\0';

        Chars = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName)); 

        VolumeName[Index] = L'\\';

        if (!Chars) 
        {
            Error = GetLastError();
            wprintf(L"QueryDosDeviceW failed with error code %d\n", Error);
            goto Cleanup;
        }

        if (!_wcsicmp(DeviceName, argv[1])) 
        {
            Found = TRUE;
            break;
        }

        //
        // Move on to the next
        //
        Status = FindNextVolumeW(FindHandle, VolumeName, ARRAYSIZE(VolumeName));

        if (!Status) 
        {
            Error = GetLastError();

            if (Error != ERROR_NO_MORE_FILES) 
            {
                wprintf(L"FindNextVolumeW failed with error code %d\n", Error);

                goto Cleanup;
            }

            //
            // We've finished iterating
            // through all  the volumes
            //
            Error = ERROR_SUCCESS;
            break;
        }
    }

    FindVolumeClose(FindHandle);
    FindHandle = INVALID_HANDLE_VALUE;

    if (!Found) 
    {
        wprintf(L"\nThe specified device name was not found\n");
        goto Cleanup;
    }

    wprintf(L"\nThe specified device name maps to:\n\n");
    wprintf(L"%s\n", VolumeName);

    //
    // Display any additional information about this volume
    //
    DisplayVolumePathNames(VolumeName);

Cleanup:

    if (FindHandle != INVALID_HANDLE_VALUE) 
    {
        FindVolumeClose(FindHandle);
        FindHandle = INVALID_HANDLE_VALUE;
    }

    return;
}

The following is an example command line used to run the example code.

volpaths \Device\HarddiskVolume1

The following is example output from running the previous command.

The specified device name maps to:

\\?\Volume{0611c52f-3ec9-11dc-9e1a-806e6f6e6963}\
    C:\

See Also

FindFirstVolume
FindNextVolume
FindVolumeClose
GetVolumePathNamesForVolumeName
QueryDosDevice

Send comments about this topic to Microsoft

Build date: 3/20/2008