Retour FLT_PREOP_SYNCHRONIZE
Notes
Un pilote minifilter ne doit pas utiliser FLT_PREOP_SYNCHRONIZE pour contenir une ressource sur les appels avant et après l’opération (comme il ne doit pas contenir une ressource sur un appel d’E/S). Pour ce faire, il est dangereux, car cela peut entraîner des interblocages.
Si la routine de rappel pré-opération d’un pilote minifilter synchronise une opération d’E/S en retournant FLT_PREOP_SYNCHRONIZE, le Gestionnaire de filtres appelle la routine de rappel post-opération de ce filtre pendant l’achèvement des E/S :
- Si le filtre ne se vide pas, le Gestionnaire de filtres appelle la routine de rappel post-opération de ce filtre dans le même contexte de thread que le rappel avant l’opération, à l’adresse IRQL <= APC_LEVEL. (Notez que ce contexte de thread n’est pas nécessairement le contexte du thread d’origine.)
- Si le filtre est en cours de drainage, le Gestionnaire de filtres ne se synchronise pas avec le thread d’origine.
Notes
Si la routine de rappel avant opération d’un filtre retourne FLT_PREOP_SYNCHRONIZE, il doit implémenter une routine de rappel post-opération pour l’opération.
Si la routine de rappel de pré-opération du filtre retourne FLT_PREOP_SYNCHRONIZE, elle peut retourner une valeur non NULL dans son paramètre de sortie CompletionContext . Ce paramètre est un pointeur de contexte facultatif qui est passé à la routine de rappel post-opération correspondante. La routine de rappel post-opération reçoit ce pointeur dans son paramètre d’entrée CompletionContext .
La routine de rappel de pré-opération d’un pilote minifilter doit retourner FLT_PREOP_SYNCHRONIZE uniquement pour les opérations d’E/S basées sur IRP. Toutefois, cette valeur status peut être retournée pour d’autres types d’opérations. Si elle est retournée pour une opération d’E/S qui n’est pas une opération d’E/S basée sur IRP, le Gestionnaire de filtres traite cette valeur de retour comme si elle était FLT_PREOP_SUCCESS_WITH_CALLBACK. Pour déterminer si une opération est une opération d’E/S basée sur IRP, utilisez la macro FLT_IS_IRP_OPERATION .
Les filtres ne doivent pas retourner FLT_PREOP_SYNCHRONIZE pour les opérations de création, car ces opérations sont déjà synchronisées par le Gestionnaire de filtres. Si un pilote minifilter a inscrit des routines de rappel de pré-opération et de post-opération pour les opérations de IRP_MJ_CREATE, la routine de rappel post-création est appelée à IRQL = PASSIVE_LEVEL, dans le même contexte de thread que la routine de rappel préalable à la création.
Les pilotes Minifilter ne doivent jamais retourner FLT_PREOP_SYNCHRONIZE pour les opérations de lecture ou d’écriture asynchrones. Cela peut gravement dégrader les performances du pilote de minifiltre et du système, et même provoquer des interblocages si, par exemple, le thread de l’enregistreur de pages modifié est bloqué. Avant de retourner FLT_PREOP_SYNCHRONIZE pour une opération de lecture ou d’écriture basée sur IRP, un pilote minifilter doit vérifier que l’opération est synchrone en appelant FltIsOperationSynchronous.
Les types d’opérations d’E/S suivants ne peuvent pas être synchronisés :
Opérations de contrôle de système de fichiers Oplock (FSCTL) (MajorFunction est IRP_MJ_FILE_SYSTEM_CONTROL ; FsControlCode est FSCTL_REQUEST_FILTER_OPLOCK, FSCTL_REQUEST_BATCH_OPLOCK, FSCTL_REQUEST_OPLOCK_LEVEL_1 ou FSCTL_REQUEST_OPLOCK_LEVEL_2.)
Notifier les opérations de modification d’annuaire (MajorFunction est IRP_MJ_DIRECTORY_CONTROL ; MinorFunction est IRP_MN_NOTIFY_CHANGE_DIRECTORY.)
Demandes de verrouillage de plage d’octets (MajorFunction est IRP_MJ_LOCK_CONTROL ; MinorFunction est IRP_MN_LOCK.)
FLT_PREOP_SYNCHRONIZE ne peut pas être retourné pour l’une de ces opérations.