Написание подпрограмм обратного вызова после операции
Драйвер минифильтра файловой системы использует одну или несколько подпрограмм обратного вызова после операции для фильтрации операций ввода-вывода.
Подпрограмма обратного вызова после операции может выполнять одно из следующих действий:
- Выполнение работы по завершению непосредственно в послеоперационной процедуре. Все работы по завершению можно выполнить в IRQL <= DISPATCH_LEVEL.
- Выполнение работы по завершению в безопасном IRQL. Верните FLT_STATUS_MORE_PROCESSING_REQUIRED и поставьте рабочий поток в очередь, чтобы обеспечить безопасную обработку IRQL. После завершения обработки рабочий поток вызывает FltCompletePendedPostOperation , чтобы продолжить обработку после операции.
- Отмена успешной операции CREATE.
Процедуры обратного вызова после операции аналогичны подпрограммам завершения, которые используются в устаревших драйверах фильтров файловой системы.
Драйвер минифильтра регистрирует подпрограмму послеоперационного обратного вызова для определенного типа операции ввода-вывода так же, как он регистрирует подпрограмму обратного вызова перед операцией, то есть сохраняя точку входа подпрограммы обратного вызова в элементе OperationRegistrationструктуры FLT_REGISTRATION , которую драйвер минифильтра передает в качестве параметра FltRegisterFilter в своей подпрограмме DriverEntry .
Драйверы минифильтра получают только те типы операций ввода-вывода, для которых они зарегистрировали подпрограмму обратного вызова перед операцией или после операции. Драйвер минифильтра может зарегистрировать подпрограмму обратного вызова перед операцией перед операцией ввода-вывода для определенного типа операции ввода-вывода без регистрации обратного вызова после операции и наоборот.
Каждая подпрограмма обратного вызова после операции определяется следующим образом:
typedef FLT_POSTOP_CALLBACK_STATUS
(*PFLT_POST_OPERATION_CALLBACK) (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
IN PVOID CompletionContext,
IN FLT_POST_OPERATION_FLAGS Flags
);
Как и в случае с процедурой завершения, подпрограмма обратного вызова после операции вызывается в irQL <= DISPATCH_LEVEL в произвольном контексте потока.
Так как она может вызываться в irQL = DISPATCH_LEVEL, подпрограмма обратного вызова после операции не может вызывать подпрограммы режима ядра, которые должны вызываться в более низком irQL, например FltLockUserBuffer или RtlCompareUnicodeString. По этой же причине все структуры данных, используемые в подпрограмме обратного вызова после операции, должны быть выделены из непагрегированного пула.
Следующие ситуации являются несколькими исключениями из предыдущего правила.
Если подпрограмма обратного вызова драйвера минифильтра перед операцией обратного вызова возвращает FLT_PREOP_SYNCHRONIZE для операции ввода-вывода на основе IRP, соответствующая подпрограмма обратного вызова после операции вызывается в irQL <= APC_LEVEL в том же контексте потока, что и подпрограмма обратного вызова перед операцией.
Подпрограмма обратного вызова после операции быстрого ввода-вывода вызывается в irQL = PASSIVE_LEVEL в том же контексте потока, что и подпрограмма обратного вызова перед операцией.
Подпрограммы обратного вызова после создания вызываются по адресу IRQL = PASSIVE_LEVEL в контексте потока, из которого была создана операция IRP_MJ_CREATE.
Когда диспетчер фильтров вызывает подпрограмму обратного вызова драйвера минифильтра после операции ввода-вывода для определенной операции ввода-вывода, драйвер минифильтра временно управляет операцией ввода-вывода. Драйвер минифильтра сохраняет этот элемент управления, пока не выполняет одно из следующих действий:
Возвращает FLT_POSTOP_FINISHED_PROCESSING из подпрограммы обратного вызова после операции.
Вызывает FltCompletePendedPostOperation из рабочей процедуры, которая обработала операцию ввода-вывода на основе IRP, которая была выполнена в подпрограмме обратного вызова после операции.
Этот раздел состоит из следующих частей.
Выполнение обработки завершения операции ввода-вывода
Ожидание операции ввода-вывода в подпрограмме обратного вызова после операции
Сбой операции ввода-вывода в подпрограмме обратного вызова после операции