HRESULT ShellItemsLoader::EnumerateFolderItemsRecursive(IShellItem* currentBrowseLocation, ShellFileType fileType, std::vector<ComPtr<IShellItem> >& shellItems)
{
    ComPtr<ISearchFolderItemFactory> searchFolderItemFactory;
    ComPtr<IShellItemArray> searchScope;

    HRESULT hr = CoCreateInstance(
        CLSID_SearchFolderItemFactory,
        nullptr,
        CLSCTX_INPROC_SERVER,
        IID_PPV_ARGS(&searchFolderItemFactory));
    if (SUCCEEDED(hr))
    {
        hr = CreateScope(currentBrowseLocation, &searchScope);
    }

    if (SUCCEEDED(hr))
    {
        hr = searchFolderItemFactory->SetScope(searchScope);
    }

    ComPtr<ICondition> searchCondition;
    if (SUCCEEDED(hr))
    {
        hr = CreateCondition(fileType, &searchCondition);
    }

    if (SUCCEEDED(hr))
    {
        hr = searchFolderItemFactory->SetCondition(searchCondition);
    }

    ComPtr<IShellItem> shellItemSearch;
    if (SUCCEEDED(hr))
    {
        hr = searchFolderItemFactory->GetShellItem(IID_PPV_ARGS(&shellItemSearch));
    }

    // Do something with shellItemSearch
    if (SUCCEEDED(hr))
    {
        ComPtr<IEnumShellItems> enumItems;
        hr = shellItemSearch->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&enumItems));
        if (SUCCEEDED(hr))
        {
            // note, this consumes all errors
            ComPtr<IShellItem> shellItem;
            unsigned long fetched;
            while SUCCEEDED(enumItems->Next(1, &shellItem, &fetched))
            {
                shellItems.push_back(shellItem);
                shellItem = nullptr; 
            }
        }
    }

    return hr;
}