Usando buffers de memória

Os drivers normalmente usam buffers de memória para passar dados de e para a estrutura e outros drivers ou para armazenar informações localmente. Este tópico descreve objetos de memória da estrutura, listas lookaside, MDLs e buffers locais.

Usando objetos de memória da estrutura

A estrutura usa objetos de memória para descrever os buffers de memória que um driver recebe e passa para a estrutura. Cada objeto de memória da estrutura representa um buffer.

Para criar um objeto de memória, o driver chama um dos seguintes métodos de objeto:

Para obter um objeto de memória que representa os buffers de uma solicitação de E/S recebida, o driver chama WdfRequestRetrieveInputMemory e WdfRequestRetrieveOutputMemory. Para obter mais informações sobre como recuperar buffers de uma solicitação de E/S, consulte Acessando buffers de dados em drivers de Framework-Based.

Para obter o endereço e o tamanho do buffer de um objeto de memória, o driver chama WdfMemoryGetBuffer.

Para mover dados para dentro ou para fora do buffer de um objeto de memória, o driver chama WdfMemoryCopyFromBuffer ou WdfMemoryCopyToBuffer. Esses métodos de objeto verificam os tamanhos de origem e destino e impedem erros de estouro de buffer.

Se o driver criar um objeto de memória chamando WdfMemoryCreatePreallocated, ele poderá atribuir posteriormente um buffer diferente ao objeto de memória chamando WdfMemoryAssignBuffer.

Quando um driver envia uma solicitação de E/S para um destino de E/S, ele normalmente passa um buffer de entrada ou saída para um método de objeto de destino de E/S de estrutura. O driver especifica o buffer passando uma estrutura WDF_MEMORY_DESCRIPTOR que descreve o buffer ou passando um identificador de objeto de memória. (Métodos de objeto de destino de E/S que enviam solicitações de E/S de forma síncrona exigem uma estrutura WDF_MEMORY_DESCRIPTOR e métodos que enviam solicitações de E/S exigem de forma assíncrona um identificador de objeto de memória.)

Para obter informações sobre quando um buffer de memória é válido, consulte Ciclo de Vida do Buffer de Memória.

Usando listas lookaside

Se o driver exigir muitos buffers de aproximadamente o mesmo tamanho, ele deverá alocá-los de uma lista lookaside. O driver cria uma lista lookaside chamando WdfLookasideListCreate. Posteriormente, o driver pode obter buffers da lista lookaside chamando WdfMemoryCreateFromLookaside.

Cada vez que o driver chama WdfMemoryCreateFromLookaside, a estrutura cria um objeto de memória, obtém um buffer da lista lookaside e atribui o buffer ao objeto . Quando o driver terminar de usar um desses objetos de memória, ele chamará WdfObjectDelete, que exclui o objeto de memória e retorna o espaço de buffer para a lista lookaside.

O sistema operacional gerencia os recursos de memória atribuídos à lista lookaside. Se o driver solicitar um buffer da lista lookaside quando nenhum estiver disponível, como na primeira vez que o driver chamar WdfMemoryCreateFromLookaside, o sistema alocará um buffer e o atribuirá à lista. Quando o driver chama WdfObjectDelete (e o espaço em buffer é retornado para a lista lookaside), o sistema mantém o buffer agora não atribuído na lista até que o driver precise dele novamente. O sistema aumenta o tamanho da lista conforme necessário; por exemplo, os drivers que solicitam buffers com mais frequência recebem listas lookaside maiores. Por outro lado, o sistema poderá reduzir o número de buffers na lista se o driver não estiver usando todos eles.

Usando MDLs

Alguns drivers usam MDLs (listas de descritores de memória) para descrever buffers. Por exemplo, um driver para um dispositivo de DMA (acesso direto à memória) deve passar um MDL para o método WdfDmaTransactionInitialize , se ele chamar esse método.

Um driver que usa MDLs pode obter um MDL que representa os buffers de uma solicitação de E/S recebida chamando WdfRequestRetrieveInputWdmMdl e WdfRequestRetrieveOutputWdmMdl.

A maioria dos drivers baseados em estrutura não usa MDLs.

Alocando buffers locais

Um driver que requer espaço de buffer interno local que ele não passará para a estrutura não precisa criar objetos de memória para representar os buffers. O driver pode chamar ExAllocatePoolWithTag para alocar buffers internos. Quando o driver terminar de usar o buffer, ele deverá chamar ExFreePoolWithTag.

No entanto, os drivers também podem usar objetos de memória para buffers locais. Uma vantagem de usar buffers de memória, em vez de chamar ExAllocatePoolWithTag, é que a estrutura exclui automaticamente objetos de memória e seus buffers quando o objeto pai de cada objeto é excluído.

Importante

Os DDIs exAllocatePool discutidos neste tópico foram preteridos em Windows 10, versão 2004 e foram substituídos por ExAllocatePool2 e ExAllocatePool3. Para obter mais informações, consulte Atualizando chamadas de ExAllocatePool preteridas para ExAllocatePool2 e ExAllocatePool3.

Alinhando buffers

O driver pode usar a função WDF_ALIGN_SIZE_UP ou WDF_ALIGN_SIZE_DOWN para calcular um tamanho de buffer alinhado a um deslocamento de alinhamento especificado. Esse cálculo será útil se o driver precisar alocar vários buffers contíguos, se cada buffer precisar começar em um limite de alinhamento de endereço.