Función WdfRequestMarkCancelable (wdfrequest.h)

[Se aplica a KMDF y UMDF]

El método WdfRequestMarkCancelable permite la cancelación de una solicitud de E/S especificada.

Sintaxis

void WdfRequestMarkCancelable(
  [in] WDFREQUEST             Request,
  [in] PFN_WDF_REQUEST_CANCEL EvtRequestCancel
);

Parámetros

[in] Request

Identificador de un objeto de solicitud de marco.

[in] EvtRequestCancel

Puntero a una función de devolución de llamada EvtRequestCancel definida por el controlador, que el marco llama si cancela la solicitud de E/S.

Valor devuelto

None

Observaciones

Se produce una comprobación de errores si el controlador proporciona un identificador de objeto no válido.

Una vez que el controlador haya recibido una solicitud de E/S del marco, el controlador puede llamar a WdfRequestMarkCancelable o, a partir de la versión 1.9 de KMDF, WdfRequestMarkCancelableEx para que la solicitud se pueda cancelar.

Al llamar a WdfRequestMarkCancelable, el controlador debe especificar una función de devolución de llamada EvtRequestCancel . El marco llama a la función de devolución de llamada si el administrador de E/S u otro controlador está intentando cancelar la solicitud de E/S.

Elegir entre WdfRequestMarkCancelable y WdfRequestMarkCancelableEx

Si el controlador usa la sincronización automática del marco, el controlador puede llamar a WdfRequestMarkCancelable o WdfRequestMarkCancelableEx.

Si el controlador no usa la sincronización automática, debe llamar a WdfRequestMarkCancelableEx en lugar de WdfRequestMarkCancelable por los siguientes motivos:

  • Si la solicitud especificada ya se ha cancelado, WdfRequestMarkCancelable llama a la función de devolución de llamada EvtRequestCancel del controlador antes de devolverla. Si el controlador adquiere un bloqueo por subproceso antes de llamar a WdfRequestMarkCancelable e intenta adquirir el mismo bloqueo de número dentro de EvtRequestCancel, el mismo subproceso intenta adquirir el mismo interbloqueo dos veces, lo que provoca un interbloqueo.
  • Sin embargo, dado que WdfRequestMarkCancelableEx nunca llama a EvtRequestCancel, este escenario no se produce. Si la solicitud ya se ha cancelado, WdfRequestMarkCancelableEx devuelve STATUS_CANCELLED. Si el controlador adquiere un bloqueo por subproceso (que establece IRQL en DISPATCH_LEVEL) antes de llamar a WdfRequestMarkCancelableEx y libera el bloqueo de número (que establece irQL en PASSIVE_LEVEL) después de que WdfRequestMarkCancelableEx devuelva, no se llamará a la función de devolución de llamada EvtRequestCancelcel antes de que se libere el bloqueo por subproceso. Por lo tanto, no se produce un interbloqueo aunque la función de devolución de llamada EvtRequestCancel use el mismo interbloqueo.

Procesamiento de una solicitud después de habilitar la cancelación

Una vez que un controlador llama a WdfRequestMarkCancelable para habilitar la cancelación, la solicitud permanece cancelable mientras el controlador posee el objeto de solicitud, a menos que el controlador llame a WdfRequestUnmarkCancelable.

Si un controlador ha llamado a WdfRequestMarkCancelable y si la función de devolución de llamada EvtRequestCancel del controlador no se ha ejecutado y llamado A WdfRequestComplete, el controlador debe llamar a WdfRequestUnmarkCancelable antes de llamar a WdfRequestComplete fuera de la función de devolución de llamada EvtRequestCancel.

Si el controlador llama a WdfRequestForwardToIoQueue para reenviar la solicitud a otra cola, se aplican las reglas siguientes:

  • Las solicitudes de E/S no se pueden cancelar cuando el controlador los reenvía a otra cola.

    Por lo general, el controlador no debe llamar a WdfRequestMarkCancelable para habilitar la cancelación de la solicitud antes de llamar a WdfRequestForwardToIoQueue. Si el controlador realiza la solicitud cancelable, debe llamar a WdfRequestUnmarkCancelable para deshabilitar la cancelación antes de llamar a WdfRequestForwardToIoQueue.

  • Mientras la solicitud está en la segunda cola, el marco lo posee y puede cancelarlo sin notificar al controlador.

    Si el controlador requiere una notificación de cancelación (para que pueda desasignar los recursos que podría haber asignado antes de llamar a WdfRequestForwardToIoQueue), el controlador debe registrar una función de devolución de llamada EvtIoCanceledOnQueue y debe usar la memoria de contexto específica de la solicitud para almacenar información sobre los recursos de la solicitud.

  • Una vez que el marco ha puesto en cola la solicitud de la segunda cola y la ha entregado al controlador, el controlador puede llamar a WdfRequestMarkCancelable para habilitar la cancelación.
Para obtener más información sobre WdfRequestMarkCancelable, vea Cancelar solicitudes de E/S.

Ejemplos

En el ejemplo de código siguiente se muestran partes de dos funciones de devolución de llamada:

  • Una función de devolución de llamada EvtIoRead que realiza un trabajo específico de la solicitud (por ejemplo, la creación de subrecquests para enviar a un destino de E/S) y, a continuación, habilita la cancelación de la solicitud de E/S recibida.
  • Una función de devolución de llamada EvtRequestCancel que cancela una solicitud de E/S.
El controlador debe usar la sincronización automática del marco.
VOID
MyEvtIoRead(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  Length
    )
{
...
    // Perform request-specific work here
    // (such as creating subrequests 
    // to send to an I/O target). 
...
    WdfRequestMarkCancelable(
                             Request,
                             MyEvtRequestCancel
                             );
    }
...
}
VOID
MyEvtRequestCancel(
    IN WDFREQUEST  Request
    )
{
    // Remove request-specific work here, because
    // we don't want the work to be done if the
    // request was canceled.

    WdfRequestComplete(
                       Request,
                       STATUS_CANCELLED
                       );
}

Requisitos

Requisito Value
Plataforma de destino Universal
Versión mínima de KMDF 1.0
Versión mínima de UMDF 2.0
Encabezado wdfrequest.h (incluya Wdf.h)
Library Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <=DISPATCH_LEVEL
Reglas de cumplimiento de DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), EvtIoStopCancel(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MarkCancOnCancReqLocal(kmdf), ReqIsCancOnCancOnCancReq(kmdf), ReqMarkCancelableSend(kmdf), ReqNotCanceledLocal(kmdf), RequestCompleted(kmdf), RequestCompletedLocal( kmdf)

Consulte también

EvtRequestCancel

WdfRequestComplete

WdfRequestForwardToIoQueue

WdfRequestMarkCancelableEx

WdfRequestUnmarkCancelable