Implementando uma rotina de cancelamento
O gerente de E/S chama uma rotina cancelar fornecida pelo driver com um IRP de entrada a ser cancelado e um ponteiro DeviceObject que representa o dispositivo de destino para a solicitação de E/S.
O IRP pode ser aquele que a rotina DispatchReadWrite do driver enfileirado assim como o aplicativo Win32 atual está sendo fechado pelo usuário. O IRP também pode ser aquele que um driver de nível superior cancelou explicitamente, dependendo da natureza do dispositivo subjacente.
Quando a rotina Cancelar é chamada, o IRP de entrada pode já ser o CurrentIrp no objeto de dispositivo de destino ou pode já estar na fila do dispositivo associada ao objeto de dispositivo de destino se o driver tiver uma rotina StartIo . Se o driver não tiver rotina StartIo , o IRP poderá estar em uma fila interna gerenciada pelo driver de IRPs quando sua rotina Cancelar for chamada. De qualquer forma, antes que o gerente de E/S chame a rotina Cancelar para o IRP de entrada, o gerente de E/S define o membro Cancel neste IRP como TRUE e define o membro CancelRoutine no IRP como NULL.
A rotina Cancelar para um IRP master associado é responsável por chamar IoCancelIrp para cancelar esses IRPs associados.
Todas as rotinas cancelar devem seguir estas diretrizes:
Chame IoReleaseCancelSpinLock para liberar o bloqueio de rotação de cancelamento do sistema.
Defina o membro Status do bloco de E/S status como STATUS_CANCELLED e defina seu membro De informações como zero.
Conclua o IRP especificado chamando IoCompleteRequest.
Como uma rotina Cancelar é sempre chamada com o bloqueio de rotação de cancelamento do sistema mantido, essa rotina não deve chamar IoAcquireCancelSpinLock , a menos que chame IoReleaseCancelSpinLock primeiro.
Uma rotina Cancelar não pode manter o bloqueio de rotação de cancelamento do sistema quando ele retorna o controle. Ou seja, cada rotina Cancelar deve chamar IoReleaseCancelSpinLock pelo menos uma vez antes de retornar o controle.
Se ele chamar IoAcquireCancelSpinLock, uma rotina Cancelar deverá fazer a chamada recíproca para IoReleaseCancelSpinLock o mais rápido possível.
Nunca chame IoCompleteRequest com um IRP enquanto mantém um bloqueio de rotação. Tentar concluir um IRP enquanto mantém um bloqueio de rotação pode causar deadlocks.