WdfRequestUnmarkCancelable 함수(wdfrequest.h)

[KMDF 및 UMDF에 적용]

WdfRequestUnmarkCancelable 메서드는 지정된 I/O 요청의 취소를 사용하지 않도록 설정합니다.

구문

NTSTATUS WdfRequestUnmarkCancelable(
  [in] WDFREQUEST Request
);

매개 변수

[in] Request

프레임워크 요청 개체에 대한 핸들입니다.

반환 값

WdfRequestUnmarkCancelable 은 작업이 성공하면 STATUS_SUCCESS 반환합니다. 그렇지 않으면 이 메서드는 다음 값 중 하나를 반환할 수 있습니다.

반환 코드 설명
STATUS_INVALID_PARAMETER
입력 매개 변수가 잘못되었거나 요청을 취소할 수 없습니다.
STATUS_INVALID_DEVICE_REQUEST
드라이버는 요청을 소유하지 않습니다.
STATUS_CANCELLED
요청이 취소되었습니다.
 

이 메서드는 다른 NTSTATUS 값을 반환할 수도 있습니다.

드라이버가 잘못된 개체 핸들을 제공하는 경우 버그 검사 발생합니다.

설명

드라이버가 이전에 WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx 를 호출하여 요청 취소를 사용하도록 설정한 경우 드라이버는 WdfRequestUnmarkCancelable 을 호출하여 I/O 요청 취소를 사용하지 않도록 설정할 수 있습니다 .

WdfRequestUnmarkCancelable이 STATUS_CANCELLED 이외의 값을 반환하는 경우 드라이버의 EvtRequestCancel 콜백 함수는 요청에 대해 호출되지 않습니다.

이전에 WdfRequestMarkCancelable 또는 WdfRequestMarkCancelableEx라는 드라이버의 경우 드라이버의 EvtRequestCancel 콜백 함수는 STATUS_CANCELLED Status 매개 변수를 사용하여 WdfRequestComplete를 호출할 수 있습니다. EvtRequestCancel 콜백 함수는 WdfRequestUnmarkCancelable을 호출할 필요가 없습니다. 드라이버가 EvtRequestCancel 콜백 함수 외부에서 WdfRequestComplete를 호출하는 경우 드라이버는 먼저 WdfRequestUnmarkCancelable을 호출해야 합니다.

그러나 EvtRequestCancel이 WdfRequestComplete 를 호출한 후에는 드라이버가 WdfRequestUnmarkCancelable 을 호출해서는 안 됩니다. 다음 예제 섹션에서 예제는 요청 핸들의 로컬 복사본을 저장한 다음 EvtRequestCancel 콜백 함수가 WdfRequestComplete를 호출할 때 이를 지웁니다. 요청 핸들의 로컬 복사본이 지워진 경우 드라이버는 WdfRequestUnmarkCancelable 을 호출하지 않습니다. 이 예제에서는 프레임워크의 자동 동기화 를 사용하여 콜백 함수를 동기화합니다.

WdfObjectReference를 호출하여 요청 개체에 대한 추가 참조를 추가해도 드라이버의 EvtRequestCancel 콜백 함수가 WdfRequestComplete를 호출한 후에는 드라이버가 WdfRequestUnmarkCancelable 호출할 수 없습니다.

WdfRequestUnmarkCancelable이 STATUS_CANCELLED 반환한 다음 EvtRequestCancel이 요청을 완료하는 경우 드라이버는 이후에 요청 개체를 사용하지 않아야 합니다.

WdfRequestUnmarkCancelable이 STATUS_CANCELLED 반환하는 경우 프레임워크가 EvtRequestCancel을 호출하기 전에 드라이버가 요청을 완료하지 않아야 합니다. 그렇지 않으면 프레임워크가 잘못된 요청으로 드라이버의 EvtRequestCancel 을 호출할 수 있습니다. 관련 코드 예제는 IWDFIoRequest::UnmarkCancelable을 참조하세요.

WdfRequestUnmarkCancelable에 대한 자세한 내용은 I/O 요청 취소를 참조하세요.

예제

다음 코드 예제에서는 ECHO 샘플 드라이버에 포함된 EvtIoRead, EvtRequestCancelEvtTimerFunc 콜백 함수의 간소화된 버전을 제공합니다. 이 예제에서는 프레임워크의 자동 동기화를 사용하는 드라이버에서 WdfRequestMarkCancelable, WdfRequestUnmarkCancelableWdfRequestComplete를 호출하는 방법을 보여 줍니다. (ECHO 샘플은 디바이스 수준 동기화를 사용합니다.)

드라이버가 프레임워크의 자동 동기화를 사용하지 않는 경우 IWDFIoRequest::UnmarkCancelable의 두 예제를 참조하세요. 이러한 예제에서는 UMDF 드라이버를 위해 작성되는 동안 취소 콜백과 표시 해제 루틴을 호출하는 다른 스레드 간의 동기화를 관리하는 데 사용할 수 있는 기술을 보여 줍니다.

VOID
  EchoEvtIoRead(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  Length
    )
{
    PQUEUE_CONTEXT queueContext = QueueGetContext(Queue);

    // Prepare for read operation here.
    // (See the Echo sample driver for details.) 
 ...
    // Enable cancellation.
    WdfRequestMarkCancelable(
                             Request,
                             EchoEvtRequestCancel
                             );

    // Save the request handle. We'll clear it after
    // we call WdfRequestComplete.
    queueContext->CurrentRequest = Request;
    return
}


VOID
 EchoEvtRequestCancel(
    IN WDFREQUEST  Request
    )
{
    PQUEUE_CONTEXT queueContext = 
        QueueGetContext(WdfRequestGetIoQueue(Request));

    WdfRequestComplete(
                       Request,
                       STATUS_CANCELLED,
     );
    // Clear the request handle so EchEvtTimerFunc will
    // know that we called WdfRequestComplete.
    queueContext->CurrentRequest = NULL;

    return;
}


VOID
  EchoEvtTimerFunc(
    IN WDFTIMER  Timer
    )
{
    NTSTATUS  Status;
    WDFREQUEST  Request;
    WDFQUEUE  queue;
    PQUEUE_CONTEXT  queueContext;

    // Retrieve our saved copy of the request handle.
    queue = WdfTimerGetParentObject(Timer);
    queueContext = QueueGetContext(queue);
    Request = queueContext->CurrentRequest;

    // We cannot call WdfRequestUnmarkCancelable
    // after a request completes, so check here to see
    // if EchoEvtRequestCancel cleared our saved
    // request handle. 
    if( Request != NULL ) {
        Status = WdfRequestUnmarkCancelable(Request);
        if(Status != STATUS_CANCELLED) {
            queueContext->CurrentRequest = NULL;
            Status = queueContext->CurrentStatus;
            WdfRequestComplete(
                               Request,
                               Status
                               );
        }
    }

    return;
}

요구 사항

요구 사항
대상 플랫폼 유니버설
최소 KMDF 버전 1.0
최소 UMDF 버전 2.0
머리글 wdfrequest.h(Wdf.h 포함)
라이브러리 Wdf01000.sys(KMDF); WUDFx02000.dll(UMDF)
IRQL <=DISPATCH_LEVEL
DDI 규정 준수 규칙 CompleteCanceledReq(kmdf), DeferredRequestCompleted(kmdf), DriverCreate(kmdf), EvtIoStopCancel(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MarkCancOnCancReqLocal(kmdf), ReqIsCancOnCancReq(kmdf), ReqMarkCancelableSend(kmdf), ReqNotCanceledLocal(kmdf)

추가 정보

EvtRequestCancel

WdfRequestComplete

WdfRequestMarkCancelable

WdfRequestMarkCancelableEx