읽기/쓰기 디스패치 루틴 요약
DispatchRead, DispatchWrite 또는 DispatchReadWrite 루틴을 구현할 때 다음 사항에 유의하세요.
IRP에서 다음 하위 수준 드라이버의 I/O 스택 위치를 설정하기 전에 유효성을 위해 들어오는 읽기/쓰기 IRP의 매개 변수를 검사 계층화된 드라이버 체인에서 최상위 드라이버의 책임입니다.
중간 및 최저 수준 드라이버는 일반적으로 체인의 최상위 드라이버를 사용하여 유효한 매개 변수를 사용하여 전송 요청을 전달할 수 있습니다. 그러나 모든 드라이버는 IRP의 I/O 스택 위치에 있는 매개 변수에 대한 온전성 검사를 수행할 수 있으며, 각 디바이스 드라이버는 디바이스에 의해 부과되는 제한을 위반할 수 있는 조건에 대한 매개 변수를 검사 합니다.
DispatchReadWrite 루틴이 오류와 함께 IRP를 완료하는 경우 적절한 NTSTATUS 형식 값으로 I/O 스택 위치 Status 멤버를 설정하고, 정보 멤버를 0으로 설정하고, IRP 및 IO_NO_INCREMENT PriorityBoost를 사용하여 IoCompleteRequest를 호출해야 합니다.
드라이버가 버퍼링된 I/O를 사용하는 경우 전송할 데이터를 포함하는 구조를 정의해야 할 수 있으며 이러한 구조체 중 일부를 내부적으로 버퍼링해야 할 수 있습니다.
드라이버가 직접 I/O를 사용하는 경우 Irp-MdlAddress>의 MDL이 단일 전송 작업에서 처리할 기본 디바이스에 대해 너무 많은 데이터(또는 너무 많은 페이지 나누기)가 포함된 버퍼를 설명하는지 여부를 검사 수 있습니다. 이 경우 드라이버는 원래 전송 요청을 더 작은 전송 작업의 시퀀스로 분할해야 합니다.
밀접하게 결합된 클래스 드라이버는 기본 포트 드라이버에 대한 DispatchReadWrite 루틴에서 이러한 요청을 분할할 수 있습니다. SCSI 클래스 드라이버, 특히 대용량 스토리지 디바이스의 경우 이 작업을 수행해야 합니다. SCSI 드라이버의 요구 사항에 대한 자세한 내용은 스토리지 드라이버를 참조하세요.
하위 수준 디바이스 드라이버의 DispatchReadWrite 루틴은 다른 드라이버 루틴이 IRP를 큐에서 제거하여 전송을 위해 디바이스를 설정할 때까지 큰 전송 요청을 부분 전송으로 분할하는 것을 연기해야 합니다.
하위 수준 디바이스 드라이버가 자체 루틴에서 추가 처리를 위해 읽기/쓰기 IRP를 큐에 대기하는 경우 IRP를 큐에 넣기 전에 IoMarkIrpPending을 호출해야 합니다. 또한 DispatchReadWrite 루틴은 이러한 상황에서 STATUS_PENDING 컨트롤을 반환해야 합니다.
DispatchReadWrite 루틴이 IRP를 낮은 드라이버에 전달하는 경우 IRP의 다음 하위 드라이버에 대한 I/O 스택 위치를 설정해야 합니다. 상위 수준 드라이버가 IoCallDriver로 전달하기 전에 IRP에서 IoCompletion 루틴을 설정하는지 여부는 드라이버의 디자인과 그 아래에 계층화된 드라이버의 디자인에 따라 달라집니다.
그러나 상위 수준 드라이버는 IRP 또는 메모리와 같은 리소스를 할당하는 경우 IoCallDriver를 호출하기 전에 IoSetCompletionRoutine을 호출해야 합니다. 해당 IoCompletion 루틴은 낮은 드라이버가 요청을 완료했지만 IoCompletion 루틴이 원래 IRP로 IoCompleteRequest를 호출하기 전에 드라이버 할당 리소스를 해제해야 합니다.
상위 수준 드라이버가 기본 이동식 미디어 디바이스 드라이버를 포함할 수 있는 하위 드라이버에 대해 IRP를 할당하는 경우 할당 드라이버는 할당하는 각 IRP에서 스레드 컨텍스트를 설정해야 합니다.