Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
11 changes: 8 additions & 3 deletions include/placeholders_interface/Placeholders.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ enum class PlaceholderAttribute
PINNED = 2,
};

struct PlaceholderResult {
bool success;
std::wstring errorMessage;
};

class Placeholders
{
public:
static void CreateOne(
static PlaceholderResult CreateOne(
_In_ PCWSTR fileName,
_In_ PCWSTR fileIdentity,
int64_t fileSize,
Expand All @@ -26,7 +31,7 @@ class Placeholders

static void MaintainIdentity(std::wstring &fullPath, PCWSTR fileIdentity, bool isDirectory);

static void CreateEntry(
static PlaceholderResult CreateEntry(
_In_ PCWSTR itemName,
_In_ PCWSTR itemIdentity,
bool isDirectory,
Expand All @@ -44,7 +49,7 @@ class Placeholders
static CF_PLACEHOLDER_STATE GetPlaceholderState(const std::wstring &filePath);
static std::vector<std::wstring> GetPlaceholderWithStatePending(const std::wstring &filePath);
static bool IsFileValidForSync(const std::wstring &filePath);
static bool ConvertToPlaceholder(const std::wstring &fullPath, const std::wstring &serverIdentity);
static PlaceholderResult ConvertToPlaceholder(const std::wstring &fullPath, const std::wstring &serverIdentity);
static std::string GetFileIdentity(const std::wstring &filePath);
static void UpdateFileIdentity(const std::wstring &filePath, const std::wstring &fileIdentity, bool isDirectory);
static PlaceholderAttribute GetAttribute(const std::wstring &filePath);
Expand Down
148 changes: 74 additions & 74 deletions native-src/placeholders_interface/Planceholders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <winbase.h>
#include <string>
#include <cctype>
#include <windows.h>
#include <shlobj.h>

using namespace std;

Expand All @@ -26,7 +28,7 @@ bool DirectoryExists(const wchar_t *path)
return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY);
}

void Placeholders::CreateOne(
PlaceholderResult Placeholders::CreateOne(
_In_ PCWSTR fileName,
_In_ PCWSTR fileIdentity,
int64_t fileSize,
Expand All @@ -37,6 +39,8 @@ void Placeholders::CreateOne(
FILETIME lastAccessTime,
_In_ PCWSTR destPath)
{
PlaceholderResult result = {false, L""};

try
{
CF_PLACEHOLDER_CREATE_INFO cloudEntry = {};
Expand All @@ -49,7 +53,8 @@ void Placeholders::CreateOne(
{
Placeholders::ConvertToPlaceholder(fullPath, fileIdentity);
Placeholders::MaintainIdentity(fullPath, fileIdentity, false);
return;
result.success = true;
return result;
}

std::wstring relativeName(fileIdentity);
Expand All @@ -71,9 +76,11 @@ void Placeholders::CreateOne(
{
winrt::check_hresult(CfCreatePlaceholders(fullDestPath.c_str(), &cloudEntry, 1, CF_CREATE_FLAG_NONE, NULL));
Placeholders::UpdatePinState(fullPath, PinState::OnlineOnly);
result.success = true;
}
catch (const winrt::hresult_error &error)
{
result.errorMessage = error.message().c_str();
wprintf(L"[CreatePlaceholder] error: %s", error.message().c_str());
}
winrt::StorageProviderItemProperty prop;
Expand All @@ -85,8 +92,11 @@ void Placeholders::CreateOne(
}
catch (...)
{
result.errorMessage = L"Failed to create or customize placeholder";
wprintf(L"[CreatePlaceholder] Failed to create or customize placeholder with %08x\n", static_cast<HRESULT>(winrt::to_hresult()));
}

return result;
}

std::string cleanString(const std::string &str)
Expand Down Expand Up @@ -128,7 +138,7 @@ void Placeholders::MaintainIdentity(std::wstring &fullPath, PCWSTR itemIdentity,
}
}

void Placeholders::CreateEntry(
PlaceholderResult Placeholders::CreateEntry(
_In_ PCWSTR itemName,
_In_ PCWSTR itemIdentity,
bool isDirectory,
Expand All @@ -140,6 +150,7 @@ void Placeholders::CreateEntry(
FILETIME lastAccessTime,
_In_ PCWSTR destPath)
{
PlaceholderResult result = {false, L""};

std::wstring fullDestPath = std::wstring(destPath) + L"\\" + std::wstring(itemName);
CF_PLACEHOLDER_CREATE_INFO cloudEntry = {};
Expand All @@ -158,7 +169,8 @@ void Placeholders::CreateEntry(
{
Placeholders::ConvertToPlaceholder(fullDestPath, itemIdentity);
Placeholders::MaintainIdentity(fullDestPath, itemIdentity, true);
return; // No hacer nada si ya existe
result.success = true;
return result;
}

if (isDirectory) // TODO: the function createEntry is used to create only folders (directories), so this if is always true
Expand All @@ -168,106 +180,94 @@ void Placeholders::CreateEntry(
HRESULT hr = CfCreatePlaceholders(fullDestPath.c_str(), &cloudEntry, 1, CF_CREATE_FLAG_NONE, NULL);
if (FAILED(hr))
{
result.errorMessage = L"Failed to create placeholder directory";
wprintf(L"[CreatePlaceholder] Failed to create placeholder directory with HRESULT 0x%08x\n", hr);
throw winrt::hresult_error(hr);
}

std::wstring finalPath = std::wstring(destPath) + L"\\" + std::wstring(itemName);
Placeholders::UpdatePinState(finalPath, PinState::OnlineOnly);
UpdateSyncStatus(finalPath, true, true);
result.success = true;
}
}
catch (const winrt::hresult_error &error)
{
result.errorMessage = error.message().c_str();
wprintf(L"[CreatePlaceholder] Error while creating %s: %s\n", isDirectory ? L"directory" : L"file", error.message().c_str());
}
catch (...)
{
result.errorMessage = L"Unknown error occurred";
wprintf(L"[CreatePlaceholder] Unknown error occurred\n");
}

return result;
}

bool Placeholders::ConvertToPlaceholder(const std::wstring &fullPath, const std::wstring &serverIdentity)
PlaceholderResult Placeholders::ConvertToPlaceholder(const std::wstring &fullPath, const std::wstring &serverIdentity)
{
try
PlaceholderResult result = {false, L""};

if (!std::filesystem::exists(fullPath))
{
if (!std::filesystem::exists(fullPath))
{
wprintf(L"[ConvertToPlaceholder] File does not exist\n");
return false;
}
result.errorMessage = L"File does not exist";
return result;
}

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

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,
nullptr);
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,
nullptr);

if (fileHandle == INVALID_HANDLE_VALUE)
{
// Manejar el error al abrir el archivo
return false;
}
if (fileHandle == INVALID_HANDLE_VALUE)
{
result.errorMessage = L"Failed to open file: " + std::to_wstring(GetLastError());
return result;
}

CF_CONVERT_FLAGS convertFlags = CF_CONVERT_FLAG_MARK_IN_SYNC;
USN convertUsn;
OVERLAPPED overlapped = {};
CF_CONVERT_FLAGS convertFlags = CF_CONVERT_FLAG_MARK_IN_SYNC;
USN convertUsn;
OVERLAPPED overlapped = {};

LPCVOID idStrLPCVOID = static_cast<LPCVOID>(serverIdentity.c_str());
DWORD idStrByteLength = static_cast<DWORD>(serverIdentity.size() * sizeof(wchar_t));
LPCVOID idStrLPCVOID = static_cast<LPCVOID>(serverIdentity.c_str());
DWORD idStrByteLength = static_cast<DWORD>(serverIdentity.size() * sizeof(wchar_t));

HRESULT hr = CfConvertToPlaceholder(fileHandle, idStrLPCVOID, idStrByteLength, convertFlags, &convertUsn, &overlapped);
HRESULT hr = CfConvertToPlaceholder(fileHandle, idStrLPCVOID, idStrByteLength, convertFlags, &convertUsn, &overlapped);

if (FAILED(hr))
if (FAILED(hr))
{
CloseHandle(fileHandle);
if (hr != 0x8007017C) // Ignorar error específico de "ya es un placeholder"
{
// Manejar el error al convertir a marcador de posición
if (hr != 0x8007017C)
{
wprintf(L"[ConvertToPlaceholder] Error converting to placeholder, ConvertToPlaceholder failed with HRESULT 0x%X\n", hr);
}

// Puedes obtener información detallada sobre el error usando FormatMessage
LPVOID errorMsg;
FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hr,
0, // Default language
(LPWSTR)&errorMsg,
0,
NULL);

// Liberar el buffer de mensaje de error
LocalFree(errorMsg);

CloseHandle(fileHandle);
return false;
result.errorMessage = L"Failed to convert to placeholder. HRESULT: 0x" + std::to_wstring(static_cast<unsigned int>(hr));
return result;
}
return result;
}

if (!isDirectory)
if (!isDirectory)
{
HRESULT hrPinState = CfSetPinState(fileHandle, CF_PIN_STATE_PINNED, CF_SET_PIN_FLAG_NONE, nullptr);
if (FAILED(hrPinState))
{
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);
result.errorMessage = L"Failed to set pin state. HRESULT: 0x" + std::to_wstring(static_cast<unsigned int>(hrPinState));
return result;
}

CloseHandle(fileHandle);
wprintf(L"[ConvertToPlaceholder] Successfully converted to placeholder: %ls\n", fullPath.c_str());
return true;
}
catch (const winrt::hresult_error &error)
{
// Manejar excepciones desconocidas
wprintf(L"[ConvertToPlaceholder] Unknown exception occurred\n");
return false;
}

CloseHandle(fileHandle);
wprintf(L"[ConvertToPlaceholder] Successfully converted to placeholder: %ls\n", fullPath.c_str());
result.success = true;
return result;
}

std::wstring GetErrorMessageFromHRESULT(HRESULT hr)
Expand Down
Loading