버퍼링되지 않거나 직접 I/O 사용

드라이버가 버퍼링되거나 직접 I/O를 사용하지 않는 경우 I/O 관리자는 드라이버에 보내는 원래 사용자 공간 가상 주소를 IRP로 전달합니다. 이러한 버퍼에 안전하게 액세스하려면 드라이버가 호출 스레드의 컨텍스트에서 실행되어야 합니다. 따라서 일반적으로 FSD와 같은 최상위 드라이버만 이 메서드를 사용하여 버퍼에 액세스할 수 있습니다.

중간 또는 최저 수준 드라이버는 항상 이 조건을 충족할 수 없습니다. 예를 들어 요청 스레드가 I/O 요청이 완료될 때까지 대기하거나 상위 수준 드라이버가 중간 또는 최저 수준 드라이버 위에 계층화된 경우 요청 스레드의 컨텍스트에서 하위 수준 드라이버의 루틴을 호출할 가능성이 낮습니다.

I/O 관리자는 다음과 같이 I/O 작업이 버퍼링되거나 직접 I/O를 사용하지 않는지 확인합니다.

드라이버가 버퍼링되거나 직접 I/O를 사용하지 않고 I/O 작업을 지정하는 IRP를 수신하는 경우 다음을 수행해야 합니다.

  1. 사용자 버퍼의 주소 범위의 유효성을 확인하고 ProbeForReadProbeForWrite 지원 루틴을 사용하여 적절한 읽기 또는 쓰기 액세스가 허용되는지 검사. 드라이버는 드라이버가 메모리에 액세스하는 동안 사용자 스레드가 버퍼에 대한 액세스 권한을 변경할 수 없도록 드라이버에서 제공하는 예외 처리기 내에서 버퍼의 주소 범위에 대한 액세스를 묶어야 합니다. 프로브에서 예외가 발생하면 드라이버는 오류를 반환해야 합니다. 드라이버는 I/O 요청을 수행한 스레드의 컨텍스트 내에서 이러한 루틴을 호출해야 합니다. 따라서 상위 수준 드라이버만 이 작업을 수행할 수 있습니다.

  2. 다음 방법 중 하나로 버퍼 및 메모리 작업을 관리합니다.

    • I/O 관리자가 버퍼링된 I/O를 사용하는 드라이버에 대해 수행하는 것처럼 자체 이중 버퍼링 작업을 수행합니다. 자세한 내용은 버퍼링된 I/O 사용을 참조하세요.
    • I/O 관리자가 직접 I/O를 사용하는 드라이버에 대해 수행하는 것처럼 자체 MDL을 만들고 메모리 관리자의 지원 루틴을 호출하여 버퍼를 잠급니다. 자세한 내용은 직접 I/O 사용을 참조하세요.
    • 호출 스레드의 컨텍스트에서 직접 사용자 버퍼에 필요한 모든 작업을 수행합니다. 드라이버가 메모리에 액세스하는 동안 사용자 스레드가 버퍼에 대한 액세스 권한 또는 버퍼의 데이터를 변경하는 경우 드라이버는 드라이버 제공 예외 처리기 내에서 버퍼에 대한 액세스를 래핑해야 합니다. 자세한 내용은 예외 처리를 참조하세요.

실제로 드라이버는 호출 스레드의 컨텍스트에서 버퍼링된 I/O, 직접 I/O 또는 I/O를 수행할지 여부를 IRP별로 선택해야 하며 사용자 모드 스레드 컨텍스트에서 발생할 수 있는 예외를 처리해야 합니다. 드라이버는 I/O 관리자가 드라이버에 대해 이러한 작업을 처리하도록 하는 대신 필요에 따라 자체 사용자 버퍼 액세스, 이중 버퍼링 작업 및 메모리 매핑을 관리해야 합니다.