Retornando FLT_PREOP_SYNCHRONIZE
Observação
Um driver de minifiltro não deve usar FLT_PREOP_SYNCHRONIZE para manter um recurso entre chamadas pré e pós-operação (o mesmo que não deve conter um recurso em uma chamada de E/S). Fazer isso não é seguro, pois pode resultar em deadlocks.
Se a rotina de retorno de chamada de pré-operação de um driver de minifiltro sincronizar uma operação de E/S retornando FLT_PREOP_SYNCHRONIZE, o Gerenciador de Filtros chamará a rotina de retorno de chamada pós-operação desse filtro durante a conclusão de E/S:
- Se o filtro não estiver sendo esvaziado, o Gerenciador de Filtros chamará a rotina de retorno de chamada pós-operação desse filtro no mesmo contexto de thread que o retorno de chamada de pré-operação, em IRQL <= APC_LEVEL. (Observe que esse contexto de thread não é necessariamente o contexto do thread de origem.)
- Se o filtro estiver sendo esvaziado, o Gerenciador de Filtros não sincronizará novamente com o thread original.
Observação
Se a rotina de retorno de chamada de pré-operação de um filtro retornar FLT_PREOP_SYNCHRONIZE, ela deverá implementar uma rotina de retorno de chamada pós-operação para a operação.
Se a rotina de retorno de chamada de pré-operação do filtro retornar FLT_PREOP_SYNCHRONIZE, ele poderá retornar um valor não NULL em seu parâmetro de saída CompletionContext . Esse parâmetro é um ponteiro de contexto opcional que é passado para a rotina de retorno de chamada pós-operação correspondente. A rotina de retorno de chamada pós-operação recebe esse ponteiro em seu parâmetro de entrada CompletionContext .
A rotina de retorno de chamada de pré-operação de um driver de minifiltro deve retornar FLT_PREOP_SYNCHRONIZE somente para operações de E/S baseadas em IRP. No entanto, esse valor de status pode ser retornado para outros tipos de operação. Se ele for retornado para uma operação de E/S que não seja uma operação de E/S baseada em IRP, o Gerenciador de Filtros tratará esse valor retornado como se fosse FLT_PREOP_SUCCESS_WITH_CALLBACK. Para determinar se uma operação é uma operação de E/S baseada em IRP, use a macro FLT_IS_IRP_OPERATION .
Os filtros não devem retornar FLT_PREOP_SYNCHRONIZE para operações de criação, pois essas operações já estão sincronizadas pelo Gerenciador de Filtros. Se um driver de minifiltro tiver registrado rotinas de retorno de chamada de pré-operação e pós-operação para operações de IRP_MJ_CREATE, a rotina de retorno de chamada pós-criação será chamada em IRQL = PASSIVE_LEVEL, no mesmo contexto de thread que a rotina de retorno de chamada de pré-criação.
Os drivers de minifiltro nunca devem retornar FLT_PREOP_SYNCHRONIZE para operações assíncronas de leitura ou gravação. Isso pode prejudicar severamente o desempenho do driver de minifiltro e do sistema e pode até mesmo causar deadlocks se, por exemplo, o thread do gravador de página modificado estiver bloqueado. Antes de retornar FLT_PREOP_SYNCHRONIZE para uma operação de leitura ou gravação baseada em IRP, um driver de minifiltro deve verificar se a operação é síncrona chamando FltIsOperationSynchronous.
Os seguintes tipos de operações de E/S não podem ser sincronizados:
Operações de controle do sistema de arquivos Oplock (FSCTL) (MajorFunction é IRP_MJ_FILE_SYSTEM_CONTROL; FsControlCode é FSCTL_REQUEST_FILTER_OPLOCK, FSCTL_REQUEST_BATCH_OPLOCK, FSCTL_REQUEST_OPLOCK_LEVEL_1 ou FSCTL_REQUEST_OPLOCK_LEVEL_2.)
Notificar operações de diretório de alteração (MajorFunction é IRP_MJ_DIRECTORY_CONTROL; MinorFunction é IRP_MN_NOTIFY_CHANGE_DIRECTORY.)
Solicitações de bloqueio de intervalo de bytes (MajorFunction é IRP_MJ_LOCK_CONTROL; MinorFunction é IRP_MN_LOCK.)
FLT_PREOP_SYNCHRONIZE não pode ser retornado para nenhuma dessas operações.