Função WdfUsbTargetPipeWriteSynchronously (wdfusb.h)

[Aplica-se a KMDF e UMDF]

O método WdfUsbTargetPipeWriteSynchronously cria uma solicitação de gravação e a envia de forma síncrona para um pipe de saída USB especificado.

Sintaxe

NTSTATUS WdfUsbTargetPipeWriteSynchronously(
  [in]            WDFUSBPIPE                Pipe,
  [in, optional]  WDFREQUEST                Request,
  [in, optional]  PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    MemoryDescriptor,
  [out, optional] PULONG                    BytesWritten
);

Parâmetros

[in] Pipe

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

[in, optional] Request

Um identificador para um objeto de solicitação de estrutura. Esse parâmetro é opcional e pode ser NULL. Para obter mais informações, consulte a seção Comentários a seguir.

[in, optional] RequestOptions

Um ponteiro para uma estrutura de WDF_REQUEST_SEND_OPTIONS alocada pelo chamador que especifica opções para a solicitação. Esse ponteiro é opcional e pode ser NULL. Para obter mais informações, consulte a seção Comentários a seguir.

[in, optional] MemoryDescriptor

Um ponteiro para uma estrutura de WDF_MEMORY_DESCRIPTOR alocada pelo chamador que descreve o buffer que contém dados que serão gravados no dispositivo. Para obter mais informações sobre esse buffer, consulte a seção Comentários a seguir.

[out, optional] BytesWritten

Um ponteiro para um local que recebe o número de bytes gravados, se a operação for bem-sucedida. Esse parâmetro é opcional e pode ser NULL.

Retornar valor

WdfUsbTargetPipeWriteSynchronously retorna o valor de status de conclusão do destino de E/S 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_INFO_LENGTH_MISMATCH
O tamanho da estrutura WDF_REQUEST_SEND_OPTIONS para a qual o parâmetro RequestOptions aponta estava incorreto.
STATUS_INVALID_PARAMETER
Um parâmetro inválido foi detectado.
STATUS_INSUFFICIENT_RESOURCES
Memória insuficiente disponível.
STATUS_INVALID_DEVICE_REQUEST
O IRQL do chamador não foi PASSIVE_LEVEL, 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_IO_TIMEOUT
O driver forneceu um valor de tempo limite e a solicitação não foi concluída dentro do tempo alocado.
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 WdfUsbTargetPipeWriteSynchronously para enviar solicitações de gravação de forma síncrona. Para enviar solicitações de gravação de forma assíncrona, use WdfUsbTargetPipeFormatRequestForWrite, seguido por WdfRequestSend.

O pipe especificado deve ser um pipe de saída e o tipo do pipe deve ser WdfUsbPipeTypeBulk ou WdfUsbPipeTypeInterrupt.

O método WdfUsbTargetPipeWriteSynchronously não retorna até que a solicitação seja concluída, a menos que o driver forneça um valor de tempo limite na estrutura WDF_REQUEST_SEND_OPTIONS do parâmetro RequestOptions ou a menos que um erro seja detectado.

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 em 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 .
  2. Use o buffer de entrada da solicitação recebida para o parâmetro MemoryDescriptor .

    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, em seguida, colocar esse identificador na estrutura WDF_MEMORY_DESCRIPTOR para a qual MemoryDescriptor aponta.

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 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. Forneça um identificador de solicitação NULL para o parâmetro Request do método WdfUsbTargetPipeWriteSynchronously ou crie um novo objeto de solicitação e forneça seu identificador:
    • Se você fornecer um identificador de solicitação NULL, a estrutura usará um objeto de solicitação interno. Essa técnica é simples de usar, mas o driver não pode cancelar a solicitação.
    • Se você chamar WdfRequestCreate para criar um ou mais objetos de solicitação, poderá reutilizar esses objetos de solicitação chamando WdfRequestReuse. Essa técnica permite que a função de retorno de chamada EvtDriverDeviceAdd do driver pré-alocar objetos de solicitação para um dispositivo. Além disso, outro thread de driver pode chamar WdfRequestCancelSentRequest para cancelar a solicitação, se necessário.

    O driver pode especificar um parâmetro RequestOptions não NULL, independentemente de o driver fornecer um parâmetro de solicitação não NULL ou NULL. Você pode, por exemplo, usar o parâmetro RequestOptions para especificar um valor de tempo limite.

  2. Forneça espaço de buffer para o parâmetro MemoryDescriptor do método WdfUsbTargetPipeWriteSynchronously.

    O driver pode especificar esse espaço de buffer como um buffer alocado localmente, como um identificador WDFMEMORY ou como um MDL. Você pode usar qualquer método mais conveniente.

    Se necessário, a estrutura converte a descrição do buffer em uma que esteja correta para o método do destino de E/S para acessar buffers de dados.

    As seguintes técnicas estão disponíveis:

    • Fornecer um buffer local

      Como wdfUsbTargetPipeWriteSynchronously manipula solicitações de E/S de forma síncrona, o driver pode criar buffers de solicitação que são locais para a rotina de chamada, como mostra o exemplo de código a seguir.

      WDF_MEMORY_DESCRIPTOR  memoryDescriptor;
      MY_BUFFER_TYPE  myBuffer;
      WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDescriptor,
                                        (PVOID) &myBuffer,
                                        sizeof(myBuffer));
      
    • Fornecer um identificador WDFMEMORY

      Chame WdfMemoryCreate ou WdfMemoryCreatePreallocated para obter um identificador para a memória gerenciada pela estrutura, como mostra o exemplo de código a seguir.

      WDF_MEMORY_DESCRIPTOR  memoryDescriptor;
      WDFMEMORY  memoryHandle = NULL;
      status = WdfMemoryCreate(NULL,
                               NonPagedPool,
                               POOL_TAG,
                               MY_BUFFER_SIZE,
                               &memoryHandle,
                               NULL);
      WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memoryDescriptor,
                                        memoryHandle,
                                        NULL);
      

      Como alternativa, o driver pode chamar WdfRequestRetrieveInputMemory para obter um identificador para um objeto de memória de estrutura que representa o buffer de entrada 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. O driver não deve concluir a solicitação de E/S recebida até que a nova solicitação que o WdfUsbTargetPipeWriteSynchronously envia para o destino de E/S tenha sido excluída, reutilizado ou reformatado. (WdfUsbTargetPipeWriteSynchronously 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.)

    • Fornecer um MDL

      Os drivers podem obter o MDL associado a uma solicitação de E/S recebida chamando WdfRequestRetrieveInputWdmMdl.

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 WdfUsbTargetPipeWriteSynchronously e destinos de E/S USB, consulte Destinos de E/S USB.

Exemplos

O exemplo de código a seguir cria um objeto de memória, obtém um ponteiro para o buffer do objeto, preenche o buffer e usa o buffer como entrada para WdfUsbTargetPipeWriteSynchronously.

WDF_MEMORY_DESCRIPTOR  writeBufDesc;
WDFMEMORY  wdfMemory;
ULONG  writeSize, bytesWritten;
size_t  bufferSize;
NTSTATUS status;

writeSize = SMALL_BUF_LEN;
status = WdfMemoryCreate(
                         WDF_NO_OBJECT_ATTRIBUTES,
                         NonPagedPool,
                         0,
                         writeSize,
                         &wdfMemory,
                         NULL
                         );
if (!NT_SUCCESS(status)){
    return status;
}

writeBuffer = WdfMemoryGetBuffer(
                                 wdfMemory,
                                 &bufferSize
                                 );

FillMyBuffer(
             writeBuffer,
             writeSize
             );

WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
                                  &writeBufDesc,
                                  writeBuffer,
                                  writeSize
                                  );

status = WdfUsbTargetPipeWriteSynchronously(
                                            pipeHandle,
                                            NULL,
                                            NULL,
                                            &writeBufDesc,
                                            &bytesWritten
                                            );

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 (include Wdfusb.h)
Biblioteca Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL PASSIVE_LEVEL
Regras de conformidade da DDI DriverCreate(kmdf), InternalIoctlReqs(kmdf), IoctlReqs(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), ReadReqs(kmdf), SyncReqSend(kmdf), UsbKmdfIrql(kmdf), UsbKmdfIrql2(kmdf), UsbKmdfIrqlExplicit(kmdf)

Confira também

WDF_MEMORY_DESCRIPTOR_INIT_BUFFER

WdfMemoryCreate

WdfMemoryGetBuffer

WdfRequestCancelSentRequest

WdfUsbTargetPipeReadSynchronously