다음을 통해 공유


Framework 개체 컬렉션

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

예를 들어, 드라이버가 대규모 I/O 요청을 나타내는 프레임워크 요청 개체를 수신하면, 드라이버는 그 큰 요청을 I/O 대상에게 보낼 수 있는 더 작은 요청들로 나누어야 할 수도 있습니다. 큰 요청을 더 작은 요청으로 나누려면 드라이버는 더 작은 요청을 나타내는 요청 개체 집합을 만들어야 합니다. 드라이버에서 만든 이러한 요청 개체를 추적하기 위해 드라이버는 컬렉션 개체를 만들고 컬렉션에 추가할 수 있습니다.

일반적으로 개체 컬렉션의 개체는 프레임워크 개체의 단일 형식으로 구성되지만 드라이버는 다양한 형식의 개체로 구성된 컬렉션을 만들 수 있습니다.

드라이버는 여러 컬렉션을 모아 하나의 컬렉션으로 만들 수도 있습니다. 즉, 컬렉션은 컬렉션 개체 집합으로 구성됩니다.

프레임워크 기반 드라이버는 개체 컬렉션에 대해 다음 작업을 수행할 수 있습니다.

  • 컬렉션 개체를 만듭니다.

    새 컬렉션을 만들기 위해 드라이버는 WdfCollectionCreate호출할 수 있습니다.

  • 컬렉션에 개체를 추가합니다.

    드라이버는 컬렉션에 개체를 추가하기 위해 WdfCollectionAdd을 한 번 이상 호출할 수 있습니다. WdfCollectionAdd 대한 각 호출은 컬렉션의 끝에 개체를 추가하고 추가된 개체의 참조 수를 증분합니다.

  • 컬렉션에서 개체를 제거합니다.

    컬렉션에서 개체를 제거하고 참조 수를 줄이려면 드라이버는 WdfCollectionRemove 호출하거나 WdfCollectionRemoveItem수 있습니다. 개체가 제거되면 제거된 개체 이후의 모든 개체는 해당 인덱스가 자동으로 감소합니다.

  • 컬렉션의 개체 수를 가져옵니다.

    컬렉션에 포함된 개체 수를 확인하기 위해 드라이버는 WdfCollectionGetCount호출할 수 있습니다.

  • 컬렉션에 있는 개체의 핸들을 얻습니다.

    드라이버가 WdfCollectionGetItem호출하여 인덱스 값을 입력 인수로 제공하는 경우 드라이버는 인덱스 값과 연결된 개체에 대한 핸들을 받습니다. (인덱스 값 0은 컬렉션의 첫 번째 개체를 나타내고, 인덱스 값 1은 두 번째 개체를 나타내며, 이와 같이 계속해서 연결된 목록과 유사합니다. 드라이버가 컬렉션에서 항목 i을 제거하면, i +1이 항목위치에 있던 항목이 i로 됩니다.)

    드라이버는 WdfCollectionGetFirstItem 또는 WdfCollectionGetLastItem 호출하여 컬렉션에 추가된 첫 번째 또는 마지막 항목에 대한 핸들을 가져올 수도 있습니다.

  • 컬렉션을 잠그기.

    드라이버는 IRQL = PASSIVE_LEVEL에서 컬렉션에 대한 액세스를 동기화하기 위해 WdfWaitLockAcquire를 호출하거나, 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);