Função MmGetSystemAddressForMdlSafe (wdm.h)
A macro MmGetSystemAddressForMdlSafe retorna um endereço virtual de espaço do sistema nãopagado para o buffer que o MDL especificado descreve.
Sintaxe
PVOID MmGetSystemAddressForMdlSafe(
[in] PMDL Mdl,
[in] ULONG Priority
);
Parâmetros
[in] Mdl
Ponteiro para um buffer cujo endereço virtual base correspondente deve ser mapeado.
[in] Priority
Especifica um valor MM_PAGE_PRIORITY que indica a importância do sucesso em condições de PTE de baixa disponibilidade. Especifique um valor de prioridade de LowPagePriority, NormalPagePriority ou HighPagePriority. Começando com Windows 8, o valor de prioridade especificado pode ser bit a bit-ORed com os sinalizadores MdlMappingNoWrite ou MdlMappingNoExecute.
LowPagePriority indica que a solicitação de mapeamento pode falhar se o sistema estiver bastante baixo em recursos. Um exemplo dessa situação é uma conexão de rede não crítica em que o driver pode lidar com a falha de mapeamento.
NormalPagePriority indica que a solicitação de mapeamento pode falhar se o sistema for muito baixo em recursos. Um exemplo dessa situação é uma solicitação não crítica do sistema de arquivos local.
HighPagePriority indica que a solicitação de mapeamento não deve falhar, a menos que o sistema esteja completamente sem recursos. Um exemplo dessa situação é o caminho do arquivo de paginação em um driver.
MdlMappingNoWrite indica que as páginas físicas mapeadas devem ser configuradas como memória sem gravação (somente leitura). Começando com Windows 8, esse bit de sinalizador pode ser bit a bit ORed com o valor MM_PAGE_PRIORITY para especificar a memória na qual as gravações estão desabilitadas.
MdlMappingNoExecute indica que as páginas físicas mapeadas devem ser configuradas como memória sem execução. Começando com Windows 8, esse bit de sinalizador pode ser bit a bit ORed com o valor MM_PAGE_PRIORITY para especificar a memória na qual a execução da instrução está desabilitada. Como prática recomendada, os drivers gravados para Windows 8 e versões posteriores do Windows sempre devem especificar memória sem execução, a menos que a memória executável seja explicitamente necessária.
Retornar valor
MmGetSystemAddressForMdlSafe retorna o endereço virtual de espaço do sistema base que mapeia as páginas físicas que o MDL especificado descreve. Se as páginas ainda não estiverem mapeadas para o espaço de endereço do sistema e a tentativa de mapeá-las falhar, NULL será retornado.
Comentários
Essa rotina mapeia as páginas físicas descritas pelo MDL especificado para o espaço de endereço do sistema, se elas ainda não estiverem mapeadas para o espaço de endereço do sistema.
Drivers de dispositivos de E/S programados (PIO) chamam essa rotina para mapear um buffer do modo de usuário, que é descrito pelo MDL em Irp-MdlAddress> e que já está mapeado para um intervalo de endereços virtuais no modo de usuário, para um intervalo no espaço de endereço do sistema.
Ao entrar nessa rotina, o MDL especificado deve descrever páginas físicas bloqueadas. Um MDL bloqueado pode ser criado usando a rotina MmProbeAndLockPages, MmBuildMdlForNonPagedPool, IoBuildPartialMdl ou MmAllocatePagesForMdlEx .
Quando o mapeamento de espaço de endereço do sistema retornado por MmGetSystemAddressForMdlSafe não for mais necessário, ele deverá ser liberado. As etapas necessárias para liberar o mapeamento dependem de como o MDL foi criado. Estes são os quatro casos possíveis:
Se o MDL foi criado por uma chamada para a rotina MmProbeAndLockPages , não é necessário liberar explicitamente o mapeamento de espaço de endereço do sistema. Em vez disso, uma chamada para a rotina MmUnlockPages libera o mapeamento, se um foi alocado.
Se o MDL foi criado por uma chamada para a rotina MmBuildMdlForNonPagedPool , MmGetSystemAddressForMdlSafe reutilizará o mapeamento de espaço de endereço do sistema existente em vez de criar um novo. Nesse caso, nenhuma limpeza é necessária (ou seja, desbloqueio e desmapeamento não são necessários).
Se o MDL foi criado por uma chamada para a rotina IoBuildPartialMdl , o driver deverá chamar a rotina MmPrepareMdlForReuse ou a rotina IoFreeMdl para liberar o mapeamento de espaço de endereço do sistema.
Se o MDL foi criado por uma chamada para a rotina MmAllocatePagesForMdlEx , o driver deverá chamar a rotina MmUnmapLockedPages para liberar o mapeamento de espaço de endereço do sistema. Se MmGetSystemAddressForMdlSafe for chamado mais de uma vez para um MDL, as chamadas subsequentes de MmGetSystemAddressForMdlSafe simplesmente retornarão o mapeamento criado pela primeira chamada. Uma chamada para MmUnmapLockedPages é suficiente para liberar esse mapeamento.
A partir do Windows 7 e do Windows Server 2008 R2, não é necessário chamar explicitamente MmUnmapLockedPages para um MDL criado por MmAllocatePagesForMdlEx. Em vez disso, uma chamada para a rotina MmFreePagesFromMdl libera o mapeamento system-address-space, se um foi alocado.
Para criar um novo mapeamento de espaço de endereço do sistema, MmGetSystemAddressForMdlSafe chama MmMapLockedPagesSpecifyCache com o parâmetro CacheType definido como MmCached. Um driver que requer um tipo de cache diferente de MmCached deve chamar MmMapLockedPagesSpecifyCache diretamente em vez de chamar MmGetSystemAddressForMdlSafe. Para obter mais informações sobre o parâmetro CacheType , consulte MmMapLockedPagesSpecifyCache.
Em uma chamada para MmMapLockedPagesSpecifyCache, o tipo de cache especificado será usado somente se as páginas descritas pelo MDL ainda não tiverem um tipo de cache associado a elas. No entanto, em quase todos os casos, as páginas já têm um tipo de cache associado e esse tipo de cache é usado pelo novo mapeamento. Uma exceção a essa regra é para páginas alocadas por MmAllocatePagesForMdl, que define o tipo de cache como MmCached , independentemente do tipo de cache original das páginas.
Apenas um thread de cada vez pode chamar MmGetSystemAddressForMdlSafe com segurança para um determinado MDL, pois essa rotina pressupõe que o thread de chamada possui o MDL. No entanto, MmGetSystemAddressForMdlSafe pode ser chamado mais de uma vez para o mesmo MDL fazendo todas as chamadas do mesmo thread ou, se as chamadas forem de vários threads, sincronizando explicitamente as chamadas.
Se um driver precisar dividir uma solicitação em solicitações menores, o driver poderá alocar MDLs adicionais ou o driver poderá usar a rotina IoBuildPartialMdl .
O endereço base retornado tem o mesmo deslocamento que o endereço virtual no MDL.
O Windows 98 não dá suporte a MmGetSystemAddressForMdlSafe. Em vez disso, use MmGetSystemAddressForMdl .
Como essa macro chama MmMapLockedPagesSpecifyCache, usá-la pode exigir vinculação a NtosKrnl.lib.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Windows 2000 |
Cabeçalho | wdm.h |
IRQL | <= DISPATCH_LEVEL |
Regras de conformidade de DDI | MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf) |