Cancelación de solicitudes de E/S en UMDF
Advertencia
UMDF 2 es la versión más reciente de UMDF y sustituye a UMDF 1. Todos los controladores UMDF nuevos deben escribirse con UMDF 2. No se agregan nuevas características a UMDF 1 y hay compatibilidad limitada con UMDF 1 en versiones más recientes de Windows 10. Los controladores universales de Windows deben usar UMDF 2.
Los ejemplos de UMDF 1 archivados se pueden encontrar en la actualización de ejemplos de controladores de Windows 11, versión 22H2 - mayo de 2022.
Para obtener más información, consulta Introducción con UMDF.
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 HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED).
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 de trabajo se completa con un estado de finalización de HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED):las siguientes solicitudes de E/S 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 IWDFIoQueue::ConfigureRequestDispatching.
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 IRequestCallbackCancel::OnCancel .
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. Por ejemplo, el marco podría entregar una solicitud de E/S a uno de los controladores de solicitudes del controlador, y el controlador podría llamar posteriormente a IWDFIoRequest::ForwardToIoQueue para colocar la solicitud en una cola diferente o IWDFIoRequest2::Requeue para volver a colocar la solicitud en la misma cola.
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 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 del controlador, el controlador debe cancelar 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 para la cola de E/S.
Llamar a MarkCancelable
Un controlador puede llamar a IWDFIoRequest::MarkCancelable para registrar una función de devolución de llamada IRequestCallbackCancel::OnCancel . Si el controlador ha llamado a MarkCancelable 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 OnCancel del controlador para que el controlador pueda cancelar la solicitud de E/S.
Un controlador debe llamar a MarkCancelable si posee una solicitud durante un tiempo relativamente largo. Por ejemplo, es posible que un controlador tenga que esperar a que un dispositivo responda o que tenga que esperar a que los controladores inferiores completen un conjunto de solicitudes que el controlador creó cuando recibió una sola solicitud.
Si un controlador no llama a MarkCancelable o si un controlador llama a IWDFIoRequest::UnmarkCancelable después de llamar a MarkCancelable, el controlador no es consciente de la cancelación y, por lo tanto, controla la solicitud como lo haría normalmente.
Llamada a IsCanceled
Si un controlador no ha llamado a MarkCancelable para registrar una función de devolución de llamada onCancel , puede llamar a IWDFIoRequest2::IsCanceled para determinar si el Administrador de E/S ha intentado cancelar una solicitud de E/S. Si IsCanceled devuelve TRUE, el controlador debe cancelar la solicitud.
Por ejemplo, un controlador que recibe una solicitud de lectura o escritura grande que divide en varias solicitudes más pequeñas podría llamar a IsCanceled 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 MarkCancelable 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 IWDFIoRequest::CancelSentRequest 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 recibido del marco de trabajo, el controlador siempre debe completar la solicitud llamando a IWDFIoRequest::Complete o IWDFIoRequest::CompleteWithInformation, con un parámetro CompletionStatus de HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED). (Si el controlador llamó a IWDFDevice::CreateRequest para crear un objeto de solicitud, el controlador llama a IWDFObject::D eleteWdfObject en lugar de completar la solicitud).