diff options
-rw-r--r-- | src/corelib/doc/snippets/ntfsp.cpp | 15 | ||||
-rw-r--r-- | src/corelib/io/qfile.h | 21 | ||||
-rw-r--r-- | src/corelib/io/qfiledevice.cpp | 14 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.cpp | 13 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 45 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/tst_qdir.cpp | 5 | ||||
-rw-r--r-- | tests/auto/corelib/io/qfile/tst_qfile.cpp | 21 | ||||
-rw-r--r-- | tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 12 |
8 files changed, 124 insertions, 22 deletions
diff --git a/src/corelib/doc/snippets/ntfsp.cpp b/src/corelib/doc/snippets/ntfsp.cpp index b4d59e6ac5..18f9bd0c5e 100644 --- a/src/corelib/doc/snippets/ntfsp.cpp +++ b/src/corelib/doc/snippets/ntfsp.cpp @@ -11,3 +11,18 @@ qt_ntfs_permission_lookup++; // turn checking on qt_ntfs_permission_lookup--; // turn it off again //! [1] +//! [raii] +void complexFunction() +{ + QNtfsPermissionCheckGuard permissionGuard; // check is enabled + + // do complex things here that need permission check enabled + +} // as the guard goes out of scope the check is disabled +//! [raii] + +//! [free-funcs] +qAreNtfsPermissionChecksEnabled(); // check status +qEnableNtfsPermissionChecks(); // turn checking on +qDisableNtfsPermissionChecks(); // turn it off again +//! [free-funcs] diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h index 3ac6795495..f608ca48f5 100644 --- a/src/corelib/io/qfile.h +++ b/src/corelib/io/qfile.h @@ -26,6 +26,27 @@ namespace std { QT_BEGIN_NAMESPACE +#ifdef Q_OS_WIN +Q_CORE_EXPORT bool qEnableNtfsPermissionChecks() noexcept; +Q_CORE_EXPORT bool qDisableNtfsPermissionChecks() noexcept; +Q_CORE_EXPORT bool qAreNtfsPermissionChecksEnabled() noexcept; + +class [[nodiscard]] QNtfsPermissionCheckGuard +{ + Q_DISABLE_COPY_MOVE(QNtfsPermissionCheckGuard) +public: + QNtfsPermissionCheckGuard() + { + qEnableNtfsPermissionChecks(); + } + + ~QNtfsPermissionCheckGuard() + { + qDisableNtfsPermissionChecks(); + } +}; +#endif // Q_OS_WIN + #if QT_CONFIG(cxx17_filesystem) namespace QtPrivate { inline QString fromFilesystemPath(const std::filesystem::path &path) diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index 6c790e9d0e..092b09ae05 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -114,6 +114,20 @@ void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum) to increment or decrement \c qt_ntfs_permission_lookup before any threads other than the main thread have started or after every thread other than the main thread has ended. + + \note From Qt 6.6 the variable \c qt_ntfs_permission_lookup is + deprecated. Please use the following alternatives. + + The safe and easy way to manage permission checks is to use the RAII class + \c QNtfsPermissionCheckGuard. + + \snippet ntfsp.cpp raii + + If you need more fine-grained control, it is possible to manage the permission + with the following functions instead: + + \snippet ntfsp.cpp free-funcs + */ //************* QFileDevice diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 49573347ca..5c9ae5df70 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -278,6 +278,19 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) threads other than the main thread have started or after every thread other than the main thread has ended. + \note From Qt 6.6 the variable \c qt_ntfs_permission_lookup is + deprecated. Please use the following alternatives. + + The safe and easy way to manage permission checks is to use the RAII class + \c QNtfsPermissionCheckGuard. + + \snippet ntfsp.cpp raii + + If you need more fine-grained control, it is possible to manage the permission + with the following functions instead: + + \snippet ntfsp.cpp free-funcs + \section1 Performance Considerations Some of QFileInfo's functions query the file system, but for diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 9cfa1d7b7d..fbc55954cb 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -384,6 +384,46 @@ constexpr QFileDevice::Permissions toSpecificPermissions(PermissionTag tag, Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0; +static QBasicAtomicInt qt_ntfs_permission_lookup_v2 = Q_BASIC_ATOMIC_INITIALIZER(0); + +/*! + \internal + + Returns true if the check was previously enabled. +*/ + +bool qEnableNtfsPermissionChecks() noexcept +{ + return qt_ntfs_permission_lookup_v2.fetchAndAddRelaxed(1) + + qt_ntfs_permission_lookup + != 0; +} + +/*! + \internal + + Returns true if the check is disabled, i.e. there are no more users. +*/ + +bool qDisableNtfsPermissionChecks() noexcept +{ + return qt_ntfs_permission_lookup_v2.fetchAndSubRelaxed(1) + + qt_ntfs_permission_lookup + == 1; +} + +/*! + \internal + + Returns true if the check is enabled. +*/ + +bool qAreNtfsPermissionChecksEnabled() noexcept +{ + return qt_ntfs_permission_lookup_v2.loadRelaxed() + + qt_ntfs_permission_lookup; +} + /*! \class QNativeFilePermissions \internal @@ -1078,8 +1118,7 @@ QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEng { QString name; #if QT_CONFIG(fslibs) - extern int qt_ntfs_permission_lookup; - if (qt_ntfs_permission_lookup > 0) { + if (qAreNtfsPermissionChecksEnabled()) { initGlobalSid(); { PSID pOwner = 0; @@ -1133,7 +1172,7 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst QFileSystemMetaData::MetaDataFlags what) { #if QT_CONFIG(fslibs) - if (qt_ntfs_permission_lookup > 0) { + if (qAreNtfsPermissionChecksEnabled()) { initGlobalSid(); QString fname = entry.nativeFilePath(); diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 39bf938c1b..75f1a35037 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -12,7 +12,6 @@ #include <qdebug.h> #include <qdir.h> #include <qfileinfo.h> -#include <qscopedvaluerollback.h> #include <qstringlist.h> #if defined(Q_OS_WIN) @@ -40,7 +39,6 @@ #ifdef Q_OS_WIN #define DRIVE "Q:" -extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; #else #define DRIVE #endif @@ -453,8 +451,7 @@ void tst_QDir::mkdirWithPermissions() QFETCH(QFile::Permissions, permissions); #ifdef Q_OS_WIN - QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup); - ++qt_ntfs_permission_lookup; + QNtfsPermissionCheckGuard permissionGuard; #endif #ifdef Q_OS_UNIX auto restoreMask = qScopeGuard([oldMask = umask(0)] { umask(oldMask); }); diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index a7fbef2485..c8048c21c8 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -171,6 +171,7 @@ private slots: #ifdef Q_OS_WIN void permissionsNtfs_data(); void permissionsNtfs(); + void deprecatedNtfsPermissionCheck(); #endif void setPermissions_data(); void setPermissions(); @@ -1267,8 +1268,7 @@ void tst_QFile::createFilePermissions() QFETCH(QFile::Permissions, permissions); #ifdef Q_OS_WIN - QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup); - ++qt_ntfs_permission_lookup; + QNtfsPermissionCheckGuard permissionGuard; #endif #ifdef Q_OS_UNIX auto restoreMask = qScopeGuard([oldMask = umask(0)] { umask(oldMask); }); @@ -1392,7 +1392,7 @@ void tst_QFile::permissions() } #if defined(Q_OS_WIN) - if (qt_ntfs_permission_lookup) + if (qAreNtfsPermissionChecksEnabled()) QEXPECT_FAIL("readonly", "QTBUG-25630", Abort); #endif #ifdef Q_OS_UNIX @@ -1414,10 +1414,21 @@ void tst_QFile::permissionsNtfs_data() void tst_QFile::permissionsNtfs() { - QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup); - qt_ntfs_permission_lookup++; + QNtfsPermissionCheckGuard permissionGuard; permissions(); } + +void tst_QFile::deprecatedNtfsPermissionCheck() +{ + QScopedValueRollback<int> guard(qt_ntfs_permission_lookup); + + QCOMPARE(qAreNtfsPermissionChecksEnabled(), false); + qt_ntfs_permission_lookup++; + QCOMPARE(qAreNtfsPermissionChecksEnabled(), true); + qt_ntfs_permission_lookup--; + QCOMPARE(qAreNtfsPermissionChecksEnabled(), false); +} + #endif void tst_QFile::setPermissions_data() diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 485d5792ac..abd4dfed5e 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -4,7 +4,6 @@ #include <QTest> #include <QStandardPaths> #include <QScopeGuard> -#include <QScopedValueRollback> #include <qfile.h> #include <qdir.h> @@ -43,9 +42,6 @@ #endif #if defined(Q_OS_WIN) -QT_BEGIN_NAMESPACE -extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; -QT_END_NAMESPACE bool IsUserAdmin(); #endif @@ -1905,8 +1901,7 @@ void tst_QFileInfo::isWritable() #endif #if defined (Q_OS_WIN) - QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup); - qt_ntfs_permission_lookup = 1; + QNtfsPermissionCheckGuard permissionGuard; QFileInfo fi2(QFile::decodeName(qgetenv("SystemRoot") + "/system.ini")); QVERIFY(fi2.exists()); QCOMPARE(fi2.isWritable(), IsUserAdmin()); @@ -2156,7 +2151,7 @@ void tst_QFileInfo::owner() NetApiBufferFree(pBuf); } } - qt_ntfs_permission_lookup = 1; + QNtfsPermissionCheckGuard permissionGuard; #endif if (userName.isEmpty()) QSKIP("Can't retrieve the user name"); @@ -2173,9 +2168,6 @@ void tst_QFileInfo::owner() QCOMPARE(fi.owner(), userName); QFile::remove(fileName); -#if defined(Q_OS_WIN) - qt_ntfs_permission_lookup = 0; -#endif } void tst_QFileInfo::group() |