The IPortableDeviceManager interface can be used to enumerate WPD devices. The GetDevices method returns a list of device paths for available WPD devices. This device path is typically a PnP path and can be used later to connect to the device.

Error-checking has been omitted in the interests of brevity.

    HRESULT hr = S_OK;
    CComPtr<IPortableDeviceManager> spDevMgr;
    LPTSTR* ppszDeviceListArray = NULL;
    DWORD cdwDevices = 0;

    hr = CoCreateInstance(CLSID_PortableDeviceManager,
                            NULL,
                            CLSCTX_INPROC_SERVER,
                            IID_IPortableDeviceManager,
                            (VOID**) &spDevMgr);

    // Get a count of the devices available by passing
    // a NULL buffer
    hr = spDevMgr->GetDevices(NULL, &cdwDevices);

    // Allocate enough memory for the device path names
    ppszDeviceListArray = new LPTSTR[cdwDevices];

    // Get the list of device paths using the valid buffer
    hr = spDevMgr->GetDevices(ppszDeviceListArray, &cdwDevices);

And that's it! ppszDeviceListArray now contains the list of available WPD device paths. We can loop through this list to either get some more information about the devices or connect to the device. In the next part, we'll use the other methods of the IPortableDeviceManager interface to display information about each device.