获取USB设备的父信息C++

2024-04-09

我正在开发一个 MFC 工具,用于检查连接的 USB 设备的一些驱动程序信息,例如位置信息、父级、硬件 ID 等。我已经获得了我想要的所有其他信息,但我一直在获取设备父级信息。

我用过安装程序API.dll在我的代码中获取设备信息。 使用获取USB设备信息句柄设置DiGetClassDevs功能。 使用获取特定设备信息数据设置DiEnumDeviceInfo功能。 使用获取设备描述和硬件 ID设置DiGetDeviceRegistryProperty功能。

// List all connected USB devices
hDevInfo = SetupDiGetClassDevs(pClassGuid, pszEnumerator, 
    NULL, pClassGuid != NULL ? DIGCF_PRESENT : DIGCF_ALLCLASSES | 
    DIGCF_PRESENT);

// Get device info data
SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData);

// Get device instance id
CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 
    0);

// Get device description
SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, 
    SPDRP_DEVICEDESC,
    &dwPropertyRegDataType, (BYTE*)szDesc, sizeof(szDesc), &dwSize);

#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, 
    b8, pid) EXTERN_C const DEVPROPKEY DECLSPEC_SELECTANY 
    name = { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6, b7,  b8 } }, pid 
}

// DEVPROP_TYPE_STRING 
DEFINE_DEVPROPKEY(DEVPKEY_Device_Manufacturer, 0xa45c254e, 0xdf1c, 
    0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13);        
// DEVPROP_TYPE_GUID
DEFINE_DEVPROPKEY(DEVPKEY_Device_ContainerId, 0x8c7ed206, 0x3f8a, 0x4827, 
    0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c, 2);     

typedef BOOL(WINAPI *FN_SetupDiGetDevicePropertyW)(
    __in       HDEVINFO DeviceInfoSet,
    __in       PSP_DEVINFO_DATA DeviceInfoData,
    __in       const DEVPROPKEY *PropertyKey,
    __out      DEVPROPTYPE *PropertyType,
    __out_opt  PBYTE PropertyBuffer,
    __in       DWORD PropertyBufferSize,
    __out_opt  PDWORD RequiredSize,
    __in       DWORD Flags
);

FN_SetupDiGetDevicePropertyW fn_SetupDiGetDevicePropertyW = 
    (FN_SetupDiGetDevicePropertyW) 
    GetProcAddress(GetModuleHandle(TEXT("Setupapi.dll")), 
    "SetupDiGetDevicePropertyW");

if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, 
    &DEVPKEY_Device_Manufacturer, &ulPropertyType, (BYTE*)szBuffer, 
    sizeof(szBuffer), &dwSize, 0)) 
{
    _tprintf(TEXT("    Device Manufacturer: \"%ls\"\n"), szBuffer);
}

if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, 
    &DEVPKEY_Device_ContainerId, &ulPropertyType, (BYTE*)szDesc, 
    sizeof(szDesc), &dwSize, 0)) 
{
    StringFromGUID2((REFGUID)szDesc, szBuffer, ARRAY_SIZE(szBuffer));
    _tprintf(TEXT("    ContainerId: \"%ls\"\n"), szBuffer);
}

获取USB设备的父信息对我来说非常有用。请帮忙提供一些线索。

请查看图片 https://i.stack.imgur.com/l8XZm.png


CM_Locate_DevNode打开给定设备 ID 的设备句柄;

CM_Get_Parent找到父设备;

CM_Get_Device_ID_Size and CM_Get_Device_ID获取设备句柄并返回设备 ID。

Sample:

#include <Windows.h>
#include <setupapi.h>
#include <cfgmgr32.h>
#include <tchar.h>
#include <stdio.h>
#define ARRAY_SIZE(arr)     (sizeof(arr)/sizeof(arr[0]))

#pragma comment (lib, "setupapi.lib")

int main()
{
    HDEVINFO hDevInfo;
    GUID guid;
    BYTE buffer[1024];
    DWORD dwRequiredSize;
    DEVINST devInstParent;
    SP_DEVICE_INTERFACE_DATA devInterfaceData;
    SP_DEVINFO_DATA devInfoData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetail;
    CONFIGRET status;
    TCHAR szDeviceInstanceID[MAX_DEVICE_ID_LEN];
    BOOL bSuccess;

    guid = GUID_DEVINTERFACE_VOLUME;
    hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        return 1;
    }

    for (DWORD dwIndex = 0;; dwIndex++)
    {
        ZeroMemory(&devInterfaceData, sizeof(devInterfaceData));
        devInterfaceData.cbSize = sizeof(devInterfaceData);

        if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid, dwIndex, &devInterfaceData)) {
            DWORD dwErrorCode = GetLastError();
            if (dwErrorCode == ERROR_NO_MORE_ITEMS)
                break;
            else
                return 1;  
        }

        ZeroMemory(&devInfoData, sizeof(devInfoData));
        devInfoData.cbSize = sizeof(devInfoData);
        pDevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer;
        pDevDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        // Get device interface detail data to get Device Instance from
        // SP_DEVINFO_DATA and Device Path from SP_DEVICE_INTERFACE_DETAIL_DATA
        bSuccess = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData,
            pDevDetail,// SP_DEVICE_INTERFACE_DETAIL_DATA
            sizeof(buffer), &dwRequiredSize, &devInfoData); // SP_DEVINFO_DATA

        status = CM_Get_Parent(&devInstParent, devInfoData.DevInst, 0);
        if (status == CR_SUCCESS) 
        {
            status = CM_Get_Device_ID(devInstParent, szDeviceInstanceID, ARRAY_SIZE(szDeviceInstanceID), 0);
            if (status == CR_SUCCESS)
                _tprintf(TEXT("    %s\n"), szDeviceInstanceID);
        }
        else 
        {
            continue;
        }
    }

    return 0;
}

调试结果:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取USB设备的父信息C++ 的相关文章

随机推荐

  • React 16.8.6 对应的测试库/react 版本是什么?

    我正在尝试制作一个打字稿前端 但我无法使用react dom client导入是因为我已经缩小到我的测试库 反应版本与我的反应版本不对应的问题 我已经尝试了多个降级版本 但似乎无法让它工作 有什么解决办法吗 我会附上我的package js
  • 将请求传递给特定的分叉节点实例

    如果我错了 请纠正我 但不可能在同一端口上启动多个 http 服务器 基于此 有趣的是 NodeJS 集群可能会分叉 因为我知道有一个主人正在将请求传递给其中一个分叉工人 什么worker是由操作系统管理的或者cluster schedul
  • Amazon SES 停止工作

    我设置了 Amazon SES 它最初运行了几个小时 然后突然停止了 我发送的所有电子邮件以及我们的域都已经过验证 我们不会发送大量电子邮件 每天只发送几百封 每当我对 web config 进行更改时 它似乎又可以再工作 2 3 小时 例
  • Rails 3 link_to (:method => :delete) 不起作用

    我有Rails 中的动词有问题 查看资源 狗 的页面 该资源有很多 跳蚤 嵌入狗体内show html haml是一个电话render dog fleas它会自动 找到并使用 fleas flea html haml 中的模板来列出与所述狗
  • 单遍读取和验证 XML 与 C# 中引用的 XSD

    我正在尝试从 XML 文件中读取数据 并根据它建议的 XSD 对其进行验证 将其转换为单个数据结构 例如 XmlDocument 我有一个解决方案 但它需要两次通过文件 我想知道是否有单次解决方案 MyBooks xml
  • 如何在 PHP 中将数字格式化为美元金额

    如何将数字转换为显示美元和美分的字符串 eg 123 45 gt 123 45 123 456 gt 123 46 123 gt 123 00 13 gt 0 13 1 gt 0 10 0 gt 0 00 如果你只想要简单的东西 numbe
  • 如何在 Windows 命令行上以合适的格式获取当前日期/时间以在文件/文件夹名称中使用?

    更新 现在已经是 2016 年了 我会使用 PowerShell 来实现此目的 除非有真正令人信服的向后兼容的原因 特别是因为使用的区域设置问题date 请参阅 npocmaka 的https stackoverflow com a 197
  • Android 上的 pthread_create 警告

    打电话后pthread create函数我收到下一条消息 W libc 26409 pthread create sched setscheduler 调用失败 不允许操作 用于创建线程的代码是 pthread attr t threadA
  • 防止单个单词在 css/html 中环绕浮动

    有没有什么方法可以防止一个或两个单词环绕浮动 但如果有更多文本则允许它 这是一个示例 其中第一个文本有问题 但第二个文本很好 http jsfiddle net wdPCp http jsfiddle net wdPCp div class
  • AllowAnonymous 不适用于 Azure 广告身份验证

    我有一个 Asp net MVC 应用程序 在其中使用 Azure AD 身份验证来对用户进行身份验证 我想允许用户无需登录即可访问某些 api 控制器 我尝试将 AllowAnonymous 属性放在控制器顶部以跳过这些控制器进行身份验证
  • 无法杀死的控制台窗口

    我正在 Visual C 2008 下使用 GLUT 开发基于 OpenGL 的 2d 模拟 有时当我遇到断言 或未处理的异常并闯入调试器时 GLUT 显示窗口关闭 但控制台窗口保持打开状态 它们只是不能杀了 它们不会出现在任务管理器 进程
  • 计算的属性不会在 Powershell 中引发异常。有哪些解决办法?

    显然有一个通过设计怪癖 https connect microsoft com PowerShell feedback details 782806 calculated properties do not throw exceptions
  • 使用 Firefox 打开确认对话框时显示“$apply already in Progress”

    我 有时 变得很奇怪 申请已在进行中在以下看似无辜的情况下打开确认对话框时出错 var mod angular module app mod controller ctrl function scope interval http scop
  • 如何知道ngOnChanges中哪些@Input发生了变化?

    我正在使用 Angular 2 现在我有两个 inputaa and bb 我想要做 If aa改变 做某事 If bb改变 做其他事情 如何知道哪些 Input发生了变化ngOnChanges Thanks Input aa Input
  • 分析心率监测器返回的数据

    我正在尝试通过蓝牙读取心率监视器传输的数据 但我真的不知道如何读取心率监视器返回的字节 每个供应商可能都有自己的将数据包装成字节的方法 但是如何将这些字节转换为某种可读格式 以便我可以分析其中的变化 例如 ASCII 值或某些十六进制值 我
  • 如何调试特定的 JavaScript 点击事件?

    在雅虎天气页面上 有一个链接标记为C改变温度单位Fahrenheit to Celsius 我正在寻找调试此操作并了解 JavaScript 在幕后执行的内容 将 F 转换为 C 调试此类操作的方法是什么 Link http weather
  • phpMyAdmin 错误 504 网关超时重新加载

    我的 phpmyadmin 有一个非常烦人的问题 它出乎意料地出现 据我所知 我的专用服务器没有发生任何变化 当我尝试在浏览器中执行任何查询或显示执行时间超过 1 秒的视图时 Windows 7 上的 firefox 即行为相同 我收到以下
  • 在类中声明一个数组。 C++

    我想创建一个初始化数组和函数的类push向数组添加一个元素而不是打印它 作为初学者 我知道初始化有问题 除了函数之外一切正常push 它不打印数组 我的班级出了什么问题 include
  • 使用 exiftool 编辑 MP4 元数据

    我有一个 MP4 文件Title元数据 exiftool movie mp4 这使 Audio Bits Per Sample 16 Audio Sample Rate 48000 Handler Type Metadata Handler
  • 获取USB设备的父信息C++

    我正在开发一个 MFC 工具 用于检查连接的 USB 设备的一些驱动程序信息 例如位置信息 父级 硬件 ID 等 我已经获得了我想要的所有其他信息 但我一直在获取设备父级信息 我用过安装程序API dll在我的代码中获取设备信息 使用获取U