Colecciones de objetos de marco

Los controladores pueden agrupar objetos de marco en colecciones representadas por objetos de colección de marcos.

Por ejemplo, si un controlador recibe un objeto de solicitud de marco que representa una solicitud de E/S grande, es posible que el controlador tenga que dividir la solicitud grande en solicitudes más pequeñas que puede enviar a un destino de E /S. Para dividir una solicitud grande en más pequeñas, el controlador debe crear un conjunto de objetos de solicitud que representen las solicitudes más pequeñas. Para realizar un seguimiento de estos objetos de solicitud creados por el controlador, el controlador puede crear un objeto de colección y agregarlos a la colección.

Normalmente, los objetos de una colección de objetos constan de un solo tipo de objeto de marco, pero un controlador puede crear una colección que consta de distintos tipos de objetos.

El controlador también puede crear una colección de colecciones. Es decir, una colección puede constar de un conjunto de objetos de colección.

Los controladores basados en framework pueden realizar las siguientes operaciones en colecciones de objetos:

  • Cree un objeto de colección.

    Para crear una nueva colección, los controladores pueden llamar a WdfCollectionCreate.

  • Agregue un objeto a una colección.

    Para agregar objetos a una colección, los controladores pueden llamar a WdfCollectionAdd, una o varias veces. Cada llamada a WdfCollectionAdd anexa un objeto al final de la colección e incrementa el recuento de referencias del objeto anexado.

  • Quitar un objeto de una colección.

    Para quitar un objeto de una colección y disminuir su recuento de referencias, los controladores pueden llamar a WdfCollectionRemove o WdfCollectionRemoveItem. Cuando se quita un objeto, todos los objetos después de quitar uno tendrán su índice reducido automáticamente.

  • Obtenga el número de objetos de una colección.

    Para determinar el número de objetos que contiene una colección, los controladores pueden llamar a WdfCollectionGetCount.

  • Obtenga un identificador para un objeto de la colección.

    Si un controlador llama a WdfCollectionGetItem, proporcionando un valor de índice como argumento de entrada, el controlador recibe un identificador para el objeto asociado al valor de índice. (Un valor de índice de cero representa el primer objeto de la colección, un valor de índice de uno representa el segundo objeto y así sucesivamente una lista vinculada. Cuando el controlador quita el elemento i de una colección, el elemento i+1 se convierte en el elemento i.)

    Los controladores también pueden llamar a WdfCollectionGetFirstItem o WdfCollectionGetLastItem para obtener un identificador al primer o último elemento que se agregó a la colección.

  • Bloquear una colección.

    Un controlador puede llamar a WdfWaitLockAcquire para sincronizar el acceso a una colección en IRQL = PASSIVE_LEVEL, o puede llamar a WdfSpinLockAcquire sincronizar el acceso en IRQL = DISPATCH_LEVEL. Una vez que un controlador adquiere un bloqueo, no se puede acceder a la colección mediante otro código del controlador que también llama a WdfWaitLockAcquire o WdfSpinLockAcquire. Después de completar una operación en la colección, el controlador debe llamar a WdfWaitLockRelease.

    Llamar a WdfWaitLockAcquire o WdfSpinLockAcquire no impide que otro código del controlador acceda simultáneamente a la colección, si ese otro código tampoco llama a WdfWaitLockAcquire o WdfSpinLockAcquire.

  • Elimina una colección.

    Para eliminar un objeto de colección, los controladores pueden llamar a WdfObjectDelete. Sin embargo, normalmente, los controladores especifican un objeto primario cuando crean una colección y el marco elimina el objeto de colección cuando elimina el objeto primario.

    Por ejemplo, si un controlador crea un conjunto de objetos de solicitud para que pueda dividir una solicitud de E/S grande en solicitudes más pequeñas, puede hacer que el objeto de solicitud de solicitud de E/S grande sea el objeto primario del objeto de colección. Finalmente, el destino de E/S del controlador llamará a WdfRequestComplete para completar las solicitudes más pequeñas. En ese momento, el controlador puede llamar a WdfRequestComplete para la solicitud de E/S grande, lo que hace que el marco elimine el objeto de solicitud y su objeto secundario: el objeto de colección.

    Cuando el marco elimina un objeto de colección que contiene objetos que no se han quitado, el marco quita los objetos de la colección y disminuye sus recuentos de referencias, pero elimina solo el objeto de colección.

A veces, un controlador debe examinar todos los objetos de una colección. En el ejemplo de código siguiente se muestra esta situación:

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