Функция 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 возвращает дескриптор общего доступа и запрашивает 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_DATAFILE_ADD_FILE доступа; в противном случае API пытается открыть файл или каталог с FILE_READ_DATA FILE_LIST_DIRECTORY/.

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

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

    Замечание

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

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

[out] ProtectedHandle

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

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

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

Замечания

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

Это направлено на удаление сложности, связанной с использованием оплока. Вызывающий объект должен закрыть дескриптор, возвращаемый 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 [только настольные приложения]
целевая платформа Виндоус
Заголовок cfapi.h
Библиотека CldApi.lib
Библиотека dll CldApi.dll

См. также

CfCloseHandle

CreateFile