Coleções de objetos framework
Os drivers podem agrupar objetos de estrutura em coleções representadas por objetos de coleção de estruturas.
Por exemplo, se um driver receber um objeto de solicitação de estrutura que representa uma solicitação de E/S grande, o driver poderá precisar dividir a solicitação grande em solicitações menores que ele pode enviar para um destino de E/S. Para dividir uma solicitação grande em menores, o driver deve criar um conjunto de objetos de solicitação que representem as solicitações menores. Para acompanhar esses objetos de solicitação criados pelo driver, o driver pode criar um objeto de coleção e adicioná-los à coleção.
Normalmente, os objetos em uma coleção de objetos consistem em um único tipo de objeto de estrutura, mas um driver pode criar uma coleção que consiste em diferentes tipos de objetos.
Seu driver também pode criar uma coleção de coleções. Ou seja, uma coleção pode consistir em um conjunto de objetos de coleção.
Os drivers baseados em estrutura podem executar as seguintes operações em coleções de objetos:
Crie um objeto de coleção.
Para criar uma nova coleção, os drivers podem chamar WdfCollectionCreate.
Adicione um objeto a uma coleção.
Para adicionar objetos a uma coleção, os drivers podem chamar WdfCollectionAdd, uma ou mais vezes. Cada chamada para WdfCollectionAdd acrescenta um objeto ao final da coleção e incrementa a contagem de referência do objeto acrescentado.
Remover um objeto de uma coleção.
Para remover um objeto de uma coleção e diminuir sua contagem de referência, os drivers podem chamar WdfCollectionRemove ou WdfCollectionRemoveItem. Quando um objeto é removido, todos os objetos após o removido terão seu índice decrementado automaticamente.
Obtenha o número de objetos em uma coleção.
Para determinar o número de objetos que uma coleção contém, os drivers podem chamar WdfCollectionGetCount.
Obtenha um identificador para um objeto na coleção.
Se um driver chamar WdfCollectionGetItem, fornecendo um valor de índice como um argumento de entrada, o driver receberá um identificador para o objeto associado ao valor de índice. (Um valor de índice zero representa o primeiro objeto na coleção, um valor de índice de um representa o segundo objeto e assim por diante, como uma lista vinculada. Quando o driver remove o item i de uma coleção, o item i+1 se torna o item i.)
Os drivers também podem chamar WdfCollectionGetFirstItem ou WdfCollectionGetLastItem para obter um identificador para o primeiro ou último item que foi adicionado à coleção.
Bloquear uma coleção.
Um driver pode chamar WdfWaitLockAcquire para sincronizar o acesso a uma coleção em IRQL = PASSIVE_LEVEL ou pode chamar WdfSpinLockAcquire para sincronizar o acesso em IRQL = DISPATCH_LEVEL. Depois que um driver adquire um bloqueio, a coleção não pode ser acessada por outro código no driver que também chama WdfWaitLockAcquire ou WdfSpinLockAcquire. Depois de concluir uma operação na coleção, o driver deve chamar WdfWaitLockRelease.
Chamar WdfWaitLockAcquire ou WdfSpinLockAcquire não impedirá que outro código no driver acesse simultaneamente a coleção, se esse outro código também não chamar WdfWaitLockAcquire ou WdfSpinLockAcquire.
Exclua uma coleção.
Para excluir um objeto de coleção, os drivers podem chamar WdfObjectDelete. Normalmente, no entanto, os drivers especificam um objeto pai quando criam uma coleção e a estrutura exclui o objeto da coleção quando exclui o objeto pai.
Por exemplo, se um driver criar um conjunto de objetos de solicitação para que ele possa dividir uma solicitação de E/S grande em solicitações menores, ele poderá tornar o objeto de solicitação de solicitação de E/S grande o objeto pai do objeto da coleção. Eventualmente, o destino de E/S do driver chamará WdfRequestComplete para concluir as solicitações menores. Nesse ponto, o driver pode chamar WdfRequestComplete para a solicitação de E/S grande, fazendo com que a estrutura exclua o objeto de solicitação e seu objeto filho: o objeto da coleção.
Quando a estrutura exclui um objeto de coleção que contém objetos que não foram removidos, a estrutura remove os objetos da coleção e diminui suas contagens de referência, mas exclui apenas o objeto da coleção.
Às vezes, um driver deve examinar todos os objetos dentro de uma coleção. O exemplo de código a seguir demonstra essa situação:
WdfWaitLockAcquire(CollectionLockHandle, NULL);
ItemCount = WdfCollectionGetCount(CollectionHandle);
for (i=0; i<ItemCount; i++) {
ObjectHandle = WdfCollectionGetItem(CollectionHandle, i);
// 1. Call object-specific methods to obtain object properties.
// 2. Perform object-specific operations.
}
WdfWaitLockRelease(CollectionLockHandle);