Search code examples
c++visual-studio-2010windows-7usbwmi

Getting Windows USB caption field from WMI, using C++


I want to iterate through the Win32_USBControllerDevice outputting the USB device captions.

The examples I have found are in C#, Powershell or Python.

Here is a fragment of my code:

bool can_continue = true;
HRESULT result;
//...
        IEnumWbemClassObject* pEnumerator = NULL;
        if (can_continue)
        {
            result = pSvc->ExecQuery(L"WQL", 
                                     L"Select * From Win32_USBControllerDevice",
                                     WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
                                     NULL,
                                     &pEnumerator);
            if (result != S_OK)
            {
                status = TF_DEVICE_COM_USB_QUERY_FAILED;
                error_text = "Query for Win32_USBControllerDevice failed";
                can_continue = false;
            }
        }
        if (can_continue)
        {
            //  Iterate through the USB devices, looking for the LeCroy o'scope.
            IWbemClassObject *pclsObj = NULL;
            ULONG uReturn = 0;

            std::ostringstream name_stream;
            while (pEnumerator)
            {
                result = pEnumerator->Next(WBEM_INFINITE, 1, 
                                           &pclsObj, &uReturn);

                if(0 == uReturn)
                {
                    break;
                }

                VARIANT vtProp;
                result = pclsObj->Get(L"Dependent", 0, &vtProp, 0, 0);
                const _bstr_t device_name = vtProp.bstrVal;
                OutputDebugStringA("USB Device found: ");
                OutputDebugStringA(device_name);
                OutputDebugStringA("\r\n");
                VariantClear(&vtProp);

                pclsObj->Release();
            }

        }

The Win32_USBControllerDevice class has the fields:

class Win32_USBControllerDevice : CIM_ControlledBy
{
  uint32                NegotiatedDataWidth;
  uint64                NegotiatedSpeed;
  uint16                AccessState;
  uint32                NumberOfHardResets;
  uint32                NumberOfSoftResets;
  CIM_USBController REF Antecedent;
  CIM_LogicalDevice REF Dependent;
};

The CIM_LogicalDevice has the fields:

class CIM_LogicalDevice : CIM_LogicalElement
{
  string   Caption;
  string   Description;
  datetime InstallDate;
  string   Name;
  string   Status;
  uint16   Availability;
  uint32   ConfigManagerErrorCode;
  boolean  ConfigManagerUserConfig;
  string   CreationClassName;
  string   DeviceID;
  uint16   PowerManagementCapabilities[];
  boolean  ErrorCleared;
  string   ErrorDescription;
  uint32   LastErrorCode;
  string   PNPDeviceID;
  boolean  PowerManagementSupported;
  uint16   StatusInfo;
  string   SystemCreationClassName;
  string   SystemName;
};

The devices in the output of the above fragment (computer name removed):

USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\ROOT_HUB\\4&370B413&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\ROOT_HUB20\\4&31D14255&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_058F&PID_6364\\058F63646476"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_058F&PID_6364&MI_00\\6&82F8931&0&0000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_GENERIC-&PROD_SD/MMC&REV_1.00\\7&1C4905A4&0&058F63646476&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_GENERIC-&PROD_COMPACT_FLASH&REV_1.01\\7&1C4905A4&0&058F63646476&1"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_GENERIC-&PROD_SM/XD-PICTURE&REV_1.02\\7&1C4905A4&0&058F63646476&2"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_GENERIC-&PROD_MS/MS-PRO&REV_1.03\\7&1C4905A4&0&058F63646476&3"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_058F&PID_6364&MI_01\\6&82F8931&0&0001"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="HID\\VID_058F&PID_6364&MI_01\\7&918E966&0&0000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_272C&PID_7D13\\5&2080E735&0&6"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_04B4&PID_00F1\\01.00.001__USB:2.0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\ROOT_HUB20\\4&2AB741E&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\ROOT_HUB\\4&270802C8&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\ROOT_HUB\\4&10B856B0&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\ROOT_HUB\\4&7274EB2&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\ROOT_HUB\\4&276DDCD3&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_046D&PID_C063\\5&3A297DC0&0&1"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="HID\\VID_046D&PID_C063\\6&179AEF98&0&0000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_413C&PID_2105\\5&3A297DC0&0&2"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="HID\\VID_413C&PID_2105\\6&F6A3C73&0&0000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\ROOT_HUB\\4&299C35A7&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_0A5C&PID_21E8\\00190E19540F"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTH\\MS_RFCOMM\\6&36F407EC&1&0"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTH\\MS_BTHBRB\\6&36F407EC&1&1"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{00001105-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{00001108-0000-1000-8000-00805F9B34FB}_LOCALMFG&000F\\7&1DE6EB2&0&D08A55436A2B_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{0000110A-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{0000110B-0000-1000-8000-00805F9B34FB}_LOCALMFG&000F\\7&1DE6EB2&0&D08A55436A2B_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{0000110C-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{0000110C-0000-1000-8000-00805F9B34FB}_LOCALMFG&000F\\7&1DE6EB2&0&D08A55436A2B_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{0000110E-0000-1000-8000-00805F9B34FB}_LOCALMFG&000F\\7&1DE6EB2&0&D08A55436A2B_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{00001112-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{00001115-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{0000111E-0000-1000-8000-00805F9B34FB}_LOCALMFG&000F\\7&1DE6EB2&0&D08A55436A2B_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{0000111F-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{00001132-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{00001800-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{00001801-0000-1000-8000-00805F9B34FB}_VID&00010075_PID&0100\\7&1DE6EB2&0&9C2A83FAE93F_C00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{24DF01A9-3E4F-4C9F-9F66-5AA8AB14F8F4}_LOCALMFG&0000\\7&1DE6EB2&0&000000000000_00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{6E0C8F4C-D928-4852-B6B2-F0F0E0D126FA}_LOCALMFG&0000\\7&1DE6EB2&0&000000000000_00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTHENUM\\{84A1E9B8-12BA-4A9C-8AB0-A43784E0D149}_LOCALMFG&0000\\7&1DE6EB2&0&000000000000_00000000"
USB Device found: \root\cimv2:Win32_PnPEntity.DeviceID="BTH\\MS_BTHPAN\\6&36F407EC&1&2"

does not match my Python Script output:

USB Root Hub
USB Root Hub
USB Composite Device
USB Mass Storage Device
Generic- SD/MMC USB Device
Generic- Compact Flash USB Device
Generic- SM/xD-Picture USB Device
Generic- MS/MS-Pro USB Device
USB Input Device
HID-compliant device
IAR Systems I-jet Probe
Cypress USB StreamerExample
USB Root Hub
USB Root Hub
USB Root Hub
USB Root Hub
USB Root Hub
USB Input Device
HID-compliant mouse
USB Input Device
HID Keyboard Device
USB Root Hub
Broadcom BCM20702 Bluetooth 4.0 USB Device
Bluetooth Device (RFCOMM Protocol TDI) #3
Microsoft Bluetooth Enumerator
Bluetooth OPP
Bluetooth Headset
Bluetooth AV Source
Bluetooth AV
Bluetooth AV Remote Control Target
Bluetooth AV Remote Control Target
Bluetooth Remote Control
Bluetooth Headset AG
Bluetooth Personal Area Network User (PANU)
Bluetooth Hands-free
Bluetooth Hands-free AG
Bluetooth Message Access
GAP Protocol
GATT Protocol
Bluetooth Hands-free Audio
Bluetooth L2CAP Interface
Bluetooth Remote Control
Bluetooth Device (Personal Area Network) #3

Questions:
1) How do I get "Caption" field, using C++?
(The Python script is printing the "caption" field.)

2) What MSDN references are used in determining how to access the "caption" field?

Environment:
Windows 7
Visual Studio 2010
C++ GUI project using MFC


Solution

  • The Dependent field of the "Win32_USBControllerDevice" is a reference.
    The solution is to extract the Device ID from the query and use it to query the Win32_PnPEntity table.

    Also, beware that the conversion from _bstr_t type to std::string may append '\0' at the end of the std::string (the std::string does not need terminating nul characters).

    Here's the additional code:

        IWbemClassObject *pclsObj = NULL;
        ULONG uReturn = 0;
    
        std::ostringstream name_stream;
        while (pEnumerator)
        {
            result = pEnumerator->Next(WBEM_INFINITE, 1, 
                                       &pclsObj, &uReturn);
    
            if(0 == uReturn)
            {
                break;
            }
    
            VARIANT vtProp;
            CIMTYPE pType;
            result = pclsObj->Get(L"Dependent", 0, &vtProp, &pType, 0);
            _bstr_t device_name_bstr = vtProp.bstrVal;
            std::string device_id = Convert_Bstr_to_string(device_name_bstr);
    
            // Create the Device ID string for the PnPEntity search.
            std::string::size_type  str_iter = device_id.find('"');
            while (str_iter != std::string::npos)
            {
                device_id.erase(str_iter, 1);
                str_iter = device_id.find('"');
            }
            str_iter = device_id.find('=');
            device_id.erase(0, str_iter + 1);
    
            //  Query the Win32_PnPEntity database for the device ID.
            std::string query = "Select * From Win32_PnPEntity Where DeviceID=\'";
            query += device_id;
            query += "\'";
            IEnumWbemClassObject* p_device_enumerator = NULL;
            _bstr_t     query_bstr(query.c_str());
            result = pSvc->ExecQuery(L"WQL", 
                                     query_bstr,
                                     WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
                                     NULL,
                                     &p_device_enumerator);
            IWbemClassObject *p_device_obj = NULL;
            uReturn = 0;
            while (p_device_enumerator)
            {
                result = p_device_enumerator->Next(WBEM_INFINITE, 1, 
                                                   &p_device_obj, &uReturn);
    
                if(0 == uReturn)
                {
                    break;
                }
    
                VARIANT vtProp;
                CIMTYPE pType;
                result = p_device_obj->Get(L"Caption", 0, &vtProp, &pType, 0);
                _bstr_t usb_device_name_bstr = vtProp.bstrVal;
                const std::string   usb_device_name = Convert_Bstr_to_string(usb_device_name_bstr);
                OutputDebugStringA("USB Device found: ");
                OutputDebugStringA(usb_device_name.c_str());
                OutputDebugStringA("\r\n");
                VariantClear(&vtProp);
                p_device_obj->Release();
            }
    
            VariantClear(&vtProp);
    
            pclsObj->Release();
        }