How can I tell whether a file is on a removable drive, a fixed drive, or a remote drive?

Raymond Chen

Raymond

With the introduction of junctions, symbolic links, and volume mount points, it is no longer the case that a drive letter corresponds to a drive. You can mount multiple drives into a single drive letter, you can have drives with no drive letter, you can have symbolic links and junctions that graft directory trees into each other in pecular ways, possibly resulting in infinitely recursive directory trees.

You can ask the kernel to dig through the whole mess and provide the volume root for a path. You can then use this volume root for other volume queries.

Remember, Little Programs take shortcuts so as to focus on the algorithm. They do little to no boundary checking.

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

int _wmain(int argc, wchar_t** argv)
{
    wchar_t buffer[1024];
    if (GetVolumePathNameW(argv[1], buffer, 1024)) {
        printf("path = %ls, type = %d\n", buffer, GetDriveType(buffer));
    } else {
        printf("failed %d\n", GetLastError());
    }
    return 0;
}

The program takes the path from the command line and first asks the kernel to identify the volume path name for the thing the path refers to. This will navigate through all the mount points, junctions, soft links, you name it, and tell you which volume is responsible for that path.

That volume root can then be passed to the Get­Drive­Type function in order to identify what kind of volume it is.

More generally, you can pass the volume path to Get­Volume­Information in order to obtain information about the volume.

Note that this tells you the information as far as the volume manager is concerned, but there are other layers of weirdness that come into play. For example, you may have a local virtual drive that was mounted from a VHD stored on a network server, or a local virtual drive that is mounted from an iSCSI drive. These report themselves as local even though the physical storage is remote. Conversely, you can use the loopback adapter to connect to the local machine (\\127.0.0.1\sharename), and it will report as remote even though it is physically local.

Raymond Chen
Raymond Chen

Follow Raymond