Enumerating all available drive letters in Windows
Asked Answered
R

7

21

I want to enumerate all available drive letters (which aren't already taken) in Windows using VC++.

How can I do this?

Remorseless answered 13/11, 2008 at 8:38 Comment(0)
T
18

::GetLogicalDrives() returns a list of available (read: used) drives as bits in a mask. This should include mapped network drives. Thus, you can simply walk the bits to find bits that are zero, meaning no drive is present. If in doubt, you can always call ::GetDriveType() with the drive letter + ":\" (":\\" in C code, or _T(":\\") in Unicode-aware terminology, of course), and that should return DRIVE_UNKNOWN or DRIVE_NO_ROOT_DIR if the drive is available.

Turbulence answered 13/11, 2008 at 8:47 Comment(0)
O
7

GetLogicalDriveStrings can get you just the list of currently used drive letters.

GetVolumeInformation can be used to get more information about a specific drive.

Onitaonlooker answered 13/11, 2008 at 8:45 Comment(0)
B
5
std::vector<std::string> getListOfDrives() {
    std::vector<std::string> arrayOfDrives;
    char* szDrives = new char[MAX_PATH]();
    if (GetLogicalDriveStringsA(MAX_PATH, szDrives));
    for (int i = 0; i < 100; i += 4)
        if (szDrives[i] != (char)0) 
            arrayOfDrives.push_back(std::string{szDrives[i],szDrives[i+1],szDrives[i+2]});
    delete[] szDrives;
    return arrayOfDrives;
}

returns a vector of drives e.g. C:\D:\E:\F:\

std::vector<std::string> drives = getListOfDrives();

for (std::string currentDrive : drives) {
    std::cout << currentDrive << std::endl;
}

enumerateing over them

Bring answered 1/9, 2019 at 19:4 Comment(0)
W
4

The GetLogicalDriveStrings Function is a good starting point.

Weaponless answered 13/11, 2008 at 8:42 Comment(0)
L
3

Im not shure how to enumerate them or if it will compile on visual c++ but I sturm-coded this on Dev C++ or Code Blocks to check what drive is acessible by using CreateFile and what type of drive is by using GetDriveType. Program checks drives from A to Z:

#include <windows.h>
#include <cstring>
#include <sstream>
#include <iostream>

using namespace std;

int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, INT nShowCmd)
{
    HANDLE hDevice = NULL;
    HANDLE fileFind = NULL;
    while(true)
    {
        Sleep(3005);
        char drv='A';
        while(drv!='[')
        {
            Sleep(105);
            const char *charDrvCF;
            const char *charDrv;
            stringstream Str;
            string drvStr;
            Str<<drv;
            Str>>drvStr;
            string drvSpc=drvStr+":\\";
            string fCheck="\\\\.\\";
            string fhCheck=fCheck+drvStr+":";
            charDrvCF=fhCheck.c_str();
            charDrv=drvSpc.c_str();      
            hDevice=CreateFile(charDrvCF,
                                GENERIC_READ|GENERIC_WRITE,
                                FILE_SHARE_READ|FILE_SHARE_WRITE,
                                NULL,
                                OPEN_EXISTING,
                                0,
                                NULL);
            if(hDevice!=INVALID_HANDLE_VALUE)
            {
                switch(GetDriveType(charDrv))
                {
                    case DRIVE_FIXED:
                    {
                        cout<<"Fixed drive detected: "<<charDrv<<endl;
                        break;
                    }
                    case DRIVE_REMOVABLE:
                    {
                        cout<<"Removable drive detected: "<<charDrv<<endl;
                        break;
                    }
                    case DRIVE_NO_ROOT_DIR:
                    {
                        cout<<"There is no volume mounted at the specified path. "<<charDrv<<endl;
                        break;
                    }
                    case DRIVE_REMOTE:
                    {
                        cout<<"The drive is a remote (network) drive. "<<charDrv<<endl;
                        break;
                    }
                    case DRIVE_CDROM:
                    {
                        cout<<"The drive is a CD-ROM drive. "<<charDrv<<endl;
                        break;
                    }
                    case DRIVE_RAMDISK:
                    {
                        cout<<"The drive is a RAM disk. "<<charDrv<<endl;
                        break;
                    }
                    case DRIVE_UNKNOWN:
                    {
                        cout<<"The drive type cannot be determined. "<<charDrv<<endl;
                        break;
                    }
                }
            }
        drv++;
        }
    }
}
Lay answered 1/12, 2012 at 17:15 Comment(0)
P
2

GetLogicalDrives and GetLogicalDriveStrings are not seeing network drives created in a different namespace.

For example calling the functions from a service running under Local System will not see the network drives created by a logged user.

This is happening starting with Windows XP. The following article describes this case: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363908(v=vs.85).aspx

Precede answered 16/7, 2012 at 11:24 Comment(1)
Why does that matter? You can re-use drive letters no matter which other users have defined them, and the question only needed usable unused letters.Rimple
Z
0

The following code will do the job:

for (w_chDrv = 'C'; w_chDrv <= 'Z'; w_chDrv++)
{
    // make root path
    _stprintf_s(w_szRootPath, 3, _T("%c:"), w_chDrv);

    // get driver type
    w_nDriverType = GetDriveType(w_szRootPath);
    if ((w_nDriverType != DRIVE_REMOVABLE) && (w_nDriverType != DRIVE_FIXED))
            continue;
    // if you got here that means w_szRootPath is a valid drive
}
Zsazsa answered 20/8, 2020 at 17:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.