CF API CF_SYNC_STATUS field in CF_OPERATION_INFO structure

273 Views Asked by At

In the Microsoft documentation CF_OPERATION_INFO structure it is very briefly written that

The current sync status of the platform.

The platform queries this information upon any failed operations on a cloud file placeholder. If a structure is available, the platform will use the information provided to construct a more meaningful and actionable message to the user. The platform will keep this information on the file until the last handle on it goes away. If null, the platform will clear the previously set sync status, if there is one.

In other place of Microsoft CfReportSyncStatus function it is written that

Once a sync status is located, the platform will use the information provided to construct a more meaningful and actionable message to the user.

I spent a lot of time trying to get this "a more meaningful and actionable message" from the system but without success.

In CloudMirror example I do the following. Commented try part and leave only catch part, thus I believe that I am simulating a transmission error.


    void FileCopierWithProgress::CopyFromServerToClient(
        _In_ CONST CF_CALLBACK_INFO* lpCallbackInfo,
        _In_ CONST CF_CALLBACK_PARAMETERS* lpCallbackParameters,
        _In_ LPCWSTR serverFolder)
    {
        //try
        //{
        //    CopyFromServerToClientWorker(
        //        lpCallbackInfo,
        //        lpCallbackInfo->ProcessInfo,
        //        lpCallbackParameters->FetchData.RequiredFileOffset,
        //        lpCallbackParameters->FetchData.RequiredLength,
        //        lpCallbackParameters->FetchData.OptionalFileOffset,
        //        lpCallbackParameters->FetchData.OptionalLength,
        //        lpCallbackParameters->FetchData.Flags,
        //        lpCallbackInfo->PriorityHint,
        //        serverFolder);
        //}
        //catch (...)
        {
            TransferData(
                lpCallbackInfo->ConnectionKey,
                lpCallbackInfo->TransferKey,
                NULL,
                lpCallbackParameters->FetchData.RequiredFileOffset,
                lpCallbackParameters->FetchData.RequiredLength,
                STATUS_UNSUCCESSFUL);
        }
    }

In the TransferData function I created the CF_SYNC_STATUS structure and put its address in the field opInfo.SyncStatus, after that, CfExecute is called.


    LPVOID syncStatus()
    {
        std::wstring message(L"It is message to sync status");
        int lmessage = sizeof(message) + 2 +16;
        // round to 16
        int extra = lmessage % 16;
        lmessage -= extra;
    
        CF_SYNC_STATUS* ss = new CF_SYNC_STATUS{ 0 };
        ss->StructSize = sizeof(CF_SYNC_STATUS) + lmessage;
        ss->Code = 123;
        ss->DescriptionLength = lmessage;
        ss->DescriptionOffset = sizeof(CF_SYNC_STATUS);
        int size = sizeof(CF_SYNC_STATUS) + 16;
        BYTE* buffer = (BYTE*)malloc(size);
        memset(buffer, 0, size);
        memcpy(buffer, ss, ss->StructSize);
        wcscpy((wchar_t*)(buffer + sizeof(CF_SYNC_STATUS)), message.c_str());
        return buffer;
    }
    
    void FileCopierWithProgress::TransferData(
        _In_ CF_CONNECTION_KEY connectionKey,
        _In_ LARGE_INTEGER transferKey,
        _In_reads_bytes_opt_(length.QuadPart) LPCVOID transferData,
        _In_ LARGE_INTEGER startingOffset,
        _In_ LARGE_INTEGER length,
        _In_ NTSTATUS completionStatus)
    {
        CF_OPERATION_INFO opInfo = { 0 };
        CF_OPERATION_PARAMETERS opParams = { 0 };
    
        opInfo.StructSize = sizeof(opInfo);
        opInfo.Type = CF_OPERATION_TYPE_TRANSFER_DATA;
        opInfo.ConnectionKey = connectionKey;
        opInfo.TransferKey = transferKey;
    
        opInfo.SyncStatus = (CF_SYNC_STATUS*)syncStatus();
    
        opParams.ParamSize = CF_SIZE_OF_OP_PARAM(TransferData);
        opParams.TransferData.CompletionStatus = completionStatus;
        opParams.TransferData.Buffer = transferData;
        opParams.TransferData.Offset = startingOffset;
        opParams.TransferData.Length = length;
    
        winrt::check_hresult(CfExecute(&opInfo, &opParams));
    }

I do not see any difference between the case when the opInfo.SyncStatus field contains NULL and when it contains the address of the structure.

Does anyone know how to properly use this feature?

Thanks.

0

There are 0 best solutions below