diff --git a/.github/workflows/sonar-analysis.yml b/.github/workflows/sonar-analysis.yml index 3b797e49..a5b7693d 100644 --- a/.github/workflows/sonar-analysis.yml +++ b/.github/workflows/sonar-analysis.yml @@ -5,7 +5,7 @@ on: types: [opened, synchronize, reopened] push: branches: - - main + - master jobs: sonar_analysis: diff --git a/dist/addon.node b/dist/addon.node index 73e6ed78..dfb9d07e 100644 Binary files a/dist/addon.node and b/dist/addon.node differ diff --git a/include/napi_helpers/napi_extract_args.h b/include/napi_helpers/napi_extract_args.h index a64568a7..027a519c 100644 --- a/include/napi_helpers/napi_extract_args.h +++ b/include/napi_helpers/napi_extract_args.h @@ -11,12 +11,12 @@ template<> inline std::wstring napi_extract_value(napi_env env, napi_value value) { size_t length; napi_get_value_string_utf16(env, value, nullptr, 0, &length); - + std::wstring result(length + 1, L'\0'); size_t actualLength; napi_get_value_string_utf16(env, value, reinterpret_cast(result.data()), length + 1, &actualLength); result.resize(actualLength); - + return result; } diff --git a/include/placeholders_interface/Placeholders.h b/include/placeholders_interface/Placeholders.h index f6fb2aa8..66aaddb6 100644 --- a/include/placeholders_interface/Placeholders.h +++ b/include/placeholders_interface/Placeholders.h @@ -12,29 +12,23 @@ class Placeholders { public: static PlaceholderResult CreateOne( - _In_ PCWSTR fileName, - _In_ PCWSTR fileIdentity, + const wchar_t *fileName, + const wchar_t *fileIdentity, int64_t fileSize, - DWORD fileIdentityLength, - uint32_t fileAttributes, - FILETIME creationTime, - FILETIME lastWriteTime, - FILETIME lastAccessTime, - _In_ PCWSTR destPath); + LARGE_INTEGER creationTime, + LARGE_INTEGER lastWriteTime, + LARGE_INTEGER lastAccessTime, + const wchar_t *destPath); static void MaintainIdentity(std::wstring &fullPath, PCWSTR fileIdentity, bool isDirectory); static PlaceholderResult CreateEntry( - _In_ PCWSTR itemName, - _In_ PCWSTR itemIdentity, - bool isDirectory, - uint32_t itemSize, - DWORD itemIdentityLength, - uint32_t itemAttributes, - FILETIME creationTime, - FILETIME lastWriteTime, - FILETIME lastAccessTime, - _In_ PCWSTR destPath); + const wchar_t *itemName, + const wchar_t *itemIdentity, + LARGE_INTEGER creationTime, + LARGE_INTEGER lastWriteTime, + LARGE_INTEGER lastAccessTime, + const wchar_t *destPath); static void ForceShellRefresh(const std::wstring &path); static void UpdateSyncStatus(const std::wstring &filePath, bool syncState, bool isDirectory); diff --git a/include/sync_root_interface/Utilities.h b/include/sync_root_interface/Utilities.h index b2498e6d..b4e5faeb 100644 --- a/include/sync_root_interface/Utilities.h +++ b/include/sync_root_interface/Utilities.h @@ -21,13 +21,16 @@ class Utilities } }; - inline static LARGE_INTEGER FileTimeToLargeInteger(_In_ const FILETIME fileTime) - { + inline static LARGE_INTEGER JsTimestampToLargeInteger(int64_t jsTimestamp) { + const int64_t EPOCH_DIFFERENCE = 11644473600000LL; + const int64_t MS_TO_100NS = 10000LL; + + int64_t windowsTime = (jsTimestamp + EPOCH_DIFFERENCE) * MS_TO_100NS; + LARGE_INTEGER largeInteger; - - largeInteger.LowPart = fileTime.dwLowDateTime; - largeInteger.HighPart = fileTime.dwHighDateTime; - + largeInteger.LowPart = static_cast(windowsTime & 0xFFFFFFFF); + largeInteger.HighPart = static_cast((windowsTime >> 32) & 0xFFFFFFFF); + return largeInteger; } diff --git a/native-src/placeholders_interface/Planceholders.cpp b/native-src/placeholders_interface/Planceholders.cpp index 95048fdd..8c75966b 100644 --- a/native-src/placeholders_interface/Planceholders.cpp +++ b/native-src/placeholders_interface/Planceholders.cpp @@ -29,15 +29,13 @@ bool DirectoryExists(const wchar_t *path) } PlaceholderResult Placeholders::CreateOne( - _In_ PCWSTR fileName, - _In_ PCWSTR fileIdentity, + const wchar_t *fileName, + const wchar_t *fileIdentity, int64_t fileSize, - DWORD fileIdentityLength, - uint32_t fileAttributes, - FILETIME creationTime, - FILETIME lastWriteTime, - FILETIME lastAccessTime, - _In_ PCWSTR destPath) + LARGE_INTEGER creationTime, + LARGE_INTEGER lastWriteTime, + LARGE_INTEGER lastAccessTime, + const wchar_t *destPath) { PlaceholderResult result = {false, L""}; @@ -67,10 +65,10 @@ PlaceholderResult Placeholders::CreateOne( cloudEntry.FsMetadata.FileSize.QuadPart = fileSize; cloudEntry.FsMetadata.BasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; - cloudEntry.FsMetadata.BasicInfo.CreationTime = Utilities::FileTimeToLargeInteger(creationTime); - cloudEntry.FsMetadata.BasicInfo.LastWriteTime = Utilities::FileTimeToLargeInteger(lastWriteTime); - cloudEntry.FsMetadata.BasicInfo.LastAccessTime = Utilities::FileTimeToLargeInteger(lastAccessTime); - cloudEntry.FsMetadata.BasicInfo.ChangeTime = Utilities::FileTimeToLargeInteger(lastWriteTime); + cloudEntry.FsMetadata.BasicInfo.CreationTime = creationTime; + cloudEntry.FsMetadata.BasicInfo.LastWriteTime = lastWriteTime; + cloudEntry.FsMetadata.BasicInfo.LastAccessTime = lastAccessTime; + cloudEntry.FsMetadata.BasicInfo.ChangeTime = lastWriteTime; try { @@ -139,16 +137,12 @@ void Placeholders::MaintainIdentity(std::wstring &fullPath, PCWSTR itemIdentity, } PlaceholderResult Placeholders::CreateEntry( - _In_ PCWSTR itemName, - _In_ PCWSTR itemIdentity, - bool isDirectory, - uint32_t itemSize, - DWORD itemIdentityLength, - uint32_t itemAttributes, - FILETIME creationTime, - FILETIME lastWriteTime, - FILETIME lastAccessTime, - _In_ PCWSTR destPath) + const wchar_t *itemName, + const wchar_t *itemIdentity, + LARGE_INTEGER creationTime, + LARGE_INTEGER lastWriteTime, + LARGE_INTEGER lastAccessTime, + const wchar_t *destPath) { PlaceholderResult result = {false, L""}; @@ -160,8 +154,10 @@ PlaceholderResult Placeholders::CreateEntry( cloudEntry.RelativeFileName = itemName; cloudEntry.Flags = CF_PLACEHOLDER_CREATE_FLAG_DISABLE_ON_DEMAND_POPULATION; // -> desactive download on demand cloudEntry.FsMetadata.BasicInfo.FileAttributes = FILE_ATTRIBUTE_DIRECTORY; - cloudEntry.FsMetadata.BasicInfo.CreationTime = Utilities::FileTimeToLargeInteger(creationTime); - cloudEntry.FsMetadata.BasicInfo.LastWriteTime = Utilities::FileTimeToLargeInteger(lastWriteTime); + cloudEntry.FsMetadata.BasicInfo.CreationTime = creationTime; + cloudEntry.FsMetadata.BasicInfo.LastWriteTime = lastWriteTime; + cloudEntry.FsMetadata.BasicInfo.LastAccessTime = lastAccessTime; + try { // TODO: si existe o es placeholder return @@ -173,28 +169,25 @@ PlaceholderResult Placeholders::CreateEntry( return result; } - if (isDirectory) // TODO: the function createEntry is used to create only folders (directories), so this if is always true + // wprintf(L"Create directory, full destination path: %ls, fullDestPath.c_str()"); + PathRemoveFileSpecW(&fullDestPath[0]); + HRESULT hr = CfCreatePlaceholders(fullDestPath.c_str(), &cloudEntry, 1, CF_CREATE_FLAG_NONE, NULL); + if (FAILED(hr)) { - // wprintf(L"Create directory, full destination path: %ls, fullDestPath.c_str()"); - PathRemoveFileSpecW(&fullDestPath[0]); - 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; + 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()); + wprintf(L"[CreatePlaceholder] Error while creating %s: %s\n", L"directory", error.message().c_str()); } catch (...) { diff --git a/native-src/virtual_drive/create_file_placeholder.cpp b/native-src/virtual_drive/create_file_placeholder.cpp index 7a18bc85..93cc8f41 100644 --- a/native-src/virtual_drive/create_file_placeholder.cpp +++ b/native-src/virtual_drive/create_file_placeholder.cpp @@ -1,93 +1,25 @@ #include #include "Placeholders.h" +#include "Utilities.h" +#include "napi_extract_args.h" -napi_value create_file_placeholder_impl(napi_env env, napi_callback_info args) +napi_value create_file_placeholder_impl(napi_env env, napi_callback_info info) { - size_t argc = 8; - napi_value argv[8]; + auto [fileName, fileIdentity, fileSize, creationTimeMs, lastWriteTimeMs, lastAccessTimeMs, destPath] = + napi_extract_args(env, info); - napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); - - if (argc < 8) - { - napi_throw_error(env, nullptr, "Insufficient arguments passed to create_file_placeholder_impl"); - return nullptr; - } - - LPCWSTR fileName; - size_t fileNameLength; - napi_get_value_string_utf16(env, argv[0], nullptr, 0, &fileNameLength); - fileName = new WCHAR[fileNameLength + 1]; - napi_get_value_string_utf16(env, argv[0], reinterpret_cast(const_cast(fileName)), fileNameLength + 1, nullptr); - - size_t fileIdentityLength; - napi_get_value_string_utf16(env, argv[1], nullptr, 0, &fileIdentityLength); - wchar_t *fileIdentity = new wchar_t[fileIdentityLength + 1]; - napi_get_value_string_utf16(env, argv[1], reinterpret_cast(fileIdentity), fileIdentityLength + 1, nullptr); - - if (fileIdentityLength > CF_PLACEHOLDER_MAX_FILE_IDENTITY_LENGTH) - { - napi_throw_error(env, nullptr, "File identity is too long"); - return nullptr; - } - - int64_t fileSize; - napi_get_value_int64(env, argv[2], &fileSize); - - uint32_t fileAttributes; - napi_get_value_uint32(env, argv[3], &fileAttributes); - - FILETIME creationTime, lastWriteTime, lastAccessTime; - - size_t creationTimeStringLength; - napi_get_value_string_utf16(env, argv[4], nullptr, 0, &creationTimeStringLength); - std::vector creationTimeStringBuffer(creationTimeStringLength + 1); - napi_get_value_string_utf16(env, argv[4], reinterpret_cast(creationTimeStringBuffer.data()), creationTimeStringLength + 1, nullptr); - - __int64 windowsTimeValue; - if (swscanf_s(creationTimeStringBuffer.data(), L"%lld", &windowsTimeValue) != 1) - { - napi_throw_error(env, nullptr, "No se pudo convertir el valor de Windows Time"); - return nullptr; - } - - creationTime.dwLowDateTime = static_cast(windowsTimeValue & 0xFFFFFFFF); - creationTime.dwHighDateTime = static_cast((windowsTimeValue >> 32) & 0xFFFFFFFF); - - size_t lastWriteTimeStringLength; - napi_get_value_string_utf16(env, argv[5], nullptr, 0, &lastWriteTimeStringLength); - std::vector lastWriteTimeStringBuffer(lastWriteTimeStringLength + 1); - napi_get_value_string_utf16(env, argv[5], reinterpret_cast(lastWriteTimeStringBuffer.data()), lastWriteTimeStringLength + 1, nullptr); - - __int64 windowsTimeValue2; - if (swscanf_s(lastWriteTimeStringBuffer.data(), L"%lld", &windowsTimeValue2) != 1) - { - napi_throw_error(env, nullptr, "No se pudo convertir el valor de Windows Time"); - return nullptr; - } - - lastWriteTime.dwLowDateTime = static_cast(windowsTimeValue2 & 0xFFFFFFFF); - lastWriteTime.dwHighDateTime = static_cast((windowsTimeValue2 >> 32) & 0xFFFFFFFF); - - lastAccessTime.dwLowDateTime = 34567890; - lastAccessTime.dwHighDateTime = 78901234; - - LPCWSTR destPath; - size_t destPathLength; - napi_get_value_string_utf16(env, argv[7], nullptr, 0, &destPathLength); - destPath = new WCHAR[destPathLength + 1]; - napi_get_value_string_utf16(env, argv[7], reinterpret_cast(const_cast(destPath)), destPathLength + 1, nullptr); + LARGE_INTEGER creationTime = Utilities::JsTimestampToLargeInteger(creationTimeMs); + LARGE_INTEGER lastWriteTime = Utilities::JsTimestampToLargeInteger(lastWriteTimeMs); + LARGE_INTEGER lastAccessTime = Utilities::JsTimestampToLargeInteger(lastAccessTimeMs); PlaceholderResult result = Placeholders::CreateOne( - fileName, - fileIdentity, + fileName.c_str(), + fileIdentity.c_str(), fileSize, - fileIdentityLength, - fileAttributes, creationTime, lastWriteTime, lastAccessTime, - destPath); + destPath.c_str()); // Create result object napi_value resultObj; @@ -106,9 +38,5 @@ napi_value create_file_placeholder_impl(napi_env env, napi_callback_info args) napi_set_named_property(env, resultObj, "errorMessage", errorMessageValue); } - delete[] fileName; - delete[] fileIdentity; - delete[] destPath; - return resultObj; } \ No newline at end of file diff --git a/native-src/virtual_drive/create_folder_placeholder.cpp b/native-src/virtual_drive/create_folder_placeholder.cpp index ec6b975f..93ec87e0 100644 --- a/native-src/virtual_drive/create_folder_placeholder.cpp +++ b/native-src/virtual_drive/create_folder_placeholder.cpp @@ -1,94 +1,24 @@ #include #include "Placeholders.h" +#include "Utilities.h" +#include "napi_extract_args.h" -napi_value create_folder_placeholder_impl(napi_env env, napi_callback_info args) +napi_value create_folder_placeholder_impl(napi_env env, napi_callback_info info) { - size_t argc = 9; - napi_value argv[9]; + auto [folderName, folderIdentity, creationTimeMs, lastWriteTimeMs, lastAccessTimeMs, destPath] = + napi_extract_args(env, info); - napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); - - if (argc < 9) - { - napi_throw_error(env, nullptr, "Insufficient arguments passed to create_folder_placeholder_impl"); - return nullptr; - } - - LPCWSTR itemName; - size_t itemNameLength; - napi_get_value_string_utf16(env, argv[0], nullptr, 0, &itemNameLength); - itemName = new WCHAR[itemNameLength + 1]; - napi_get_value_string_utf16(env, argv[0], reinterpret_cast(const_cast(itemName)), itemNameLength + 1, nullptr); - - LPCWSTR itemIdentity; - size_t itemIdentityLength; - napi_get_value_string_utf16(env, argv[1], nullptr, 0, &itemIdentityLength); - itemIdentity = new WCHAR[itemIdentityLength + 1]; - napi_get_value_string_utf16(env, argv[1], reinterpret_cast(const_cast(itemIdentity)), itemIdentityLength + 1, nullptr); - - bool isDirectory; - napi_get_value_bool(env, argv[2], &isDirectory); - - uint32_t itemSize; - napi_get_value_uint32(env, argv[3], &itemSize); - - DWORD itemIdentityLengthDword = static_cast(itemIdentityLength); - - uint32_t itemAttributes; - napi_get_value_uint32(env, argv[4], &itemAttributes); - - FILETIME creationTime, lastWriteTime, lastAccessTime; - - size_t creationTimeStringLengthFolder; - napi_get_value_string_utf16(env, argv[5], nullptr, 0, &creationTimeStringLengthFolder); - std::vector creationTimeStringBufferFolder(creationTimeStringLengthFolder + 1); - napi_get_value_string_utf16(env, argv[5], reinterpret_cast(creationTimeStringBufferFolder.data()), creationTimeStringLengthFolder + 1, nullptr); - - __int64 windowsTimeValue; - if (swscanf_s(creationTimeStringBufferFolder.data(), L"%lld", &windowsTimeValue) != 1) - { - napi_throw_error(env, nullptr, "No se pudo convertir el valor de Windows Time"); - return nullptr; - } - - creationTime.dwLowDateTime = static_cast(windowsTimeValue & 0xFFFFFFFF); - creationTime.dwHighDateTime = static_cast((windowsTimeValue >> 32) & 0xFFFFFFFF); - - size_t lastWriteTimeStringLength; - napi_get_value_string_utf16(env, argv[6], nullptr, 0, &lastWriteTimeStringLength); - std::vector lastWriteTimeStringBuffer(lastWriteTimeStringLength + 1); - napi_get_value_string_utf16(env, argv[6], reinterpret_cast(lastWriteTimeStringBuffer.data()), lastWriteTimeStringLength + 1, nullptr); - - __int64 windowsTimeValue2; - if (swscanf_s(lastWriteTimeStringBuffer.data(), L"%lld", &windowsTimeValue2) != 1) - { - napi_throw_error(env, nullptr, "No se pudo convertir el valor de Windows Time"); - return nullptr; - } - - lastWriteTime.dwLowDateTime = static_cast(windowsTimeValue2 & 0xFFFFFFFF); - lastWriteTime.dwHighDateTime = static_cast((windowsTimeValue2 >> 32) & 0xFFFFFFFF); - - lastAccessTime.dwLowDateTime = 34567890; - lastAccessTime.dwHighDateTime = 34567890; - - LPCWSTR destPath; - size_t destPathLength; - napi_get_value_string_utf16(env, argv[8], nullptr, 0, &destPathLength); - destPath = new WCHAR[destPathLength + 1]; - napi_get_value_string_utf16(env, argv[8], reinterpret_cast(const_cast(destPath)), destPathLength + 1, nullptr); + LARGE_INTEGER creationTime = Utilities::JsTimestampToLargeInteger(creationTimeMs); + LARGE_INTEGER lastWriteTime = Utilities::JsTimestampToLargeInteger(lastWriteTimeMs); + LARGE_INTEGER lastAccessTime = Utilities::JsTimestampToLargeInteger(lastAccessTimeMs); PlaceholderResult result = Placeholders::CreateEntry( - itemName, - itemIdentity, - isDirectory, - itemSize, - itemIdentityLengthDword, - itemAttributes, + folderName.c_str(), + folderIdentity.c_str(), creationTime, lastWriteTime, lastAccessTime, - destPath); + destPath.c_str()); // Create result object napi_value resultObj; @@ -107,9 +37,5 @@ napi_value create_folder_placeholder_impl(napi_env env, napi_callback_info args) napi_set_named_property(env, resultObj, "errorMessage", errorMessageValue); } - delete[] itemName; - delete[] itemIdentity; - delete[] destPath; - return resultObj; } diff --git a/native-src/virtual_drive/dehydrate_file.cpp b/native-src/virtual_drive/dehydrate_file.cpp index 7bfa5967..7453492e 100644 --- a/native-src/virtual_drive/dehydrate_file.cpp +++ b/native-src/virtual_drive/dehydrate_file.cpp @@ -28,11 +28,11 @@ napi_value dehydrate_file(napi_env env, napi_callback_info info) { DWORD err = HRESULT_CODE(hr); if (err == ERROR_SHARING_VIOLATION || err == ERROR_CLOUD_FILE_IN_USE) { - MessageBoxW( - nullptr, - L"Unable to free up space because the file is currently in use.\nPlease close the file and try again.", - L"File in use", - MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL); + // MessageBoxW( + // nullptr, + // L"Unable to free up space because the file is currently in use.\nPlease close the file and try again.", + // L"File in use", + // MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL); } winrt::throw_hresult(hr); diff --git a/package.json b/package.json index 1fe63dbf..a6977be6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@internxt/node-win", - "version": "1.0.23", + "version": "1.0.24", "author": "Internxt ", "description": "Drive desktop node addon", "main": "dist/index.js",