【问题标题】:Get device instance DWORD from device instance path string从设备实例路径字符串中获取设备实例 DWORD
【发布时间】:2012-11-26 10:41:44
【问题描述】:

我得到一个像

这样的设备实例路径
L"\\\\?\\USB#VID_0403&PID_6001#6&2cc2d230&0&2#{219d0508-57a8-4ff5-97a1-bd86587c6c7e}"

来自IWDFRemoteInterfaceInitialize::RetrieveSymbolicLink
但是对于CM_Get_Parent,我需要设备的 DEVINST/DWORD,这让我抓狂。
例如我试过了

instancePath = L"\\\\?\\USB#VID_0403&PID_6001#6&2cc2d230&0&2#{219d0508-57a8-4ff5-97a1-bd86587c6c7e}";
HDEVINFO hinfo = SetupDiGetClassDevs(NULL, instancePath, NULL, DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES);

和其他一些 SetupDi... voodoo 没有成功。任何帮助都非常感谢,因为 - 如前所述 - 我已经有好几个小时无法摆脱这种疯狂了,尽管有几十个相反的例子(devid->instance path)我还没有找到任何实例路径->DEVINST。

【问题讨论】:

  • 我遇到了完全相同的问题。答案将不胜感激。

标签: c++ windows winapi device-driver device-instance-id


【解决方案1】:

正如你所说,没有直接的方法。

但是,您应该能够通过一些字符串编辑从您的设备路径/设备接口 ID 中获取设备实例 ID,遵循以下步骤:

  1. 完全删除开始的\\\\?\\ 部分,直到USB
  2. 完全删除最后的{...} 部分
  3. # 替换为\

"\\\\?\\USB#VID_0403&PID_6001#6&2cc2d230&0&2#{219d0508-57a8-4ff5-97a1-bd86587c6c7e}"

你现在应该有

"USB\VID_0403&PID_6001\6&2cc2d230&0&2\"

这应该是一个有效的设备实例 ID。如果不是,请尝试删除最后一个“\”。

然后,您可以将其提供给 CM_Locate_DevNode() 并获得所需的 DEVINST。

【讨论】:

  • 虽然您可以解析设备路径字符串,但 Windows 文档指出应该这样做。我相信这是因为将来允许更改设备路径字符串的格式。看看下面 alexmerry 的回答。它们提供了检索此字符串的函数。
【解决方案2】:

虽然修改路径可能会起作用,但 Windows 文档明确表示您应该解析设备路径。

不过,您可以使用 CfgMgr32 API 来实现,使用 CM_Get_Device_Interface_PropertyW ()DEVPKEY_Device_InstanceId

#include <cfgmgr32.h>
#include <initguid.h> // needed for devpkey.h to parse properly
#include <devpkey.h>

#include <cassert>
#include <string>
#include <vector>

/*
 *   @brief The following retrieves the Device Instance ID from the main device path.
 *   @param device_path A device path that has the form of the following:
 *                      \\?\usb#vid_[VENDOR_ID]&pid_[PRODUCT_ID]#INSTANCE_ID#{[DEVICE_INTERFACE_GUID]}
 *
 *                      Where the following components are described as:
 *                          1. VENDOR_ID             - The vendor ID of the device.
 *                          2. PRODUCT_ID            - The product ID of the device.
 *                          3. INSTANCE_ID           - The unique ID generated when the device connects to the host.
 *                          4. DEVICE_INTERFACE_GUID - The GUID that describes the interface of the device.
 *                                                     This is NOT the same as the "Device Class GUID."
 *   @return The Device Instance ID (linked below). A Device Instance ID has the form of:
 *           <device-id>\<instance-id>
 *
 *           Example: USB\VID_2109&PID_0813\7&3981c8d6&0&2
 *   @see https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-instance-ids
 *   @see https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_device_interface_propertyw
 */
std::wstring map_path (LPCWSTR device_path) {
    ULONG buf_size = 0;
    DEVPROPTYPE type;
    CM_Get_Device_Interface_PropertyW(
        device_path, &DEVPKEY_Device_InstanceId, &type,
        nullptr, &buf_size, 0);

    std::vector<BYTE> buffer(buf_size);
    auto result = CM_Get_Device_Interface_PropertyW(
        device_path, &DEVPKEY_Device_InstanceId, &type,
        buffer.data(), &buf_size, 0);

    assert(result == CR_SUCCESS);
    assert(type == DEVPROP_TYPE_STRING);

    // buffer will be null-terminated
    return reinterpret_cast<wchar_t*>(buffer.data());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多