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 |
---|---|
|
Le pilote fournit un handle non valide. |
|
La requête identifiée par le paramètre FoundRequest est introuvable dans la file d’attente d’E/S. |
|
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 :
- 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 contextuel de l’objet.
- Utilisez-le comme paramètre d’entrée pour WdfObjectDereference.
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(¶ms);
*Request = NULL;
prevTagRequest = tagRequest = NULL;
do {
WDF_REQUEST_PARAMETERS_INIT(¶ms);
status = WdfIoQueueFindRequest(
Queue,
prevTagRequest,
NULL,
¶ms,
&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) |