Trabalhando com pipes USB em drivers UMDF 1.x
Aviso
O UMDF 2 é a versão mais recente do UMDF e substitui o UMDF 1. Todos os novos drivers UMDF devem ser gravados usando UMDF 2. Nenhum novo recurso está sendo adicionado ao UMDF 1 e há suporte limitado para UMDF 1 em versões mais recentes do Windows 10. Os drivers universais do Windows devem usar o UMDF 2.
Os exemplos de UMDF 1 arquivados podem ser encontrados no Windows 11, versão 22H2 – Atualização de exemplos de driver de maio de 2022.
Para obter mais informações, consulte Introdução com UMDF.
A estrutura representa cada pipe em uma interface USB como um objeto de pipe USB de estrutura. Quando um driver configura um dispositivo USB, a estrutura cria um objeto de pipe USB de estrutura para cada pipe em cada interface selecionada. Os métodos de objeto pipe permitem que um driver:
Obtendo informações de pipe UMDF-USB
Depois que um driver UMDF chama o método IWDFUsbInterface::RetrieveUsbPipeObject para obter um ponteiro para a interface IWDFUsbTargetPipe para um objeto de pipe USB, o driver pode chamar os seguintes métodos que o objeto de pipe USB define para obter informações sobre o pipe USB:
IWDFUsbTargetPipe::GetInformation
Recupera informações sobre um pipe USB e seu ponto de extremidade.
IWDFUsbTargetPipe::GetType
Retorna o tipo de um pipe USB.
IWDFUsbTargetPipe::IsInEndPoint
Determina se um pipe USB está conectado a um ponto de extremidade de entrada.
IWDFUsbTargetPipe::IsOutEndPoint
Determina se um pipe USB está conectado a um ponto de extremidade de saída.
IWDFUsbTargetPipe::RetrievePipePolicy
Recupera uma política de pipe winUsb.
Leitura de um pipe UMDF-USB
Para ler dados de um pipe de entrada USB, o driver pode usar (ou ambos) das seguintes técnicas:
Ler dados de forma síncrona.
Para ler dados de forma síncrona de um pipe de entrada USB, um driver UMDF primeiro chama o método IWDFIoTarget::FormatRequestForRead para criar uma solicitação de leitura. Em seguida, o driver chama o método IWDFIoRequest::Send , especificando o sinalizador WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, para enviar a solicitação de forma síncrona.
Ler dados de forma assíncrona.
Para ler dados de forma assíncrona de um pipe de entrada USB, um driver UMDF primeiro chama o método IWDFIoTarget::FormatRequestForRead para criar uma solicitação de leitura. Em seguida, o driver chama o método IWDFIoRequest::Send sem especificar o sinalizador WDF_REQUEST_SEND_OPTION_SYNCHRONOUS.
Leia dados de forma síncrona e contínua.
Um leitor contínuo é um mecanismo fornecido por estrutura que garante que uma solicitação de leitura esteja sempre disponível para um pipe USB. Esse mecanismo garante que o driver esteja sempre pronto para receber dados de um dispositivo que fornece um fluxo de entrada assíncrono e não solicitado. Por exemplo, um driver para uma NIC (cartão de interface de rede) pode usar um leitor contínuo para receber dados de entrada.
Para configurar um leitor contínuo para um pipe de entrada, a função de retorno de chamada IPnpCallbackHardware::OnPrepareHardware do driver deve chamar o método IWDFUsbTargetPipe2::ConfigureContinuousReader . Esse método enfileira um conjunto de solicitações de leitura para o destino de E/S do dispositivo.
Além disso, a função de retorno de chamada IPnpCallback::OnD0Entry do driver deve chamar IWDFIoTargetStateManagement::Start para iniciar o leitor contínuo e a função de retorno de chamada IPnpCallback::OnD0Exit do driver deve chamar IWDFIoTargetStateManagement::Stop para interromper o leitor contínuo.
Sempre que os dados estiverem disponíveis no dispositivo, O destino de E/S concluirá uma solicitação de leitura e a estrutura chamará uma das duas funções de retorno de chamada: IUsbTargetPipeContinuousReaderCallbackReadComplete::OnReaderCompletion se o destino de E/S ler os dados com êxito ou IUsbTargetPipeContinuousReaderCallbackReadersFailed::OnReaderFailure se o destino de E/S relatar um erro.
Depois que um driver tiver chamado IWDFUsbTargetPipe2::ConfigureContinuousReader, o driver não poderá usar IWDFIoRequest::Send para enviar solicitações de E/S para o pipe, a menos que a função de retorno de chamada IUsbTargetPipeContinuousReaderCallbackReadersFailed::OnReaderFailure do driver seja chamada e retorne FALSE.
Há suporte para leitores contínuos nas versões 1.9 e posteriores do UMDF.
Gravando em um pipe UMDF-USB
Para gravar dados em um pipe de saída USB, um driver UMDF pode primeiro chamar o método IWDFIoTarget::FormatRequestForWrite para criar uma solicitação de gravação. Em seguida, o driver pode chamar o método IWDFIoRequest::Send para enviar a solicitação de forma assíncrona.
Parando, liberando e redefinindo um pipe UMDF-USB
Um driver UMDF pode chamar os seguintes métodos para parar, liberar ou redefinir um pipe USB:
IWDFUsbTargetPipe::Abort
Envia uma solicitação de forma síncrona para interromper todas as transferências pendentes em um pipe USB.
IWDFUsbTargetPipe::Flush
Envia de forma síncrona uma solicitação para descartar todos os dados salvos pelo WinUsb quando o dispositivo retornou mais dados do que o cliente solicitado.
IWDFUsbTargetPipe::Reset
Envia de forma síncrona uma solicitação para redefinir um pipe USB.
Definindo a política para um pipe UMDF-USB
Um driver UMDF pode chamar o método IWDFUsbTargetPipe::SetPipePolicy para controlar o comportamento usado pelo WinUsb para um pipe USB (por exemplo, tempos limite, manipulação de pacotes curtos e outros comportamentos).
Tratamento de erros de pipe
Se o destino USB do driver concluir uma solicitação de E/S com um erro status valor, o driver deverá fazer o seguinte:
Chame IWDFIoTargetStateManagement::Stop com o sinalizador WdfIoTargetCancelSentIo definido. Essa chamada interrompe o pipe e cancela quaisquer solicitações de E/S adicionais que o driver enviou para o destino USB, se o destino não tiver concluído as solicitações.
Chame IWDFUsbTargetPipe::Abort para enviar uma solicitação de anulação para o pipe.
Chame IWDFUsbTargetPipe::Reset para enviar uma solicitação de redefinição para o pipe.
Chame IWDFIoTargetStateManagement::Start para reiniciar o pipe.
Reenviar a solicitação de E/S que falhou e todas as solicitações de E/S que seguiram a solicitação com falha.