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 |
---|---|
|
O tamanho da estrutura WDF_REQUEST_SEND_OPTIONS para a qual o parâmetro RequestOptions aponta 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 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 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:
- Especifique o identificador da solicitação recebida para o parâmetro Request .
-
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.
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 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.
-
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.
-
Fornecer um buffer local
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
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