다음을 통해 공유


함수 또는 필터 드라이버의 AddDevice 루틴

함수 또는 필터 드라이버의 AddDevice 루틴은 다음 단계를 수행해야 합니다.

  1. IoCreateDevice를 호출하여 추가되는 디바이스에 대한 기능 또는 필터 디바이스 개체(FDO 또는 필터 DO)를 만듭니다.

    이렇게 하면 PnP 관리자의 보안이 무시되므로 디바이스 개체에 대해 DeviceName 을 지정하지 마세요. 사용자 모드 구성 요소에 디바이스에 대한 기호 링크가 필요한 경우 디바이스 인터페이스를 등록합니다(아래 다음 단계 참조). 커널 모드 구성 요소에 레거시 디바이스 이름이 필요한 경우 드라이버는 디바이스 개체의 이름을 지정해야 하지만 이름을 지정하지 않는 것이 좋습니다.

    DeviceCharacteristics 매개 변수에 FILE_DEVICE_SECURE_OPEN 포함합니다. 이 특성은 I/O 관리자가 상대 열기 및 후행 파일 이름 열기를 포함하여 열려 있는 모든 요청에 대해 디바이스 개체에 대한 보안 검사를 수행하도록 지시합니다.

  2. [선택 사항] 디바이스에 대한 하나 이상의 기호 링크를 만듭니다.

    IoRegisterDeviceInterface를 호출하여 디바이스 기능을 등록하고 애플리케이션 또는 시스템 구성 요소가 디바이스를 여는 데 사용할 수 있는 기호 링크를 만듭니다. 드라이버는 IRP_MN_START_DEVICE 요청을 처리할 때 IoSetDeviceInterfaceState를 호출하여 인터페이스를 사용하도록 설정해야 합니다. 자세한 내용은 디바이스 인터페이스 클래스를 참조하세요.

  3. 디바이스 확장에 디바이스의 PDO에 대한 포인터를 저장합니다.

    PnP 관리자는 PDO에 대한 포인터를 AddDevicePhysicalDeviceObject 매개 변수로 제공합니다. 드라이버는 IoGetDeviceProperty와 같은 루틴에 대한 호출에서 PDO 포인터를 사용합니다.

  4. 디바이스 확장에 플래그를 정의하여 디바이스 일시 중지, 제거 및 놀라울 제거와 같은 디바이스의 특정 PnP 상태를 추적합니다.

    예를 들어 디바이스가 일시 중지된 상태인 동안 들어오는 IRP를 보유해야 함을 나타내는 하나의 플래그를 정의합니다. 드라이버에 IRP를 큐에 대기하는 메커니즘이 아직 없는 경우 IRP를 보유하기 위한 큐를 만듭니다. 자세한 내용은 큐 및 큐 해제 IRP를 참조하세요 .

    또한 디바이스 확장에 IO_REMOVE_LOCK 구조를 할당하고 IoInitializeRemoveLock 을 호출하여 이 구조를 초기화합니다. 자세한 내용은 잠금 제거 사용을 참조하세요.

  5. 디바이스 개체에서 DO_BUFFERED_IO 또는 DO_DIRECT_IO 플래그 비트를 설정하여 I/O 관리자가 디바이스 스택으로 전송되는 I/O 요청에 사용할 버퍼링 유형을 지정합니다. 상위 수준 드라이버 또는 스택의 다음 하위 드라이버와 동일한 값을 가진 이 멤버입니다(최상위 드라이버의 경우 제외). 자세한 내용은 디바이스 개체 초기화를 참조하세요.

  6. 필요한 경우 전원 관리에 대한 DO_POWER_INRUSH 또는 DO_POWER_PAGABLE 플래그를 설정합니다. 페이지가 지정 가능한 드라이버는 DO_POWER_PAGABLE 플래그를 설정해야 합니다. 디바이스 개체 플래그는 일반적으로 디바이스에 대한 PDO를 만들 때 버스 드라이버에 의해 설정됩니다. 그러나 상위 수준의 드라이버는 FDO를 만들거나 DO를 필터링할 때 AddDevice 루틴에서 이러한 플래그의 값을 변경해야 하는 경우가 있습니다. 자세한 내용은 전원 관리에 대한 디바이스 개체 플래그 설정을 참조하세요.

  7. 드라이버가 이벤트, 스핀 잠금 또는 기타 개체와 같은 이 디바이스를 관리하는 데 사용하는 다른 소프트웨어 리소스를 만들고/또는 초기화합니다. (I/O 포트와 같은 하드웨어 리소스는 IRP_MN_START_DEVICE 요청에 대한 응답으로 나중에 구성됩니다.)

    AddDevice 루틴은 IRQL = PASSIVE_LEVEL 시스템 스레드 컨텍스트에서 실행되기 때문에 초기화 중에 독점적으로 사용하기 위해 ExAllocatePoolWithTag에 할당된 모든 메모리는 드라이버가 시스템 페이지 파일을 보유하는 디바이스를 제어하지 않는 한 페이징 풀에서 사용할 수 있습니다. AddDevice가 컨트롤을 반환하기 전에 ExFreePool을 사용하여 이러한 메모리 할당을 해제해야 합니다.

  8. 디바이스 개체를 디바이스 스택에 연결합니다(IoAttachDeviceToDeviceStack).

    TargetDevice 매개 변수에서 디바이스의 PDO에 대한 포인터를 지정합니다.

    IoAttachDeviceToDeviceStack에서 반환된 포인터를 저장합니다. 디바이스에 대한 다음 하위 드라이버의 디바이스 개체를 가리키는 이 포인터는 IRP를 디바이스 스택 아래로 전달할 때 IoCallDriverPoCallDriver 에 필요한 매개 변수입니다.

  9. FDO에서 DO_DEVICE_INITIALIZING 플래그를 지우거나 다음과 같은 문을 사용하여 DO를 필터링합니다.

    FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    
  10. 디바이스에 대한 PnP IRP(예: IRP_MN_QUERY_RESOURCE_REQUIREMENTSIRP_MN_START_DEVICE)를 처리할 준비를 합니다.

드라이버는 PnP 관리자가 디바이스에 할당한 하드웨어 리소스 목록을 포함하는 IRP_MN_START_DEVICE 받을 때까지 디바이스 제어를 시작해서는 안 됩니다.