Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Начиная с Windows 11 все минифильтры должны добавить поддержку операций BypassIO. Операции обхода ввода-вывода запрашиваются путем вызова FltFsControlFile или ZwFsControlFile с:
- Код элемента управления FSCTL_MANAGE_BYPASS_IO .
- Сведения о запросе в структуре FS_BPIO_INPUT , на которую указывает параметр InputBuffer .
- Структура, выделенная вызывающим объектом FS_BPIO_OUTPUT , на которую указывает параметр OutputBuffer , в котором система возвращает результаты операции.
Эта страница содержит сведения о каждой операции BypassIO. Запрос операции указывается как значение FS_BPIO_OPERATIONS в элементе Operation структуры FS_BPIO_INPUT.
Дополнительные сведения о BypassIO см. в разделе "BypassIO для фильтров".
запрос FS_BPIO_OP_ENABLE
Этот запрос может поступать из режима пользователя или ядра. В настоящее время BypassIO для некэшированных записей не поддерживается.
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 во время предварительной операции, но рекомендуется по возможности его включать.
Файловая система автоматически отклоняет запрос на включение функции BypassIO для следующих типов файлов:
- Каталоги (альтернативные потоки данных в каталоге могут использовать BypassIO)
- Тома данных (подключение DASD)
- Сжатые файлы NTFS
- Файлы с использованием NTFS-encryted
- Разреженные файлы
- Файлы подкачки
- Все файлы на томах DAX
Большинству фильтров не нужно сохранять состояние, в котором BypassIO был включен на конкретном потоке. Вместо этого эти сведения можно запрашивать, вызвав 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_DISABLEFSCTL_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 для тома, и теперь необходимо остановить BypassIO (например, из-за какого-то внешнего запроса), драйвер должен отправить операцию FS_BPIO_OP_VOLUME_STACK_PAUSEFSCTL_MANAGE_BYPASS_IO на верхнюю часть стека томов, чтобы уведомить файловую систему о прекращении работы BypassIO в этом томе и его стеках хранения. Файловая система очищает все активные операции BypassIO из этого тома, а затем возвращается. Затем драйвер стека томов может обработать внешний запрос.
Затем все активные файлы с поддержкой BypassIO перестают выполнять операции обхода на уровне хранилища. Запрос на операцию:
- Можно отправить на дескриптор тома или любой дескриптор файла для заданного тома.
- Можно отправлять несколько раз на один том.
- Можно отправить, если в томе нет файлов с поддержкой BypassIO.
BypassIO продолжает работать в стеке файловой системы.
Эта операция не должна провалиться.
Пример приостановки стека томов
BitLocker — это пример компонента, использующего эту операцию, когда необходимо включить шифрование на томе.
Другой пример является следующим сценарием: предположим, что Volsnap позволило включить BypassIO в томе, в котором не было активных моментальных снимков тома. Позже был сделан запрос на создание снимка состояния тома. Volsnap выполняет следующие действия перед продолжением:
- Отправляет операцию FS_BPIO_OP_VOLUME_STACK_PAUSE в верхнюю часть стека, запрашивая, что система отключает BypassIO в стеке томов. Это делается при каждом создании нового моментального снимка. После успешного завершения возврата BypassIO теперь отключён и очищен на заданном томе.
- Обрабатывает запрос на создание моментального снимка
Volsnap должен затем наложить вето на все будущие BPIO_OP_ENABLE и BPIO_OP_QUERY запросы на этот том.
запрос FS_BPIO_OP_VOLUME_STACK_RESUME
Драйвер стека томов отправляет эту операцию FSCTL в файловую систему, чтобы возобновить обработку BypassIO в заданном томе. Он отправляет эту операцию, когда сценарий, который вызвал драйвер отправить FS_BPIO_OP_VOLUME_STACK_PAUSE, больше не активен. Эта операция может быть отправлена, даже если в настоящее время BypassIO не включен или не приостановлен.
Этот запрос может поступать из режима пользователя или ядра.
Эта операция не должна провалиться.
Пример возобновления стека томов
При использовании ранее описанного сценария приостановки стека томов, предположите, что у тома больше нет активных моментальных снимков. Volsnap будет отправлять FS_BPIO_OP_VOLUME_STACK_RESUME только после того, как последний моментальный снимок будет удалён.
запрос FS_BPIO_OP_STREAM_PAUSE
Фильтр может отправлять операцию FS_BPIO_OP_STREAM_PAUSE для приостановки BypassIO на потоке. Этот запрос может поступать из режима пользователя или ядра. Все активные файлы с поддержкой BypassIO перестают выполнять операции BypassIO.
В частности, если фильтр ранее позволял включить BypassIO в потоке, а затем необходимо остановить BypassIO (из-за поступившего извне запроса, например, запроса на шифрование файла или каталога), он может отправить FS_BPIO_OP_STREAM_PAUSEвниз по стеку фильтров, чтобы сообщить файловой системе прекратить выполнение BypassIO в заданном потоке. Фильтр не должен отправлять эту операцию в верхнюю часть стека.
Перед возвратом файловой системы, она приостанавливает все открытые на потоке дескрипторы BypassIO и завершает все активные операции BypassIO в потоке. Эти действия гарантируют, что при возврате фильтр может выполнить операцию файла, которую он должен выполнить.
Эта операция может отправляться в один поток несколько раз. Файловая система игнорирует это, если оно отправлено в поток, который в настоящее время не поддерживает обход ввода-вывода.
Если фильтр выполняет операцию приостановки потока, BypassIO продолжается в стеках томов и хранилищ.
Эта операция не должна провалиться.
Пример приостановки потока: фильтр шифрования
Предположим, что фильтр шифрования позволил активировать BypassIO в потоке, который не был зашифрован, но позже на него поступил запрос на шифрование.
Перед тем как фильтр шифрования продолжит работу, необходимо вызвать FsRtlGetBypassIoOpenCount, чтобы определить, активен ли BypassIO в этом потоке. Если да, фильтр шифрования отправляет операцию FS_BPIO_OP_STREAM_PAUSE, запрашивающую отключение BypassIO в системе. После успешного выполнения возвращения BypassIO отключается и перестает функционировать, так что фильтр может безопасно выполнять шифрование. Чтобы устранить возможные условия гонки, фильтр должен наложить вето на все будущие FS_BPIO_OP_ENABLE и FS_BPIO_OP_QUERY запросы в отношении этого зашифрованного потока данных.
запрос FS_BPIO_OP_STREAM_RESUME
Если сценарий, вызвавший фильтр на отправку операции FS_BPIO_OP_STREAM_PAUSE, больше не существует, фильтр отправляет операцию FS_BPIO_OP_STREAM_RESUME в файловую систему, чтобы возобновить обработку BypassIO заданного потока. Этот запрос может поступать из режима пользователя или ядра.
Если эта операция отправляется, когда 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.