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 |
---|---|
|
Il driver fornisce un handle non valido. |
|
Impossibile trovare la richiesta identificata dal parametro FoundRequest nella coda di I/O. |
|
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 :
- Usarlo come parametro FoundRequest in una chiamata successiva a WdfIoQueueFindRequest.
- Usarlo come parametro FoundRequest in una chiamata successiva a WdfIoQueueRetrieveFoundRequest.
- Usarlo come parametro di input in una chiamata successiva a WdfObjectGetTypedContext o un metodo definito dal driver per accedere allo spazio di contesto dell'oggetto.
- Usarlo come parametro di input per WdfObjectDereference.
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(¶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;
}
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) |