Fonction WdfRequestSend (wdfrequest.h)
[S’applique à KMDF et UMDF]
La méthode WdfRequestSend envoie une demande d’E/S spécifiée à une cible d’E/S spécifiée.
Syntaxe
BOOLEAN WdfRequestSend(
[in] WDFREQUEST Request,
[in] WDFIOTARGET Target,
PWDF_REQUEST_SEND_OPTIONS Options
);
Paramètres
[in] Request
Handle d’un objet de requête d’infrastructure.
[in] Target
Handle d’un objet cible d’E/S framework. Pour plus d’informations sur l’obtention de ce handle, consultez la section Remarques suivante.
Options
Pointeur vers une structure de WDF_REQUEST_SEND_OPTIONS qui contient des options de requête fournies par l’appelant. Ce paramètre est facultatif et peut avoir la valeur NULL si vous ne souhaitez activer aucune option de requête.
Valeur retournée
WdfRequestSend retourne TRUE si la demande a été envoyée à la cible. Sinon, cette méthode retourne FALSE, et l’appel de WdfRequestGetStatus renvoie un status qui échoue à un test NT_SUCCESS().
Un bogue case activée se produit si le pilote fournit un handle d’objet non valide.
Remarques
L’objet de requête que le pilote spécifie pour le paramètre Request peut être celui qu’il a reçu ou celui qu’il a créé en appelant la méthode WdfRequestCreate .
Pour obtenir un handle pour un objet cible d’E/S, le pilote peut effectuer l’une des opérations suivantes :
- Si le pilote utilise des cibles d’E/S générales, il appelle WdfDeviceGetIoTarget. Pour plus d’informations, consultez Initialisation d’une cible d’E/S générale.
- Si le pilote utilise une cible d’E/S spécialisée, il appelle une ou plusieurs méthodes que l’objet cible spécialisé définit. Par exemple, un pilote pour un périphérique USB peut appeler WdfUsbTargetDeviceGetIoTarget ou WdfUsbTargetPipeGetIoTarget.
Si WdfRequestSend échoue ou si votre pilote définit l’indicateur WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, le pilote peut appeler WdfRequestGetStatus immédiatement après avoir appelé WdfRequestSend.
Si WdfRequestSend réussit et que votre pilote ne définit pas l’indicateur WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, le pilote appelle généralement WdfRequestGetStatus à partir d’une fonction de rappel CompletionRoutine .
Si le pilote envoie la requête de manière synchrone, nous vous recommandons de définir une valeur de délai d’attente dans la structure WDF_REQUEST_SEND_OPTIONS et l’indicateur de délai d’attente dans le membre Flags de cette structure.
Si le pilote fournit une valeur de délai d’attente, il doit appeler WdfRequestAllocateTimer avant d’appeler WdfRequestSend. Cela garantit que WdfRequestSend n’échouera pas s’il n’y a pas de ressources système suffisantes pour allouer un minuteur.
Si le pilote définit l’indicateur WDF_REQUEST_SEND_OPTION_SYNCHRONOUS , il doit appeler WdfRequestSend à l’adresse IRQL = PASSIVE_LEVEL. Si cet indicateur n’est pas défini, le pilote doit appeler cette méthode à l’adresse IRQL <= DISPATCH_LEVEL. WdfRequestSend envoie la demande à l’IRQL de l’appelant.
Un pilote ne peut pas appeler WdfRequestSend pour envoyer une demande d’E/S à un canal USB, si le pilote a configuré un lecteur continu pour le canal.
Lors de l’envoi d’une requête à un pilote UMDF, un pilote en mode noyau doit respecter les restrictions IRQL décrites dans Prise en charge des clients Kernel-Mode dans les pilotes UMDF.
Pour plus d’informations sur WdfRequestSend, consultez Transfert des demandes d’E/S.
Exemples
L’exemple de code suivant est une version abrégée d’une fonction de rappel EvtIoWrite à partir de l’exemple de pilote kmdf_fx2 . La fonction valide la longueur de la mémoire tampon de la requête, obtient un handle dans la mémoire tampon, met en forme la requête pour une cible USB et envoie la requête.
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;
}
Configuration requise
Condition requise | Valeur |
---|---|
Plateforme cible | Universal |
Version KMDF minimale | 1.0 |
Version UMDF minimale | 2.0 |
En-tête | wdfrequest.h (include Wdf.h) |
Bibliothèque | Wdf01000.sys (KMDF) ; WUDFx02000.dll (UMDF) |
IRQL | Consultez la section Notes. |
Règles de 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) |