Share via


Fonction MmGetSystemAddressForMdlSafe (wdm.h)

La macro MmGetSystemAddressForMdlSafe retourne une adresse virtuelle d’espace système non paginée pour la mémoire tampon décrite par le MDL spécifié.

Syntaxe

PVOID MmGetSystemAddressForMdlSafe(
  [in] PMDL  Mdl,
  [in] ULONG Priority
);

Paramètres

[in] Mdl

Pointeur vers une mémoire tampon dont l’adresse virtuelle de base correspondante doit être mappée.

[in] Priority

Spécifie une valeur MM_PAGE_PRIORITY qui indique l’importance de la réussite dans des conditions de PTE faiblement disponibles. Spécifiez une valeur de priorité de LowPagePriority, NormalPagePriority ou HighPagePriority. À compter de Windows 8, la valeur de priorité spécifiée peut être ORed au niveau du bit avec les indicateurs MdlMappingNoWrite ou MdlMappingNoExecute.

  • LowPagePriority indique que la demande de mappage peut échouer si le système est relativement faible en ressources. Un exemple de cette situation est une connexion réseau non critique dans laquelle le pilote peut gérer l’échec de mappage.

  • NormalPagePriority indique que la demande de mappage peut échouer si le système est très faible en ressources. Une demande de système de fichiers local non critique est un exemple de cette situation.

  • HighPagePriority indique que la demande de mappage ne doit pas échouer, sauf si le système manque complètement de ressources. Le chemin d’accès du fichier de pagination dans un pilote est un exemple de cette situation.

  • MdlMappingNoWrite indique que les pages physiques mappées doivent être configurées en tant que mémoire sans écriture (lecture seule). À compter de Windows 8, ce bit d’indicateur peut être au niveau du bit-ORed avec la valeur MM_PAGE_PRIORITY pour spécifier la mémoire dans laquelle les écritures sont désactivées.

  • MdlMappingNoExecute indique que les pages physiques mappées doivent être configurées en tant que mémoire sans exécution. À compter de Windows 8, ce bit d’indicateur peut être au niveau du bit-ORed avec la valeur MM_PAGE_PRIORITY pour spécifier la mémoire dans laquelle l’exécution de l’instruction est désactivée. Comme bonne pratique, les pilotes écrits pour Windows 8 et versions ultérieures de Windows doivent toujours spécifier la mémoire sans exécution, sauf si la mémoire exécutable est explicitement requise.

Valeur retournée

MmGetSystemAddressForMdlSafe retourne l’adresse virtuelle de l’espace système de base qui mappe les pages physiques décrites par le MDL spécifié. Si les pages ne sont pas déjà mappées à l’espace d’adressage système et que la tentative de mappage échoue, null est retourné.

Remarques

Cette routine mappe les pages physiques décrites par le MDL spécifié dans l’espace d’adressage système, si elles ne sont pas déjà mappées à l’espace d’adressage système.

Les pilotes d’appareils d’E/S programmées (PIO) appellent cette routine pour mapper une mémoire tampon en mode utilisateur, qui est décrite par mdL à Irp-MdlAddress> et qui est déjà mappée à une plage d’adresses virtuelle en mode utilisateur, à une plage dans l’espace d’adressage système.

Lors de l’entrée de cette routine, la MDL spécifiée doit décrire les pages physiques verrouillées. Un MDL verrouillé peut être créé à l’aide de la routine MmProbeAndLockPages, MmBuildMdlForNonPagedPool, IoBuildPartialMdl ou MmAllocatePagesForMdlEx .

Lorsque le mappage d’espace d’adressage système retourné par MmGetSystemAddressForMdlSafe n’est plus nécessaire, il doit être libéré. Les étapes requises pour libérer le mappage dépendent de la façon dont le MDL a été créé. Voici les quatre cas possibles :

  • Si le MDL a été créé par un appel à la routine MmProbeAndLockPages , il n’est pas nécessaire de libérer explicitement le mappage d’espace d’adressage système. Au lieu de cela, un appel à la routine MmUnlockPages libère le mappage, le cas échéant.

  • Si le MDL a été créé par un appel à la routine MmBuildMdlForNonPagedPool , MmGetSystemAddressForMdlSafe réutilise le mappage d’espace d’adressage système existant au lieu d’en créer un nouveau. Dans ce cas, aucun nettoyage n’est requis (autrement dit, le déverrouillage et le démappage ne sont pas nécessaires).

  • Si le MDL a été créé par un appel à la routine IoBuildPartialMdl , le pilote doit appeler la routine MmPrepareMdlForReuse ou la routine IoFreeMdl pour libérer le mappage de l’espace d’adressage système.

  • Si le MDL a été créé par un appel à la routine MmAllocatePagesForMdlEx , le pilote doit appeler la routine MmUnmapLockedPages pour libérer le mappage de l’espace d’adressage système. Si MmGetSystemAddressForMdlSafe est appelé plusieurs fois pour une MDL, les appels MmGetSystemAddressForMdlSafe suivants retournent simplement le mappage qui a été créé par le premier appel. Un seul appel à MmUnmapLockedPages est suffisant pour publier ce mappage.

À compter de Windows 7 et Windows Server 2008 R2, il n’est pas nécessaire d’appeler explicitement MmUnmapLockedPages pour une MDL qui a été créée par MmAllocatePagesForMdlEx. Au lieu de cela, un appel à la routine MmFreePagesFromMdl libère le mappage de l’espace d’adressage système, s’il en a été alloué.

Pour créer un mappage d’espace d’adressage système, MmGetSystemAddressForMdlSafe appelle MmMapLockedPagesSpecifyCache avec le paramètre CacheType défini sur MmCached. Un pilote qui nécessite un type de cache autre que MmCached doit appeler Directement MmMapLockedPagesSpecifyCache au lieu d’appeler MmGetSystemAddressForMdlSafe. Pour plus d’informations sur le paramètre CacheType , consultez MmMapLockedPagesSpecifyCache.

Dans un appel à MmMapLockedPagesSpecifyCache, le type de cache spécifié est utilisé uniquement si les pages décrites par le MDL n’ont pas déjà un type de cache associé. Toutefois, dans presque tous les cas, les pages ont déjà un type de cache associé, et ce type de cache est utilisé par le nouveau mappage. Une exception à cette règle concerne les pages allouées par MmAllocatePagesForMdl, qui définit le type de cache sur MmCached , quel que soit le type de cache d’origine des pages.

Un seul thread à la fois peut appeler en toute sécurité MmGetSystemAddressForMdlSafe pour un MDL particulier, car cette routine suppose que le thread appelant est propriétaire du MDL. Toutefois, MmGetSystemAddressForMdlSafe peut être appelé plusieurs fois pour la même MDL en effectuant tous les appels à partir du même thread ou, si les appels proviennent de plusieurs threads, en synchronisant explicitement les appels.

Si un pilote doit fractionner une requête en demandes plus petites, il peut allouer des LISTES MDL supplémentaires, ou le pilote peut utiliser la routine IoBuildPartialMdl .

L’adresse de base retournée a le même décalage que l’adresse virtuelle dans le MDL.

Windows 98 ne prend pas en charge MmGetSystemAddressForMdlSafe. Utilisez à la place MmGetSystemAddressForMdl .

Étant donné que cette macro appelle MmMapLockedPagesSpecifyCache, son utilisation peut nécessiter une liaison vers NtosKrnl.lib.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows 2000
En-tête wdm.h
IRQL <= DISPATCH_LEVEL
Règles de conformité DDI MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf)