Concluindo solicitações de E/S

Cada driver baseado em estrutura eventualmente deve concluir cada solicitação de E/S que recebe da estrutura. Os drivers concluem solicitações chamando o método WdfRequestComplete, WdfRequestCompleteWithInformation ou WdfRequestCompleteWithPriorityBoost do objeto de solicitação.

Quando concluir uma solicitação

Um driver deve concluir uma solicitação quando determina que um dos seguintes casos é verdadeiro:

  • A operação de E/S solicitada foi concluída com êxito.

  • A operação de E/S solicitada foi iniciada, mas falhou antes de ser concluída.

  • A operação de E/S solicitada não tem suporte ou não era válida no momento em que foi recebida e não pôde ser iniciada.

  • A operação de E/S solicitada foi cancelada.

Se o driver atender à solicitação de E/S criando a atividade de E/S no dispositivo, o driver normalmente chamará WdfRequestComplete de sua função de retorno de chamada EvtInterruptDpc ou EvtDpcFunc .

Se o driver receber uma solicitação inválida ou sem suporte, ele normalmente chamará WdfRequestComplete do manipulador de solicitação que recebeu a solicitação.

Se a operação de E/S tiver sido cancelada, o driver normalmente chamará WdfRequestComplete de sua função de retorno de chamada EvtRequestCancel .

Se o driver encaminhar a solicitação de E/S para um destino de E /S, o driver concluirá a solicitação depois que o destino de E/S concluir a solicitação, da seguinte forma:

  • Se o driver encaminhar a solicitação de E/S de forma síncrona para o destino de E/S, a chamada do driver para o destino de E/S retornará somente depois que um driver de nível inferior tiver concluído a solicitação (a menos que ocorra um erro). Depois que o destino de E/S retornar, o driver deverá chamar WdfRequestComplete.

  • Se o driver encaminhar a solicitação de E/S de forma assíncrona, você deseja que o driver seja notificado quando um driver de nível inferior concluir a solicitação. Se o driver registrar uma função de retorno de chamada CompletionRoutine , a estrutura chamará essa função de retorno de chamada depois que o destino de E/S concluir a solicitação. A função de retorno de chamada CompletionRoutine normalmente chama WdfRequestComplete.

Para registrar uma função de retorno de chamada CompletionRoutine , o driver deve chamar WdfRequestSetCompletionRoutine antes de encaminhar a solicitação de E/S para um destino de E/S.

Se o driver não precisar ser notificado quando um destino de E/S concluir uma solicitação de E/S encaminhada de forma assíncrona, o driver não precisará registrar uma função de retorno de chamada CompletionRoutine . Em vez disso, o driver pode definir o sinalizador WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET ao chamar WdfRequestSend. Nesse caso, o driver não chama WdfRequestComplete.

Um driver não conclui uma solicitação de E/S criada chamando WdfRequestCreate ou WdfRequestCreateFromIrp. Em vez disso, o driver deve chamar WdfObjectDelete para excluir o objeto de solicitação, normalmente depois que um destino de E/S concluir a solicitação.

Por exemplo, um driver pode receber uma solicitação de leitura ou gravação para uma quantidade de dados maior do que os destinos de E/S do driver podem lidar ao mesmo tempo. O driver deve dividir os dados em várias solicitações menores e enviar essas solicitações menores para um ou mais destinos de E/S. As técnicas para lidar com essa situação incluem:

  • Chamar WdfRequestCreate para criar um único objeto de solicitação adicional que representa uma solicitação menor.

    O driver pode enviar essa solicitação de forma síncrona para um destino de E/S. A função de retorno de chamada CompletionRoutine da solicitação menor pode chamar WdfRequestReuse para que o driver possa reutilizar a solicitação e enviá-la para o destino de E/S novamente. Depois que o destino de E/S concluir a última das solicitações menores, a função de retorno de chamada CompletionRoutine poderá chamar WdfObjectDelete para excluir o objeto de solicitação criado pelo driver e o driver poderá chamar WdfRequestComplete para concluir a solicitação original.

  • Chamar WdfRequestCreate para criar vários objetos de solicitação adicionais que representam as solicitações menores.

    Os destinos de E/S do driver podem processar essas várias solicitações menores de forma assíncrona. O driver pode registrar uma função de retorno de chamada CompletionRoutine para cada uma das solicitações menores. Sempre que a função de retorno de chamada CompletionRoutine é chamada, ela pode chamar WdfObjectDelete para excluir um objeto de solicitação criado pelo driver. Depois que o destino de E/S concluir todas as solicitações menores, o driver poderá chamar WdfRequestComplete para concluir a solicitação original.

Fornecendo informações de conclusão

Quando um driver conclui uma solicitação, ele pode, opcionalmente, fornecer algumas informações adicionais que outros drivers podem acessar. Por exemplo, um driver pode fornecer o número de bytes que foram transferidos para uma solicitação de leitura ou gravação. Para fornecer essas informações, o driver pode fazer o seguinte:

Obtendo informações de conclusão

Para obter informações sobre uma solicitação de E/S que outro driver concluiu, um driver pode:

Se um driver enviar uma solicitação de E/S de forma síncrona, ele normalmente chamará WdfRequestGetStatus, WdfRequestGetCompletionParams e WdfRequestGetInformation após o retorno da chamada síncrona. Se um driver envia uma solicitação de E/S de forma assíncrona, ele normalmente chama esses métodos de dentro de uma função de retorno de chamada CompletionRoutine .

Para obter mais informações sobre como concluir solicitações de E/S, consulte Synchronizing Cancel and Completion Code.