Compartir a través de


Macro MmLockPagableCodeSection (wdm.h)

La rutina MmLockPagableCodeSection 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 se bloquean cuando se devuelve esta función.

Valor devuelto

None

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) admiten controladores que pueden hacer lo siguiente:

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

  • Haga que el mismo subconjunto de rutinas de controlador estén disponibles 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 de dispositivo 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 reflejados, conjuntos de franjas y conjuntos de volúmenes. Sin embargo, una máquina determinada solo se puede configurar con un conjunto reflejado, 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 como pertenecientes a secciones de código paginables. Durante la inicialización del controlador, las secciones de código paginables se convierten en residentes solo 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 el usuario solicite.

Como otros ejemplos, los controladores serie y paralelos proporcionados por el sistema tienen rutinas DispatchCreate y DispatchClose a las que se llama cuando se abre un puerto determinado para E/S exclusiva y cuando se libera el identificador de 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ódigo paginable que la rutina DispatchCreate hace residente solo cuando se abre el primer puerto para E/S.

Tenga en cuenta que cada uno de los controladores del sistema anteriores cumple 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ódigo paginable. La palabra clave PAGE y el sufijo determinado por el controlador, que puede tener hasta cuatro caracteres, distinguen mayúsculas de minúsculas; es decir, PAGE debe escribirse en mayúsculas.

Una sola llamada a MmLockPagableCodeSection en, por ejemplo, la rutina DispatchCreate de un controlador, hace que toda la sección, que contenga todas las rutinas de controlador marcadas con el mismo identificador PAGExxxx , 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, incluidos los siguientes:

  • Nunca haga que un ISR sea paginable. 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 podría compartirse. En general, incluso si un controlador puede deshabilitar explícitamente las interrupciones en su dispositivo, no se debe crear una ISR paginable.

  • Nunca haga que una rutina DPC sea paginable si el controlador no puede controlar cuándo se pone en cola el DPC, como cualquier rutina DpcForIsr o CustomDpc que se pueda poner 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 la rutina DispatchRead o DispatchWrite 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 rutinas DispatchRead y DispatchWrite residentes mientras se ejecuta el sistema, como deben todos los controladores superpuestas por encima de este 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 no se pueden paginar y se descartan en cuanto el controlador vuelve de su driverEntry o su rutina Reinitialize , 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 la mmUnlockPagableImageSection recíproca 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 sean paginables.

Requisitos

Requisito Value
Plataforma de destino Escritorio
Encabezado wdm.h (incluya Wdm.h, Ntddk.h, Ntifs.h)
Library NtosKrnl.lib
Archivo DLL NtosKrnl.exe
IRQL <=APC_LEVEL

Consulte también

MmLockPagableDataSection

MmLockPagableSectionByHandle

MmPageEntireDriver

MmResetDriverPaging

MmUnlockPagableImageSection