You can use GetLogicalDriveStrings - this returns a buffer containing all valid drive letters on the system.
UPDATE:
Here is sample program I wrote that enumerates the drives using GetLogicalDriveStrings and outputs some basic information about them.
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
int __cdecl main()
{
DWORD cchBuffer;
WCHAR* driveStrings;
UINT driveType;
PWSTR driveTypeString;
ULARGE_INTEGER freeSpace;
// Find out how big a buffer we need
cchBuffer = GetLogicalDriveStrings(0, NULL);
driveStrings = (WCHAR*)malloc((cchBuffer + 1) * sizeof(TCHAR));
// Fetch all drive strings
GetLogicalDriveStrings(cchBuffer, driveStrings);
// Loop until we find the final '\0'
// driveStrings is a double null terminated list of null terminated strings)
while (*driveStrings)
{
// Dump drive information
driveType = GetDriveType(driveStrings);
GetDiskFreeSpaceEx(driveStrings, &freeSpace, NULL, NULL);
switch (driveType)
{
case DRIVE_FIXED:
driveTypeString = L"Hard disk";
break;
case DRIVE_CDROM:
driveTypeString = L"CD/DVD";
break;
case DRIVE_REMOVABLE:
driveTypeString = L"Removable";
break;
case DRIVE_REMOTE:
driveTypeString = L"Network";
break;
default:
driveTypeString = L"Unknown";
break;
}
printf("%S - %S - %I64u GB free\n", driveStrings, driveTypeString,
freeSpace.QuadPart / 1024 / 1024 / 1024);
// Move to next drive string
// +1 is to move past the null at the end of the string.
driveStrings += lstrlen(driveStrings) + 1;
}
return 0;
}
On my machine this outputs:
C:\ - Hard disk - 181 GB free
D:\ - CD/DVD - 0 GB free
E:\ - Hard disk - 806 GB free