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


Написание подпрограмм обратного вызова после операции

Драйвер минифильтра файловой системы использует одну или несколько подпрограмм обратного вызова после операции для фильтрации операций ввода-вывода.

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

  • Выполнение работы по завершению непосредственно в послеоперационной процедуре. Все работы по завершению можно выполнить в 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, которая была выполнена в подпрограмме обратного вызова после операции.

Этот раздел состоит из следующих частей.

Выполнение обработки завершения операции ввода-вывода

Ожидание операции ввода-вывода в подпрограмме обратного вызова после операции

Сбой операции ввода-вывода в подпрограмме обратного вызова после операции