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 a 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 precisará Formatar a solicitação primeiro seguindo as regras descritas em enviando solicitações de e/s de forma assíncrona.

Enviar solicitações de e/s para um destino de e/s é 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 seu driver:

  • Você pode usar e/s síncrona se o driver não enviar 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 pode perder dados ou reduzir o desempenho de seu dispositivo (e, possivelmente, o sistema inteiro). Nesses casos, a e/s assíncrona pode ser a melhor opção.

  • A e/s síncrona é útil para lidar com operações que devem iniciar e concluir sem atividade simultânea adicional. 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 ao chamar 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 ser capazes de obter recursos do sistema, como itens de trabalho, se o driver não o estiver liberando.

  • Se os drivers acima e abaixo da sua na pilha exigirem que as operações continuem de forma síncrona, o driver deverá usar e/s síncrona. Portanto, você deve aprender sobre os requisitos de outros drivers que podem existir na pilha de drivers.

O exemplo a seguir mostra como enviar uma solicitação de 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;