Skip to content

Commit

Permalink
Implement Utility::lockFile
Browse files Browse the repository at this point in the history
  • Loading branch information
TheOneRing committed Mar 9, 2022
1 parent 868df3c commit 9c8fce7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 25 deletions.
33 changes: 18 additions & 15 deletions src/common/filesystembase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const wchar_t *>(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<const wchar_t *>(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
Expand Down
27 changes: 17 additions & 10 deletions src/common/filesystembase.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
#pragma once

#include "config.h"
#include "ocsynclib.h"

#include "utility.h"

#include <QString>
#include <ctime>
#include <QFileInfo>
#include <QLoggingCategory>

#include <ocsynclib.h>

class QFile;

Expand Down Expand Up @@ -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
/**
Expand All @@ -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)
Expand Down

0 comments on commit 9c8fce7

Please sign in to comment.