C 如何列出物理磁盘?
如何在Windows中列出物理磁盘? 为了获得可用的C 如何列出物理磁盘?,c,windows,winapi,hard-drive,C,Windows,Winapi,Hard Drive,如何在Windows中列出物理磁盘? 为了获得可用的“\\\\.\PhysicalDrive0”列表。WMIC 是一个非常完整的工具 wmic磁盘驱动器列表 例如,提供(太多)详细清单 要了解更多信息 wmic磁盘驱动器列表摘要 C 提到: 在C中: 系统(“wmic磁盘驱动器列表”); 如前所述,您也可以调用WinAPI,但是。。。如“”,这是相当复杂的(通常用C++,而不是C)。 动力壳 或使用PowerShell: Get-WmiObject Win32_DiskDrive Get
“\\\\.\PhysicalDrive0”
列表。WMIC
是一个非常完整的工具
wmic磁盘驱动器列表
例如,提供(太多)详细清单
要了解更多信息
wmic磁盘驱动器列表摘要
C
提到:
在C中:
系统(“wmic磁盘驱动器列表”);
如前所述,您也可以调用WinAPI,但是。。。如“”,这是相当复杂的(通常用C++,而不是C)。
动力壳
或使用PowerShell:
Get-WmiObject Win32_DiskDrive
GetLogicalDrives()枚举所有装入的磁盘分区,而不是物理驱动器
您可以使用(或不使用)GetLogicalDrives枚举驱动器号,然后调用QueryDosDevice()找出该驱动器号映射到的物理驱动器
或者,您可以在HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices对注册表中的信息进行解码。然而,那里的二进制数据编码并不明显。如果您有Russinovich和Solomon的著作Microsoft Windows Internals的副本,则此注册表配置单元将在第10章中讨论。我修改了一个名为“dskwipe”的开源程序,以便从中提取磁盘信息。Dskwipe是用C编写的,您可以从中提取此函数。二进制文件和源文件可在此处获得: 返回的信息如下所示:
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
我今天在我的RSS阅读器上偶然发现了这个。我有一个更干净的解决方案给你。这个例子是用Delphi编写的,但是可以很容易地转换成C/C++(都是Win32) 从以下注册表位置查询所有值名称: HKLM\SYSTEM\MountedDevices 一个接一个地将它们传递到下面的函数中,系统将返回设备名。非常干净和简单
函数VolumeNameToDeviceName(const VolName:String):String;
变量
s:字符串;
TargetPath:WideChar的数组[0..MAX_PATH];
bSucceeded:布尔值;
开始
结果:=”;
//VolumeName的格式如下:\\?\Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963}\
//我们需要将其剥离到卷{c4ee0265-bada-11dd-9cd5-806e6f6e6963}
s:=副本(卷名,5,长度(卷名)-5);
bSucceeded:=QueryDosDeviceW(PWideChar(宽字符串)),TargetPath,MAX_PATH)0;
如果成功,那么
开始
结果:=目标路径;
结束
否则开始
//引发异常
结束;
结束;
列出美英字母表中的所有字母,跳过a和b。“CDEFGHIJKLMNOPQRSTUVWXYZ”。使用CreateFile
打开每个驱动器,例如CreateFile(“\\.\C:”)
。如果它没有返回无效的句柄值,那么您得到了一个“良好”的驱动器。接下来,获取该句柄并通过DeviceIoControl
运行它以获取磁盘唯一可靠的方法是在所有\\上调用CreateFile()
。\Physicaldiskx
,其中x从0到15(16是允许的最大磁盘数)。检查返回的句柄值。如果无效,请检查GetLastError()
是否找到错误文件。如果它返回任何其他内容,则磁盘存在,但由于某种原因您无法访问它。一种方法:
“\\.\X:
(不带引号)的文件,其中X是逻辑驱动器号dwIoControlCode
参数设置为:
在卷驻留在单个物理驱动器上的简单情况下,物理驱动器号在
diskdextens.extensts[0]中可用。DiskNumber
Thic WMIC命令组合工作正常:
wmic volume list brief
这可能太晚了5年:)。但我还没有看到答案,加上这个 我们可以使用获取磁盘列表,即系统中的设备 一旦我们有了它们的设备路径,我们就可以发出命令,用
存储设备号来构造“\\.\PHYSICALDRIVE%d”
另见
#包括
#包括
#包括
#pragma注释(lib,“setupapi.lib”)
#包括
#包括
使用名称空间std;
#定义开始\u错误\u CHK()\
DWORD error=错误\成功\
德沃德失败线\
字符串失效API;
#定义CHK(表达式、api)\
如果(!(expr)){\
error=GetLastError()\
failedLine=\uuuuuuuuuuuuuu线\
failedApi=(api)\
转到错误退出\
}
#定义END_ERROR_CHK()\
错误=错误\成功\
退出时出错:\
if(ERROR_SUCCESS!=ERROR){\
cout可能希望包括旧的A:和B:驱动器,因为您永远不知道谁可能正在使用它们!
我厌倦了USB驱动器碰撞我的两个SDHC驱动器,这两个驱动器只用于Readyboost。
我一直在用一个实用程序将它们分配到高位字母Z:Y:上,该实用程序将根据您的意愿为设备分配驱动器号。我想知道……我可以制作一个Readyboost驱动器号a:?是的!
我可以把我的第二个SDHC驱动器号写为B:?可以
我以前用过软驱,没想到A:或B:对我来说会派上用场
准备好了
我的观点是,不要假设A:&B:不会被任何人用于任何事情
您甚至可能会发现使用了旧的SUBST命令!唯一正确的答案是@Grodriguez的答案,下面是他懒得编写的代码:
#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;
}
}
#包括
#包括
#包括
#包括
使用名称空间std;
typedef结构\u磁盘\u范围{
德沃德磁盘号;
大整数起始偏移量;
大整数扩展长度;
}磁盘盘区,*PDISK盘区;
typedef结构\u卷\u磁盘\u扩展{
德沃德数;
磁盘扩展数据块[任意大小]
wmic volume list brief
#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;
}
#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;
}
}
queryAndPrintResult(L"SELECT * FROM Win32_DiskDrive", L"Name");
powershell "get-physicaldisk"