How can I get all the physical drive paths (\\.\PhysicalDriveX) on a Windows computer, with C/C++?
The answers in this question suggest getting the logical drive letter, and then getting the physical drive corresponding to that mounted drive. The problem is, I want to get all
physical drives connected to the computer, including drives that are not mounted.
Other answers suggest incrementing a value from 0-15 and checking if a drive exists there (\\.\PhysicalDrive0, \\.\PhysicalDrive1, ...) or calling WMIC to list all the drives.[
As these seem like they would work, they seem like they are not the best approach to be taking. Is there not a simple function such as GetPhysicalDrives
that simply returns a vector of std::string
's containing the paths of all the physical drives?
You can use QueryDosDevice
. Based on the description, you'd expect this to list things like C:
and D:
, but it will also lists things like PhysicalDrive0
, PhysicalDrive1
and so on.
The major shortcoming is that it will also list a lot of other device names you probably don't care about, so (for example) on my machine, I get a list of almost 600 device names, of which only a fairly small percentage is related to what you care about.
Just in case you care, some (old) sample code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
int main(int argc, char **argv) {
char physical[65536];
char logical[65536];
if ( argc > 1) {
for (int i=1; i<argc; i++) {
QueryDosDevice(argv[i],logical, sizeof(logical));
std::cout << argv[i] << " : \t" << logical << std::endl << std::endl;
}
return 0;
}
QueryDosDevice(NULL, physical, sizeof(physical));
std::cout << "devices: " << std::endl;
for (char *pos = physical; *pos; pos+=strlen(pos)+1) {
QueryDosDevice(pos, logical, sizeof(logical));
std::cout << pos << " : \t" << logical << std::endl << std::endl;
}
return 0;
}
However, if I run this like `devlist | grep "^Physical", it lists the physical drives.