@@ -517,6 +517,8 @@ QString VfsWinPrivate::syncRootPath() const
517517 return QDir::toNativeSeparators (Utility::stripTrailingSlash (q->params ().filesystemPath ));
518518}
519519
520+ QMutex VfsWinPrivate::registrationMutex;
521+
520522// Register as a sync provider with cfapi as well as with the explorer integration
521523void VfsWinPrivate::registerFolder (const VfsSetupParams ¶ms)
522524{
@@ -607,7 +609,7 @@ void VfsWinPrivate::registerFolder(const VfsSetupParams ¶ms)
607609 // A Uri to a cloud storage recycle bin.
608610 // providerInfo.RecycleBinUri(L"recycle bin");
609611
610- providerInfo.ShowSiblingsAsGroup (params. groupInSidebar () );
612+ providerInfo.ShowSiblingsAsGroup (true );
611613
612614 // Prepage the key from the shell property store we'll use to determine
613615 // availability.
@@ -642,14 +644,6 @@ void VfsWinPrivate::registerFolder(const VfsSetupParams ¶ms)
642644 return ;
643645 }
644646
645- // Code below this point cannot run in parallel: the calls below will first search for existing sync root
646- // information, and as a second step it will register the new provider for the folder. If multiple
647- // sync connections are being created in short order (e.g. when setting up a new account), it is possible
648- // that a second call to `registerFolder` will start running this registration. This can result in
649- // multiple side-bar entries in the windows explorer.
650- static QMutex registrationMutex;
651- QMutexLocker registrationLock (®istrationMutex);
652-
653647 try {
654648 auto previousInfo = StorageProviderSyncRootManager::GetSyncRootInformationForFolder (f);
655649 const QString oldId = hstringToQString (previousInfo.Id ());
@@ -699,6 +693,7 @@ void VfsWinPrivate::registerFolder(const VfsSetupParams ¶ms)
699693 }
700694
701695 try {
696+ QMutexLocker registrationLock (®istrationMutex);
702697 StorageProviderSyncRootManager::Register (providerInfo);
703698 } catch (winrt::hresult_error const & ex) {
704699 qCWarning (lcVfs) << " Error registering StorageProvider for" << params.filesystemPath << QString::number (ex.code ()) << hstringToQString (ex.message ());
@@ -727,13 +722,15 @@ void VfsWinPrivate::registerFolder(const VfsSetupParams ¶ms)
727722 };
728723 // clang-format on
729724
730- HRESULT ok = CfConnectSyncRoot (
731- syncRootW.c_str (),
732- callbacks,
733- this , // use VfsWinPrivate as callback context
734- CF_CONNECT_FLAG_BLOCK_SELF_IMPLICIT_HYDRATION // don't let antivirus implicitly hydrate (or something, a bit unclear)
735- | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH, // request that callbacks get the full path
736- &_connectionKey);
725+ HRESULT ok;
726+ {
727+ QMutexLocker registrationLock (®istrationMutex);
728+ ok = CfConnectSyncRoot (syncRootW.c_str (), callbacks,
729+ this , // use VfsWinPrivate as callback context
730+ CF_CONNECT_FLAG_BLOCK_SELF_IMPLICIT_HYDRATION // don't let antivirus implicitly hydrate (or something, a bit unclear)
731+ | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH, // request that callbacks get the full path
732+ &_connectionKey);
733+ }
737734 if (FAILED (ok)) {
738735 Q_EMIT q->error (tr (" Unable to connect sync root: %1 error: %2" ).arg (syncRoot, Utility::formatWinError (ok)));
739736 return ;
@@ -809,20 +806,18 @@ void VfsWin::stop()
809806 wait.processEvents (QEventLoop::AllEvents, 100 );
810807 }
811808
809+ QMutexLocker registrationLock (&d->registrationMutex );
812810 CfDisconnectSyncRoot (d->_connectionKey );
813811}
814812
815813void VfsWin::unregisterFolder ()
816814{
817815 Q_D (VfsWin);
818- using SyncRootManager = winrt::Windows::Storage::Provider::StorageProviderSyncRootManager;
819- try {
820- SyncRootManager::Unregister (d->_registrationId );
821- } catch (winrt::hresult_error const &ex) {
822- qCWarning (lcVfs) << " Could not Unregister() sync root:" << hstringToQString (ex.message ());
823- }
824816
825- // Remove the folder from the search index
817+ if (d->_registrationState == VfsWinPrivate::Unregistered)
818+ return ;
819+
820+ // First step: remove the folder from the search index
826821 const std::wstring url (convertFullNativePathToFullyDecodedUrlW (d->syncRootPath ()));
827822 winrt::com_ptr<ISearchCrawlScopeManager> searchCrawlScopeManager = getSearchCrawlScopeManager ();
828823
@@ -835,6 +830,15 @@ void VfsWin::unregisterFolder()
835830 } else {
836831 qCWarning (lcVfs) << " Unable to get the SearchCrawlScopeManager to remove the path" << url;
837832 }
833+
834+ // Final step: unregister the path. We're now completely done with it.
835+ using SyncRootManager = winrt::Windows::Storage::Provider::StorageProviderSyncRootManager;
836+ try {
837+ QMutexLocker registrationLock (&d->registrationMutex );
838+ SyncRootManager::Unregister (d->_registrationId );
839+ } catch (winrt::hresult_error const &ex) {
840+ qCWarning (lcVfs) << " Could not Unregister() sync root:" << hstringToQString (ex.message ());
841+ }
838842}
839843
840844OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> VfsWin::updateMetadata (const SyncFileItem &item, const QString &filePath, const QString &replacesFile)
0 commit comments