Concluindo solicitações de E/S
Cada driver baseado em estrutura deve, eventualmente, concluir todas as solicitações de E/S recebidas da estrutura. Os drivers completam 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 determinar 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 atende à solicitação de E/S criando atividade de E/S no dispositivo, o driver normalmente chama WdfRequestComplete de sua função de retorno de chamada EvtInterruptDpc ou EvtDpcFunc .
Se o driver receber uma solicitação inválida ou inválida, ele normalmente chamará WdfRequestComplete do manipulador de solicitação que recebeu a solicitação.
Se a operação de E/S foi cancelada, o driver normalmente chama 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 maneira:
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ê desejará que seu 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 tiver concluído 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 pode chamar WdfObjectDelete para excluir o objeto de solicitação criado pelo driver e o driver pode 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 um dos seguintes procedimentos:
Chame WdfRequestSetInformation antes de chamar WdfRequestComplete.
Obtendo informações de conclusão
Para obter informações sobre uma solicitação de E/S que outro driver concluiu, um driver pode:
Chame WdfRequestGetStatus para obter o valor de status de conclusão especificado pelo driver de nível inferior quando ele chamou WdfRequestComplete.
Chame WdfRequestGetCompletionParams para obter uma estrutura WDF_REQUEST_COMPLETION_PARAMS que contenha informações adicionais sobre a solicitação concluída, como identificadores para objetos de memória que representam os buffers da solicitação ou informações específicas do barramento.
Um driver pode chamar WdfRequestGetCompletionParams somente depois de chamar WdfRequestSend para enviar a solicitação de E/S de forma síncrona ou assíncrona para um destino de E/S. O driver não deve chamar WdfRequestGetCompletionParams depois de chamar um dos métodos que enviam solicitações de E/S para destinos de E/S apenas de forma síncrona (como WdfIoTargetSendReadSynchronously).
Chame WdfRequestGetInformation para obter informações adicionais de conclusão de E/S especificadas pelo driver de nível inferior quando ele chamou WdfRequestSetInformation ou WdfRequestCompleteWithInformation, se os drivers na pilha de driver fornecerem essas informações.
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 enviar uma solicitação de E/S de forma assíncrona, ele normalmente chamará 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 Sincronizando o código de cancelamento e de conclusão.