Função MmGetSystemAddressForMdlSafe (wdm.h)
A macro MmGetSystemAddressForMdlSafe retorna um endereço virtual de espaço no 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, NormalPagePriorityou HighPagePriority. A partir do 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 estiver muito com poucos 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). A partir do 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. A partir do 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 o 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.
Valor de retorno
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.
Observações
Essa rotina mapeia as páginas físicas descritas pelo MDL especificado no espaço de endereço do sistema, caso ainda não estejam 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 de 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 o MmProbeAndLockPages, MmBuildMdlForNonPagedPool, IoBuildPartialMdlou rotina de MmAllocatePagesForMdlEx.
Quando o mapeamento de espaço de endereço do sistema retornado pelo 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 o MmUnlockPages rotina libera o mapeamento, se um foi alocado.
Se o MDL foi criado por uma chamada para a rotina de 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 rotinaIoFreeMdl para liberar o mapeamento de espaço-endereço do sistema.
Se o MDL foi criado por uma chamada para a rotina de MmAllocatePagesForMdlEx, o driver deverá chamar o MmUnmapLockedPages rotina 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 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 o MmFreePagesFromMdl rotina libera o mapeamento de espaço de endereço do sistema, se um foi alocado.
Para criar um novo mapeamento de espaço de endereço do sistema, chamadas mmGetSystemAddressForMdlSafe 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 com segurança MmGetSystemAddressForMdlSafe para um determinado MDL, pois essa rotina pressupõe que o thread de chamada é proprietário do 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 o rotina de 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. Use MmGetSystemAddressForMdl.
Como essa macro chama MmMapLockedPagesSpecifyCache, usá-la pode exigir vinculação a NtosKrnl.lib.
Requisitos
Requisito | Valor |
---|---|
de cliente com suporte mínimo | Windows 2000 |
cabeçalho | wdm.h |
IRQL | <= DISPATCH_LEVEL |
regras de conformidade de DDI | MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf) |