Windows: how do I determine the drivers that the system will load for a composite USB device?

There is a composite USB device, you know the Hub and the port number where it is connected, you can get descriptors. I want to know what drivers the system will load for each of the functions in this device. The GUID_DEVINTERFACE_USB_DEVICE enumeration via SetupAPI allows you to determine the path to the driver, but for composite devices, only the composite device driver is obtained. Where to look?

 3

1 answers

For composite devices, you can use SetupAPI to get a list of child devices (DEVPKEY_Device_Children) and output their drivers. The property returns a list of InstanceID child devices separated by a null byte (REG_SZ_MULTI). Then you need to enumerate all the devices, filter the necessary devices by InstanceID, and you can get information about the driver.

Sample C++ code for displaying the driver name, the path to the INF file, and the driver version for all USB devices and their child devices:

#pragma comment(lib,"Setupapi.lib")

#include <Windows.h>
#include <Setupapi.h>
#include <winusb.h>
#include <stdlib.h>
#include <Devpkey.h>
#include <iostream>
#include <string>
#include <memory>
#include <strsafe.h>


void ErrorMes(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    wprintf(L"%s failed with error %d: %s", 
        lpszFunction, dw, lpMsgBuf);     

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);

}


/*Вывод информации об устройстве с указанным InstanceID*/
BOOL PrintDevice(wchar_t* id)
{
    unsigned index;
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    TCHAR id_upper[1024]=L"";
    TCHAR buf[1024]=L"";
    TCHAR match[1024];
    DEVPROPTYPE dpt=0;      

    for(int i=0;i<wcslen(id);i++){
        id_upper[i]=toupper(id[i]);//преобразование в заглавные буквы
    }       

    // List all connected devices
    hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
    for (index = 0; ; index++) {
        DeviceInfoData.cbSize = sizeof(DeviceInfoData);
        if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData)) {
            return FALSE;     // no match
        }

        BOOL res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData,
                        &DEVPKEY_Device_InstanceId,&dpt,(PBYTE)buf,1000,NULL,0);
        if(res==FALSE)continue;


        if(wcscmp(buf,id_upper)==0){
            //устройство найдено
            res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData,
                        &DEVPKEY_Device_DeviceDesc,&dpt,(PBYTE)buf,1000,NULL,0);

            //name
            if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
            else wprintf(L"\n\t * %s\n ",buf);          

            //service
            res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData,
                    &DEVPKEY_Device_Service,&dpt,(PBYTE)buf,1000,NULL,0);

            if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
            else wprintf(L"\tDriver: %s\n ",buf);

            //driver
            res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData,
                &DEVPKEY_Device_DriverInfPath,&dpt,(PBYTE)buf,1000,NULL,0);

            if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
            else wprintf(L"\tINF File: %s\n ",buf);         

            //version
            res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData,
                &DEVPKEY_Device_DriverVersion,&dpt,(PBYTE)buf,1000,NULL,0);

            if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
            else wprintf(L"\tVersion: %s\n ",buf);  

            return TRUE;
        }


    }
    return FALSE;//устройство не найдено
}


int main()
{
    setlocale(LC_ALL,"Russian");

    GUID guid;

    HRESULT hr = CLSIDFromString(L"{A5DCBF10-6530-11D2-901F-00C04FB951ED}", (LPCLSID)&guid);//USB device

    HDEVINFO deviceInfoHandle = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    if (deviceInfoHandle != INVALID_HANDLE_VALUE)
    {
        int deviceIndex = 0;
        while (true)
        {
            SP_DEVICE_INTERFACE_DATA deviceInterface = { 0 };
            deviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

            //перечисление устройств
            if (SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &guid, deviceIndex, &deviceInterface))
            {
                DWORD cbRequired = 0;

                SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, 0, 0, &cbRequired, 0);
                if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
                {                    
                   //получение информации о устройстве
                   DEVPROPTYPE dpt=0;
                   wchar_t buffer[1000]=L"";
                   DWORD RequiredSize = 0;
                   SP_DEVINFO_DATA devinfo = { 0 };
                               devinfo.cbSize = sizeof(SP_DEVINFO_DATA);

                   BOOL success = SetupDiEnumDeviceInfo(deviceInfoHandle, deviceIndex, &devinfo);
                   if(success==FALSE){ErrorMes(L"SetupDiEnumDeviceInfo");}

                   BOOL res;

                   //location
                   res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo,
                    &DEVPKEY_Device_LocationInfo,&dpt,(PBYTE)buffer,1000,NULL,0);

                   if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
                   else wprintf(L"%s\n",buffer);

                   //name
                   res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo,
                    &DEVPKEY_Device_DeviceDesc,&dpt,(PBYTE)buffer,1000,NULL,0);

                   if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
                   else wprintf(L"Name: %s\n",buffer);

                   //service
                   res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo,
                    &DEVPKEY_Device_Service,&dpt,(PBYTE)buffer,1000,NULL,0);

                   if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
                   else wprintf(L"Driver: %s\n",buffer);

                   //driver
                   res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo,
                    &DEVPKEY_Device_DriverInfPath,&dpt,(PBYTE)buffer,1000,NULL,0);

                   if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
                   else wprintf(L"INF file: %s\n",buffer);

                   //version
                   res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo,
                    &DEVPKEY_Device_DriverVersion,&dpt,(PBYTE)buffer,1000,NULL,0);

                   if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty");
                   else wprintf(L"Version: %s\n",buffer);


                   //children
                   res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo,
                    &DEVPKEY_Device_Children,&dpt,(PBYTE)buffer,1000,NULL,0);

                   if(res!=FALSE){
                       printf("Children: \n");
                       wchar_t* p=buffer;//указатель на текущий элемент REG_SZ_MULTI

                       //вывод дочерних устройств
                       while(true){
                        if(wcscmp(p,L"")==0)break;
                        PrintDevice(p); 
                        p+=wcslen(p)+1; //переход к следующему элементу REG_SZ_MULTI                        
                       }

                   }//endif                     

                }
            }
            else
            {
                break;
            }

            ++deviceIndex;
            printf("\n");
        }//end while

        SetupDiDestroyDeviceInfoList(deviceInfoHandle);
    }          

    system("PAUSE");
    return 0;
}

Sample output:

USB devices

 2
Author: MSDN.WhiteKnight, 2017-11-06 11:52:48