Partilhar via


Escrevendo rotinas de retorno de chamada de postoperation

Um driver de minifiltro do sistema de arquivos usa uma ou mais rotinas de retorno de chamada de postoperation para filtrar operações de E/S.

Uma rotina de retorno de chamada de postoperation pode executar uma das seguintes ações:

  • Realize o trabalho de conclusão diretamente na rotina postoperation. Todo o trabalho de conclusão pode ser realizado em IRQL <= DISPATCH_LEVEL.
  • Realize o trabalho de conclusão em um IRQL seguro. Retornar FLT_STATUS_MORE_PROCESSING_REQUIRED e enfileirar um thread de trabalho para permitir o processamento em IRQL seguro. Quando o processamento é concluído, o thread de trabalho chama FltCompletePendedPostOperation para continuar o processamento de postoperation.
  • Cancele uma operação CREATE bem-sucedida.

As rotinas de retorno de chamada do Postoperation são semelhantes às rotinas de conclusão usadas em drivers de filtro do sistema de arquivos herdados.

Um driver de minifiltro registra uma rotina de retorno de chamada de postoperation para um tipo específico de operação de E/S da mesma forma que registra uma rotina de retorno de chamada de pré-operação, ou seja, armazenando o ponto de entrada da rotina de retorno de chamada no membro OperationRegistration da estrutura FLT_REGISTRATION que o driver de minifiltro passa como um parâmetro para FltRegisterFilter em sua rotina DriverEntry .

Os drivers de minifiltro recebem apenas os tipos de operações de E/S para os quais eles registraram uma rotina de retorno de chamada de pré-operação ou operação de operação. Um driver de minifiltro pode registrar uma rotina de retorno de chamada de pré-operação para um determinado tipo de operação de E/S sem registrar um retorno de chamada de postoperation e vice-versa.

Cada rotina de retorno de chamada de postoperation é definida da seguinte maneira:

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 
    ); 

Como uma rotina de conclusão, uma rotina de retorno de chamada de postoperation é chamada em IRQL <= DISPATCH_LEVEL, em um contexto de thread arbitrário.

Como ela pode ser chamada em IRQL = DISPATCH_LEVEL, uma rotina de retorno de chamada de postoperation não pode chamar rotinas de modo kernel que devem ser chamadas em um IRQL inferior, como FltLockUserBuffer ou RtlCompareUnicodeString. Pelo mesmo motivo, todas as estruturas de dados usadas em uma rotina de retorno de chamada de postoperation devem ser alocadas do pool nãopagado.

As seguintes situações são várias exceções à regra anterior:

  • Se a rotina de retorno de chamada de pré-operação de um driver de minifiltro retornar FLT_PREOP_SYNCHRONIZE para uma operação de E/S baseada em IRP, a rotina de retorno de chamada de postoperation correspondente será chamada em IRQL <= APC_LEVEL, no mesmo contexto de thread que a rotina de retorno de chamada de pré-operação.

  • A rotina de retorno de chamada de postoperation para uma operação de E/S rápida é chamada em IRQL = PASSIVE_LEVEL, no mesmo contexto de thread que a rotina de retorno de chamada de pré-operação.

  • As rotinas de retorno de chamada pós-criação são chamadas em IRQL = PASSIVE_LEVEL, no contexto do thread que originou a operação de IRP_MJ_CREATE.

Quando o gerenciador de filtros chama a rotina de retorno de chamada postoperation de um driver de minifiltro para uma determinada operação de E/S, o driver de minifiltro controla temporariamente a operação de E/S. O driver de minifiltro mantém esse controle até que ele siga um destes procedimentos:

  • Retorna FLT_POSTOP_FINISHED_PROCESSING da rotina de retorno de chamada postoperation.

  • Chama FltCompletePendedPostOperation de uma rotina de trabalho que processou uma operação de E/S baseada em IRP que estava pendente na rotina de retorno de chamada de postoperation.

Esta seção inclui:

Executando o processamento de conclusão para uma operação de E/S

Pendente de uma operação de E/S em uma rotina de retorno de chamada postoperation

Falha em uma operação de E/S em uma rotina de retorno de chamada de postoperation