次の方法で共有


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 値も返す場合があります。

ドライバーが無効なオブジェクト ハンドルを提供すると、バグ チェックが発生します。

注釈

ドライバーは WdfRequestUnmarkCancelable を呼び出して、以前に WdfRequestMarkCancelable または WdfRequestMarkCancelableEx を呼び出して要求の取り消しを有効にした場合、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 サンプル ドライバーに含まれる EvtIoReadEvtRequestCancelEvtTimerFunc コールバック関数の簡略化されたバージョンを提供します。 この例では、フレームワークの自動同期を使用するドライバーで WdfRequestMarkCancelableWdfRequestUnmarkCancelableWdfRequestComplete を呼び出す方法を示します。 (ECHO サンプルでは、デバイス レベルの同期を使用します)。

ドライバーがフレームワークの自動同期を使用していない場合は、 IWDFIoRequest::UnmarkCancelable の 2 つの例を参照してください。 UMDF ドライバー用に記述されている間、これらの例では、キャンセル コールバックと Unmark ルーチンを呼び出す別のスレッドとの間の同期を管理するために使用できる手法を示します。

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
Header wdfrequest.h (Wdf.h を含む)
Library 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