WdfRequestMarkCancelable 함수(wdfrequest.h)
[KMDF 및 UMDF에 적용]
WdfRequestMarkCancelable 메서드를 사용하면 지정된 I/O 요청을 취소할 수 있습니다.
구문
void WdfRequestMarkCancelable(
[in] WDFREQUEST Request,
[in] PFN_WDF_REQUEST_CANCEL EvtRequestCancel
);
매개 변수
[in] Request
프레임워크 요청 개체에 대한 핸들입니다.
[in] EvtRequestCancel
I/O 요청을 취소하는 경우 프레임워크가 호출하는 드라이버 정의 EvtRequestCancel 콜백 함수에 대한 포인터입니다.
반환 값
없음
설명
드라이버가 잘못된 개체 핸들을 제공하는 경우 버그 검사 발생합니다.
드라이버가 프레임워크에서 I/O 요청을 받은 후 드라이버는 WdfRequestMarkCancelable 을 호출하거나 KMDF 버전 1.9부터 WdfRequestMarkCancelableEx 를 호출하여 요청을 취소할 수 있도록 할 수 있습니다.
WdfRequestMarkCancelable을 호출할 때 드라이버는 EvtRequestCancel 콜백 함수를 지정해야 합니다. I/O 관리자 또는 다른 드라이버가 I/O 요청을 취소하려고 하는 경우 프레임워크는 콜백 함수를 호출합니다.
WdfRequestMarkCancelable과 WdfRequestMarkCancelableEx 중에서 선택
드라이버가 프레임워크의 자동 동기화를 사용하는 경우 드라이버는 WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx를 호출할 수 있습니다.드라이버가 자동 동기화를 사용하지 않는 경우 다음과 같은 이유로 WdfRequestMarkCancelable 대신 WdfRequestMarkCancelableEx 를 호출해야 합니다.
- 지정된 요청이 이미 취소된 경우 WdfRequestMarkCancelable 은 반환하기 전에 드라이버의 EvtRequestCancel 콜백 함수를 호출합니다. 드라이버가 WdfRequestMarkCancelable 을 호출하기 전에 스핀 잠금을 획득하고 EvtRequestCancel 내에서 동일한 스핀 잠금을 획득하려고 하면 동일한 스레드가 동일한 스핀 잠금을 두 번 획득하려고 시도하여 교착 상태가 발생합니다.
- 그러나 WdfRequestMarkCancelableEx 는 EvtRequestCancel을 호출하지 않으므로 이 시나리오는 발생하지 않습니다. 요청이 이미 취소된 경우 WdfRequestMarkCancelableEx 는 STATUS_CANCELLED 반환합니다. 드라이버가 WdfRequestMarkCancelableEx 를 호출하기 전에 스핀 잠금(IRQL을 DISPATCH_LEVEL 설정)을 획득하고 WdfRequestMarkCancelableEx 가 반환된 후 스핀 잠금(IRQL을 PASSIVE_LEVEL 설정)을 해제하는 경우 스핀 잠금이 해제되기 전에 EvtRequestCancel 콜백 함수가 호출되지 않습니다. 따라서 EvtRequestCancel 콜백 함수가 동일한 스핀 잠금을 사용하는 경우에도 교착 상태가 발생하지 않습니다.
취소를 사용하도록 설정한 후 요청 처리
드라이버가 WdfRequestMarkCancelable을 호출하여 취소를 사용하도록 설정한 후에는 드라이버가 WdfRequestUnmarkCancelable을 호출하지 않는 한 드라이버가 요청 개체를 소유하는 동안 요청을 취소할 수 있습니다.드라이버가 WdfRequestMarkCancelable을 호출하고 드라이버의 EvtRequestCancel 콜백 함수가 실행되지 않고 WdfRequestComplete를 호출한 경우 드라이버는 EvtRequestCancel 콜백 함수 외부에서 WdfRequestComplete를 호출하기 전에 WdfRequestUnmarkCancelable을 호출해야 합니다.
드라이버가 WdfRequestForwardToIoQueue 를 호출하여 요청을 다른 큐로 전달하는 경우 다음 규칙이 적용됩니다.
-
드라이버가 다른 큐로 전달할 때 I/O 요청을 취소할 수 없습니다.
일반적으로 드라이버는 WdfRequestForwardToIoQueue 를 호출하기 전에 요청을 취소할 수 있도록 WdfRequestMarkCancelable을 호출해서는 안 됩니다. 드라이버가 요청을 취소할 수 있도록 하는 경우 WdfRequestForwardToIoQueue를 호출하기 전에 취소를 사용하지 않도록 설정하려면 WdfRequestUnmarkCancelable을 호출해야 합니다.
-
요청이 두 번째 큐에 있는 동안 프레임워크는 요청을 소유하고 드라이버에 알리지 않고 취소할 수 있습니다.
드라이버에 취소 알림이 필요한 경우( WdfRequestForwardToIoQueue를 호출하기 전에 할당되었을 수 있는 리소스의 할당을 취소할 수 있도록) 드라이버는 EvtIoCanceledOnQueue 콜백 함수를 등록해야 하며 요청 관련 컨텍스트 메모리를 사용하여 요청의 리소스에 대한 정보를 저장해야 합니다.
- 프레임워크가 두 번째 큐에서 요청을 큐에서 제거하고 드라이버에 전달한 후 드라이버는 WdfRequestMarkCancelable 을 호출하여 취소를 사용하도록 설정할 수 있습니다.
예제
다음 코드 예제에서는 두 콜백 함수의 일부를 보여 줍니다.
- 요청별 작업(예: I/O 대상에 보낼 하위 쿼리 만들기)을 수행한 다음 수신된 I/O 요청을 취소하는 EvtIoRead 콜백 함수입니다.
- I/O 요청을 취소하는 EvtRequestCancel 콜백 함수입니다.
VOID
MyEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
...
// Perform request-specific work here
// (such as creating subrequests
// to send to an I/O target).
...
WdfRequestMarkCancelable(
Request,
MyEvtRequestCancel
);
}
...
}
VOID
MyEvtRequestCancel(
IN WDFREQUEST Request
)
{
// Remove request-specific work here, because
// we don't want the work to be done if the
// request was canceled.
WdfRequestComplete(
Request,
STATUS_CANCELLED
);
}
요구 사항
요구 사항 | 값 |
---|---|
대상 플랫폼 | 유니버설 |
최소 KMDF 버전 | 1.0 |
최소 UMDF 버전 | 2.0 |
머리글 | wdfrequest.h(Wdf.h 포함) |
라이브러리 | Wdf01000.sys(KMDF); WUDFx02000.dll(UMDF) |
IRQL | <=DISPATCH_LEVEL |
DDI 규정 준수 규칙 | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), EvtIoStopCancel(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MarkCancOnCancReqLocal(kmdf), ReqIsCancOnCancReq(kmdf), ReqMarkCancelableSend(kmdf), ReqNotCanceledLocal(kmdf), RequestCompleted(kmdf), RequestCompletedLocal( kmdf) |