return {QString{"Could not update metadata due to invalid modification time for %1: %2"}.arg(path).arg(modtime)};
}
- const auto info = findPlaceholderInfo(path);
- if (!info) {
- return { "Can't update non existing placeholder info" };
- }
-
const auto fileIdentity = QString::fromUtf8(fileId).toStdWString();
const auto fileIdentitySize = (fileIdentity.length() + 1) * sizeof(wchar_t);
- CF_FILE_RANGE dehydrationRange;
- dehydrationRange.StartingOffset.QuadPart = 0;
- dehydrationRange.Length.QuadPart = size;
-
- const qint64 result = CfUpdatePlaceholder(handleForPath(path).get(), nullptr,
- fileIdentity.data(), sizeToDWORD(fileIdentitySize),
- &dehydrationRange,
- 1,
- CF_UPDATE_FLAG_MARK_IN_SYNC | CF_UPDATE_FLAG_DEHYDRATE,
- nullptr,
- nullptr);
-
- if (result != S_OK) {
- qCWarning(lcCfApiWrapper) << "Couldn't update placeholder info for" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage());
- return { "Couldn't update placeholder info" };
+ const auto info = findPlaceholderInfo(path);
+ if (info) {
+ CF_FILE_RANGE dehydrationRange;
+ dehydrationRange.StartingOffset.QuadPart = 0;
+ dehydrationRange.Length.QuadPart = size;
+
+ const qint64 result = CfUpdatePlaceholder(handleForPath(path).get(),
+ nullptr,
+ fileIdentity.data(),
+ sizeToDWORD(fileIdentitySize),
+ &dehydrationRange,
+ 1,
+ CF_UPDATE_FLAG_MARK_IN_SYNC | CF_UPDATE_FLAG_DEHYDRATE,
+ nullptr,
+ nullptr);
+
+ if (result != S_OK) {
+ qCWarning(lcCfApiWrapper) << "Couldn't update placeholder info for" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage());
+ return {"Couldn't update placeholder info"};
+ }
+ } else {
+ const qint64 result = CfConvertToPlaceholder(handleForPath(path).get(),
+ fileIdentity.data(),
+ sizeToDWORD(fileIdentitySize),
+ CF_CONVERT_FLAG_MARK_IN_SYNC | CF_CONVERT_FLAG_DEHYDRATE,
+ nullptr,
+ nullptr);
+
+ if (result != S_OK) {
+ qCWarning(lcCfApiWrapper) << "Couldn't convert to placeholder" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage());
+ return {"Couldn't convert to placeholder"};
+ }
}
return OCC::Vfs::ConvertToPlaceholderResult::Ok;
QTest::newRow("skip local discovery") << false;
}
+ void testReplaceOnlineOnlyFile()
+ {
+ FakeFolder fakeFolder{FileInfo{}};
+ auto vfs = setupVfs(fakeFolder);
+
+ // Create a new local (non-placeholder) file
+ fakeFolder.localModifier().insert("file");
+ QVERIFY(!vfs->pinState("file").isValid());
+
+ CopyFile(QString(fakeFolder.localPath() + "file").toStdWString().data(), QString(fakeFolder.localPath() + "file1").toStdWString().data(), false);
+
+ // Sync the files: files should be converted to placeholder files
+ QVERIFY(fakeFolder.syncOnce());
+ QVERIFY(vfs->pinState("file").isValid());
+
+ // Convert to Online Only
+ ::setPinState(fakeFolder.localPath() + "file", PinState::OnlineOnly, cfapi::Recurse);
+
+ QVERIFY(fakeFolder.syncOnce());
+ QCOMPARE(*vfs->pinState("file"), PinState::OnlineOnly);
+ CFVERIFY_VIRTUAL(fakeFolder, "file");
+
+ // Replace the file
+ CopyFile(QString(fakeFolder.localPath() + "file1").toStdWString().data(), QString(fakeFolder.localPath() + "file").toStdWString().data(), false);
+
+ // Sync again: file should be correctly dehydrated again without error.
+ QVERIFY(fakeFolder.syncOnce());
+ QVERIFY(vfs->pinState("file").isValid());
+ QCOMPARE(*vfs->pinState("file"), PinState::OnlineOnly);
+ CFVERIFY_VIRTUAL(fakeFolder, "file");
+ }
+
void testVirtualFileLifecycle()
{
QFETCH(bool, doLocalDiscovery);