Поделиться через


Поддержка операций BypassIO

Начиная с Windows 11 все минифильтры должны добавить поддержку операций BypassIO. Операции обхода обхода запрашиваются путем вызова FltFsControlFile или ZwFsControlFile с:

Эта страница содержит сведения о каждой операции BypassIO. Запрос операции указывается в качестве значения FS_BPIO_OPERATIONS в элементе операции FS_BPIO_INPUT.

Дополнительные сведения об BypassIO см. в разделе "Обход обхода" для фильтров.

запрос FS_BPIO_OP_ENABLE

Этот запрос может поступать из режима пользователя или ядра. В настоящее время обход обхода без кэширования записей не поддерживается.

FS_BPIO_OP_ENABLE запросы, которые система включает BypassIO для данного файла, что означает, что драйвер может не видеть все некачественные операции чтения для этого файла.

BypassIO — это концепция открытия файла; то есть запрос FS_BPIO_OP_ENABLE влияет только на объект файла, связанный с запросом включения, и не изменяет поведение других открывается в том же файле или потоке. Если отправляются несколько запросов на один и тот же объект файла, то только первый запрос имеет смысл, а все последующие запросы игнорируются.

В обратном вызове перед выполнением драйвера:

  • Если драйвер может поддерживать BypassIO для данного файла, он должен перенаправить запрос вниз стек.

  • Если драйвер не может поддерживать BypassIO для данного файла, он должен вызвать FltVetoBypassIo со следующими сведениями:

    • Имя драйвера, которое находится в структуре FLT_RELATED_OBJECTS, на которую указывает параметр FltObjects.
    • Код ошибки NTSTATUS, описывающий причину вето на запрос включения в параметр OperationStatus .
    • Уникальная описательная строка с подробными сведениями о том, почему вы ветоировали запрос на включение в параметре FailureReason .

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

Минифильтр должен завершить FSCTL_MANAGE_BYPASS_IO с STATUS_SUCCESS, если FltVetoBypassIo выполнен успешно; в противном случае он должен вернуть ошибку, возвращаемую FltVetoBypassIo.

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

Примечание.

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

Файловая система автоматически ветоирует запрос на включение обхода для следующих типов файлов:

  • Каталоги (альтернативные потоки данных в каталоге могут использовать BypassIO)
  • Тома (открывается DASD)
  • Сжатые файлы NTFS
  • Файлы с использованием NTFS-encryted
  • Разреженные файлы
  • Файлы подкачки
  • Все файлы на томах DAX

Большинству фильтров не нужно поддерживать состояние, включаемое Обходом в определенном потоке. Вместо этого эти сведения можно запрашивать, вызвав FsRtlGetBypassIoOpenCount.

пример FS_BPIO_OP_ENABLE: фильтр шифрования

Когда фильтр шифрования получает операцию FS_BPIO_OP_ENABLE в файле:

  • Если файл уже зашифрован, фильтр должен вызвать FltVetoBypassIo для вето операции BypassIO, предоставляя соответствующее состояние и диагностическое сообщение, например:

    • OpStatus = STATUS_NOT_SUPPORTED_WITH_ENCRYPTION
    • FailureReason = "Зашифрованный файл не поддерживается"
  • Если файл в настоящее время не зашифрован, фильтр должен разрешить BypassIO. Если следующий запрос выполняется для шифрования этого файла, фильтр может использовать операцию FS_BPIO_OP_STREAM_PAUSE для отключения BypassIO.

запрос FS_BPIO_OP_DISABLE

Этот запрос может поступать из режима пользователя или ядра. Он позволяет драйверу очистить любое связанное состояние BypassIO.

Если драйвер, ранее разрешенный ОбходИО в этом файле, и теперь необходимо отключить поддержку BypassIO для файла, он должен отправить FS_BPIO_OP_DISABLE FSCTL_MANAGE_BYPASS_IO операцию в верхней части стека файловой системы с помощью связанного дескриптора. Примером того, когда это условие может произойти, является драйвер шифрования, который получил запрос на шифрование этого файла.

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

Эта операция не должна завершиться ошибкой.

запрос FS_BPIO_OP_QUERY

Этот запрос может поступать из режима пользователя или ядра.

Фильтр должен обрабатывать запрос FS_BPIO_OP_QUERY аналогично операции FS_BPIO_OP_ENABLE, вызывая FltVetoBypassIo вето соответствующим образом с той же диагностической информацией, что и описанные ранее в соответствующих параметрах. Основное различие заключается в том, что драйвер не вводит состояние BypassIO ENABLE во время запроса.

Операция FS_BPIO_OP_QUERY может быть отправлена в дескрипторах каталогов и томов (запрос FS_BPIO_OP_ENABLE не может быть отправлен в дескриптор каталога или тома).

Пример запроса: фильтр шифрования

Когда фильтр шифрования получает операцию FS_BPIO_OP_QUERY в файле:

  • Если файл уже зашифрован, фильтр должен вызвать FltVetoBypassIo для вето операции BypassIO, предоставляя соответствующее состояние и диагностическое сообщение, например:

    • OpStatus = STATUS_NOT_SUPPORTED_WITH_ENCRYPTION
    • FailureReason = "Зашифрованный файл не поддерживается"
  • Если файл в настоящее время не зашифрован, фильтр должен успешно выполнить запрос.

запрос FS_BPIO_OP_VOLUME_STACK_PAUSE

Этот запрос может поступать из режима пользователя или ядра.

Если драйвер стека томов ранее разрешал Обходио включено в томе, и теперь необходимо остановить BypassIO (например, из-за какого-то внешнего запроса), драйвер должен отправить FS_BPIO_OP_VOLUME_STACK_PAUSE FSCTL_MANAGE_BYPASS_IO операции в верхней части стека томов, чтобы уведомить файловую систему об остановке обхода в томах и стеках хранилища этого тома. Файловая система очищает все активные операции BypassIO из этого тома, а затем возвращается. Затем драйвер стека томов может обработать внешний запрос.

Затем все активные файлы с поддержкой BypassIO перестают выполнять операции обхода на уровне хранилища. Этот запрос операции:

  • Можно отправить на дескриптор тома или любой дескриптор файла для заданного тома.
  • Можно отправлять несколько раз в один том.
  • Можно отправить, если в томе нет файлов с поддержкой BypassIO.

BypassIO продолжает работать в стеке файловой системы.

Эта операция не должна завершиться ошибкой.

Пример приостановки стека томов

BitLocker — это пример компонента, использующего эту операцию, если требуется включить шифрование на томе.

Другой пример является следующим сценарием: предположим, что Volsnap позволило включить BypassIO в томе, в котором не было активных моментальных снимков тома. Позже был сделан запрос на создание моментального снимка тома. Volsnap выполняет следующие действия перед продолжением:

  • Отправляет операцию FS_BPIO_OP_VOLUME_STACK_PAUSE в верхнюю часть стека, запрашивая, что система отключает BypassIO в стеке томов. Это делается при каждом создании нового моментального снимка. После успешного возврата обход обхода теперь отключается и очищается на заданном томе.
  • Обрабатывает запрос на создание моментального снимка

Volsnap должен затем вето на все будущие BPIO_OP_ENABLE и BPIO_OP_QUERY запросов на этот том.

запрос FS_BPIO_OP_VOLUME_STACK_RESUME

Драйвер стека томов отправляет эту операцию FSCTL в файловую систему, чтобы возобновить обработку BypassIO в заданном томе. Он отправляет эту операцию, когда сценарий, который вызвал отправку драйвера FS_BPIO_OP_VOLUME_STACK_PAUSE больше не активен. Эта операция может быть отправлена, даже если в настоящее время не включена или приостановлена обходная операция.

Этот запрос может поступать из режима пользователя или ядра.

Эта операция не должна завершиться ошибкой.

Пример возобновления стека томов

Использование сценария приостановки стека томов, описанного ранее, говорят, что том больше не имеет активных моментальных снимков. Volsnap будет отправлять FS_BPIO_OP_VOLUME_STACK_RESUME только после того, как последний моментальный снимок исчезнет.

запрос FS_BPIO_OP_STREAM_PAUSE

Фильтр может отправить операцию FS_BPIO_OP_STREAM_PAUSE для приостановки Обходио в потоке. Этот запрос может поступать из режима пользователя или ядра. Все активные файлы с поддержкой BypassIO перестают выполнять операции BypassIO.

В частности, если фильтр, ранее разрешенный ОбходИО, должен быть включен в потоке, а позже необходимо остановить BypassIO (из-за внешнего запроса, такого как запрос на шифрование файла или каталога), он может отправить FS_BPIO_OP_STREAM_PAUSE вниз стек фильтров, чтобы сообщить файловой системе прекратить выполнение Обходио в заданном потоке. Фильтр не должен отправлять эту операцию в верхнюю часть стека.

Перед возвратом файловой системы все дескриптор BypassIO открыты в потоке и завершает все активные операции BypassIO в потоке. Эти действия гарантируют, что при возврате фильтр может выполнить операцию файла, которую он должен выполнить.

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

Если фильтр выполняет операцию приостановки потока, Обходио продолжается в стеках томов и хранилищ.

Эта операция не должна завершиться ошибкой.

Пример приостановки потока: фильтр шифрования

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

Перед продолжением фильтра шифрования необходимо вызвать FsRtlGetBypassIoOpenCount , чтобы определить, активен ли Обходио в этом потоке. Если да, фильтр шифрования отправляет операцию FS_BPIO_OP_STREAM_PAUSE , запрашивающую отключение обхода системы. При успешном возвращении обход обхода отключается и отключается, поэтому фильтр может безопасно выполнять запрос на шифрование. Чтобы устранить возможные условия гонки, фильтр должен вето на все будущие FS_BPIO_OP_ENABLE и FS_BPIO_OP_QUERY запросов на этот зашифрованный поток.

запрос FS_BPIO_OP_STREAM_RESUME

Если сценарий, который вызвал фильтрацию для отправки операции FS_BPIO_OP_STREAM_PAUSE больше не существует, фильтр отправляет операцию FS_BPIO_OP_STREAM_RESUME в файловую систему, чтобы возобновить обработку BypassIO заданного потока. Этот запрос может поступать из режима пользователя или ядра.

Если эта операция отправляется, когда Обходиоо не включено или приостановлено, она игнорируется.

Приостановка и возобновление не учитываются. Скорее, в резюме файловая система выдает запрос FS_BPIO_OP_QUERY в начало стека файловой системы, чтобы определить, блокируются ли остальные фильтры. Файловая система возобновляет обход только в том случае, если все фильтры в стеке не блокируют BypassIO.

Эта операция не должна завершиться ошибкой.

Пример возобновления потока: фильтр шифрования

Используя описанный ранее сценарий FS_BPIO_OP_STREAM_PAUSE , предположим, что файл, который ранее был зашифрован после вызова FS_BPIO_OP_STREAM_PAUSE , больше не шифруется. Затем фильтр должен отправить операцию FS_BPIO_OP_STREAM_RESUME , чтобы разрешить BypassIO возобновить работу в этом потоке.

запрос FS_BPIO_OP_GET_INFO

Этот запрос может поступать из режима пользователя или ядра. Файловая система возвращает сведения об BypassIO для тома в структуре FS_BPIO_INFO .