Sincronizar o cancelamento em rotinas de driver que processam IRPs
Qualquer rotina de driver que seja removida da fila ou chamada com um IRP mantido em um estado cancelável, incluindo a rotina StartIo de um driver, deve fazer o seguinte:
Chame IoAcquireCancelSpinLock.
Verifique se Irp é igual a DeviceObject-CurrentIrp>. Caso contrário, chame IoReleaseCancelSpinLock e retorne o controle.
Se os dois não forem os mesmos, o CurrentIrp pode ter sido cancelado entre o momento em que IoStartPacket liberou o bloqueio de rotação de cancelamento e essa rotina o adquiriu.
Chame IoSetCancelRoutine com um ponteiro NULL CancelRoutine para remover o IRP do estado cancelável.
Verifique o campo Irp-Cancel> para determinar se o IRP deve ser cancelado ou se deve começar a processar a solicitação de E/S.
Se Irp-Cancel> estiver definido como TRUE, faça o seguinte:
Chame IoReleaseCancelSpinLock.
Defina Irp-IoStatus.Status> como STATUS_CANCELLED.
Defina Irp-IoStatus.Information> como 0.
Chame IoStartNextPacket (em uma rotina StartIo ) para iniciar o próximo pacote.
Chame IoCompleteRequest com um aumento de prioridade de IO_NO_INCREMENT para concluir o IRP.
Se Irp-Cancel> estiver definido como FALSE, chame IoReleaseCancelSpinLock e inicie o processamento solicitado da solicitação de E/S ou passe o IRP para o próximo driver inferior, conforme apropriado.
Os drivers que gerenciam suas próprias filas de IRPs, em vez de usar a fila de dispositivos fornecida pelo gerenciador de E/S, não precisam adquirir o bloqueio de rotação de cancelamento ao chamar IoSetCancelRoutine. No entanto, esses drivers devem verificar o ponteiro da rotina Cancelar que IoSetCancelRoutine retorna para determinar se a rotina de cancelamento já foi iniciada.
Em qualquer driver que lida com IRPs canceláveis, cada rotina de driver que processa um IRP antes que o dispositivo subjacente tenha sido programado para a operação de E/S solicitada deve verificar o estado cancelável de todos os IRPs de entrada. Especificamente, um driver de dispositivo de nível mais alto com rotinas StartIo e ControllerControl deve processar IRPs de entrada em ambas as rotinas de driver, conforme já descrito.