Funzione WdfRequestSend (wdfrequest.h)
[Si applica a KMDF e UMDF]
Il metodo WdfRequestSend invia una richiesta di I/O specificata a una destinazione di I/O specificata.
Sintassi
BOOLEAN WdfRequestSend(
[in] WDFREQUEST Request,
[in] WDFIOTARGET Target,
PWDF_REQUEST_SEND_OPTIONS Options
);
Parametri
[in] Request
Handle per un oggetto richiesta del framework.
[in] Target
Handle per un oggetto di destinazione di I/O del framework. Per altre informazioni su come ottenere questo handle, vedere la sezione Osservazioni seguente.
Options
Puntatore a una struttura WDF_REQUEST_SEND_OPTIONS che contiene le opzioni di richiesta fornite dal chiamante. Questo parametro è facoltativo e può essere NULL se non si desidera abilitare alcuna opzione di richiesta.
Valore restituito
WdfRequestSend restituisce TRUE se la richiesta è stata inviata alla destinazione. In caso contrario, questo metodo restituisce FALSE e la chiamata a WdfRequestGetStatus restituisce uno stato che non supera un test di NT_SUCCESS().
Se il driver fornisce un handle di oggetto non valido, si verifica un controllo di bug.
Commenti
L'oggetto richiesta specificato dal driver per il parametro Request può essere quello ricevuto o quello creato chiamando il metodo WdfRequestCreate .
Per ottenere un handle per un oggetto di destinazione di I/O, il driver può eseguire una delle operazioni seguenti:
- Se il driver usa destinazioni di I/O generali, chiama WdfDeviceGetIoTarget. Per altre informazioni, vedere Inizializzazione di una destinazione di I/O generale.
- Se il driver usa una destinazione di I/O specializzata, chiama uno o più metodi definiti dall'oggetto di destinazione specializzato. Ad esempio, un driver per un dispositivo USB può chiamare WdfUsbTargetDeviceGetIoTarget o WdfUsbTargetPipeGetIoTarget.
Se WdfRequestSend ha esito negativo o se il driver imposta il flag di WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, il driver può chiamare WdfRequestGetStatus immediatamente dopo aver chiamato WdfRequestSend.
Se WdfRequestSend ha esito positivo e il driver non imposta il flag di WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, il driver chiama in genere WdfRequestGetStatus dall'interno di una funzione di callback CompletionRoutine .
Se il driver invia la richiesta in modo sincrono, è consigliabile che il driver imposti un valore di timeout nella struttura WDF_REQUEST_SEND_OPTIONS e il flag di timeout nel membro Flags di questa struttura.
Se il driver fornisce un valore di timeout, deve chiamare WdfRequestAllocateTimer prima di chiamare WdfRequestSend. In questo modo , WdfRequestSend non avrà esito negativo se sono presenti risorse di sistema insufficienti per allocare un timer.
Se il driver imposta il flag WDF_REQUEST_SEND_OPTION_SYNCHRONOUS , deve chiamare WdfRequestSend in IRQL = PASSIVE_LEVEL. Se questo flag non è impostato, il driver deve chiamare questo metodo in IRQL <= DISPATCH_LEVEL. WdfRequestSend invia la richiesta all'IRQL del chiamante.
Un driver non può chiamare WdfRequestSend per inviare una richiesta di I/O a una pipe USB, se il driver ha configurato un lettore continuo per la pipe.
Quando si invia una richiesta a un driver UMDF, un driver in modalità kernel deve seguire le restrizioni IRQL descritte in Supporto dei client Kernel-Mode nei driver UMDF.
Per altre informazioni su WdfRequestSend, vedere Inoltro di richieste di I/O.
Esempio
L'esempio di codice seguente è una versione abbreviata di una funzione di callback EvtIoWrite dal driver di esempio kmdf_fx2 . La funzione convalida la lunghezza del buffer della richiesta, ottiene un handle per il buffer, formatta la richiesta per una destinazione USB e invia la richiesta.
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;
}
Requisiti
Requisito | Valore |
---|---|
Piattaforma di destinazione | Universale |
Versione KMDF minima | 1,0 |
Versione UMDF minima | 2,0 |
Intestazione | wdfrequest.h (include Wdf.h) |
Libreria | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | Vedere la sezione Osservazioni. |
Regole di conformità DDI | 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) |