대화형 또는 느린 디바이스를 서비스하는 드라이버 또는 일반적으로 한 번에 비교적 적은 양의 데이터를 전송하는 드라이버는 버퍼링된 I/O 전송 방법을 사용해야 합니다. 작은 대화형 전송에 버퍼링된 I/O를 사용하면 메모리 관리자가 직접 I/O를 요청하는 드라이버와 마찬가지로 각 전송에 대한 전체 물리적 페이지를 잠글 필요가 없으므로 전반적인 실제 메모리 사용량이 향상됩니다. 일반적으로 비디오, 키보드, 마우스, 직렬 및 병렬 드라이버는 버퍼링된 I/O를 요청합니다.
I/O 관리자는 다음과 같이 I/O 작업이 버퍼링된 I/O를 사용하고 있음을 확인합니다.
IRP_MJ_READ 및 IRP_MJ_WRITE 요청의 경우 DO_BUFFERED_IO DEVICE_OBJECT 구조의 Flags 멤버에 설정됩니다. 자세한 내용은 디바이스 개체 초기화참조하세요.
IRP_MJ_DEVICE_CONTROL 및 IRP_MJ_INTERNAL_DEVICE_CONTROL 요청의 경우 IOCTL 코드의 값에는 METHOD_BUFFERED IOCTL 값의 TransferType 값으로 포함됩니다. 자세한 내용은 I/O 제어 코드 정의을 참조하세요.
다음 그림에서는 I/O 관리자가 버퍼링된 I/O를 사용하는 전송 작업에 대한 IRP_MJ_READ 요청을 설정하는 방법을 보여 줍니다.
이 그림은 드라이버가 읽기 요청에 대한 데이터를 전송하기 위해 IRP에서 SystemBuffer 포인터를 사용하는 방법의 개요를 보여주며, 드라이버가 디바이스 객체의 Flags를 DO_BUFFERED_IO와 OR 연산했을 때를 설명합니다.
일부 사용자 공간 가상 주소 범위는 현재 스레드의 버퍼를 나타내며, 해당 버퍼의 콘텐츠는 페이지 기반 실제 주소 범위(이전 그림의 어두운 음영)의 범위 내에 어딘가에 저장될 수 있습니다.
I/O 관리자는 스레드가 버퍼를 나타내는 사용자 공간 가상 주소의 범위를 전달하는 현재 스레드의 읽기 요청을 처리합니다.
I/O 관리자는 사용자가 제공한 버퍼의 접근성을 확인하고 ExAllocatePoolWithTag 를 호출하여 사용자가 제공한 버퍼의 크기인 비페이지 시스템 공간 버퍼(SystemBuffer)를 만듭니다.
I/O 관리자는 드라이버에 보내는 IRP에서 새로 할당된 SystemBuffer 에 대한 액세스를 제공합니다.
그림에 쓰기 요청이 표시된 경우 I/O 관리자는 IRP를 드라이버로 보내기 전에 사용자 버퍼에서 시스템 버퍼로 데이터를 복사합니다.
이전 그림에 표시된 읽기 요청의 경우 드라이버는 디바이스에서 시스템 공간 버퍼로 데이터를 읽습니다. 이 버퍼의 메모리는 페이징되지 않으며 드라이버는 버퍼를 먼저 잠그지 않고도 안전하게 액세스할 수 있습니다. 읽기 요청이 충족되면 드라이버는 IRP를 사용하여 IoCompleteRequest 를 호출합니다.
원래 스레드가 다시 활성화되면 I/O 관리자는 시스템 버퍼에서 사용자 버퍼로 읽기 데이터를 복사합니다. 또한 ExFreePool 을 호출하여 시스템 버퍼를 해제합니다.
I/O 관리자가 드라이버에 대한 시스템 공간 버퍼를 만든 후 요청된 사용자 모드 스레드를 교환할 수 있으며 다른 프로세스에 속한 스레드에서 해당 실제 메모리를 다른 스레드에서 다시 사용할 수 있습니다. 그러나 IRP에 제공된 시스템 공간 가상 주소 범위는 드라이버가 IRP를 사용하여 IoCompleteRequest 를 호출할 때까지 유효합니다.
한 번에 많은 양의 데이터를 전송하는 드라이버, 특히 다중 페이지 전송을 수행하는 드라이버는 버퍼링된 I/O를 사용하려고 시도해서는 안 됩니다. 시스템이 실행되면 I/O 관리자가 이러한 드라이버에 대해 IRP로 보낼 큰 연속 시스템 공간 버퍼를 할당할 수 없도록 페이지가 없는 풀이 조각화될 수 있습니다.
일반적으로 드라이버는 직접 I/O를 사용하는 경우에도 IRP_MJ_DEVICE_CONTROL 요청과 같은 일부 유형의 IRP에 버퍼링 된 I/O를 사용합니다. 직접 I/O를 사용하는 드라이버는 일반적으로 IRP_MJ_READ 및 IRP_MJ_WRITE 요청 및 대용량 데이터 전송이 필요한 드라이버 정의 IRP_MJ_INTERNAL_DEVICE_CONTROL 요청에 대해서만 이 작업을 수행합니다.
모든 IRP_MJ_DEVICE_CONTROL 및 IRP_MJ_INTERNAL_DEVICE_CONTROL 요청에는 I/O 제어 코드가 포함됩니다. I/O 컨트롤 코드가 버퍼링된 I/O를 사용하여 IRP를 지원해야 한다고 나타내는 경우 I/O 관리자는 단일 시스템 버퍼를 사용하여 사용자 애플리케이션의 입력 및 출력 버퍼를 나타냅니다. 이러한 I/O 제어 코드를 지원하는 드라이버는 버퍼에서 입력 데이터(있는 경우)를 읽은 다음 입력 데이터를 덮어써 출력 데이터(있는 경우)를 제공해야 합니다. 자세한 내용은 I/O 제어 코드 정의을 참조하세요.