My SetupDiEnumDeviceInterfaces is not working

匆匆过客 提交于 2019-11-30 20:32:33

Have a go with this.


I have tried to hack your original code about as little as possible; the following codes (for me at least) get through to the inner while(SetupDiEnumDeviceInterfaces..):

void DeviceManager::GetDeviceUSB(std::string vid, std::string pid)
{
    DWORD deviceIndex = 0;
    deviceInfoData.cbSize = sizeof(deviceInfoData);

    //buried somewhere deep in the ddk
    static GUID GUID_DEVINTERFACE_USB_HUB={ 0xf18a0e88, 0xc30c, 0x11d0, {0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8} };
    static GUID GUID_DEVINTERFACE_USB_DEVICE ={ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
    static GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER={ 0x3abf6f2d, 0x71c4, 0x462a, {0x8a, 0x92, 0x1e, 0x68, 0x61, 0xe6, 0xaf, 0x27}};

    //get usb device interfaces
    HDEVINFO deviceInterfaceSet=SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_DEVICEINTERFACE);


    while(SetupDiEnumDeviceInfo(deviceInterfaceSet, deviceIndex, &deviceInfoData))
    {
        deviceInfoData.cbSize = sizeof(deviceInfoData);

        ULONG IDSize;
        CM_Get_Device_ID_Size(&IDSize, deviceInfoData.DevInst, 0);

        TCHAR* deviceID = new TCHAR[IDSize];

        CM_Get_Device_ID(deviceInfoData.DevInst, deviceID, MAX_PATH, 0);

        if( deviceID[8]==vid.at(0) && deviceID[9]==vid.at(1) && deviceID[10]==vid.at(2) && deviceID[11]==vid.at(3) && //VID
            deviceID[17]==pid.at(0) && deviceID[18]==pid.at(1) && deviceID[19]==pid.at(2) && deviceID[20]==pid.at(3)) //PID
        {
            DWORD deviceInterfaceIndex = 0;
            deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);

            while(SetupDiEnumDeviceInterfaces(deviceInterfaceSet, &deviceInfoData, &GUID_DEVINTERFACE_USB_DEVICE, deviceInterfaceIndex, &deviceInterfaceData))
            {
                deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
                std::cout << deviceInterfaceIndex << std::endl;

                //get some more details etc
                //DWORD requiredBufferSize;
                //SetupDiGetDeviceInterfaceDetail(deviceInterfaceSet, &deviceInterfaceData, NULL, 0, &requiredBufferSize, 

                deviceInterfaceIndex++;
            }
        }

        deviceIndex++;
    }
}



afaik, this method picks up the same devices as with your OP constructor call:
(NB: i included some other useful interface guids)

deviceInfoSet = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); //Gets all Devices


but i am doing this to get the device interfaces:

// /coughs/ you might want to put back the DIGCF_PRESENT flag i removed for testing
HDEVINFO deviceInterfaceSet=SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_DEVICEINTERFACE); 


i also pass the deviceInfoData to SetupDiEnumDeviceInterfaces since according to the documentation:

A pointer to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet. This parameter is optional and can be NULL. If this parameter is specified, SetupDiEnumDeviceInterfaces constrains the enumeration to the interfaces that are supported by the specified device. If this parameter is NULL, repeated calls to SetupDiEnumDeviceInterfaces return information about the interfaces that are associated with all the device information elements in DeviceInfoSet. This pointer is typically returned by SetupDiEnumDeviceInfo.



    [Edit: additional notes (; as requested ;) ]


Your USB device has an associated setup class and interface class(es):

From the device setup classes documentation:

The device setup class defines the class installer and class co-installers that are involved in installing the device

From the device interface classes documentation:

A device interface class is a way of exporting device and driver functionality to other system components, including other drivers, as well as user-mode applications


Also, see this handy comparison
Also, this related doc is useful


So:

deviceInfoSet = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL,DIGCF_PRESENT|DIGCF_ALLCLASSES);

this is retrieving all setup class information sets and filtering on "USB"


You could do this:

deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES|DIGCF_DEVICEINTERFACE);`

this retrieves class information sets for devices that support a device interface of any class. (Applying an emumerator ID s/a "USB" seems to have no affect) Crucially however: The function adds to the device information set a device information element that represents such a device and then adds to the device information element a device interface list that contains all the device interfaces that the device supports.


(And note: SP_DEVINFO_DATA.ClassGuid is always the GUID of the device's setup class)


Afaik:
but you then still need to provide an InterfaceClassGuid when invoking SetupDiEnumDeviceInterfaces() ~tbh, i don't really understand why this would be necessary if the caller is providing the optional DeviceInfoData but since it's all closed source, how would i know !? :)


&Here is info regarding GUID_DEVINTERFACE_USB_DEVICE


(; disclaimer: i do not work for M$; do treat the above infos with suspicion :) && of course dyoRs ;)



hope this helps, best of luck!

The problem starts with how SetupDiGetClassDevs is called.

If you are looking to get a device path, use SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE ,,,)

SetupDiEnumDeviceInterfaces fails with error 259 if SetupDiGetClassDevs is given the wrong GUID in ClassGuid which MS Help says is A pointer to the GUID for a device setup class or a device interface class.

Include file devguid.h contains a set of GUID_DEVCLASS values. These are NOT the same as GUID_DEVINTERFACE_* values which are the one you need.

Use #include <uuids.h> which includes ksuuids.h where you'll find GUID_DEVINTERFACE_* values.

There's a more detailed explanation on my website, with some source code that should help in correctly enumerating USB devices.

See http://pixcl.com/SetupDiEnumInterfaces_Fail.htm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!