Partager via


WdfRequestUnmarkCancelable, fonction (wdfrequest.h)

[S’applique à KMDF et UMDF]

La méthode WdfRequestUnmarkCancelable désactive l’annulation d’une demande d’E/S spécifiée.

Syntaxe

NTSTATUS WdfRequestUnmarkCancelable(
  [in] WDFREQUEST Request
);

Paramètres

[in] Request

Handle pour un objet de requête d’infrastructure.

Valeur retournée

WdfRequestUnmarkCancelable retourne STATUS_SUCCESS si l’opération réussit. Sinon, cette méthode peut retourner l’une des valeurs suivantes :

Code de retour Description
STATUS_INVALID_PARAMETER
Un paramètre d’entrée n’est pas valide ou la demande n’est pas déjà annulable.
STATUS_INVALID_DEVICE_REQUEST
Le pilote n’est pas propriétaire de la demande.
STATUS_CANCELLED
La demande a été annulée.
 

Cette méthode peut également retourner d’autres valeurs NTSTATUS.

Un bogue case activée se produit si le pilote fournit un handle d’objet non valide.

Remarques

Un pilote peut appeler WdfRequestUnmarkCancelable pour désactiver l’annulation d’une demande d’E/S, si le pilote a précédemment appelé WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx pour activer l’annulation de la demande.

Si WdfRequestUnmarkCancelable retourne une valeur autre que STATUS_CANCELLED, la fonction de rappel EvtRequestCancel du pilote n’est pas appelée pour la demande.

Si le pilote a précédemment appelé WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx, la fonction de rappel EvtRequestCancel du pilote peut appeler WdfRequestComplete avec un paramètre Status de STATUS_CANCELLED. La fonction de rappel EvtRequestCancel n’a pas besoin d’appeler WdfRequestUnmarkCancelable. Si le pilote appelle WdfRequestComplete en dehors de sa fonction de rappel EvtRequestCancel , le pilote doit d’abord appeler WdfRequestUnmarkCancelable.

Toutefois, le pilote ne doit pas appeler WdfRequestUnmarkCancelable après qu’EvtRequestCancel a appelé WdfRequestComplete. Dans la section Exemple suivant, l’exemple stocke une copie locale du handle de requête, puis l’efface lorsque la fonction de rappel EvtRequestCancel appelle WdfRequestComplete. Le pilote n’appelle pas WdfRequestUnmarkCancelable si la copie locale du handle de demande a été effacée. Cet exemple utilise la synchronisation automatique de l’infrastructure pour synchroniser les fonctions de rappel.

Notez que l’appel de WdfObjectReference pour ajouter une référence supplémentaire à l’objet de requête ne permet pas à votre pilote d’appeler WdfRequestUnmarkCancel après que la fonction de rappel EvtRequestCancel du pilote appelle WdfRequestComplete.

Si WdfRequestUnmarkCancelable retourne STATUS_CANCELLED, puis Qu’EvtRequestCancel termine la requête, le pilote ne doit pas utiliser l’objet request par la suite.

Si WdfRequestUnmarkCancelable retourne STATUS_CANCELLED, le pilote ne doit pas terminer la demande avant que le framework appelle EvtRequestCancel. Sinon, l’infrastructure peut appeler evtRequestCancel du pilote avec une requête non valide. Pour obtenir des exemples de code connexes, consultez IWDFIoRequest ::UnmarkCancelable.

Pour plus d’informations sur WdfRequestUnmarkCancelable, consultez Annulation des demandes d’E/S.

Exemples

L’exemple de code suivant fournit des versions simplifiées des fonctions de rappel EvtIoRead, EvtRequestCancel et EvtTimerFunc que contient l’exemple de pilote ECHO . Cet exemple montre comment appeler WdfRequestMarkCancelable, WdfRequestUnmarkCancelable et WdfRequestComplete dans un pilote qui utilise la synchronisation automatique de l’infrastructure. (L’exemple ECHO utilise la synchronisation au niveau de l’appareil.)

Si votre pilote n’utilise pas la synchronisation automatique de l’infrastructure, consultez les deux exemples sur IWDFIoRequest ::UnmarkCancelable. Lorsqu’ils sont écrits pour un pilote UMDF, ces exemples illustrent les techniques que vous pouvez utiliser pour gérer la synchronisation entre le rappel d’annulation et un autre thread qui appelle la routine 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;
}

Configuration requise

Condition requise Valeur
Plateforme cible Universal
Version KMDF minimale 1.0
Version UMDF minimale 2.0
En-tête wdfrequest.h (inclure Wdf.h)
Bibliothèque Wdf01000.sys (KMDF) ; WUDFx02000.dll (UMDF)
IRQL <=DISPATCH_LEVEL
Règles de conformité 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)

Voir aussi

EvtRequestCancel

WdfRequestComplete

WdfRequestMarkCancelable

WdfRequestMarkCancelableEx