diff options
author | Joerg Bornemann <joerg.bornemann@theqtcompany.com> | 2015-04-29 14:36:24 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@theqtcompany.com> | 2015-05-26 11:01:14 +0000 |
commit | 80c8d324b335753d5b1758f29775b844904bb2c6 (patch) | |
tree | 8865d7629eba535fbf9564d15f15025641375a8e /src/corelib/io/qlockfile_win.cpp | |
parent | a0e5210d8b6b21d33800e1fac30efbf2868f9f5b (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.cpp | 45 |
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); |