当转到 Windows 的“设备管理器”并单击(几乎)列表中的任何设备时,“常规”选项卡中的一条信息称为“位置”。那是一个字符串,可以是:
- 人类可读,例如“在 NVIDIA GeForce GTX 1080 上”
- 半有用的,例如“位置 0(内部高清音频总线)”或“PCI 总线 9,设备 0,功能 0”
- USB 位置,例如“Port_#0004.Hub_#0015”甚至是“0009.0000.0000.004.000.000.000.000.000”
该信息可通过 Windows 的统一设备属性模型API 获得。
我正在寻找的是从给定IMFActivate
对象中获取该信息。
有没有办法这样做?我找不到如何从该激活对象获取“设备”信息。我拥有的唯一数据是“符号链接”(在我的例子中,这个字符串:),\\?\usb#vid_04b4&pid_8888&mi_00#9&4fe28be&0&0000#{e5323777-f976-4f5b-9b55-b94699c46e44}\global
但该链接的格式与我在“位置”中看到的字符串完全不同。
因此我的问题是:如何获取设备的“位置”字符串,给定它的IMFActivate
对象?
更新
这是我用来“转换”符号链接的代码,由提供IMFActivate
的设备 id 字符串提供,可由 setup-api 函数识别,然后提取“位置字符串”:
CString symLink2Location(const CString & _symLink)
{
DEVINST di;
CString devId = _symLink;
devId = devId.Left( devId.Find(L"#{") );
devId.Replace(L"\\\\?\\", L"");
devId.Replace(L"#", L"\\");
const auto rc = CM_Locate_DevNodeW(&di, devId.GetBuffer(), CM_LOCATE_DEVNODE_NORMAL);
if(rc == CR_SUCCESS){
DEVPROPTYPE dpt;
ULONG sz = MAX_PATH;
WCHAR prop[MAX_PATH];
if(CM_Get_DevNode_PropertyW(di, &DEVPKEY_Device_LocationInfo, &dpt, (PBYTE)&prop, &sz, 0) == CR_SUCCESS){
if(dpt == DEVPROP_TYPE_STRING){
return prop;
}
}
}
return L"";
}
更新 2
devmgmt.msc
以下是“声音、视频和游戏控制器”下的 3 个音频输入设备:
- MS LifeCam Cinema (TM),位置:0000.0014.0000.013.003.000.000.000.000(符号链接
\\?\SWD#MMDEVAPI#{0.0.1.00000000}.{751fe058-cef2-4d28-bbeb-e438981938d7}#{2eef81be-33fa-4800-9670-1cd474972c3f}
:) - MS LifeCam Studio (TM),位置:0000.0014.0000.013.004.004.000.000.000(符号链接
\\?\SWD#MMDEVAPI#{0.0.1.00000000}.{59267d2e-940b-45f5-8655-45372787bd85}#{2eef81be-33fa-4800-9670-1cd474972c3f}
:) - SUB2r USB 3.0 高清网络摄像头,位置:0009.0000.0000.004.000.000.000.000.000(符号链接
\\?\SWD#MMDEVAPI#{0.0.1.00000000}.{26a4f608-cbd8-4206-b958-d57ee6847153}#{2eef81be-33fa-4800-9670-1cd474972c3f}
:)
所有 3 个都是 USB 设备,调用时会列出所有 3 个,MFEnumDeviceSources
但它们的“符号链接”不会解析为硬件设备。