Skip to content
Binary file modified dist/addon.node
Binary file not shown.
1 change: 0 additions & 1 deletion include/sync_root_interface/SyncRoot.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ class SyncRoot
static std::string GetFileIdentity(const wchar_t *path);
static void HydrateFile(const wchar_t *filePath);
static void DehydrateFile(const wchar_t *filePath);
static void DeleteFileSyncRoot(const wchar_t *path);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not used in javascript so we can remove it.


private:
CF_CONNECTION_KEY connectionKey;
Expand Down
1 change: 0 additions & 1 deletion include/virtual_drive/Wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ napi_value addLoggerPathWrapper(napi_env env, napi_callback_info args);
napi_value UpdateSyncStatusWrapper(napi_env env, napi_callback_info args);
napi_value GetPlaceholderStateWrapper(napi_env env, napi_callback_info args);
napi_value ConvertToPlaceholderWrapper(napi_env env, napi_callback_info args);
napi_value DeleteFileSyncRootWrapper(napi_env env, napi_callback_info args);
napi_value UpdateFileIdentityWrapper(napi_env env, napi_callback_info args);
napi_value DehydrateFileWrapper(napi_env env, napi_callback_info args);
napi_value HydrateFileWrapper(napi_env env, napi_callback_info args);
Expand Down
11 changes: 8 additions & 3 deletions include/virtual_drive/napi_safe_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@
#include <string>

template <typename Fn>
napi_value napi_safe_wrap(napi_env env, napi_callback_info info, Fn&& fn) {
napi_value napi_safe_wrap(napi_env env, napi_callback_info info, Fn&& fn, const char* function_name) {
try {
return fn(env, info);
} catch (const std::exception& e) {
napi_throw_error(env, nullptr, e.what());
std::string error_msg = std::string("[") + function_name + "] " + e.what();
napi_throw_error(env, nullptr, error_msg.c_str());
} catch (...) {
napi_throw_error(env, nullptr, "Unknown native error");
std::string error_msg = std::string("[") + function_name + "] Unknown native error";
napi_throw_error(env, nullptr, error_msg.c_str());
}

return nullptr;
}

#define NAPI_SAFE_WRAP(env, info, fn) \
napi_safe_wrap(env, info, fn, __FUNCTION__)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Basically we have created this wrapper so we log also the name of the function that is wrapping. Why? This is wrapper that wraps all unexpected C++ exceptions and converts them in a javascript exception (napi_throw_error). We concatenate the message with the name of the function FUNCTION.


#endif
17 changes: 0 additions & 17 deletions native-src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,23 +139,6 @@ napi_value init(napi_env env, napi_value exports)
return nullptr;
}

napi_property_descriptor deleteFileSyncRootDesc = {
"deleteFileSyncRoot",
nullptr,
DeleteFileSyncRootWrapper,
nullptr,
nullptr,
nullptr,
napi_default,
nullptr};

napi_status deleteFileSyncRootStatus = napi_define_properties(env, exports, 1, &deleteFileSyncRootDesc);
if (deleteFileSyncRootStatus != napi_ok)
{
napi_throw_error(env, nullptr, "Failed to define getFileIdentity function");
return nullptr;
}

napi_property_descriptor addLoggerPathDesc = {
"addLoggerPath",
nullptr,
Expand Down
108 changes: 23 additions & 85 deletions native-src/sync_root_interface/SyncRoot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ namespace fs = std::filesystem;
CF_CONNECTION_KEY gloablConnectionKey;
std::map<std::wstring, CF_CONNECTION_KEY> connectionMap;

void TransformInputCallbacksToSyncCallbacks(napi_env env, InputSyncCallbacks input)
{
register_threadsafe_callbacks(env, input);
}

void AddCustomState(
_In_ winrt::IVector<winrt::StorageProviderItemPropertyDefinition> &customStates,
_In_ LPCWSTR displayNameResource,
Expand Down Expand Up @@ -257,40 +252,30 @@ HRESULT SyncRoot::UnregisterSyncRoot(const wchar_t *providerIdStr)

HRESULT SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env, CF_CONNECTION_KEY *connectionKey)
{
try
{
Utilities::AddFolderToSearchIndexer(syncRootPath);

TransformInputCallbacksToSyncCallbacks(env, syncCallbacks);

CF_CALLBACK_REGISTRATION callbackTable[] = {
{CF_CALLBACK_TYPE_FETCH_DATA, fetch_data_callback_wrapper},
{CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, cancel_fetch_data_callback_wrapper},
CF_CALLBACK_REGISTRATION_END};

HRESULT hr = CfConnectSyncRoot(
syncRootPath,
callbackTable,
nullptr, // Contexto (opcional)
CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH,
connectionKey);
wprintf(L"Connection key: %llu\n", *connectionKey);
if (SUCCEEDED(hr))
{
connectionMap[syncRootPath] = *connectionKey;
}
return hr;
}
catch (const std::exception &e)
{
wprintf(L"Excepción capturada: %hs\n", e.what());
return E_FAIL;
}
catch (...)
{
wprintf(L"Excepción desconocida capturada\n");
return E_FAIL;
Utilities::AddFolderToSearchIndexer(syncRootPath);
register_threadsafe_callbacks(env, syncCallbacks);

CF_CALLBACK_REGISTRATION callbackTable[] = {
{CF_CALLBACK_TYPE_FETCH_DATA, fetch_data_callback_wrapper},
{CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, cancel_fetch_data_callback_wrapper},
CF_CALLBACK_REGISTRATION_END
};

HRESULT hr = CfConnectSyncRoot(
syncRootPath,
callbackTable,
nullptr,
CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH,
connectionKey
);

wprintf(L"Connection key: %llu\n", connectionKey->Internal);

if (SUCCEEDED(hr)) {
connectionMap[syncRootPath] = *connectionKey;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we have removed the try catch since we already obtaining this using the previous NAPI_SAFE_WRAP in Wrappers.cpp


return hr;
}

// disconection sync root
Expand All @@ -308,50 +293,3 @@ HRESULT SyncRoot::DisconnectSyncRoot(const wchar_t *syncRootPath)
}
return E_FAIL;
}

// struct
struct FileIdentityInfo
{
BYTE *FileIdentity;
size_t FileIdentityLength;
};

void SyncRoot::DeleteFileSyncRoot(const wchar_t *path)
{
try
{
// Mostrar el archivo a eliminar
wprintf(L"Intentando eliminar: %ls\n", path);

// Verificar si el archivo es un directorio o un archivo regular
bool isDirectory = fs::is_directory(path);
wprintf(L"Es directorio: %d\n", isDirectory);

// Si es un directorio, eliminar recursivamente
if (isDirectory)
{
fs::remove_all(path); // Esta línea reemplaza la función personalizada DeleteFileOrDirectory
wprintf(L"Directorio eliminado con éxito: %ls\n", path);
}
else
{
// Si es un archivo, simplemente eliminar
if (!DeleteFileW(path))
{
wprintf(L"No se pudo eliminar el archivo: %ls\n", path);
}
else
{
wprintf(L"Archivo eliminado con éxito: %ls\n", path);
}
}
}
catch (const std::exception &e)
{
wprintf(L"Excepción capturada: %hs\n", e.what());
}
catch (...)
{
wprintf(L"Excepción desconocida capturada\n");
}
}
39 changes: 7 additions & 32 deletions native-src/virtual_drive/Wrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "get_file_identity.h"
#include "connect_sync_root.h"
#include "hydrate_file.h"
#include "napi_safe_wrap.h"
#include "NAPI_SAFE_WRAP.h"

std::string WStringToUTF8(const std::wstring &wstr)
{
Expand All @@ -24,7 +24,7 @@ std::string WStringToUTF8(const std::wstring &wstr)

napi_value CreatePlaceholderFile(napi_env env, napi_callback_info args)
{
return napi_safe_wrap(env, args, create_file_placeholder_impl);
return NAPI_SAFE_WRAP(env, args, create_file_placeholder_impl);
}

/**
Expand Down Expand Up @@ -81,7 +81,7 @@ napi_value UnregisterSyncRootWrapper(napi_env env, napi_callback_info args)
}

napi_value RegisterSyncRootWrapper(napi_env env, napi_callback_info info) {
return napi_safe_wrap(env, info, register_sync_root_impl);
return NAPI_SAFE_WRAP(env, info, register_sync_root_impl);
}

napi_value GetRegisteredSyncRootsWrapper(napi_env env, napi_callback_info args)
Expand Down Expand Up @@ -151,12 +151,12 @@ napi_value GetRegisteredSyncRootsWrapper(napi_env env, napi_callback_info args)

napi_value ConnectSyncRootWrapper(napi_env env, napi_callback_info args)
{
return napi_safe_wrap(env, args, connect_sync_root_impl);
return NAPI_SAFE_WRAP(env, args, connect_sync_root_impl);
}

napi_value CreateEntryWrapper(napi_env env, napi_callback_info args)
{
return napi_safe_wrap(env, args, create_folder_placeholder_impl);
return NAPI_SAFE_WRAP(env, args, create_folder_placeholder_impl);
}

// disconection wrapper
Expand Down Expand Up @@ -190,32 +190,7 @@ napi_value DisconnectSyncRootWrapper(napi_env env, napi_callback_info args)

napi_value GetFileIdentityWrapper(napi_env env, napi_callback_info args)
{
return napi_safe_wrap(env, args, get_file_identity_impl);
}

napi_value DeleteFileSyncRootWrapper(napi_env env, napi_callback_info args)
{
printf("DeleteFileSyncRootWrapper\n");
size_t argc = 1;
napi_value argv[1];
napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr);

if (argc < 1)
{
napi_throw_error(env, nullptr, "The path is required for DeleteFileSyncRoot");
return nullptr;
}

LPCWSTR fullPath;
size_t pathLength;
napi_get_value_string_utf16(env, argv[0], nullptr, 0, &pathLength);
fullPath = new WCHAR[pathLength + 1];
napi_get_value_string_utf16(env, argv[0], reinterpret_cast<char16_t *>(const_cast<wchar_t *>(fullPath)), pathLength + 1, nullptr);

SyncRoot::DeleteFileSyncRoot(fullPath);

delete[] fullPath;
return nullptr;
return NAPI_SAFE_WRAP(env, args, get_file_identity_impl);
}

napi_value addLoggerPathWrapper(napi_env env, napi_callback_info args)
Expand Down Expand Up @@ -409,7 +384,7 @@ napi_value UpdateFileIdentityWrapper(napi_env env, napi_callback_info args)

napi_value HydrateFileWrapper(napi_env env, napi_callback_info args)
{
return napi_safe_wrap(env, args, hydrate_file_impl);
return NAPI_SAFE_WRAP(env, args, hydrate_file_impl);
}

napi_value DehydrateFileWrapper(napi_env env, napi_callback_info args)
Expand Down
60 changes: 11 additions & 49 deletions native-src/virtual_drive/connect_sync_root.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,77 +5,39 @@ napi_value connect_sync_root_impl(napi_env env, napi_callback_info args)
{
size_t argc = 2;
napi_value argv[2];

napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr);

if (argc < 2)
{
napi_throw_error(env, nullptr, "Se requieren más argumentos para ConnectSyncRoot");
return nullptr;
}

LPCWSTR syncRootPath;
size_t pathLength;
napi_get_value_string_utf16(env, argv[0], nullptr, 0, &pathLength);
syncRootPath = new WCHAR[pathLength + 1];
napi_get_value_string_utf16(env, argv[0], reinterpret_cast<char16_t *>(const_cast<wchar_t *>(syncRootPath)), pathLength + 1, nullptr);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This could lead to a memory leak.

std::wstring syncRootPath(pathLength, L'\0');
napi_get_value_string_utf16(env, argv[0], reinterpret_cast<char16_t*>(&syncRootPath[0]), pathLength + 1, nullptr);

// CALLBACKS
InputSyncCallbacks callbacks = {};

napi_value fetchDataCallback;
napi_value cancelFetchDataCallback;

if (napi_get_named_property(env, argv[1], "fetchDataCallback", &fetchDataCallback) == napi_ok)
{
napi_create_reference(env, fetchDataCallback, 1, &callbacks.fetch_data_callback_ref);
}

napi_valuetype valuetype_fetch_data;
napi_status type_status_fetch_data = napi_typeof(env, fetchDataCallback, &valuetype_fetch_data);
if (type_status_fetch_data != napi_ok || valuetype_fetch_data != napi_function)
{
napi_throw_error(env, nullptr, "fetchDataCallback should be a function.");
return nullptr;
}
napi_get_named_property(env, argv[1], "fetchDataCallback", &fetchDataCallback);
napi_create_reference(env, fetchDataCallback, 1, &callbacks.fetch_data_callback_ref);

if (napi_get_named_property(env, argv[1], "cancelFetchDataCallback", &cancelFetchDataCallback) == napi_ok)
{
napi_create_reference(env, cancelFetchDataCallback, 1, &callbacks.cancel_fetch_data_callback_ref);
}

napi_valuetype valuetype_cancel_fetch_data;
napi_status type_status_cancel_fetch_data = napi_typeof(env, cancelFetchDataCallback, &valuetype_cancel_fetch_data);
if (type_status_cancel_fetch_data != napi_ok || valuetype_cancel_fetch_data != napi_function)
{
napi_throw_error(env, nullptr, "cancelFetchDataCallback should be a function.");
return nullptr;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since we control the input from javascript we don't need to validate here that we pass functions, otherwise it will break in development and we make this function clearer and simpler.

napi_value cancelFetchDataCallback;
napi_get_named_property(env, argv[1], "cancelFetchDataCallback", &cancelFetchDataCallback);
napi_create_reference(env, cancelFetchDataCallback, 1, &callbacks.cancel_fetch_data_callback_ref);

CF_CONNECTION_KEY connectionKey;
HRESULT hr = SyncRoot::ConnectSyncRoot(syncRootPath, callbacks, env, &connectionKey);
HRESULT hr = SyncRoot::ConnectSyncRoot(syncRootPath.c_str(), callbacks, env, &connectionKey);

delete[] syncRootPath;

if (FAILED(hr))
{
if (FAILED(hr)) {
napi_throw_error(env, nullptr, "ConnectSyncRoot failed");
return nullptr;
}

napi_value resultObj, hrValue, connectionKeyValue;

napi_create_object(env, &resultObj);

napi_create_int32(env, static_cast<int32_t>(hr), &hrValue);
napi_set_named_property(env, resultObj, "hr", hrValue);

std::wstringstream ss;
ss << connectionKey.Internal;

std::wstring connectionKeyString = ss.str();
napi_create_string_utf16(env, reinterpret_cast<const char16_t *>(connectionKeyString.c_str()), connectionKeyString.length(), &connectionKeyValue);

std::wstring connectionKeyString = std::to_wstring(connectionKey.Internal);
napi_create_string_utf16(env, reinterpret_cast<const char16_t*>(connectionKeyString.c_str()), connectionKeyString.length(), &connectionKeyValue);
napi_set_named_property(env, resultObj, "connectionKey", connectionKeyValue);

return resultObj;
Expand Down
Loading