C 如何列出物理磁盘?

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

如何在Windows中列出物理磁盘? 为了获得可用的
“\\\\.\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"