diff --git a/src/common/utility.h b/src/common/utility.h index e19f0da6ae1ee..9f5f71a5b976a 100644 --- a/src/common/utility.h +++ b/src/common/utility.h @@ -275,6 +275,8 @@ namespace Utility { OCSYNC_EXPORT QString formatWinError(long error); + OCSYNC_EXPORT bool canCreateFileInPath(const QString &path); + class OCSYNC_EXPORT NtfsPermissionLookupRAII { public: diff --git a/src/common/utility_win.cpp b/src/common/utility_win.cpp index 37b348660c0de..c9b1b1641da41 100644 --- a/src/common/utility_win.cpp +++ b/src/common/utility_win.cpp @@ -33,6 +33,7 @@ #include #include #include +#include extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; @@ -430,6 +431,15 @@ void Utility::UnixTimeToLargeIntegerFiletime(time_t t, LARGE_INTEGER *hundredNSe hundredNSecs->HighPart = ll >>32; } +bool Utility::canCreateFileInPath(const QString &path) +{ + Q_ASSERT(!path.isEmpty()); + const auto pathWithSlash = !path.endsWith(QLatin1Char('/')) + ? path + QLatin1Char('/') + : path; + QTemporaryFile testFile(pathWithSlash + QStringLiteral("~$write-test-file-XXXXXX")); + return testFile.open(); +} QString Utility::formatWinError(long errorCode) { diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 40ec8412685d3..2d0a523d3e99b 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -1701,10 +1701,20 @@ static QString checkPathValidityRecursive(const QString &path) return FolderMan::tr("The selected path is not a folder!"); } + #ifdef Q_OS_WIN + if (!selFile.isWritable()) { + // isWritable() doesn't cover all NTFS permissions + // try creating and removing a test file, and make sure it is excluded from sync + if (!Utility::canCreateFileInPath(path)) { + return FolderMan::tr("You have no permission to write to the selected folder!"); + } + } + #else if (!selFile.isWritable()) { return FolderMan::tr("You have no permission to write to the selected folder!"); } - return QString(); + #endif + return {}; } // QFileInfo::canonicalPath returns an empty string if the file does not exist.