【发布时间】:2020-01-14 21:18:54
【问题描述】:
我正在更新我的问题,以更好地反映我的实际目标。为了快速说明我最初的困惑,说“设备接口类 GUID”和Device Instance ID 之间存在一对一的关系是不正确的。一个设备可以有很多设备接口。正如 Ben Voigt 在 cmets 中所述,see this 了解更多信息。
如何在调用CM_Get_Child (...)函数后打开子设备的句柄?
以下面的代码片段为例:
#pragma comment (lib, "Setupapi.lib")
#pragma comment (lib, "Cfgmgr32.lib")
#include <iostream>
#include <Windows.h>
#include <Setupapi.h>
#include <Cfgmgr32.h>
#define GUID_STRING_SIZE 40
int main ()
{
CONFIGRET CMResult = CR_SUCCESS;
WCHAR DeviceInstanceID[] = L"USB\\VID_2109&PID_0813\\8&216C1825&0&4\0"; // Parent Device Instance ID.
DEVNODE ParentDeviceNode = (DWORD) 0; // A device instance handle. This handle is bounded to the local machine.
CMResult = CM_Locate_DevNode ((PDEVINST) &ParentDeviceNode, DeviceInstanceID, CM_LOCATE_DEVNODE_NORMAL);
if (CMResult != CR_SUCCESS)
{
std::cout << "No parent device node found." << std::endl;
return -1;
}
else
{
DEVINST NextChildDeviceNode = (DWORD) 0;
CMResult = CM_Get_Child ((PDEVINST) &NextChildDeviceNode, ParentDeviceNode, 0x0); // Gets the first child of the parent node. If this returns "CR_NO_SUCH_DEVNODE," then there is no child attached.
if (CMResult != CR_SUCCESS)
{
std::cout << "No child device node found." << std::endl;
return -2;
}
else
{
ULONG ChildInstanceIDBuffLength = 0;
CMResult = CM_Get_Device_ID_Size (&ChildInstanceIDBuffLength, NextChildDeviceNode, 0x0);
if (CMResult != CR_SUCCESS)
{
std::cout << "Could not get the size of the device instance ID of child device." << std::endl;
return -3;
}
else
{
WCHAR * ChildInstanceIDBuff = (WCHAR *) malloc (ChildInstanceIDBuffLength);
CMResult = CM_Get_Device_IDW (NextChildDeviceNode, ChildInstanceIDBuff, ChildInstanceIDBuffLength, 0x0);
if (CMResult != CR_SUCCESS)
{
std::cout << "Could not actual device instance ID string of child device" << std::endl;
return -4;
}
else
{
std::cout << "Found child device instance ID: ";
std::wcout << ChildInstanceIDBuff << std::endl;
/*
* Open handle to the child device node now!
*/
}
free (ChildInstanceIDBuff);
}
}
}
return 0;
}
如何使用新获得的子Device Instance ID 打开设备句柄? CreateFile (...) 需要完整的设备路径,其中包括缺少的“设备接口类 GUID”。
更具体地说,设备路径具有以下格式:\\?\usb#vid_2109&pid_0813#7&3981C8D6&0&2#{[DEVICE_INTERFACE_GUID]},其中:
- [DEVICE_INTERFACE_GUID] - 这是“设备接口类 GUID”。这与“设备设置类 GUID”不相同。
如果没有某种程度的蛮力(例如CM_Enumerate_Classes (...) 使用 CM_ENUMERATE_CLASSES_INTERFACE 标志),似乎没有一种简单的方法来获得这个“设备接口类 GUID”。 我是否可以调用一个函数来仅使用设备的“设备实例 ID”来获取设备句柄,这样我就可以调用 DeviceIoControl (...) 并查询有关设备的信息?
【问题讨论】:
-
一个设备可以实现多个设备接口...
-
@BenVoigt 那么,有没有办法获得这些接口的列表?我想知道的是,当我调用
CM_Get_Child (...)时,我得到了子设备的“Device Instance Handle”(即可用于在设备树)。怎样才能得到完整的设备路径,才能真正在设备上打开一个文件句柄来查询信息? -
有一种方法,我找到过一次,但是比较隐蔽,不知道有没有保留代码。同时我建议你写你的问题不要假设实例 ID 到设备接口路径的 1:1 映射。
-
你需要什么设备路径?
DEVPKEY_Device_PDOName适合你吗?我被问到 - 你是如何/从哪里获得 pDeviceID 的?那么你一开始有什么,最终目标是什么?