Funzione WdfIoQueueFindRequest (wdfio.h)

[Si applica a KMDF e UMDF]

Il metodo WdfIoQueueFindRequest individua la richiesta successiva in una coda I/O o o la richiesta successiva che corrisponde ai criteri specificati, ma non concede la proprietà della richiesta al driver.

Sintassi

NTSTATUS WdfIoQueueFindRequest(
  [in]           WDFQUEUE                Queue,
  [in, optional] WDFREQUEST              FoundRequest,
  [in, optional] WDFFILEOBJECT           FileObject,
  [in, out]      PWDF_REQUEST_PARAMETERS Parameters,
  [out]          WDFREQUEST              *OutRequest
);

Parametri

[in] Queue

Handle a un oggetto code del framework.

[in, optional] FoundRequest

Handle dell'oggetto richiesta ricevuto dal driver da una chiamata precedente a WdfIoQueueFindRequest. Questo parametro è facoltativo e può essere NULL.

[in, optional] FileObject

Handle per un oggetto file framework. Questo parametro è facoltativo e può essere NULL.

[in, out] Parameters

Puntatore a una struttura WDF_REQUEST_PARAMETERS allocata dal driver che riceve i parametri associati alla richiesta trovata. Questo parametro è facoltativo e può essere NULL.

[out] OutRequest

Puntatore a una posizione che riceve un handle alla richiesta trovata. Se non viene trovata alcuna corrispondenza, la posizione riceve NULL.

Valore restituito

WdfIoQueueFindRequest restituisce STATUS_SUCCESS se l'operazione ha esito positivo. In caso contrario, questo metodo potrebbe restituire uno dei valori seguenti:

Codice restituito Descrizione
STATUS_INVALID_PARAMETER
Il driver fornisce un handle non valido.
STATUS_NOT_FOUND
Impossibile trovare la richiesta identificata dal parametro FoundRequest nella coda di I/O.
STATUS_NO_MORE_ENTRIES
Il framework ha raggiunto la fine della coda di I/O senza trovare una richiesta che corrisponda ai criteri di ricerca.
 

Questo metodo potrebbe restituire anche altri valori NTSTATUS.

Un controllo di bug si verifica se il driver fornisce un handle di oggetti non valido.

Commenti

Il metodo WdfIoQueueFindRequest cerca una coda di I/O specificata e tenta di trovare una richiesta di I/O.

Il driver può chiamare WdfIoQueueFindRequest solo se il driver usa il metodo di invio manuale per la coda di I/O specificata.

Se FileObject non è NULL, WdfIoQueueFindRequest esamina solo le richieste associate all'handle dell'oggetto file specificato.

Se FoundRequest è NULL, questo metodo individua la prima richiesta nella coda I/O corrispondente al valore FileObject . Se FoundRequest non è NULL, il metodo inizia la ricerca nella richiesta identificata da FoundRequest. Per creare un ciclo iterativo, specificare NULL per la prima chiamata e quindi usare l'handle restituito come parametro FoundRequest per le chiamate successive.

Se i parametri non sono NULL, questo metodo copia i parametri della richiesta rilevati nella struttura fornita dal driver.

Ogni chiamata a WdfIoQueueFindRequest che restituisce STATUS_SUCCESS incrementa il conteggio dei riferimenti dell'oggetto richiesta il cui handle viene restituito in OutRequest. Pertanto, il driver deve chiamare WdfObjectDereference dopo aver completato l'uso dell'handle.

La chiamata a WdfIoQueueFindRequestnon concede la proprietà del driver di eventuali richieste. Se si vuole che il driver ottenga la proprietà di una richiesta in modo che possa elaborare la richiesta, il driver deve chiamare WdfIoQueueRetrieveFoundRequest. Infatti, il driver può eseguire solo le operazioni seguenti con l'handle che riceve per il parametro OutRequest :

Se una chiamata a WdfIoQueueFindRequest restituisce STATUS_NOT_FOUND, è stata rimossa una richiesta precedentemente presente nella coda. La richiesta potrebbe essere stata annullata. Una chiamata a WdfIoQueueRetrieveFoundRequest può restituire anche STATUS_NOT_FOUND.

Per altre informazioni sul metodo WdfIoQueueFindRequest , vedere Gestione delle code di I/O.

Esempio

Esempio 1

L'esempio di codice seguente è dal driver di esempio PCIDRV . In questo esempio viene eseguita una ricerca in una coda di I/O per una richiesta contenente un codice di funzione I/O specificato. Se viene trovata una richiesta corrispondente, nell'esempio viene chiamata 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;

}

Esempio 2

Nell'esempio di codice seguente viene illustrato come creare una routine di ricerca per utilizzo generico che chiama una subroutine specifica della ricerca. Se il driver deve cercare una o più code per più tipi di informazioni, è possibile fornire più sottoroutine specifiche della ricerca. Ogni volta che il driver chiama la routine di ricerca per utilizzo generico, specifica l'indirizzo di una delle sottoroutine specifiche della ricerca.

//
// 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.
    //
...
}
... 

Requisiti

Requisito Valore
Piattaforma di destinazione Universale
Versione KMDF minima 1.0
Versione UMDF minima 2,0
Intestazione wdfio.h (includere Wdf.h)
Libreria Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
Regole di conformità DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed(kmdf), wdfioqueueretrievefoundrequest, WdfIoQueueRetrieveFoundRequest(kmdf), wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest(kmdf)

Vedi anche

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop

WdfObjectDereference