Partilhar via


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.