Von*_*onC 66
wmic是一个非常完整的工具
wmic diskdrive list
Run Code Online (Sandbox Code Playgroud)
例如,提供(太多)详细列表
少知情
wmic diskdrive list brief
Run Code Online (Sandbox Code Playgroud)
在C:
system("wmic diskdrive list");
Run Code Online (Sandbox Code Playgroud)
如评论所述,您也可以调用WinAPI,但是......如" 如何使用C应用程序从WMI获取数据? "中所示,这非常复杂(通常使用C++,而不是C).
或者使用PowerShell:
Get-WmiObject Win32_DiskDrive
Run Code Online (Sandbox Code Playgroud)
Gro*_*uez 44
一种方法:
使用枚举逻辑驱动器 GetLogicalDrives
对于每个逻辑驱动器,打开一个名为"\\.\X:"
(不带引号)的文件,其中X是逻辑驱动器号.
调用DeviceIoControl
将句柄传递给上一步打开的文件,dwIoControlCode
参数设置为IOCTL_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);
Run Code Online (Sandbox Code Playgroud)这将返回逻辑卷的物理位置信息,作为VOLUME_DISK_EXTENTS
结构.
在卷位于单个物理驱动器上的简单情况下,可以使用物理驱动器号 diskExtents.Extents[0].DiskNumber
小智 28
这可能是5年太晚了:).但是,由于我还没有找到答案,所以加上这个.
我们可以使用Setup API来获取磁盘列表,即系统实现中的设备GUID_DEVINTERFACE_DISK
.
一旦我们有了自己的设备路径,我们可以发出IOCTL_STORAGE_GET_DEVICE_NUMBER
来构建"\\.\PHYSICALDRIVE%d"
与STORAGE_DEVICE_NUMBER.DeviceNumber
#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;
}
Run Code Online (Sandbox Code Playgroud)
小智 14
答案远比上述所有答案都简单.物理驱动器列表实际上存储在注册表项中,该注册表项还提供设备映射.
HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \服务\硬盘\枚举
Count是PhysicalDrive#的编号,每个编号的Registry Value是相应的物理驱动器.
例如,注册表值"0"是PhysicalDrive0.该值是PhysicalDrive0映射到的实际设备.此处包含的值可以传递到CM_Locate_DevNode参数中pDeviceID使用即插即用服务.这样您就可以在设备上收集大量信息.例如,如果您需要驱动器名称,序列号等,请使用设备管理器中的属性,如"友好显示名称".
不需要在系统或其他hackery上运行的WMI服务,并且至少在2000年以来Windows中一直存在此功能,并且在Windows 10中仍然如此.
Mic*_*ick 12
我修改了一个名为"dskwipe"的开源程序,以便从中获取此磁盘信息.Dskwipe是用C语言编写的,你可以将它从中拉出来.二进制和源代码可在此处获得:dskwipe 0.3已发布
返回的信息将如下所示:
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
Run Code Online (Sandbox Code Playgroud)
ann*_*nni 10
唯一确定的方法是调用x从0到15的CreateFile()
所有\\.\Physicaldiskx
位置(16是允许的最大磁盘数).检查返回的句柄值.如果作废的支票GetLastError()
为ERROR_FILE_NOT_FOUND.如果它返回任何其他内容,则磁盘存在,但由于某种原因您无法访问它.
GetLogicalDrives()枚举所有已安装的磁盘分区,而不是物理驱动器.
您可以使用(或不使用)GetLogicalDrives枚举驱动器号,然后调用QueryDosDevice()以找出该字母映射到的物理驱动器.
或者,您可以在HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices中解码注册表中的信息.然而,那里的二进制数据编码并不明显.如果您有一份Russinovich和Solomon的书Microsoft Windows Internals,那么这个注册表配置单元将在第10章中讨论.
唯一正确的答案是@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;
}
}
Run Code Online (Sandbox Code Playgroud)
我认为安装Windows驱动程序开发工具包是一个漫长的过程,所以我已经包含了需要DeviceIoControl
用于此任务的声明.
归档时间: |
|
查看次数: |
158007 次 |
最近记录: |