Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
21bd1ad
Create napi safe wrap
dajimenezriv-internxt Aug 15, 2025
819a1f1
Extract create folder placeholder
dajimenezriv-internxt Aug 16, 2025
cc1b678
Extract create file placeholder
dajimenezriv-internxt Aug 16, 2025
444a2d5
Extract get file identity
dajimenezriv-internxt Aug 19, 2025
b5eff5e
Update package.json
dajimenezriv-internxt Aug 19, 2025
fe31746
Extract connect sync root
dajimenezriv-internxt Aug 27, 2025
32c5ea9
Extract hydrate file
dajimenezriv-internxt Sep 8, 2025
75681d6
Hydrate file thread safe
dajimenezriv-internxt Sep 8, 2025
205f2be
Improve safe wrap
dajimenezriv-internxt Sep 8, 2025
9648c94
Remove delete file from c++
dajimenezriv-internxt Sep 8, 2025
46ee84c
Extract convert to placeholder
dajimenezriv-internxt Sep 10, 2025
313dfbf
Refactor register sync root
dajimenezriv-internxt Sep 15, 2025
ff28084
Extract code
dajimenezriv-internxt Sep 15, 2025
d1a7164
Improve
dajimenezriv-internxt Sep 15, 2025
70d004e
Simplify providerId
dajimenezriv-internxt Sep 15, 2025
69ce991
Commit
dajimenezriv-internxt Sep 15, 2025
1020526
Commit
dajimenezriv-internxt Sep 15, 2025
e94646e
Commit
dajimenezriv-internxt Sep 15, 2025
0601df9
Update get_registered_sync_roots.cpp
dajimenezriv-internxt Sep 15, 2025
73a1c9e
Update addon.node
dajimenezriv-internxt Sep 15, 2025
ae38d77
Commt
dajimenezriv-internxt Sep 15, 2025
f7b6a44
Commit
dajimenezriv-internxt Sep 16, 2025
41028a0
Simplify unregister
dajimenezriv-internxt Sep 16, 2025
38a0e29
Fix wrapper
dajimenezriv-internxt Sep 16, 2025
4832626
Remove context
dajimenezriv-internxt Sep 16, 2025
d947054
Improve napi
dajimenezriv-internxt Sep 16, 2025
39f1f5e
Merge branch 'master' into refactor-unregister-sync-root
dajimenezriv-internxt Sep 17, 2025
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
3 changes: 2 additions & 1 deletion binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"native-src/virtual_drive/get_registered_sync_roots/get_registered_sync_roots_wrapper.cpp",
"native-src/virtual_drive/hydrate_file.cpp",
"native-src/virtual_drive/register_sync_root/register_sync_root.cpp",
"native-src/virtual_drive/register_sync_root/register_sync_root_wrapper.cpp"
"native-src/virtual_drive/register_sync_root/register_sync_root_wrapper.cpp",
"native-src/virtual_drive/unregister_sync_root_wrapper.cpp"
],
"include_dirs": [
"include",
Expand Down
Binary file modified dist/addon.node
Binary file not shown.
2 changes: 0 additions & 2 deletions include/sync_root_interface/SyncRoot.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ class SyncRoot
public:
static HRESULT ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env, CF_CONNECTION_KEY *connectionKey);
static HRESULT DisconnectSyncRoot(const wchar_t *syncRootPath);
static HRESULT UnregisterSyncRoot(const GUID &providerId);
static HRESULT UnregisterSyncRoot(const wchar_t *providerIdStr);
static std::string GetFileIdentity(const wchar_t *path);
static void HydrateFile(const wchar_t *filePath);
static void DehydrateFile(const wchar_t *filePath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ struct SyncRoots
std::wstring path;
std::wstring displayName;
std::wstring version;
std::wstring context;
};

std::vector<SyncRoots> get_registered_sync_roots();
15 changes: 10 additions & 5 deletions include/virtual_drive/napi_safe_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@

template <typename Fn>
napi_value napi_safe_wrap(napi_env env, napi_callback_info info, Fn&& fn, const char* function_name) {
std::ostringstream oss;

try {
return fn(env, info);
} catch (const winrt::hresult_error& e) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Improve it to handle windows cloud api errors so we can print correctly the errors.

oss << "[" << function_name << "] WinRT error: "
<< winrt::to_string(e.message())
<< " (HRESULT: 0x" << std::hex << e.code() << ")";
} catch (const std::exception& e) {
std::string error_msg = std::string("[") + function_name + "] " + e.what();
napi_throw_error(env, nullptr, error_msg.c_str());
oss << "[" << function_name << "] " << e.what();
} catch (...) {
std::string error_msg = std::string("[") + function_name + "] Unknown native error";
napi_throw_error(env, nullptr, error_msg.c_str());
oss << "[" << function_name << "] Unknown native error";
}


napi_throw_error(env, nullptr, oss.str().c_str());
return nullptr;
}

Expand Down
5 changes: 5 additions & 0 deletions include/virtual_drive/unregister_sync_root_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <node_api.h>

napi_value unregister_sync_root_wrapper(napi_env env, napi_callback_info args);
34 changes: 0 additions & 34 deletions native-src/sync_root_interface/SyncRoot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,40 +104,6 @@ void SyncRoot::DehydrateFile(const wchar_t *filePath)
}
}

HRESULT SyncRoot::UnregisterSyncRoot(const GUID &providerId)
{
try
{
// Convert GUID to string for syncRootID
wchar_t syncRootID[39];
StringFromGUID2(providerId, syncRootID, 39);

Logger::getInstance().log("Unregistering sync root.", LogLevel::INFO);
winrt::StorageProviderSyncRootManager::Unregister(syncRootID);
return S_OK;
}
catch (...)
{
wprintf(L"Could not unregister the sync root, hr %08x\n", static_cast<HRESULT>(winrt::to_hresult()));
return E_FAIL;
}
}

HRESULT SyncRoot::UnregisterSyncRoot(const wchar_t *providerIdStr)
{
try
{
Logger::getInstance().log("Unregistering sync root (string).", LogLevel::INFO);
winrt::StorageProviderSyncRootManager::Unregister(providerIdStr);
return S_OK;
}
catch (...)
{
wprintf(L"Could not unregister the sync root (string), hr %08x\n", static_cast<HRESULT>(winrt::to_hresult()));
return E_FAIL;
}
}

HRESULT SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env, CF_CONNECTION_KEY *connectionKey)
{
Utilities::AddFolderToSearchIndexer(syncRootPath);
Expand Down
57 changes: 4 additions & 53 deletions native-src/virtual_drive/Wrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,64 +16,15 @@
#include "hydrate_file.h"
#include "convert_to_placeholder.h"
#include "get_registered_sync_roots_wrapper.h"
#include "unregister_sync_root_wrapper.h"
#include "NAPI_SAFE_WRAP.h"

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

/**
* v2.5.7 Carlos Gonzalez
* Added backward compatibility for the default virtual drive identifier "syncRootID".
* If the provided ID is "syncRootID", it will be unregistered without throwing an error,
* maintaining support for previous versions that used it instead of a GUID.
*/

napi_value UnregisterSyncRootWrapper(napi_env env, napi_callback_info args)
{
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 provider ID is required for UnregisterSyncRoot");
return nullptr;
}

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


HRESULT result;
HRESULT guidResult = CLSIDFromString(providerIdStr, &providerId);

if (SUCCEEDED(guidResult))
{
result = SyncRoot::UnregisterSyncRoot(providerId);
}
else if (wcscmp(providerIdStr, L"syncRootID") == 0)
{
result = SyncRoot::UnregisterSyncRoot(providerIdStr);
}
else
{
napi_throw_error(env, nullptr, "Invalid provider ID: must be a GUID or 'syncRootID'");
delete[] providerIdStr;
return nullptr;
}

delete[] providerIdStr;

napi_value napiResult;
napi_create_int32(env, static_cast<int32_t>(result), &napiResult);
return napiResult;
napi_value UnregisterSyncRootWrapper(napi_env env, napi_callback_info args) {
return NAPI_SAFE_WRAP(env, args, unregister_sync_root_wrapper);
}

napi_value RegisterSyncRootWrapper(napi_env env, napi_callback_info info) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ std::vector<SyncRoots> get_registered_sync_roots() {
sr.path = info.Path().Path();
sr.displayName = info.DisplayNameResource();
sr.version = info.Version();

auto contextBuffer = info.Context();
if (contextBuffer) {
sr.context = winrt::CryptographicBuffer::ConvertBinaryToString(winrt::BinaryStringEncoding::Utf8, contextBuffer).c_str();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We no longer need the context of the cloud provider since now we are filtering by the displayName and path.


syncRootList.push_back(sr);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ napi_value get_registered_sync_roots_wrapper(napi_env env, napi_callback_info ar
add_string_property(env, jsObj, "path", roots[i].path);
add_string_property(env, jsObj, "displayName", roots[i].displayName);
add_string_property(env, jsObj, "version", roots[i].version);
add_string_property(env, jsObj, "context", roots[i].context);

napi_set_element(env, jsArray, i, jsObj);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,5 @@ void register_sync_root(const wchar_t *syncRootPath, const wchar_t *providerName
winrt::Uri uri(L"https://drive.internxt.com/app/trash");
info.RecycleBinUri(uri);

std::wstring syncRootIdentity(syncRootPath);
syncRootIdentity.append(L"#inxt#");
syncRootIdentity.append(providerName);

winrt::IBuffer contextBuffer = winrt::CryptographicBuffer::ConvertStringToBinary(syncRootIdentity, winrt::BinaryStringEncoding::Utf8);
info.Context(contextBuffer);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As said, we were adding the context when registering the cloud provider to filter later, however now we filter using the displayName and path.


winrt::StorageProviderSyncRootManager::Register(info);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#include <Windows.h>
#include "register_sync_root.h"

napi_value register_sync_root_wrapper(napi_env env, napi_callback_info args)
{
napi_value register_sync_root_wrapper(napi_env env, napi_callback_info args) {
size_t argc = 5;
napi_value argv[5];
napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr);
Expand Down
19 changes: 19 additions & 0 deletions native-src/virtual_drive/unregister_sync_root_wrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <windows.h>
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 the new unregister. Basically now we don't care if it's an uuid, the "syncRoot" text or whatever. We assume that was javascript sends here is a existing sync root, which it should.

#include <node_api.h>
#include <string>
#include "stdafx.h"

napi_value unregister_sync_root_wrapper(napi_env env, napi_callback_info args) {
size_t argc = 1;
napi_value argv[1];
napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr);

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

winrt::StorageProviderSyncRootManager::Unregister(providerId);

return nullptr;
}