I have following code structure:
winrt::Windows::Foundation::IAsyncOperationWithProgress<Transfer::TransferStatus, Transfer::TransferProgress> Windows::
TransferClient::TransferAsync(winrt::Windows::Foundation::Collections::IVector<hstring> filesToSend)
{
co_await winrt::resume_background();
auto f_taskProgress{ co_await winrt::get_progress_token() };
f_taskProgress.set_result(m_progress.Status);
m_progress.FilesSentSuccessfully = 0;
try
{
uint32_t listSize = filesToSend.Size();
m_progress.TotalFilesToSend = listSize;
for (uint32_t i = 0; i < listSize; i++)
{
hstring file = filesToSend.GetAt(i);
std::wstring str(file.c_str());
m_progress.FileName = file;
hFile = CreateFileW(str.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
gle = GetLastError();
hr = THR(HRESULT_FROM_WIN32(gle));
}
else
{
BOOL b = GetFileSizeEx(hFile, &li);
if (!b)
{
gle = GetLastError();
hr = THR(HRESULT_FROM_WIN32(gle));
}
else
{
if (0 != li.HighPart)
{
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
}
else
{
m_progress.Status = TransferStatus::InProgress;
f_taskProgress.set_result(m_progress.Status);
_cbSize = li.LowPart;
WCHAR _szFilename[MAX_PATH];
StringCchCopy(_szFilename, ARRAYSIZE(_szFilename), file.c_str());
hr = THR(session.PutObject(
_szFilename, NULL, hFile, _cbSize, &s_StatusCallback /*s_StatusCallback*/, this));
}
}
CloseHandle(hFile);
hFile = NULL;
}
if (FAILED(hr))
{
break;
}
else
{
m_progress.FilesSentSuccessfully += 1;
}
}
f_taskProgress(m_progress);
m_progress.Status = TransferStatus::Completed;
f_taskProgress.set_result(m_progress.Status);
}
}
co_return m_progress.Status;
}
catch (...)
{
std::wcout << winrt::to_message().c_str() << std::endl;
co_return TransferStatus::Unknown;
}
}
HRESULT
TransferClient::s_StatusCallback(LPVOID pvIn, ULONG cbTransmittedIn)
{
TransferClient* pthis = (TransferClient*)pvIn;
return pthis->StatusCallback(cbTransmittedIn);
}
HRESULT
TransferClient::StatusCallback(ULONG cbTransmittedIn)
{
m_progress.BytesSent = cbTransmittedIn;
// Not able to access f_taskProgress
// since it is a local variable to the above async function
f_taskProgress(m_progress);
HRETURN(S_OK);
}
The problem is function PutObject takes a C style callback function pointer. It calls this callback when some bytes are transferred and I want that progress to update in UI. So I created a static function on the class and pass that. But now, I cannot access my progress token inside this callback even when I have this pointer. I cannot store it on class since its type is auto. I tried with local struct within TransferAsync and static method but it will not be a C-style function pointer that PutObject is expecting. PutObject is not mine so cannot modify it.
So, how do I update the progress from the callback?