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

如何通过PDEV_BROADCAST_DEVICEINTERFACE获取USB设备详细信息

从WM_DEVICECHANGE获取USB设备详细信息

你当前通过PDEV_BROADCAST_DEVICEINTERFACE拿到的dbcc_name只是设备的接口路径,本身不包含厂商、描述、容量这类详细数据。要获取这些信息,需要结合Windows的SetupAPI和磁盘IO控制函数,以下是具体实现方案:

一、获取设备基本信息(名称、厂商、描述)

通过设备接口路径,我们可以从系统注册表中读取设备的属性信息,需要用到SetupAPI系列函数:

前置准备

  • 包含头文件:#include <SetupAPI.h>、#include <InitGuid.h>
  • 链接库:#pragma comment(lib, "SetupAPI.lib")

实现代码

在你的DBT_DEVICEARRIVAL分支中添加以下逻辑:

case DBT_DEVICEARRIVAL:
{
    std::cout << "new device connected: " << path << std::endl;

    // 1. 初始化设备信息集合(以磁盘设备为例,可根据需求更换GUID)
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (hDevInfo == INVALID_HANDLE_VALUE)
        break;

    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = {0};
    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    // 2. 打开目标设备接口
    if (!SetupDiOpenDeviceInterface(hDevInfo, lpdbv->dbcc_name, 0, &deviceInterfaceData))
    {
        SetupDiDestroyDeviceInfoList(hDevInfo);
        break;
    }

    // 3. 获取设备接口详情,拿到SP_DEVINFO_DATA
    DWORD requiredSize = 0;
    SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &requiredSize, NULL);
    std::vector<BYTE> detailBuffer(requiredSize);
    SP_DEVICE_INTERFACE_DETAIL_DATA* pDetailData = reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA*>(detailBuffer.data());
    pDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    SP_DEVINFO_DATA devInfoData = {0};
    devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, pDetailData, requiredSize, NULL, &devInfoData))
    {
        // 4. 读取各类设备属性
        WCHAR buffer[256] = {0};
        
        // 友好名称
        if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_FRIENDLYNAME, NULL, reinterpret_cast<PBYTE>(buffer), sizeof(buffer), NULL))
            std::wcout << L"Friendly Name: " << buffer << std::endl;
        
        // 设备描述
        memset(buffer, 0, sizeof(buffer));
        if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_DEVICEDESC, NULL, reinterpret_cast<PBYTE>(buffer), sizeof(buffer), NULL))
            std::wcout << L"Device Description: " << buffer << std::endl;
        
        // 厂商名称
        memset(buffer, 0, sizeof(buffer));
        if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_MFG, NULL, reinterpret_cast<PBYTE>(buffer), sizeof(buffer), NULL))
            std::wcout << L"Manufacturer: " << buffer << std::endl;
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);
    break;
}

二、获取存储设备容量

要获取USB存储设备的容量,需要通过CreateFile打开设备,再用DeviceIoControl发送磁盘控制指令:

实现代码

同样在DBT_DEVICEARRIVAL分支中添加:

// 打开设备句柄
HANDLE hDevice = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice != INVALID_HANDLE_VALUE)
{
    DISK_GEOMETRY_EX geometryEx = {0};
    DWORD bytesReturned = 0;

    // 获取磁盘几何信息,计算总容量
    if (DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &geometryEx, sizeof(geometryEx), &bytesReturned, NULL))
    {
        ULONGLONG totalBytes = geometryEx.DiskSize.QuadPart;
        ULONGLONG totalGB = totalBytes / (1024 * 1024 * 1024);
        std::cout << "Total Capacity: " << totalGB << " GB" << std::endl;
    }

    CloseHandle(hDevice);
}

注意事项

  • 设备类GUID:上述代码用了GUID_DEVINTERFACE_DISK(磁盘设备),如果是其他类型USB设备(比如摄像头、打印机),需要替换为对应类的GUID
  • 权限问题:CreateFile需要足够的读取权限,确保程序以合适的权限运行
  • 错误处理:实际开发中要严格检查每个API的返回值,避免空指针或无效句柄导致崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:55:28