diff --git a/README.md b/README.md index 1b4cf2bc..95fadfc8 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/internxt/node-win) \ No newline at end of file +[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/internxt/node-win) [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=coverage)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=bugs)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) diff --git a/binding.gyp b/binding.gyp index 858e963a..8f2aacf2 100644 --- a/binding.gyp +++ b/binding.gyp @@ -17,7 +17,6 @@ "native-src/logger/Logger.cpp", "native-src/logger/LoggerPath.cpp", "native-src/main.cpp", - "native-src/placeholders_interface/PlaceHolderInfo.cpp", "native-src/placeholders_interface/Planceholders.cpp", "native-src/sync_root_interface/SyncRoot.cpp", "native-src/sync_root_interface/Utilities.cpp", diff --git a/dist/addon.node b/dist/addon.node index 35fe60b1..381ce8cc 100644 Binary files a/dist/addon.node and b/dist/addon.node differ diff --git a/include/placeholders_interface/PlaceHolderInfo.h b/include/placeholders_interface/PlaceHolderInfo.h deleted file mode 100644 index fa0514fc..00000000 --- a/include/placeholders_interface/PlaceHolderInfo.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "stdafx.h" -#include - -struct FileState -{ - std::string placeholderId; - CF_PIN_STATE pinState; -}; - -class FileHandle -{ -public: - using Deleter = void (*)(void *); - - FileHandle(); - FileHandle(void *data, Deleter deleter); - - inline void *get() const { return _data.get(); } - inline explicit operator bool() const noexcept { return static_cast(_data); } - -private: - std::unique_ptr _data; -}; - -FileHandle handleForPath(const std::wstring &path); diff --git a/include/placeholders_interface/Placeholders.h b/include/placeholders_interface/Placeholders.h index ac1befec..335a555e 100644 --- a/include/placeholders_interface/Placeholders.h +++ b/include/placeholders_interface/Placeholders.h @@ -1,7 +1,14 @@ #pragma once + #include #include -#include +#include + +struct FileState +{ + std::string placeholderId; + CF_PIN_STATE pinState; +}; class Placeholders { diff --git a/include/stdafx.h b/include/stdafx.h index de7986e5..d55c1e3d 100644 --- a/include/stdafx.h +++ b/include/stdafx.h @@ -19,17 +19,18 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include #include -namespace winrt { +namespace winrt +{ using namespace Windows::Foundation; using namespace Windows::Storage; using namespace Windows::Storage::Streams; diff --git a/include/sync_root_interface/SyncRoot.h b/include/sync_root_interface/SyncRoot.h index 4864fa34..d14dd3d9 100644 --- a/include/sync_root_interface/SyncRoot.h +++ b/include/sync_root_interface/SyncRoot.h @@ -9,9 +9,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); - -private: - CF_CONNECTION_KEY connectionKey; + static void ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env); + static void DisconnectSyncRoot(const wchar_t *syncRootPath); }; diff --git a/include/sync_root_interface/callbacks/Callbacks.h b/include/sync_root_interface/callbacks/Callbacks.h index 381e25cd..b4c57ae7 100644 --- a/include/sync_root_interface/callbacks/Callbacks.h +++ b/include/sync_root_interface/callbacks/Callbacks.h @@ -2,10 +2,8 @@ #include -// Fetch Data Callback void register_threadsafe_fetch_data_callback(const std::string &resource_name, napi_env env, InputSyncCallbacks input); void CALLBACK fetch_data_callback_wrapper(_In_ CONST CF_CALLBACK_INFO *callbackInfo, _In_ CONST CF_CALLBACK_PARAMETERS *callbackParameters); -// Fetch Data Cancel Callback void register_threadsafe_cancel_fetch_data_callback(const std::string &resource_name, napi_env env, InputSyncCallbacks input); void CALLBACK cancel_fetch_data_callback_wrapper(_In_ CONST CF_CALLBACK_INFO *callbackInfo, _In_ CONST CF_CALLBACK_PARAMETERS *callbackParameters); diff --git a/native-src/main.cpp b/native-src/main.cpp index ddb1a1e8..f8e07b7d 100644 --- a/native-src/main.cpp +++ b/native-src/main.cpp @@ -20,11 +20,7 @@ napi_value init(napi_env env, napi_value exports) size_t property_count = sizeof(properties) / sizeof(properties[0]); - if (napi_define_properties(env, exports, property_count, properties) != napi_ok) - { - napi_throw_error(env, nullptr, "Failed to define properties"); - return nullptr; - } + napi_define_properties(env, exports, property_count, properties); return exports; } diff --git a/native-src/placeholders_interface/PlaceHolderInfo.cpp b/native-src/placeholders_interface/PlaceHolderInfo.cpp deleted file mode 100644 index efb60713..00000000 --- a/native-src/placeholders_interface/PlaceHolderInfo.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "PlaceHolderInfo.h" -#include -#include -#include -#include -#include -#include "Logger.h" - -FileHandle::FileHandle() - : _data( - nullptr, [](void *) {}) -{ -} - -FileHandle::FileHandle(void *data, Deleter deleter) - : _data(data, deleter) -{ -} - -FileHandle handleForPath(const std::wstring &wPath) -{ - if (wPath.empty()) - { - return {}; - } - - /** - * v1.0.9 Jonathan Arce - * - * We directly use the wPath parameter in handleForPath for several important reasons: - * - * 1. Performance optimization: Using wPath directly avoids unnecessary string conversions - * between wide strings and UTF-8/ANSI, which would be costly for file operations. - * - * 2. Unicode support: Windows APIs like CfOpenFileWithOplock and CreateFileW require wide - * character strings (wchar_t) to properly handle Unicode paths with international - * characters, spaces, and special symbols. - */ - - std::filesystem::path pathFs(wPath); - if (!std::filesystem::exists(pathFs)) - { - return {}; - } - - if (std::filesystem::is_directory(pathFs)) - { - HANDLE handle = nullptr; - const HRESULT openResult = CfOpenFileWithOplock(wPath.c_str(), CF_OPEN_FILE_FLAG_NONE, &handle); - if (openResult == S_OK) - { - return {handle, [](HANDLE h) - { CfCloseHandle(h); }}; - } - else - { - // Convert only for logging purposes - std::wstring_convert> converter; - std::string path = converter.to_bytes(wPath); - printf("Could not CfOpenFileWithOplock for path: %s with error: %ld\n", path.c_str(), openResult); - } - } - else if (std::filesystem::is_regular_file(pathFs)) - { - HANDLE handle = CreateFileW( - wPath.c_str(), // Use wide string path directly - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE, - nullptr, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - nullptr); - if (handle != INVALID_HANDLE_VALUE) - { - return {handle, [](HANDLE h) - { CloseHandle(h); }}; - } - else - { - // Convert only for logging purposes - std::wstring_convert> converter; - std::string path = converter.to_bytes(wPath); - printf("Could not CreateFile for path: %s with error: %ld\n", path.c_str(), GetLastError()); - } - } - - return {}; -} \ No newline at end of file diff --git a/native-src/placeholders_interface/Planceholders.cpp b/native-src/placeholders_interface/Planceholders.cpp index 56664ad4..90f0d6c6 100644 --- a/native-src/placeholders_interface/Planceholders.cpp +++ b/native-src/placeholders_interface/Planceholders.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "Placeholders.h" #include "Logger.h" -#include "PlaceholderInfo.h" #include #include #include diff --git a/native-src/sync_root_interface/SyncRoot.cpp b/native-src/sync_root_interface/SyncRoot.cpp index 4a135d5f..6f02babf 100644 --- a/native-src/sync_root_interface/SyncRoot.cpp +++ b/native-src/sync_root_interface/SyncRoot.cpp @@ -2,13 +2,12 @@ #include "SyncRoot.h" #include "stdafx.h" #include -#include "Logger.h" #include #include std::map connectionMap; -HRESULT SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env, CF_CONNECTION_KEY *connectionKey) +void SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env) { register_threadsafe_fetch_data_callback("FetchDataThreadSafe", env, syncCallbacks); register_threadsafe_cancel_fetch_data_callback("CancelFetchDataThreadSafe", env, syncCallbacks); @@ -18,35 +17,29 @@ HRESULT SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallback {CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, cancel_fetch_data_callback_wrapper}, CF_CALLBACK_REGISTRATION_END}; + CF_CONNECTION_KEY connectionKey; + 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); + &connectionKey); - if (SUCCEEDED(hr)) - { - connectionMap[syncRootPath] = *connectionKey; - } + winrt::check_hresult(hr); - return hr; + connectionMap[syncRootPath] = connectionKey; } -// disconection sync root -HRESULT SyncRoot::DisconnectSyncRoot(const wchar_t *syncRootPath) +void SyncRoot::DisconnectSyncRoot(const wchar_t *syncRootPath) { auto it = connectionMap.find(syncRootPath); if (it != connectionMap.end()) { HRESULT hr = CfDisconnectSyncRoot(it->second); - if (SUCCEEDED(hr)) - { - connectionMap.erase(it); - } - return hr; + + winrt::check_hresult(hr); + + connectionMap.erase(it); } - return E_FAIL; } diff --git a/native-src/sync_root_interface/callbacks/FetchData/FetchData.cpp b/native-src/sync_root_interface/callbacks/FetchData/FetchData.cpp index 3366060f..3eff8ac9 100644 --- a/native-src/sync_root_interface/callbacks/FetchData/FetchData.cpp +++ b/native-src/sync_root_interface/callbacks/FetchData/FetchData.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include #include #include #include @@ -17,6 +17,7 @@ #include #include #include +#include napi_threadsafe_function g_fetch_data_threadsafe_callback = nullptr; @@ -213,7 +214,8 @@ static napi_value response_callback_fn_fetch_data(napi_env env, napi_callback_in ::Sleep(CHUNKDELAYMS); - CfSetPinState(handleForPath(ctxPtr->fullClientPath.c_str()).get(), CF_PIN_STATE_PINNED, CF_SET_PIN_FLAG_NONE, nullptr); + auto fileHandle = Placeholders::OpenFileHandle(ctxPtr->fullClientPath.c_str(), FILE_WRITE_ATTRIBUTES, true); + CfSetPinState(fileHandle.get(), CF_PIN_STATE_PINNED, CF_SET_PIN_FLAG_NONE, nullptr); } { diff --git a/native-src/virtual_drive/connect_sync_root.cpp b/native-src/virtual_drive/connect_sync_root.cpp index 6346ea39..eb28e02b 100644 --- a/native-src/virtual_drive/connect_sync_root.cpp +++ b/native-src/virtual_drive/connect_sync_root.cpp @@ -1,5 +1,5 @@ #include -#include "SyncRoot.h" +#include napi_value connect_sync_root_impl(napi_env env, napi_callback_info args) { @@ -10,7 +10,7 @@ napi_value connect_sync_root_impl(napi_env env, napi_callback_info args) size_t pathLength; napi_get_value_string_utf16(env, argv[0], nullptr, 0, &pathLength); std::wstring syncRootPath(pathLength, L'\0'); - napi_get_value_string_utf16(env, argv[0], reinterpret_cast(&syncRootPath[0]), pathLength + 1, nullptr); + napi_get_value_string_utf16(env, argv[0], reinterpret_cast(&syncRootPath[0]), pathLength + 1, nullptr); InputSyncCallbacks callbacks = {}; @@ -22,23 +22,7 @@ napi_value connect_sync_root_impl(napi_env env, napi_callback_info args) 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.c_str(), callbacks, env, &connectionKey); + SyncRoot::ConnectSyncRoot(syncRootPath.c_str(), callbacks, env); - 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(hr), &hrValue); - napi_set_named_property(env, resultObj, "hr", hrValue); - - std::wstring connectionKeyString = std::to_wstring(connectionKey.Internal); - napi_create_string_utf16(env, reinterpret_cast(connectionKeyString.c_str()), connectionKeyString.length(), &connectionKeyValue); - napi_set_named_property(env, resultObj, "connectionKey", connectionKeyValue); - - return resultObj; + return nullptr; } diff --git a/native-src/virtual_drive/dehydrate_file.cpp b/native-src/virtual_drive/dehydrate_file.cpp index 857d7803..a6d9ef72 100644 --- a/native-src/virtual_drive/dehydrate_file.cpp +++ b/native-src/virtual_drive/dehydrate_file.cpp @@ -1,6 +1,7 @@ #include #include "napi_extract_args.h" #include "stdafx.h" +#include "Placeholders.h" napi_value dehydrate_file(napi_env env, napi_callback_info info) { @@ -13,7 +14,7 @@ napi_value dehydrate_file(napi_env env, napi_callback_info info) throw std::runtime_error("Cannot dehydrate folder"); } - winrt::handle fileHandle(CreateFileW(path.c_str(), 0, FILE_READ_DATA, nullptr, OPEN_EXISTING, 0, nullptr)); + auto fileHandle = Placeholders::OpenFileHandle(path, FILE_WRITE_ATTRIBUTES, true); LARGE_INTEGER offset; offset.QuadPart = 0; diff --git a/native-src/virtual_drive/disconnect_sync_root.cpp b/native-src/virtual_drive/disconnect_sync_root.cpp index 66872479..fe84245f 100644 --- a/native-src/virtual_drive/disconnect_sync_root.cpp +++ b/native-src/virtual_drive/disconnect_sync_root.cpp @@ -2,10 +2,11 @@ #include "napi_extract_args.h" #include "SyncRoot.h" -napi_value disconnect_sync_root(napi_env env, napi_callback_info info) { +napi_value disconnect_sync_root(napi_env env, napi_callback_info info) +{ auto [syncRootPath] = napi_extract_args(env, info); - HRESULT result = SyncRoot::DisconnectSyncRoot(syncRootPath.c_str()); + SyncRoot::DisconnectSyncRoot(syncRootPath.c_str()); return nullptr; } diff --git a/native-src/virtual_drive/hydrate_file.cpp b/native-src/virtual_drive/hydrate_file.cpp index a5b1b152..8aabc0c0 100644 --- a/native-src/virtual_drive/hydrate_file.cpp +++ b/native-src/virtual_drive/hydrate_file.cpp @@ -1,8 +1,8 @@ #include #include #include -#include "napi_extract_args.h" -#include "SyncRoot.h" +#include +#include struct AsyncWork { @@ -22,7 +22,7 @@ void hydrate_file(const std::wstring &path) throw std::runtime_error("Cannot hydrate folder"); } - winrt::handle fileHandle(CreateFileW(path.c_str(), 0, FILE_READ_DATA, nullptr, OPEN_EXISTING, 0, nullptr)); + auto fileHandle = Placeholders::OpenFileHandle(path, FILE_WRITE_ATTRIBUTES, true); LARGE_INTEGER offset; offset.QuadPart = 0; diff --git a/native-src/virtual_drive/register_sync_root/register_sync_root.cpp b/native-src/virtual_drive/register_sync_root/register_sync_root.cpp index be1eabe0..a835b3d0 100644 --- a/native-src/virtual_drive/register_sync_root/register_sync_root.cpp +++ b/native-src/virtual_drive/register_sync_root/register_sync_root.cpp @@ -2,7 +2,6 @@ #include "SyncRoot.h" #include "stdafx.h" #include -#include "Logger.h" #include #include