Função WdfIoQueueFindRequest (wdfio.h)

[Aplica-se a KMDF e UMDF]

O método WdfIoQueueFindRequest localiza a próxima solicitação em uma fila de E/S ou a próxima solicitação que corresponde aos critérios especificados, mas não concede a propriedade da solicitação ao driver.

Sintaxe

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

Um identificador para um objeto de fila de estrutura.

[in, optional] FoundRequest

Um identificador de objeto de solicitação que o driver recebeu de uma chamada anterior para WdfIoQueueFindRequest. Esse parâmetro é opcional e pode ser NULL.

[in, optional] FileObject

Um identificador para um objeto de arquivo de estrutura. Esse parâmetro é opcional e pode ser NULL.

[in, out] Parameters

Um ponteiro para uma estrutura de WDF_REQUEST_PARAMETERS alocada pelo driver que recebe parâmetros associados à solicitação encontrada. Esse parâmetro é opcional e pode ser NULL.

[out] OutRequest

Um ponteiro para um local que recebe um identificador para a solicitação encontrada. Se nenhuma correspondência for encontrada, o local receberá NULL.

Retornar valor

WdfIoQueueFindRequest retornará STATUS_SUCCESS se a operação for bem-sucedida. Caso contrário, esse método poderá retornar um dos seguintes valores:

Código de retorno Descrição
STATUS_INVALID_PARAMETER
O driver fornece um identificador inválido.
STATUS_NOT_FOUND
A solicitação identificada pelo parâmetro FoundRequest não pode ser encontrada na fila de E/S.
STATUS_NO_MORE_ENTRIES
A estrutura chegou ao fim da fila de E/S sem encontrar uma solicitação que corresponda aos critérios de pesquisa.
 

Esse método também pode retornar outros valores NTSTATUS.

Um bug marcar ocorrerá se o driver fornecer um identificador de objeto inválido.

Comentários

O método WdfIoQueueFindRequest pesquisa uma fila de E/S especificada e tenta encontrar uma solicitação de E/S.

Seu driver só poderá chamar WdfIoQueueFindRequest se o driver estiver usando o método de expedição manual para a fila de E/S especificada.

Se FileObject não for NULL, WdfIoQueueFindRequest examinará apenas as solicitações associadas ao identificador de objeto de arquivo especificado.

Se FoundRequest for NULL, esse método localizará a primeira solicitação na fila de E/S que corresponde ao valor FileObject . Se FoundRequest não for NULL, o método começará a pesquisar na solicitação identificada por FoundRequest. Para criar um loop iterativo, especifique NULL para a primeira chamada e use o identificador retornado como o parâmetro FoundRequest para chamadas subsequentes.

Se Parameters não for NULL, esse método copiará os parâmetros da solicitação encontrada para a estrutura fornecida pelo driver.

Cada chamada para WdfIoQueueFindRequest que retorna STATUS_SUCCESS incrementa a contagem de referência do objeto de solicitação cujo identificador é retornado em OutRequest. Portanto, seu driver deve chamar WdfObjectDereference depois de terminar de usar o identificador.

Chamar WdfIoQueueFindRequestnão concede a propriedade do driver de nenhuma solicitação. Se você quiser que o driver obtenha a propriedade de uma solicitação para que ela possa processar a solicitação, o driver deverá chamar WdfIoQueueRetrieveFoundRequest. Na verdade, o driver pode fazer apenas o seguinte com o identificador que recebe para o parâmetro OutRequest :

  • Use-o como o parâmetro FoundRequest em uma chamada subsequente para WdfIoQueueFindRequest.
  • Use-o como o parâmetro FoundRequest em uma chamada subsequente para WdfIoQueueRetrieveFoundRequest.
  • Use-o como o parâmetro de entrada em uma chamada subsequente para WdfObjectGetTypedContext ou um método definido pelo driver para acessar o espaço de contexto do objeto.
  • Use-o como o parâmetro de entrada para WdfObjectDereference.
Se uma chamada para WdfIoQueueFindRequest retornar STATUS_NOT_FOUND, uma solicitação que estava anteriormente na fila foi removida. A solicitação pode ter sido cancelada. Uma chamada para WdfIoQueueRetrieveFoundRequest também pode retornar STATUS_NOT_FOUND.

Para obter mais informações sobre o método WdfIoQueueFindRequest , consulte Gerenciando filas de E/S.

Exemplos

Exemplo 1

O exemplo de código a seguir é do driver de exemplo PCIDRV . Este exemplo pesquisa uma fila de E/S para uma solicitação que contém um código de função de E/S especificado. Se uma solicitação correspondente for encontrada, o exemplo chamará 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;

}

Exemplo 2

O exemplo de código a seguir mostra como você pode criar uma rotina de pesquisa de uso geral que chama uma sub-rotina específica da pesquisa. Se o driver precisar pesquisar várias informações em uma ou mais filas, você poderá fornecer várias sub-rotinas específicas da pesquisa. Sempre que o driver chama a rotina de pesquisa de uso geral, ele especifica o endereço de uma de suas sub-rotinas específicas da pesquisa.

//
// 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 Valor
Plataforma de Destino Universal
Versão mínima do KMDF 1.0
Versão mínima do UMDF 2,0
Cabeçalho wdfio.h (inclua Wdf.h)
Biblioteca Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
Regras de conformidade de DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed(kmdf), wdfioqueueretrievefoundrequest, WdfIoQueueRetrieveFoundRequest(kmdf), wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest(kmdf)

Confira também

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop

WdfObjectDereference