mirror of
https://github.com/nextcloud/desktop.git
synced 2024-10-24 21:35:47 +03:00
parent
3ec19ee355
commit
b3c02798a3
3 changed files with 71 additions and 2 deletions
|
@ -25,6 +25,7 @@
|
|||
#ifdef Q_OS_WIN
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
// We use some internals of csync:
|
||||
|
@ -149,6 +150,62 @@ bool FileSystem::renameReplace(const QString& originFileName, const QString& des
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FileSystem::openFileSharedRead(QFile* file, QString* error)
|
||||
{
|
||||
bool ok = false;
|
||||
if (error) {
|
||||
error->clear();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//
|
||||
// The following code is adapted from Qt's QFSFileEnginePrivate::nativeOpen()
|
||||
// by including the FILE_SHARE_DELETE share mode.
|
||||
//
|
||||
|
||||
// Enable full sharing.
|
||||
DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
|
||||
int accessRights = GENERIC_READ;
|
||||
DWORD creationDisp = OPEN_EXISTING;
|
||||
|
||||
// Create the file handle.
|
||||
SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
|
||||
HANDLE fileHandle = CreateFileW(
|
||||
(const wchar_t*)file->fileName().utf16(),
|
||||
accessRights,
|
||||
shareMode,
|
||||
&securityAtts,
|
||||
creationDisp,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
// Bail out on error.
|
||||
if (fileHandle == INVALID_HANDLE_VALUE) {
|
||||
if (error) {
|
||||
*error = qt_error_string();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert the HANDLE to an fd and pass it to QFile's foreign-open
|
||||
// function. The fd owns the handle, so when QFile later closes
|
||||
// the fd the handle will be closed too.
|
||||
int fd = _open_osfhandle((intptr_t)fileHandle, _O_RDONLY);
|
||||
if (fd == -1) {
|
||||
if (error) {
|
||||
*error = "could not make fd from handle";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ok = file->open(fd, QIODevice::ReadOnly, QFile::AutoCloseHandle);
|
||||
#else
|
||||
ok = file->open(QFile::ReadOnly);
|
||||
#endif
|
||||
if (! ok && error) {
|
||||
*error = file->errorString();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <ctime>
|
||||
|
||||
#include <owncloudlib.h>
|
||||
|
@ -49,4 +50,13 @@ bool setModTime(const QString &filename, time_t modTime);
|
|||
bool renameReplace(const QString &originFileName, const QString &destinationFileName,
|
||||
QString *errorString);
|
||||
|
||||
/**
|
||||
* Replacement for QFile::open(ReadOnly) that sets a more permissive sharing mode
|
||||
* on Windows.
|
||||
*
|
||||
* Warning: The resuting file may have an empty fileName and be unsuitable for use
|
||||
* with QFileInfo!
|
||||
*/
|
||||
bool openFileSharedRead(QFile* file, QString* error);
|
||||
|
||||
}}
|
||||
|
|
|
@ -348,9 +348,11 @@ void PropagateUploadFileQNAM::startNextChunk()
|
|||
QString path = _item._file;
|
||||
|
||||
QFile file(_propagator->getFilePath(_item._file), this);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
QString openError;
|
||||
// Warning: this clears file->fileName() and makes it unsuitable for QFileInfo!
|
||||
if (!FileSystem::openFileSharedRead(&file, &openError)) {
|
||||
// Soft error because this is likely caused by the user modifying his files while syncing
|
||||
abortWithError(SyncFileItem::SoftError, file.errorString());
|
||||
abortWithError(SyncFileItem::SoftError, openError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue