Функция CfOpenFileWithOplock (cfapi.h)

Открывает асинхронный непрозрачный дескриптор для файла или каталога (как для обычных файлов, так и для файлов заполнителей) и настраивает для него правильную блокировку на основе открытых флагов.

Синтаксис

HRESULT CfOpenFileWithOplock(
  [in]  LPCWSTR            FilePath,
  [in]  CF_OPEN_FILE_FLAGS Flags,
  [out] PHANDLE            ProtectedHandle
);

Параметры

[in] FilePath

Полный путь к открываемой папке или файлу.

[in] Flags

Флаги для указания разрешений на открытие файла. Для флагов можно задать сочетание следующих значений:

  • Если указан CF_OPEN_FILE_FLAG_EXCLUSIVE , API возвращает дескриптор share-none и запрашивает RH (OPLOCK_LEVEL_CACHE_READ|OPLOCK_LEVEL_CACHE_HANDLE) блокировка файла; в противном случае открывается дескриптор общего доступа и запрашивается R (OPLOCK_LEVEL_CACHE_READ ).

    1. Если указано CF_OPEN_FILE_FLAG_EXCLUSIVE , открытой является "общий доступ нет" и получается (OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE) oplock.
      • Обычный вызов CreateFile , который открывается для любого из FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE (или один или оба GENERIC_READ | GENERIC_WRITE) приведет к прерыванию блокировки из-за конфликта общего доступа. Владелец oplock получит, чтобы закончить и подтвердить.
    2. Если CF_OPEN_FILE_FLAG_EXCLUSIVE не указан, открывается параметр "Общий доступ ко всем" и он получает OPLOCK_LEVEL_CACHE_READ oplock.
      • Обычный вызов CreateFile не нарушает блокировку.
      • Если обычный файл CreateFile задает режим общего доступа, который конфликтует с доступом дескриптора Cf (например, если обычный Файл CreateFile не указывает FILE_SHARE_READ), обычный файл CreateFile завершится сбоем с ERROR_SHARING_VIOLATION.
      • Блокировка не прерывается до тех пор, пока другой вызывающий объект не выпустит конфликтующий ввод-вывод, например запись. Когда это произойдет, прерывание блокировки является только рекомендацией.
  • Если указано CF_OPEN_FILE_FLAG_WRITE_ACCESS , API пытается открыть файл или каталог с FILE_READ_DATA/FILE_LIST_DIRECTORY и FILE_WRITE_DATA/FILE_ADD_FILE доступа; в противном случае API пытается открыть файл или каталог с FILE_READ_DATA/FILE_LIST_DIRECTORY.

  • Если указано CF_OPEN_FILE_FLAG_DELETE_ACCESS , API пытается открыть файл или каталог с доступом DELETE ; В противном случае файл открывается обычным образом.

  • Если указано CF_OPEN_FILE_FLAG_FOREGROUND , CfOpenFileWithOplock не запрашивает oplock. Его следует использовать, когда вызывающий объект выступает в качестве приложения переднего плана. Т. е. им не важно, вызывает ли дескриптор файла, созданный этим API, нарушения общего доступа для других вызывающих абонентов, и они не заботятся о нарушении блокировки, которые уже могут быть в файле. Таким образом, они открывают дескриптор, не запрашивая блокировку.

    Примечание

    Фоновое поведение по умолчанию запрашивает блокировку при открытии дескриптора файла, чтобы его вызов завершился сбоем, если он уже есть, и им можно будет указать закрыть дескриптор, если им нужно выйти из этого пути, чтобы избежать нарушения общего доступа в дальнейшем.

    Если вызывающий объект не укажет CF_OPEN_FILE_FLAG_EXCLUSIVEв CfOpenFileWithOplock, он получает oplock будет только OPLOCK_LEVEL_CACHE_READ, а не (OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE)), поэтому защита от нарушений общего доступа, которую обычно может потребоваться фоновому приложению, не будет.

[out] ProtectedHandle

Непрозрачный дескриптор для только что открытого файла или каталога. Обратите внимание, что это не обычный дескриптор Win32 и, следовательно, не может использоваться напрямую с API Win32, отличной от CfApi.

Возвращаемое значение

Если эта функция завершается успешно, она возвращает .S_OK В противном случае возвращается код ошибки HRESULT .

Комментарии

Если блокировка не работает, API автоматически обрабатывает уведомление о прерывании от имени вызывающего объекта, очищая все активные запросы и закрывая базовый дескриптор Win32.

Это позволяет устранить сложность, связанную с использованием oplock. Вызывающий объект должен закрыть дескриптор, возвращенный CfOpenFileWithOplock , с помощью CfCloseHandle.

Фоновое приложение обычно хочет прозрачно работать с файлами. В частности, они хотят избежать нарушений общего доступа для других (переднего плана) открывателей. Для этого они принимают (OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE) oplock, например, будет предоставлено с помощью CF_OPEN_FILE_FLAG_EXCLUSIVE с CfOpenFileWithOplock. Если впоследствии появляется другое средство открытия, режимы которого запрашиваемые режимы общего доступа и общего доступа конфликтуют с фоновым приложением, то блокировка фонового приложения прерывается. При этом фоновому приложению будет предложено закрыть дескриптор файла (для дескриптора Cf, что приводит к тому, что он становится недействительным — реальный базовый дескриптор был закрыт). Когда фоновое приложение закрывает свой дескриптор, открытие другого средства открытия продолжается, не сталкиваясь с нарушением общего доступа. Все это работает из-за OPLOCK_LEVEL_CACHE_HANDLE частью oplock. Без CF_OPEN_FILE_FLAG_EXCLUSIVE блокировка имеет только OPLOCK_LEVEL_CACHE_READ защиту, поэтому описанная защита от нарушений общего доступа не выполняется.

Требования

Требование Значение
Минимальная версия клиента Windows 10 версии 1709 [только классические приложения]
Минимальная версия сервера Windows Server 2016 [только классические приложения]
Целевая платформа Windows
Header cfapi.h
Библиотека CldApi.lib
DLL CldApi.dll

См. также раздел

CfCloseHandle

CreateFile