7#include "private/qlockfile_p.h"
8#include "private/qfilesystementry_p.h"
11#include "QtCore/qdatetime.h"
12#include "QtCore/qdir.h"
13#include "QtCore/qdebug.h"
14#include "QtCore/qfileinfo.h"
15#include "QtCore/qthread.h"
17#include <qt_windows.h>
24 WIN32_FILE_ATTRIBUTE_DATA data;
25 return GetFileAttributesEx(fileName, GetFileExInfoStandard, &data);
30 const DWORD dwShareMode = 0;
31 SECURITY_ATTRIBUTES securityAtts = {
sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
32 HANDLE fh = CreateFile(qt_castToWchar(QDir::toNativeSeparators(fileName)),
33 GENERIC_READ | GENERIC_WRITE,
37 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
39 bool success = (fh != INVALID_HANDLE_VALUE);
44 const DWORD lastError = GetLastError();
45 if (lastError == ERROR_FILE_NOT_FOUND)
51QLockFile::LockError QLockFilePrivate::tryLock_sys()
53 const QFileSystemEntry fileEntry(fileName);
59 const DWORD dwShareMode = FILE_SHARE_READ;
60 SECURITY_ATTRIBUTES securityAtts = {
sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
61 HANDLE fh = CreateFile((
const wchar_t*)fileEntry.nativeFilePath().utf16(),
62 GENERIC_READ | GENERIC_WRITE,
66 FILE_ATTRIBUTE_NORMAL,
68 if (fh == INVALID_HANDLE_VALUE) {
69 const DWORD lastError = GetLastError();
71 case ERROR_SHARING_VIOLATION:
72 case ERROR_ALREADY_EXISTS:
73 case ERROR_FILE_EXISTS:
74 return QLockFile::LockFailedError;
75 case ERROR_ACCESS_DENIED:
78 return fileExists((
const wchar_t*)fileEntry.nativeFilePath().utf16())
79 ? QLockFile::LockFailedError
80 : QLockFile::PermissionError;
82 qWarning(
"Got unexpected locking error %llu", quint64(lastError));
83 return QLockFile::UnknownError;
89 QByteArray fileData = lockFileContents();
90 DWORD bytesWritten = 0;
91 QLockFile::LockError error = QLockFile::NoError;
92 if (!WriteFile(fh, fileData.constData(), fileData.size(), &bytesWritten, NULL) || !FlushFileBuffers(fh))
93 error = QLockFile::UnknownError;
97bool QLockFilePrivate::removeStaleLock()
100 return deleteFile(fileName);
103bool QLockFilePrivate::isProcessRunning(qint64 pid,
const QString &appname)
105 HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
111 if (!::GetExitCodeProcess(procHandle, &exitCode))
113 ::CloseHandle(procHandle);
114 if (exitCode != STILL_ACTIVE)
117 const QString processName = processNameByPid(pid);
118 if (!processName.isEmpty() && processName != appname)
124QString QLockFilePrivate::processNameByPid(qint64 pid)
126 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, DWORD(pid));
130 wchar_t buf[MAX_PATH];
131 const DWORD length = GetModuleFileNameExW(hProcess, NULL, buf,
sizeof(buf) /
sizeof(
wchar_t));
132 CloseHandle(hProcess);
135 QString name = QString::fromWCharArray(buf, length);
136 int i = name.lastIndexOf(u'\\');
138 name.remove(0, i + 1);
139 i = name.lastIndexOf(u'.');
145void QLockFile::unlock()
150 CloseHandle(d->fileHandle);
152 static const int maxAttempts = 500;
153 while (!deleteFile(d->fileName) && ++attempts < maxAttempts) {
157 if (attempts == maxAttempts) {
158 qWarning() <<
"Could not remove our own lock file" << d->fileName
159 <<
". Either other users of the lock file are reading it constantly for 500 ms, "
160 "or we (no longer) have permissions to delete the file";
164 d->lockError = QLockFile::NoError;
static bool deleteFile(const QString &fileName)
static QT_BEGIN_NAMESPACE bool fileExists(const wchar_t *fileName)