Коллекции объектов Framework
Драйверы могут группировать объекты платформы в коллекции, представленные объектами коллекции фреймворка .
Например, если драйвер получает объект запроса платформы, представляющий большой запрос ввода-вывода, драйвер может разбить большой запрос на небольшие запросы, которые он может отправлять в целевой объект ввода-вывода . Чтобы разбить большой запрос на меньшие, драйвер должен создать набор объектов запроса, представляющих меньшие запросы. Для отслеживания этих объектов запроса, созданных драйвером, драйвер может создать объект коллекции и добавить их в коллекцию.
Как правило, объекты в коллекции объектов состоят из одного типа объекта платформы, но драйвер может создать коллекцию, состоящую из различных типов объектов.
Драйвер также может создать коллекцию коллекций. То есть коллекция может состоять из набора объектов коллекции.
Драйверы на основе платформы могут выполнять следующие операции с коллекциями объектов:
Создайте объект коллекции.
Чтобы создать новую коллекцию, драйверы могут вызывать WdfCollectionCreate.
Добавьте объект в коллекцию.
Чтобы добавить объекты в коллекцию, драйверы могут вызывать WdfCollectionAddодин или несколько раз. Каждый вызов WdfCollectionAdd добавляет объект к концу коллекции и увеличивает число ссылок добавленного объекта.
Удаление объекта из коллекции.
Для удаления объекта из коллекции и уменьшения его количества ссылок драйверы могут вызывать WdfCollectionRemove или WdfCollectionRemoveItem. При удалении объекта индексы всех последующих объектов будут автоматически уменьшаться на единицу.
Получите количество объектов в коллекции.
Чтобы определить количество объектов, содержащих коллекцию, драйверы могут вызывать WdfCollectionGetCount.
Получите дескриптор для объекта из коллекции.
Если драйвер вызывает WdfCollectionGetItem, предоставляя значение индекса в качестве входного аргумента, он получает дескриптор объекта, связанного с этим значением индекса. (Значение индекса нуля представляет первый объект в коллекции, значение индекса одного представляет второй объект и т. д., например связанный список. Когда драйвер удаляет элемент i из коллекции, элемент i+1 становится элементом i.)
Драйверы также могут вызывать WdfCollectionGetFirstItem или WdfCollectionGetLastItem для получения дескриптора первого или последнего элемента, добавленного в коллекцию.
Блокировка коллекции.
Драйвер может вызывать WdfWaitLockAcquire для синхронизации доступа к коллекции в IRQL = PASSIVE_LEVEL, или вызывать WdfSpinLockAcquire для синхронизации доступа в IRQL = DISPATCH_LEVEL. После получения блокировки драйвер не может получить доступ к коллекции другим кодом в драйвере, который также вызывает WdfWaitLockAcquire или WdfSpinLockAcquire. После завершения операции с коллекцией драйвер должен вызвать WdfWaitLockRelease.
Вызов WdfWaitLockAcquire или WdfSpinLockAcquire не предотвращает одновременный доступ к коллекции другим кодом, если другой код не вызывает WdfWaitLockAcquire или WdfSpinLockAcquire.
Удалите коллекцию.
Чтобы удалить объект коллекции, драйверы могут вызывать WdfObjectDelete. Однако, как правило, драйверы указывают родительский объект при создании коллекции, а платформа удаляет объект коллекции при удалении родительского объекта.
Например, если драйвер создает набор объектов запроса, чтобы он смог разбить большой запрос ввода-вывода на небольшие запросы, он может сделать большой объект запроса ввода-вывода родительским объектом объекта коллекции. В конечном итоге целевой объект I/O драйвера вызовет WdfRequestComplete для выполнения небольших запросов. На этом этапе драйвер может вызывать WdfRequestComplete для большого запроса ввода-вывода, что приводит к удалению объекта запроса и его дочернего объекта: объекта коллекции.
Когда платформа удаляет объект коллекции, содержащий объекты, которые не были удалены, платформа удаляет объекты из коллекции и уменьшает их количество ссылок, но удаляет только объект коллекции.
Иногда драйвер должен проверять все объекты в коллекции. В следующем примере кода показано следующее:
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);