如何使用设备实例 ID 打开设备的句柄? [英] How to open a handle to a device using its Device Instance ID?

查看:54
本文介绍了如何使用设备实例 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:

  1. [DEVICE_INTERFACE_GUID] - 这是设备接口类 GUID".这与设备设置类 GUID"不同.
  1. [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 classes CM_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆