简体   繁体   中英

C++ - WinAPI get list of all connected USB devices

I'm trying to create a program that will categorize all the connected USB devices and their port GUID.

I found an example of how to get all the information from connected input devices:

#include <windows.h>
#include <iostream>

// Namespace
using namespace std;

// Main
int main()
{
    // Program
    cout << "USB Device Lister." << endl;

    // Get Number Of Devices
    UINT nDevices = 0;
    GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST));

    // Got Any?
    if (nDevices < 1)
    {
        // Exit
        cout << "ERR: 0 Devices?";
        cin.get();
        return 0;
    }

    // Allocate Memory For Device List
    PRAWINPUTDEVICELIST pRawInputDeviceList;
    pRawInputDeviceList = new RAWINPUTDEVICELIST[sizeof(RAWINPUTDEVICELIST) * nDevices];

    // Got Memory?
    if (pRawInputDeviceList == NULL)
    {
        // Error
        cout << "ERR: Could not allocate memory for Device List.";
        cin.get();
        return 0;
    }

    // Fill Device List Buffer
    int nResult;
    nResult = GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST));

    // Got Device List?
    if (nResult < 0)
    {
        // Clean Up
        delete[] pRawInputDeviceList;

        // Error
        cout << "ERR: Could not get device list.";
        cin.get();
        return 0;
    }

    // Loop Through Device List
    for (UINT i = 0; i < nDevices; i++)
    {
        // Get Character Count For Device Name
        UINT nBufferSize = 0;
        nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, // Device
            RIDI_DEVICENAME,                // Get Device Name
            NULL,                           // NO Buff, Want Count!
            &nBufferSize);                 // Char Count Here!

                                           // Got Device Name?
        if (nResult < 0)
        {
            // Error
            cout << "ERR: Unable to get Device Name character count.. Moving to next device." << endl << endl;

            // Next
            continue;
        }

        // Allocate Memory For Device Name
        WCHAR* wcDeviceName = new WCHAR[nBufferSize + 1];

        // Got Memory
        if (wcDeviceName == NULL)
        {
            // Error
            cout << "ERR: Unable to allocate memory for Device Name.. Moving to next device." << endl << endl;

            // Next
            continue;
        }

        // Get Name
        nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, // Device
            RIDI_DEVICENAME,                // Get Device Name
            wcDeviceName,                   // Get Name!
            &nBufferSize);                 // Char Count

                                           // Got Device Name?
        if (nResult < 0)
        {
            // Error
            cout << "ERR: Unable to get Device Name.. Moving to next device." << endl << endl;

            // Clean Up
            delete[] wcDeviceName;

            // Next
            continue;
        }

        // Set Device Info & Buffer Size
        RID_DEVICE_INFO rdiDeviceInfo;
        rdiDeviceInfo.cbSize = sizeof(RID_DEVICE_INFO);
        nBufferSize = rdiDeviceInfo.cbSize;

        // Get Device Info
        nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice,
            RIDI_DEVICEINFO,
            &rdiDeviceInfo,
            &nBufferSize);

        // Got All Buffer?
        if (nResult < 0)
        {
            // Error
            cout << "ERR: Unable to read Device Info.. Moving to next device." << endl << endl;

            // Next
            continue;
        }

        // Mouse
        if (rdiDeviceInfo.dwType == RIM_TYPEMOUSE)
        {
            // Current Device
            cout << endl << "Displaying device " << i + 1 << " information. (MOUSE)" << endl;
            wcout << L"Device Name: " << wcDeviceName << endl;
            cout << "Mouse ID: " << rdiDeviceInfo.mouse.dwId << endl;
            cout << "Mouse buttons: " << rdiDeviceInfo.mouse.dwNumberOfButtons << endl;
            cout << "Mouse sample rate (Data Points): " << rdiDeviceInfo.mouse.dwSampleRate << endl;
            if (rdiDeviceInfo.mouse.fHasHorizontalWheel)
            {
                cout << "Mouse has horizontal wheel" << endl;
            }
            else
            {
                cout << "Mouse does not have horizontal wheel" << endl;
            }
        }

        // Keyboard
        else if (rdiDeviceInfo.dwType == RIM_TYPEKEYBOARD)
        {
            // Current Device
            cout << endl << "Displaying device " << i + 1 << " information. (KEYBOARD)" << endl;
            wcout << L"Device Name: " << wcDeviceName << endl;
            cout << "Keyboard mode: " << rdiDeviceInfo.keyboard.dwKeyboardMode << endl;
            cout << "Number of function keys: " << rdiDeviceInfo.keyboard.dwNumberOfFunctionKeys << endl;
            cout << "Number of indicators: " << rdiDeviceInfo.keyboard.dwNumberOfIndicators << endl;
            cout << "Number of keys total: " << rdiDeviceInfo.keyboard.dwNumberOfKeysTotal << endl;
            cout << "Type of the keyboard: " << rdiDeviceInfo.keyboard.dwType << endl;
            cout << "Subtype of the keyboard: " << rdiDeviceInfo.keyboard.dwSubType << endl;
        }

        // Some HID
        else // (rdi.dwType == RIM_TYPEHID)
        {
            // Current Device
            cout << endl << "Displaying device " << i + 1 << " information. (HID)" << endl;
            wcout << L"Device Name: " << wcDeviceName << endl;
            cout << "Vendor Id:" << rdiDeviceInfo.hid.dwVendorId << endl;
            cout << "Product Id:" << rdiDeviceInfo.hid.dwProductId << endl;
            cout << "Version No:" << rdiDeviceInfo.hid.dwVersionNumber << endl;
            cout << "Usage for the device: " << rdiDeviceInfo.hid.usUsage << endl;
            cout << "Usage Page for the device: " << rdiDeviceInfo.hid.usUsagePage << endl;
        }

        // Delete Name Memory!
        delete[] wcDeviceName;
    }

    // Clean Up - Free Memory
    delete[] pRawInputDeviceList;

    // Exit
    cout << endl << "Finnished.";
    cin.get();
    return 0;
}

I tried to convert this code to get all the connected USB devices but failed. So my question is what is the best way to collect the data I'm looking for?

If you want all USB devices, not just "input" devices, then you need to use the same APIs that Device Manager does.

For example, all devices shown by Device Manager can be listed with the help of the SetupDiGetClassDevs function.

For listing USB devices, you'll want to use the enumerator parameter set to "USB" (the enumerator is the bus where the device is attached, for example it can be "PCI" , "PCMCIA" , "USB" for the main computer busses, and it can also be a secondary bus provided by an expansion device, eg "SCSI" , "FTDIBUS" , and so on). You may sometimes find that you're more interested in child devices than the USB-attached parent device itself.

Keep in mind that it is not enough just to comment // (rdi.dwType == RIM_TYPEHID) as you did in following sequence, since it will print only rdiDeviceInfo.hid.SOMETHING info. If device is not HID, I would expect some junk, or similar to be printed.

else // (rdi.dwType == RIM_TYPEHID)
        {
            // Current Device
            cout << endl << "Displaying device " << i + 1 << " information. (HID)" << endl;
            wcout << L"Device Name: " << wcDeviceName << endl;
            cout << "Vendor Id:" << rdiDeviceInfo.hid.dwVendorId << endl;
            cout << "Product Id:" << rdiDeviceInfo.hid.dwProductId << endl;
            cout << "Version No:" << rdiDeviceInfo.hid.dwVersionNumber << endl;
            cout << "Usage for the device: " << rdiDeviceInfo.hid.usUsage << endl;
            cout << "Usage Page for the device: " << rdiDeviceInfo.hid.usUsagePage << endl;
        }

I would recommend you to add some logging and breakpoints (to print number of devices, to print all device names etc.). If you don't solve it, please paste the code that you use for testing with precise issue explanation.

UPDATE:

GetRawInputDeviceList function

Remarks

The devices returned from this function are the mouse, the keyboard, and other Human Interface Device (HID) devices.

If your device is not HID don't expect to see it in a list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM