From 5bc4a068ad5c891edffb362bd496d3f2eb0d2afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Thu, 22 May 2025 11:55:25 +0200 Subject: [PATCH] feat: add file in use check and improve error messaging in DehydrateFile --- native-src/sync_root_interface/SyncRoot.cpp | 43 +++++++++++++++++---- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/native-src/sync_root_interface/SyncRoot.cpp b/native-src/sync_root_interface/SyncRoot.cpp index 6049075b..10cc9641 100644 --- a/native-src/sync_root_interface/SyncRoot.cpp +++ b/native-src/sync_root_interface/SyncRoot.cpp @@ -5,6 +5,7 @@ #include "Logger.h" #include #include +#include "Placeholders.h" namespace fs = std::filesystem; // variable to disconect @@ -78,13 +79,38 @@ void SyncRoot::HydrateFile(const wchar_t *filePath) } } +bool IsFileInUse(const wchar_t* filePath) { + WIN32_FIND_DATAW findData; + HANDLE hFind = FindFirstFileW(filePath, &findData); + + if (hFind == INVALID_HANDLE_VALUE) { + DWORD error = GetLastError(); + if (error == ERROR_SHARING_VIOLATION || error == ERROR_CLOUD_FILE_IN_USE) { + return true; + } + return false; + } + + FindClose(hFind); + return false; +} + void SyncRoot::DehydrateFile(const wchar_t *filePath) { - // Logger::getInstance().log("Dehydration file init", LogLevel::INFO); wprintf(L"Dehydration file init %ls\n", filePath); DWORD attrib = GetFileAttributesW(filePath); if (!(attrib & FILE_ATTRIBUTE_DIRECTORY)) { + if (IsFileInUse(filePath)) { + wprintf(L"Cannot dehydrate because the file is currently in use: %ls\n", filePath); + MessageBoxW( + nullptr, + L"Unablaa to free up space because the file is currently in use.\nPlease close the file and try again.", + L"File in use", + MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL); + return; + } + winrt::handle placeholder(CreateFileW(filePath, 0, FILE_READ_DATA, nullptr, OPEN_EXISTING, 0, nullptr)); LARGE_INTEGER offset; @@ -94,8 +120,7 @@ void SyncRoot::DehydrateFile(const wchar_t *filePath) if (attrib & FILE_ATTRIBUTE_UNPINNED) { - // Logger::getInstance().log("Dehydrating file " + Logger::fromWStringToString(filePath), LogLevel::INFO); - wprintf(L"Dehydrating file starteeed %ls\n", filePath); + wprintf(L"Dehydrating file started %ls\n", filePath); HRESULT hr = CfDehydratePlaceholder(placeholder.get(), offset, length, CF_DEHYDRATE_FLAG_NONE, NULL); if (FAILED(hr)) @@ -104,23 +129,27 @@ void SyncRoot::DehydrateFile(const wchar_t *filePath) if (err == ERROR_SHARING_VIOLATION || err == ERROR_CLOUD_FILE_IN_USE) { wprintf(L"Cannot dehydrate because the file is currently in use: %ls\n", filePath); - MessageBoxW( nullptr, - L"Unable to free up space because the file is currently in use.\nPlease close the file and try again.", + L"Unablbb to free up space because the file is currently in use.\nPlease close the file and try again.", L"File in use", MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL); + + // Only restore states if CfDehydratePlaceholder failed + try { + Placeholders::UpdatePinState(filePath, PinState::AlwaysLocal); + } catch (...) { + wprintf(L"Failed to restore file states: %ls\n", filePath); + } } else { wprintf(L"Error dehydrating file %ls\n", filePath); } - // Logger::getInstance().log("Error dehydrating file " + Logger::fromWStringToString(filePath), LogLevel::ERROR); } else { wprintf(L"Dehydration finished %ls\n", filePath); - // Logger::getInstance().log("Dehydration finished " + Logger::fromWStringToString(filePath), LogLevel::INFO); } } }