Partilhar via


Macro MmLockPagableCodeSection (wdm.h)

A rotina MmLockPagableCodeSection bloqueia uma seção do código do driver, contendo um conjunto de rotinas de driver marcadas com uma diretiva de compilador especial, no espaço do sistema.

Sintaxe

void MmLockPagableCodeSection(
  [in]  Address
);

Parâmetros

[in] Address

Especifica um endereço simbólico. Esse endereço normalmente é o nome de uma função de driver dentro de uma seção do código do driver que foi marcada com algo como #pragma alloc_text (PAGExxxx, driverfunction). Todas as funções na seção PAGExxxx serão bloqueadas quando essa função retornar.

Valor de retorno

Nenhum

Observações

MmLockPagableCodeSection retorna um valor opaco que o sistema operacional usa para identificar esta seção do código do driver. Esse valor opaco pode ser passado posteriormente para MmLockPagableSectionByHandle (se o driver desbloquear e, posteriormente, retravar a seção) ou para MmUnlockPagableImageSection.

A rotina MmLockPagableCodeSection e MmUnlockPagableImageSection (a rotina que executa a ação oposta) dão suporte a drivers que podem fazer o seguinte:

  • Adiar o carregamento de um subconjunto de rotinas de driver na memória residente até que as solicitações de E/S de entrada para os dispositivos do driver tornem necessário que essas rotinas processem IRPs.

  • Disponibilize o mesmo subconjunto de rotinas de driver para paginação quando eles tiverem concluído o processamento de solicitações de E/S e nenhuma solicitação adicional para os dispositivos do driver são esperadas no momento.

MmLockPagableCodeSection, MmLockPagableSectionByHandle e MmUnlockPagableImageSection destinam-se ao uso por drivers intermediários e de dispositivo que têm as seguintes características:

  • O driver tem caminhos de código que podem não ser necessários enquanto o sistema está em execução, mas, se forem necessários, o código do driver deve ser residente porque ele é executado em um contexto de thread arbitrário ou em IRQL >= DISPATCH_LEVEL.

  • O driver pode determinar exatamente quando as rotinas pagináveis devem ser carregadas e quando elas podem ser excluídas novamente.

Por exemplo, o driver de disco tolerante a falhas fornecido pelo sistema dá suporte à criação de conjuntos de espelhos, conjuntos de distribuição e conjuntos de volumes. No entanto, um computador específico pode ser configurado apenas com um conjunto de espelhos, apenas com um conjunto de distribuição, apenas com um conjunto de volumes ou com qualquer combinação dessas três opções possíveis. Nessas circunstâncias, o driver ftdisk do sistema reduz o tamanho de sua imagem carregada marcando rotinas que dão suporte explicitamente a conjuntos de espelhos, listras e volumes como pertencentes a seções de código pagináveis. Durante a inicialização do driver, as seções de código pagináveis só serão residentes se o usuário tiver configurado os discos para ter conjuntos de espelho, distribuição ou volume. Se o usuário reparticionar os discos dinamicamente, o driver ftdisk bloqueará quaisquer seções de código pagináveis adicionais necessárias para dar suporte a qualquer espelho, faixa ou conjuntos de volumes que o usuário solicitar.

Como outros exemplos, os drivers paralelos e serial fornecidos pelo sistema têm DispatchCreate e DispatchClose rotinas que são chamadas quando uma porta específica é aberta para E/S exclusiva e quando o identificador de uma porta aberta é liberado, respectivamente. No entanto, as solicitações de E/S serial e paralelas são esporádicas, determinadas por quais aplicativos o usuário final está executando no momento e quais opções de aplicativo o usuário final está se exercitando no momento. Nessas circunstâncias, os drivers serial e paralelos do sistema reduzem os tamanhos de suas imagens carregadas marcando muitas rotinas como pertencentes a uma seção de código paginável que o DispatchCreate rotina faz residente somente quando a primeira porta é aberta para E/S.

Observe que cada um dos drivers do sistema anterior atende a ambos os critérios para ter seções pagináveis: o driver tem caminhos de código que podem não ser necessários enquanto o sistema está em execução, e o driver pode determinar exatamente quando sua seção paginável deve ser carregada e pode ser paginada novamente.

Como é uma operação cara para bloquear uma seção, se um driver bloquear uma seção de código paginável em mais de um lugar, use MmLockPagableCodeSection para a primeira solicitação. Faça solicitações de bloqueio subsequentes chamando MmLockPagableSectionByHandle passando o identificador retornado por MmLockPagableCodeSection. O bloqueio por identificador melhora significativamente o desempenho do driver porque o gerenciador de memória usa o valor de retorno opaco para localizar rapidamente a seção relevante em vez de pesquisar uma lista de módulos carregada. Uma seção bloqueada é desbloqueada chamando MmUnlockPagableImageSection.

Cada rotina de driver em uma seção de código paginável deve ser marcada com a seguinte diretiva do compilador:

#pragma alloc_text(PAGExxxx, DriverRoutine)

em que xxxx é um identificador exclusivo opcional de quatro caracteres para a seção paginável do chamador e driverroutine é um ponto de entrada a ser incluído na seção de código pageable. A palavra-chave PAGE e o sufixo determinado pelo driver, que pode ter até quatro caracteres, diferenciam maiúsculas de minúsculas; ou seja, page deve ser maiúscula.

Uma única chamada para MmLockPagableCodeSection, por exemplo, a rotina de dispatchCreate de de um driver, faz com que toda a seção, contendo todas as rotinas de driver marcadas com o mesmo PAGExxxx identificador, seja bloqueada no espaço do sistema.

Determinados tipos de rotinas de driver não podem fazer parte da seção paginável de qualquer driver, incluindo o seguinte:

  • Nunca torne um ISR paginável. É possível que um driver de dispositivo receba uma interrupção espúria mesmo que seu dispositivo não esteja em uso, especialmente se o vetor de interrupção puder ser compartilhado. Em geral, mesmo que um driver possa desabilitar explicitamente as interrupções em seu dispositivo, um ISR não deverá ser tornado paginável.

  • Nunca torne uma rotina DPC paginável se o driver não puder controlar quando o DPC estiver na fila, como qualquer DpcForIsr ou rotina de CustomDpc que possa ser enfileirada de um ISR. Em geral, as rotinas de driver que são executadas no IRQL >= DISPATCH_LEVEL e que podem ser chamadas em um contexto de thread arbitrário ou em resposta a um evento externo aleatório não devem ser tornadas pagináveis.

  • Nunca torne a rotina de DispatchRead ou DispatchWrite paginável em qualquer driver que possa fazer parte do caminho de E/S de paginação do sistema. O driver de um disco que pode conter o arquivo de página do sistema deve ter DispatchRead e DispatchWrite rotinas residentes enquanto o sistema está em execução, assim como todos os drivers em camadas acima desse driver de disco.

Observe que as rotinas em uma seção paginável marcada com a diretiva do compilador #pragma alloc_text(PAGExxxx, ...) diferem das rotinas marcadas com a diretiva do compilador #pragma alloc_text(INIT, ...). As rotinas na seção INIT do não são pagináveis e são descartadas assim que o driver retorna de sua driverEntry ou sua rotina Reinicializar, se tiver uma.

O gerenciador de memória mantém uma contagem de bloqueio interno na seção paginável de qualquer driver. Chamadas para MmLockPagableCodeSection incrementam essa contagem e o recíproco MmUnlockPagableImageSection diminui a contagem. A seção paginável de um driver não está disponível para ser excluída, a menos que essa contagem seja zero.

Para obter mais informações sobre como criar seções de código pagináveis, consulte Tornando os drivers pagináveis.

Requisitos

Requisito Valor
da Plataforma de Destino Área de trabalho
cabeçalho wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
biblioteca NtosKrnl.lib
de DLL NtosKrnl.exe
IRQL <=APC_LEVEL

Consulte também

MmLockPagableDataSection

MmLockPagableSectionByHandle

MmPageEntireDriver

MmResetDriverPaging

MmUnlockPagableImageSection