框架对象集合
驱动程序可以将框架对象分组到由 框架集合对象表示的集合中。
例如,如果驱动程序收到表示大型 I/O 请求的框架请求对象,则驱动程序可能需要将大型请求分解为可发送到 I/O 目标的较小请求。 若要将大型请求分解为较小的请求,驱动程序必须创建一组表示较小请求的请求对象。 为了跟踪这些驱动程序创建的请求对象,驱动程序可能会创建一个集合对象并将其添加到集合中。
通常,对象集合中的对象由单一类型的框架对象组成,但驱动程序可以创建由不同类型的对象组成的集合。
驱动程序还可以创建集合集合。 也就是说,集合可以包含一组集合对象。
基于框架的驱动程序可以对对象集合执行以下操作:
创建集合对象。
若要创建新集合,驱动程序可以调用 WdfCollectionCreate。
将 对象添加到集合。
若要将对象添加到集合,驱动程序可以调用 WdfCollectionAdd 一次或多次。 每次调用 WdfCollectionAdd 都会将对象追加到集合末尾,并递增追加对象的引用计数。
从集合中删除对象。
若要从集合中删除对象并减小其引用计数,驱动程序可以调用 WdfCollectionRemove 或 WdfCollectionRemoveItem。 删除对象后,删除对象后的所有对象索引将自动递减。
获取集合中的对象数。
若要确定集合包含的对象数,驱动程序可以调用 WdfCollectionGetCount。
获取集合中对象的句柄。
如果驱动程序调用 WdfCollectionGetItem,并提供索引值作为输入参数,则驱动程序会收到与索引值关联的对象的句柄。 (索引值为 0 表示集合中的第一个对象,索引值 1 表示第二个对象,依此类而论,就像链接列表一样。当驱动程序从集合中删除项 i 时,项 i+1 将成为项 i.)
驱动程序还可以调用 WdfCollectionGetFirstItem 或 WdfCollectionGetLastItem ,以获取添加到集合中的第一个或最后一项的句柄。
锁定集合。
驱动程序可以调用 WdfWaitLockAcquire 以同步对 IRQL = PASSIVE_LEVEL 集合的访问,也可以调用 IRQL = DISPATCH_LEVEL 处的 WdfSpinLockAcquire 同步访问。 驱动程序获取锁后,驱动程序中调用 WdfWaitLockAcquire 或 WdfSpinLockAcquire 的其他代码无法访问该集合。 完成对集合的操作后,驱动程序必须调用 WdfWaitLockRelease。
如果其他代码不同时调用 WdfWaitLockAcquire 或 WdfSpinLockAcquire,则调用 WdfWaitLockAcquire 不会阻止驱动程序中的其他代码同时访问集合。
删除集合。
若要删除集合对象,驱动程序可以调用 WdfObjectDelete。 但是,更常见的情况是,驱动程序在创建集合时指定父对象,框架在删除父对象时会删除集合对象。
例如,如果驱动程序创建一组请求对象,以便它可以将大型 I/O 请求分解为较小的请求,则它可以使大型 I/O 请求的请求对象成为集合对象的父对象。 最终,驱动程序的 I/O 目标将调用 WdfRequestComplete 来完成较小的请求。 此时,驱动程序可以为大型 I/O 请求调用 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);