mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
Merge pull request #7477 from nextcloud/bugfix/readOnlyVirtualFilesFixes
Improve read only virtual files support on Windows
This commit is contained in:
commit
f1c6b65265
@ -131,6 +131,7 @@ void FileSystem::setFileReadOnly(const QString &filename, bool readonly)
|
||||
{
|
||||
qCWarning(lcFileSystem()) << filename << (readonly ? "readonly" : "read write") << e.what();
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
QFile file(filename);
|
||||
|
||||
@ -275,9 +275,9 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
||||
case DisplayPathRole:
|
||||
return getDisplayPath();
|
||||
case PathRole:
|
||||
return QFileInfo(getFilePath()).path();
|
||||
return getFilePath();
|
||||
case OpenablePathRole:
|
||||
return a._isMultiObjectActivity ? QFileInfo(getFilePath()).canonicalPath() : QFileInfo(getFilePath()).canonicalFilePath();
|
||||
return getFilePath();
|
||||
case DisplayLocationRole:
|
||||
return displayLocation();
|
||||
case ActionsLinksRole: {
|
||||
|
||||
@ -1193,11 +1193,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
||||
item->_direction = SyncFileItem::Down;
|
||||
item->_instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
const auto pinState = _discoveryData->_syncOptions._vfs->pinState(path._local);
|
||||
if (FileSystem::isLnkFile(path._local) && !_discoveryData->_syncOptions._vfs->pinState(path._local).isValid()) {
|
||||
item->_type = ItemTypeVirtualFileDownload;
|
||||
} else {
|
||||
item->_type = ItemTypeVirtualFileDehydration;
|
||||
}
|
||||
item->_type = ItemTypeVirtualFileDehydration;
|
||||
} else if (!serverModified
|
||||
&& (dbEntry._inode != localEntry.inode
|
||||
|| (localEntry.isMetadataMissing && item->_type == ItemTypeFile && !FileSystem::isLnkFile(item->_file))
|
||||
@ -1735,6 +1731,15 @@ void ProcessDirectoryJob::processFileFinalize(
|
||||
item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_UPDATE_VFS_METADATA;
|
||||
}
|
||||
|
||||
if (_discoveryData->_syncOptions._vfs &&
|
||||
(item->_type == CSyncEnums::ItemTypeFile || item->_type == CSyncEnums::ItemTypeDirectory) &&
|
||||
item->_instruction == CSyncEnums::CSYNC_INSTRUCTION_NONE &&
|
||||
FileSystem::isLnkFile((_discoveryData->_localDir + path._local))) {
|
||||
item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_SYNC;
|
||||
item->_direction = SyncFileItem::Down;
|
||||
item->_type = CSyncEnums::ItemTypeVirtualFileDehydration;
|
||||
}
|
||||
|
||||
if (path._original != path._target && (item->_instruction == CSYNC_INSTRUCTION_UPDATE_VFS_METADATA || item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA || item->_instruction == CSYNC_INSTRUCTION_NONE)) {
|
||||
ASSERT(_dirItem && _dirItem->_instruction == CSYNC_INSTRUCTION_RENAME);
|
||||
// This is because otherwise subitems are not updated! (ideally renaming a directory could
|
||||
|
||||
@ -498,6 +498,13 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
|
||||
}
|
||||
|
||||
qCDebug(lcPropagateDownload) << "dehydrating file" << _item->_file;
|
||||
if (FileSystem::isLnkFile(fsPath)) {
|
||||
const auto convertResult = vfs->convertToPlaceholder(fsPath, *_item);
|
||||
if (!convertResult) {
|
||||
qCCritical(lcPropagateDownload()) << "error when converting a shortcut file to placeholder" << convertResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
auto r = vfs->dehydratePlaceholder(*_item);
|
||||
if (!r) {
|
||||
done(SyncFileItem::NormalError, r.error(), ErrorCategory::GenericError);
|
||||
|
||||
@ -117,7 +117,8 @@ void PropagateLocalRemove::start()
|
||||
}
|
||||
|
||||
QString removeError;
|
||||
if (_moveToTrash) {
|
||||
const auto availability = propagator()->syncOptions()._vfs->availability(_item->_file, Vfs::AvailabilityRecursivity::RecursiveAvailability);
|
||||
if (_moveToTrash && (!availability || (*availability != VfsItemAvailability::AllDehydrated && *availability != VfsItemAvailability::OnlineOnly && *availability != VfsItemAvailability::Mixed))) {
|
||||
if ((QDir(filename).exists() || FileSystem::fileExists(filename))
|
||||
&& !FileSystem::moveToTrash(filename, &removeError)) {
|
||||
done(SyncFileItem::NormalError, removeError, ErrorCategory::GenericError);
|
||||
@ -228,8 +229,6 @@ void PropagateLocalMkdir::startLocalMkdir()
|
||||
#if !defined(Q_OS_MACOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15
|
||||
if (!_item->_remotePerm.isNull() &&
|
||||
!_item->_remotePerm.hasPermission(RemotePermissions::CanAddFile) &&
|
||||
!_item->_remotePerm.hasPermission(RemotePermissions::CanRename) &&
|
||||
!_item->_remotePerm.hasPermission(RemotePermissions::CanMove) &&
|
||||
!_item->_remotePerm.hasPermission(RemotePermissions::CanAddSubDirectories)) {
|
||||
try {
|
||||
FileSystem::setFolderPermissions(newDirStr, FileSystem::FolderPermissions::ReadOnly);
|
||||
|
||||
@ -157,17 +157,17 @@ void CALLBACK cfApiFetchDataCallback(const CF_CALLBACK_INFO *callbackInfo, const
|
||||
callbackInfo->FileSize.QuadPart);
|
||||
};
|
||||
|
||||
if (QCoreApplication::applicationPid() == callbackInfo->ProcessInfo->ProcessId) {
|
||||
qCCritical(lcCfApiWrapper) << "implicit hydration triggered by the client itself. Will lead to a deadlock. Cancel";
|
||||
sendTransferError();
|
||||
return;
|
||||
}
|
||||
|
||||
auto vfs = reinterpret_cast<OCC::VfsCfApi *>(callbackInfo->CallbackContext);
|
||||
Q_ASSERT(vfs->metaObject()->className() == QByteArrayLiteral("OCC::VfsCfApi"));
|
||||
const auto path = QString(QString::fromWCharArray(callbackInfo->VolumeDosName) + QString::fromWCharArray(callbackInfo->NormalizedPath));
|
||||
const auto requestId = QString::number(callbackInfo->TransferKey.QuadPart, 16);
|
||||
|
||||
if (QCoreApplication::applicationPid() == callbackInfo->ProcessInfo->ProcessId) {
|
||||
qCCritical(lcCfApiWrapper) << "implicit hydration triggered by the client itself. Will lead to a deadlock. Cancel" << path << requestId;
|
||||
sendTransferError();
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(lcCfApiWrapper) << "Request hydration for" << path << requestId;
|
||||
|
||||
const auto invokeResult = QMetaObject::invokeMethod(vfs, [=] { vfs->requestHydration(requestId, path); }, Qt::QueuedConnection);
|
||||
@ -781,10 +781,12 @@ bool OCC::CfApiWrapper::isSparseFile(const QString &path)
|
||||
OCC::CfApiWrapper::FileHandle OCC::CfApiWrapper::handleForPath(const QString &path)
|
||||
{
|
||||
if (path.isEmpty()) {
|
||||
qCWarning(lcCfApiWrapper) << "empty path";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!FileSystem::fileExists(path)) {
|
||||
qCWarning(lcCfApiWrapper) << "file does not exist";
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -807,6 +809,7 @@ OCC::CfApiWrapper::FileHandle OCC::CfApiWrapper::handleForPath(const QString &pa
|
||||
}
|
||||
}
|
||||
|
||||
qCWarning(lcCfApiWrapper) << "no handle was created";
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -372,6 +372,14 @@ Vfs::AvailabilityResult VfsCfApi::availability(const QString &folderPath, const
|
||||
return VfsItemAvailability::AlwaysLocal;
|
||||
else
|
||||
return VfsItemAvailability::AllHydrated;
|
||||
} else {
|
||||
if (pin && *pin == PinState::OnlineOnly) {
|
||||
return VfsItemAvailability::OnlineOnly;
|
||||
} else if (pin && *pin == PinState::AlwaysLocal) {
|
||||
return VfsItemAvailability::AlwaysLocal;
|
||||
} else {
|
||||
return VfsItemAvailability::AllDehydrated;
|
||||
}
|
||||
}
|
||||
return AvailabilityError::NoSuchItem;
|
||||
}
|
||||
@ -511,7 +519,7 @@ int VfsCfApi::finalizeHydrationJob(const QString &requestId)
|
||||
VfsCfApi::HydratationAndPinStates VfsCfApi::computeRecursiveHydrationAndPinStates(const QString &folderPath, const Optional<PinState> &basePinState)
|
||||
{
|
||||
Q_ASSERT(!folderPath.endsWith('/'));
|
||||
const auto fullPath = params().filesystemPath + folderPath;
|
||||
const auto fullPath = QString{params().filesystemPath + folderPath};
|
||||
QFileInfo info(params().filesystemPath + folderPath);
|
||||
|
||||
if (!FileSystem::fileExists(fullPath)) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user