rewrite this code to store the data in a std container instead of qjsonobject
do not emit anything like "... continues the same"

struct EnumFilesConfig
{
    int  maxNestLevel = 0;
    std::unordered_map<int, int> maxItemsPerLevel;
    bool captureFoldersOnly = false;
    int  currentLevel       = 0;
};

DuplicateTracker enumFilesDuplicateTracker;

template <typename T>
void enumFiles(const T& t, QJsonObject& jsonObject, EnumFilesConfig config = {})
{
	VMSTART // VM_F446_W

    HRESULT hr                = S_FALSE;
    CComPtr<IShellItem> pItem = NULL;

    if constexpr (std::is_same_v<T, GUID>) // FOLDERID_Desktop, FOLDERID_Documents, FOLDERID_Downloads etc
        hr = SHCreateItemInKnownFolder(t, KF_FLAG_DEFAULT, nullptr, IID_PPV_ARGS(&pItem));
    else if constexpr (std::is_same_v<T, QString>)
        hr = SHCreateItemFromParsingName(t.toStdWString().c_str(), nullptr, IID_PPV_ARGS(&pItem));
    else if constexpr (std::is_array_v<T> || std::is_same_v<T, wchar_t*>)
        hr = SHCreateItemFromParsingName(t, nullptr, IID_PPV_ARGS(&pItem));
    if (hr != S_OK || !pItem)
        return;



    const auto getFileProperty = [](CComPtr<IPropertyStore> pPropertyStore, const PROPERTYKEY& key) -> QByteArray
    {
        VMSTART // VM_F464_W

        PROPVARIANT propvar;
        PropVariantInit(&propvar);
        HRESULT hr = pPropertyStore->GetValue(key, &propvar);
        if (FAILED(hr))
        {
            //qq << "GetValue failed with HRESULT:" << hr;
            PropVariantClear(&propvar);
            return "";
        }

        QString result;
        switch (propvar.vt)
        {
            case VT_LPWSTR:  // Wide string (pointer to a wide string)
            if (propvar.pwszVal != NULL)
                result = QString::fromWCharArray(propvar.pwszVal);
            break;
    
            case VT_BSTR:  // Binary string
            if (propvar.bstrVal != NULL)
                result = QString::fromWCharArray(propvar.bstrVal);
            break;
    
            case VT_UI4:  // Unsigned 32-bit integer
            result = QString::number(propvar.ulVal);
            break;
    
            case VT_UI8:  // Unsigned 64-bit integer
            result = QString::number(propvar.uhVal.QuadPart);
            break;
    
            case VT_I4:  // Signed 32-bit integer
            result = QString::number(propvar.lVal);
            break;
    
            case VT_I8:  // Signed 64-bit integer
            result = QString::number(propvar.hVal.QuadPart);
            break;
    
            case VT_BOOL:  // Boolean value
            result = (propvar.boolVal == VARIANT_TRUE) ? "True" : "False";
            break;
    
            case VT_VECTOR | VT_LPWSTR:
            {
                QStringList stringList;
                for (ULONG i = 0; i < propvar.calpwstr.cElems; i++)
                {
                    if (propvar.calpwstr.pElems[i] != NULL)
                        stringList << QString::fromWCharArray(propvar.calpwstr.pElems[i]);
                }
                result = stringList.join(", ");
            }
            break;
    
            case VT_FILETIME:  // File time (dates/timestamps)
            {
                SYSTEMTIME systemTime;
                FileTimeToSystemTime(&propvar.filetime, &systemTime);
                result = QString("%1-%2-%3 %4:%5:%6")
                    .arg(systemTime.wYear)
                    .arg(systemTime.wMonth, 2, 10, QChar('0'))
                    .arg(systemTime.wDay, 2, 10, QChar('0'))
                    .arg(systemTime.wHour, 2, 10, QChar('0'))
                    .arg(systemTime.wMinute, 2, 10, QChar('0'))
                    .arg(systemTime.wSecond, 2, 10, QChar('0'));
            }
            break;
    
            case VT_R8:  // Double-precision floating-point number
            result = QString::number(propvar.dblVal);
            break;
    
            case VT_EMPTY:  // No value
            break;
    
            case VT_CLSID:  // GUID/UUID (Class Identifier)
            if (propvar.puuid != NULL)
            {
                wchar_t* guidString = NULL;
                StringFromCLSID(*propvar.puuid, &guidString);
                result = QString::fromWCharArray(guidString);
                CoTaskMemFree(guidString);
            }
            break;
    
            case VT_VECTOR | VT_UI1:  // Binary data
            result = QString("Binary Data (size: %1 bytes)").arg(propvar.caub.cElems);
            break;
    
            case VT_UNKNOWN:  // Unknown type
            result = "Unknown";
            break;
    
            case VT_NULL:
            break;
    
            default:
#ifdef QT_DEBUG
            qq << "Unhandled PROPVARIANT type:" << propvar.vt;
#endif QT_DEBUG
            break;
        }

		RtlSecureZeroMemory(&propvar, sizeof(propvar));
        PropVariantClear(&propvar);

        QByteArray data(result.toUtf8());
        if (result.isEmpty())
            return data;

        QCLEAR(result)

#ifdef QT_DEBUG
        PWSTR propName = NULL;
        PSGetNameFromPropertyKey(key, &propName);
        //qq << "\n" << "[[" << QString::fromWCharArray(propName) << "]]\n> " << result;
        if (propName)
            CoTaskMemFree(propName);
#endif

        wEncrypt(data);
        //wDecrypt(data);   

        VMEND // VM_F464_W
        return data;
    };
    
    const auto getProperties   = [=](CComPtr<IShellItem> pItem) -> QJsonArray
    {
        VMSTART // VM_F598_W

        CComPtr<IPropertyStore> pPropertyStore;
        if (FAILED(pItem->BindToHandler(nullptr, BHID_PropertyStore, IID_PPV_ARGS(&pPropertyStore))))
        {
            CComPtr<IPropertyStoreFactory> factory;
            HRESULT hr = pItem->BindToHandler(nullptr, BHID_PropertyStore, IID_PPV_ARGS(&factory));
            if (FAILED(hr))
                return QJsonArray();
            hr = factory->GetPropertyStore(GPS_BESTEFFORT, nullptr, IID_PPV_ARGS(&pPropertyStore));
            if (FAILED(hr))
                return QJsonArray();
        }
        if (!pPropertyStore)
			return QJsonArray();

        PROPVARIANT propvar;
        PropVariantInit(&propvar);
        HRESULT hr = pPropertyStore->GetValue(PKEY_PerceivedType, &propvar);
        if (FAILED(hr))
        {
            PropVariantClear(&propvar);
            return QJsonArray();
        }

        bool isImage = (propvar.lVal >= 2 && propvar.lVal <= 4);
        RtlSecureZeroMemory(&propvar, sizeof(propvar));
        PropVariantClear(&propvar);

        // https://learn.microsoft.com/en-us/windows/win32/properties/props-system-perceivedtype
        if (isImage)
            return QJsonArray(); // dont take properties for: images, audio, video

        PROPERTYKEY PKEY_ProductVersion;
        PSGetPropertyKeyFromName(L"System.Software.ProductVersion", &PKEY_ProductVersion);

        QJsonArray jsonArray;
		for (const auto& key : { PKEY_Size,                 PKEY_FileDescription,  PKEY_FileVersion, PKEY_ProductVersion,
                                 PKEY_Software_ProductName, PKEY_OriginalFileName, PKEY_Company,     PKEY_Copyright })
		{
            QByteArray data = getFileProperty(pPropertyStore, key);
            jsonArray.append(data.isEmpty() ? 0 : data.data());
			QCLEAR(data)
		}
        
        VMEND // VM_F598_W
        return jsonArray;
    };



    DWORD attributes = 0;
    hr = pItem->GetAttributes(SFGAO_STORAGE | SFGAO_FOLDER | SFGAO_LINK, &attributes);
    if (attributes & SFGAO_LINK) // shortcut (.lnk)
    {
        CComPtr<IShellLink> shellLink;
        HRESULT hr = pItem->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&shellLink));
        if (!shellLink)
            return;
        hr = shellLink->Resolve(NULL, SLR_NO_UI);
        if (FAILED(hr))
            return;        
        WCHAR path[MAX_PATH];
        hr = shellLink->GetPath(path, MAX_PATH, NULL, SLGP_RAWPATH);
        if (SUCCEEDED(hr) && path[0])
        {
            config.currentLevel++;
            if (config.currentLevel <= config.maxNestLevel)
                enumFiles(path, jsonObject, config);

            RtlSecureZeroMemory(path, sizeof(path));
        }
        return;
    }



    CComHeapPtr<wchar_t> displayName;
    bool isFolder = ((attributes & SFGAO_FOLDER) && (attributes & SFGAO_STORAGE));
    pItem->GetDisplayName(isFolder ? SIGDN_FILESYSPATH : SIGDN_NORMALDISPLAY, &displayName);
    if (displayName.m_pData == NULL || !displayName.m_pData[0])
        return;

    QString string = QString::fromWCharArray(displayName.m_pData);
    RtlSecureZeroMemory(displayName.m_pData, wcslen(displayName.m_pData) * sizeof(wchar_t));
    
    QByteArray file(string.toUtf8());
	QCLEAR(string)



    if (isFolder)
    {
        if (enumFilesDuplicateTracker.hasSeenL(file))
        {
			file.prepend("[D]"); // mark as duplicate
            wEncrypt(file);
            jsonObject.insert(file, QJsonObject());
            QCLEAR(file)
            return; // already parsed this folder
        }

        wEncrypt(file);
        auto it = jsonObject.insert(file, QJsonObject());
        QCLEAR(file)

        CComPtr<IEnumShellItems> items;
        CComPtr<IPropertyBag> bag;
        CComPtr<IBindCtx> ctx;
        PSCreateMemoryPropertyStore(IID_PPV_ARGS(&bag));
        CreateBindCtx(0, &ctx);
        if (bag && ctx)
        {
            ctx->RegisterObjectParam((LPOLESTR)STR_PROPERTYBAG_PARAM, bag);
            ATL::CComVariant flags = CComVariant(SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN | SHCONTF_NONFOLDERS);
            bag->Write(STR_ENUM_ITEMS_FLAGS, &flags);
        }

        hr = pItem->BindToHandler(ctx, BHID_EnumItems, IID_PPV_ARGS(&items));
        if (FAILED(hr) || !items)
            return;

        QJsonObject folderObject;
        int maxItems = config.maxItemsPerLevel[config.currentLevel];
        if (!maxItems)
			maxItems = 100; // Default to 100 if not specified
        
        int itemCount = 0;
        do
        {
            CComPtr<IShellItem> pChildItem;
            if (itemCount >= maxItems || items->Next(1, &pChildItem, nullptr) != S_OK)
                break;

            if (config.currentLevel < config.maxNestLevel)
            {
                CComHeapPtr<wchar_t> name;
                pChildItem->GetDisplayName(SIGDN_FILESYSPATH, &name);
                if (name.m_pData == NULL || !name.m_pData[0])
                    continue;

                EnumFilesConfig newConfig = config;
                newConfig.currentLevel++;
                enumFiles(name.m_pData, folderObject, newConfig);
                RtlSecureZeroMemory(name.m_pData, wcslen(name.m_pData) * sizeof(wchar_t));
            }
            else
            {
                //qq << "\n\n- - - - - - - -\n" << childPath << "\n- - - - - - - -\n";
                /*
                DWORD propertyCount;
                hr = pPropertyStore->GetCount(&propertyCount);
                if (SUCCEEDED(hr))
                {
                    for (DWORD i = 0; i < propertyCount; i++)
                    {
                        PROPERTYKEY key;
                        hr = pPropertyStore->GetAt(i, &key);
                        if (SUCCEEDED(hr))
                            QString propertyValue = getFileProperty(pChildItem, key);
                    }
                }
                */
                
                attributes = 0;
                hr = pChildItem->GetAttributes(SFGAO_FOLDER, &attributes);
                bool isFolder = (FAILED(hr) || (attributes & SFGAO_FOLDER));

                CComHeapPtr<wchar_t> name;
                pChildItem->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
                if (!name.m_pData || !name.m_pData[0])
                    continue;

                QString string = QString::fromWCharArray(name);
                QByteArray file(string.toUtf8());
				QCLEAR(string)
                wEncrypt(file);
				RtlSecureZeroMemory(name.m_pData, wcslen(name.m_pData) * sizeof(wchar_t));

                if (isFolder)
                    folderObject[file]; // not necessary to get properties for folders
                else if (!config.captureFoldersOnly)
                    folderObject[file] = getProperties(pChildItem);

				QCLEAR(file)
            }
            
            itemCount++;
        } while (true);

        it.value() = folderObject;
    }
    else if (!config.captureFoldersOnly) // its a file and the option to get only folders is not set
    {
        wEncrypt(file);
        jsonObject[file] = getProperties(pItem);
        QCLEAR(file)
    }



	VMEND // VM_F446_W
}