WdfRequestMarkCancelable, fonction (wdfrequest.h)

[S’applique à KMDF et UMDF]

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

Syntaxe

void WdfRequestMarkCancelable(
  [in] WDFREQUEST             Request,
  [in] PFN_WDF_REQUEST_CANCEL EvtRequestCancel
);

Paramètres

[in] Request

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

[in] EvtRequestCancel

Pointeur vers une fonction de rappel EvtRequestCancel définie par le pilote, que le framework appelle s’il annule la demande d’E/S.

Valeur de retour

None

Remarques

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

Une fois que votre pilote a reçu une demande d’E/ S de l’infrastructure, il peut appeler WdfRequestMarkCancelable ou, à compter de KMDF version 1.9, WdfRequestMarkCancelableEx pour rendre la requête annulable.

Lors de l’appel de WdfRequestMarkCancelable, votre pilote doit spécifier une fonction de rappel EvtRequestCancel . L’infrastructure appelle la fonction de rappel si le gestionnaire d’E/S ou un autre pilote tente d’annuler la demande d’E/S.

Choix entre WdfRequestMarkCancelable et WdfRequestMarkCancelableEx

Si votre pilote utilise la synchronisation automatique de l’infrastructure, il peut appeler WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx.

Si le pilote n’utilise pas la synchronisation automatique, il doit appeler WdfRequestMarkCancelableEx au lieu de WdfRequestMarkCancelable pour les raisons suivantes :

  • Si la requête spécifiée a déjà été annulée, WdfRequestMarkCancelable appelle la fonction de rappel EvtRequestCancel du pilote avant de revenir. Si le pilote acquiert un verrouillage tournant avant d’appeler WdfRequestMarkCancelable et tente d’acquérir le même verrouillage tournant à l’intérieur d’EvtRequestCancel, le même thread tente d’acquérir le même verrouillage tournant deux fois, ce qui provoque un interblocage.
  • Toutefois, étant donné que WdfRequestMarkCancelableEx n’appelle jamais EvtRequestCancel, ce scénario ne se produit pas. Si la demande a déjà été annulée, WdfRequestMarkCancelableEx retourne STATUS_CANCELLED. Si votre pilote acquiert un verrouillage tournant (qui définit l’IRQL sur DISPATCH_LEVEL) avant d’appeler WdfRequestMarkCancelableEx et libère le verrouillage spinlock (qui définit l’IRQL sur PASSIVE_LEVEL) après le retour de WdfRequestMarkCancelableEx , la fonction de rappel EvtRequestCancel n’est pas appelée avant la sortie du verrouillage tournant. Par conséquent, un interblocage ne se produit pas même si la fonction de rappel EvtRequestCancel utilise le même verrouillage tournant.

Traitement d’une demande après l’activation de l’annulation

Une fois qu’un pilote a appelé WdfRequestMarkCancelable pour activer l’annulation, la demande reste annulable alors que le pilote est propriétaire de l’objet de requête, sauf si le pilote appelle WdfRequestUnmarkCancelable.

Si un pilote a appelé WdfRequestMarkCancelable et si la fonction de rappel EvtRequestCancel du pilote n’a pas été exécutée et a appelé WdfRequestComplete, le pilote doit appeler WdfRequestUnmarkCancelable avant d’appeler WdfRequestComplete en dehors de la fonction de rappel EvtRequestCancel .

Si le pilote appelle WdfRequestForwardToIoQueue pour transférer la requête vers une autre file d’attente, les règles suivantes s’appliquent :

  • Les demandes d’E/S ne peuvent pas être annulées lorsque votre pilote les transfère à une autre file d’attente.

    En règle générale, votre pilote ne doit pas appeler WdfRequestMarkCancelable pour activer l’annulation de la demande avant d’appeler WdfRequestForwardToIoQueue. Si le pilote rend la demande annulable, il doit appeler WdfRequestUnmarkCancelable pour désactiver l’annulation avant d’appeler WdfRequestForwardToIoQueue.

  • Lorsque la requête se trouve dans la deuxième file d’attente, le framework la possède et peut l’annuler sans en informer le pilote.

    Si le pilote nécessite une notification d’annulation (afin qu’il puisse libérer toutes les ressources qu’il a allouées avant d’appeler WdfRequestForwardToIoQueue), le pilote doit inscrire une fonction de rappel EvtIoCanceledOnQueue et utiliser la mémoire contextuelle spécifique à la requête pour stocker des informations sur les ressources de la requête.

  • Une fois que l’infrastructure a supprimé la file d’attente de la requête de la deuxième file d’attente et l’a remise au pilote, le pilote peut appeler WdfRequestMarkCancelable pour activer l’annulation.
Pour plus d’informations sur WdfRequestMarkCancelable, consultez Annulation des demandes d’E/S.

Exemples

L’exemple de code suivant montre des parties de deux fonctions de rappel :

  • Une fonction de rappel EvtIoRead qui effectue un travail spécifique à la demande (par exemple, la création de sous-requêtes à envoyer à une cible d’E/S), puis active l’annulation de la demande d’E/S reçue.
  • Fonction de rappel EvtRequestCancel qui annule une demande d’E/S.
Le pilote doit utiliser la synchronisation automatique de l’infrastructure.
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
                       );
}

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 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)

Voir aussi

EvtRequestCancel

WdfRequestComplete

WdfRequestForwardToIoQueue

WdfRequestMarkCancelableEx

WdfRequestUnmarkCancelable