다음을 통해 공유


드라이버 스택 아래로 IRP 전달

드라이버의 디스패치 루틴이 IRP를 받으면 자체 I/O 스택 위치를 검사 매개 변수가 유효한지 확인할 수 있도록 IoGetCurrentIrpStackLocation을 호출해야 합니다. 드라이버가 요청 자체를 충족하고 완료할 수 없는 경우 다음 중 하나를 수행할 수 있습니다.

  • 하위 수준 드라이버의 추가 처리를 위해 IRP를 에 전달합니다.

  • 하나 이상의 새 IRP를 만들고 하위 수준 드라이버에 전달합니다.

상위 수준 드라이버는 다음과 같이 I/O 요청을 다음 하위 드라이버에 전달해야 합니다.

  1. 드라이버가 입력 IRP를 다음 하위 수준 드라이버에 전달하는 경우 디스패치 루틴은 IoSkipCurrentIrpStackLocation 또는 IoCopyCurrentIrpStackLocationToNext 를 호출하여 다음 하위 드라이버의 I/O 스택 위치를 설정해야 합니다.

    드라이버가 IoAllocateIrp 를 호출하여 하위 드라이버에 대해 하나 이상의 추가 IRP를 할당하는 경우 디스패치 루틴은 Intermediate-Level 드라이버에서 IRP 처리에 설명된 단계에 따라 다음 하위 드라이버의 I/O 스택 위치를 초기화해야 합니다.

    디스패치 루틴은 특정 요청에 대해 다음으로 낮은 드라이버의 I/O 스택 위치에 있는 일부 매개 변수를 수정할 수 있습니다. 예를 들어 상위 수준 드라이버는 기본 디바이스에 전송 용량의 알려진 제한이 있는 경우 대용량 전송 요청에 대한 매개 변수를 수정하고 IRP를 다시 사용하여 기본 디바이스 드라이버에 부분 전송 요청을 보낼 수 있습니다.

  2. IoSetCompletionRoutine을 호출합니다.

    디스패치 루틴이 수신된 IRP를 다음 하위 드라이버에 전달하는 경우 IoCompletion 루틴을 설정하는 것은 선택 사항이지만 유용합니다. 루틴은 낮은 드라이버가 요청을 완료한 방법을 결정하고, 부분 전송을 위해 IRP를 다시 사용하고, IRP를 추적하는 경우 드라이버가 유지 관리하는 상태를 업데이트하고, 오류와 함께 반환된 요청을 다시 시도하는 등의 작업을 수행할 수 있기 때문입니다.

    디스패치 루틴에서 새 IRP를 할당한 경우 낮은 드라이버가 완료된 후 루틴이 각 IRP를 해제해야 하므로 IoCompletion 루틴을 설정해야 합니다.

    IoCompletion 루틴에 대한 자세한 내용은 IRP 완료를 참조하세요.

  3. 낮은 드라이버에서 처리할 각 IRP를 사용하여 IoCallDriver 를 호출합니다.

  4. 다음과 같은 적절한 NTSTATUS 값을 반환합니다.

    • STATUS_PENDING

      일반적으로 드라이버는 입력 IRP가 IRP_MJ_READ 또는 IRP_MJ_WRITE 같은 비동기 요청인 경우 STATUS_PENDING 반환합니다.

    • IoCallDriver 호출의 결과

      입력 IRP가 IRP_MJ_CREATE 같은 동기 요청인 경우 드라이버는 IoCallDriver 호출 결과를 자주 반환합니다.

가장 낮은 수준의 디바이스 드라이버는 다음과 같이 디스패치 루틴에서 완료할 수 없는 모든 IRP를 다른 드라이버 루틴에 전달합니다.

  1. 입력 IRP 를 사용하여 IoMarkIrpPending 을 호출합니다.

  2. 드라이버 관리 IRP 큐에 설명된 대로 드라이버가 자체 내부 IRP 큐를 관리하지 않는 한 IoStartPacket 을 호출하여 드라이버의 StartIo 루틴에 IRP를 전달하거나 큐에 대기합니다.

    드라이버에 StartIo 루틴이 없지만 취소 가능한 IRP를 처리하는 경우 취소 루틴을 등록하거나 취소 안전 IRP 큐를 구현해야 합니다. 루틴 취소 에 대한 자세한 내용은 IRP 취소를 참조하세요.

  3. STATUS_PENDING 반환합니다.