Freigeben über


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 bestimmten Kriterien entspricht, gewährt jedoch keine Besitz der Anforderung an den Treiber.

Syntax

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

Die Parameter

[in] Queue

Ein Handle zu einem Framework-Warteschlangenobjekt.

[in, optional] FoundRequest

Ein Anforderungsobjekthandle, das der Treiber von einem vorherigen Aufruf an WdfIoQueueFindRequestempfangen hat. Dieser Parameter ist optional und kann NULL-werden.

[in, optional] FileObject

Ein Handle zu einem Framework-Dateiobjekt. Dieser Parameter ist optional und kann NULL-werden.

[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-werden.

[out] OutRequest

Ein Zeiger auf einen Speicherort, der ein Handle für die gefundene Anforderung empfängt. Wenn keine Übereinstimmung gefunden wird, empfängt 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 einen ungültigen Handle zur Auswahl.
STATUS_NOT_FOUND
Die vom FoundRequest Parameter identifizierte Anforderung wurde in der E/A-Warteschlange nicht gefunden.
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-Wertezurückgeben.

Wenn der Treiber ein ungültiges Objekthandle bereitstellt, tritt eine Fehlerüberprüfung auf.

Bemerkungen

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 Verteilermethode für die angegebene E/A-Warteschlange verwendet.

Wenn FileObject- nicht NULL-ist, überprüft WdfIoQueueFindRequest nur Anforderungen, die dem angegebenen Dateiobjekthandle zugeordnet sind.

Wenn FoundRequest-NULL-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 an der Anforderung, die durch FoundRequestidentifiziert wird. Um eine iterative Schleife zu erstellen, geben Sie NULL- für den ersten Aufruf an, und verwenden Sie dann das zurückgegebene Handle als FoundRequest Parameter für nachfolgende Aufrufe.

Wenn Parameter 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 WdfIoQueueFindRequestrequestdem Treiber Besitz anforderungen nicht gewähren. Wenn Ihr Treiber den Besitz einer Anforderung abrufen soll, damit er die Anforderung verarbeiten kann, muss der Treiber WdfIoQueueRetrieveFoundRequestaufrufen. Tatsächlich kann der Treiber nur folgendes mit dem Handle ausführen, das er für den parameter OutRequest empfängt:

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 gesucht, die einen angegebenen E/A-Funktionscode enthält. Wenn eine übereinstimmende Anforderung gefunden wird, ruft das Beispiel WdfIoQueueRetrieveFoundRequestauf.

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 Informationstypen 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
Minimale KMDF-Version 1.0
Mindest-UMDF-Version 2.0
Kopfzeile wdfio.h (einschließen 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)

Siehe auch

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop-

WdfObjectDereference-