실행 중인 시스템에 PnP 디바이스 추가

이 섹션에서는 시스템이 사용자가 실행 중인 컴퓨터에 추가한 PnP 디바이스를 구성할 때 발생하는 이벤트 시퀀스에 대해 설명합니다. 이 설명에서는 PnP 관리자, 버스 드라이버 및 새 디바이스를 열거하고 구성하는 기능 및 필터 드라이버의 역할을 강조 표시합니다.

이 논의의 대부분은 컴퓨터가 부팅될 때 존재하는 PnP 디바이스를 구성하는 것과도 관련이 있습니다. 특히 INF 파일에서 드라이버가 SERVICE_DEMAND_START 표시된 디바이스는 디바이스가 동적으로 추가되거나 부팅 시 존재하는지 여부에 관계없이 기본적으로 동일한 방식으로 구성됩니다.

다음 그림에서는 사용자가 하드웨어를 컴퓨터에 연결할 때부터 디바이스를 구성하는 첫 번째 단계를 보여 줍니다.

플러그 앤 플레이 디바이스 열거 및 보고를 보여 주는 다이어그램

다음 노트는 이전 그림의 원을 그리는 숫자에 해당합니다.

  1. 사용자가 PnP 디바이스를 PnP 버스의 무료 슬롯에 연결합니다.

    이 예제에서 사용자는 PnP USB 조이스틱을 USB 호스트 컨트롤러의 허브에 연결합니다. USB 허브는 자식 디바이스를 연결할 수 있으므로 PnP 버스 디바이스입니다.

  2. 버스 디바이스의 함수 드라이버는 새 디바이스가 버스에 있는지 확인합니다.

    드라이버가 이를 결정하는 방법은 버스 아키텍처에 따라 달라집니다. 일부 버스의 경우 버스 함수 드라이버는 새 디바이스의 핫 플러그 알림을 받습니다. 버스가 핫 플러그 알림을 지원하지 않는 경우 사용자는 제어판 적절한 조치를 취하여 버스를 열거해야 합니다.

    이 예제에서 USB 버스는 핫 플러그 알림을 지원하므로 USB 버스의 함수 드라이버에 자식이 변경되었다는 알림이 표시됩니다.

  3. 버스 디바이스의 함수 드라이버는 PnP 관리자에게 자식 디바이스 집합이 변경되었음을 알릴 수 있습니다.

    함수 드라이버는 IoInvalidateDeviceRelations를 BusRelations형식 으로 호출하여 PnP 관리자에게 알 릴 수 있습니다.

  4. PnP 관리자는 버스의 드라이버에 버스의 현재 디바이스 목록을 쿼리합니다.

    PnP 관리자는 버스에 대한 디바이스 스택에 IRP_MN_QUERY_DEVICE_RELATIONS 요청을 보냅니다. Parameters.QueryDeviceRelations.Type 값은 BusRelations로, PnP 관리자가 버스에 있는 현재 디바이스 목록(버스 관계)을 요청하고 있음을 나타냅니다.

    PnP 관리자는 버스에 대한 디바이스 스택의 최상위 드라이버에 IRP를 보냅니다. PnP IRP에 대한 규칙에 따라 스택의 각 드라이버는 적절한 경우 IRP를 처리하고 IRP를 다음 드라이버로 전달합니다.

  5. 버스 디바이스의 함수 드라이버는 IRP를 처리합니다.

    이 IRP 처리에 대한 자세한 내용은 IRP_MN_QUERY_DEVICE_RELATIONS 참조 페이지를 참조하세요.

    이 예제에서 USB 허브 드라이버는 허브 FDO에 대해 이 IRP를 처리합니다. 허브 드라이버는 조이스틱 디바이스에 대한 PDO 를 만들고 IRP로 반환된 자식 디바이스 목록에 조이스틱 PDO에 대한 참조 포인터를 포함합니다.

    USB 허브의 부모 버스 드라이버(USB 호스트 컨트롤러 클래스/미니클래스 드라이버 쌍)가 IRP를 완료하면 IRP는 허브 드라이버에 의해 등록된 모든 IoCompletion 루틴을 통해 디바이스 스택을 백업합니다.

버스 함수 드라이버는 PnP 관리자가 자식 디바이스 목록에 대해 쿼리할 것을 요청하여 자식 목록의 변경 내용을 보고합니다. 결과 IRP_MN_QUERY_DEVICE_RELATIONS 요청은 버스 장치의 모든 드라이버에서 볼 수 있습니다. 일반적으로 버스 함수 드라이버는 IRP를 처리하고 자식을 보고하는 유일한 드라이버입니다. 일부 디바이스 스택에서는 버스 필터 드라이버가 있고 버스 관계 목록을 생성하는 데 참여합니다. 한 가지 예는 ACPI 디바이스에 대한 버스 필터 드라이버로 연결되는 ACPI입니다. 일부 디바이스 스택에서 비버스 필터 드라이버는 IRP_MN_QUERY_DEVICE_RELATIONS 요청을 처리하지만 일반적인 것은 아닙니다.

이 시점에서 PnP 관리자에는 버스의 현재 디바이스 목록이 있습니다. 그런 다음 PnP 관리자는 디바이스가 새로 도착했는지 또는 제거되었는지 확인합니다. 이 예제에는 하나의 새 디바이스가 있습니다. 다음 그림에서는 PnP 관리자가 새 디바이스에 대한 devnode를 만들고 디바이스 구성을 시작하는 방법을 보여줍니다.

새 플러그 앤 플레이 디바이스에 대한 devnode 만들기를 보여 주는 다이어그램

다음 노트는 이전 그림의 원을 그리는 숫자에 해당합니다.

  1. PnP 관리자는 버스의 모든 새 자식 디바이스에 대한 devnode를 만듭니다.

    PnP 관리자는 IRP_MN_QUERY_DEVICE_RELATIONS IRP에서 반환된 버스 관계 목록을 현재 PnP 디바이스 트리에 기록된 버스의 자식 목록과 비교합니다. PnP 관리자는 각 새 디바이스에 대한 devnode를 만들고 제거된 모든 디바이스에 대한 제거 처리를 시작합니다.

    이 예제에는 하나의 새 디바이스(조이스틱)가 있으므로 PnP 관리자는 조이스틱에 대한 devnode를 만듭니다. 이 시점에서 조이스틱에 대해 구성된 유일한 드라이버는 조이스틱의 PDO를 만든 부모 USB 허브 버스 드라이버입니다. 선택적 버스 필터 드라이버도 디바이스 스택에 있지만 단순성을 위해 버스 필터 드라이버를 생략하는 예제입니다.

    이전 그림에서 두 devnode 사이의 넓은 화살표는 조이스틱 devnode가 USB 허브 devnode의 자식임을 나타냅니다.

  2. PnP 관리자는 새 디바이스에 대한 정보를 수집하고 디바이스 구성을 시작합니다.

    PnP 관리자는 디바이스 스택에 일련의 IRP를 보내 디바이스에 대한 정보를 수집합니다. 이 시점에서 디바이스 스택은 디바이스의 부모 버스 드라이버에서 만든 PDO만 구성하고 선택적 버스 필터 드라이버에 대한 DO를 필터링합니다. 따라서 버스 드라이버 및 버스 필터 드라이버는 이러한 IRP에 응답하는 유일한 드라이버입니다. 이 예제에서 조이스틱 디바이스 스택의 유일한 드라이버는 부모 버스 드라이버인 USB 허브 드라이버입니다.

    PnP 관리자는 디바이스 스택에 IRP를 전송하여 새 디바이스에 대한 정보를 수집합니다. 이러한 IRP에는 다음이 포함됩니다.

    PnP 관리자는 새 PnP 디바이스를 처리하는 이 단계에서 위에 나열된 IRP를 보내지만 반드시 나열된 순서대로 전송되는 것은 아니므로 IRP가 전송되는 순서를 가정해서는 안 됩니다. 또한 PnP 관리자가 위에 나열된 IRP만 보낸다고 가정해서는 안 됩니다.

    PnP 관리자는 레지스트리를 확인하여 디바이스가 이전에 이 컴퓨터에 설치되었는지 확인합니다. PnP 관리자는 열거자\<deviceID> 하위 키를 거형 >분기 아래의 디바이스에 대해 확인 < 합니다. 이 예제에서 디바이스는 새 디바이스이며 "처음부터" 구성해야 합니다.

  3. PnP 관리자는 레지스트리에 디바이스에 대한 정보를 저장합니다.

    레지스트리의 열거형 분기는 운영 체제 구성 요소에서 사용하도록 예약되어 있으며 레이아웃이 변경될 수 있습니다. 드라이버 작성기는 시스템 루틴을 사용하여 드라이버와 관련된 정보를 추출해야 합니다. 드라이버에서 직접 열거형 분기에 액세스하지 마세요. 다음 열거형 정보는 디버깅 목적으로만 나열됩니다.

    • PnP 관리자는 디바이스 열거자의 키 아래에 디바이스에 대한 하위 키를 만듭니다.

      PnP 관리자는 HKLM\System\CurrentControlSet\Enum\<enumerator>\<deviceID>라는 하위 키를 만듭니다. 열거자> 하위 키가 아직 없는 경우 만듭니다<.

      열거자는 PnP 하드웨어 표준을 기반으로 PnP 디바이스를 검색하는 구성 요소입니다. 열거자의 작업은 PnP 관리자와 협력하여 PnP 버스 드라이버에 의해 수행됩니다. 디바이스는 일반적으로 PCI 또는 PCMCIA와 같은 부모 버스 드라이버에 의해 열거됩니다. 일부 디바이스는 ACPI와 같은 버스 필터 드라이버에 의해 열거됩니다.

    • PnP 관리자는 디바이스의 이 instance 대한 하위 키를 만듭니다.

      Capabilities.UniqueIDIRP_MN_QUERY_CAPABILITIESTRUE로 반환되면 디바이스의 고유 ID는 시스템 전체에서 고유합니다. 그렇지 않은 경우 PnP 관리자는 ID를 수정하여 시스템 전체에서 고유하게 지정합니다.

      PnP 관리자는 HKLM\System\CurrentControlSet\Enum\<enumerator><\deviceID>\<instanceID>라는 하위 키를 만듭니다.

    • PnP 관리자는 디바이스 instance 대한 하위 키에 디바이스에 대한 정보를 씁니다.

      PnP 관리자는 디바이스에 제공된 경우 다음을 비롯한 정보를 저장합니다.

      DeviceDescIRP_MN_QUERY_DEVICE_TEXT

      위치IRP_MN_QUERY_DEVICE_TEXT

      기능 - IRP_MN_QUERY_CAPABILITIES 플래그

      UINumberIRP_MN_QUERY_CAPABILITIES

      HardwareIDIRP_MN_QUERY_ID

      CompatibleIDsIRP_MN_QUERY_ID

      ContainerIDIRP_MN_QUERY_ID

      LogConf\BootConfigIRP_MN_QUERY_RESOURCES

      LogConf\BasicConfigVectorIRP_MN_QUERY_RESOURCE_REQUIREMENTS

이 시점에서 PnP 관리자는 디바이스에 대한 함수 드라이버를 찾고 드라이버(있는 경우)를 필터링할 준비가 된 것입니다. (다음 그림을 참조하세요.)

함수 및 필터 드라이버 찾기를 보여 주는 다이어그램

다음 노트는 이전 그림의 번호가 매겨진 원에 해당합니다.

  1. 커널 모드 PnP 관리자는 사용자 모드 PnP 관리자 및 사용자 모드 설치 구성 요소와 조정하여 디바이스에 대한 함수 및 필터 드라이버를 찾습니다(있는 경우).

    커널 모드 PnP 관리자는 이벤트를 사용자 모드 PnP 관리자에 큐에 대기하여 설치해야 하는 디바이스를 식별합니다. 권한 있는 사용자가 로그인하면 사용자 모드 구성 요소는 드라이버 찾기를 진행합니다. 디바이스 설치 개요를 참조하세요. 설치 구성 요소 및 디바이스 설치에 대한 해당 역할에 대한 자세한 내용은 를 참조하세요.

  2. 사용자 모드 설치 구성 요소는 커널 모드 PnP 관리자에게 함수를 로드하고 드라이버를 필터링하도록 지시합니다.

    사용자 모드 구성 요소는 커널 모드로 다시 호출하여 드라이버를 로드하여 AddDevice 루틴을 호출합니다.

다음 그림에서는 PnP 관리자가 드라이버를 로드하고(해당하는 경우), AddDevice 루틴을 호출하고, 드라이버에 디바이스를 시작하도록 지시하는 방법을 보여 줍니다.

adddevice 루틴을 호출하고 새 디바이스를 시작하는 것을 보여 주는 다이어그램

다음 노트는 이전 그림의 번호가 매겨진 원에 해당합니다.

  1. 낮은 필터 드라이버

    함수 드라이버가 디바이스 스택에 연결되기 전에 PnP 관리자는 하위 필터 드라이버를 처리합니다. 각 하위 필터 드라이버에 대해 PnP 관리자는 드라이버가 아직 로드되지 않은 경우 드라이버의 DriverEntry 루틴을 호출합니다. 그런 다음 PnP 관리자는 드라이버의 AddDevice 루틴을 호출합니다. AddDevice 루틴에서 필터 드라이버는 필터 디바이스 개체(필터 DO)를 만들고 디바이스 스택(IoAttachDeviceToDeviceStack)에 연결합니다. 디바이스 개체를 디바이스 스택에 연결하면 드라이버는 디바이스의 드라이버로 작동합니다.

    USB 조이스틱 예제에는 디바이스에 대한 하나의 하위 필터 드라이버가 있습니다.

  2. 함수 드라이버

    낮은 필터가 연결되면 PnP 관리자는 함수 드라이버를 처리합니다. PnP 관리자는 드라이버가 아직 로드되지 않은 경우 함수 드라이버의 DriverEntry 루틴을 호출하고 함수 드라이버의 AddDevice 루틴을 호출합니다. 함수 드라이버는 FDO(함수 디바이스 개체)를 만들어 디바이스 스택에 연결합니다.

    이 예제에서 USB 조이스틱의 함수 드라이버는 실제로 HID 클래스 드라이버와 HID 미니클래스 드라이버와 같은 한 쌍의 드라이버입니다. 두 드라이버는 함께 작동하여 함수 드라이버 역할을 합니다. 드라이버 쌍은 FDO를 하나만 만들고 디바이스 스택에 연결합니다.

  3. 상위 필터 드라이버

    함수 드라이버가 연결되면 PnP 관리자는 모든 상위 필터 드라이버를 처리합니다.

    이 예제에는 디바이스에 대한 상위 필터 드라이버가 하나 있습니다.

  4. 리소스 할당 및 디바이스 시작

    PnP 관리자는 필요한 경우 디바이스에 리소스를 할당하고 IRP를 발급하여 디바이스를 시작합니다.

    • 리소스 할당

      구성 프로세스 초기에 PnP 관리자는 디바이스의 부모 버스 드라이버에서 디바이스에 대한 하드웨어 리소스 요구 사항을 수집했습니다. 디바이스에 대한 전체 드라이버 집합을 로드한 후 PnP 관리자는 디바이스 스택에 IRP_MN_FILTER_RESOURCE_REQUIREMENTS 요청을 보냅니다. 스택의 모든 드라이버는 이 IRP를 처리하고 필요한 경우 디바이스의 리소스 요구 사항 목록을 수정할 수 있습니다.

      PnP 관리자는 디바이스의 요구 사항 및 현재 사용 가능한 리소스에 따라 디바이스에 리소스가 필요한 경우 디바이스에 리소스를 할당합니다.

      PnP 관리자는 새 디바이스의 요구 사항을 충족하기 위해 기존 디바이스의 리소스 할당을 다시 정렬해야 할 수 있습니다. 이 리소스 재할당을 "리밸런싱"이라고 합니다. 기존 디바이스의 드라이버는 리밸런스 중에 일련의 중지 및 시작 IRP를 수신하지만 리밸런스는 사용자에게 투명해야 합니다.

      USB 조이스틱의 예에서 USB 디바이스에는 하드웨어 리소스가 필요하지 않으므로 PnP 관리자는 리소스 목록을 NULL로 설정합니다.

    • 디바이스 시작(IRP_MN_START_DEVICE)

      PnP 관리자가 디바이스에 리소스를 할당하면 디바이스 스택에 IRP_MN_START_DEVICE IRP를 전송하여 드라이버가 디바이스를 시작하도록 지시합니다.

    디바이스가 시작된 후 PnP 관리자는 디바이스의 드라이버에 세 개의 IRP를 더 보냅니다.

    • IRP_MN_QUERY_CAPABILITIES

      시작 IRP가 성공적으로 완료되면 PnP 관리자는 디바이스 스택에 다른 IRP_MN_QUERY_CAPABILITIES IRP를 보냅니다. 디바이스의 모든 드라이버에는 IRP를 처리하는 옵션이 있습니다. 기능 또는 필터 드라이버가 기능 정보를 수집하기 위해 디바이스에 액세스해야 할 수 있으므로 PnP 관리자는 모든 드라이버가 연결되고 디바이스가 시작된 후 이 IRP를 보냅니다.

    • IRP_MN_QUERY_PNP_DEVICE_STATE

      예를 들어 이 IRP는 드라이버가 디바이스를 장치 관리자 및 핫플러그 프로그램과 같은 사용자 인터페이스에 표시해서는 안 된다고 보고할 수 있는 기회를 제공합니다. 이 기능은 시스템에 있지만 현재 구성에서 사용할 수 없는 디바이스(예: 노트북의 도킹 해제 시 사용할 수 없는 노트북의 게임 포트)에 유용합니다.

    • 버스 관계에 대한 IRP_MN_QUERY_DEVICE_RELATIONS

      PnP 관리자는 이 IRP를 보내 디바이스에 자식 디바이스가 있는지 여부를 확인합니다. 이 경우 PnP 관리자는 각 자식 디바이스를 구성합니다.

GUID_PNP_LOCATION_INTERFACE 사용

GUID_PNP_LOCATION_INTERFACE 인터페이스는 디바이스에 대한 SPDRP_LOCATION_PATHS 플러그 앤 플레이(PnP) 디바이스 속성을 제공합니다.

드라이버에서 이 인터페이스를 구현하려면 InterfaceType = GUID_PNP_LOCATION_INTERFACE 사용하여 IRP_MN_QUERY_INTERFACE IRP를 처리합니다. 드라이버는 인터페이스의 개별 루틴에 대한 포인터를 포함하는 PNP_LOCATION_INTERFACE 구조체에 대한 포인터를 제공합니다. PnpGetLocationString 루틴은 디바이스의 SPDRP_LOCATION_PATHS 속성의 디바이스별 부분을 제공합니다.