From 9ba88f6baf8c60cef0dbc6e0116e0be513a65157 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 12 Feb 2015 11:02:56 +0100 Subject: [PATCH] Windows: Sync .lnk files correctly. #2792 --- src/libsync/filesystem.cpp | 29 +++++++++++++++++++++++------ src/libsync/filesystem.h | 7 +++++++ src/libsync/propagatedownload.cpp | 3 +-- src/libsync/propagateupload.cpp | 6 +++--- src/libsync/propagatorjobs.cpp | 2 ++ 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/libsync/filesystem.cpp b/src/libsync/filesystem.cpp index bbb78d6e9..b59f68794 100644 --- a/src/libsync/filesystem.cpp +++ b/src/libsync/filesystem.cpp @@ -49,7 +49,7 @@ bool FileSystem::fileEquals(const QString& fn1, const QString& fn2) return false; } - if (f1.size() != f2.size()) { + if (getSize(fn1) != getSize(fn2)) { return false; } @@ -82,12 +82,9 @@ time_t FileSystem::getModTime(const QString &filename) csync_vio_file_stat_t* stat = csync_vio_file_stat_new(); qint64 result = -1; if (csync_vio_local_stat(filename.toUtf8().data(), stat) != -1 - && (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME)) - { + && (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME)) { result = stat->mtime; - } - else - { + } else { qDebug() << "Could not get modification time for" << filename << "with csync, using QFileInfo"; result = Utility::qDateTimeToTime_t(QFileInfo(filename).lastModified()); @@ -217,6 +214,26 @@ bool FileSystem::openFileSharedRead(QFile* file, QString* error) return ok; } +qint64 FileSystem::getSize(const QString& filename) +{ +#ifdef Q_OS_WIN + if (filename.endsWith(".lnk")) { + // Use csync to get the file size. Qt seems unable to get at it. + qint64 result = 0; + csync_vio_file_stat_t* stat = csync_vio_file_stat_new(); + if (csync_vio_local_stat(filename.toUtf8().data(), stat) != -1 + && (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE)) { + result = stat->size; + } else { + qDebug() << "Could not get size time for" << filename << "with csync"; + } + csync_vio_file_stat_destroy(stat); + return result; + } +#endif + return QFileInfo(filename).size(); +} + #ifdef Q_OS_WIN QString FileSystem::fileSystemForPath(const QString & path) { diff --git a/src/libsync/filesystem.h b/src/libsync/filesystem.h index cfdf407e0..cd89e38fb 100644 --- a/src/libsync/filesystem.h +++ b/src/libsync/filesystem.h @@ -43,6 +43,13 @@ time_t OWNCLOUDSYNC_EXPORT getModTime(const QString &filename); bool setModTime(const QString &filename, time_t modTime); +/** Get the size for a file. + * + * Use this over QFileInfo::size() to avoid bugs with lnk files on Windows. + * See https://bugreports.qt.io/browse/QTBUG-24831. + */ +qint64 OWNCLOUDSYNC_EXPORT getSize(const QString& filename); + /** * Rename the file \a originFileName to \a destinationFileName, and overwrite the destination if it * already exists diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 07b3f41fb..6e3f559fd 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -517,11 +517,10 @@ void PropagateDownloadFileQNAM::downloadFinished() return; } - existingFile.refresh(); // Maybe we downloaded a newer version of the file than we thought we would... // Get up to date information for the journal. FileSystem::setModTime(fn, _item._modtime); - _item._size = existingFile.size(); + _item._size = FileSystem::getSize(fn); _propagator->_journal->setFileRecord(SyncJournalFileRecord(_item, fn)); _propagator->_journal->setDownloadInfo(_item._file, SyncJournalDb::DownloadInfo()); diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index dc140f758..ca1793bc4 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -159,7 +159,7 @@ void PropagateUploadFileQNAM::start() // Update the mtime and size, it might have changed since discovery. _item._modtime = FileSystem::getModTime(fi.absoluteFilePath()); - quint64 fileSize = fi.size(); + quint64 fileSize = FileSystem::getSize(fi.absoluteFilePath()); _item._size = fileSize; // But skip the file if the mtime is too close to 'now'! @@ -220,7 +220,7 @@ bool UploadDevice::prepareAndOpen(const QString& fileName, qint64 start, qint64 return false; } - size = qMin(file.size(), size); + size = qMin(FileSystem::getSize(fileName), size); _data.resize(size); if (!file.seek(start)) { setErrorString(file.errorString()); @@ -501,7 +501,7 @@ void PropagateUploadFileQNAM::slotPutFinished() // compare expected and real modification time of the file and size const time_t new_mtime = FileSystem::getModTime(fi.absoluteFilePath()); - const quint64 new_size = static_cast(fi.size()); + const quint64 new_size = static_cast(FileSystem::getSize(fi.absoluteFilePath())); if (new_mtime != _item._modtime || new_size != _item._size) { qDebug() << "The local file has changed during upload:" << "mtime: " << _item._modtime << "<->" << new_mtime diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp index 9e2d6fbc1..fecacdb38 100644 --- a/src/libsync/propagatorjobs.cpp +++ b/src/libsync/propagatorjobs.cpp @@ -48,6 +48,8 @@ static bool removeRecursively(const QString &path, QString &error) di.next(); const QFileInfo& fi = di.fileInfo(); bool ok; + // The use of isSymLink here is okay: + // we never want to go into this branch for .lnk files if (fi.isDir() && !fi.isSymLink()) { ok = removeRecursively(di.filePath(), error); // recursive } else {