Função WdfIoTargetSendWriteSynchronously (wdfiotarget.h)

[Aplica-se a KMDF e UMDF]

O método WdfIoTargetSendWriteSynchronously cria uma solicitação de gravação e a envia de forma síncrona para um destino de E/S.

Sintaxe

NTSTATUS WdfIoTargetSendWriteSynchronously(
  [in]            WDFIOTARGET               IoTarget,
  [in, optional]  WDFREQUEST                Request,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    InputBuffer,
  [in, optional]  PLONGLONG                 DeviceOffset,
  [in, optional]  PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  [out, optional] PULONG_PTR                BytesWritten
);

Parâmetros

[in] IoTarget

Um identificador para um objeto de destino de E/S local ou remoto que foi obtido de uma chamada anterior para WdfDeviceGetIoTarget ou WdfIoTargetCreate ou de um método fornecido por um destino de E/S especializado.

[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 sobre esse parâmetro, consulte a seção Comentários a seguir.

[in, optional] InputBuffer

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. Esse parâmetro é opcional e pode ser NULL. Para obter mais informações sobre esse parâmetro, consulte a seção Comentários a seguir.

[in, optional] DeviceOffset

Um ponteiro para um local que especifica um deslocamento inicial para a transferência. O destino de E/S (ou seja, o driver inferior seguinte) define como usar esse valor. Por exemplo, os drivers na pilha de driver de um disco podem especificar um deslocamento desde o início do disco. O destino de E/S obtém essas informações no membro Parameters.Write.DeviceOffset da estrutura WDF_REQUEST_PARAMETERS da solicitação. Esse ponteiro é opcional. A maioria dos drivers define esse ponteiro como NULL.

[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 sobre esse parâmetro, 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 ponteiro é opcional e pode ser NULL.

Retornar valor

Se a operação for bem-sucedida, WdfIoTargetSendWriteSynchronously retornará após a conclusão da solicitação de E/S e o valor retornado será a conclusão da solicitação status valor. Caso contrário, esse método pode retornar um dos seguintes valores:

Código de retorno Descrição
STATUS_INVALID_PARAMETER
Um parâmetro inválido foi detectado.
STATUS_INFO_LENGTH_MISMATCH
O tamanho da estrutura WDF_REQUEST_SEND_OPTIONS que o parâmetro RequestOptions apontou estava incorreto.
STATUS_INVALID_DEVICE_REQUEST
A solicitação de E/S já estava na fila para um destino de E/S.
STATUS_INSUFFICIENT_RESOURCES
A estrutura não pôde alocar recursos do sistema (normalmente memória).
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 WdfIoTargetSendWriteSynchronously para enviar solicitações de gravação de forma síncrona. Para enviar solicitações de gravação de forma assíncrona, use o método WdfIoTargetFormatRequestForWrite , seguido pelo método WdfRequestSend .

WdfIoTargetSendWriteSynchronously 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 do método WdfIoTargetSendWriteSynchronously.
  2. Use o buffer de entrada da solicitação recebida para o parâmetro InputBuffer do método WdfIoTargetSendWriteSynchronously.

    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 que o driver fornece para o parâmetro InputBuffer .

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 WdfIoTargetSendWriteSynchronously 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 InputBuffer do método WdfIoTargetSendWriteSynchronously.

    O driver pode especificar esse espaço de buffer como um buffer alocado localmente, como um identificador WDFMEMORY ou como uma MDL (lista de descritores de memória). 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 para especificar o espaço em buffer estão disponíveis:

    • Forneça um buffer local.

      Como wdfIoTargetSendWriteSynchronously 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));
      
    • Forneça 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 WdfIoTargetSendWriteSynchronously envia para o destino de E/S tenha sido excluída, reutilizado ou reformatado. (WdfIoTargetSendWriteSynchronously 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.)

    • Forneça um MDL.

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

Alguns destinos de E/S aceitam solicitações de gravação que têm um buffer de comprimento zero. Para esses destinos de E/S, o driver pode especificar NULL para o parâmetro InputBuffer .

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 WdfIoTargetSendWriteSynchronously, consulte Enviando solicitações de E/S para destinos gerais de E/S.

Para obter mais informações sobre destinos de E/S, consulte Usando destinos de E/S.

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 WdfIoTargetSendWriteSynchronously. 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.

WDF_MEMORY_DESCRIPTOR  MemoryDescriptor;
WDFMEMORY  MemoryHandle = NULL;
ULONG_PTR  bytesWritten = NULL;

status = WdfMemoryCreate(
                         NULL,
                         NonPagedPool,
                         POOL_TAG,
                         MY_BUFFER_SIZE,
                         &MemoryHandle,
                         NULL
                         );
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(
                                  &MemoryDescriptor,
                                  MemoryHandle,
                                  NULL
                                  );
status = WdfIoTargetSendWriteSynchronously(
                                          ioTarget,
                                          NULL,
                                          &MemoryDescriptor,
                                          NULL,
                                          NULL,
                                          &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 wdfiotarget.h (inclua Wdf.h)
Biblioteca Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <=PASSIVE_LEVEL
Regras de conformidade da DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), InternalIoctlReqs(kmdf), IoctlReqs(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), ReadReqs(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf), SyncReqSend(kmdf)

Confira também

EvtDriverDeviceAdd

WDF_MEMORY_DESCRIPTOR

WDF_MEMORY_DESCRIPTOR_INIT_HANDLE

WDF_REQUEST_PARAMETERS

WDF_REQUEST_SEND_OPTIONS

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForWrite

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCancelSentRequest

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveInputWdmMdl

WdfRequestReuse

WdfRequestSend