애플리케이션, 시스템 또는 드라이버에서 디바이스의 진행 중인 I/O 작업(예: 디스크에서 여러 블록을 읽는 요청)을 취소할 수 있습니다. 디바이스의 I/O 작업이 취소되면 I/O 관리자는 I/O 작업과 연결된 처리되지 않은 모든 I/O 요청을 취소하려고 시도합니다. I/O 관리자가 I/O 요청을 취소하려고 할 때 디바이스의 드라이버가 알림을 받도록 등록할 수 있으며, 드라이버는 완료 상태가 STATUS_CANCELLED 완료하는 자신이 소유한 요청을 취소할 수 있습니다.
프레임워크는 프레임워크 기반 드라이버에 대한 일부 취소 작업을 처리합니다. 디바이스의 I/O 작업이 취소되면 프레임워크는 취소된 작업과 연결된 다음 I/O 요청(완료 상태가 STATUS_CANCELLED)을 완료합니다.
드라이버의 기본 I/O 큐에 프레임워크가 배치한 배달되지 않은 I/O 요청.
프레임워크가 드라이버가 WdfDeviceConfigureRequestDispatching호출했기 때문에 배달되지 않은 I/O 요청을 다른 큐로 이미 전달했습니다.
프레임워크는 이러한 요청을 취소하므로 드라이버에 전달하지 않습니다.
프레임워크가 드라이버에 I/O 요청을 전달한 후에는 드라이버 요청을 소유하고 프레임워크는 취소할 수 없습니다. 이 시점에서는 드라이버만 I/O 요청을 취소할 수 있지만 프레임워크는 요청을 취소해야 한다고 드라이버에 알려야 합니다. 드라이버는 EvtRequestCancel 콜백 함수를 제공하여 이 알림을 받습니다.
경우에 따라 드라이버는 I/O 큐에서 I/O 요청을 수신하지만 요청을 처리하는 대신 나중에 처리하기 위해 동일한 또는 다른 I/O 큐에 요청을 다시 큐에 추가합니다. 이 상황의 예는 다음과 같습니다.
프레임워크는 드라이버의요청 처리기 중 하나에 I/O 요청을 전달하며, 이후 드라이버는 WdfRequestForwardToIoQueue(또는 WdfRequestForwardToParentDeviceIoQueue)를 사용하여 요청을 다른 큐에 배치하거나 WdfRequestRequeue요청을 동일한 큐에 다시 배치합니다.
프레임워크는 드라이버의 EvtIoInCallerContext 콜백 함수에 I/O 요청을 전달하고, 드라이버는 WdfDeviceEnqueueRequest 호출하여 요청을 프레임워크에 다시 전달하고, 프레임워크는 이후에 드라이버의 I/O 큐 중 하나에 요청을 배치합니다.
이러한 경우 요청이 I/O 큐에 있으므로 프레임워크에서 I/O 요청을 취소할 수 있습니다. 그러나 드라이버가 요청이 있는 I/O 큐에 대한 EvtIoCanceledOnQueue 콜백 함수를 등록한 경우 프레임워크는 연결된 I/O 작업이 취소될 때 요청을 취소하는 대신 콜백 함수를 호출합니다. 프레임워크가 드라이버의 EvtIoCanceledOnQueue 콜백 함수를 호출하는 경우 드라이버가 요청을 완료해야 합니다.
요약하면 I/O 작업이 취소되면 프레임워크는 드라이버에 전달되지 않은 연결된 모든 I/O 요청을 항상 취소합니다. 드라이버가 요청을 수신한 다음 다시 큐에 넣은 경우 드라이버가 I/O 큐에 대한 EvtIoCanceledOnQueue 콜백 함수를 제공하지 않는 한 프레임워크는 요청을 취소합니다(요청이 큐에 있는 경우).
WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx를 호출하는 경우
드라이버는 WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx 호출하여 EvtRequestCancel 콜백 함수를 등록할 수 있습니다. 드라이버가 WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx호출하고 요청과 연결된 I/O 작업이 취소된 경우 프레임워크는 드라이버가 I/O 요청을 취소할 수 있도록 드라이버의 EvtRequestCancel 콜백 함수를 호출합니다.
드라이버는 비교적 오랜 시간 동안 요청을 소유하게 될 경우, WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx 을 호출해야 합니다. 예를 들어, 드라이버는 디바이스가 응답할 때까지 기다려야 하거나 드라이버가 단일 요청을 받았을 때 만든 요청 집합이 하위 드라이버에서 완료될 때까지 기다릴 수 있습니다.
드라이버가 WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx을 호출하지 않거나, WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx을 호출한 후에 WdfRequestUnmarkCancelable을 호출하는 경우, 드라이버는 취소를 인식하지 못하므로 일반적으로 요청을 처리합니다.
WdfRequestIsCanceled를 호출하기
드라이버가 WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx 호출하여 EvtRequestCancel 콜백 함수를 등록하지 않은 경우 WdfRequestIsCanceled 호출하여 I/O 관리자가 I/O 요청을 취소하려고 했는지 확인할 수 있습니다. WdfRequestIsCanceledTRUE을 반환하고 드라이버가 요청을 소유하는 경우, 드라이버는 요청을 취소해야 합니다. 드라이버가 요청을 소유하지 않으면 WdfRequestIsCanceled 호출해서는 안 됩니다.
WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx 호출하지 않은 드라이버는 다음과 같은 상황에서 WdfRequestIsCanceled 호출할 수 있습니다.
디바이스 인터럽트를 기다리는 드라이버는 EvtInterruptDpc 콜백 함수에서 WdfRequestIsCanceled 호출할 수 있습니다.
디바이스를 폴링하는 드라이버는 폴링 스레드에서 WdfRequestIsCanceled 호출할 수 있습니다.
드라이버가 DMA 트랜잭션을 여러 개의 작은 전송으로 나눈 후, 각 전송이 완료될 때마다 WdfRequestIsCanceled를 호출할 수 있습니다.
수신된 요청에 대해 WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx를 호출하지 않은 경우, 드라이버는 큰 읽기 또는 쓰기 요청을 여러 개의 작은 요청으로 분할하고 각 작은 요청이 드라이버의 I/O 대상에 의해 완료될 때마다 WdfRequestIsCanceled를 호출할 수 있습니다.
요청 취소
I/O 요청을 취소하면 다음 중 하나라도 포함될 수 있습니다.
진행 중인 I/O 작업을 중지합니다.
I/O 대상에 요청을 전달하지 않습니다.
WdfRequestCancelSentRequest 호출은 드라이버가 이전에 I/O 대상에 제출한 요청을 취소하려고 시도하는을 호출하는 것입니다.
드라이버가 프레임워크에서 받은 요청 개체에 대한 I/O 요청을 취소하는 경우 드라이버는 STATUS_CANCELLED Status 매개 변수를 사용하여 WdfRequestComplete, WdfRequestCompleteWithInformation또는 WdfRequestCompleteWithPriorityBoost호출하여 항상 요청을 완료해야 합니다. (드라이버가 요청 개체를 만들기 위해 WdfRequestCreate 호출하는 경우 드라이버는 요청을 완료하는 대신 WdfObjectDelete 호출합니다.)
취소 동작 동기화
I/O 요청을 취소하는 코드를 동기화하는 방법에 대한 자세한 내용은 다음을 참조하세요.