Cancelación de solicitudes de E/S
Una aplicación, el sistema o un controlador pueden cancelar la operación de E/S en curso de un dispositivo (por ejemplo, una solicitud para leer varios bloques de un disco). Si se cancela la operación de E/S de un dispositivo, el administrador de E/S intenta cancelar todas las solicitudes de E/S sin procesar asociadas a la operación de E/S. Los controladores del dispositivo pueden registrarse para recibir notificaciones cuando el administrador de E/S intenta cancelar las solicitudes de E/S y los controladores pueden cancelar las solicitudes que poseen completando con un estado de finalización de STATUS_CANCELLED.
El marco controla parte del trabajo de cancelación de los controladores basados en el marco. Si se cancela la operación de E/S de un dispositivo, el marco completa las siguientes solicitudes de E/S (con un estado de finalización de STATUS_CANCELLED) que están asociadas a la operación cancelada:
Solicitudes de E/S no entregados que el marco ha colocado en la cola de E/S predeterminada del controlador.
Solicitudes de E/S no entregados que el marco ha reenviado a otra cola porque el controlador llamado WdfDeviceConfigureRequestDispatching.
Dado que el marco cancela estas solicitudes, no las entrega al controlador.
Una vez que el marco haya entregado una solicitud de E/S al controlador, el controlador posee la solicitud y el marco no puede cancelarla. En este momento, solo el controlador puede cancelar la solicitud de E/S, pero el marco debe notificar al controlador que se debe cancelar una solicitud. Los controladores reciben esta notificación proporcionando una función de devolución de llamada EvtRequestCancel .
A veces, un controlador recibe una solicitud de E/S de una cola de E/S, pero, en lugar de procesar la solicitud, el controlador vuelve a poner en cola la solicitud a la misma u otra cola de E/S para su posterior procesamiento. Entre los ejemplos de esta situación se incluyen los siguientes:
El marco entrega una solicitud de E/S a uno de los controladores de solicitudes del controlador y el controlador llama posteriormente a WdfRequestForwardToIoQueue (o WdfRequestForwardToParentDeviceIoQueue) para colocar la solicitud en una cola diferente o WdfRequestRequeue para volver a colocar la solicitud en la misma cola.
El marco entrega una solicitud de E/S a la función de devolución de llamada EvtIoInCallerContext del controlador, el controlador llama a WdfDeviceEnqueueRequest para volver a pasar la solicitud al marco y el marco coloca posteriormente la solicitud en una de las colas de E/S del controlador.
En estos casos, el marco puede cancelar la solicitud de E/S porque la solicitud está en una cola de E/S. Sin embargo, si el controlador ha registrado una función de devolución de llamada EvtIoCanceledOnQueue para la cola de E/S en la que reside la solicitud, el marco llama a la función de devolución de llamada, en lugar de cancelar la solicitud, cuando se cancela la operación de E/S asociada. Si el marco llama a la función de devolución de llamada EvtIoCanceledOnQueue del controlador, el controlador debe completar la solicitud.
En resumen, cuando se cancela una operación de E/S, el marco siempre cancela todas las solicitudes de E/S asociadas que nunca se entregaron al controlador. Si el controlador recibe una solicitud y, a continuación, la vuelve a poner en cola, el marco cancelará la solicitud (si la solicitud está en la cola) a menos que el controlador proporcione una función de devolución de llamada EvtIoCanceledOnQueue para la cola de E/S.
Llamar a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx
Un controlador puede llamar a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx para registrar una función de devolución de llamada EvtRequestCancel . Si el controlador ha llamado a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx y, si se cancela la operación de E/S asociada a la solicitud, el marco llama a la función de devolución de llamada EvtRequestCancel del controlador para que el controlador pueda cancelar la solicitud de E/S.
Un controlador debe llamar a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx si poseerá una solicitud durante un tiempo relativamente largo. Por ejemplo, un controlador puede tener que esperar a que un dispositivo responda o puede esperar a que los controladores inferiores completen un conjunto de solicitudes que el controlador creó cuando recibió una única solicitud.
Si un controlador no llama a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx, o si un controlador llama a WdfRequestUnmarkCancelable después de llamar a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx, el controlador no es consciente de la cancelación y, por lo tanto, controla la solicitud como lo haría normalmente.
Llamar a WdfRequestIsCanceled
Si un controlador no ha llamado a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx para registrar una función de devolución de llamada EvtRequestCancel, puede llamar a WdfRequestIsCanceled para determinar si el administrador de E/S ha intentado cancelar una solicitud de E/S. Si WdfRequestIsCanceled devuelve TRUE y el controlador posee la solicitud, el controlador debe cancelar la solicitud. Si el controlador no posee la solicitud, no debe llamar a WdfRequestIsCanceled.
Un controlador que no ha llamado a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx podría llamar a WdfRequestIsCanceled en las siguientes circunstancias:
Un controlador que espera interrupciones del dispositivo podría llamar a WdfRequestIsCanceled desde su función de devolución de llamada EvtInterruptDpc .
Un controlador que sondea su dispositivo podría llamar a WdfRequestIsCanceled desde el subproceso de sondeo.
Un controlador que divide una transacción DMA en varias transferencias más pequeñas podría llamar a WdfRequestIsCanceled una vez finalizada cada transferencia.
Un controlador que recibe una solicitud de lectura o escritura grande que divide en varias solicitudes más pequeñas podría llamar a WdfRequestIsCanceled después de que el destino de E/S del controlador complete cada una de las solicitudes más pequeñas, si el controlador no ha llamado a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx para la solicitud recibida.
Cancelación de la solicitud
La cancelación de una solicitud de E/S puede implicar cualquiera de las siguientes acciones:
Detener una operación de E/S en curso.
No reenviar la solicitud a un destino de E/S.
Llamar a WdfRequestCancelSentRequest para intentar cancelar una solicitud que el controlador había enviado previamente a un destino de E/S.
Si un controlador cancela una solicitud de E/S para un objeto de solicitud que el controlador recibió del marco de trabajo, el controlador siempre debe completar la solicitud llamando a WdfRequestComplete, WdfRequestCompleteWithInformation o WdfRequestCompleteWithPriorityBoost, con un parámetro Status de STATUS_CANCELLED. (Si el controlador llamado WdfRequestCreate para crear un objeto de solicitud, el controlador llama a WdfObjectDelete en lugar de completar la solicitud).
Sincronización de la cancelación
Para obtener información sobre la sincronización de código que cancela las solicitudes de E/S, consulte: