Función WdfIoQueueFindRequest (wdfio.h)
[Se aplica a KMDF y UMDF]
El método WdfIoQueueFindRequest localiza la siguiente solicitud en una cola de E/S o la siguiente solicitud que coincide con los criterios especificados, pero no concede la propiedad de la solicitud al controlador.
Sintaxis
NTSTATUS WdfIoQueueFindRequest(
[in] WDFQUEUE Queue,
[in, optional] WDFREQUEST FoundRequest,
[in, optional] WDFFILEOBJECT FileObject,
[in, out] PWDF_REQUEST_PARAMETERS Parameters,
[out] WDFREQUEST *OutRequest
);
Parámetros
[in] Queue
Identificador de un objeto de cola de marco.
[in, optional] FoundRequest
Identificador de objeto de solicitud que el controlador recibió de una llamada anterior a WdfIoQueueFindRequest. Este parámetro es opcional y puede ser NULL.
[in, optional] FileObject
Identificador de un objeto de archivo de marco. Este parámetro es opcional y puede ser NULL.
[in, out] Parameters
Puntero a una estructura de WDF_REQUEST_PARAMETERS asignada por el controlador que recibe parámetros asociados a la solicitud encontrada. Este parámetro es opcional y puede ser NULL.
[out] OutRequest
Puntero a una ubicación que recibe un identificador de la solicitud encontrada. Si no se encuentra ninguna coincidencia, la ubicación recibe NULL.
Valor devuelto
WdfIoQueueFindRequest devuelve STATUS_SUCCESS si la operación se realiza correctamente. De lo contrario, este método podría devolver uno de los siguientes valores:
Código devuelto | Descripción |
---|---|
|
El controlador proporciona un identificador no válido. |
|
La solicitud identificada por el parámetro FoundRequest no se encuentra en la cola de E/S. |
|
El marco alcanzó el final de la cola de E/S sin encontrar una solicitud que coincida con los criterios de búsqueda. |
Este método también podría devolver otros valores NTSTATUS.
Se produce una comprobación de errores si el controlador proporciona un identificador de objeto no válido.
Comentarios
El método WdfIoQueueFindRequest busca en una cola de E/S especificada e intenta encontrar una solicitud de E/S.
El controlador puede llamar a WdfIoQueueFindRequest solo si el controlador usa el método de distribución manual para la cola de E/S especificada.
Si FileObject no es NULL, WdfIoQueueFindRequest solo examina las solicitudes asociadas al identificador de objeto de archivo especificado.
Si FoundRequest es NULL, este método busca la primera solicitud en la cola de E/S que coincide con el valor FileObject . Si FoundRequest no es NULL, el método comienza a buscar en la solicitud identificada por FoundRequest. Para crear un bucle iterativo, especifique NULL para la primera llamada y, a continuación, use el identificador devuelto como el parámetro FoundRequest para las llamadas posteriores.
Si Parameters no es NULL, este método copia los parámetros de la solicitud encontrada en la estructura proporcionada por el controlador.
Cada llamada a WdfIoQueueFindRequest que devuelve STATUS_SUCCESS incrementa el recuento de referencias del objeto de solicitud cuyo identificador se devuelve en OutRequest. Por lo tanto, el controlador debe llamar a WdfObjectDereference una vez que haya terminado de usar el identificador .
La llamada a WdfIoQueueFindRequestno concede la propiedad del controlador de ninguna solicitud. Si desea que el controlador obtenga la propiedad de una solicitud para que pueda procesar la solicitud, el controlador debe llamar a WdfIoQueueRetrieveFoundRequest. De hecho, el controlador solo puede hacer lo siguiente con el identificador que recibe para el parámetro OutRequest :
- Úselo como parámetro FoundRequest en una llamada posterior a WdfIoQueueFindRequest.
- Úselo como parámetro FoundRequest en una llamada posterior a WdfIoQueueRetrieveFoundRequest.
- Úselo como parámetro de entrada en una llamada posterior a WdfObjectGetTypedContext o un método definido por el controlador para acceder al espacio de contexto del objeto.
- Úselo como parámetro de entrada para WdfObjectDereference.
Para obtener más información sobre el método WdfIoQueueFindRequest , vea Administración de colas de E/S.
Ejemplos
Ejemplo 1
El ejemplo de código siguiente procede del controlador de ejemplo PCIDRV . En este ejemplo se busca una cola de E/S para una solicitud que contiene un código de función de E/S especificado. Si se encuentra una solicitud coincidente, el ejemplo llama a 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;
}
Ejemplo 2
En el ejemplo de código siguiente se muestra cómo crear una rutina de búsqueda de uso general que llama a una subrutina específica de búsqueda. Si el controlador debe buscar una o varias colas para varios tipos de información, puede proporcionar varias subrutinas específicas de búsqueda. Cada vez que el controlador llama a la rutina de búsqueda de uso general, especifica la dirección de una de las subrutinas específicas de la búsqueda.
//
// 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.
//
...
}
...
Requisitos
Requisito | Value |
---|---|
Plataforma de destino | Universal |
Versión mínima de KMDF | 1.0 |
Versión mínima de UMDF | 2.0 |
Encabezado | wdfio.h (incluya Wdf.h) |
Library | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <= DISPATCH_LEVEL |
Reglas de cumplimiento de DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed(kmdf), wdfioqueueretrievefoundrequest, WdfIoQueueRetrieveFoundRequest(kmdf), wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest(kmdf) |