Compartir a través de


Implementación de una rutina de cancelación

El administrador de E/S llama a una rutina Cancel proporcionada por el controlador con un IRP de entrada que se va a cancelar y un puntero DeviceObject que representa el dispositivo de destino para la solicitud de E/S.

IRP podría ser uno que la rutina DispatchReadWrite del controlador haya puesto en cola al igual que el usuario cierra la aplicación Win32 actual. IRP también podría ser uno que un controlador de nivel superior canceló explícitamente, en función de la naturaleza del dispositivo subyacente.

Cuando se llama a la rutina Cancel , es posible que el IRP de entrada ya sea CurrentIrp en el objeto de dispositivo de destino o que ya esté en la cola de dispositivos asociada al objeto de dispositivo de destino si el controlador tiene una rutina StartIo . Si el controlador no tiene ninguna rutina StartIo , el IRP podría estar en una cola interna administrada por el controlador de IRP cuando se llama a su rutina Cancel . En cualquier caso, antes de que el administrador de E/S llame a la rutina Cancel para el IRP entrante, el administrador de E/S establece el miembro Cancel en TRUE y establece el miembro CancelRoutine en NULL.

La rutina Cancel para un IRP maestro que tiene IRP asociados es responsable de llamar a IoCancelIrp para cancelar esos IRP asociados.

Todas las rutinas Cancel deben seguir estas directrices:

  • Llame a IoReleaseCancelSpinLock para liberar el bloqueo de número de cancelación del sistema.

  • Establezca el miembro Status del bloque de estado de E/S en STATUS_CANCELLED y establezca su miembro Information en cero.

  • Complete el IRP especificado llamando a IoCompleteRequest.

  • Dado que siempre se llama a una rutina Cancel con el bloqueo de número de cancelación del sistema, esta rutina no debe llamar a IoAcquireCancelSpinLock a menos que llame primero a IoReleaseCancelSpinLock .

  • Una rutina Cancelar no puede contener el bloqueo de número de cancelación del sistema cuando devuelve el control. Es decir, cada rutina Cancel debe llamar a IoReleaseCancelSpinLock al menos una vez antes de que devuelva el control.

  • Si llama a IoAcquireCancelSpinLock, una rutina Cancel debe realizar la llamada recíproca a IoReleaseCancelSpinLock lo antes posible.

  • Nunca llame a IoCompleteRequest con un IRP mientras mantiene un bloqueo de número. Si se intenta completar un IRP mientras se mantiene presionado un bloqueo de número, se pueden producir interbloqueos.