diff --git a/src/common/filesystembase.cpp b/src/common/filesystembase.cpp index 426aefa6807..dd22b8cf879 100644 --- a/src/common/filesystembase.cpp +++ b/src/common/filesystembase.cpp @@ -454,35 +454,38 @@ bool FileSystem::moveToTrash(const QString &fileName, QString *errorString) #endif } -bool FileSystem::isFileLocked(const QString &fileName, LockMode mode) -{ #ifdef Q_OS_WIN - // Check if file exists +Utility::Handle FileSystem::lockFile(const QString &fileName, LockMode mode) +{ const QString fName = longWinPath(fileName); auto accessMode = mode == LockMode::Exclusive ? 0 : FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + // Check if file exists DWORD attr = GetFileAttributesW(reinterpret_cast(fName.utf16())); if (attr != INVALID_FILE_ATTRIBUTES) { // Try to open the file with as much access as possible.. - HANDLE win_h = CreateFileW( + return Utility::Handle { CreateFileW( reinterpret_cast(fName.utf16()), GENERIC_READ | GENERIC_WRITE, accessMode, - NULL, OPEN_EXISTING, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, - NULL); + nullptr) }; + } + return {}; +} +#endif - if (win_h == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_SHARING_VIOLATION) { - return true; - } - return false; - } else { - CloseHandle(win_h); - } - } else { + +bool FileSystem::isFileLocked(const QString &fileName, LockMode mode) +{ +#ifdef Q_OS_WIN + const auto handle = lockFile(fileName, mode); + if (!handle) { const auto error = GetLastError(); if (error != ERROR_FILE_NOT_FOUND && error != ERROR_PATH_NOT_FOUND) { qCWarning(lcFileSystem()) << "GetFileAttributesW" << Utility::formatWinError(error); + } else if (error == ERROR_SHARING_VIOLATION) { + return true; } } #else diff --git a/src/common/filesystembase.h b/src/common/filesystembase.h index b4ace754cdc..dd8f09a7963 100644 --- a/src/common/filesystembase.h +++ b/src/common/filesystembase.h @@ -19,13 +19,15 @@ #pragma once #include "config.h" +#include "ocsynclib.h" + +#include "utility.h" #include #include #include #include -#include class QFile; @@ -122,7 +124,17 @@ namespace FileSystem { * Warning: The resulting file may have an empty fileName and be unsuitable for use * with QFileInfo! Calling seek() on the QFile with >32bit signed values will fail! */ - bool OCSYNC_EXPORT openAndSeekFileSharedRead(QFile *file, QString *error, qint64 seek); + bool OCSYNC_EXPORT openAndSeekFileSharedRead(QFile * file, QString * error, qint64 seek); + + enum class LockMode { + Shared, + Exclusive + }; + Q_ENUM_NS(LockMode); + /** + * Returns true when a file is locked. (Windows only) + */ + bool OCSYNC_EXPORT isFileLocked(const QString &fileName, LockMode mode); #ifdef Q_OS_WIN /** @@ -142,17 +154,12 @@ namespace FileSystem { * the windows API functions work with the normal "unixoid" representation too. */ QString OCSYNC_EXPORT pathtoUNC(const QString &str); -#endif - enum class LockMode { - Shared, - Exclusive - }; - Q_ENUM_NS(LockMode); /** - * Returns true when a file is locked. (Windows only) + * This function creates a file handle with the desired LockMode */ - bool OCSYNC_EXPORT isFileLocked(const QString &fileName, LockMode mode); + Utility::Handle OCSYNC_EXPORT lockFile(const QString &fileName, LockMode mode); +#endif /** * Returns whether the file is a shortcut file (ends with .lnk)