summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qlockfile_win.cpp
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-04-29 14:36:24 +0200
committerJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-05-26 11:01:14 +0000
commit80c8d324b335753d5b1758f29775b844904bb2c6 (patch)
tree8865d7629eba535fbf9564d15f15025641375a8e /src/corelib/io/qlockfile_win.cpp
parenta0e5210d8b6b21d33800e1fac30efbf2868f9f5b (diff)
take process name into account for QLockFile's pid clash resolution
To cover the situation that the process ID got reused, the current process name is compared to the name of the process that corresponds to the process ID from the lock file. If the process names differ, the lock file is considered stale. [ChangeLog][QtCore][QLockFile] Detection of stale lock files got more robust and takes the name of the process that belongs to the stored PID into account. Task-number: QTBUG-45497 Change-Id: Ic3c0d7e066435451203e77b9b9ce2d70bfb9c570 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> Reviewed-by: David Faure <david.faure@kdab.com>
Diffstat (limited to 'src/corelib/io/qlockfile_win.cpp')
-rw-r--r--src/corelib/io/qlockfile_win.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index 4e0d8134ec..8cbe0a9dfd 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org>
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -140,6 +141,9 @@ bool QLockFilePrivate::isApparentlyStale() const
::CloseHandle(procHandle);
if (dwR == WAIT_TIMEOUT)
return true;
+ const QString processName = processNameByPid(pid);
+ if (!processName.isEmpty() && processName != appname)
+ return true; // PID got reused by a different application.
}
}
#else // !Q_OS_WINRT
@@ -151,6 +155,47 @@ bool QLockFilePrivate::isApparentlyStale() const
return staleLockTime > 0 && age > staleLockTime;
}
+QString QLockFilePrivate::processNameByPid(qint64 pid)
+{
+#if !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE)
+ typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
+
+ HMODULE hPsapi = LoadLibraryA("psapi");
+ if (!hPsapi)
+ return QString();
+
+ GetModuleFileNameExFunc qGetModuleFileNameEx
+ = (GetModuleFileNameExFunc)GetProcAddress(hPsapi, "GetModuleFileNameExW");
+ if (!qGetModuleFileNameEx) {
+ FreeLibrary(hPsapi);
+ return QString();
+ }
+
+ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, DWORD(pid));
+ if (!hProcess) {
+ FreeLibrary(hPsapi);
+ return QString();
+ }
+ wchar_t buf[MAX_PATH];
+ const DWORD length = qGetModuleFileNameEx(hProcess, NULL, buf, sizeof(buf) / sizeof(wchar_t));
+ CloseHandle(hProcess);
+ FreeLibrary(hPsapi);
+ if (!length)
+ return QString();
+ QString name = QString::fromWCharArray(buf, length);
+ int i = name.lastIndexOf(QLatin1Char('\\'));
+ if (i >= 0)
+ name.remove(0, i + 1);
+ i = name.lastIndexOf(QLatin1Char('.'));
+ if (i >= 0)
+ name.truncate(i);
+ return name;
+#else
+ Q_UNUSED(pid);
+ return QString();
+#endif
+}
+
void QLockFile::unlock()
{
Q_D(QLockFile);