Compartilhar via


Função WdfUsbTargetPipeFormatRequestForRead (wdfusb.h)

[Aplica-se a KMDF e UMDF]

O método WdfUsbTargetPipeFormatRequestForRead cria uma solicitação de leitura para um pipe de entrada USB, mas não envia a solicitação.

Sintaxe

NTSTATUS WdfUsbTargetPipeFormatRequestForRead(
  [in]           WDFUSBPIPE        Pipe,
  [in]           WDFREQUEST        Request,
  [in, optional] WDFMEMORY         ReadMemory,
  [in, optional] PWDFMEMORY_OFFSET ReadOffset
);

Parâmetros

[in] Pipe

Um identificador para um objeto de pipe de estrutura que foi obtido chamando WdfUsbInterfaceGetConfiguredPipe.

[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, optional] ReadMemory

Um identificador para um objeto de memória de estrutura. Esse objeto representa um buffer que receberá dados do pipe. O tamanho do buffer deve ser um múltiplo do tamanho máximo do pacote do pipe, a menos que o driver tenha chamado WdfUsbTargetPipeSetNoMaximumPacketSizeCheck. Para obter mais informações sobre esse buffer, consulte a seção Comentários a seguir.

[in, optional] ReadOffset

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 leitura, para a transferência de dados. Se esse ponteiro for NULL, a transferência de dados começará no início do buffer e o tamanho da transferência será o tamanho do buffer.

Retornar valor

WdfUsbTargetPipeFormatRequestForRead retornará STATUS_SUCCESS se a operação for bem-sucedida. Caso contrário, esse método pode retornar um dos seguintes valores:

Código de retorno Descrição
STATUS_INVALID_PARAMETER
Um parâmetro inválido foi detectado.
STATUS_INSUFFICIENT_RESOURCES
Memória insuficiente disponível.
STATUS_INVALID_DEVICE_REQUEST
Um descritor de memória inválido foi especificado, o tipo do pipe não era válido, a direção de transferência era inválida ou a solicitação de E/S especificada já estava na fila para um destino de E/S.
STATUS_INTEGER_OVERFLOW
O deslocamento especificado pelo parâmetro Offset era inválido.
STATUS_INVALID_BUFFER_SIZE
O tamanho do buffer não era um múltiplo do tamanho máximo do pacote do pipe. O tamanho do buffer deve ser um múltiplo do tamanho máximo do pacote do pipe, a menos que o driver tenha chamado WdfUsbTargetPipeSetNoMaximumPacketSizeCheck.
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 WdfUsbTargetPipeFormatRequestForRead, seguido por WdfRequestSend, para enviar solicitações de leitura de forma síncrona ou assíncrona. Como alternativa, use o método WdfUsbTargetPipeReadSynchronously para enviar solicitações de leitura de forma síncrona.

O pipe especificado pelo parâmetro Pipe deve ser um pipe de entrada e o tipo do pipe deve ser WdfUsbPipeTypeBulk ou WdfUsbPipeTypeInterrupt.

Você pode encaminhar uma solicitação de E/S 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 E/S que seu driver recebeu em uma fila de E/S:

  1. Especifique o identificador da solicitação recebida para o parâmetro Request do método WdfUsbTargetPipeFormatRequestForRead.
  2. Use o buffer de saída da solicitação recebida para o parâmetro ReadMemory do método WdfUsbTargetPipeFormatRequestForRead.

    O driver deve chamar WdfRequestRetrieveOutputMemory para obter um identificador para um objeto de memória de estrutura que representa o buffer de saída da solicitação e usar esse identificador como o valor do parâmetro ReadMemory .

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

    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 o parâmetro ReadMemory do método WdfUsbTargetPipeFormatRequestForRead.

    Seu driver deve especificar esse espaço de buffer como um 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 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.
    Observe que, se o driver chamar WdfRequestRetrieveOutputMemory e passar o identificador de memória para WdfUsbTargetPipeFormatRequestForRead, 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. (WdfUsbTargetPipeFormatRequestForRead 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 de chamar WdfUsbTargetPipeFormatRequestForRead para formatar uma solicitação de E/S, 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 WdfUsbTargetPipeFormatRequestForRead 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 WdfUsbTargetPipeFormatRequestForRead) e reenviar (chamar WdfRequestSend) cada objeto de solicitação sem arriscar uma STATUS_INSUFFICIENT_RESOURCES retornar valor de uma chamada posterior para WdfRequestCreate. Todas as chamadas subsequentes para WdfUsbTargetPipeFormatRequestForRead 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 todas as vezes, recursos adicionais poderão ser alocados.)

A estrutura define o sinalizador USBD_SHORT_TRANSFER_OK em seu URB interno. Definir esse sinalizador permite que o último pacote de uma transferência de dados seja menor que o tamanho máximo do pacote.

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 o método WdfUsbTargetPipeFormatRequestForRead e destinos de E/S USB, consulte Destinos de E/S USB.

Exemplos

O exemplo de código a seguir é do driver de exemplo kmdf_fx2 . Este exemplo é uma função de retorno de chamada EvtIoRead que encaminha uma solicitação de leitura para um pipe USB. O exemplo chama WdfRequestRetrieveOutputMemory para obter o buffer de saída da solicitação e formata a solicitação de leitura para que a solicitação possa ser enviada para um pipe USB. Em seguida, o exemplo registra uma função de retorno de chamada CompletionRoutine . Por fim, ele envia a solicitação para o pipe USB.

VOID 
OsrFxEvtIoRead(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  Length
    )
{
    WDFUSBPIPE  pipe;
    NTSTATUS  status;
    WDFMEMORY  reqMemory;
    PDEVICE_CONTEXT  pDeviceContext;

    //
    // First, validate input parameters.
    //
    if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) {
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
 
    pipe = pDeviceContext->BulkReadPipe;
 
    status = WdfRequestRetrieveOutputMemory(
                                            Request,
                                            &reqMemory
                                            );
    if (!NT_SUCCESS(status)){
        goto Exit;
    }
 
    status = WdfUsbTargetPipeFormatRequestForRead(
                                                  pipe,
                                                  Request,
                                                  reqMemory,
                                                  NULL
                                                  ); 
    if (!NT_SUCCESS(status)) {
        goto Exit;
    }

    WdfRequestSetCompletionRoutine(
                                   Request,
                                   EvtRequestReadCompletionRoutine,
                                   pipe
                                   );
    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 wdfusb.h (inclua Wdfusb.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), UsbKmdfIrql(kmdf), UsbKmdfIrql2(kmdf), UsbKmdfIrqlExplicit(kmdf)

Confira também

WDFMEMORY_OFFSET

WdfRequestCompleteWithInformation

WdfRequestGetStatus

WdfRequestSend

WdfRequestSetCompletionRoutine

WdfUsbInterfaceGetConfiguredPipe