Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/sync_root_interface/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Utilities
static std::wstring ProcessErrorNameToWString(_In_ ProcessErrorName error);
static std::wstring FileOperationErrorToWString(_In_ FileOperationError error);
static bool IsTemporaryFile(const std::wstring &fullPath);
static std::wstring GetErrorMessageCloudFiles(HRESULT hr);

static winrt::com_array<wchar_t>
ConvertSidToStringSid(_In_ PSID sid)
Expand Down
145 changes: 105 additions & 40 deletions native-src/placeholders_interface/Planceholders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,22 +189,21 @@ bool Placeholders::ConvertToPlaceholder(const std::wstring &fullPath, const std:
{
if (!std::filesystem::exists(fullPath))
{
// El archivo no existe
wprintf(L"[ConvertToPlaceholder] File does not exist\n");
return false;
}

// Obtener un handle al archivo
// print fullPath
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And maybe this one isn't necessary either. I think wprintf with fullPath.c_str() is self-explanatory.

wprintf(L"[ConvertToPlaceholder] Full path: %ls\n", fullPath.c_str());
bool isDirectory = fs::is_directory(fullPath);

// Obtener un handle al archivo o carpeta
HANDLE fileHandle = CreateFileW(
fullPath.c_str(),
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr,
OPEN_EXISTING,
isDirectory ? FILE_FLAG_BACKUP_SEMANTICS : 0, // Agregar FILE_FLAG_BACKUP_SEMANTICS si es una carpeta
isDirectory ? FILE_FLAG_BACKUP_SEMANTICS : 0,
nullptr);

if (fileHandle == INVALID_HANDLE_VALUE)
Expand All @@ -217,7 +216,6 @@ bool Placeholders::ConvertToPlaceholder(const std::wstring &fullPath, const std:
USN convertUsn;
OVERLAPPED overlapped = {};

// Convierte la cadena de la identidad del servidor a LPCVOID
LPCVOID idStrLPCVOID = static_cast<LPCVOID>(serverIdentity.c_str());
DWORD idStrByteLength = static_cast<DWORD>(serverIdentity.size() * sizeof(wchar_t));

Expand Down Expand Up @@ -246,13 +244,19 @@ bool Placeholders::ConvertToPlaceholder(const std::wstring &fullPath, const std:
LocalFree(errorMsg);

CloseHandle(fileHandle);

return false;
}

if (!isDirectory)
{
CfSetPinState(fileHandle, CF_PIN_STATE_PINNED, CF_SET_PIN_FLAG_NONE, nullptr);
HRESULT hrPinState = CfSetPinState(fileHandle, CF_PIN_STATE_PINNED, CF_SET_PIN_FLAG_NONE, nullptr);
if (FAILED(hrPinState))
{
std::wstring errorMessage = Utilities::GetErrorMessageCloudFiles(hrPinState);
wprintf(L"[ConvertToPlaceholder] Error setting pin state, HRESULT: 0x%X\nDetails: %s\n", hrPinState, errorMessage.c_str());
CloseHandle(fileHandle);
return false;
}
}

CloseHandle(fileHandle);
Expand All @@ -267,43 +271,113 @@ bool Placeholders::ConvertToPlaceholder(const std::wstring &fullPath, const std:
}
}

// Función para obtener el mensaje de error de HRESULT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this comment is necessary since the function name describes well what it does, but in any case, we should put comments in english.

std::wstring GetErrorMessageFromHRESULT(HRESULT hr)
{
LPWSTR errorMessage = nullptr;
DWORD result = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&errorMessage),
0,
nullptr);

std::wstring message;
if (result > 0 && errorMessage)
{
message = errorMessage;
LocalFree(errorMessage);
}
else
{
message = L"Error desconocido";
}

return message;
}

/**
* @brief Mark a file or directory as synchronized
* @param filePath path to the file or directory
* @param isDirectory true if the path is a directory, false if it is a file
* @return void
*/
void Placeholders::UpdateSyncStatus(const std::wstring &filePath, bool inputSyncState, bool isDirectory = false)
void Placeholders::UpdateSyncStatus(const std::wstring &filePath,
bool inputSyncState,
bool isDirectory /* = false */)
{
wprintf(L"[UpdateSyncStatus] Path: %ls\n", filePath.c_str());
HANDLE fileHandle = CreateFileW(
filePath.c_str(),
FILE_WRITE_ATTRIBUTES, // permisson needed to change the state
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_EXISTING,
isDirectory ? FILE_FLAG_BACKUP_SEMANTICS : FILE_ATTRIBUTE_NORMAL,
nullptr);

if (fileHandle == INVALID_HANDLE_VALUE)
CF_PLACEHOLDER_STATE state = GetPlaceholderState(filePath);
if (state == CF_PLACEHOLDER_STATE_INVALID)
{
if (!ConvertToPlaceholder(filePath, L"temp_identity"))
{
wprintf(L"[UpdateSyncStatus] ‑ no se pudo convertir a placeholder\n");
return;
}
}


DWORD flags = FILE_FLAG_OPEN_REPARSE_POINT;
if (isDirectory) flags |= FILE_FLAG_BACKUP_SEMANTICS;

HANDLE h = CreateFileW(filePath.c_str(),
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr,
OPEN_EXISTING,
flags,
nullptr);

if (h == INVALID_HANDLE_VALUE)
{
wprintf(L"[UpdateSyncStatus] Error al abrir el archivo: %d\n", GetLastError());
wprintf(L"[UpdateSyncStatus] CreateFileW falló: %lu\n", GetLastError());
CloseHandle(fileHandle);
return;
}

// https://learn.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfsetinsyncstate
// https://learn.microsoft.com/en-us/windows/win32/api/cfapi/ne-cfapi-cf_in_sync_state
CF_IN_SYNC_STATE syncState = inputSyncState ? CF_IN_SYNC_STATE_IN_SYNC : CF_IN_SYNC_STATE_NOT_IN_SYNC;
// wprintf(L"Marking item as %s: %ls\n", inputSyncState ? L"IN_SYNC" : L"NOT_IN_SYNC", filePath.c_str());
HRESULT hr = CfSetInSyncState(fileHandle, syncState, CF_SET_IN_SYNC_FLAG_NONE, nullptr);
// imprimir hresult
CF_IN_SYNC_STATE sync = inputSyncState ? CF_IN_SYNC_STATE_IN_SYNC
: CF_IN_SYNC_STATE_NOT_IN_SYNC;

HRESULT hr = CfSetInSyncState(h, sync, CF_SET_IN_SYNC_FLAG_NONE, nullptr);

if (FAILED(hr))
{
wprintf(L"[UpdateSyncStatus] Error al establecer el estado de sincronización: %ld\n", hr);
switch (HRESULT_CODE(hr))
{
case ERROR_RETRY:
Sleep(50);
hr = CfSetInSyncState(h, sync, CF_SET_IN_SYNC_FLAG_NONE, nullptr);
wprintf(L"[UpdateSyncStatus] Retry CfSetInSyncState\n");
break;

case ERROR_CLOUD_FILE_PROVIDER_NOT_RUNNING: // 0x1A94
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, filePath.c_str(), nullptr);
wprintf(L"[UpdateSyncStatus] Retry CfSetInSyncState\n");
break;

case ERROR_CLOUD_FILE_NOT_IN_SYNC:
ConvertToPlaceholder(filePath, L"temp_identity");
hr = CfSetInSyncState(h, sync, CF_SET_IN_SYNC_FLAG_NONE, nullptr);
wprintf(L"[UpdateSyncStatus] Retry CfSetInSyncState\n");
break;

default:
wprintf(L"[UpdateSyncStatus] CfSetInSyncState 0x%08X\n", hr);
break;
}
}
else
{
wprintf(L"[UpdateSyncStatus] Estado actualizado\n");
}

CloseHandle(fileHandle);
CloseHandle(h);

SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, filePath.c_str(), nullptr);
}

void Placeholders::UpdateFileIdentity(const std::wstring &filePath, const std::wstring &fileIdentity, bool isDirectory)
Expand Down Expand Up @@ -351,20 +425,11 @@ void Placeholders::UpdateFileIdentity(const std::wstring &filePath, const std::w

if (FAILED(hr))
{
wprintf(L"[UpdateFileIdentity] Error updating fileIdentity: 0x%08X\n", hr);
LPWSTR errorMessage = nullptr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
HRESULT_CODE(hr),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&errorMessage),
0,
nullptr);
if (errorMessage)
{
wprintf(L"[UpdateFileIdentity] Error: %ls\n", errorMessage);
LocalFree(errorMessage);
}
std::wstring errorMessage = Utilities::GetErrorMessageCloudFiles(hr);
wprintf(L"[UpdateFileIdentity] Error updating fileIdentity: %ls\n", errorMessage.c_str());
CloseHandle(fileHandle);
return;

}

CloseHandle(fileHandle);
Expand Down
20 changes: 20 additions & 0 deletions native-src/sync_root_interface/Utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,26 @@ void Utilities::ApplyTransferStateToFile(_In_ PCWSTR fullPath, _In_ CF_CALLBACK_
}
}

std::wstring Utilities::GetErrorMessageCloudFiles(HRESULT hr) {
LPWSTR errorMsg = nullptr;
DWORD size = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
hr,
0,
(LPWSTR)&errorMsg,
0,
nullptr
);

std::wstring message;
if (size > 0 && errorMsg != nullptr) {
message.assign(errorMsg, size);
}
LocalFree(errorMsg);
return message;
}


bool Utilities::IsTemporaryFile(const std::wstring &fullPath)
{
Expand Down
Loading