WdfRequestSend-Funktion (wdfrequest.h)
[Gilt für KMDF und UMDF]
Die WdfRequestSend-Methode sendet eine angegebene E/A-Anforderung an ein angegebenes E/A-Ziel.
Syntax
BOOLEAN WdfRequestSend(
[in] WDFREQUEST Request,
[in] WDFIOTARGET Target,
PWDF_REQUEST_SEND_OPTIONS Options
);
Parameter
[in] Request
Ein Handle für ein Frameworkanforderungsobjekt.
[in] Target
Ein Handle für ein Framework-E/A-Zielobjekt. Weitere Informationen zum Abrufen dieses Handle finden Sie im folgenden Abschnitt Mit anmerkungen.
Options
Ein Zeiger auf eine WDF_REQUEST_SEND_OPTIONS Struktur, die vom Aufrufer bereitgestellte Anforderungsoptionen enthält. Dieser Parameter ist optional und kann NULL sein, wenn Sie keine Anforderungsoptionen aktivieren möchten.
Rückgabewert
WdfRequestSend gibt TRUE zurück, wenn die Anforderung an das Ziel gesendet wurde. Andernfalls gibt diese Methode FALSE zurück, und das Aufrufen von WdfRequestGetStatus gibt eine status zurück, die einen NT_SUCCESS()-Test nicht erfolgreich ist.
Eine Fehlerüberprüfung tritt auf, wenn der Treiber ein ungültiges Objekthandle bereitstellt.
Hinweise
Das Anforderungsobjekt, das der Treiber für den Request-Parameter angibt, kann eines sein, das er empfangen hat , oder eines, das er durch Aufrufen der WdfRequestCreate-Methode erstellt hat .
Um ein Handle für ein E/A-Zielobjekt abzurufen, kann der Treiber eine der folgenden Aktionen ausführen:
- Wenn der Treiber allgemeine E/A-Ziele verwendet, ruft er WdfDeviceGetIoTarget auf. Weitere Informationen finden Sie unter Initialisieren eines allgemeinen E/A-Ziels.
- Wenn der Treiber ein spezialisiertes E/A-Ziel verwendet, ruft er eine oder mehrere Methoden auf, die vom spezialisierten Zielobjekt definiert werden. Ein Treiber für ein USB-Gerät kann beispielsweise WdfUsbTargetDeviceGetIoTarget oder WdfUsbTargetPipeGetIoTarget aufrufen.
Wenn WdfRequestSend fehlschlägt oder Ihr Treiber das WDF_REQUEST_SEND_OPTION_SYNCHRONOUS-Flag festlegt, kann der Treiber WdfRequestGetStatus sofort nach dem Aufruf von WdfRequestSend aufrufen.
Wenn WdfRequestSend erfolgreich ist und Ihr Treiber das WDF_REQUEST_SEND_OPTION_SYNCHRONOUS-Flag nicht festgelegt hat, ruft der Treiber in der Regel WdfRequestGetStatus in einer CompletionRoutine-Rückruffunktion auf.
Wenn der Treiber die Anforderung synchron sendet, wird empfohlen, dass der Treiber einen Timeoutwert in der WDF_REQUEST_SEND_OPTIONS-Struktur und das Timeoutflag im Flags-Member dieser Struktur festlegen.
Wenn der Treiber einen Timeoutwert bereitstellt, sollte er WdfRequestAllocateTimer aufrufen, bevor WdfRequestSend aufgerufen wird. Dadurch wird sichergestellt, dass WdfRequestSend nicht fehlschlägt , wenn nicht genügend Systemressourcen vorhanden sind, um einen Timer zuzuweisen.
Wenn der Treiber das WDF_REQUEST_SEND_OPTION_SYNCHRONOUS-Flag festlegt, muss er WdfRequestSend unter IRQL = PASSIVE_LEVEL aufrufen. Wenn dieses Flag nicht festgelegt ist, muss der Treiber diese Methode unter IRQL <= DISPATCH_LEVEL aufrufen. WdfRequestSend sendet die Anforderung am IRQL des Aufrufers.
Ein Treiber kann WdfRequestSend nicht aufrufen, um eine E/A-Anforderung an eine USB-Pipe zu senden, wenn der Treiber einen kontinuierlichen Reader für die Pipe konfiguriert hat.
Beim Senden einer Anforderung an einen UMDF-Treiber muss ein Kernelmodustreiber die IRQL-Einschränkungen befolgen, die unter Unterstützen Kernel-Mode Clients in UMDF-Treibern beschrieben sind.
Weitere Informationen zu WdfRequestSend finden Sie unter Weiterleiten von E/A-Anforderungen.
Beispiele
Das folgende Codebeispiel ist eine verkürzte Version einer EvtIoWrite-Rückruffunktion aus dem kmdf_fx2 Beispieltreibers. Die Funktion überprüft die Pufferlänge der Anforderung, ruft ein Handle für den Puffer ab, formatiert die Anforderung für ein USB-Ziel und sendet die Anforderung.
VOID
OsrFxEvtIoWrite(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
WDFUSBPIPE pipe;
NTSTATUS status;
WDFMEMORY reqMemory;
PDEVICE_CONTEXT pDeviceContext;
UNREFERENCED_PARAMETER(Queue);
//
// Check if the transfer size is valid.
//
if (Length > MAX_TRANSFER_BUFFER_SIZE) {
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
//
// Get driver-defined context space from
// the device object. The driver stored the
// pipe handle there.
//
pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
pipe = pDeviceContext->BulkWritePipe;
//
// Get a handle to a memory object that represents
// the input buffer.
//
status = WdfRequestRetrieveInputMemory(Request, &reqMemory);
if (!NT_SUCCESS(status)){
goto Exit;
}
//
// Format the request so it can be sent to a USB target.
//
status = WdfUsbTargetPipeFormatRequestForWrite(
pipe,
Request,
reqMemory,
NULL // Offsets
);
if (!NT_SUCCESS(status)) {
goto Exit;
}
//
// Set a CompletionRoutine callback function.
//
WdfRequestSetCompletionRoutine(
Request,
EvtRequestReadCompletionRoutine,
pipe
);
//
// Send the request. If an error occurs, complete the request.
//
if (WdfRequestSend(
Request,
WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(Request);
goto Exit;
}
Exit:
if (!NT_SUCCESS(status)) {
WdfRequestCompleteWithInformation(
Request,
status,
0
);
}
return;
}
Anforderungen
Anforderung | Wert |
---|---|
Zielplattform | Universell |
KMDF-Mindestversion | 1.0 |
UMDF-Mindestversion | 2.0 |
Kopfzeile | wdfrequest.h (einschließen von Wdf.h) |
Bibliothek | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | Weitere Informationen finden Sie im Abschnitt mit den Hinweisen. |
DDI-Complianceregeln | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), ReqCompletionRoutine(kmdf), ReqMarkCancelableSend(kmdf), ReqSendFail(kmdf), ReqSendWhileSpinlock(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf), RequestFormattedValid(kmdf), RequestGetStatusValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf), SyncReqSend2(kmdf), WdfRequestSendSyncAtDispatch(kmdf), WdfRequestSendSyncAtDispatch2(kmdf) |