다음을 통해 공유


I/O 큐 관리

I/O 큐 시작

드라이버가 WdfIoQueueCreate 를 호출하여 I/O 큐를 만들면 프레임워크는 자동으로 큐에서 I/O 요청을 수신하고 드라이버에 전달할 수 있도록 합니다.

드라이버는 일반적으로 EvtDriverDeviceAdd 콜백 함수 내에서 WdfIoQueueCreate를 호출합니다. 프레임워크는 드라이버의 EvtDriverDeviceAdd 콜백 함수가 반환된 후 드라이버에 I/O 요청을 배달하기 시작할 수 있습니다.

드라이버가 전원 관리 형 I/O 큐를 사용하는 경우 디바이스가 작동 상태로 들어가고 프레임워크가 드라이버의 EvtDeviceD0Entry 콜백 함수를 호출할 때까지 프레임워크에서 드라이버에 요청 배달을 시작할 수 없습니다.

I/O 큐 중지 및 다시 시작

드라이버는 WdfIoQueueStop 또는 WdfIoQueueStopSynchronously 를 호출하여 프레임워크가 I/O 큐에서 I/O 요청을 전달하지 못하도록 일시적으로 방지할 수 있습니다. I/O 요청 배달을 다시 시작하기 위해 드라이버는 WdfIoQueueStart를 호출합니다.

드라이버에서 전원 관리형 I/O 큐를 사용하는 경우 디바이스가 작동(D0) 상태를 벗어나면 프레임워크가 자동으로 디바이스의 큐를 중지하고, 디바이스 상태가 D0으로 반환되면 프레임워크가 큐를 다시 시작합니다.

I/O 큐에 요청 추가

시스템에서 드라이버에 읽기, 쓰기 또는 디바이스 I/O 제어 요청을 보내면 프레임워크는 요청을 I/O 큐에 배치합니다. 드라이버는 WdfDeviceConfigureRequestDispatching을 호출하여 프레임워크가 각 큐에 저장하는 요청 유형을 제어할 수 있습니다.

또한 드라이버는 WdfRequestForwardToIoQueue를 호출하여 프레임워크에서 받은 요청을 다시 큐에 추가할 수 있습니다.

I/O 큐에서 요청 가져오기

드라이버가 I/O 큐에 대한 순차적 또는 병렬 디스패치 메서드를 지정하는 경우 요청 처리기에서 요청을 받습니다.

드라이버가 수동 또는 순차적 디스패치 메서드를 지정하는 경우 WdfIoQueueRetrieveNextRequest 또는 WdfIoQueueRetrieveRequestByFileObject를 호출하여 요청을 가져올 수 있습니다.

I/O 요청 검색

드라이버가 I/O 큐에 대한 수동 디스패치 메서드를 지정하는 경우 다음 단계를 사용하여 큐의 특정 요청을 검색할 수 있습니다.

  1. WdfIoQueueFindRequest를 호출하여 드라이버 지정 조건과 일치하는 요청을 찾습니다.

  2. WdfIoQueueRetrieveFoundRequest를 호출하여 WdfIoQueueFindRequest가 찾은 요청을 검색합니다.

I/O 큐 제거 또는 드레이닝

I/O 큐를 제거한다는 것은 큐에 I/O 요청 삽입을 중지하고 큐에 이미 있는 요청을 취소하는 것을 의미합니다.

I/O 큐를 드레이닝한다는 것은 큐에 이미 있는 모든 요청을 드라이버에 배달할 수 있도록 허용하면서 큐에 I/O 요청 삽입을 중지하는 것을 의미합니다.

드라이버는 일반적으로 큐가 전원 관리되지 않는 경우에만 큐를 제거하거나 드레이닝합니다. 전원 관리 I/O 큐의 경우 드라이버는 EvtIoStopEvtIoResume 콜백 함수를 제공할 수 있습니다.

일부 드라이버 큐가 전원 관리되지 않는 경우 연결된 디바이스 또는 I/O 채널을 사용할 수 없게 되면 큐를 제거하거나 드레이닝할 수 있습니다. 일반적으로 각 요청에 매우 중요한 정보가 포함될 가능성이 높은 경우가 아니면 드레이닝 대신 큐를 제거합니다. 예를 들어 네트워크 디바이스의 드라이버는 큐를 제거할 수 있지만 스토리지 디바이스의 드라이버는 큐를 드레이닝할 수 있습니다.

드라이버가 I/O 큐를 제거하거나 드레이닝하도록 하려면 드라이버는 다음 큐 개체 메서드 중 하나를 호출할 수 있습니다.

WdfIoQueueDrainWdfIoQueueDrainSynchronously를 호출할 때 주의해야 합니다. 드레이닝 작업은 요청이 완료될 때까지 대기하므로 큐의 보류 중인 요청이 적시에 완료될 것으로 확신하는 경우에만 큐를 드레이닝해야 합니다. I/O 요청이 완료되는 데 걸리는 시간을 모르고 미해결 요청을 취소할 수 있는 경우 큐를 제거하는 것이 좋습니다.

한 I/O 큐에서 다른 큐로 요청 이동

드라이버가 I/O 요청을 받은 후 드라이버가 요청을 다른 I/O 큐에 다시 큐에 넣도록 할 수 있습니다. 이를 위해 드라이버는 WdfRequestForwardToIoQueue 또는 WdfRequestForwardToParentDeviceIoQueue를 호출하여 지정된 큐의 꼬리에 요청을 추가합니다. 결국 프레임워크는 지정된 큐의 디스패치 메서드를 사용하여 드라이버에 요청을 다시 전달합니다. I/O 요청을 한 I/O 큐에서 다른 큐로 이동하는 방법에 대한 자세한 내용은 I/O 요청 다시 큐에 넣기를 참조하세요.

큐에 대기하기 전에 I/O 요청 가로채기

프레임워크가 요청을 I/O 큐에 배치하기 전에 드라이버가 I/O 요청을 가로챌 수 있습니다. I/O 요청을 가로채려면 드라이버가 WdfDeviceInitSetIoInCallerContextCallback 을 호출하여 EvtIoInCallerContext 콜백 함수를 등록해야 합니다.

프레임워크는 EvtIoInCallerContext 콜백 함수를 디바이스와 연결합니다. 결과적으로 프레임워크는 시스템이 디바이스로 보내는 요청을 받을 때마다 EvtIoInCallerContext 콜백 함수를 호출합니다.

일반적으로 EvtIoInCallerContext 콜백 함수가 요청을 받으면 요청에 대한 일부 예비 처리를 수행합니다. 다음으로 콜백 함수는 WdfDeviceEnqueueRequest를 호출하여 프레임워크에 요청을 다시 제공합니다. 그런 다음 프레임워크는 EvtIoInCallerContext 콜백 함수를 호출하지 않은 경우와 마찬가지로 적절한 I/O 큐에 요청을 배치할 수 있습니다.

드라이버가 EvtIoInCallerContext 콜백 함수를 제공할 수 있는 주된 이유는 드라이버가 버퍼링되거나 직접 I/O가 아닌 I/O 메서드를 지원하는 I/O 작업을 처리해야 하기 때문입니다. 이 I/O 메서드의 경우 드라이버는 I/O 요청의 보낸 사람의 프로세스 컨텍스트에서 수신된 버퍼에 액세스해야 합니다. 자세한 내용은 Framework-Based 드라이버에서 데이터 버퍼 액세스를 참조하세요.

I/O 큐 속성 가져오기

프레임워크 큐 개체의 속성을 가져오기 위해 드라이버는 다음 메서드를 호출할 수 있습니다.