如何使用设备实例 ID 打开设备的句柄? [英] How to open a handle to a device using its Device Instance ID?
问题描述
我正在更新我的问题,以更好地反映我实际追求的目标.为了快速说明我最初的困惑,说设备接口类 GUID"和 设备实例 ID.一个设备可以有多个设备接口.正如 Ben Voigt 在评论中指出的那样,参见此了解更多信息.
I am updating my question to better reflect what I was actually going after. To state a fact about my original confusion quickly, it is incorrect to say that there is a 1-to-1 relationship between "Device Interface Class GUID" and the Device Instance ID. A device can have many device interfaces. As Ben Voigt noted in the comments, see this for more information.
调用CM_Get_Child (...)
函数?
以下面的代码片段为例:
Take the following code snip as an example:
#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;
}
如何使用新获取的子设备实例ID打开设备的句柄? CreateFile (...)
需要完整的设备路径,其中包括缺少的设备接口类 GUID".
How can I use the newly obtained child Device Instance ID to open a handle to the device? CreateFile (...)
requires the complete device path, which includes the missing "Device Interface Class GUID."
更具体地说,设备路径具有以下格式:\\?\usb#vid_2109&pid_0813#7&3981C8D6&0&2#{[DEVICE_INTERFACE_GUID]}
,其中:
More specifically, a device path has the following format:
\\?\usb#vid_2109&pid_0813#7&3981C8D6&0&2#{[DEVICE_INTERFACE_GUID]}
, where:
- [DEVICE_INTERFACE_GUID] - 这是设备接口类 GUID".这与设备设置类 GUID"不同.
- [DEVICE_INTERFACE_GUID] - This the "Device Interface Class GUID." This is NOT the same as the "Device Setup Class GUID."
如果没有某种程度的蛮力(例如 CM_Enumerate_Classes (...)
使用 CM_ENUMERATE_CLASSES_INTERFACE 标志).是否可以调用一个函数来获取设备句柄,仅使用其设备实例 ID",然后我就可以调用 DeviceIoControl (...)
并查询有关信息设备?
There does not appear to be an easy way to get this "Device Interface Class GUID" without some level of brute force (e.g. CM_Enumerate_Classes (...)
using the CM_ENUMERATE_CLASSES_INTERFACE flag). Is there a function I can call to get a handle to a device using only its "Device Instance ID," so that I can then call DeviceIoControl (...)
and query information about the device?
推荐答案
您可以使用 CM_Enumerate_Classes
函数 带有 CM_ENUMERATE_CLASSES_INTERFACE
标志(需要 Windows 8)以获得可能的值作为第三个参数传递SetupDiEnumDeviceInterfaces
.
You can use the CM_Enumerate_Classes
function with the CM_ENUMERATE_CLASSES_INTERFACE
flag (Requires Windows 8) to get possible values to pass as that third parameter of SetupDiEnumDeviceInterfaces
.
从 Windows 8 和更高版本的操作系统开始,调用者可以使用 ulFlags
成员来指定 CM_Enumerate_Classes
应该返回哪些设备类.在 Windows 8 之前,CM_Enumerate_Classes
仅返回设备设置类.
Beginning with Windows 8 and later operating systems, callers can use the
ulFlags
member to specify which device classesCM_Enumerate_Classes
should return. Prior to Windows 8,CM_Enumerate_Classes
returned only device setup classes.
请注意,查找设备上的所有接口对于诊断驱动程序问题和/或逆向工程从废料中拯救出来的随机外围设备非常有用.但是,在调用 CreateFile
之前,您应该很早就知道您正在处理的接口类是什么.
Note that finding all interfaces on a device is very useful for diagnosing driver problems and/or reverse engineering random peripherals rescued from scrap. But you should know what interface class you are dealing with long before you get to the point of calling CreateFile
.
这篇关于如何使用设备实例 ID 打开设备的句柄?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!