Возврат FLT_PREOP_SYNCHRONIZE
Примечание
Драйвер минифильтра не должен использовать FLT_PREOP_SYNCHRONIZE для хранения ресурса в вызовах до и после операции (так же, как он не должен содержать ресурс во время вызова ввода-вывода). Это небезопасно, так как это может привести к взаимоблокировкам.
Если подпрограмма обратного вызова драйвера минифильтра перед операцией синхронизирует операцию ввода-вывода , возвращая FLT_PREOP_SYNCHRONIZE, диспетчер фильтров вызывает подпрограмму обратного вызова этого фильтра после операции во время завершения ввода-вывода:
- Если фильтр не истощается, диспетчер фильтров вызывает подпрограмму обратного вызова этого фильтра после операции в том же контексте потока, что и обратный вызов перед операцией, по адресу IRQL <= APC_LEVEL. (Обратите внимание, что этот контекст потока не обязательно является контекстом исходного потока.)
- Если фильтр стекает, диспетчер фильтров не синхронизируется с исходным потоком.
Примечание
Если подпрограмма обратного вызова фильтра перед операцией возвращает FLT_PREOP_SYNCHRONIZE, она должна реализовать подпрограмму обратного вызова после операции.
Если подпрограмма обратного вызова фильтра перед операцией возвращает FLT_PREOP_SYNCHRONIZE, она может вернуть значение, отличное от NULL, в выходном параметре CompletionContext . Этот параметр является необязательным указателем контекста, который передается в соответствующую подпрограмму обратного вызова после операции. Подпрограмма обратного вызова после операции получает этот указатель во входном параметре CompletionContext .
Подпрограмма предварительного обратного вызова драйвера минифильтра должна возвращать FLT_PREOP_SYNCHRONIZE только для операций ввода-вывода на основе IRP. Однако это значение состояния может быть возвращено для других типов операций. Если оно возвращается для операции ввода-вывода, которая не является операцией ввода-вывода на основе IRP, диспетчер фильтров обрабатывает это возвращаемое значение так, как если бы оно было FLT_PREOP_SUCCESS_WITH_CALLBACK. Чтобы определить, является ли операция операцией ввода-вывода на основе IRP, используйте макрос FLT_IS_IRP_OPERATION .
Фильтры не должны возвращать FLT_PREOP_SYNCHRONIZE для операций создания, так как эти операции уже синхронизированы диспетчером фильтров. Если драйвер минифильтра зарегистрировал подпрограммы обратного вызова перед операцией и после операции для IRP_MJ_CREATE операций, подпрограмма обратного вызова после создания вызывается в IRQL = PASSIVE_LEVEL в том же контексте потока, что и подпрограмма обратного вызова перед созданием.
Драйверы минифильтра никогда не должны возвращать FLT_PREOP_SYNCHRONIZE для асинхронных операций чтения или записи. Это может серьезно снизить производительность драйвера минифильтра и системы и даже привести к взаимоблокировкам, если, например, заблокирован поток записи измененных страниц. Прежде чем возвращать FLT_PREOP_SYNCHRONIZE для операции чтения или записи на основе IRP, драйвер минифильтра должен убедиться, что операция синхронна, вызвав FltIsOperationSynchronous.
Не удается синхронизировать следующие типы операций ввода-вывода:
Операции управления файловой системой Oplock (FSCTL) (MajorFunction — IRP_MJ_FILE_SYSTEM_CONTROL; FsControlCode имеет значение FSCTL_REQUEST_FILTER_OPLOCK, FSCTL_REQUEST_BATCH_OPLOCK, FSCTL_REQUEST_OPLOCK_LEVEL_1 или FSCTL_REQUEST_OPLOCK_LEVEL_2.)
Уведомлять об операциях каталога изменений (MajorFunction — IRP_MJ_DIRECTORY_CONTROL; MinorFunction IRP_MN_NOTIFY_CHANGE_DIRECTORY.)
Запросы на блокировку диапазона байтов (MajorFunction — IRP_MJ_LOCK_CONTROL; MinorFunction имеет IRP_MN_LOCK.)
FLT_PREOP_SYNCHRONIZE не может быть возвращено ни для одной из этих операций.