Compartilhar via


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
STATUS_INVALID_PARAMETER
Um parâmetro inválido foi detectado.
STATUS_INVALID_DEVICE_REQUEST
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.
STATUS_INSUFFICIENT_RESOURCES
A estrutura não pôde alocar recursos do sistema (normalmente memória).
STATUS_REQUEST_NOT_ACCEPTED
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:

  1. Especifique o identificador da solicitação recebida para o parâmetro Request do método WdfIoTargetFormatRequestForIoctl.
  2. 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.

  3. 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.

Para obter mais informações sobre como encaminhar uma solicitação de E/S, consulte Encaminhando solicitações de E/S.

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:

  1. 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.

  2. 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:

    Observe que, se o driver chamar WdfRequestRetrieveInputMemory ou WdfRequestRetrieveOutputMemory e passar o identificador de memória para WdfIoTargetFormatRequestForIoctl, o driver não deverá concluir a solicitação de E/S recebida até que o driver exclua, reutilize ou reformate o novo objeto de solicitação criado pelo driver. (WdfIoTargetFormatRequestForIoctl incrementa a contagem de referência do objeto de memória. Excluir, reutilizar ou reformatar um objeto de solicitação diminui a contagem de referência do objeto de memória.)
Depois que um driver chama WdfIoTargetFormatRequestForIoctl para formatar uma solicitação de controle de dispositivo, o driver deve chamar WdfRequestSend para enviar a solicitação (de forma síncrona ou assíncrona) para um 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(
                                  &params, 
                                  WDF_REQUEST_REUSE_NO_FLAGS, 
                                  STATUS_SUCCESS
                                  );
    status = WdfRequestReuse(Request, &params);
    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

EvtDriverDeviceAdd

WDFMEMORY_OFFSET

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForInternalIoctl

WdfIoTargetSendIoctlSynchronously

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveOutputMemory

WdfRequestReuse

WdfRequestSend