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
STATUS_INVALID_PARAMETER
El controlador proporciona un identificador no válido.
STATUS_NOT_FOUND
La solicitud identificada por el parámetro FoundRequest no se encuentra en la cola de E/S.
STATUS_NO_MORE_ENTRIES
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 :

Si una llamada a WdfIoQueueFindRequest devuelve STATUS_NOT_FOUND, se ha quitado una solicitud que se encontraba anteriormente en la cola. Es posible que se haya cancelado la solicitud. Una llamada a WdfIoQueueRetrieveFoundRequest también puede devolver STATUS_NOT_FOUND.

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(&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;

}

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)

Consulte también

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop

WdfObjectDereference