Skip to content

Commit dc3f154

Browse files
Hydrate file thread safe (#188)
* Create napi safe wrap * Extract create folder placeholder * Extract create file placeholder * Extract get file identity * Update package.json * Extract connect sync root * Extract hydrate file * Hydrate file thread safe * Improve safe wrap * Remove delete file from c++
1 parent ce01cdc commit dc3f154

File tree

9 files changed

+107
-221
lines changed

9 files changed

+107
-221
lines changed

dist/addon.node

-19 KB
Binary file not shown.

include/sync_root_interface/SyncRoot.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ class SyncRoot
3333
static std::string GetFileIdentity(const wchar_t *path);
3434
static void HydrateFile(const wchar_t *filePath);
3535
static void DehydrateFile(const wchar_t *filePath);
36-
static void DeleteFileSyncRoot(const wchar_t *path);
3736

3837
private:
3938
CF_CONNECTION_KEY connectionKey;

include/virtual_drive/Wrappers.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ napi_value addLoggerPathWrapper(napi_env env, napi_callback_info args);
1414
napi_value UpdateSyncStatusWrapper(napi_env env, napi_callback_info args);
1515
napi_value GetPlaceholderStateWrapper(napi_env env, napi_callback_info args);
1616
napi_value ConvertToPlaceholderWrapper(napi_env env, napi_callback_info args);
17-
napi_value DeleteFileSyncRootWrapper(napi_env env, napi_callback_info args);
1817
napi_value UpdateFileIdentityWrapper(napi_env env, napi_callback_info args);
1918
napi_value DehydrateFileWrapper(napi_env env, napi_callback_info args);
2019
napi_value HydrateFileWrapper(napi_env env, napi_callback_info args);

include/virtual_drive/napi_safe_wrap.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,21 @@
66
#include <string>
77

88
template <typename Fn>
9-
napi_value napi_safe_wrap(napi_env env, napi_callback_info info, Fn&& fn) {
9+
napi_value napi_safe_wrap(napi_env env, napi_callback_info info, Fn&& fn, const char* function_name) {
1010
try {
1111
return fn(env, info);
1212
} catch (const std::exception& e) {
13-
napi_throw_error(env, nullptr, e.what());
13+
std::string error_msg = std::string("[") + function_name + "] " + e.what();
14+
napi_throw_error(env, nullptr, error_msg.c_str());
1415
} catch (...) {
15-
napi_throw_error(env, nullptr, "Unknown native error");
16+
std::string error_msg = std::string("[") + function_name + "] Unknown native error";
17+
napi_throw_error(env, nullptr, error_msg.c_str());
1618
}
1719

1820
return nullptr;
1921
}
2022

23+
#define NAPI_SAFE_WRAP(env, info, fn) \
24+
napi_safe_wrap(env, info, fn, __FUNCTION__)
25+
2126
#endif

native-src/main.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -139,23 +139,6 @@ napi_value init(napi_env env, napi_value exports)
139139
return nullptr;
140140
}
141141

142-
napi_property_descriptor deleteFileSyncRootDesc = {
143-
"deleteFileSyncRoot",
144-
nullptr,
145-
DeleteFileSyncRootWrapper,
146-
nullptr,
147-
nullptr,
148-
nullptr,
149-
napi_default,
150-
nullptr};
151-
152-
napi_status deleteFileSyncRootStatus = napi_define_properties(env, exports, 1, &deleteFileSyncRootDesc);
153-
if (deleteFileSyncRootStatus != napi_ok)
154-
{
155-
napi_throw_error(env, nullptr, "Failed to define getFileIdentity function");
156-
return nullptr;
157-
}
158-
159142
napi_property_descriptor addLoggerPathDesc = {
160143
"addLoggerPath",
161144
nullptr,

native-src/sync_root_interface/SyncRoot.cpp

Lines changed: 23 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ namespace fs = std::filesystem;
1111
CF_CONNECTION_KEY gloablConnectionKey;
1212
std::map<std::wstring, CF_CONNECTION_KEY> connectionMap;
1313

14-
void TransformInputCallbacksToSyncCallbacks(napi_env env, InputSyncCallbacks input)
15-
{
16-
register_threadsafe_callbacks(env, input);
17-
}
18-
1914
void AddCustomState(
2015
_In_ winrt::IVector<winrt::StorageProviderItemPropertyDefinition> &customStates,
2116
_In_ LPCWSTR displayNameResource,
@@ -257,40 +252,30 @@ HRESULT SyncRoot::UnregisterSyncRoot(const wchar_t *providerIdStr)
257252

258253
HRESULT SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env, CF_CONNECTION_KEY *connectionKey)
259254
{
260-
try
261-
{
262-
Utilities::AddFolderToSearchIndexer(syncRootPath);
263-
264-
TransformInputCallbacksToSyncCallbacks(env, syncCallbacks);
265-
266-
CF_CALLBACK_REGISTRATION callbackTable[] = {
267-
{CF_CALLBACK_TYPE_FETCH_DATA, fetch_data_callback_wrapper},
268-
{CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, cancel_fetch_data_callback_wrapper},
269-
CF_CALLBACK_REGISTRATION_END};
270-
271-
HRESULT hr = CfConnectSyncRoot(
272-
syncRootPath,
273-
callbackTable,
274-
nullptr, // Contexto (opcional)
275-
CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH,
276-
connectionKey);
277-
wprintf(L"Connection key: %llu\n", *connectionKey);
278-
if (SUCCEEDED(hr))
279-
{
280-
connectionMap[syncRootPath] = *connectionKey;
281-
}
282-
return hr;
283-
}
284-
catch (const std::exception &e)
285-
{
286-
wprintf(L"Excepción capturada: %hs\n", e.what());
287-
return E_FAIL;
288-
}
289-
catch (...)
290-
{
291-
wprintf(L"Excepción desconocida capturada\n");
292-
return E_FAIL;
255+
Utilities::AddFolderToSearchIndexer(syncRootPath);
256+
register_threadsafe_callbacks(env, syncCallbacks);
257+
258+
CF_CALLBACK_REGISTRATION callbackTable[] = {
259+
{CF_CALLBACK_TYPE_FETCH_DATA, fetch_data_callback_wrapper},
260+
{CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, cancel_fetch_data_callback_wrapper},
261+
CF_CALLBACK_REGISTRATION_END
262+
};
263+
264+
HRESULT hr = CfConnectSyncRoot(
265+
syncRootPath,
266+
callbackTable,
267+
nullptr,
268+
CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH,
269+
connectionKey
270+
);
271+
272+
wprintf(L"Connection key: %llu\n", connectionKey->Internal);
273+
274+
if (SUCCEEDED(hr)) {
275+
connectionMap[syncRootPath] = *connectionKey;
293276
}
277+
278+
return hr;
294279
}
295280

296281
// disconection sync root
@@ -308,50 +293,3 @@ HRESULT SyncRoot::DisconnectSyncRoot(const wchar_t *syncRootPath)
308293
}
309294
return E_FAIL;
310295
}
311-
312-
// struct
313-
struct FileIdentityInfo
314-
{
315-
BYTE *FileIdentity;
316-
size_t FileIdentityLength;
317-
};
318-
319-
void SyncRoot::DeleteFileSyncRoot(const wchar_t *path)
320-
{
321-
try
322-
{
323-
// Mostrar el archivo a eliminar
324-
wprintf(L"Intentando eliminar: %ls\n", path);
325-
326-
// Verificar si el archivo es un directorio o un archivo regular
327-
bool isDirectory = fs::is_directory(path);
328-
wprintf(L"Es directorio: %d\n", isDirectory);
329-
330-
// Si es un directorio, eliminar recursivamente
331-
if (isDirectory)
332-
{
333-
fs::remove_all(path); // Esta línea reemplaza la función personalizada DeleteFileOrDirectory
334-
wprintf(L"Directorio eliminado con éxito: %ls\n", path);
335-
}
336-
else
337-
{
338-
// Si es un archivo, simplemente eliminar
339-
if (!DeleteFileW(path))
340-
{
341-
wprintf(L"No se pudo eliminar el archivo: %ls\n", path);
342-
}
343-
else
344-
{
345-
wprintf(L"Archivo eliminado con éxito: %ls\n", path);
346-
}
347-
}
348-
}
349-
catch (const std::exception &e)
350-
{
351-
wprintf(L"Excepción capturada: %hs\n", e.what());
352-
}
353-
catch (...)
354-
{
355-
wprintf(L"Excepción desconocida capturada\n");
356-
}
357-
}

native-src/virtual_drive/Wrappers.cpp

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "get_file_identity.h"
1515
#include "connect_sync_root.h"
1616
#include "hydrate_file.h"
17-
#include "napi_safe_wrap.h"
17+
#include "NAPI_SAFE_WRAP.h"
1818

1919
std::string WStringToUTF8(const std::wstring &wstr)
2020
{
@@ -24,7 +24,7 @@ std::string WStringToUTF8(const std::wstring &wstr)
2424

2525
napi_value CreatePlaceholderFile(napi_env env, napi_callback_info args)
2626
{
27-
return napi_safe_wrap(env, args, create_file_placeholder_impl);
27+
return NAPI_SAFE_WRAP(env, args, create_file_placeholder_impl);
2828
}
2929

3030
/**
@@ -81,7 +81,7 @@ napi_value UnregisterSyncRootWrapper(napi_env env, napi_callback_info args)
8181
}
8282

8383
napi_value RegisterSyncRootWrapper(napi_env env, napi_callback_info info) {
84-
return napi_safe_wrap(env, info, register_sync_root_impl);
84+
return NAPI_SAFE_WRAP(env, info, register_sync_root_impl);
8585
}
8686

8787
napi_value GetRegisteredSyncRootsWrapper(napi_env env, napi_callback_info args)
@@ -151,12 +151,12 @@ napi_value GetRegisteredSyncRootsWrapper(napi_env env, napi_callback_info args)
151151

152152
napi_value ConnectSyncRootWrapper(napi_env env, napi_callback_info args)
153153
{
154-
return napi_safe_wrap(env, args, connect_sync_root_impl);
154+
return NAPI_SAFE_WRAP(env, args, connect_sync_root_impl);
155155
}
156156

157157
napi_value CreateEntryWrapper(napi_env env, napi_callback_info args)
158158
{
159-
return napi_safe_wrap(env, args, create_folder_placeholder_impl);
159+
return NAPI_SAFE_WRAP(env, args, create_folder_placeholder_impl);
160160
}
161161

162162
// disconection wrapper
@@ -190,32 +190,7 @@ napi_value DisconnectSyncRootWrapper(napi_env env, napi_callback_info args)
190190

191191
napi_value GetFileIdentityWrapper(napi_env env, napi_callback_info args)
192192
{
193-
return napi_safe_wrap(env, args, get_file_identity_impl);
194-
}
195-
196-
napi_value DeleteFileSyncRootWrapper(napi_env env, napi_callback_info args)
197-
{
198-
printf("DeleteFileSyncRootWrapper\n");
199-
size_t argc = 1;
200-
napi_value argv[1];
201-
napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr);
202-
203-
if (argc < 1)
204-
{
205-
napi_throw_error(env, nullptr, "The path is required for DeleteFileSyncRoot");
206-
return nullptr;
207-
}
208-
209-
LPCWSTR fullPath;
210-
size_t pathLength;
211-
napi_get_value_string_utf16(env, argv[0], nullptr, 0, &pathLength);
212-
fullPath = new WCHAR[pathLength + 1];
213-
napi_get_value_string_utf16(env, argv[0], reinterpret_cast<char16_t *>(const_cast<wchar_t *>(fullPath)), pathLength + 1, nullptr);
214-
215-
SyncRoot::DeleteFileSyncRoot(fullPath);
216-
217-
delete[] fullPath;
218-
return nullptr;
193+
return NAPI_SAFE_WRAP(env, args, get_file_identity_impl);
219194
}
220195

221196
napi_value addLoggerPathWrapper(napi_env env, napi_callback_info args)
@@ -409,7 +384,7 @@ napi_value UpdateFileIdentityWrapper(napi_env env, napi_callback_info args)
409384

410385
napi_value HydrateFileWrapper(napi_env env, napi_callback_info args)
411386
{
412-
return napi_safe_wrap(env, args, hydrate_file_impl);
387+
return NAPI_SAFE_WRAP(env, args, hydrate_file_impl);
413388
}
414389

415390
napi_value DehydrateFileWrapper(napi_env env, napi_callback_info args)

native-src/virtual_drive/connect_sync_root.cpp

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,77 +5,39 @@ napi_value connect_sync_root_impl(napi_env env, napi_callback_info args)
55
{
66
size_t argc = 2;
77
napi_value argv[2];
8-
98
napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr);
109

11-
if (argc < 2)
12-
{
13-
napi_throw_error(env, nullptr, "Se requieren más argumentos para ConnectSyncRoot");
14-
return nullptr;
15-
}
16-
17-
LPCWSTR syncRootPath;
1810
size_t pathLength;
1911
napi_get_value_string_utf16(env, argv[0], nullptr, 0, &pathLength);
20-
syncRootPath = new WCHAR[pathLength + 1];
21-
napi_get_value_string_utf16(env, argv[0], reinterpret_cast<char16_t *>(const_cast<wchar_t *>(syncRootPath)), pathLength + 1, nullptr);
12+
std::wstring syncRootPath(pathLength, L'\0');
13+
napi_get_value_string_utf16(env, argv[0], reinterpret_cast<char16_t*>(&syncRootPath[0]), pathLength + 1, nullptr);
2214

23-
// CALLBACKS
2415
InputSyncCallbacks callbacks = {};
2516

2617
napi_value fetchDataCallback;
27-
napi_value cancelFetchDataCallback;
28-
29-
if (napi_get_named_property(env, argv[1], "fetchDataCallback", &fetchDataCallback) == napi_ok)
30-
{
31-
napi_create_reference(env, fetchDataCallback, 1, &callbacks.fetch_data_callback_ref);
32-
}
33-
34-
napi_valuetype valuetype_fetch_data;
35-
napi_status type_status_fetch_data = napi_typeof(env, fetchDataCallback, &valuetype_fetch_data);
36-
if (type_status_fetch_data != napi_ok || valuetype_fetch_data != napi_function)
37-
{
38-
napi_throw_error(env, nullptr, "fetchDataCallback should be a function.");
39-
return nullptr;
40-
}
18+
napi_get_named_property(env, argv[1], "fetchDataCallback", &fetchDataCallback);
19+
napi_create_reference(env, fetchDataCallback, 1, &callbacks.fetch_data_callback_ref);
4120

42-
if (napi_get_named_property(env, argv[1], "cancelFetchDataCallback", &cancelFetchDataCallback) == napi_ok)
43-
{
44-
napi_create_reference(env, cancelFetchDataCallback, 1, &callbacks.cancel_fetch_data_callback_ref);
45-
}
46-
47-
napi_valuetype valuetype_cancel_fetch_data;
48-
napi_status type_status_cancel_fetch_data = napi_typeof(env, cancelFetchDataCallback, &valuetype_cancel_fetch_data);
49-
if (type_status_cancel_fetch_data != napi_ok || valuetype_cancel_fetch_data != napi_function)
50-
{
51-
napi_throw_error(env, nullptr, "cancelFetchDataCallback should be a function.");
52-
return nullptr;
53-
}
21+
napi_value cancelFetchDataCallback;
22+
napi_get_named_property(env, argv[1], "cancelFetchDataCallback", &cancelFetchDataCallback);
23+
napi_create_reference(env, cancelFetchDataCallback, 1, &callbacks.cancel_fetch_data_callback_ref);
5424

5525
CF_CONNECTION_KEY connectionKey;
56-
HRESULT hr = SyncRoot::ConnectSyncRoot(syncRootPath, callbacks, env, &connectionKey);
26+
HRESULT hr = SyncRoot::ConnectSyncRoot(syncRootPath.c_str(), callbacks, env, &connectionKey);
5727

58-
delete[] syncRootPath;
59-
60-
if (FAILED(hr))
61-
{
28+
if (FAILED(hr)) {
6229
napi_throw_error(env, nullptr, "ConnectSyncRoot failed");
6330
return nullptr;
6431
}
6532

6633
napi_value resultObj, hrValue, connectionKeyValue;
67-
6834
napi_create_object(env, &resultObj);
6935

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

73-
std::wstringstream ss;
74-
ss << connectionKey.Internal;
75-
76-
std::wstring connectionKeyString = ss.str();
77-
napi_create_string_utf16(env, reinterpret_cast<const char16_t *>(connectionKeyString.c_str()), connectionKeyString.length(), &connectionKeyValue);
78-
39+
std::wstring connectionKeyString = std::to_wstring(connectionKey.Internal);
40+
napi_create_string_utf16(env, reinterpret_cast<const char16_t*>(connectionKeyString.c_str()), connectionKeyString.length(), &connectionKeyValue);
7941
napi_set_named_property(env, resultObj, "connectionKey", connectionKeyValue);
8042

8143
return resultObj;

0 commit comments

Comments
 (0)