visual-c++usb

list USB device with specified VID and PID without using Windows driver Kit


is there a way to find a USB device with specified VID and PID on windows without involve calling to WDK functions?


Solution

  • The code below will do the trick:

    static const char dongleVid[] = {'1', '2', '3', '4', '\0'};
    static const char donglePid[] = {'5', '6', '7', '8', '\0'};
    static const LPCTSTR arPrefix[3] = {TEXT("VID_"), TEXT("PID_"), TEXT("MI_")};
    
    const std::string requiredVid = boost::to_upper_copy(std::string(arPrefix[0]) + std::string(dongleVid));
    const std::string requiredPid = boost::to_upper_copy(std::string(arPrefix[1]) + std::string(donglePid));
    unsigned i, j;
    
    DWORD dwSize, dwPropertyRegDataType;
    OSVERSIONINFO osvi;
    CONFIGRET r;
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    
    TCHAR szDeviceInstanceID[MAX_DEVICE_ID_LEN];
    TCHAR szDesc[1024];
    LPTSTR pszToken, pszNextToken;
    TCHAR szVid[MAX_DEVICE_ID_LEN], szPid[MAX_DEVICE_ID_LEN], szMi[MAX_DEVICE_ID_LEN];
    
    #ifdef UNICODE
    FN_SetupDiGetDeviceProperty fn_SetupDiGetDeviceProperty = (FN_SetupDiGetDeviceProperty)
        GetProcAddress(GetModuleHandle(TEXT("Setupapi.dll")), "SetupDiGetDevicePropertyW");
    #else
    FN_SetupDiGetDeviceProperty fn_SetupDiGetDeviceProperty = (FN_SetupDiGetDeviceProperty)
        GetProcAddress(GetModuleHandle(TEXT("Setupapi.dll")), "SetupDiGetDevicePropertyA");
    #endif
    
    // List all connected USB devices
    hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        return false;
    }
    // Find the ones that are driverless
    for (i = 0; ; i++)
    {
        DeviceInfoData.cbSize = sizeof(DeviceInfoData);
        if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
        {
            break;
        }
    
        r = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID , MAX_PATH, 0);
        if (r != CR_SUCCESS)
        {
            continue;
        }
    
        SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,
                                              &dwPropertyRegDataType, (BYTE*)szDesc,
                                              sizeof(szDesc),   // The size, in bytes
                                              &dwSize);
    
        // Retreive the device description as reported by the device itself
        memset(&osvi, 0, sizeof(OSVERSIONINFO));
        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    
        pszToken = _tcstok_s(szDeviceInstanceID , TEXT("\\#&"), &pszNextToken);
        szVid[0] = TEXT('\0');
        szPid[0] = TEXT('\0');
        szMi[0] = TEXT('\0');
        while (pszToken != NULL)
        {
            for (j = 0; j < 3; j++)
            {
                if (_tcsncmp(pszToken, arPrefix[j], lstrlen(arPrefix[j])) == 0)
                {
                    switch (j)
                    {
                        case 0:
                            _tcscpy_s(szVid, ARRAY_SIZE(szVid), pszToken);
                            break;
                        case 1:
                            _tcscpy_s(szPid, ARRAY_SIZE(szPid), pszToken);
                            break;
                        case 2:
                            _tcscpy_s(szMi, ARRAY_SIZE(szMi), pszToken);
                            break;
                        default:
                            break;
                    }
                }
            }
            pszToken = _tcstok_s(NULL, TEXT("\\#&"), &pszNextToken);
        }
    
    
        std::string foundVid = boost::to_upper_copy(std::string(szVid));
        std::string foundPid = boost::to_upper_copy(std::string(szPid));
    
        if (requiredVid == foundVid && requiredPid == foundPid)
        {
            return true;
        }
    }