Framework 개체 컬렉션

드라이버는 프레임워크 개체를 프레임워크 컬렉션 개체로 표현되는 컬렉션으로 그룹화할 수 있습니다.

예를 들어 드라이버가 큰 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 또는 WdfSpinLockAcquire를 호출하지 않는 경우 드라이버의 다른 코드가 컬렉션에 동시에 액세스하는 것을 방지하지 않습니다.

  • 컬렉션을 삭제합니다.

    컬렉션 개체를 삭제하기 위해 드라이버는 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);