Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/sonar-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
types: [opened, synchronize, reopened]
push:
branches:
- main
- master

jobs:
sonar_analysis:
Expand Down
Binary file modified dist/addon.node
Binary file not shown.
4 changes: 2 additions & 2 deletions include/napi_helpers/napi_extract_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ template<>
inline std::wstring napi_extract_value<std::wstring>(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<char16_t*>(result.data()), length + 1, &actualLength);
result.resize(actualLength);

return result;
}

Expand Down
30 changes: 12 additions & 18 deletions include/placeholders_interface/Placeholders.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
15 changes: 9 additions & 6 deletions include/sync_root_interface/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
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 was done in a function in javascript:

  private convertToWindowsTime(jsTime: number) {
    return BigInt(jsTime) * 10000n + 116444736000000000n;
  }

However, now we move all conversations from the date number in javascript to C++.

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<DWORD>(windowsTime & 0xFFFFFFFF);
largeInteger.HighPart = static_cast<DWORD>((windowsTime >> 32) & 0xFFFFFFFF);

return largeInteger;
}

Expand Down
73 changes: 33 additions & 40 deletions native-src/placeholders_interface/Planceholders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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""};

Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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""};

Expand All @@ -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
Expand All @@ -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
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 just removed the if as the TODO says. This was just used only for folders.

// 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 (...)
{
Expand Down
94 changes: 11 additions & 83 deletions native-src/virtual_drive/create_file_placeholder.cpp
Original file line number Diff line number Diff line change
@@ -1,93 +1,25 @@
#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.

Here we just replace all parse values with the new template napi_extract_args and convert the datetime values to a windows format (LARGE_INTEGER).

#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<std::wstring, std::wstring, int64_t, int64_t, int64_t, int64_t, std::wstring>(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<char16_t *>(const_cast<wchar_t *>(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<char16_t *>(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<wchar_t> creationTimeStringBuffer(creationTimeStringLength + 1);
napi_get_value_string_utf16(env, argv[4], reinterpret_cast<char16_t *>(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<DWORD>(windowsTimeValue & 0xFFFFFFFF);
creationTime.dwHighDateTime = static_cast<DWORD>((windowsTimeValue >> 32) & 0xFFFFFFFF);

size_t lastWriteTimeStringLength;
napi_get_value_string_utf16(env, argv[5], nullptr, 0, &lastWriteTimeStringLength);
std::vector<wchar_t> lastWriteTimeStringBuffer(lastWriteTimeStringLength + 1);
napi_get_value_string_utf16(env, argv[5], reinterpret_cast<char16_t *>(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<DWORD>(windowsTimeValue2 & 0xFFFFFFFF);
lastWriteTime.dwHighDateTime = static_cast<DWORD>((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<char16_t *>(const_cast<wchar_t *>(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;
Expand All @@ -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;
}
Loading
Loading