From: allexzander Date: Wed, 17 Mar 2021 08:05:35 +0000 (+0200) Subject: Fix for Windows long path issue. X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~313^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=3fde838beef27dd6857cef1e66e203114b537c55;p=nextcloud-desktop.git Fix for Windows long path issue. Signed-off-by: allexzander --- diff --git a/src/csync/vio/csync_vio_local_win.cpp b/src/csync/vio/csync_vio_local_win.cpp index a2cbdaf56..cc31927d5 100644 --- a/src/csync/vio/csync_vio_local_win.cpp +++ b/src/csync/vio/csync_vio_local_win.cpp @@ -52,7 +52,7 @@ struct csync_vio_handle_t { QString path; // Always ends with '\' }; -static int _csync_vio_local_stat_mb(const mbchar_t *uri, csync_file_stat_t *buf); +static int _csync_vio_local_stat_mb(const QString &path, csync_file_stat_t *buf); csync_vio_handle_t *csync_vio_local_opendir(const QString &name) { @@ -174,12 +174,12 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h file_stat->size = (handle->ffd.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + handle->ffd.nFileSizeLow; file_stat->modtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem); - std::wstring fullPath; + QString fullPath; fullPath.reserve(handle->path.size() + std::wcslen(handle->ffd.cFileName)); - fullPath += handle->path.toStdWString(); // path always ends with '\', by construction - fullPath += handle->ffd.cFileName; + fullPath += handle->path; // path always ends with '\', by construction + fullPath += QString::fromWCharArray(handle->ffd.cFileName); - if (_csync_vio_local_stat_mb(fullPath.data(), file_stat.get()) < 0) { + if (_csync_vio_local_stat_mb(fullPath, file_stat.get()) < 0) { // Will get excluded by _csync_detect_update. file_stat->type = ItemTypeSkip; } @@ -190,12 +190,11 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h int csync_vio_local_stat(const QString &uri, csync_file_stat_t *buf) { - const std::wstring wuri = uri.toStdWString(); - int rc = _csync_vio_local_stat_mb(wuri.data(), buf); + int rc = _csync_vio_local_stat_mb(uri, buf); return rc; } -static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf) +static int _csync_vio_local_stat_mb(const QString &path, csync_file_stat_t *buf) { /* Almost nothing to do since csync_vio_local_readdir already filled up most of the information But we still need to fetch the file ID. @@ -206,18 +205,20 @@ static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf BY_HANDLE_FILE_INFORMATION fileInfo; ULARGE_INTEGER FileIndex; - h = CreateFileW( wuri, 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + const auto longPath = OCC::FileSystem::longWinPath(path); + + h = CreateFileW(longPath.toStdWString().data(), 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr ); if( h == INVALID_HANDLE_VALUE ) { - qCCritical(lcCSyncVIOLocal, "CreateFileW failed on %ls", wuri); + qCCritical(lcCSyncVIOLocal) << "CreateFileW failed on" << longPath; errno = GetLastError(); return -1; } if(!GetFileInformationByHandle( h, &fileInfo ) ) { - qCCritical(lcCSyncVIOLocal, "GetFileInformationByHandle failed on %ls", wuri); + qCCritical(lcCSyncVIOLocal) << "GetFileInformationByHandle failed on" << longPath; errno = GetLastError(); CloseHandle(h); return -1; diff --git a/src/libsync/vfs/cfapi/cfapiwrapper.cpp b/src/libsync/vfs/cfapi/cfapiwrapper.cpp index fe0c36dea..7a46040a7 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.cpp +++ b/src/libsync/vfs/cfapi/cfapiwrapper.cpp @@ -15,6 +15,7 @@ #include "cfapiwrapper.h" #include "common/utility.h" +#include "common/filesystembase.h" #include "hydrationjob.h" #include "vfs_cfapi.h" @@ -370,6 +371,10 @@ bool OCC::CfApiWrapper::isSparseFile(const QString &path) OCC::CfApiWrapper::FileHandle OCC::CfApiWrapper::handleForPath(const QString &path) { + if (path.isEmpty()) { + return {}; + } + if (QFileInfo(path).isDir()) { HANDLE handle = nullptr; const qint64 openResult = CfOpenFileWithOplock(path.toStdWString().data(), CF_OPEN_FILE_FLAG_NONE, &handle); @@ -377,10 +382,13 @@ OCC::CfApiWrapper::FileHandle OCC::CfApiWrapper::handleForPath(const QString &pa return {handle, [](HANDLE h) { CfCloseHandle(h); }}; } } else { - const auto handle = CreateFile(path.toStdWString().data(), 0, 0, nullptr, + const auto longpath = OCC::FileSystem::longWinPath(path); + const auto handle = CreateFile(longpath.toStdWString().data(), 0, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (handle != INVALID_HANDLE_VALUE) { return {handle, [](HANDLE h) { CloseHandle(h); }}; + } else { + qCCritical(lcCfApiWrapper) << "Could not CreateFile for longpath:" << longpath << "with error:" << GetLastError(); } } diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.cpp b/src/libsync/vfs/cfapi/vfs_cfapi.cpp index baeea51c1..6c6d9e49d 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -375,7 +375,8 @@ VfsCfApi::HydratationAndPinStates VfsCfApi::computeRecursiveHydrationAndPinState return currentState; } - const auto path = folderPath + '/' + name; + // if the folderPath.isEmpty() we don't want to end up having path "/example.file" because this will lead to double slash later, when appending to "SyncFolder/" + const auto path = folderPath.isEmpty() ? name : folderPath + '/' + name; const auto states = computeRecursiveHydrationAndPinStates(path, currentState.pinState); return HydratationAndPinStates { states.pinState,