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.
Valor de retorno
WdfUsbTargetPipeReadSynchronously retornará 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 poderá retornar um dos seguintes valores:
Código de retorno | Descrição |
---|---|
|
O tamanho da estrutura de WDF_REQUEST_SEND_OPTIONS apontado por RequestOptions estava incorreto. |
|
Um parâmetro inválido foi detectado. |
|
Memória insuficiente estava 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 pacote de solicitação de E/S ( |
Esse método também pode retornar outros valores NTSTATUS .
Uma verificação de bug ocorre se o driver fornece um identificador de objeto inválido.
Observações
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 de 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 à qual o RequestOptions parâmetro aponta ou a menos que um erro seja detectado.
Você pode encaminhar uma solicitação de E/S que seu driver recebeu 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:
- 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
do método WdfUsbTargetPipeReadSynchronously do método. O driver deve chamar WdfRequestRetrieveOutputMemory para obter um identificador para um objeto de memória da estrutura que representa o buffer de saída da solicitação e, em seguida, colocar esse identificador na estrutura de WDF_MEMORY_DESCRIPTOR que o MemoryDescriptor aponta.
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:
-
Forneça um identificador de solicitação NULL no parâmetro WdfUsbTargetPipeReadSynchronously parâmetro Request do método 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, você poderá reutilizar esses objetos de solicitação chamando WdfRequestReuse. Essa técnica permite que o do driver EvtDriverDeviceAdd função de retorno de chamada para 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
NULL não RequestOptions, independentemente de o driver fornecer uma NULL não ou um parâmetro de solicitação de NULL . Você pode, por exemplo, usar o parâmetro RequestOptions para especificar um valor de tempo limite. -
Forneça espaço em buffer para o
parâmetro do do métodoMemoryDescriptor. Seu 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 de do destino de E/S para acessar buffers de dados.
As seguintes técnicas estão disponíveis:
-
Fornecer um buffer local
Como 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 por 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 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
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 |
---|---|
da 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 | PASSIVE_LEVEL |
regras de conformidade de DDI |