Funzione WdfIoTargetFormatRequestForIoctl (wdfiotarget.h)
[Si applica a KMDF e UMDF]
Il metodo WdfIoTargetFormatRequestForIoctl compila una richiesta di controllo del dispositivo per una destinazione di I/O, ma non invia la richiesta.
Sintassi
NTSTATUS WdfIoTargetFormatRequestForIoctl(
[in] WDFIOTARGET IoTarget,
[in] WDFREQUEST Request,
[in] ULONG IoctlCode,
[in, optional] WDFMEMORY InputBuffer,
[in, optional] PWDFMEMORY_OFFSET InputBufferOffset,
[in, optional] WDFMEMORY OutputBuffer,
[in, optional] PWDFMEMORY_OFFSET OutputBufferOffset
);
Parametri
[in] IoTarget
Handle a un oggetto di destinazione I/O locale o remoto ottenuto da una chiamata precedente a WdfDeviceGetIoTarget o WdfIoTargetCreate o da un metodo fornito da una destinazione I/O specializzata.
[in] Request
Handle per un oggetto richiesta framework. Per ulteriori informazioni, vedere la sezione Osservazioni successiva.
[in] IoctlCode
Codice di controllo I/O (IOCTL) supportato dalla destinazione I/O.
[in, optional] InputBuffer
Handle per un oggetto memoria framework. Questo oggetto rappresenta un buffer che contiene dati che verranno inviati alla destinazione di I/O. Per ulteriori informazioni, vedere la sezione Osservazioni successiva.
[in, optional] InputBufferOffset
Puntatore a una struttura WDFMEMORY_OFFSET allocata dal chiamante che fornisce valori facoltativi di offset e lunghezza di byte. Il framework usa questi valori per determinare l'indirizzo iniziale e la lunghezza, all'interno del buffer di input, per il trasferimento dei dati. Se questo puntatore è NULL, il trasferimento dei dati inizia all'inizio del buffer di input e la dimensione del trasferimento è la dimensione del buffer.
[in, optional] OutputBuffer
Handle per un oggetto memoria framework. Questo oggetto rappresenta un buffer che riceverà i dati dalla destinazione di I/O. Per ulteriori informazioni, vedere la sezione Osservazioni successiva.
[in, optional] OutputBufferOffset
Puntatore a una struttura WDFMEMORY_OFFSET allocata dal chiamante che fornisce valori facoltativi di offset e lunghezza di byte. Il framework usa questi valori per determinare l'indirizzo iniziale e la lunghezza, all'interno del buffer di output, per il trasferimento dei dati. Se questo puntatore è NULL, il trasferimento dei dati inizia all'inizio del buffer di output e la dimensione del trasferimento è la dimensione del buffer.
Valore restituito
WdfIoTargetFormatRequestForIoctl restituisce STATUS_SUCCESS se l'operazione ha esito positivo. In caso contrario, questo metodo potrebbe restituire uno dei valori seguenti:
Codice restituito | Descrizione |
---|---|
|
È stato rilevato un parametro non valido. |
|
La lunghezza del trasferimento è maggiore della lunghezza del buffer oppure la richiesta di I/O è già stata accodata a una destinazione di I/O. |
|
Il framework non è riuscito ad allocare le risorse di sistema (in genere memoria). |
|
Il pacchetto di richiesta I/O (IRP) che il parametro Request rappresenta non fornisce strutture IO_STACK_LOCATION sufficienti per consentire al driver di inoltrare la richiesta. |
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
Usare il metodo WdfIoTargetFormatRequestForIoctl , seguito dal metodo WdfRequestSend , per inviare richieste di controllo del dispositivo in modo sincrono o asincrono. In alternativa, usare il metodo WdfIoTargetSendIoctlSynchronously per inviare richieste di controllo dispositivo in modo sincrono.
Per altre informazioni sulle richieste di controllo del dispositivo, vedere Uso dei codici di controllo I/O.
È possibile inoltrare una richiesta di controllo del dispositivo ricevuta dal driver in una coda di I/O oppure creare e inviare una nuova richiesta. In entrambi i casi, il framework richiede un oggetto request e uno spazio buffer.
Per inoltrare una richiesta di controllo del dispositivo ricevuta dal driver in una coda di I/O:
- Specificare l'handle della richiesta ricevuta per il parametro Request del metodo WdfIoTargetFormatRequestForIoctl.
-
Usare il buffer di input della richiesta ricevuta per il parametro InputBuffer del metodo WdfIoTargetFormatRequestForIoctl.
Il driver deve chiamare WdfRequestRetrieveInputMemory per ottenere un handle a un oggetto memoria del framework che rappresenta il buffer di input della richiesta e deve usare tale handle come valore per InputBuffer.
-
Usare il buffer di output della richiesta ricevuta per il parametro OutputBuffer del metodo WdfIoTargetFormatRequestForIoctl.
Il driver deve chiamare WdfRequestRetrieveOutputMemory per ottenere un handle nel buffer di output della richiesta e deve usare tale handle come valore per OutputBuffer.
I driver spesso dividono le richieste di I/O ricevute in richieste più piccole inviate a una destinazione di I/O, in modo che il driver possa creare nuove richieste.
Per creare una nuova richiesta di I/O:
-
Creare un nuovo oggetto request e specificare il relativo handle per il parametro Request del metodo WdfIoTargetFormatRequestForIoctl.
Chiamare WdfRequestCrea per preallocare uno o più oggetti richiesta. È possibile riutilizzare questi oggetti richiesta chiamando WdfRequestReuse. La funzione di callback EvtDriverDevice del driver può preallocare gli oggetti di richiesta per un dispositivo.
-
Fornire spazio del buffer e fornire l'handle del buffer per i parametri InputBuffer e OutputBuffer del metodo WdfIoTargetFormatRequestForIoctl.
Il driver deve specificare questo spazio buffer come handle WDFMEMORY per la memoria gestita dal framework. Il driver può eseguire una delle operazioni seguenti:
- Chiamare WdfMemoryCreate o WdfMemoryCreatePreallocated per creare un nuovo buffer di memoria, se si vuole che il driver passi un nuovo buffer alla destinazione di I/O.
- Chiamare WdfRequestRetrieveInputMemory o WdfRequestRetrieveOutputMemory per ottenere un handle all'oggetto memoria che rappresenta il buffer della richiesta di I/O ricevuta, se si vuole che il driver passi il contenuto del buffer alla destinazione I/O.
Più chiamate a WdfIoTargetFormatRequestForIoctl che usano la stessa richiesta non causano allocazioni di risorse aggiuntive. Pertanto, per ridurre la possibilità che WdfRequestCreate restituirà STATUS_INSUFFICIENT_RESOURCES, la funzione evtDriverDeviceAdd callback del driver può chiamare WdfRequestCreate per preallocare uno o più oggetti richiesta per un dispositivo. Il driver può successivamente riutilizzare (chiamare WdfRequestReuse), riformatare (chiamare WdfIoTargetFormatRequestForIoctl) e inviare nuovamente (chiamare WdfRequestSend) ogni oggetto richiesta senza rischiare un valore restituito STATUS_INSUFFICIENT_RESOURCES da una chiamata successiva a WdfRequestCreate. Tutte le chiamate successive a WdfIoTargetFormatRequestForIoctl per l'oggetto richiesta riutilizzato restituiranno STATUS_SUCCESS, se i valori dei parametri non cambiano. Se il driver non chiama lo stesso metodo di formattazione delle richieste ogni volta, è possibile allocare risorse aggiuntive. Inoltre, se il codice di controllo I/O specifica un tipo di trasferimento di METHOD_BUFFERED, il framework deve allocare un buffer di sistema per ogni richiesta e tale allocazione potrebbe non riuscire a causa di risorse di memoria insufficienti.
Per informazioni sull'acquisizione di informazioni sullo stato dopo il completamento di una richiesta di I/O, vedere Recupero delle informazioni di completamento.
Per altre informazioni su WdfIoTargetFormatRequestForIoctl, vedere Invio di richieste di I/O a destinazioni di I/O generali.
Per altre informazioni sulle destinazioni di I/O, vedere Uso delle destinazioni di I/O.
Esempio
Il codice seguente riutilizza un oggetto richiesta preallocato e oggetti di memoria preallocati. L'esempio assegna buffer di input e output agli oggetti di memoria, formatta l'oggetto richiesta, registra una funzione di callback di CompletamentoRoutine e invia la richiesta a una destinazione di I/O.
NTSTATUS
NICSendOidRequestToTargetAsync(
IN WDFIOTARGET IoTarget,
IN WDFREQUEST Request,
IN PFILE_OBJECT FileObject,
IN ULONG IoctlControlCode,
IN OUT PVOID InputBuffer,
IN ULONG InputBufferLength,
IN OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
OUT PULONG BytesReadOrWritten
)
{
NTSTATUS status;
PREQUEST_CONTEXT reqContext;
WDF_REQUEST_REUSE_PARAMS params;
WDFMEMORY inputMem, outputMem;
WDF_REQUEST_REUSE_PARAMS_INIT(
¶ms,
WDF_REQUEST_REUSE_NO_FLAGS,
STATUS_SUCCESS
);
status = WdfRequestReuse(Request, ¶ms);
if (!NT_SUCCESS(status)){
return status;
}
reqContext = GetRequestContext(Request);
inputMem = outputMem = NULL;
if (InputBuffer != NULL) {
status = WdfMemoryAssignBuffer(
reqContext->InputMemory,
InputBuffer,
InputBufferLength
);
if (!NT_SUCCESS(status)) {
return status;
}
inputMem = reqContext->InputMemory;
}
if (OutputBuffer != NULL) {
status = WdfMemoryAssignBuffer(
reqContext->OutputMemory,
OutputBuffer,
OutputBufferLength
);
if (!NT_SUCCESS(status)) {
return status;
}
outputMem = reqContext->OutputMemory;
}
status = WdfIoTargetFormatRequestForIoctl(
IoTarget,
Request,
IoctlControlCode,
inputMem,
NULL,
outputMem,
NULL
);
if (!NT_SUCCESS(status)) {
return status;
}
WdfRequestSetCompletionRoutine(
Request,
NICSendOidRequestToTargetAsyncCompletionRoutine,
BytesReadOrWritten
);
if (WdfRequestSend(
Request,
IoTarget,
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(Request);
}
return status;
}
Requisiti
Requisito | Valore |
---|---|
Piattaforma di destinazione | Universale |
Versione KMDF minima | 1.0 |
Versione UMDF minima | 2,0 |
Intestazione | wdfiotarget.h (include Wdf.h) |
Libreria | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
Regole di conformità DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestFormattedValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf) |
Vedi anche
WdfIoTargetFormatRequestForInternalIoctl
WdfIoTargetSendIoctlSynchronously