Skip to content

Commit 716b2ff

Browse files
Remove mantain identity (#204)
1 parent 0475ba4 commit 716b2ff

14 files changed

Lines changed: 136 additions & 287 deletions

File tree

dist/addon.node

-4.5 KB
Binary file not shown.

include/placeholders_interface/Placeholders.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
class Placeholders
77
{
88
public:
9-
static void MaintainIdentity(const std::wstring &fullPath, PCWSTR fileIdentity, bool isDirectory);
10-
static void UpdateSyncStatus(const std::wstring &filePath, bool isDirectory);
11-
static void UpdateFileIdentity(const std::wstring &filePath, const std::wstring &fileIdentity, bool isDirectory);
12-
static FileState GetPlaceholderInfo(const std::wstring &directoryPath);
9+
static winrt::file_handle OpenFileHandle(const std::wstring &path, DWORD accessRights, bool openAsPlaceholder);
10+
static void UpdateSyncStatus(const std::wstring &path);
11+
static void UpdateFileIdentity(const std::wstring &path, const std::wstring &placeholderId);
12+
static FileState GetPlaceholderInfo(const std::wstring &path);
1313
};

include/sync_root_interface/SyncRoot.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,11 @@
66
#include <iostream>
77
#include <vector>
88

9-
struct ItemInfo
10-
{
11-
std::wstring path;
12-
std::wstring fileIdentity;
13-
bool isPlaceholder;
14-
};
15-
169
class SyncRoot
1710
{
1811
public:
1912
static HRESULT ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env, CF_CONNECTION_KEY *connectionKey);
2013
static HRESULT DisconnectSyncRoot(const wchar_t *syncRootPath);
21-
static void HydrateFile(const wchar_t *filePath);
2214

2315
private:
2416
CF_CONNECTION_KEY connectionKey;

include/sync_root_interface/Utilities.h

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ class Utilities
44
{
55
public:
66
static void ApplyTransferStateToFile(_In_ LPCWSTR fullPath, _In_ CF_CALLBACK_INFO &callbackInfo, UINT64 total, UINT64 completed);
7-
static std::wstring GetErrorMessageCloudFiles(HRESULT hr);
87

98
static winrt::com_array<wchar_t>
109
ConvertSidToStringSid(_In_ PSID sid)
@@ -20,16 +19,17 @@ class Utilities
2019
}
2120
};
2221

23-
inline static LARGE_INTEGER JsTimestampToLargeInteger(int64_t jsTimestamp) {
22+
inline static LARGE_INTEGER JsTimestampToLargeInteger(int64_t jsTimestamp)
23+
{
2424
const int64_t EPOCH_DIFFERENCE = 11644473600000LL;
2525
const int64_t MS_TO_100NS = 10000LL;
26-
26+
2727
int64_t windowsTime = (jsTimestamp + EPOCH_DIFFERENCE) * MS_TO_100NS;
28-
28+
2929
LARGE_INTEGER largeInteger;
3030
largeInteger.LowPart = static_cast<DWORD>(windowsTime & 0xFFFFFFFF);
3131
largeInteger.HighPart = static_cast<DWORD>((windowsTime >> 32) & 0xFFFFFFFF);
32-
32+
3333
return largeInteger;
3434
}
3535

@@ -39,18 +39,4 @@ class Utilities
3939
largeInteger.QuadPart = longlong;
4040
return largeInteger;
4141
}
42-
43-
static DWORD convertSizeToDWORD(size_t &convertVar)
44-
{
45-
if (convertVar > UINT_MAX)
46-
{
47-
convertVar = UINT_MAX;
48-
}
49-
return static_cast<DWORD>(convertVar);
50-
}
51-
52-
static DWORD sizeToDWORD(size_t size)
53-
{
54-
return convertSizeToDWORD(size);
55-
}
5642
};

native-src/placeholders_interface/Planceholders.cpp

Lines changed: 38 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -17,71 +17,41 @@
1717
#include <shlobj.h>
1818
#include "convert_to_placeholder.h"
1919

20-
using namespace std;
21-
22-
namespace fs = std::filesystem;
23-
2420
#pragma comment(lib, "shlwapi.lib")
2521

26-
std::string cleanString(const std::string &str)
22+
winrt::file_handle Placeholders::OpenFileHandle(const std::wstring &path, DWORD dwDesiredAccess, bool openAsPlaceholder)
2723
{
28-
std::string cleanedStr;
29-
for (char ch : str)
30-
{
31-
if (std::isprint(static_cast<unsigned char>(ch)))
32-
{
33-
cleanedStr.push_back(ch);
34-
}
35-
}
36-
return cleanedStr;
37-
}
38-
39-
void Placeholders::MaintainIdentity(const std::wstring &fullPath, PCWSTR itemIdentity, bool isDirectory)
40-
{
41-
std::string identity = Placeholders::GetPlaceholderInfo(fullPath).placeholderId;
42-
if (!identity.empty())
43-
{
44-
int len = WideCharToMultiByte(CP_UTF8, 0, itemIdentity, -1, NULL, 0, NULL, NULL);
45-
if (len > 0)
46-
{
47-
std::string itemIdentityStr(len, 0);
48-
WideCharToMultiByte(CP_UTF8, 0, itemIdentity, -1, &itemIdentityStr[0], len, NULL, NULL);
49-
std::string cleanIdentity = cleanString(identity);
50-
std::string cleanItemIdentity = cleanString(itemIdentityStr);
51-
if (cleanIdentity != cleanItemIdentity)
52-
{
53-
wprintf(L"[MaintainIdentity] Identity is incorrect, updating...\n");
54-
std::wstring itemIdentityStrW(itemIdentity);
55-
Placeholders::UpdateFileIdentity(fullPath, itemIdentityStrW, isDirectory);
56-
}
57-
}
58-
else
59-
{
60-
// Handle error as needed
61-
}
62-
}
63-
}
24+
bool isDirectory = std::filesystem::is_directory(path);
6425

65-
void Placeholders::UpdateSyncStatus(const std::wstring &path, bool isDirectory)
66-
{
67-
DWORD flags = FILE_FLAG_OPEN_REPARSE_POINT;
26+
DWORD dwFlagsAndAttributes = 0;
27+
if (openAsPlaceholder)
28+
dwFlagsAndAttributes |= FILE_FLAG_OPEN_REPARSE_POINT;
6829
if (isDirectory)
69-
flags |= FILE_FLAG_BACKUP_SEMANTICS;
30+
dwFlagsAndAttributes |= FILE_FLAG_BACKUP_SEMANTICS;
31+
32+
DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
7033

7134
winrt::file_handle fileHandle{CreateFileW(
7235
path.c_str(),
73-
FILE_WRITE_ATTRIBUTES,
74-
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
36+
dwDesiredAccess,
37+
dwShareMode,
7538
nullptr,
7639
OPEN_EXISTING,
77-
flags,
40+
dwFlagsAndAttributes,
7841
nullptr)};
7942

8043
if (!fileHandle)
8144
{
82-
throw std::runtime_error("Failed to open item: " + std::to_string(GetLastError()));
45+
throw std::runtime_error("Failed to open file handle: " + std::to_string(GetLastError()));
8346
}
8447

48+
return fileHandle;
49+
}
50+
51+
void Placeholders::UpdateSyncStatus(const std::wstring &path)
52+
{
53+
auto fileHandle = Placeholders::OpenFileHandle(path, FILE_WRITE_ATTRIBUTES, true);
54+
8555
winrt::check_hresult(CfSetInSyncState(
8656
fileHandle.get(),
8757
CF_IN_SYNC_STATE_IN_SYNC,
@@ -91,82 +61,42 @@ void Placeholders::UpdateSyncStatus(const std::wstring &path, bool isDirectory)
9161
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, path.c_str(), nullptr);
9262
}
9363

94-
void Placeholders::UpdateFileIdentity(const std::wstring &filePath, const std::wstring &fileIdentity, bool isDirectory)
64+
void Placeholders::UpdateFileIdentity(const std::wstring &path, const std::wstring &placeholderId)
9565
{
96-
HANDLE fileHandle = CreateFileW(
97-
filePath.c_str(),
98-
FILE_WRITE_ATTRIBUTES, // permisson needed to change the state
99-
FILE_SHARE_READ | FILE_SHARE_WRITE,
100-
nullptr,
101-
OPEN_EXISTING,
102-
isDirectory ? FILE_FLAG_BACKUP_SEMANTICS : FILE_ATTRIBUTE_NORMAL,
103-
nullptr);
66+
auto fileHandle = OpenFileHandle(path, FILE_WRITE_ATTRIBUTES, true);
10467

105-
if (fileHandle == INVALID_HANDLE_VALUE)
106-
{
107-
DWORD errorCode = GetLastError();
108-
wprintf(L"[UpdateFileIdentity] Error opening file: %d\n", errorCode);
109-
LPWSTR errorMessage = nullptr;
110-
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
111-
nullptr,
112-
errorCode,
113-
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
114-
reinterpret_cast<LPWSTR>(&errorMessage),
115-
0,
116-
nullptr);
117-
if (errorMessage)
118-
{
119-
wprintf(L"[UpdateFileIdentity] Error: %ls\n", errorMessage);
120-
LocalFree(errorMessage);
121-
}
122-
return;
123-
}
124-
125-
HRESULT hr = CfUpdatePlaceholder(
126-
fileHandle, // Handle del archivo.
127-
nullptr, // CF_FS_METADATA opcional.
128-
fileIdentity.c_str(), // Identidad del archivo.
129-
static_cast<DWORD>(fileIdentity.size() * sizeof(wchar_t)), // Longitud de la identidad del archivo.
130-
nullptr, // Rango a deshidratar, opcional.
131-
0, // Conteo de rangos a deshidratar, debe ser 0 si no se usa.
132-
CF_UPDATE_FLAG_NONE, // Flags de actualización.
133-
nullptr, // USN opcional.
134-
nullptr // OVERLAPPED opcional.
135-
);
136-
137-
if (FAILED(hr))
138-
{
139-
std::wstring errorMessage = Utilities::GetErrorMessageCloudFiles(hr);
140-
wprintf(L"[UpdateFileIdentity] Error updating fileIdentity: %ls\n", errorMessage.c_str());
141-
CloseHandle(fileHandle);
142-
return;
143-
}
144-
145-
CloseHandle(fileHandle);
68+
winrt::check_hresult(CfUpdatePlaceholder(
69+
fileHandle.get(),
70+
nullptr,
71+
placeholderId.c_str(),
72+
static_cast<DWORD>(placeholderId.size() * sizeof(wchar_t)),
73+
nullptr,
74+
0,
75+
CF_UPDATE_FLAG_NONE,
76+
nullptr,
77+
nullptr));
14678
}
14779

14880
FileState Placeholders::GetPlaceholderInfo(const std::wstring &path)
14981
{
82+
auto fileHandle = OpenFileHandle(path, FILE_READ_ATTRIBUTES, true);
83+
15084
constexpr DWORD fileIdMaxLength = 400;
15185
constexpr DWORD infoSize = sizeof(CF_PLACEHOLDER_BASIC_INFO) + fileIdMaxLength;
15286

15387
std::vector<char> buffer(infoSize);
15488
auto *info = reinterpret_cast<CF_PLACEHOLDER_BASIC_INFO *>(buffer.data());
15589

156-
auto fileHandle = handleForPath(path);
157-
if (!fileHandle)
158-
{
159-
throw std::runtime_error("Failed to get file handle: " + std::to_string(GetLastError()));
160-
}
161-
16290
winrt::check_hresult(CfGetPlaceholderInfo(
16391
fileHandle.get(),
16492
CF_PLACEHOLDER_INFO_BASIC,
16593
info,
16694
infoSize,
16795
nullptr));
16896

169-
return FileState{
170-
std::string(reinterpret_cast<const char *>(info->FileIdentity), info->FileIdentityLength),
171-
info->PinState};
97+
std::string placeholderId(reinterpret_cast<const char *>(info->FileIdentity), info->FileIdentityLength);
98+
99+
placeholderId.erase(std::remove(placeholderId.begin(), placeholderId.end(), '\0'), placeholderId.end());
100+
101+
return FileState{placeholderId, info->PinState};
172102
}

native-src/sync_root_interface/SyncRoot.cpp

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,6 @@
88

99
std::map<std::wstring, CF_CONNECTION_KEY> connectionMap;
1010

11-
void SyncRoot::HydrateFile(const wchar_t *filePath)
12-
{
13-
wprintf(L"Hydration file started %ls\n", filePath);
14-
DWORD attrib = GetFileAttributesW(filePath);
15-
if (!(attrib & FILE_ATTRIBUTE_DIRECTORY))
16-
{
17-
winrt::handle placeholder(CreateFileW(filePath, 0, FILE_READ_DATA, nullptr, OPEN_EXISTING, 0, nullptr));
18-
19-
LARGE_INTEGER offset;
20-
offset.QuadPart = 0;
21-
LARGE_INTEGER length;
22-
GetFileSizeEx(placeholder.get(), &length);
23-
24-
if (attrib & FILE_ATTRIBUTE_PINNED)
25-
{
26-
// if (!(attrib & FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS))
27-
// {
28-
Logger::getInstance().log("Hydration file init", LogLevel::INFO);
29-
30-
auto start = std::chrono::steady_clock::now();
31-
32-
HRESULT hr = CfHydratePlaceholder(placeholder.get(), offset, length, CF_HYDRATE_FLAG_NONE, NULL);
33-
34-
if (FAILED(hr))
35-
{
36-
Logger::getInstance().log("Error hydrating file " + Logger::fromWStringToString(filePath), LogLevel::ERROR);
37-
}
38-
else
39-
{
40-
auto end = std::chrono::steady_clock::now();
41-
auto elapsedMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
42-
43-
if (elapsedMilliseconds < 200)
44-
{
45-
wprintf(L"Already Hydrated: %d ms\n", elapsedMilliseconds);
46-
}
47-
else
48-
{
49-
wprintf(L"Hydration finished %ls\n", filePath);
50-
}
51-
}
52-
}
53-
}
54-
}
55-
5611
HRESULT SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env, CF_CONNECTION_KEY *connectionKey)
5712
{
5813
register_threadsafe_fetch_data_callback("FetchDataThreadSafe", env, syncCallbacks);
@@ -61,23 +16,22 @@ HRESULT SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallback
6116
CF_CALLBACK_REGISTRATION callbackTable[] = {
6217
{CF_CALLBACK_TYPE_FETCH_DATA, fetch_data_callback_wrapper},
6318
{CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, cancel_fetch_data_callback_wrapper},
64-
CF_CALLBACK_REGISTRATION_END
65-
};
19+
CF_CALLBACK_REGISTRATION_END};
6620

6721
HRESULT hr = CfConnectSyncRoot(
6822
syncRootPath,
6923
callbackTable,
7024
nullptr,
7125
CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH,
72-
connectionKey
73-
);
26+
connectionKey);
7427

7528
wprintf(L"Connection key: %llu\n", connectionKey->Internal);
76-
77-
if (SUCCEEDED(hr)) {
29+
30+
if (SUCCEEDED(hr))
31+
{
7832
connectionMap[syncRootPath] = *connectionKey;
7933
}
80-
34+
8135
return hr;
8236
}
8337

0 commit comments

Comments
 (0)