CfSetInSyncState не ведет себя так, как описано в документации. (CfAPI) - PullRequest
0 голосов
/ 23 марта 2020

Я пытаюсь использовать CfSetInSyncState с USN.

В документации говорится, что вы можете указать USN, и изменение будет выполнено только тогда, когда USN все еще совпадает.

Однако вызов метода для файла NOT_IN_SYN C с текущим номером USN не будет успешным. Возвращается 0x80070179 «ERROR_CLOUD_FILE_NOT_IN_SYN C». Возвращенное значение USN также не изменилось.

У меня есть минимальный пример на github , который продемонстрирует это.

Я пробовал разные флаги для получения дескриптора, а также вместо этого использовал метод CreateFile. Открытие файла также, похоже, не меняет USN. Но до тех пор, пока я не узнал, что я не смог установить SyncState, если был указан USN, и не смог получить текущий USN из функции.

Как я могу использовать CfSetInSyncState таким образом, чтобы он только устанавливал состояние в IN_SYN C, когда USN не изменился.


Edit

Я обновил образец, чтобы он очистил потенциальные предыдущие файлы и сгенерировал некоторые выходные данные:

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.

Я ожидаю, что первый блок (установив для файла non syn c syn c) будет не сбой, так как USN не изменился до вызова cfSetInSyncState. (Это то, что в настоящее время блокирует меня)

Я также ожидал бы получить текущий USN при возврате метода, даже если он не удался. Но я не уверен в этом. В документации написано ...value after setting the in-sync state..., которое я могу интерпретировать только в случае успеха.

Во втором блоке (файл syn c не синхронизирован) я ожидал бы получить текущий USN вместо 0.

В настоящее время я пробую разные подходы при открытии дескриптора файла, но пока ничего не помогло. Есть ли ошибка при регистрации Syn cRoot, что для его работы должен быть установлен какой-либо флаг?

1 Ответ

0 голосов
/ 24 марта 2020
  • Для вновь созданного заполнителя с CF_PLACEHOLDER_CREATE_FLAG_NONE: чтобы успешно изменить синхронизированное состояние c с помощью CfSetInSyncState, вы можете установить для ввода USN значение 0 вместо USN возвращается с CfCreatePlaceholders.
  • . Для вновь созданного заполнителя с CF_PLACEHOLDER_CREATE_FLAG_MARK_IN_SYNC: либо 0, либо USN, возвращенный с CfCreatePlaceholders в качестве входных данных, будет изменяться синхронно c состояние успешно выполнено CfSetInSyncState.

Я ожидаю, что первый блок (установка файла syn c на syn c) не будет завершен

Отредактированная строка кода: tmpUsn = 0;// usn;

Снимок результата:

enter image description here

Обновление: CfSetInSyncState, кажется, не возвращает фактический USN. Вы можете получить действительный номер USN через DeviceIoControl с 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 usn , FSCTL_READ_FILE_USN_DATA IOCTL.

...