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 la propriété de la demande 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 pour un objet de file d’attente d’infrastructure.

[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 pour un objet de fichier d’infrastructure. Ce paramètre est facultatif et peut être NULL.

[in, out] Parameters

Pointeur vers une structure de WDF_REQUEST_PARAMETERS allouée par le pilote qui reçoit les 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 pour la requête trouvée. Si aucune correspondance n’est trouvée, l’emplacement reçoit la valeur NULL.

Valeur retournée

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.

Un bogue case activée 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 demande d’E/S.

Votre pilote peut appeler WdfIoQueueFindRequest uniquement s’il utilise la méthode de répartition manuelle pour la file d’attente d’E/S spécifiée.

Si FileObject n’a pas la valeur NULL, WdfIoQueueFindRequest examine uniquement les demandes associées au handle d’objet de fichier spécifié.

Si FoundRequest a la valeur 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’a pas la valeur NULL, la méthode commence la recherche à 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’a pas la valeur 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 de WdfIoQueueFindRequest n’accorde pas au pilote la propriété des requêtes. Si vous souhaitez que votre pilote obtienne la propriété d’une demande afin qu’il puisse traiter la demande, il doit appeler WdfIoQueueRetrieveFoundRequest. En fait, le pilote peut effectuer uniquement les opérations suivantes avec le handle qu’il reçoit pour le paramètre OutRequest :

Si un appel à WdfIoQueueFindRequest retourne STATUS_NOT_FOUND, une requête qui se trouvait 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 requête 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 rechercher plusieurs types d’informations dans une ou plusieurs files d’attente, 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.
    //
...
}
... 

Configuration requise

Condition requise Valeur
Plateforme cible Universal
Version KMDF minimale 1.0
Version UMDF minimale 2.0
En-tête wdfio.h (inclure 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