다음을 통해 공유


PnP IRP를 디바이스 스택 아래로 전달

PnP 관리자는 IRP를 사용하여 드라이버가 디바이스를 시작, 중지 및 제거하고 해당 디바이스에 대해 드라이버를 쿼리하도록 지시합니다. 모든 PnP IRP에는 IRP_MJ_PNP 주 함수 코드가 있으며, 모든 PnP 드라이버는 이 함수 코드를 서비스하기 위해 DispatchPnP 루틴을 제공해야 합니다. PnP 관리자는 IRP를 보낼 때 Irp-IoStatus.Status>를 STATUS_NOT_SUPPORTED 초기화합니다. 자세한 내용은 DispatchPnP 루틴을 참조하세요.

PnP 부 IRP 목록은 플러그 앤 플레이 부 IRP를 참조하세요.

스택의 드라이버가 IRP에 실패하지 않는 한 디바이스의 모든 드라이버는 PnP IRP에 응답할 수 있어야 합니다. (다음 그림을 참조하세요.)

플러그 앤 플레이 irp를 디바이스 스택 아래로 전달하는 것을 보여 주는 다이어그램

디바이스에 대한 단일 드라이버는 PnP IRP에 응답하는 유일한 드라이버라고 가정할 수 없습니다. 예를 들어 IRP_MN_QUERY_CAPABILITIES 요청에 응답하고 IRP를 다음 하위 드라이버에 전달하지 않고 완료하는 함수 드라이버를 고려합니다. 부모 버스 드라이버에서 지원하는 고유한 instance ID 또는 전원 관리 기능과 같은 하위 드라이버에서 지원하는 기능은 보고되지 않습니다.

PnP IRP는 부모 버스 드라이버가 IoCompleteRequest 를 호출하고 I/O 관리자가 함수 드라이버 또는 필터 드라이버에 의해 등록된 IoCompletion 루틴을 호출할 때 디바이스 스택을 백업합니다.

함수 또는 필터 드라이버는 PnP IRP를 받을 때 다음을 수행해야 합니다.

  • 드라이버가 IRP에 대한 응답으로 작업을 수행하는 경우:
    1. 적절한 작업을 수행합니다.
    2. Irp-IoStatus.Status>를 STATUS_SUCCESS 같은 적절한 상태 설정합니다. IRP에 적합한 경우 Irp-IoStatus.Information>를 설정합니다.
    3. IoSkipCurrentIrpStackLocation 또는 IoCopyCurrentIrpStackLocationToNext를 사용하여 다음 스택 위치를 설정합니다. IoCompletion 루틴을 설정하는 경우 후자의 루틴을 호출합니다.
    4. 필요한 경우 IoCompletion 루틴을 설정합니다.
    5. IRP를 완료하지 마세요. ( IoCompleteRequest를 호출하지 마세요.) 부모 버스 드라이버가 IRP를 완료합니다.
  • 드라이버가 이 IRP에 대한 작업을 수행하지 않으면 IRP를 다음 드라이버에 전달할 준비를 하기만 하면 됩니다.
    1. IRP에서 스택 위치를 제거하려면 IoSkipCurrentIrpStackLocation 을 호출합니다.
    2. Irp-IoStatus>에서 필드를 설정하지 마세요.
    3. IoCompletion 루틴을 설정하지 마세요.
    4. IRP를 완료하지 마세요. ( IoCompleteRequest를 호출하지 마세요.) 부모 버스 드라이버가 IRP를 완료합니다.

함수 또는 필터 드라이버가 IRP에 실패하지 않으면 IRP를 IoCallDriver를 사용하여 다음 하위 드라이버로 전달합니다. 드라이버에는 다음 아래 드라이버에 대한 포인터가 있습니다. 해당 포인터는 상위 드라이버의 AddDevice 루틴에 있는 IoAttachDeviceToDeviceStack 호출 에서 반환되었습니다.

부모 버스 드라이버는 IRP에 응답하는 작업을 수행한 후 IRP를 완료합니다. 버스 드라이버가 IoCompleteRequest를 호출한 후 I/O 관리자는 디바이스에 대한 함수 또는 필터 드라이버에 의해 등록된 모든 IoCompletion 루틴을 호출합니다.