EVT_WDF_OBJECT_CONTEXT_CLEANUP función de devolución de llamada (wdfobject.h)

[Se aplica a KMDF y UMDF]

La función de devolución de llamada de eventos EvtCleanupCallback de un controlador quita las referencias del controlador en un objeto para que se pueda eliminar el objeto.

Sintaxis

EVT_WDF_OBJECT_CONTEXT_CLEANUP EvtWdfObjectContextCleanup;

void EvtWdfObjectContextCleanup(
  [in] WDFOBJECT Object
)
{...}

Parámetros

[in] Object

Identificador de un objeto de marco.

Valor devuelto

None

Observaciones

El controlador puede especificar una función de devolución de llamada EvtCleanupCallback en una estructura de WDF_OBJECT_ATTRIBUTES . Esta estructura se usa como entrada para todos los métodos de marco que crean objetos de marco, como WdfDeviceCreate.

El marco llama a la función de devolución de llamada cuando el marco o un controlador intentan eliminar el objeto.

Si el controlador ha llamado a WdfObjectReference para aumentar el recuento de referencias de un objeto, el controlador debe proporcionar una función de devolución de llamada EvtCleanupCallback que llama a WdfObjectDereference. Esta llamada garantiza que el recuento de referencias del objeto se reduce a cero y, como resultado, el marco puede llamar a la función de devolución de llamada EvtDestroyCallback del controlador y, a continuación, eliminar el objeto.

Si un controlador proporciona una función de devolución de llamada EvtCleanupCallback y una función de devolución de llamada EvtDestroyCallback para un objeto, el marco llama primero a la función de devolución de llamada EvtCleanupCallback .

Una vez que el marco llama a la función de devolución de llamada EvtCleanupCallback de un objeto, el controlador solo puede acceder al objeto desde su función de devolución de llamada EvtDestroyCallback . Sin embargo, un controlador no debe intentar llamar a métodos en un objeto desde su EvtDestroyCallback.

Cuando un controlador crea un objeto, a veces asigna búferes de memoria específicos del objeto y almacena los punteros de búfer en el espacio de contexto del objeto. La función de devolución de llamada EvtCleanupCallback o EvtDestroyCallback del controlador puede desasignar estos búferes de memoria.

Normalmente, si el controlador no llama a WdfObjectReference para un objeto, la función de devolución de llamada EvtCleanupCallback del objeto puede desasignar las asignaciones de contexto de objeto. En este caso, el controlador no necesita una función de devolución de llamada EvtDestroyCallback para el objeto .

Cuando se elimina un objeto, el marco también elimina los elementos secundarios del objeto. Con una excepción, el marco llama a las rutinas EvtCleanupCallback de los objetos secundarios antes de llamar a los de sus objetos primarios, por lo que se garantiza que los controladores siguen existiendo el objeto primario cuando se ejecuta la rutina EvtCleanupCallback de un elemento secundario.

La excepción a esta ordenación garantizada se aplica a las solicitudes de E/S que el controlador se completa en DISPATCH_LEVEL. Si este tipo de objeto de solicitud de E/S tiene uno o varios elementos secundarios cuyas rutinas EvtCleanupCallback deben llamarse en PASSIVE_LEVEL, es posible que la solicitud primaria se elimine antes de uno o varios de sus elementos secundarios. Un objeto requiere limpieza en PASSIVE_LEVEL si debe esperar a que se complete algo o si tiene acceso a la memoria paginada.

Si el controlador intenta eliminar este objeto (o el elemento primario de este objeto) mientras se ejecuta en DISPATCH_LEVEL, el marco pone en cola evtCleanupCallback en un elemento de trabajo para su procesamiento posterior en PASSIVE_LEVEL y, a continuación, llama a la devolución de llamada de limpieza del objeto primario sin determinar si se han ejecutado las devoluciones de llamada para los elementos secundarios.

Para evitar cualquier problema que pueda resultar de este comportamiento, los controladores no deben establecer el objeto de solicitud como elemento primario para cualquier objeto que requiera limpieza en PASSIVE_LEVEL. De forma predeterminada, el elemento primario para la mayoría de los objetos es WDFDEVICE, por lo que los controladores solo deben aceptar el valor predeterminado. Por lo general, si el objeto WDFDEVICE se pasa como parámetro (ya sea directamente o como parte de una estructura) al método que crea el objeto , WDFDEVICE es el elemento primario predeterminado. Para obtener una lista completa de los elementos primarios predeterminados, vea Resumen de objetos de marco.

Si no se aplica la excepción anterior, el marco llama a las funciones de devolución de llamada EvtCleanupCallback del objeto secundario antes de llamar a la función de devolución de llamada EvtCleanupCallback del objeto primario. A continuación, si el recuento de referencias del elemento secundario es cero, el marco llama a la función de devolución de llamada EvtDestroyCallback del objeto secundario. Por último, si el recuento de referencias del elemento primario es cero, el marco llama a la función de devolución de llamada EvtDestroyCallback del objeto primario.

Para obtener más información sobre cómo eliminar objetos de marco, vea Ciclo de vida de objetos de marco.

Normalmente, el marco llama a la función de devolución de llamada EvtCleanupCallback en IRQL <= DISPATCH_LEVEL. Sin embargo, el marco llama a la función de devolución de llamada en IRQL = PASSIVE_LEVEL en las situaciones siguientes:

  • El tipo de identificador del objeto es WDFDEVICE, WDFDRIVER, WDFDPC, WDFINTERRUPT, WDFIOTARGET, WDFQUEUE, WDFSTRING, WDFTIMER o WDFWORKITEM.
  • El tipo de identificador del objeto es WDFMEMORY o WDFLOOKASIDE y el controlador ha especificado PagedPool para el parámetro PoolType en WdfMemoryCreate o WdfLookasideListCreate.
Cuando se elimina un objeto de elemento de trabajo, ya sea explícitamente o porque se elimina el objeto primario del elemento de trabajo, antes de llamar a la función de devolución de llamada EvtCleanupCallback del elemento de trabajo, el marco espera hasta que se hayan devuelto todas las instancias de la función de devolución de llamada EvtWorkItem del elemento de trabajo. Para obtener más información, vea WdfWorkItemEnqueue.

Del mismo modo, cuando se elimina un objeto de temporizador, ya sea explícitamente o porque se está eliminando el objeto primario del temporizador, antes de llamar a la función de devolución de llamada EvtCleanupCallback del temporizador, el marco espera hasta que se hayan devuelto todas las instancias de la función de devolución de llamada de eventos EvtTimerFunc del temporizador.

A partir de la versión 1.9 del marco, el archivo de encabezado wdfroletypes.h contiene algunos tipos de función alternativos específicos del tipo de objeto para la función de devolución de llamada EvtCleanupCallback . Estos tipos alternativos ayudan a las herramientas de comprobación a determinar si el controlador usa correctamente la función de devolución de llamada. Use la tabla siguiente para determinar qué tipo de función se va a usar.

Tipo de objeto Tipo de función
Objeto de dispositivo EVT_WDF_DEVICE_CONTEXT_CLEANUP
Objeto de cola de E/S EVT_WDF_IO_QUEUE_CONTEXT_CLEANUP_CALLBACK
File (objeto) EVT_WDF_FILE_CONTEXT_CLEANUP_CALLBACK
Todos los demás objetos EVT_WDF_OBJECT_CONTEXT_CLEANUP

Requisitos

Requisito Value
Plataforma de destino Universal
Versión mínima de KMDF 1.0
Versión mínima de UMDF 2.0
Encabezado wdfobject.h (incluya Wdf.h)
IRQL vea la sección Comentarios.

Consulte también

EvtDestroyCallback

WDF_OBJECT_ATTRIBUTES

WdfObjectDereference

WdfObjectReference

WdfWorkItemFlush