다음을 통해 공유


동적 열거형

동적 열거형 은 시스템이 실행되는 동안 시스템에 연결된 디바이스의 수와 유형에 대한 변경 내용을 감지하고 보고하는 드라이버의 기능입니다.

부모 디바이스에 연결된 디바이스의 수 또는 유형이 시스템 구성에 따라 달라지는 경우 버스 드라이버는 동적 열거형을 사용해야 합니다. 이러한 디바이스 중 일부는 항상 시스템에 연결될 수 있으며, 일부는 시스템이 실행되는 동안 연결되고 분리될 수 있습니다.

예를 들어 시스템의 PCI 버스에 연결된 디바이스의 수와 유형은 시스템에 따라 달라지지만 사용자가 전원을 끄고 케이스를 열고 스크루드라이버를 사용하여 디바이스를 추가하거나 제거하지 않는 한 영구적으로 적용됩니다. 반면에 사용자는 시스템이 실행되는 동안 케이블을 연결하거나 뽑아 USB 장치를 추가하거나 제거할 수 있습니다.

동적 자식 목록

프레임워크를 사용하면 드라이버가 프레임워크 자식 목록 개체를 제공하여 동적 열거형을 지원할 수 있습니다. 각 자식 목록 개체는 부모 디바이스에 연결된 자식 디바이스의 목록을 나타냅니다. 부모 디바이스의 버스 드라이버는 부모의 자식 디바이스를 식별하고, 부모 디바이스의 자식 목록에 추가하고, 각 자식에 대한 물리적 디바이스 개체(PDO)를 만들어야 합니다.

드라이버가 디바이스에 대한 FDO를 나타내는 프레임워크 디바이스 개체를 만들 때마다 프레임워크는 디바이스에 대한 빈 기본 자식 목록을 만듭니다. 드라이버는 WdfFdoGetDefaultChildList를 호출하여 디바이스의 기본 자식 목록에 대한 핸들을 가져올 수 있습니다. 일반적으로 디바이스의 자식을 열거하는 버스 드라이버를 작성하는 경우 드라이버는 기본 자식 목록에 자식을 추가할 수 있습니다. 추가 자식 목록을 만들어야 하는 경우 드라이버는 WdfChildListCreate를 호출할 수 있습니다.

드라이버가 자식 목록을 사용하려면 먼저 WDF_CHILD_LIST_CONFIG 구조를 초기화하고 구조체를 WdfFdoInitSetDefaultChildListConfig, 기본 자식 목록 또는 WdfChildListCreate에 전달하여 자식 목록 개체를 구성해야 합니다.

동적 자식 설명

버스 드라이버가 자식 디바이스를 식별할 때마다 자식 디바이스의 설명을 자식 목록에 추가해야 합니다. 자식 설명은 필수 식별 설명과 선택적 주소 설명으로 구성됩니다.

식별 설명 식별 설명은 드라이버가 열거하는 각 디바이스를 고유하게 식별하는 정보를 포함하는 구조체입니다. 드라이버는 이 구조를 정의하지만 첫 번째 멤버는 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER 구조체여야 합니다.

일반적으로 식별 설명에는 디바이스의 디바이스 식별 문자열( 일련 번호) 및 버스에서 디바이스 위치에 대한 정보(예: 슬롯 번호)가 포함됩니다.

드라이버는 프레임워크가 식별 설명의 정보를 조작할 수 있도록 하는 다음 콜백 함수 집합을 제공할 수 있습니다.

일반적으로 드라이버의 ID 설명 구조에 동적으로 할당된 버퍼에 대한 포인터가 포함된 경우 이러한 콜백 함수를 제공해야 합니다. 이러한 콜백 함수의 용도에 대한 자세한 내용은 참조 페이지를 참조하세요.

주소 설명 주소 설명은 디바이스가 연결되어 있는 동안 정보가 변경 될 수 있는 경우 드라이버가 버스에서 디바이스에 액세스할 수 있도록 필요한 정보를 포함하는 구조체입니다. 드라이버는 이 구조를 정의하지만 첫 번째 멤버는 WDF_CHILD_ADDRESS_DESCRIPTION_HEADER 구조체여야 합니다.

주소 설명은 선택 사항입니다. 디바이스의 주소 정보가 디바이스가 연결된 시간과 플러그를 뽑은 시간 사이에 변경할 수 없는 경우 모든 디바이스의 주소 정보를 식별 설명에 저장할 수 있습니다. 예를 들어 USB 컨트롤러는 디바이스가 연결되어 있을 때 디바이스에 주소를 할당하며 이러한 주소는 변경되지 않습니다.

반면에 일부 버스는 변경할 수 있는 주소 지정 정보를 사용합니다. 예를 들어 IEEE 1394 버스는 발생한 버스 재설정 수인 "세대 수"를 사용합니다. IEEE 1394 디바이스에 대한 각 비동기 I/O 요청에는 세대 수가 포함되어야 합니다. 이 주소 정보는 변경 될 수 있으므로 드라이버 주소 설명에 저장 해야 합니다.

드라이버는 다음 콜백 함수 집합을 제공하여 주소 설명의 정보를 조작할 수 있습니다.

일반적으로 드라이버의 주소 설명 구조에 동적으로 할당된 버퍼에 대한 포인터가 포함된 경우 이러한 콜백 함수를 제공해야 합니다. 이러한 콜백 함수의 용도에 대한 자세한 내용은 참조 페이지를 참조하세요.

동적 자식 목록에 디바이스 추가

프레임워크가 버스 드라이버의 EvtDriverDeviceAdd 콜백 함수를 호출하는 경우 콜백 함수는 WdfDeviceCreate 를 호출하여 일반적으로 버스 어댑터인 부모 디바이스에 대한 FDO를 만들어야 합니다. FDO를 만드는 방법에 대한 자세한 내용은 함수 드라이버에서 디바이스 개체 만들기를 참조하세요. 그런 다음 드라이버는 부모 디바이스의 자식을 열거하고 자식 목록에 자식을 추가해야 합니다.

필요에 따라 드라이버는 WdfDeviceSetBusInformationForChildren 를 호출하여 버스에 대한 정보를 프레임워크에 제공할 수 있습니다. 이렇게 하면 자식 디바이스 및 앱이 버스를 더 쉽게 식별할 수 있기 때문에 권장됩니다.

자식 목록에 자식을 추가하려면 드라이버가 찾은 각 자식 디바이스에 대해 WdfChildListAddOrUpdateChildDescriptionAsPresent 를 호출해야 합니다. 이 호출은 드라이버가 부모 디바이스에 연결된 자식 디바이스를 검색했음을 프레임워크에 알릴 수 있습니다. 드라이버가 WdfChildListAddOrUpdateChildDescriptionAsPresent를 호출하면 ID 설명과 필요에 따라 주소 설명을 제공합니다.

드라이버가 WdfChildListAddOrUpdateChildDescriptionAsPresent 를 호출하여 새 디바이스를 보고한 후 프레임워크는 PnP 관리자에게 새 디바이스가 있음을 알릴 수 있습니다. 그런 다음 PnP 관리자는 새 디바이스에 대한 디바이스 스택 및 드라이버 스택을 빌드합니다. 이 프로세스의 일부로 프레임워크는 버스 드라이버의 EvtChildListCreateDevice 콜백 함수를 호출합니다. 이 콜백 함수는 WdfDeviceCreate 를 호출하여 새 디바이스에 대한 PDO를 만들어야 합니다.

일반적으로 여러 자식 디바이스가 부모에 연결되므로 버스 드라이버는 WdfChildListAddOrUpdateChildDescriptionAsPresent 를 여러 번 호출해야 합니다. 이 작업을 수행하는 가장 효율적인 방법은 다음과 같습니다.

  1. WdfChildListBeginScan을 호출합니다.

  2. 각 자식 디바이스 에 대해 WdfChildListAddOrUpdateChildDescriptionAsPresent 를 호출합니다.

  3. WdfChildListEndScan을 호출합니다.

드라이버의 동적 열거형을 WdfChildListBeginScanWdfChildListEndScan 호출로 둘러싸는 경우 프레임워크는 모든 변경 내용을 자식 목록에 저장하고 드라이버가 WdfChildListEndScan을 호출할 때 PnP 관리자에게 변경 내용을 알릴 수 있습니다. 나중에 프레임워크는 자식 목록의 각 디바이스에 대해 버스 드라이버의 EvtChildListCreateDevice 콜백 함수를 호출합니다. 이 콜백 함수는 WdfDeviceCreate 를 호출하여 각 새 디바이스에 대한 PDO를 만듭니다.

드라이버가 WdfChildListBeginScan을 호출하면 프레임워크는 이전에 보고된 모든 디바이스가 더 이상 존재하지 않는 것으로 표시합니다. 따라서 드라이버는 새로 검색된 자식뿐만 아니라 드라이버가 검색할 수 있는 모든 자식에 대해 WdfChildListAddOrUpdateChildDescriptionAsPresent 를 호출해야 합니다. 자식 목록에 단일 자식 을 추가하려면 드라이버는 먼저 WdfChildListBeginScan을 호출하지 않고 WdfChildListUpdateAllChildDescriptionsAsPresent 를 단일 호출할 수 있습니다.

동적 자식 목록 업데이트

동적 자식 목록에서 정보를 업데이트하는 두 가지 일반적인 방법이 있습니다.

  1. 부모 디바이스가 자식의 도착 또는 제거를 나타내는 인터럽트를 받으면 드라이버의 EvtInterruptDpc 콜백 함수는 디바이스가 연결되어 있는 경우 WdfChildListAddOrUpdateChildDescriptionAsPresent 를 호출하거나 디바이스가 분리된 경우 WdfChildListUpdateChildDescriptionAsMissing을 호출합니다.

  2. 드라이버는 부모 디바이스가 작동(D0) 상태가 될 때마다 프레임워크가 호출하는 EvtChildListScanForChildren 콜백 함수를 제공할 수 있습니다. 이 콜백 함수는 WdfChildListBeginScan, WdfChildListAddOrUpdateChildDescriptionAsPresent (또는 WdfChildListUpdateAllChildDescriptionsAsPresent) 및 WdfChildListEndScan을 호출하여 모든 자식 디바이스를 열거해야 합니다.

드라이버에서 이러한 기술 중 하나 또는 둘 다를 사용할 수 있습니다.

동적 자식 목록 트래버스

드라이버가 자식 목록의 내용을 검사하도록 하려면 다음 기술 중 하나를 사용하여 목록을 트래버스할 수 있습니다.

  • 각 자식 디바이스 설명의 내용을 가져오기 위해 드라이버는 다음을 수행할 수 있습니다.

    1. WdfChildListBeginIteration을 호출합니다.
    2. WdfChildListRetrieveNextDevice를 필요한 횟수만큼 호출합니다.
    3. WdfChildListEndIteration을 호출합니다.

    WdfChildListBeginIteration을 호출할 때 드라이버는 프레임워크가 모든 디바이스 설명 또는 하위 집합만 검색해야 하는지 여부를 나타내는 WDF_RETRIEVE_CHILD_FLAGS 형식 플래그를 지정합니다. WdfChildListRetrieveNextDevice가 일치 항목을 찾으면 자식 디바이스의 식별 및 주소 설명과 해당 디바이스 개체에 대한 핸들을 검색합니다.

  • 현재 자식 디바이스 설명에 포함된 주소 설명을 가져와야 하는 경우 드라이버는 식별 설명을 지정하여 WdfChildListRetrieveAddressDescription을 호출할 수 있습니다. 프레임워크는 일치하는 식별 설명이 있는 자식 디바이스를 찾은 다음 주소 설명을 검색할 때까지 자식 목록을 트래버스합니다.

  • 특정 자식 디바이스와 연결된 프레임워크 디바이스 개체에 대한 핸들을 가져와야 하는 경우 드라이버는 WdfChildListRetrievePdo를 호출할 수 있습니다. 프레임워크는 일치하는 식별 설명이 있는 자식 디바이스를 찾은 다음 디바이스 개체 핸들을 반환할 때까지 자식 목록을 트래버스합니다. 다른 스레드에서 PDO의 갑작스런 PnP 제거로부터 호출자를 보호하려면 WdfChildListBeginIterationWdfChildListEndIteration 을 사용하여 호출을 래핑해야 합니다.

PDO의 ID 및 주소 설명에 액세스

드라이버는 다음 메서드를 호출하여 PDO의 식별 설명 또는 주소 설명에 액세스할 수 있습니다.

다시 열거형 요청 처리

동적 열거형을 지원하는 프레임워크 기반 버스 드라이버는 REENUMERATE_SELF_INTERFACE_STANDARD 인터페이스를 통해 특정 자식 디바이스를 다시 열거하라는 요청을 받을 수 있습니다. 자세한 내용은 열거형 요청 처리를 참조하세요.