다음을 통해 공유


버퍼링된 I/O를 사용하는 DispatchReadWrite

버퍼링된 I/O에 대한 디바이스 개체를 설정하는 가장 낮은 수준의 디바이스 드라이버는 디바이스에서 전송된 데이터를 Irp-AssociatedIrp.SystemBuffer>의 잠긴 시스템 공간 버퍼로 반환하여 읽기 요청을 충족합니다. 동일한 버퍼에서 디바이스로 데이터를 전송하여 쓰기 요청을 충족합니다.

따라서 이러한 디바이스 드라이버의 DispatchReadWrite 루틴은 일반적으로 전송 요청을 수신할 때 다음을 수행합니다.

  1. IoGetCurrentIrpStackLocation을 호출하고 전송 요청의 방향을 결정합니다.

  2. 요청에 대한 매개 변수의 유효성을 확인합니다.

    • 읽기 요청의 경우 루틴은 일반적으로 드라이버의 IoStackLocation-Parameters.Read.Length> 값을 확인하여 버퍼가 디바이스에서 전송된 데이터를 받을 수 있을 만큼 큰지 여부를 확인합니다.

      예를 들어 시스템 키보드 클래스 드라이버는 Win32 사용자 입력 스레드에서만 제공되는 읽기 요청을 처리합니다. 이 드라이버는 디바이스에서 키 입력을 저장하고, 들어오는 읽기 요청을 충족하기 위해 내부 링 버퍼에 이러한 구조의 일부 수를 보유하는 구조체 KEYBOARD_INPUT_DATA 정의합니다.

    • 쓰기 요청의 경우 루틴은 일반적으로 Parameters.Write.Length의 값을 확인하고 필요한 경우 Irp-AssociatedIrp.SystemBuffer>의 데이터를 확인합니다. 즉, 디바이스가 정의된 값 범위의 멤버를 포함하는 구조적 데이터 패킷만 허용하는 경우입니다.

  3. 매개 변수가 잘못된 경우 DispatchReadWrite 루틴은 IRP 완료에 이미 설명된 대로 IRP를 즉시 완료합니다. 그렇지 않으면, IRP를 다른 드라이버 루틴에서 추가 처리를 위해 전달하며, 이 과정은 드라이버 스택 아래로 IRP 전달에서 설명된 대로 진행됩니다.

버퍼링된 I/O를 사용하는 가장 낮은 수준의 디바이스 드라이버는 일반적으로 요청의 발신자가 지정한 크기의 데이터를 읽거나 작성하여 전송 요청을 충족해야 합니다. 이러한 드라이버는 디바이스에서 들어오거나 디바이스로 전송되는 데이터의 구조를 정의할 가능성이 높으며 시스템 키보드 클래스 드라이버와 마찬가지로 구조화된 데이터를 내부적으로 버퍼링할 가능성이 높습니다.

내부적으로 데이터를 버퍼링하는 드라이버는 IRP_MJ_FLUSH_BUFFERS 요청을 지원해야 하며 IRP_MJ_SHUTDOWN 요청을 지원할 수도 있습니다.

체인에서 가장 높은 수준의 드라이버는 일반적으로 낮은 드라이버에 읽기/쓰기 요청을 전달하기 전에 입력 IRP의 매개 변수를 확인하는 역할을 합니다. 따라서 많은 하위 수준 드라이버는 읽기/쓰기 IRP의 I/O 스택 위치에 유효한 매개 변수가 있다고 가정할 수 있습니다. 체인의 최하위 수준 드라이버가 데이터 전송에 대한 디바이스별 제약 조건을 알고 있는 경우 해당 드라이버는 I/O 스택 위치에서 매개 변수의 유효성을 확인해야 합니다.