summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/doc/snippets/ntfsp.cpp15
-rw-r--r--src/corelib/io/qfile.h21
-rw-r--r--src/corelib/io/qfiledevice.cpp14
-rw-r--r--src/corelib/io/qfileinfo.cpp13
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp45
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp5
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp21
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp12
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()