Função WdfIoTargetSendInternalIoctlSynchronously (wdfiotarget.h)

[Aplica-se somente ao KMDF]

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

Sintaxe

NTSTATUS WdfIoTargetSendInternalIoctlSynchronously(
  [in]            WDFIOTARGET               IoTarget,
  [in, optional]  WDFREQUEST                Request,
  [in]            ULONG                     IoctlCode,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    InputBuffer,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    OutputBuffer,
  [in, optional]  PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  [out, optional] PULONG_PTR                BytesReturned
);

Parâmetros

[in] IoTarget

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

[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] IoctlCode

Um IOCTL (código de controle de E/S) compatível com o destino de E/S.

[in, optional] InputBuffer

Um ponteiro para uma estrutura de WDF_MEMORY_DESCRIPTOR alocada pelo chamador que descreve um buffer que será gravado no destino de E/S. Para obter mais informações, consulte a seção Comentários a seguir. Esse parâmetro é opcional e pode ser NULL se a solicitação não enviar dados.

[in, optional] OutputBuffer

Um ponteiro para uma estrutura de WDF_MEMORY_DESCRIPTOR alocada pelo chamador que descreve um buffer que receberá dados do destino de E/S. Para obter mais informações, consulte a seção Comentários a seguir. Esse parâmetro é opcional e pode ser NULL se a solicitação não receber dados.

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

[out, optional] BytesReturned

Um ponteiro para um local que recebe informações (como o número de bytes que foram transferidos) que outro driver fornece quando conclui a solicitação chamando WdfRequestCompleteWithInformation. Esse ponteiro é opcional e pode ser NULL.

Valor retornado

Se a operação for bem-sucedida, WdfIoTargetSendInternalIoctlSynchronously retorna após a conclusão da solicitação de controle de dispositivo interno e o valor retornado é o valor de status de conclusão da solicitação. Caso contrário, esse método poderá 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 de WDF_REQUEST_SEND_OPTIONS que o parâmetro RequestOptions apontou estava incorreto.
STATUS_INVALID_DEVICE_REQUEST
A solicitação 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 De solicitação 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.

Ocorre uma verificação de bug se o driver fornece um identificador de objeto inválido.

Comentários

Use o método WdfIoTargetSendInternalIoctlSynchronously para enviar solicitações internas de controle de dispositivo de forma síncrona. Para enviar solicitações internas de controle de dispositivo de forma assíncrona, use o método WdfIoTargetFormatRequestForInternalIoctl , seguido pelo método WdfRequestSend .

Para obter mais informações sobre solicitações internas de controle de dispositivo, consulte Usando códigos de controle de E/S.

O método WdfIoTargetSendInternalIoctlSynchronously 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 de WDF_REQUEST_SEND_OPTIONS do parâmetro RequestOptions ou a menos que um erro seja detectado.

Você pode encaminhar uma solicitação de controle de dispositivo interno 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 controle de dispositivo interno que seu driver recebeu em uma fila de E/S:

  1. Especifique o identificador da solicitação recebida para o parâmetro Solicitação do método WdfIoTargetSendInternalIoctlSynchronously.
  2. Use o buffer de entrada da solicitação recebida para o parâmetro InputBuffer do método WdfIoTargetSendInternalIoctlSynchronously.

    O driver deve chamar WdfRequestRetrieveInputMemory para obter um identificador para o buffer de entrada da solicitação. Em seguida, o driver deve colocar esse identificador na estrutura WDF_MEMORY_DESCRIPTOR que o driver fornece para o parâmetro InputBuffer .

  3. Use o buffer de saída da solicitação recebida para o parâmetro OutputBuffer do método WdfIoTargetSendInternalIoctlSynchronously.

    O driver deve chamar WdfRequestRetrieveOutputMemory para obter um identificador para o buffer de saída da solicitação e, em seguida, deve colocar esse identificador na estrutura WDF_MEMORY_DESCRIPTOR que o driver fornece para o parâmetro OutputBuffer .

Para obter mais informações sobre como encaminhar uma solicitação de E/S, consulte Solicitações de E/S de Encaminhamento.

Os drivers geralmente dividem as solicitações de E/S recebidas em solicitações menores enviadas 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 Solicitação do método WdfIoTargetSendInternalIoctlSynchronously 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 habilita a função de retorno de chamada EvtDriverDeviceAdd do driver 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 RequestOptions não NULL, independentemente de o driver fornecer um parâmetro não NULL ou de solicitaçãoNULL. Você pode, por exemplo, usar o parâmetro RequestOptions para especificar um valor de tempo limite.

  2. Forneça espaço de buffer para os parâmetros InputBuffer e OutputBuffer do método WdfIoTargetSendInternalIoctlSynchronously, se a solicitação exigir.

    O driver pode especificar esse espaço de buffer como buffers alocados localmente, como identificador WDFMEMORY ou como MDLs (listas de descritores de memória). Você pode usar qualquer método mais conveniente.

    Se necessário, a estrutura converte as descrições do buffer para que elas estejam corretas para o tipo de transferência do IOCTL. Para obter mais informações sobre tipos de transferência IOCTL, consulte Definindo códigos de controle de E/S.

    As técnicas a seguir para especificar o espaço de buffer estão disponíveis:

    • Forneça buffers locais.

      Como wdfIoTargetSendInternalIoctlSynchronously lida com 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 identificadores WDFMEMORY.

      Chame WdfMemoryCreate ou WdfMemoryCreatePreallocated para obter um identificador para 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 WdfRequestRetrieveInputMemory ou WdfRequestRetrieveOutputMemory para obter um identificador para um objeto de memória de estrutura que representa um buffer de solicitação de E/S recebido, 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 wdfIoTargetSendInternalIoctlSynchronously envia para o destino de E/S tenha sido excluída, reutilizado ou reformatado. (WdfIoTargetSendInternalIoctlSynchronously incrementa a contagem de referência do objeto de memória. Excluir, reutilizar ou reformatar um objeto de solicitação decrementa a contagem de referência do objeto de memória.)

    • Forneça MDLs.

      Os drivers podem obter MDLs associadas a uma solicitação de E/S recebida chamando WdfRequestRetrieveInputWdmMdl e WdfRequestRetrieveOutputWdmMdl.

Para obter informações sobre como obter informações de status após a conclusão de uma solicitação de E/S, consulte Obter informações de conclusão.

Para obter mais informações sobre WdfIoTargetSendInternalIoctlSynchronously, consulte Envio de solicitações de E/S para destinos gerais de E/S.

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

Exemplos

O exemplo de código a seguir define um buffer local, inicializa uma estrutura WDF_MEMORY_DESCRIPTOR e chama WdfIoTargetSendInternalIoctlSynchronously. 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  outputDescriptor;
NTSTATUS  status;
MY_DRIVER_INFORMATION  driverInformation;

WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
                                  &outputDescriptor,
                                  (PVOID) &driverInformation,
                                  sizeof(MY_DRIVER_INFORMATION)
                                  );

status = WdfIoTargetSendInternalIoctlSynchronously(
                                                   hidTarget,
                                                   NULL,
                                                   IOCTL_INTERNAL_GET_MY_DRIVER_INFORMATION,
                                                   NULL,
                                                   &outputDescriptor,
                                                   NULL,
                                                   NULL
                                                   );

Requisitos

   
Plataforma de Destino Universal
Versão mínima do KMDF 1,0
Cabeçalho wdfiotarget.h (include Wdf.h)
Biblioteca Wdf01000.sys (consulte o Controle de Versão da Biblioteca da Estrutura).)
IRQL PASSIVE_LEVEL
Regras de conformidade DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), IoctlReqs(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), ReadReqs(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf), WriteReqs(kmdf)

Confira também

EvtDriverDeviceAdd

WDF_MEMORY_DESCRIPTOR

WDF_REQUEST_SEND_OPTIONS

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForInternalIoctl

WdfIoTargetSendIoctlSynchronously

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCancelSentRequest

WdfRequestCompleteWithInformation

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveInputWdmMdl

WdfRequestRetrieveOutputMemory

WdfRequestRetrieveOutputWdmMdl

WdfRequestReuse

WdfRequestSend