Partager via


WdfIoQueueFindRequest, fonction (wdfio.h)

[S’applique à KMDF et UMDF]

La méthode WdfIoQueueFindRequest localise la requête suivante dans une file d’attente d’E/S ou la requête suivante qui correspond aux critères spécifiés, mais n’accorde pas propriété de la requête au pilote.

Syntaxe

NTSTATUS WdfIoQueueFindRequest(
  [in]           WDFQUEUE                Queue,
  [in, optional] WDFREQUEST              FoundRequest,
  [in, optional] WDFFILEOBJECT           FileObject,
  [in, out]      PWDF_REQUEST_PARAMETERS Parameters,
  [out]          WDFREQUEST              *OutRequest
);

Paramètres

[in] Queue

Handle vers un objet de file d’attente framework.

[in, optional] FoundRequest

Handle d’objet de requête que le pilote a reçu d’un appel précédent à WdfIoQueueFindRequest. Ce paramètre est facultatif et peut être NULL.

[in, optional] FileObject

Handle d’un objet de fichier framework. Ce paramètre est facultatif et peut être NULL.

[in, out] Parameters

Pointeur vers une structure WDF_REQUEST_PARAMETERS allouée par le pilote qui reçoit des paramètres associés à la requête trouvée. Ce paramètre est facultatif et peut être NULL.

[out] OutRequest

Pointeur vers un emplacement qui reçoit un handle vers la requête trouvée. Si aucune correspondance n’est trouvée, l’emplacement reçoit NULL.

Valeur de retour

WdfIoQueueFindRequest 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
Le pilote fournit un handle non valide.
STATUS_NOT_FOUND
La requête identifiée par le paramètre FoundRequest est introuvable dans la file d’attente d’E/S.
STATUS_NO_MORE_ENTRIES
L’infrastructure a atteint la fin de la file d’attente d’E/S sans trouver une demande qui correspond aux critères de recherche.
 

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

Une vérification de bogue se produit si le pilote fournit un handle d’objet non valide.

Remarques

La méthode WdfIoQueueFindRequest recherche une file d’attente d’E/S spécifiée et tente de trouver une requête d’E/S.

Votre pilote peut appeler WdfIoQueueFindRequest uniquement si le pilote utilise la méthode de distribution manuelle pour la file d’attente d’E/S spécifiée.

Si FileObject n’est pas NULL, WdfIoQueueFindRequest examine uniquement les requêtes associées au handle d’objet de fichier spécifié.

Si FoundRequest est NULL, cette méthode localise la première requête dans la file d’attente d’E/S qui correspond à la valeur FileObject. Si FoundRequest n’est pas NULL, la méthode commence à rechercher à la demande identifiée par FoundRequest. Pour créer une boucle itérative, spécifiez NULL pour le premier appel, puis utilisez le handle retourné comme paramètre FoundRequest pour les appels suivants.

Si Parameters n’est pas NULL, cette méthode copie les paramètres de la requête trouvée dans la structure fournie par le pilote.

Chaque appel à WdfIoQueueFindRequest qui retourne STATUS_SUCCESS incrémente le nombre de références de l’objet de requête dont le handle est retourné dans OutRequest. Par conséquent, votre pilote doit appeler WdfObjectDereference une fois que vous avez terminé d’utiliser le handle.

L’appel WdfIoQueueFindRequest n'pas accorder au pilote propriété de toutes les requêtes. Si vous souhaitez que votre pilote obtienne la propriété d’une demande afin qu’elle puisse traiter la demande, le pilote doit appeler WdfIoQueueRetrieveFoundRequest. En fait, le pilote ne peut effectuer que les opérations suivantes avec le handle qu’il reçoit pour le paramètre OutRequest :

  • Utilisez-le comme paramètre FoundRequest dans un appel ultérieur à WdfIoQueueFindRequest.
  • Utilisez-le comme paramètre FoundRequest dans un appel ultérieur à WdfIoQueueRetrieveFoundRequest.
  • Utilisez-le comme paramètre d’entrée dans un appel ultérieur à WdfObjectGetTypedContext ou une méthode définie par le pilote pour accéder à l’espace de contexte de l’objet.
  • Utilisez-le comme paramètre d’entrée pour WdfObjectDereference .
Si un appel à WdfIoQueueFindRequest retourne STATUS_NOT_FOUND, une demande qui était précédemment dans la file d’attente a été supprimée. La demande a peut-être été annulée. Un appel à WdfIoQueueRetrieveFoundRequest peut également retourner STATUS_NOT_FOUND.

Pour plus d’informations sur la méthode WdfIoQueueFindRequest, consultez Gestion des files d’attente d’E/S.

Exemples

Exemple 1 :

L’exemple de code suivant provient de l’exemple de pilote PCIDRV . Cet exemple recherche dans une file d’attente d’E/S une requête qui contient un code de fonction d’E/S spécifié. Si une demande correspondante est trouvée, l’exemple appelle WdfIoQueueRetrieveFoundRequest.

NTSTATUS
NICGetIoctlRequest(
    IN WDFQUEUE Queue,
    IN ULONG FunctionCode,
    OUT WDFREQUEST*  Request
    )
{
    NTSTATUS  status = STATUS_UNSUCCESSFUL;
    WDF_REQUEST_PARAMETERS  params;
    WDFREQUEST  tagRequest;
    WDFREQUEST  prevTagRequest;

    WDF_REQUEST_PARAMETERS_INIT(&params);
 
    *Request = NULL;
    prevTagRequest = tagRequest = NULL;

    do {
        WDF_REQUEST_PARAMETERS_INIT(&params);
        status = WdfIoQueueFindRequest(
                                       Queue,
                                       prevTagRequest,
                                       NULL,
                                       &params,
                                       &tagRequest
                                       );
        if (prevTagRequest) {
            WdfObjectDereference(prevTagRequest);
        }
        if (status == STATUS_NO_MORE_ENTRIES) {
            status = STATUS_UNSUCCESSFUL;
            break;
        }
        if (status == STATUS_NOT_FOUND) {
            //
            // The prevTagRequest request has disappeared from the
            // queue. There might be other requests that match
            // the criteria, so restart the search. 
            //
            prevTagRequest = tagRequest = NULL;
            continue;
        }
        if (!NT_SUCCESS(status)) { 
            status = STATUS_UNSUCCESSFUL;
            break;
        }
        if (FunctionCode == params.Parameters.DeviceIoControl.IoControlCode){
            //
            // Found a match. Retrieve the request from the queue.
            //
            status = WdfIoQueueRetrieveFoundRequest(
                                                    Queue,
                                                    tagRequest,
                                                    Request
                                                    );
            WdfObjectDereference(tagRequest);
            if (status == STATUS_NOT_FOUND) {
                //
                // The tagRequest request has disappeared from the
                // queue. There might be other requests that match 
                // the criteria, so restart the search. 
                //
                prevTagRequest = tagRequest = NULL;
                continue;
            }
            if (!NT_SUCCESS(status)) {
                status = STATUS_UNSUCCESSFUL;
                break;
            }
            //
            //  Found a request.
            //
            ASSERT(*Request == tagRequest);
            status =  STATUS_SUCCESS;
            break;
        } else {
            //
            // This request is not the correct one. Drop the reference 
            // on the tagRequest after the driver obtains the next request.
            //
            prevTagRequest = tagRequest;
            continue;
        }
    } while (TRUE);
    return status;

}

Exemple 2

L’exemple de code suivant montre comment créer une routine de recherche à usage général qui appelle une sous-routine spécifique à la recherche. Si votre pilote doit effectuer une recherche dans une ou plusieurs files d’attente pour plusieurs types d’informations, vous pouvez fournir plusieurs sous-routines spécifiques à la recherche. Chaque fois que votre pilote appelle la routine de recherche à usage général, il spécifie l’adresse de l’une de vos sous-routines spécifiques à la recherche.

//
// Type declaration for the driver's search-specific subroutines. 
//
typedef BOOLEAN (*PFN_CALLBACK_COMPARE)(WDFREQUEST, ULONG);

//
// General-purpose search routine. One of the routine's
// parameters is the address of a search-specific
// subroutine. The search routine calls back to the
// subroutine.
//
WDFREQUEST
FindRequestWithMatchingData(
    __in WDFQUEUE Queue,
    __in PFN_CALLBACK_COMPARE CallbackCompare,
    __in ULONG Data
    )
{
    WDFREQUEST  prevTagRequest = NULL;
    WDFREQUEST  tagRequest = NULL;
    WDFREQUEST  outRequest = NULL;
    NTSTATUS  status = STATUS_INVALID_DEVICE_REQUEST;

    PAGED_CODE();

    do {
        status = WdfIoQueueFindRequest(Queue,
                                       prevTagRequest,
                                       NULL,
                                       NULL,
                                       &tagRequest);
        if (prevTagRequest) {
            //
            // WdfIoQueueFindRequest incremented the
            // reference count of the prevTagRequest object,
            // so we decrement the count here.
            //
            WdfObjectDereference(prevTagRequest);
        }
        if (status == STATUS_NO_MORE_ENTRIES) {
            KdPrint(("WdfIoQueueFindRequest returned status 0x%x\n", status));
            break;
        }
        if (status == STATUS_NOT_FOUND) {
            //
            // The prevTagRequest object is no longer
            // in the queue.
            //
            prevTagRequest = tagRequest = NULL;
            continue;
        }
        if ( !NT_SUCCESS(status)) {
            KdPrint(("WdfIoQueueFindRequest failed 0x%x\n", status));
            break;
        }

        //
        // We have a handle to the next request that is
        // in the queue. Now we call the subroutine
        // that determines if this request matches our 
        // search criteria.
        //
        if (CallbackCompare(tagRequest, Data)) {
            // 
            // We found a match. Get the request handle.
            // 
            status = WdfIoQueueRetrieveFoundRequest(Queue,
                                                    tagRequest,
                                                    &outRequest);
            //
            // WdfIoQueueRetrieveFoundRequest incremented the
            // reference count of the TagRequest object,
            // so we decrement the count here.
            //
            WdfObjectDereference(tagRequest);

            if (status == STATUS_NOT_FOUND) {
                //
                // The TagRequest object is no longer
                // in the queue. But other requests might
                // match our criteria, so we restart the search.
                //
                prevTagRequest = tagRequest = NULL;
                continue;
            }

            if (!NT_SUCCESS(status)) {
                KdPrint(("WdfIoQueueRetrieveFoundRequest failed 0x%x\n", 
                          status));
            }

            //
            // We found the request we were looking for. 
            //
            break;

        } else {
            //
            // The request did not match our criteria.
            // Get another request.
            //
            prevTagRequest = tagRequest;
            continue;
        }
    } while(TRUE);
    return outRequest;
 }

/
// An example of a driver's search-specific subroutine.
// Your driver can have multiple subroutines to handle
// multiple types of searches.
//
BOOLEAN
CallbackCheckForInfo1(
    __in WDFREQUEST Request,
    __in ULONG DataToBeMatched
    )
{
    PREQUEST_CONTEXT reqContext;

    PAGED_CODE();

    //
    // Retrieve information that the driver has stored
    // in the request object's context space.
    //
    reqContext = GetRequestContext(Request);
    if (reqContext->ContextInfo1 == DataToBeMatched) {
        return TRUE;
    }
    else {
        return FALSE;
    }
}

//
// This code shows a call to the FindRequestWithMatchingData routine.
//
WDFREQUEST  matchedRequest = NULL;
...
matchedRequest = FindRequestWithMatchingData(readQueue,
                                             CallbackCheckForInfo1,
                                             INFO_VALUE);
if (matchedRequest != NULL) {
    // 
    // Found a request with a context value of INFO_VALIUE.
    //
...
}
... 

Spécifications

Besoin Valeur
plateforme cible Universel
version minimale de KMDF 1.0
version minimale de UMDF 2.0
En-tête wdfio.h (include Wdf.h)
Bibliothèque Wdf01000.sys (KMDF) ; WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
règles de conformité DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed(kmdf), wdfioqueueretrievefoundrequest, WdfIoQueueRetrieveFoundRequest(kmdf), wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest(kmdf)

Voir aussi

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop

WdfObjectDereference