Função WdfUsbTargetPipeReadSynchronously (wdfusb.h)
[Aplica-se a KMDF e UMDF]
O método WdfUsbTargetPipeReadSynchronously cria uma solicitação de leitura e a envia de forma síncrona para um pipe de entrada USB especificado.
Sintaxe
NTSTATUS WdfUsbTargetPipeReadSynchronously(
[in] WDFUSBPIPE Pipe,
[in, optional] WDFREQUEST Request,
[in, optional] PWDF_REQUEST_SEND_OPTIONS RequestOptions,
[in, optional] PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
[out, optional] PULONG BytesRead
);
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 receberá dados do dispositivo. 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.
[out, optional] BytesRead
Um ponteiro para um local que recebe o número de bytes que foram lidos, se a operação for bem-sucedida. Esse parâmetro é opcional e pode ser NULL.
Retornar valor
WdfUsbTargetPipeReadSynchronously 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 |
---|---|
|
O tamanho da estrutura de WDF_REQUEST_SEND_OPTIONS apontada por RequestOptions estava incorreto. |
|
Um parâmetro inválido foi detectado. |
|
Memória insuficiente disponível. |
|
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. |
|
O tamanho do buffer não era um múltiplo do tamanho máximo do pacote do pipe. |
|
O driver forneceu um valor de tempo limite e a solicitação não foi concluída dentro do tempo alocado. |
|
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 WdfUsbTargetPipeReadSynchronously para enviar solicitações de leitura de forma síncrona. Para enviar solicitações de leitura de forma assíncrona, use WdfUsbTargetPipeFormatRequestForRead, seguido por WdfRequestSend.
O pipe especificado pelo parâmetro Pipe deve ser um pipe de entrada e o tipo do pipe deve ser WdfUsbPipeTypeBulk ou WdfUsbPipeTypeInterrupt.
O método WdfUsbTargetPipeReadSynchronously 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 para a qual o parâmetro RequestOptions aponta 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:
- Especifique o identificador da solicitação recebida para o parâmetro Request .
-
Use o buffer de saída da solicitação recebida para o parâmetro MemoryDescriptor do método WdfUsbTargetPipeReadSynchronously.
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, em seguida, colocar esse identificador na estrutura WDF_MEMORY_DESCRIPTOR para a qual MemoryDescriptor aponta.
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:
-
Forneça um identificador de solicitação NULL no parâmetro Request do método WdfUsbTargetPipeReadSynchronously 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.
-
Forneça espaço de buffer para o parâmetro MemoryDescriptor do método WdfUsbTargetPipeReadSynchronously.
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 o WdfUsbTargetPipeReadSynchronously manipula solicitações de E/S de forma síncrona, o driver pode criar buffers de solicitaçã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 WdfRequestRetrieveOutputMemory para obter um identificador para um objeto de memória de estrutura que representa o buffer de saída 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 WdfUsbTargetPipeReadSynchronously envia para o destino de E/S tenha sido excluída, reutilizado ou reformatado. (WdfUsbTargetPipeReadSynchronously 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 WdfRequestRetrieveOutputWdmMdl.
-
Fornecer um buffer local
Um driver não poderá chamar WdfUsbTargetPipeReadSynchronously se tiver configurado um leitor contínuo para o pipe.
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 WdfUsbTargetPipeReadSynchronously 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 de estrutura, inicializa uma estrutura WDF_MEMORY_DESCRIPTOR e passa a estrutura para WdfUsbTargetPipeReadSynchronously. Este exemplo especifica NULL para o identificador de objeto de solicitação, portanto, a estrutura criará um novo objeto de solicitação para o destino de E/S.
WDFMEMORY wdfMemory;
WDF_MEMORY_DESCRIPTOR readBufDesc;
ULONG BytesRead;
status = WdfMemoryCreate(
WDF_NO_OBJECT_ATTRIBUTES,
NonPagedPool,
0,
readSize,
&wdfMemory,
NULL
);
if (!NT_SUCCESS(status)){
return ;
}
buffer = WdfMemoryGetBuffer(
wdfMemory,
NULL
);
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
&readBufDesc,
buffer,
readSize
);
status = WdfUsbTargetPipeReadSynchronously(
Pipe,
NULL,
NULL,
&readBufDesc,
&BytesRead
);
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), SyncReqSend(kmdf), UsbKmdfIrql(kmdf), UsbKmdfIrql2(kmdf), UsbKmdfIrqlExplicit(kmdf), WriteReqs(kmdf) |
Confira também
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de