Partilhar via


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:

  1. Chame IoAcquireCancelSpinLock.

  2. 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.

  3. Chame IoSetCancelRoutine com um ponteiro NULL CancelRoutine para remover o IRP do estado cancelável.

  4. 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.