Windows: Sync .lnk files correctly. #2792

This commit is contained in:
Christian Kamm 2015-02-12 11:02:56 +01:00
parent 6be0b2b6c3
commit 9ba88f6baf
5 changed files with 36 additions and 11 deletions

View file

@ -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)
{

View file

@ -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

View file

@ -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());

View file

@ -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<quint64>(fi.size());
const quint64 new_size = static_cast<quint64>(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

View file

@ -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 {