diff --git a/include/sync_root_interface/Utilities.h b/include/sync_root_interface/Utilities.h index 8164fdf2..3effcb19 100644 --- a/include/sync_root_interface/Utilities.h +++ b/include/sync_root_interface/Utilities.h @@ -12,6 +12,7 @@ class Utilities static std::wstring FileOperationErrorToWString(_In_ FileOperationError error); static bool IsTemporaryFile(const std::wstring &fullPath); static std::wstring GetErrorMessageCloudFiles(HRESULT hr); + static void ClearTransferProperties(_In_ LPCWSTR fullPath); static winrt::com_array ConvertSidToStringSid(_In_ PSID sid) diff --git a/native-src/sync_root_interface/Utilities.cpp b/native-src/sync_root_interface/Utilities.cpp index 1f1e9ada..35b824bd 100644 --- a/native-src/sync_root_interface/Utilities.cpp +++ b/native-src/sync_root_interface/Utilities.cpp @@ -88,6 +88,26 @@ void Utilities::AddFolderToSearchIndexer(_In_ PCWSTR folder) } } +void Utilities::ClearTransferProperties(PCWSTR fullPath) +{ + winrt::com_ptr item; + winrt::com_ptrstore; + + if (FAILED(SHCreateItemFromParsingName(fullPath, nullptr, + __uuidof(item), item.put_void()))) + return; + + if (FAILED(item->GetPropertyStore(GPS_READWRITE | GPS_VOLATILEPROPERTIESONLY, + __uuidof(store), store.put_void()))) + return; + + PROPVARIANT empty; PropVariantInit(&empty); + store->SetValue(PKEY_StorageProviderTransferProgress, empty); + store->SetValue(PKEY_SyncTransferStatus, empty); + store->Commit(); +} + + void Utilities::ApplyTransferStateToFile(_In_ PCWSTR fullPath, _In_ CF_CALLBACK_INFO &callbackInfo, UINT64 total, UINT64 completed) { Logger::getInstance().log("ApplyTransferStateToFile", LogLevel::INFO); @@ -116,10 +136,10 @@ void Utilities::ApplyTransferStateToFile(_In_ PCWSTR fullPath, _In_ CF_CALLBACK_ { // First, get the Volatile property store for the file. That's where the properties are maintained. winrt::com_ptr shellItem; + winrt::com_ptrpropStoreVolatile; + winrt::check_hresult(SHCreateItemFromParsingName(fullPath, nullptr, __uuidof(shellItem), shellItem.put_void())); - // wprintf(L"transfer-> fullPath \"%s\"\n", fullPath); - // wprintf(L"transfer-> shellItem \"%s\"\n", shellItem); - winrt::com_ptr propStoreVolatile; + // wprintf(L"transfer-> propStoreVolatile \"%s\"\n", propStoreVolatile); winrt::check_hresult( shellItem->GetPropertyStore( @@ -130,27 +150,39 @@ void Utilities::ApplyTransferStateToFile(_In_ PCWSTR fullPath, _In_ CF_CALLBACK_ // The PKEY_StorageProviderTransferProgress property works with a UINT64 array that is two elements, with // element 0 being the amount of data transferred, and element 1 being the total amount // that will be transferred. - PROPVARIANT transferProgress; - UINT64 values[]{completed, total}; - winrt::check_hresult(InitPropVariantFromUInt64Vector(values, ARRAYSIZE(values), &transferProgress)); // TODO: should work, but doesn't the library doesn't have this function implemented - winrt::check_hresult(propStoreVolatile->SetValue(PKEY_StorageProviderTransferProgress, transferProgress)); - // wprintf(L"transfer-> transferProgress \"%s\"\n", transferProgress); - // Set the sync transfer status accordingly - - PROPVARIANT transferStatus; - winrt::check_hresult( - InitPropVariantFromUInt32( - (completed < total) ? SYNC_TRANSFER_STATUS::STS_TRANSFERRING : SYNC_TRANSFER_STATUS::STS_NONE, - &transferStatus)); - winrt::check_hresult(propStoreVolatile->SetValue(PKEY_SyncTransferStatus, transferStatus)); - // wprintf(L"transfer-> transferStatus \"%s\"\n", transferStatus); - // Without this, all your hard work is wasted. - winrt::check_hresult(propStoreVolatile->Commit()); - // wprintf(L"transfer-> propStoreVolatile \"%s\"\n", propStoreVolatile); - // Broadcast a notification that something about the file has changed, so that apps - // who subscribe (such as File Explorer) can update their UI to reflect the new progress - SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, static_cast(fullPath), nullptr); - wprintf(L"Succesfully Set Transfer Progress on \"%s\" to %llu/%llu\n", fullPath, completed, total); + if (completed < total) + { + PROPVARIANT pvProgress, pvStatus; + UINT64 values[] { completed, total }; + InitPropVariantFromUInt64Vector(values, ARRAYSIZE(values), &pvProgress); + InitPropVariantFromUInt32(SYNC_TRANSFER_STATUS::STS_TRANSFERRING, &pvStatus); + + propStoreVolatile->SetValue(PKEY_StorageProviderTransferProgress, pvProgress); + propStoreVolatile->SetValue(PKEY_SyncTransferStatus, pvStatus); + propStoreVolatile->Commit(); + + PropVariantClear(&pvProgress); + } + else + { + PROPVARIANT empty; PropVariantInit(&empty); + propStoreVolatile->SetValue(PKEY_StorageProviderTransferProgress, empty); + propStoreVolatile->SetValue(PKEY_SyncTransferStatus, empty); + propStoreVolatile->Commit(); + + HANDLE h = CreateFileW(fullPath, + FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT, + nullptr); + if (h != INVALID_HANDLE_VALUE) { + CfSetInSyncState(h, CF_IN_SYNC_STATE_IN_SYNC, + CF_SET_IN_SYNC_FLAG_NONE, nullptr); + CloseHandle(h); + } + } } catch (...) { diff --git a/package.json b/package.json index eaf05714..a13024fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@internxt/node-win", - "version": "1.0.10", + "version": "1.0.11", "description": "Drive desktop node addon", "main": "dist/index.ts", "types": "dist/index.d.ts",