Cancelando solicitações de E/S no UMDF
Aviso
O UMDF 2 é a versão mais recente do UMDF e substitui o UMDF 1. Todos os novos drivers UMDF devem ser gravados usando UMDF 2. Nenhum novo recurso está sendo adicionado ao UMDF 1 e há suporte limitado para UMDF 1 em versões mais recentes do Windows 10. Drivers universais do Windows devem usar UMDF 2.
Os exemplos umdf 1 arquivados podem ser encontrados no Windows 11, versão 22H2 – Atualização de exemplos de driver de maio de 2022.
Para obter mais informações, consulte Introdução com UMDF.
A operação de E/S em andamento de um dispositivo (como uma solicitação para ler vários blocos de um disco) pode ser cancelada por um aplicativo, pelo sistema ou por um driver. Se a operação de E/S de um dispositivo for cancelada, o Gerenciador de E/S tentará cancelar todas as solicitações de E/S não processadas associadas à operação de E/S. Os drivers do dispositivo podem se registrar para serem notificados quando o Gerenciador de E/S tenta cancelar solicitações de E/S, e os drivers podem cancelar as solicitações que possuem concluindo-as com uma status de conclusão de HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED).
A estrutura lida com alguns dos trabalhos de cancelamento para drivers baseados em estrutura. Se a operação de E/S de um dispositivo for cancelada, a estrutura será concluída com uma status de conclusão de HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED)-- as seguintes solicitações de E/S associadas à operação cancelada:
Solicitações de E/S não entregues que a estrutura colocou na fila de E/S padrão do driver.
Solicitações de E/S não entregues que a estrutura encaminhou para outra fila porque o driver chamado IWDFIoQueue::ConfigureRequestDispatching.
Como a estrutura cancela essas solicitações, ela não as entrega ao driver.
Depois que a estrutura tiver entregue uma solicitação de E/S ao driver, o driver será o proprietário da solicitação e a estrutura não poderá cancelá-la. Neste ponto, somente o driver pode cancelar a solicitação de E/S, mas a estrutura deve notificar o driver de que uma solicitação deve ser cancelada. Os drivers recebem essa notificação fornecendo uma função de retorno de chamada IRequestCallbackCancel::OnCancel .
Às vezes, um driver recebe uma solicitação de E/S de uma fila de E/S, mas, em vez de processar a solicitação, o driver enfileira a solicitação para a mesma fila ou outra fila de E/S para processamento posterior. Por exemplo, a estrutura pode fornecer uma solicitação de E/S para um dos manipuladores de solicitação do driver, e o driver pode, posteriormente, chamar IWDFIoRequest::ForwardToIoQueue para colocar a solicitação em uma fila diferente ou IWDFIoRequest2::Requeue para colocar a solicitação de volta na mesma fila.
Nesses casos, a estrutura pode cancelar a solicitação de E/S porque a solicitação está em uma fila de E/S. No entanto, se o driver tiver registrado uma função de retorno de chamada para a fila de E/S na qual a solicitação reside, a estrutura chamará a função de retorno de chamada, em vez de cancelar a solicitação, quando a operação de E/S associada estiver sendo cancelada. Se a estrutura chamar a função de retorno de chamada do driver, o driver deverá cancelar a solicitação.
Em resumo, quando uma operação de E/S é cancelada, a estrutura sempre cancela todas as solicitações de E/S associadas que nunca foram entregues ao driver. Se o driver receber uma solicitação e, em seguida, recoduzê-la, a estrutura cancelará a solicitação (se a solicitação estiver na fila), a menos que o driver forneça uma função de retorno de chamada para a fila de E/S.
Chamando MarkCancelable
Um driver pode chamar IWDFIoRequest::MarkCancelable para registrar uma função de retorno de chamada IRequestCallbackCancel::OnCancel . Se o driver tiver chamado MarkCancelable e se a operação de E/S associada à solicitação for cancelada, a estrutura chamará a função de retorno de chamada OnCancel do driver para que o driver possa cancelar a solicitação de E/S.
Um driver deve chamar MarkCancelable se ele tiver uma solicitação por um tempo relativamente longo. Por exemplo, um driver pode ter que aguardar a resposta de um dispositivo ou pode ter que esperar que drivers inferiores concluam um conjunto de solicitações que o driver criou quando recebeu uma única solicitação.
Se um driver não chamar MarkCancelable ou se um driver chamar IWDFIoRequest::UnmarkCancelable depois de chamar MarkCancelable, o driver não estará ciente do cancelamento e, portanto, manipulará a solicitação como normalmente faria.
Chamando IsCanceled
Se um driver não tiver chamado MarkCancelable para registrar uma função de retorno de chamada OnCancel , ele poderá chamar IWDFIoRequest2::IsCanceled para determinar se o Gerenciador de E/S tentou cancelar uma solicitação de E/S. Se IsCanceled retornar TRUE, o driver deverá cancelar a solicitação.
Por exemplo, um driver que recebe uma solicitação de leitura ou gravação grande que divide em várias solicitações menores pode chamar IsCanceled depois que o destino de E/S do driver concluir cada uma das solicitações menores, se o driver não tiver chamado MarkCancelable para a solicitação recebida.
Cancelando a solicitação
Cancelar uma solicitação de E/S pode envolver qualquer uma das seguintes opções:
Interrompendo uma operação de E/S em andamento.
Não encaminhar a solicitação para um destino de E/S.
Chamar IWDFIoRequest::CancelSentRequest para tentar cancelar uma solicitação que o driver havia enviado anteriormente a um destino de E/S.
Se um driver estiver cancelando uma solicitação de E/S para um objeto de solicitação que o driver recebeu da estrutura, o driver sempre deverá concluir a solicitação chamando IWDFIoRequest::Complete ou IWDFIoRequest::CompleteWithInformation, com um parâmetro CompletionStatus de HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED). (Se o driver chamado IWDFDevice::CreateRequest criar um objeto de solicitação, o driver chamará IWDFObject::D eleteWdfObject em vez de concluir a solicitação.)