WdfIoQueueFindRequest-Funktion (wdfio.h)

[Gilt für KMDF und UMDF]

Die WdfIoQueueFindRequest-Methode sucht die nächste Anforderung in einer E/A-Warteschlange oder die nächste Anforderung, die den angegebenen Kriterien entspricht, gewährt dem Treiber jedoch nicht den Besitz der Anforderung.

Syntax

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

Parameter

[in] Queue

Ein Handle für ein Framework-Warteschlangenobjekt.

[in, optional] FoundRequest

Ein Anforderungsobjekthandle, das der Treiber von einem vorherigen Aufruf von WdfIoQueueFindRequest empfangen hat. Dieser Parameter ist optional und kann NULL sein.

[in, optional] FileObject

Ein Handle für ein Frameworkdateiobjekt. Dieser Parameter ist optional und kann NULL sein.

[in, out] Parameters

Ein Zeiger auf eine vom Treiber zugewiesene WDF_REQUEST_PARAMETERS Struktur, die Parameter empfängt, die der gefundenen Anforderung zugeordnet sind. Dieser Parameter ist optional und kann NULL sein.

[out] OutRequest

Ein Zeiger auf einen Speicherort, der ein Handle für die gefundene Anforderung empfängt. Wenn keine Übereinstimmung gefunden wird, erhält der Speicherort NULL.

Rückgabewert

WdfIoQueueFindRequest gibt STATUS_SUCCESS zurück, wenn der Vorgang erfolgreich ist. Andernfalls gibt diese Methode möglicherweise einen der folgenden Werte zurück:

Rückgabecode Beschreibung
STATUS_INVALID_PARAMETER
Der Treiber stellt ein ungültiges Handle bereit.
STATUS_NOT_FOUND
Die Anforderung, die durch den FoundRequest-Parameter identifiziert wird, kann nicht in der E/A-Warteschlange gefunden werden.
STATUS_NO_MORE_ENTRIES
Das Framework hat das Ende der E/A-Warteschlange erreicht, ohne eine Anforderung zu finden, die den Suchkriterien entspricht.
 

Diese Methode kann auch andere NTSTATUS-Werte zurückgeben.

Eine Fehlerüberprüfung tritt auf, wenn der Treiber ein ungültiges Objekthandle bereitstellt.

Hinweise

Die WdfIoQueueFindRequest-Methode durchsucht eine angegebene E/A-Warteschlange und versucht, eine E/A-Anforderung zu finden.

Ihr Treiber kann WdfIoQueueFindRequest nur aufrufen, wenn der Treiber die manuelle Verteilungsmethode für die angegebene E/A-Warteschlange verwendet.

Wenn FileObject nicht NULL ist, untersucht WdfIoQueueFindRequest nur Anforderungen, die dem angegebenen Dateiobjekthandle zugeordnet sind.

Wenn FoundRequestNULL ist, sucht diese Methode die erste Anforderung in der E/A-Warteschlange, die dem FileObject-Wert entspricht. Wenn FoundRequest nicht NULL ist, beginnt die -Methode mit der Suche nach der Anforderung, die von FoundRequest identifiziert wird. Um eine iterative Schleife zu erstellen, geben Sie null für den ersten Aufruf an, und verwenden Sie dann den zurückgegebenen Handle als FoundRequest-Parameter für nachfolgende Aufrufe.

Wenn Parameters nicht NULL ist, kopiert diese Methode die Parameter der gefundenen Anforderung in die vom Treiber bereitgestellte Struktur.

Jeder Aufruf von WdfIoQueueFindRequest , der STATUS_SUCCESS zurückgibt, erhöht die Verweisanzahl des Anforderungsobjekts, dessen Handle in OutRequest zurückgegeben wird. Daher muss Ihr Treiber WdfObjectDereference aufrufen, nachdem Sie die Verwendung des Handle abgeschlossen haben.

Das Aufrufen von WdfIoQueueFindRequest gewährt dem Treiber nicht den Besitz von Anforderungen. Wenn Ihr Treiber den Besitz einer Anforderung erhalten soll, damit er die Anforderung verarbeiten kann, muss der Treiber WdfIoQueueRetrieveFoundRequest aufrufen. Tatsächlich kann der Treiber nur Folgendes mit dem Handle ausführen, das er für den OutRequest-Parameter empfängt:

  • Verwenden Sie ihn als FoundRequest-Parameter in einem nachfolgenden Aufruf von WdfIoQueueFindRequest.
  • Verwenden Sie ihn als FoundRequest-Parameter in einem nachfolgenden Aufruf von WdfIoQueueRetrieveFoundRequest.
  • Verwenden Sie ihn als Eingabeparameter in einem nachfolgenden Aufruf von WdfObjectGetTypedContext oder einer vom Treiber definierten Methode für den Zugriff auf den Kontextraum des Objekts.
  • Verwenden Sie ihn als Eingabeparameter für WdfObjectDereference.
Wenn ein Aufruf von WdfIoQueueFindRequest STATUS_NOT_FOUND zurückgibt, wurde eine Anforderung entfernt, die sich zuvor in der Warteschlange befand. Die Anforderung wurde möglicherweise abgebrochen. Ein Aufruf von WdfIoQueueRetrieveFoundRequest kann auch STATUS_NOT_FOUND zurückgeben.

Weitere Informationen zur WdfIoQueueFindRequest-Methode finden Sie unter Verwalten von E/A-Warteschlangen.

Beispiele

Beispiel 1

Das folgende Codebeispiel stammt aus dem PCIDRV-Beispieltreiber . In diesem Beispiel wird eine E/A-Warteschlange nach einer Anforderung durchsucht, die einen angegebenen E/A-Funktionscode enthält. Wenn eine übereinstimmende Anforderung gefunden wird, ruft das Beispiel WdfIoQueueRetrieveFoundRequest auf.

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;

}

Beispiel 2

Das folgende Codebeispiel zeigt, wie Sie eine allgemeine Suchroutine erstellen können, die eine suchspezifische Unterroutine aufruft. Wenn Ihr Treiber eine oder mehrere Warteschlangen nach mehreren Arten von Informationen durchsuchen muss, können Sie mehrere suchspezifische Unterroutinen bereitstellen. Jedes Mal, wenn Ihr Treiber die allgemeine Suchroutine aufruft, gibt er die Adresse einer Ihrer suchspezifischen Unterroutinen an.

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

Anforderungen

Anforderung Wert
Zielplattform Universell
KMDF-Mindestversion 1.0
UMDF-Mindestversion 2.0
Kopfzeile wdfio.h (einschließen von Wdf.h)
Bibliothek Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
DDI-Complianceregeln DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed(kmdf), wdfioqueueretrievefoundrequest, WdfIoQueueRetrieveFoundRequest(kmdf), wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest(kmdf)

Weitere Informationen

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop

WdfObjectDereference