Função WdfIoTargetFormatRequestForIoctl (wdfiotarget.h)
[Aplica-se a KMDF e UMDF]
O método WdfIoTargetFormatRequestForIoctl cria uma solicitação de controle de dispositivo para um destino de E/S, mas não envia a solicitação.
Sintaxe
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
);
Parâmetros
[in] IoTarget
Um identificador para um objeto de destino de E/S local ou remoto que foi obtido de uma chamada anterior para WdfDeviceGetIoTarget ou WdfIoTargetCreate, ou de um método que um destino de E/S especializado fornece.
[in] Request
Um identificador para um objeto de solicitação de estrutura. Para obter mais informações, consulte a seção Comentários a seguir.
[in] IoctlCode
Um IOCTL (código de controle de E/S) compatível com o destino de E/S.
[in, optional] InputBuffer
Um identificador para um objeto de memória de estrutura. Esse objeto representa um buffer que contém dados que serão enviados para o destino de E/S. Para obter mais informações, consulte a seção Comentários a seguir.
[in, optional] InputBufferOffset
Um ponteiro para uma estrutura de WDFMEMORY_OFFSET alocada pelo chamador que fornece valores opcionais de deslocamento e comprimento de bytes. A estrutura usa esses valores para determinar o endereço inicial e o comprimento, dentro do buffer de entrada, para a transferência de dados. Se esse ponteiro for NULL, a transferência de dados começará no início do buffer de entrada e o tamanho da transferência será o tamanho do buffer.
[in, optional] OutputBuffer
Um identificador para um objeto de memória de estrutura. Esse objeto representa um buffer que receberá dados do destino de E/S. Para obter mais informações, consulte a seção Comentários a seguir.
[in, optional] OutputBufferOffset
Um ponteiro para uma estrutura de WDFMEMORY_OFFSET alocada pelo chamador que fornece valores opcionais de deslocamento e comprimento de bytes. A estrutura usa esses valores para determinar o endereço inicial e o comprimento, dentro do buffer de saída, para a transferência de dados. Se esse ponteiro for NULL, a transferência de dados começará no início do buffer de saída e o tamanho da transferência será o tamanho do buffer.
Retornar valor
WdfIoTargetFormatRequestForIoctl retornará STATUS_SUCCESS se a operação for bem-sucedida. Caso contrário, esse método poderá retornar um dos seguintes valores:
Código de retorno | Descrição |
---|---|
|
Um parâmetro inválido foi detectado. |
|
O comprimento da transferência era maior que o comprimento do buffer ou a solicitação de E/S já estava na fila para um destino de E/S. |
|
A estrutura não pôde alocar recursos do sistema (normalmente memória). |
|
O IRP (pacote de solicitação de E/S) que o parâmetro Request representa não fornece estruturas de IO_STACK_LOCATION suficientes para permitir que o driver encaminhe a solicitação. |
Esse método também pode retornar outros valores NTSTATUS.
Um bug marcar ocorrerá se o driver fornecer um identificador de objeto inválido.
Comentários
Use o método WdfIoTargetFormatRequestForIoctl , seguido pelo método WdfRequestSend , para enviar solicitações de controle de dispositivo de forma síncrona ou assíncrona. Como alternativa, use o método WdfIoTargetSendIoctlSynchronously para enviar solicitações de controle de dispositivo de forma síncrona.
Para obter mais informações sobre solicitações de controle de dispositivo, consulte Usando códigos de controle de E/S.
Você pode encaminhar uma solicitação de controle de dispositivo recebida pelo driver em uma fila de E/S ou pode criar e enviar uma nova solicitação. Em ambos os casos, a estrutura requer um objeto de solicitação e algum espaço de buffer.
Para encaminhar uma solicitação de controle de dispositivo recebida pelo driver em uma fila de E/S:
- Especifique o identificador da solicitação recebida para o parâmetro Request do método WdfIoTargetFormatRequestForIoctl.
-
Use o buffer de entrada da solicitação recebida para o parâmetro InputBuffer do método WdfIoTargetFormatRequestForIoctl.
O driver deve chamar WdfRequestRetrieveInputMemory para obter um identificador para um objeto de memória de estrutura que representa o buffer de entrada da solicitação e deve usar esse identificador como o valor de InputBuffer.
-
Use o buffer de saída da solicitação recebida para o parâmetro OutputBuffer do método WdfIoTargetFormatRequestForIoctl.
O driver deve chamar WdfRequestRetrieveOutputMemory para obter um identificador para o buffer de saída da solicitação e deve usar esse identificador como o valor de OutputBuffer.
Os drivers geralmente dividem as solicitações de E/S recebidas em solicitações menores que eles enviam para um destino de E/S, para que o driver possa criar novas solicitações.
Para criar uma nova solicitação de E/S:
-
Crie um novo objeto de solicitação e forneça seu identificador para o parâmetro Request do método WdfIoTargetFormatRequestForIoctl.
Chame WdfRequestCreate para pré-alocar um ou mais objetos de solicitação. Você pode reutilizar esses objetos de solicitação chamando WdfRequestReuse. A função de retorno de chamada EvtDriverDeviceAdd do driver pode pré-alocar objetos de solicitação para um dispositivo.
-
Forneça espaço em buffer e forneça o identificador do buffer para os parâmetros InputBuffer e OutputBuffer do método WdfIoTargetFormatRequestForIoctl.
Seu driver deve especificar esse espaço de buffer como identificador WDFMEMORY para memória gerenciada por estrutura. O driver pode fazer um dos seguintes procedimentos:
- Chame WdfMemoryCreate ou WdfMemoryCreatePreallocated para criar um novo buffer de memória, se você quiser que o driver passe um novo buffer para o destino de E/S.
- Chame WdfRequestRetrieveInputMemory ou WdfRequestRetrieveOutputMemory para obter um identificador para o objeto de memória que representa o buffer de uma solicitação de E/S recebida, se você quiser que o driver passe o conteúdo desse buffer para o destino de E/S.
Várias chamadas para WdfIoTargetFormatRequestForIoctl que usam a mesma solicitação não causam alocações de recursos adicionais. Portanto, para reduzir a chance de WdfRequestCreate retornar STATUS_INSUFFICIENT_RESOURCES, a função de retorno de chamada EvtDriverDeviceAdd do driver pode chamar WdfRequestCreate para pré-alocar um ou mais objetos de solicitação para um dispositivo. O driver pode reutilizar posteriormente (chamar WdfRequestReuse), reformat (chamar WdfIoTargetFormatRequestForIoctl) e reenviar (chamar WdfRequestSend) cada objeto de solicitação sem arriscar um valor de retorno STATUS_INSUFFICIENT_RESOURCES de uma chamada posterior para WdfRequestCreate. Todas as chamadas subsequentes para WdfIoTargetFormatRequestForIoctl para o objeto de solicitação reutilizado retornarão STATUS_SUCCESS, se os valores de parâmetro não forem alterados. (Se o driver não chamar o mesmo método de formatação de solicitação cada vez, recursos adicionais poderão ser alocados. Além disso, se o código de controle de E/S especificar um tipo de transferência de METHOD_BUFFERED, a estrutura deverá alocar um buffer do sistema para cada solicitação e essa alocação poderá falhar devido a recursos de memória insuficientes.)
Para obter informações sobre como obter informações de status após a conclusão de uma solicitação de E/S, consulte Obtendo informações de conclusão.
Para obter mais informações sobre WdfIoTargetFormatRequestForIoctl, consulte Enviando solicitações de E/S para destinos gerais de E/S.
Para obter mais informações sobre destinos de E/S, consulte Usando destinos de E/S.
Exemplos
O código a seguir reutiliza um objeto de solicitação preallocado e objetos de memória pré-alocados. O exemplo atribui buffers de entrada e saída aos objetos de memória, formata o objeto de solicitação, registra uma função de retorno de chamada CompletionRoutine e envia a solicitação para um destino de E/S.
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;
}
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 | wdfiotarget.h (inclua Wdf.h) |
Biblioteca | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
Regras de conformidade de DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestFormattedValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf) |
Confira também
WdfIoTargetFormatRequestForInternalIoctl
WdfIoTargetSendIoctlSynchronously