Écriture de routines de rappel post-opération
Un pilote de minifiltre de système de fichiers utilise une ou plusieurs routines de rappel post-opération pour filtrer les opérations d’E/S.
Une routine de rappel post-opération peut effectuer l’une des actions suivantes :
- Accomplir le travail d’achèvement directement dans la routine de post-opération. Tout le travail d’achèvement peut être effectué à IRQL <= DISPATCH_LEVEL.
- Accomplir le travail d’achèvement à un IRQL sécurisé. Retourner FLT_STATUS_MORE_PROCESSING_REQUIRED et mettre en file d’attente un thread de travail pour permettre le traitement à l’IRQL sécurisé. Une fois le traitement terminé, le thread de travail appelle FltCompletePendedPostOperation pour poursuivre le traitement post-opération.
- Annuler une opération CREATE réussie.
Les routines de rappel post-opération sont similaires aux routines d’achèvement utilisées dans les pilotes de filtre de système de fichiers hérités.
Un pilote de minifiltre enregistre une routine de rappel post-opération pour un type particulier d’opération d’E/S de la même façon qu’il inscrit une routine de rappel de préopération, c’est-à-dire en stockant le point d’entrée de la routine de rappel dans le membre OperationRegistration de la structure FLT_REGISTRATION que le pilote de minifiltre transmet en tant que paramètre à FltRegisterFilter dans sa routine DriverEntry .
Les pilotes minifiltres reçoivent uniquement les types d’opérations d’E/S pour lesquelles ils ont inscrit une routine de rappel de préopération ou de post-opération. Un pilote de minifiltre peut inscrire une routine de rappel de préopération pour un type donné d’opération d’E/S sans inscrire de rappel postopératoire, et inversement.
Chaque routine de rappel post-opération est définie comme suit :
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
);
Comme une routine d’achèvement, une routine de rappel post-opération est appelée dans IRQL <= DISPATCH_LEVEL, dans un contexte de thread arbitraire.
Étant donné qu’elle peut être appelée à l’adresse IRQL = DISPATCH_LEVEL, une routine de rappel post-opération ne peut pas appeler des routines en mode noyau qui doivent être appelées à un IRQL inférieur, comme FltLockUserBuffer ou RtlCompareUnicodeString. Pour la même raison, toutes les structures de données utilisées dans une routine de rappel post-opération doivent être allouées à partir d’un pool non paginé.
Les situations suivantes sont plusieurs exceptions à la règle précédente :
Si la routine de rappel de préopération d’un pilote minifiltre retourne FLT_PREOP_SYNCHRONIZE pour une opération d’E/S basée sur IRP, la routine de rappel post-opération correspondante est appelée dans IRQL <= APC_LEVEL, dans le même contexte de thread que la routine de rappel de préopération.
La routine de rappel post-opération pour une opération d’E/S rapide est appelée à IRQL = PASSIVE_LEVEL, dans le même contexte de thread que la routine de rappel de préopération.
Les routines de rappel post-création sont appelées dans IRQL = PASSIVE_LEVEL, dans le contexte du thread à l’origine de l’opération IRP_MJ_CREATE.
Lorsque le gestionnaire de filtres appelle la routine de rappel post-opération d’un pilote de minifiltre pour une opération d’E/S donnée, le pilote de minifiltre contrôle temporairement l’opération d’E/S. Le pilote de minifiltre conserve ce contrôle jusqu’à ce qu’il effectue l’une des opérations suivantes :
Retourne FLT_POSTOP_FINISHED_PROCESSING de la routine de rappel post-opération.
Appelle FltCompletePendedPostOperation à partir d’une routine de travail qui a traité une opération d’E/S basée sur IRP qui a été bloquée dans la routine de rappel post-opération.
Cette section comprend :
Exécution du traitement de fin pour une opération d’E/S
En attente d’une opération d’E/S dans une routine de rappel postopératoire
Échec d’une opération d’E/S dans une routine de rappel de post-opération