框架对象集合

驱动程序可以将框架对象分组到由 框架集合对象表示的集合中。

例如,如果驱动程序收到表示大型 I/O 请求的框架请求对象,则驱动程序可能需要将大型请求分解为可发送到 I/O 目标的较小请求。 若要将大型请求分解为较小的请求,驱动程序必须创建一组表示较小请求的请求对象。 为了跟踪这些驱动程序创建的请求对象,驱动程序可能会创建一个集合对象并将其添加到集合中。

通常,对象集合中的对象由单一类型的框架对象组成,但驱动程序可以创建由不同类型的对象组成的集合。

驱动程序还可以创建集合集合。 也就是说,集合可以包含一组集合对象。

基于框架的驱动程序可以对对象集合执行以下操作:

  • 创建集合对象。

    若要创建新集合,驱动程序可以调用 WdfCollectionCreate

  • 将 对象添加到集合。

    若要将对象添加到集合,驱动程序可以调用 WdfCollectionAdd 一次或多次。 每次调用 WdfCollectionAdd 都会将对象追加到集合末尾,并递增追加对象的引用计数。

  • 从集合中删除对象。

    若要从集合中删除对象并减小其引用计数,驱动程序可以调用 WdfCollectionRemoveWdfCollectionRemoveItem。 删除对象后,删除对象后的所有对象索引将自动递减。

  • 获取集合中的对象数。

    若要确定集合包含的对象数,驱动程序可以调用 WdfCollectionGetCount

  • 获取集合中对象的句柄。

    如果驱动程序调用 WdfCollectionGetItem,并提供索引值作为输入参数,则驱动程序会收到与索引值关联的对象的句柄。 (索引值为 0 表示集合中的第一个对象,索引值 1 表示第二个对象,依此类而论,就像链接列表一样。当驱动程序从集合中删除项 i 时,项 i+1 将成为项 i.)

    驱动程序还可以调用 WdfCollectionGetFirstItemWdfCollectionGetLastItem ,以获取添加到集合中的第一个或最后一项的句柄。

  • 锁定集合。

    驱动程序可以调用 WdfWaitLockAcquire 以同步对 IRQL = PASSIVE_LEVEL 集合的访问,也可以调用 IRQL = DISPATCH_LEVEL 处的 WdfSpinLockAcquire 同步访问。 驱动程序获取锁后,驱动程序中调用 WdfWaitLockAcquireWdfSpinLockAcquire 的其他代码无法访问该集合。 完成对集合的操作后,驱动程序必须调用 WdfWaitLockRelease

    如果其他代码不同时调用 WdfWaitLockAcquireWdfSpinLockAcquire,则调用 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);