Enviando solicitações de E/S de forma síncrona

A tabela a seguir lista os métodos de objeto de destino de E/S que o driver pode chamar para enviar solicitações de E/S de forma síncrona para um destino de E/S. Para obter informações detalhadas sobre como usar esses métodos, consulte as páginas de referência dos métodos.

Método Finalidade

WdfIoTargetSendReadSynchronously

Envia uma solicitação de leitura

WdfIoTargetSendWriteSynchronously

Envia uma solicitação de gravação

WdfIoTargetSendIoctlSynchronously

Envia uma solicitação de controle de dispositivo

WdfIoTargetSendInternalIoctlSynchronously

Envia uma solicitação de controle de dispositivo interno

WdfIoTargetSendInternalIoctlOthersSynchronously

Envia uma solicitação de controle de dispositivo interno não padrão

Você também pode enviar solicitações de forma síncrona chamando WdfRequestSend, mas você precisa formatar a solicitação primeiro seguindo as regras descritas em Enviar solicitações de E/S de forma assíncrona.

Enviar solicitações de E/S para um destino de E/S de forma síncrona é mais simples de programar do que enviar solicitações de E/S de forma assíncrona. No entanto, você deve usar as seguintes diretrizes para ajudá-lo a decidir se a E/S síncrona é apropriada para o driver:

  • Você poderá usar E/S síncrona se o driver não enviar muitas solicitações de E/S e se o desempenho do sistema ou do dispositivo não for reduzido porque o driver aguarda a conclusão de cada solicitação de E/S.

  • Se o driver precisar lidar com muitas solicitações de E/S em curtos períodos de tempo, você provavelmente não poderá permitir que o driver aguarde a conclusão de cada solicitação antes de enviar a próxima solicitação. Caso contrário, o driver poderá perder dados ou reduzir o desempenho de seu dispositivo (e, possivelmente, de todo o sistema). Nesses casos, e/S assíncrona pode ser a melhor opção.

  • E/S síncrona é útil para lidar com operações que devem ser iniciadas e concluídas sem atividades simultâneas adicionais. Essas operações podem incluir a redefinição de um pipe USB ou a leitura de registros de dispositivo.

  • Na maioria das vezes, o driver deve especificar um valor de tempo limite quando chama um método de objeto que envia uma solicitação de E/S de forma síncrona. Se o driver não especificar um valor de tempo limite e se um dispositivo ou um driver de nível inferior não responder, o driver poderá parar. Como resultado, o usuário pode experimentar um aplicativo sem resposta. Além disso, outros drivers podem não conseguir obter recursos do sistema, como itens de trabalho, se o driver não os estiver liberando.

  • Se os drivers acima e abaixo do seu na pilha exigirem operações para continuar de forma síncrona, seu driver deverá usar E/S síncrona. Portanto, você deve aprender sobre os requisitos de outros drivers que podem existir na pilha de driver.

O exemplo a seguir mostra como enviar uma solicitação IOCTL (controle de E/S síncrona):

NTSTATUS                status;
    WDF_MEMORY_DESCRIPTOR   inputDesc, outputDesc;
    PWDF_MEMORY_DESCRIPTOR  pInputDesc = NULL, pOutputDesc = NULL;
    ULONG_PTR               bytesReturned;

    UNREFERENCED_PARAMETER(FileObject);

    if (InputBuffer) {
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputDesc,
                                    InputBuffer,
                                    InputBufferLength);
        pInputDesc = &inputDesc;
    }

    if (OutputBuffer) {
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDesc,
                                    OutputBuffer,
                                    OutputBufferLength);
        pOutputDesc = &outputDesc;
    }

    status = WdfIoTargetSendIoctlSynchronously(
                        IoTarget,
                        WDF_NO_HANDLE, // Request
                        IoctlControlCode,
                        pInputDesc,
                        pOutputDesc,
                        NULL, // PWDF_REQUEST_SEND_OPTIONS
                        &bytesReturned);
    if (!NT_SUCCESS(status)) {
         DEBUGP(MP_ERROR,
        ("WdfIoTargetSendIoctlSynchronously failed 0x%x\n",
          status));
    }

    *BytesReadOrWritten = (ULONG)bytesReturned;