You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用GUID_DEVINTERFACE_DISK过滤CM_Get_Device_Interface_List结果

正确调用CM_Get_Device_Interface_List获取GUID_DEVINTERFACE_DISK设备的方法

报错原因说明

你遇到的类型不兼容报错是正确的,你看到的示例代码存在根本性错误:CM_Get_Device_Interface_List的第一个参数要求传入设备接口类GUID的字符串表示,不是GUID结构体的指针,强制将LPGUID类型转为PCWSTR属于非法内存访问,必然触发异常。

方法1:直接获取所有当前存在的磁盘设备接口

无需额外调用SetupDi系列函数,仅通过CM_Get_Device_Interface_List即可完成需求,步骤如下:

  1. 调用系统API StringFromGUID2 将GUID_DEVINTERFACE_DISK结构体转换为符合要求的带大括号的GUID字符串格式。
  2. 第一次调用CM_Get_Device_Interface_List,传入空缓冲区获取所需的缓冲区长度。
  3. 分配足够内存后,第二次调用获取实际的磁盘设备接口列表,返回的缓冲区为多字符串结构,每个设备接口路径以\0分隔,末尾以连续两个\0结束。

示例代码

需包含头文件并链接对应库:

#include <windows.h>
#include <initguid.h>
#include <ntdddisk.h>
#include <cfgmgr32.h>
#include <tchar.h>
#pragma comment(lib, "Cfgmgr32.lib")

功能实现代码:

CONFIGRET cr;
WCHAR szGuidBuf[GUID_STRING_LENGTH] = {0};
ULONG ulBufLen = 0;
PWSTR pDeviceList = NULL;

// 将GUID结构体转为系统要求的字符串格式
if (StringFromGUID2(GUID_DEVINTERFACE_DISK, szGuidBuf, GUID_STRING_LENGTH) == 0) {
    // 转换失败处理逻辑
    return;
}

// 第一次调用获取所需缓冲区长度
cr = CM_Get_Device_Interface_ListW(szGuidBuf, NULL, NULL, &ulBufLen, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr != CR_SUCCESS) {
    // 错误处理逻辑
    return;
}

// 分配缓冲区内存
pDeviceList = (PWSTR)HeapAlloc(GetProcessHeap(), 0, ulBufLen * sizeof(WCHAR));
if (!pDeviceList) {
    // 内存分配失败处理逻辑
    return;
}

// 第二次调用获取实际设备接口列表
cr = CM_Get_Device_Interface_ListW(szGuidBuf, NULL, pDeviceList, ulBufLen, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr == CR_SUCCESS) {
    PWSTR pCur = pDeviceList;
    // 遍历多字符串结构
    while (*pCur) {
        // pCur即为当前磁盘的设备接口路径,可直接传入CreateFile访问设备
        wprintf(L"磁盘接口路径:%s\n", pCur);
        pCur += wcslen(pCur) + 1;
    }
}

// 释放内存
HeapFree(GetProcessHeap(), 0, pDeviceList);

方法2:过滤指定磁盘设备的接口

如果需要获取单个磁盘对应的关联卷等信息,可结合DEVINST过滤:

  1. 调用SetupDiGetClassDevs时需传入DIGCF_PRESENT | DIGCF_DEVICEINTERFACE标志,避免仅获取到设备安装类信息。
  2. 调用CM_Get_Device_ID将你拿到的DEVINST转为字符串形式的设备实例ID。
  3. 调用CM_Get_Device_Interface_List时,将第二个参数pwszDeviceID设置为上述设备实例ID,即可过滤出仅属于该磁盘的接口列表。

常见注意事项

  • 不要混淆CM_Get_Device_Interface_List和CM_Get_Device_ID_List,前者用于获取可直接访问的设备接口路径,后者用于获取设备实例ID列表。
  • 遍历返回的多字符串缓冲区时,必须以连续两个\0作为结束标志,避免内存越界。
  • 你拿到的DEVINST值为1、2属于正常情况,DEVINST是系统分配的设备编号,数值本身不代表设备属性,只要能正常通过API调用即可。

内容的提问来源于stack exchange,提问作者Damn Vegetables

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:24:01