Win32 C++ Enumerate "Internal Storage" File System of devices such as iPhone and MTP-USB digital camera
22:40 17 Oct 2025

In order to enumerate the content of connected devices such as iPhones and a digital camera connected via MTP (USB), which aren't simple file drives, I looked at the example WPD API Sample. The relevant file there is ContentEnumeration.cpp.

The code generally is:

HRESULT                         hr = S_OK;
CComPtr pContent;
hr = pDevice->Content(&pContent);
RecursiveEnumerate(WPD_DEVICE_OBJECT_ID, pContent);

with RecursiveEnumerate defined as:

void RecursiveEnumerate(
    PCWSTR                  pszObjectID,
    IPortableDeviceContent* pContent)
{
    CComPtr pEnumObjectIDs;

    // Print the object identifier being used as the parent during enumeration.
    printf("%ws\n",pszObjectID);


    HRESULT hr = pContent->EnumObjects(0,               // Flags are unused
                                       pszObjectID,     // Starting from the passed in object
                                       NULL,            // Filter is unused
                                       &pEnumObjectIDs);
    // Loop calling Next() while S_OK is being returned.
    while(hr == S_OK)
    {
        DWORD  cFetched = 0;
        PWSTR  szObjectIDArray[NUM_OBJECTS_TO_REQUEST] = {0};
        hr = pEnumObjectIDs->Next(NUM_OBJECTS_TO_REQUEST,   // Number of objects to request on each NEXT call
                                  szObjectIDArray,          // Array of PWSTR array which will be populated on each NEXT call
                                  &cFetched);               // Number of objects written to the PWSTR array
        if (SUCCEEDED(hr))
        {
            // Traverse the results of the Next() operation and recursively enumerate
            // Remember to free all returned object identifiers using CoTaskMemFree()
            for (DWORD dwIndex = 0; dwIndex < cFetched; dwIndex++)
            {
                RecursiveEnumerate(szObjectIDArray[dwIndex],pContent);

                // Free allocated PWSTRs after the recursive enumeration call has completed.
                CoTaskMemFree(szObjectIDArray[dwIndex]);
                szObjectIDArray[dwIndex] = NULL;
            }
        }
    }
}

For simple connected USB file drives, this gives the right file/folder contents, but for iPhones and MTP-USB devices it doesn't. For those devices the output is

o9900
o98FF
o98FE
o98FD
etc.

Windows Explorer allows those devices to be expanded to show an "Internal Storage" or "Device Storage" pseudo-folder, and the child objects of that folder are real folders such as 202403_ and files underneath that can be manipulated. Does anyone know how the real contents can be accessed?

c++ winapi