summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-04-20 10:57:20 +0200
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-04-23 09:59:43 +0000
commit6545404afad30b60d1a8e9a2abaf301abaf8f6a5 (patch)
treed83252e4fa3cbb111171c34500334f047f3e04ee /tests
parent1f2ce78f16a3a8b5d182fbb9c03c373efaa136d8 (diff)
Windows: Fix QLockFile hanging when file cannot be created.
Return QLockFile::PermissionError when file does not exist, preventing the stale file detection logic from triggering. Add Windows-only autotest trying to create a lock file in a system folder guarded with checks for elevated processes and UAC virtualization. Task-number: QTBUG-45631 Change-Id: I1790f8f925660f6bf1df94c2ced901e6ec57cbb0 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com> Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp65
-rw-r--r--tests/auto/corelib/io/qlockfile/tst_qlockfile.pro1
2 files changed, 66 insertions, 0 deletions
diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
index 90f65e9dbc..bef3d3a012 100644
--- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
+++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
@@ -36,8 +36,11 @@
#include <QtConcurrentRun>
#include <qlockfile.h>
#include <qtemporarydir.h>
+#include <qsysinfo.h>
#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
#include <unistd.h>
+#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+# include <qt_windows.h>
#endif
class tst_QLockFile : public QObject
@@ -58,6 +61,7 @@ private slots:
void staleLongLockFromBusyProcess();
void staleLockRace();
void noPermissions();
+ void noPermissionsWindows();
public:
QString m_helperApp;
@@ -415,5 +419,66 @@ void tst_QLockFile::noPermissions()
QCOMPARE(int(lockFile.error()), int(QLockFile::PermissionError));
}
+enum ProcessProperty {
+ ElevatedProcess = 0x1,
+ VirtualStore = 0x2
+};
+
+Q_DECLARE_FLAGS(ProcessProperties, ProcessProperty)
+Q_DECLARE_OPERATORS_FOR_FLAGS(ProcessProperties)
+
+static inline ProcessProperties processProperties()
+{
+ ProcessProperties result;
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+ HANDLE processToken = NULL;
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &processToken)) {
+ DWORD elevation; // struct containing a DWORD, not present in some MinGW headers.
+ DWORD cbSize = sizeof(elevation);
+ if (GetTokenInformation(processToken, TokenElevation, &elevation, cbSize, &cbSize)
+ && elevation) {
+ result |= ElevatedProcess;
+ }
+ // Check for UAC virtualization (compatibility mode for old software
+ // allowing it to write to system folders by mirroring them under
+ // "\Users\...\AppData\Local\VirtualStore\", which is typically the case
+ // for MinGW).
+ DWORD virtualStoreEnabled = 0;
+ cbSize = sizeof(virtualStoreEnabled);
+ if (GetTokenInformation(processToken, TokenVirtualizationEnabled, &virtualStoreEnabled, cbSize, &cbSize)
+ && virtualStoreEnabled) {
+ result |= VirtualStore;
+ }
+ CloseHandle(processToken);
+ }
+#endif
+ return result;
+}
+
+void tst_QLockFile::noPermissionsWindows()
+{
+ // Windows: Do the permissions test in a system directory in which
+ // files cannot be created.
+#if !defined(Q_OS_WIN) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
+ QSKIP("This test is for desktop Windows only");
+#endif
+#ifdef Q_OS_WIN
+ if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS7)
+ QSKIP("This test requires at least Windows 7");
+#endif
+ if (const int p = processProperties()) {
+ const QByteArray message = "This test cannot be run (properties=0x"
+ + QByteArray::number(p, 16) + ')';
+ QSKIP(message.constData());
+ }
+
+ const QString fileName = QFile::decodeName(qgetenv("ProgramFiles"))
+ + QLatin1Char('/') + QCoreApplication::applicationName()
+ + QDateTime::currentDateTime().toString(QStringLiteral("yyMMddhhmm"));
+ QLockFile lockFile(fileName);
+ QVERIFY(!lockFile.lock());
+ QCOMPARE(int(lockFile.error()), int(QLockFile::PermissionError));
+}
+
QTEST_MAIN(tst_QLockFile)
#include "tst_qlockfile.moc"
diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.pro b/tests/auto/corelib/io/qlockfile/tst_qlockfile.pro
index 2f7009b736..6eb72343bc 100644
--- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.pro
+++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.pro
@@ -4,3 +4,4 @@ TARGET = tst_qlockfile
SOURCES += tst_qlockfile.cpp
QT = core testlib concurrent
+win32:!wince:!winrt:LIBS += -ladvapi32