首页 > 解决方案 > CF_OPERATION_INFO 结构中的 CF API CF_SYNC_STATUS 字段

问题描述

在 Microsoft 文档CF_OPERATION_INFO 结构中,它非常简短地写道

平台的当前同步状态。

该平台会在云文件占位符上的任何失败操作时查询此信息。如果结构可用,平台将使用提供的信息为用户构建更有意义和可操作的消息。平台会将这些信息保留在文件中,直到最后一个句柄消失。如果为null,则平台将清除之前设置的同步状态,如果有的话。

在 MicrosoftCfReportSyncStatus功能的其他地方,它写道

一旦定位到同步状态,平台将使用提供的信息为用户构建更有意义和可操作的消息。

我花了很多时间试图从系统中获得这个“更有意义和可操作的信息”,但没有成功。

CloudMirror 示例中,我执行以下操作。评论了 try 部分,只留下 catch 部分,因此我相信我正在模拟传输错误。


    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);
        }
    }

在 TransferData 函数中,我创建了 CF_SYNC_STATUS 结构并将其地址放在字段 opInfo.SyncStatus 中,然后调用 CfExecute。


    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));
    }

我看不出 opInfo.SyncStatus 字段包含 NULL 和包含结构地址的情况之间有什么区别。

有谁知道如何正确使用此功能?

谢谢。

标签: windowswinapiminifilter

解决方案


推荐阅读