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 |
---|---|
|
Der Treiber stellt einen ungültigen Handle zur Auswahl. |
|
Die vom FoundRequest Parameter identifizierte Anforderung wurde in der E/A-Warteschlange nicht gefunden. |
|
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:
- 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 eine treiberdefinierte Methode für den Zugriff auf den Kontextbereich des Objekts.
- Verwenden Sie ihn als Eingabeparameter, um WdfObjectDereference-.
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(¶ms);
*Request = NULL;
prevTagRequest = tagRequest = NULL;
do {
WDF_REQUEST_PARAMETERS_INIT(¶ms);
status = WdfIoQueueFindRequest(
Queue,
prevTagRequest,
NULL,
¶ms,
&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) |