Collections d’objets Framework

Les pilotes peuvent regrouper des objets d’infrastructure dans des collections qui sont représentées par des objets de collection d’infrastructure.

Par exemple, si un pilote reçoit un objet de demande d’infrastructure qui représente une demande d’E/S volumineuse, il peut être amené à diviser la demande volumineuse en demandes plus petites qu’il peut envoyer à une cible d’E/S. Pour diviser une demande volumineuse en requêtes plus petites, le pilote doit créer un ensemble d’objets de requête qui représentent les demandes plus petites. Pour suivre ces objets de requête créés par le pilote, le pilote peut créer un objet de collection et les ajouter à la collection.

En règle générale, les objets d’une collection d’objets se composent d’un seul type d’objet framework, mais un pilote peut créer une collection qui se compose de différents types d’objets.

Votre pilote peut également créer une collection de collections. Autrement dit, une collection peut se composer d’un ensemble d’objets de collection.

Les pilotes basés sur l’infrastructure peuvent effectuer les opérations suivantes sur les collections d’objets :

  • Créez un objet de collection.

    Pour créer une collection, les pilotes peuvent appeler WdfCollectionCreate.

  • Ajouter un objet à une collection.

    Pour ajouter des objets à une collection, les pilotes peuvent appeler WdfCollectionAdd une ou plusieurs fois. Chaque appel à WdfCollectionAdd ajoute un objet à la fin de la collection et incrémente le nombre de références de l’objet ajouté.

  • Supprimer un objet d’une collection.

    Pour supprimer un objet d’une collection et décrémenter son nombre de références, les pilotes peuvent appeler WdfCollectionRemove Ou WdfCollectionRemoveItem. Lorsqu’un objet est supprimé, tous les objets après l’objet supprimé ont leur index automatiquement décrémenté.

  • Obtenir le nombre d’objets d’une collection.

    Pour déterminer le nombre d’objets qu’une collection contient, les pilotes peuvent appeler WdfCollectionGetCount.

  • Obtenir un handle pour un objet de la collection.

    Si un pilote appelle WdfCollectionGetItem, en fournissant une valeur d’index en tant qu’argument d’entrée, le pilote reçoit un handle à l’objet associé à la valeur d’index. (Une valeur d’index de zéro représente le premier objet de la collection, une valeur d’index d’un représente le deuxième objet, et ainsi de suite, comme une liste liée. Lorsque le pilote supprime l’élément i d’une collection, l’élément i+1 devient l’élément i.)

    Les pilotes peuvent également appeler WdfCollectionGetFirstItem ou WdfCollectionGetLastItem pour obtenir un handle pour le premier ou le dernier élément ajouté à la collection.

  • Verrouillez une collection.

    Un pilote peut appeler WdfWaitLockAcquire pour synchroniser l’accès à une collection à l’adresse IRQL = PASSIVE_LEVEL, ou appeler l’accès de synchronisation WdfSpinLockAcquire à l’adresse IRQL = DISPATCH_LEVEL. Une fois qu’un pilote a acquis un verrou, la collection n’est pas accessible par un autre code dans le pilote qui appelle également WdfWaitLockAcquire ou WdfSpinLockAcquire. Après avoir terminé une opération sur la collection, le pilote doit appeler WdfWaitLockRelease.

    L’appel de WdfWaitLockAcquire ou WdfSpinLockAcquire n’empêche pas d’autres codes du pilote d’accéder simultanément à la collection, si cet autre code n’appelle pas également WdfWaitLockAcquire ou WdfSpinLockAcquire.

  • Supprimer une collection.

    Pour supprimer un objet de collection, les pilotes peuvent appeler WdfObjectDelete. Plus généralement, toutefois, les pilotes spécifient un objet parent lorsqu’ils créent une collection, et l’infrastructure supprime l’objet de collection lorsqu’il supprime l’objet parent.

    Par exemple, si un pilote crée un ensemble d’objets de requête afin de pouvoir diviser une demande d’E/S volumineuse en demandes plus petites, il peut faire de l’objet de requête de la demande d’E/S volumineuse l’objet parent de l’objet de collection. Finalement, la cible d’E/S du pilote appelle WdfRequestComplete pour effectuer les demandes plus petites. À ce stade, le pilote peut appeler WdfRequestComplete pour la demande d’E/S volumineuse, ce qui entraîne la suppression de l’objet de requête et de son objet enfant : l’objet de collection.

    Lorsque l’infrastructure supprime un objet de collection qui contient des objets qui n’ont pas été supprimés, l’infrastructure supprime les objets de la collection et décrémente leur nombre de références, mais supprime uniquement l’objet de collection.

Parfois, un pilote doit examiner tous les objets d’une collection. L’exemple de code suivant illustre cette situation :

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);