How to list physical disks in Windows?
In order to obtain a list of "\\\\.\PhysicalDrive0"
available.
15 Answers
WMIC
wmic
is a very complete tool
wmic diskdrive list
provide a (too much) detailed list, for instance
for less info
wmic diskdrive list brief
#C Sebastian Godelet mentions in the comments:
In C:
system("wmic diskdrive list");
As commented, you can also call the WinAPI, but... as shown in "How to obtain data from WMI using a C Application?", this is quite complex (and generally done with C++, not C).
PowerShell
Or with PowerShell:
Get-WmiObject Win32_DiskDrive
Update Feb. 2022, Microsoft announces in "Windows 10 features we're no longer developing"
The WMIC tool is deprecated in Windows 10, version 21H1 and the 21H1 General Availability Channel release of Windows Server.
This tool is superseded by Windows PowerShell for WMI.
Note: This deprecation only applies to the command-line management tool. WMI itself is not affected.
-
16-1 Does not answer the question, which is asking for how to do it in C. – unixman83 Feb 16 '12 at 13:26
-
13+1 Does not answer the question, but it is a very useful piece of information :-) – Grodriguez Jul 27 '12 at 07:53
-
8you could do a `system("wmic diskdrive list");` in C – Sebastian Nov 21 '12 at 13:28
-
You can also use WMI via WinApi, not just calling wmic app. – Alex P. Jan 22 '19 at 21:30
-
Win32_DiskDrive does not list a physical disk when software raid or StorageSpaces enabled. Original physical disks got filtered out. Easy to compare with PowerShell Get-PhysicalDisk – Dmitry Gusarov Mar 01 '20 at 02:07
-
I recently dipped my toes into having C++ call MI (the similar-API successor to WMI, which is now deprecated), and decided for my purposes (working with VHDs, volumes, and filesysyem devices) that it was *much* less work to have the C++ generate Powershell one-liners at run-time and call them via `system`. – Keith Russell Mar 25 '20 at 14:56
One way to do it:
Enumerate logical drives using
GetLogicalDrives
For each logical drive, open a file named
"\\.\X:"
(without the quotes) where X is the logical drive letter.Call
DeviceIoControl
passing the handle to the file opened in the previous step, and thedwIoControlCode
parameter set toIOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
:HANDLE hHandle; VOLUME_DISK_EXTENTS diskExtents; DWORD dwSize; [...] iRes = DeviceIoControl( hHandle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, (LPVOID) &diskExtents, (DWORD) sizeof(diskExtents), (LPDWORD) &dwSize, NULL);
This returns information of the physical location of a logical volume, as a VOLUME_DISK_EXTENTS
structure.
In the simple case where the volume resides on a single physical drive, the physical drive number is available in diskExtents.Extents[0].DiskNumber

- 21,501
- 10
- 63
- 107
-
14
-
2Note that his suggested implementation of `DeviceIoControl(IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)` call will fail if a volume spans multiple disks. In other words, you first need to ask `DeviceIoControl` for the size of `VOLUME_DISK_EXTENTS` struct, then allocate that much memory, and only then call it again with the allocated buffer. It works the way shown above because most volumes reside on just one disk. – ahmd0 Oct 24 '15 at 21:32
-
sorry, I can`t open the "\\.\C:“ successfully by using CreateFile((_T("\\.\C:"), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,///*FILE_FLAG_WRITE_THROUGH |*/FILE_FLAG_NO_BUFFERING, NULL); Could you figure out my problem? – bowman han Nov 12 '15 at 07:25
-
@ahmd0 `VOLUME_DISK_EXTENTS` holds enough memory for one extent, so you can call it like Grodriguez suggests and then check for `success || ERROR_MORE_DATA == GetLastError()` since we only care about the first extent anyway. – Millie Smith Mar 24 '17 at 17:17
-
@bowmanhan That's what I'm using (with only `FILE_ATTRIBUTE_NORMAL`). Try administrator privileges. – Millie Smith Mar 24 '17 at 17:17
-
1Use 0 instead of GENERIC_READ, this will allow open disk even w/o admin privileges, but still you will be able to read meta information like disk extents. – ivan.ukr Jul 12 '18 at 14:46
This might be 5 years too late :). But as I see no answer for this yet, adding this.
We can use Setup APIs to get the list of disks ie., devices in the system implementing GUID_DEVINTERFACE_DISK
.
Once we have their device paths, we can issue IOCTL_STORAGE_GET_DEVICE_NUMBER
to construct "\\.\PHYSICALDRIVE%d"
with STORAGE_DEVICE_NUMBER.DeviceNumber
See also SetupDiGetClassDevs
function
#include <Windows.h>
#include <Setupapi.h>
#include <Ntddstor.h>
#pragma comment( lib, "setupapi.lib" )
#include <iostream>
#include <string>
using namespace std;
#define START_ERROR_CHK() \
DWORD error = ERROR_SUCCESS; \
DWORD failedLine; \
string failedApi;
#define CHK( expr, api ) \
if ( !( expr ) ) { \
error = GetLastError( ); \
failedLine = __LINE__; \
failedApi = ( api ); \
goto Error_Exit; \
}
#define END_ERROR_CHK() \
error = ERROR_SUCCESS; \
Error_Exit: \
if ( ERROR_SUCCESS != error ) { \
cout << failedApi << " failed at " << failedLine << " : Error Code - " << error << endl; \
}
int main( int argc, char **argv ) {
HDEVINFO diskClassDevices;
GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;
DWORD requiredSize;
DWORD deviceIndex;
HANDLE disk = INVALID_HANDLE_VALUE;
STORAGE_DEVICE_NUMBER diskNumber;
DWORD bytesReturned;
START_ERROR_CHK();
//
// Get the handle to the device information set for installed
// disk class devices. Returns only devices that are currently
// present in the system and have an enabled disk device
// interface.
//
diskClassDevices = SetupDiGetClassDevs( &diskClassDeviceInterfaceGuid,
NULL,
NULL,
DIGCF_PRESENT |
DIGCF_DEVICEINTERFACE );
CHK( INVALID_HANDLE_VALUE != diskClassDevices,
"SetupDiGetClassDevs" );
ZeroMemory( &deviceInterfaceData, sizeof( SP_DEVICE_INTERFACE_DATA ) );
deviceInterfaceData.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );
deviceIndex = 0;
while ( SetupDiEnumDeviceInterfaces( diskClassDevices,
NULL,
&diskClassDeviceInterfaceGuid,
deviceIndex,
&deviceInterfaceData ) ) {
++deviceIndex;
SetupDiGetDeviceInterfaceDetail( diskClassDevices,
&deviceInterfaceData,
NULL,
0,
&requiredSize,
NULL );
CHK( ERROR_INSUFFICIENT_BUFFER == GetLastError( ),
"SetupDiGetDeviceInterfaceDetail - 1" );
deviceInterfaceDetailData = ( PSP_DEVICE_INTERFACE_DETAIL_DATA ) malloc( requiredSize );
CHK( NULL != deviceInterfaceDetailData,
"malloc" );
ZeroMemory( deviceInterfaceDetailData, requiredSize );
deviceInterfaceDetailData->cbSize = sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );
CHK( SetupDiGetDeviceInterfaceDetail( diskClassDevices,
&deviceInterfaceData,
deviceInterfaceDetailData,
requiredSize,
NULL,
NULL ),
"SetupDiGetDeviceInterfaceDetail - 2" );
disk = CreateFile( deviceInterfaceDetailData->DevicePath,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
CHK( INVALID_HANDLE_VALUE != disk,
"CreateFile" );
CHK( DeviceIoControl( disk,
IOCTL_STORAGE_GET_DEVICE_NUMBER,
NULL,
0,
&diskNumber,
sizeof( STORAGE_DEVICE_NUMBER ),
&bytesReturned,
NULL ),
"IOCTL_STORAGE_GET_DEVICE_NUMBER" );
CloseHandle( disk );
disk = INVALID_HANDLE_VALUE;
cout << deviceInterfaceDetailData->DevicePath << endl;
cout << "\\\\?\\PhysicalDrive" << diskNumber.DeviceNumber << endl;
cout << endl;
}
CHK( ERROR_NO_MORE_ITEMS == GetLastError( ),
"SetupDiEnumDeviceInterfaces" );
END_ERROR_CHK();
Exit:
if ( INVALID_HANDLE_VALUE != diskClassDevices ) {
SetupDiDestroyDeviceInfoList( diskClassDevices );
}
if ( INVALID_HANDLE_VALUE != disk ) {
CloseHandle( disk );
}
return error;
}
-
Adding another link (I didn't have enough rep to post in the answer) [Setup API Functions](http://msdn.microsoft.com/en-us/library/windows/hardware/ff551069(v=vs.85).aspx) – arun Aug 12 '13 at 09:19
-
1
-
note that these SetupAPI functions will _not_ only list all _physical_ drives but virtual ones, too - in fact _every_ registered disk drive _interface_ will be listed, methinks this _may_ be solution to the question but it will also produce a lot of "noise data", using SetupAPI is much more complex than what is suggested in this answer – specializt Apr 20 '15 at 00:06
-
I wrote a small library called [libwindevblk](https://github.com/vrichomme/libwindevblk/tree/dev/libwindevblk) based on the answer above that list drives, retrieves volume names when possible and provide an api allowing to read/write simply on partitions – Vincent Ricosti Aug 21 '20 at 10:57
-
It seems like the IOCTL_STORAGE_GET_DEVICE_NUMBER stage requires admin rights? Does anyone have a way to get that info without Admin? – Harry Mallon Jul 31 '23 at 11:01
The answer is far simpler than all the above answers. The physical drive list is actually stored in a Registry key which also gives the device mapping.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum
Count is the number of PhysicalDrive# and each numbered Registry Value is the corresponding physical drive.
For example, Registry Value "0" is PhysicalDrive0. The value is the actual device PhysicalDrive0 is mapped to. The value contained here can be passed into CM_Locate_DevNode within parameter pDeviceID to use the plug and play services. This will allow you to gather a wealth of information on the device. Such as the properties from Device Manager like "Friendly Display Name" if you need a name for the drive, serial numbers and more.
There is no need for WMI services which may not be running on the system or other hackery and this functionality has been present in Windows since at least 2000 and continues to be the case in Windows 10.

- 369
- 3
- 3
-
Interesting alternative, probably more relevant than my 7+ years old answer. +1 – VonC May 20 '16 at 14:43
-
Best option in my opinion, since is simple, reliable and the use of the registry is probably what developers of windows wanted when desining windows. – felknight Jul 24 '16 at 07:36
-
Far better option than my answer, +1. The last question is why does it have to contain actual information. Is it documented? At which moment Windows writes data there? Does management console use it? – polkovnikov.ph May 17 '17 at 12:34
-
2Excellent method, but it has one small drawback: it can't list each physical drive size, since these are not stored in the registry (WMI services do provide them though). For things like getting the manufacturer and model of each drive, it's still much better and less resource intensive, so +1 from me. I need to get the size of each drive and I'm not using this in C, so I'll have to go the WMI way. It's more or less the same story as with the physical memory, whose detailed data isn't stored in the registry either... – Yin Cognyto Jan 01 '19 at 21:09
-
"present in Windows since at least 2000": Cannot confirm. The registry key is missing in Windows XP and Windows 7. – stackprotector Aug 17 '20 at 14:44
-
MS says somewhere in their docs that you shouldn't use the registry to get hardware info, since they could change the registry at any time. – Jon Marnock Apr 01 '21 at 03:00
-
1Another issue with this approach - the disks numbers can be incorrect. If you have a USB sticks you can plug USB1 to make it show as Disk 1 and USB2 as Disk 2. Then unplug USB1. USB2 will remain as Disk 2, however the registry incorrectly reports it as 1. To verify, use diskpart. – ymerej May 18 '21 at 14:57
I've modified an open-source program called "dskwipe" in order to pull this disk information out of it. Dskwipe is written in C, and you can pull this function out of it. The binary and source are available here: dskwipe 0.3 has been released
The returned information will look something like this:
Device Name Size Type Partition Type
------------------------------ --------- --------- --------------------
\\.\PhysicalDrive0 40.0 GB Fixed
\\.\PhysicalDrive1 80.0 GB Fixed
\Device\Harddisk0\Partition0 40.0 GB Fixed
\Device\Harddisk0\Partition1 40.0 GB Fixed NTFS
\Device\Harddisk1\Partition0 80.0 GB Fixed
\Device\Harddisk1\Partition1 80.0 GB Fixed NTFS
\\.\C: 80.0 GB Fixed NTFS
\\.\D: 2.1 GB Fixed FAT32
\\.\E: 40.0 GB Fixed NTFS

- 13,248
- 9
- 69
- 119
-
1i thought it was it, but it force brute search for the drives..isn't there an api that will just report back the devices ? – CiNN Dec 09 '08 at 23:03
-
2
-
is this a guaranteed known thing that for every \\.\PhysicalDriveX there will be one or more matching \Device\HarddiskX, as in there will be a Harddisk device matching the physical drive number and those two numbers match? – stu Aug 03 '23 at 19:15
The only sure shot way to do this is to call CreateFile()
on all \\.\Physicaldiskx
where x is from 0 to 15 (16 is maximum number of disks allowed). Check the returned handle value. If invalid check GetLastError()
for ERROR_FILE_NOT_FOUND. If it returns anything else then the disk exists but you cannot access it for some reason.

- 40,830
- 17
- 95
- 117

- 338
- 2
- 12
-
7
-
1Why limit to `15`? Keep enumerating till you fail. I am not sure if some device number would be skipped by the OS. – Ajay Dec 15 '17 at 10:57
-
3@Ajay my best guess is in case you plug device A, plug device B, then unplug device A – morganbaz Aug 25 '18 at 15:16
-
diskpart jumped from `Disk 1` to `Disk 3`(USB flash drive after replug) so I'm un-upvoting this answer but I can't. `\\.\Physicaldisk2` exists but it isn't a drive(I don't know what it is). in `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum`, `2` starts with ``USBSTOR\`` instead of ``SCSI\``. Setup API finds 0,1,3 so that works (@arun's answer) – Mr. Doge Jun 21 '22 at 15:43
-
``USBSTOR\`` is actually the correct drive(because `CreateFile` below, then will list the 4 partitions), it's swapped with a SCSI that I don't know of : registry: 2 is USBSTOR, 3 is SCSI, vs Setup API (and diskpart too): 3 is USBSTOR, 2 is SCSI, this specific SCSI isn't a disk `SCSI\Disk&Ven_MSFT&Prod_XVDD` – Mr. Doge Jun 21 '22 at 16:07
The only correct answer is the one by @Grodriguez, and here's a code that he was too lazy to write:
#include <windows.h>
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
typedef struct _DISK_EXTENT {
DWORD DiskNumber;
LARGE_INTEGER StartingOffset;
LARGE_INTEGER ExtentLength;
} DISK_EXTENT, *PDISK_EXTENT;
typedef struct _VOLUME_DISK_EXTENTS {
DWORD NumberOfDiskExtents;
DISK_EXTENT Extents[ANYSIZE_ARRAY];
} VOLUME_DISK_EXTENTS, *PVOLUME_DISK_EXTENTS;
#define CTL_CODE(DeviceType, Function, Method, Access) \
(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#define IOCTL_VOLUME_BASE ((DWORD)'V')
#define METHOD_BUFFERED 0
#define FILE_ANY_ACCESS 0x00000000
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
int main() {
bitset<32> drives(GetLogicalDrives());
vector<char> goodDrives;
for (char c = 'A'; c <= 'Z'; ++c) {
if (drives[c - 'A']) {
if (GetDriveType((c + string(":\\")).c_str()) == DRIVE_FIXED) {
goodDrives.push_back(c);
}
}
}
for (auto & drive : goodDrives) {
string s = string("\\\\.\\") + drive + ":";
HANDLE h = CreateFileA(
s.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS, NULL
);
if (h == INVALID_HANDLE_VALUE) {
cerr << "Drive " << drive << ":\\ cannot be opened";
continue;
}
DWORD bytesReturned;
VOLUME_DISK_EXTENTS vde;
if (!DeviceIoControl(
h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL, 0, &vde, sizeof(vde), &bytesReturned, NULL
)) {
cerr << "Drive " << drive << ":\\ cannot be mapped into physical drive";
continue;
}
cout << "Drive " << drive << ":\\ is on the following physical drives: ";
for (int i = 0; i < vde.NumberOfDiskExtents; ++i) {
cout << vde.Extents[i].DiskNumber << ' ';
}
cout << endl;
}
}
I think that installation of Windows Driver Development Kit is quite a lengthy process, so I've included the declarations one needs to use DeviceIoControl
for this task.

- 6,256
- 6
- 44
- 79
-
2also : redefining windows macros may just be the worst idea ever - such an application will break and stop working pretty soon. – specializt Apr 19 '15 at 23:58
-
2Like I showed in my comment to [this answer](http://stackoverflow.com/a/11683906/670017) you're calling `DeviceIoControl` incorrectly. You can't assume that there's only one extent. You need to ask `DeviceIoControl` for the size of the needed `VOLUME_DISK_EXTENTS` buffer. – ahmd0 Oct 24 '15 at 21:35
-
@ahmd0 I'd be glad to fix it. Could you point to the msdn page that describes such behaviour, please? (Though the way to create a disk that is situated on two extents would be OK too, as I I've just found no way to test it.) – polkovnikov.ph Oct 25 '15 at 18:25
-
@polkovnikov.ph: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365727.aspx You basically call `DeviceIoControl` on memory for a single `VOLUME_DISK_EXTENTS` like you did but then check if it failed, and if so, see if it returned `ERROR_MORE_DATA` in `GetLastError` and if so, allocate a new buffer for `NumberOfDiskExtents` number of `DISK_EXTENT` structs (that it returned) and call `DeviceIoControl` again and make sure that it succeeds. You obviously don't do all this if the first call to `DeviceIoControl` succeeds. – ahmd0 Oct 28 '15 at 17:31
-
Here's an example. It's been asked recently: http://stackoverflow.com/q/33327177/670017 – ahmd0 Oct 28 '15 at 17:36
-
5Not every physical drive will be associated to a logical drive and even then not every logical drive will be assigned a drive letter. – anni Jul 13 '16 at 21:23
-
@ahmd0 I read that back while I was writing the code. The problem is that I have never seen a single case when there was more than 1 extent, and there's no way to test the code. If you know a way to create such environment, tell me. – polkovnikov.ph May 17 '17 at 12:40
-
@polkovnikov.ph: Oh, sure. There's a ton of cases. I admit it doesn't happen as often these days, but still. Simply create two partitions on the same physical drive, give each one its own drive letter and you'll have it. I made one of my old USB sticks like that (for testing purposes.) I'm not sure if Windows' `Disk Manager` can do it, if not then use good ol' `diskpart` to create those partitions. – ahmd0 May 17 '17 at 21:44
-
@ahmd0 Partitions shouldn't have anything in common with extents. Partitions divide physical drive into several logical, while extents should join several parts of a physical drive (not even sure if only one) into one logical drive. Why would partition of a USB stick lead to creation of logical drive with several extents? – polkovnikov.ph May 18 '17 at 01:05
-
@polkovnikov.ph: Hmm. Maybe it wasn't a partition. It's been awhile that I worked with this. I'll see if I can find my test project... – ahmd0 May 18 '17 at 04:28
-
2Like @anni said, filesystem devices can be attached without a drive letter. I'm programmatically mounting VHDs for a product that opens a lot of them at once, and if I didn't pass the no-drive-letter parameter, I'd run out of letters. – Keith Russell Mar 25 '20 at 15:24
GetLogicalDrives() enumerates all mounted disk partitions, not physical drives.
You can enumerate the drive letters with (or without) GetLogicalDrives, then call QueryDosDevice() to find out which physical drive the letter is mapped to.
Alternatively, you can decode the information in the registry at HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices. The binary data encodings there are not obvious, however. If you have a copy of Russinovich and Solomon's book Microsoft Windows Internals, this registry hive is discussed in Chapter 10.

- 9,546
- 3
- 35
- 41
-
3QueryDosDevice retuens partition, not the disk itself. Single disk is split to C: and D:, Win7 x64. So: c => "\Device\HarddiskVolume2"; d => "\Device\HarddiskVolume3'" – Arioch 'The Jul 25 '12 at 12:47
Thic WMIC command combination works fine:
wmic volume list brief

- 37,523
- 16
- 80
- 96

- 71
- 1
- 1
-
1volumes != physical disks. This command will not list physical disks that contain zero volumes, such as uninitialized disks. (Also, although it is not a fatal problem like the previous one, the output of this command will require further processing to deduplicate ids of physical disks that contain multiple volumes.) – Keith Russell Mar 25 '20 at 15:28
If you only need to look at the existing disks, this one will suffice:
powershell "get-physicaldisk"

- 61
- 3
-
Always write your answers with details, like how it works and if it is not working for the OP then give the reason for that, check this link for more details. https://stackoverflow.com/help/how-to-answer – DaniyalAhmadSE Dec 05 '20 at 07:18
Might want to include the old A: and B: drives as you never know who might be using them! I got tired of USB drives bumping my two SDHC drives that are just for Readyboost. I had been assigning them to High letters Z: Y: with a utility that will assign drive letters to devices as you wish. I wondered.... Can I make a Readyboost drive letter A: ? YES! Can I put my second SDHC drive letter as B: ? YES!
I've used Floppy Drives back in the day, never thought that A: or B: would come in handy for Readyboost.
My point is, don't assume A: & B: will not be used by anyone for anything You might even find the old SUBST command being used!

- 21
- 1
Here is a new solution of doing it with doing WMI calls.
Then all you need to do is just to call :
queryAndPrintResult(L"SELECT * FROM Win32_DiskDrive", L"Name");

- 10,860
- 6
- 57
- 75
I just ran across this in my RSS Reader today. I've got a cleaner solution for you. This example is in Delphi, but can very easily be converted to C/C++ (It's all Win32).
Query all value names from the following registry location: HKLM\SYSTEM\MountedDevices
One by one, pass them into the following function and you will be returned the device name. Pretty clean and simple! I found this code on a blog here.
function VolumeNameToDeviceName(const VolName: String): String;
var
s: String;
TargetPath: Array[0..MAX_PATH] of WideChar;
bSucceeded: Boolean;
begin
Result := ”;
// VolumeName has a format like this: \\?\Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963}\
// We need to strip this to Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963}
s := Copy(VolName, 5, Length(VolName) - 5);
bSucceeded := QueryDosDeviceW(PWideChar(WideString(s)), TargetPath, MAX_PATH) <> 0;
if bSucceeded then
begin
Result := TargetPath;
end
else begin
// raise exception
end;
end;

- 13,248
- 9
- 69
- 119
-
2i want to have the physical name so that i could play with unallocated space, so my guess it that this unallocated space wouldn't have a mounted volume guid... – CiNN Dec 12 '08 at 08:45
-
1'Fraid this isn't what we're looking for, and is similar to @Alnitak's answer. – Matt Joiner Oct 28 '10 at 10:30
-
1You're supposed to use SetupApi in windows xp and later, and no longer use the registry, which was the way to do it in Win98, but not any more. – Warren P Dec 16 '11 at 20:07
In Windows Powershell
Get-WmiObject -Class Win32_DiskDrive -ComputerName <COMPUTERNAME> | select Name,SerialNumber,SCSITargetID,Size

- 1
- 1
Make a list of all letters in the US English Alphabet, skipping a & b. "CDEFGHIJKLMNOPQRSTUVWXYZ". Open each of those drives with CreateFile
e.g. CreateFile("\\.\C:")
. If it does not return INVALID_HANDLE_VALUE
then you got a 'good' drive. Next take that handle and run it through DeviceIoControl
to get the Disk #. See my related answer for more details.