首页 > 解决方案 > CfSetInSyncState 的行为不像记录的那样。(CfAPI)

问题描述

我尝试将 CfSetInSyncState 与 USN 一起使用。

文档说您可以提供一个 USN,并且只有在 USN 仍然匹配时才会执行更改。

但是,使用当前 USN 对 NOT_IN_SYNC 文件调用方法将不会成功。它返回0x80070179“ERROR_CLOUD_FILE_NOT_IN_SYNC”。返回的 USN 值也没有改变。

我在github上有一个最小的示例来演示这一点。

我尝试了不同的标志来获取句柄,并且还使用了 CreateFile 方法。打开文件似乎也不会改变 USN。但是,直到知道如果提供了 USN,我无法设置 SyncState,也无法从函数中检索当前的 USN。

CfSetInSyncState当 USN 没有改变时,我如何才能使用它只会将状态设置为 IN_SYNC。


编辑

我更新了示例,因此它将清理潜在的先前文件并生成一些输出:

Cloud sample test!
Try Set In Sync

Created placeholder test1.txt with USN 1631131882568.
Try to set Sync state IN_SYNC
Faild to set InSyncState
USN was NOT changed.


Try Set NOT In Sync

Created placeholder test2.txt with USN 1631131882728.
setting USN variable to -1 But will still work for NOT_IN_SYNC.
Seting Sync state to NOT IN SYNC.
USN was changed now 0.

我在 AppPackage 项目中运行它,因为这似乎是 CfAPI 的要求。

我希望第一个块(将非同步文件设置为同步)不会失败,因为 USN 在cfSetInSyncState调用之前没有改变。(这是目前阻止我的原因)

我还希望在方法返回时获得当前的 USN,即使它失败了。但我不太确定那个。文档说...value after setting the in-sync state...只有在成功的情况下我才能解释。

在第二个块(将文件同步到非同步)中,我希望实际接收到当前的 USN 而不是 0。

目前我尝试不同的方法来打开文件句柄,但到目前为止没有任何帮助。注册 SyncRoot 是否有错误,必须设置一些标志才能使其工作?

标签: c++windowswinapiminifilter

解决方案


  • 对于新创建的占位符CF_PLACEHOLDER_CREATE_FLAG_NONE:要使其成功更改同步状态CfSetInSyncState,您可以将输入 USN 设置为0而不是从返回的 USN CfCreatePlaceholders
  • 对于新创建的占位符CF_PLACEHOLDER_CREATE_FLAG_MARK_IN_SYNC: 或者作为输入0返回的 USNCfCreatePlaceholders将通过 成功更改同步状态CfSetInSyncState

我希望第一个块(将非同步文件设置为同步)不会失败

编辑的代码行:tmpUsn = 0;// usn;

结果快照:

在此处输入图像描述

更新: CfSetInSyncState似乎没有返回实际的 USN。DeviceIoControl您可以通过以下方式获得实际的 USN FSCTL_READ_FILE_USN_DATA

#define BUF_LEN 1024
// ...

CHAR Buffer[BUF_LEN];
DWORD dwBytes;
HANDLE hFile = INVALID_HANDLE_VALUE;
USN_RECORD_V2* fUsn = NULL;

hFile = CreateFile(TEXT("C:\\Test\\Cloud\\test1.txt"),
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    0,
    NULL);

if (hFile == INVALID_HANDLE_VALUE)
{
    printf("CreateFile failed (%d)\n", GetLastError());
    return;
}

memset(Buffer, 0, BUF_LEN);

if (!DeviceIoControl(hFile,
    FSCTL_READ_FILE_USN_DATA,
    NULL,
    0,
    Buffer,
    BUF_LEN,
    &dwBytes,
    NULL))
{
    printf("Read journal failed (%d)\n", GetLastError());
    return;
}

printf("****************************************\n");

fUsn = (USN_RECORD_V2*)Buffer;

printf("USN: %I64x\n", fUsn->Usn);
printf("File name: %.*S\n",
    fUsn->FileNameLength / 2,
    fUsn->FileName);
printf("Reason: %x\n", fUsn->Reason);

CloseHandle(hFile);

请参阅Fsutil usnFSCTL_READ_FILE_USN_DATA IOCTL


推荐阅读