Função WdfRequestSend (wdfrequest.h)
[Aplica-se a KMDF e UMDF]
O método WdfRequestSend envia uma solicitação de E/S especificada para um destino de E/S especificado.
Sintaxe
BOOLEAN WdfRequestSend(
[in] WDFREQUEST Request,
[in] WDFIOTARGET Target,
PWDF_REQUEST_SEND_OPTIONS Options
);
Parâmetros
[in] Request
Um identificador para um objeto de solicitação de estrutura.
[in] Target
Um identificador para um objeto de destino de E/S de estrutura. Para obter mais informações sobre como obter esse identificador, consulte a seção Comentários a seguir.
Options
Um ponteiro para uma estrutura de WDF_REQUEST_SEND_OPTIONS que contém opções de solicitação fornecidas pelo chamador. Esse parâmetro é opcional e pode ser NULL se você não quiser habilitar nenhuma opção de solicitação.
Retornar valor
WdfRequestSend retornará TRUE se a solicitação tiver sido enviada para o destino. Caso contrário, esse método retorna FALSE e chamar WdfRequestGetStatus retorna um status que falha em um teste de NT_SUCCESS().
Um bug marcar ocorrerá se o driver fornecer um identificador de objeto inválido.
Comentários
O objeto de solicitação especificado pelo driver para o parâmetro Request pode ser aquele que ele recebeu ou um que ele criou chamando o método WdfRequestCreate .
Para obter um identificador para um objeto de destino de E/S, o driver pode fazer um dos seguintes procedimentos:
- Se o driver estiver usando destinos gerais de E/S, ele chamará WdfDeviceGetIoTarget. Para obter mais informações, consulte Inicializando um destino de E/S geral.
- Se o driver estiver usando um destino de E/S especializado, ele chamará um ou mais métodos que o objeto de destino especializado define. Por exemplo, um driver para um dispositivo USB pode chamar WdfUsbTargetDeviceGetIoTarget ou WdfUsbTargetPipeGetIoTarget.
Se WdfRequestSend falhar ou se o driver definir o sinalizador WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, o driver poderá chamar WdfRequestGetStatus imediatamente após chamar WdfRequestSend.
Se WdfRequestSend for bem-sucedido e seu driver não definir o sinalizador WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, o driver normalmente chamará WdfRequestGetStatus de dentro de uma função de retorno de chamada CompletionRoutine .
Se o driver enviar a solicitação de forma síncrona, recomendamos que o driver defina um valor de tempo limite na estrutura WDF_REQUEST_SEND_OPTIONS e o sinalizador de tempo limite no membro Flags dessa estrutura.
Se o driver fornecer um valor de tempo limite, ele deverá chamar WdfRequestAllocateTimer antes de chamar WdfRequestSend. Isso garante que o WdfRequestSend não falhará se não houver recursos suficientes do sistema para alocar um temporizador.
Se o driver definir o sinalizador WDF_REQUEST_SEND_OPTION_SYNCHRONOUS , ele deverá chamar WdfRequestSend em IRQL = PASSIVE_LEVEL. Se esse sinalizador não estiver definido, o driver deverá chamar esse método em IRQL <= DISPATCH_LEVEL. WdfRequestSend envia a solicitação no IRQL do chamador.
Um driver não pode chamar WdfRequestSend para enviar uma solicitação de E/S para um pipe USB, se o driver tiver configurado um leitor contínuo para o pipe.
Ao enviar uma solicitação para um driver UMDF, um driver de modo kernel deve seguir as restrições IRQL descritas em Suporte Kernel-Mode clientes em drivers UMDF.
Para obter mais informações sobre WdfRequestSend, consulte Encaminhando solicitações de E/S.
Exemplos
O exemplo de código a seguir é uma versão abreviada de uma função de retorno de chamada EvtIoWrite do driver de exemplo kmdf_fx2 . A função valida o comprimento do buffer da solicitação, obtém um identificador para o buffer, formata a solicitação de um destino USB e envia a solicitação.
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;
}
Requisitos
Requisito | Valor |
---|---|
Plataforma de Destino | Universal |
Versão mínima do KMDF | 1.0 |
Versão mínima do UMDF | 2,0 |
Cabeçalho | wdfrequest.h (inclua Wdf.h) |
Biblioteca | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | Consulte a seção Observações. |
Regras de conformidade de 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) |