Función MmGetSystemAddressForMdlSafe (wdm.h)

La macro MmGetSystemAddressForMdlSafe devuelve una dirección virtual de espacio del sistema no paginada para el búfer que describe el MDL especificado.

Sintaxis

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

Parámetros

[in] Mdl

Puntero a un búfer cuya dirección virtual base correspondiente se va a asignar.

[in] Priority

Especifica un valor de MM_PAGE_PRIORITY que indica la importancia del éxito en condiciones de PTE de baja disponibilidad. Especifique un valor de prioridad de LowPagePriority, NormalPagePriority o HighPagePriority. A partir de Windows 8, el valor de prioridad especificado puede ser bit a bit-ORed con las marcas MdlMappingNoWrite o MdlMappingNoExecute.

  • LowPagePriority indica que la solicitud de asignación puede producir un error si el sistema es bastante bajo en los recursos. Un ejemplo de esta situación es una conexión de red no crítica en la que el controlador puede controlar el error de asignación.

  • NormalPagePriority indica que la solicitud de asignación puede producir un error si el sistema es muy bajo en los recursos. Un ejemplo de esta situación es una solicitud de sistema de archivos local no crítica.

  • HighPagePriority indica que la solicitud de asignación no debe producir un error a menos que el sistema esté completamente fuera de los recursos. Un ejemplo de esta situación es la ruta de acceso del archivo de paginación en un controlador.

  • MdlMappingNoWrite indica que las páginas físicas asignadas deben configurarse como memoria sin escritura (solo lectura). A partir de Windows 8, este bit de marca puede ser bit a bit-ORed con el valor de MM_PAGE_PRIORITY para especificar la memoria en la que se deshabilitan las escrituras.

  • MdlMappingNoExecute indica que las páginas físicas asignadas deben configurarse como memoria sin ejecutar. A partir de Windows 8, este bit de marca puede ser bit a bit-ORed con el valor de MM_PAGE_PRIORITY para especificar la memoria en la que se deshabilita la ejecución de instrucciones. Como procedimiento recomendado, los controladores escritos para Windows 8 y versiones posteriores de Windows siempre deben especificar memoria sin ejecutar, a menos que se requiera explícitamente memoria ejecutable.

Valor devuelto

MmGetSystemAddressForMdlSafe devuelve la dirección virtual del espacio del sistema base que asigna las páginas físicas que describe el MDL especificado. Si las páginas aún no están asignadas al espacio de direcciones del sistema y se produce un error al intentar asignarlas, se devuelve NULL .

Comentarios

Esta rutina asigna las páginas físicas descritas por el MDL especificado en el espacio de direcciones del sistema, si aún no están asignadas al espacio de direcciones del sistema.

Los controladores de dispositivos de E/S programadas (PIO) llaman a esta rutina para asignar un búfer en modo de usuario, que se describe en mdL en Irp-MdlAddress> y que ya está asignado a un intervalo de direcciones virtuales en modo de usuario, a un intervalo en el espacio de direcciones del sistema.

Al entrar a esta rutina, el MDL especificado debe describir las páginas físicas bloqueadas. Un MDL bloqueado se puede compilar mediante la rutina MmProbeAndLockPages, MmBuildMdlForNonPagedPool, IoBuildPartialMdl o MmAllocatePagesForMdlEx .

Cuando la asignación de espacio de direcciones del sistema que devuelve MmGetSystemAddressForMdlSafe ya no es necesaria, debe liberarse. Los pasos necesarios para liberar la asignación dependen de cómo se ha compilado MDL. Estos son los cuatro casos posibles:

  • Si la MDL se creó mediante una llamada a la rutina MmProbeAndLockPages , no es necesario liberar explícitamente la asignación de espacio de direcciones del sistema. En su lugar, una llamada a la rutina MmUnlockPages libera la asignación, si se asignó una.

  • Si el MDL se creó mediante una llamada a la rutina MmBuildMdlForNonPagedPool , MmGetSystemAddressForMdlSafe reutiliza la asignación de espacio de direcciones del sistema existente en lugar de crear una nueva. En este caso, no se requiere ninguna limpieza (es decir, no es necesario desbloquear y desamajar).

  • Si la MDL se creó mediante una llamada a la rutina IoBuildPartialMdl , el controlador debe llamar a la rutina MmPrepareMdlForReuse o a la rutina IoFreeMdl para liberar la asignación del espacio de direcciones del sistema.

  • Si el MDL se creó mediante una llamada a la rutina MmAllocatePagesForMdlEx , el controlador debe llamar a la rutina MmUnmapLockedPages para liberar la asignación del espacio de direcciones del sistema. Si se llama a MmGetSystemAddressForMdlSafe más de una vez para una MDL, las llamadas posteriores a MmGetSystemAddressForMdlSafe simplemente devuelven la asignación que creó la primera llamada. Una llamada a MmUnmapLockedPages es suficiente para liberar esta asignación.

A partir de Windows 7 y Windows Server 2008 R2, no es necesario llamar explícitamente a MmUnmapLockedPages para una MDL creada por MmAllocatePagesForMdlEx. En su lugar, una llamada a la rutina MmFreePagesFromMdl libera la asignación del espacio de direcciones del sistema, si se asignó una.

Para crear una nueva asignación de espacio de direcciones del sistema, MmGetSystemAddressForMdlSafe llama a MmMapLockedPagesSpecifyCache con el parámetro CacheType establecido en MmCached. Un controlador que requiera un tipo de caché distinto de MmCached debe llamar directamente a MmMapLockedPagesSpecifyCache en lugar de llamar a MmGetSystemAddressForMdlSafe. Para obtener más información sobre el parámetro CacheType , vea MmMapLockedPagesSpecifyCache.

En una llamada a MmMapLockedPagesSpecifyCache, el tipo de caché especificado solo se usa si las páginas descritas por MDL aún no tienen un tipo de caché asociado. Sin embargo, en casi todos los casos, las páginas ya tienen un tipo de caché asociado y este tipo de caché lo usa la nueva asignación. Una excepción a esta regla es para las páginas asignadas por MmAllocatePagesForMdl, que establece el tipo de caché en MmCached , independientemente del tipo de caché original de las páginas.

Solo un subproceso a la vez puede llamar de forma segura a MmGetSystemAddressForMdlSafe para un MDL determinado, ya que esta rutina supone que el subproceso que llama posee mdl. Sin embargo, se puede llamar a MmGetSystemAddressForMdlSafe más de una vez para la misma MDL realizando todas las llamadas desde el mismo subproceso o, si las llamadas proceden de varios subprocesos, mediante la sincronización explícita de las llamadas.

Si un controlador debe dividir una solicitud en solicitudes más pequeñas, el controlador puede asignar MDL adicionales o el controlador puede usar la rutina IoBuildPartialMdl .

La dirección base devuelta tiene el mismo desplazamiento que la dirección virtual en MDL.

Windows 98 no admite MmGetSystemAddressForMdlSafe. En su lugar, use MmGetSystemAddressForMdl .

Dado que esta macro llama a MmMapLockedPagesSpecifyCache, es posible que sea necesario vincular a NtosKrnl.lib.

Requisitos

Requisito Value
Cliente mínimo compatible Windows 2000
Encabezado wdm.h
IRQL <= DISPATCH_LEVEL
Reglas de cumplimiento de DDI MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf)