Accès aux mémoires tampons utilisateur dans une routine de rappel de préopération
La routine de rappel de préopération d’un pilote de minifiltre doit traiter une mémoire tampon dans une opération d’E/S basée sur IRP comme suit :
Vérifiez si une MDL existe pour la mémoire tampon. Le pointeur MDL se trouve dans le paramètre MdlAddress ou OutputMdlAddress dans le FLT_PARAMETERS de l’opération. Les pilotes de minifiltre peuvent appeler FltDecodeParameters pour interroger le pointeur MDL.
Une méthode pour obtenir un MDL valide consiste à rechercher l’indicateur IRP_MN_MDL dans le membre MinorFunction du bloc de paramètres d’E/S, FLT_IO_PARAMETER_BLOCK, dans les données de rappel. L’exemple suivant montre comment case activée pour l’indicateur IRP_MN_MDL.
NTSTATUS status; PMDL *ReadMdl = NULL; PVOID ReadAddress = NULL; if (FlagOn(CallbackData->Iopb->MinorFunction, IRP_MN_MDL)) { ReadMdl = &CallbackData->Iopb->Parameters.Read.MdlAddress; }
Toutefois, l’indicateur IRP_MN_MDL ne peut être défini que pour les opérations de lecture et d’écriture. Il est préférable d’utiliser FltDecodeParameters pour récupérer un MDL, car la routine recherche un MDL valide pour toute opération. Dans l’exemple suivant, seul le paramètre MDL est retourné s’il est valide.
NTSTATUS status; PMDL *ReadMdl = NULL; PVOID ReadAddress = NULL; status = FltDecodeParameters(CallbackData, &ReadMdl, NULL, NULL, NULL);
S’il existe un MDL pour la mémoire tampon, appelez MmGetSystemAddressForMdlSafe pour obtenir l’adresse système de la mémoire tampon, puis utilisez cette adresse pour accéder à la mémoire tampon.
Dans la continuité de l’exemple précédent, le code suivant obtient l’adresse système.
if (*ReadMdl != NULL) { ReadAddress = MmGetSystemAddressForMdlSafe(*ReadMdl, NormalPagePriority); if (ReadAddress == NULL) { CallbackData->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; CallbackData->IoStatus.Information = 0; } }
S’il n’existe pas de MDL pour la mémoire tampon, utilisez l’adresse de mémoire tampon pour accéder à la mémoire tampon. Pour garantir la validité d’une adresse de mémoire tampon d’espace utilisateur, le pilote de minifiltre doit utiliser une routine telle que ProbeForRead ou ProbeForWrite, en plaçant toutes les références de mémoire tampon dans try/, sauf les blocs.
Une routine de rappel de préopération doit traiter une mémoire tampon dans une opération d’E/S rapide comme suit :
Utilisez l’adresse de mémoire tampon pour accéder à la mémoire tampon (car une opération d’E/S rapide ne peut pas avoir de MDL).
Pour garantir la validité d’une adresse de mémoire tampon d’espace utilisateur, le pilote de minifiltre doit utiliser une routine telle que ProbeForRead ou ProbeForWrite, en plaçant toutes les références de mémoire tampon dans try/, sauf les blocs.
Pour les opérations qui peuvent être rapides basées sur les E/S ou les IRP, toutes les références de mémoire tampon doivent être placées dans try/, à l’exception des blocs. Bien que vous n’ayez pas à inclure ces références pour les opérations basées sur IRP qui utilisent des E/S mises en mémoire tampon, les blocs try/except constituent une précaution sûre.