Compartir a través de


Macro MmLockPagableCodeSection (wdm.h)

El MmLockPagableCodeSection rutina bloquea una sección del código de controlador, que contiene un conjunto de rutinas de controlador marcadas con una directiva especial del compilador, en el espacio del sistema.

Sintaxis

void MmLockPagableCodeSection(
  [in]  Address
);

Parámetros

[in] Address

Especifica una dirección simbólica. Esta dirección suele ser el nombre de una función de controlador dentro de una sección del código de controlador que se ha marcado con algo como #pragma alloc_text (PAGExxxx, driverfunction). Se garantiza que todas las funciones de la sección pagExxxx de se bloquean cuando esta función devuelve.

Valor devuelto

Ninguno

Observaciones

MmLockPagableCodeSection devuelve un valor opaco que el sistema operativo usa para identificar esta sección del código del controlador. Este valor opaco se puede pasar posteriormente a mmLockPagableSectionByHandle (si el controlador desbloquea y luego vuelve a interbloquear la sección) o a MmUnlockPagableImageSection.

La rutina MmLockPagableCodeSection y mmUnlockPagableImageSection (la rutina que realiza la acción opuesta) admite controladores que pueden hacer lo siguiente:

  • Aplazar la carga de un subconjunto de rutinas de controlador en la memoria residente hasta que las solicitudes de E/S entrantes para los dispositivos del controlador hacen necesario que estas rutinas procesen IRP.

  • Haga que el mismo subconjunto de rutinas de controladores esté disponible para paginar cuando hayan completado el procesamiento de solicitudes de E/S y no se espera ninguna solicitud adicional para los dispositivos del controlador.

MmLockPagableCodeSection, MmLockPagableSectionByHandle y MmUnlockPagableImageSection están diseñados para su uso por los controladores intermedios y dispositivos que tienen las siguientes características:

  • El controlador tiene rutas de acceso de código que podrían no ser necesarias mientras se ejecuta el sistema, pero, si son necesarias, el código del controlador debe residir porque se ejecuta en un contexto de subproceso arbitrario o en IRQL >= DISPATCH_LEVEL.

  • El controlador puede determinar exactamente cuándo se deben cargar las rutinas paginables y cuándo se pueden paginar de nuevo.

Por ejemplo, el controlador de disco tolerante a errores proporcionado por el sistema admite la creación de conjuntos de reflejos, conjuntos de franjas y conjuntos de volúmenes. Sin embargo, una máquina determinada solo se puede configurar con un conjunto de reflejos, solo con un conjunto de franjas, solo con un conjunto de volúmenes o con cualquier combinación de estas tres opciones posibles. En estas circunstancias, el controlador ftdisk del sistema reduce el tamaño de su imagen cargada marcando rutinas que admiten explícitamente conjuntos de reflejo, franja y volumen que pertenecen a secciones de código paginables. Durante la inicialización del controlador, las secciones de código paginables solo se hacen residentes si el usuario ha configurado los discos para que tengan conjuntos de volúmenes, franjas o reflejos. Si el usuario vuelve a particionar los discos dinámicamente, el controlador ftdisk bloquea las secciones de código paginables adicionales necesarias para admitir cualquier conjunto de reflejo, franja o volumen que solicite el usuario.

Como otros ejemplos, los controladores serie y paralelos proporcionados por el sistema tienen DispatchCreate y DispatchClose rutinas a las que se llama cuando se abre un puerto determinado para E/S exclusiva y cuando se libera el controlador para un puerto abierto, respectivamente. Sin embargo, las solicitudes de E/S en serie y paralelas son esporádicas, determinadas por las aplicaciones que el usuario final está ejecutando actualmente y qué opciones de aplicación está realizando actualmente el usuario final. En estas circunstancias, los controladores serie y paralelo del sistema reducen los tamaños de sus imágenes cargadas marcando muchas rutinas como pertenecientes a una sección de códigos paginable que el DispatchCreate rutina hace residente solo cuando se abre el primer puerto para E/S.

Tenga en cuenta que cada uno de los controladores del sistema anteriores satisface ambos criterios para tener secciones paginables: el controlador tiene rutas de acceso de código que podrían no ser necesarias mientras se ejecuta el sistema y el controlador puede determinar exactamente cuándo se debe cargar su sección paginable y se puede volver a paginar.

Dado que es una operación costosa para bloquear una sección, si un controlador bloquea una sección de código paginable en más de un lugar, use MmLockPagableCodeSection para la primera solicitud. Realice solicitudes de bloqueo posteriores llamando a MmLockPagableSectionByHandle pasando el identificador devuelto por MmLockPagableCodeSection. El bloqueo por identificador mejora significativamente el rendimiento del controlador porque el administrador de memoria usa el valor devuelto opaco para localizar rápidamente la sección pertinente en lugar de buscar una lista de módulos cargada. Se desbloquea una sección bloqueada llamando a MmUnlockPagableImageSection.

Cada rutina de controlador dentro de una sección de código paginable debe marcarse con la siguiente directiva del compilador:

#pragma alloc_text(PAGExxxx, DriverRoutine)

donde xxxx es un identificador único opcional de cuatro caracteres para la sección paginable del autor de la llamada y driverRoutine es un punto de entrada que se incluirá en la sección de códigos paginables. La palabra clave PAGE y el sufijo determinado por el controlador, que puede tener hasta cuatro caracteres, distingue mayúsculas de minúsculas; es decir, PAGE debe estar en mayúsculas.

Una sola llamada a MmLockPagableCodeSection en, por ejemplo, el dispatchCreate rutina de un controlador, hace que toda la sección, que contenga todas las rutinas de controlador marcadas con la misma PAGEidentificador de xxxx, se bloqueen en el espacio del sistema.

Algunos tipos de rutinas de controlador no pueden formar parte de la sección paginable de ningún controlador, incluido lo siguiente:

  • Nunca se puede paginar un ISR. Es posible que un controlador de dispositivo reciba una interrupción falsa incluso si su dispositivo no está en uso, especialmente si el vector de interrupción se podría compartir. En general, incluso si un controlador puede deshabilitar explícitamente las interrupciones en su dispositivo, un ISR no se debe hacer paginable.

  • Nunca se puede paginar una rutina DPC si el controlador no puede controlar cuándo se pone en cola el DPC, como cualquier DpcForIsr o CustomDpc rutina que podría estar en cola desde un ISR. En general, las rutinas de controlador que se ejecutan en IRQL >= DISPATCH_LEVEL y que se pueden llamar en un contexto de subproceso arbitrario o en respuesta a un evento externo aleatorio no deben ser paginables.

  • Nunca haga que el DispatchRead o DispatchWrite rutina se pueda paginar en cualquier controlador que pueda formar parte de la ruta de acceso de E/S de paginación del sistema. El controlador de un disco que puede contener el archivo de página del sistema debe tener DispatchRead y dispatchWrite rutinas que residen mientras se ejecuta el sistema, como deben todos los controladores superpuestas por encima de este tipo de controlador de disco.

Tenga en cuenta que las rutinas de una sección paginable marcadas con la directiva del compilador #pragma alloc_text(PAGExxxx, ...) difieren de las rutinas marcadas con la directiva del compilador #pragma alloc_text(INIT, ...). Las rutinas de la sección INIT de no se pueden paginar y se descartan tan pronto como el controlador vuelva de su DriverEntry o su rutina Reinicializar, si tiene una.

El administrador de memoria mantiene un recuento de bloqueos interno en la sección paginable de cualquier controlador. Las llamadas a MmLockPagableCodeSection incrementan este recuento y el MmUnlockPagableImageSection disminuye el recuento. La sección paginable de un controlador no está disponible para paginarse a menos que este recuento sea cero.

Para obtener más información sobre cómo crear secciones de código paginables, vea Hacer que los controladores se puedan paginar.

Requisitos

Requisito Valor
de la plataforma de destino de Escritorio
encabezado de wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
biblioteca de NtosKrnl.lib
DLL de NtosKrnl.exe
irQL <=APC_LEVEL

Consulte también

MmLockPagableDataSection

mmLockPagableSectionByHandle

MmPageEntireDriver

MmResetDriverPaging

MmUnlockPagableImageSection