다음을 통해 공유


DispatchPnP 루틴

드라이버의 DispatchPnP 루틴은 IRP_MJ_PNP I/O 함수 코드에 대한 IRP를 처리하여 플러그 앤 플레이 지원합니다. IRP_MJ_PNP 함수 코드와 연결된 몇 가지 부 I/O 함수 코드(플러그 앤 플레이 부 IRP 참조)가 있으며, 그 중 일부는 모든 드라이버가 처리해야 하고 일부는 선택적으로 처리할 수 있습니다. PnP 관리자는 이러한 부 함수 코드를 사용하여 드라이버가 디바이스를 시작, 중지 및 제거하고 드라이버에 디바이스에 대해 쿼리하도록 지시합니다.

함수 또는 필터 드라이버가 IRP에 실패할 수 있는 몇 가지 경우를 제외하고 디바이스의 모든 드라이버는 디바이스에 대한 PnP IRP를 처리할 수 있어야 합니다.

각 드라이버의 DispatchPnP 루틴은 다음 규칙을 따라야 합니다.

  • 함수 또는 필터 드라이버가 IRP를 처리하고 리소스가 부족하여 오류가 발생하지 않는 한 함수 또는 필터 드라이버는 PnP IRP를 디바이스 스택의 다음 드라이버로 전달해야 합니다.

    디바이스의 모든 드라이버는 드라이버 중 하나에 오류가 발생하지 않는 한 디바이스에 대한 PnP IRP를 처리할 수 있어야 합니다. PnP 관리자는 디바이스 스택의 최상위 드라이버에 IRP를 보냅니다. 함수 및 필터 드라이버는 IRP를 다음 드라이버로 전달하고 부모 버스 드라이버는 IRP를 완료합니다. 자세한 내용은 디바이스 스택 아래로 PnP IRP 전달 을 참조하세요.

    IRP를 처리하려고 하고 오류(예: 리소스 부족)가 발생하는 경우 드라이버가 IRP에 실패할 수 있습니다. 드라이버가 처리하지 않는 코드가 포함된 IRP를 수신하는 경우 드라이버는 IRP에 실패하지 않아야 합니다. IRP의 상태 수정하지 않고 이러한 IRP를 다음 드라이버로 전달해야 합니다.

  • 드라이버는 특정 PnP IRP를 처리해야 하며 필요에 따라 다른 IP를 처리할 수 있습니다.

    각 PnP 드라이버는 IRP_MN_REMOVE_DEVICE 같은 특정 IRP를 처리해야 하며 필요에 따라 다른 IDP를 처리할 수 있습니다. 각 종류의 드라이버(함수 드라이버, 필터 드라이버 및 버스 드라이버)에 필요한 IRP 및 선택 사항에 대한 자세한 내용은 플러그 앤 플레이 부 IRP를 참조하세요.

    드라이버는 적절한 오류 상태 필요한 PnP IRP에 실패할 수 있지만 드라이버는 이러한 IRP에 대한 STATUS_NOT_SUPPORTED 반환해서는 안 됩니다.

  • 드라이버가 PnP IRP를 성공적으로 처리하는 경우 드라이버는 IRP 상태 성공으로 설정합니다. 상태 설정하기 위해 스택의 다른 드라이버에 의존하지 않습니다.

    드라이버는 Irp-IoStatus.Status>를 STATUS_SUCCESS 설정하여 드라이버가 IRP를 성공적으로 처리했음을 PnP 관리자에게 알릴 수 있습니다. 일부 IRP의 경우 버스가 아닌 드라이버는 부모 버스 드라이버에 의존하여 상태 성공으로 설정할 수 있습니다. 그러나 이것은 위험한 관행입니다. 일관성과 견고성을 위해 드라이버는 IRP 상태 성공적으로 처리하는 각 PnP IRP에 대해 성공으로 설정해야 합니다.

  • 드라이버가 IRP에 실패하면 드라이버가 오류 상태 IRP를 완료하고 IRP를 다음 드라이버로 전달하지 않습니다.

    IRP_MN_QUERY_STOP_DEVICE 같은 IRP를 실패하려면 드라이버가 Irp-IoStatus.Status>를 STATUS_UNSUCCESSFUL 설정합니다. 다른 IRP에 대한 추가 오류 상태 값에는 STATUS_INSUFFICIENT_RESOURCES 및 STATUS_INVALID_DEVICE_STATE 포함됩니다.

    드라이버는 처리하는 IRP에 대한 STATUS_NOT_SUPPORTED 설정하지 않습니다. PnP 관리자가 설정한 초기 상태. 이 상태 IRP를 완료하면 스택의 드라이버가 IRP를 처리하지 않고 모든 드라이버가 IRP를 다음 드라이버에 전달했음을 의미합니다.

  • 드라이버는 IRP에 대한 참조 페이지에 지정된 대로 디스패치 루틴(IRP의 디바이스 스택 아래로 이동), IoCompletion 루틴(IRP의 디바이스 스택 백업 방법) 또는 둘 다에서 PnP IRP를 처리해야 합니다.

    IRP_MN_REMOVE_DEVICE 같은 일부 PnP IRP는 먼저 디바이스 스택의 맨 위에 있는 드라이버가 처리한 다음, 각 다음 하위 드라이버에서 처리해야 합니다. IRP_MN_START_DEVICE 같은 다른 항목은 부모 버스 드라이버에서 먼저 처리해야 합니다. IRP_MN_QUERY_CAPABILITIES 같은 다른 항목은 디바이스 스택을 따라 내려가는 방법과 백업하는 방법 모두에서 처리할 수 있습니다. 각 PnP IRP에 적용되는 규칙은 플러그 앤 플레이 부 IRP를 참조하세요. 부모 버스 드라이버에서 먼저 처리해야 하는 PnP IRP를 처리하는 방법에 대한 자세한 내용은 낮은 드라이버가 완료될 때까지 PnP IRP 처리 연기를 참조하세요.

  • 드라이버는 IRP의 디바이스 스택에서 IRP에 정보를 추가하고 IRP의 백업 방법에 대한 정보를 수정하거나 제거해야 합니다.

    PnP 쿼리 IRP에 대한 응답으로 정보를 반환하는 경우 드라이버는 이 규칙을 따라 디바이스에 대해 계층화된 드라이버가 순서대로 정보를 전달할 수 있도록 해야 합니다.

  • 명시적으로 문서화된 경우를 제외하고 드라이버는 특정 순서로 전송되는 PnP IRP에 의존해서는 안됩니다.

  • 드라이버가 PnP IRP를 보낼 때 IRP를 디바이스 스택의 최상위 드라이버로 보내야 합니다.

    대부분의 PnP IRP는 PnP 관리자에 의해 전송되지만 일부는 드라이버에서 보낼 수 있습니다(예: IRP_MN_QUERY_INTERFACE). 드라이버는 디바이스 스택의 맨 위에 있는 드라이버에 PnP IRP를 보내야 합니다. IoGetAttachedDeviceReference를 호출하여 디바이스 스택 맨 위에 있는 드라이버의 디바이스 개체에 대한 포인터를 가져옵니다.