Procesamiento de llamadas de notificación
El motor de filtro llama a la función de llamada notifyFn de una llamada para notificar al controlador de llamada los eventos asociados a la llamada.
Adición de filtro
Cuando se agrega un filtro que especifica una llamada para la acción del filtro al motor de filtros, el motor de filtros llama a la función de llamada notifyFn de la llamada, pasando FWPS_CALLOUT_NOTIFY_ADD_FILTER en el parámetro notifyType .
Un controlador de llamada puede registrar una llamada con el motor de filtros después de los filtros que especifican la llamada para la acción del filtro ya se ha agregado al motor de filtros. En esta situación, el motor de filtros no llama a la función de llamada notifyFn de la llamada para notificar a la llamada sobre cualquiera de los filtros existentes.
El motor de filtros solo llama a la función de llamada notifyFn de la llamada para notificar a la llamada cuando se agregan nuevos filtros que especifican la llamada para la acción del filtro al motor de filtros. En esta situación, es posible que no se llame a la función de llamada notifyFn de una llamada para cada filtro del motor de filtros que especifique la llamada para la acción del filtro.
Si un controlador de llamada registra una llamada después de iniciar el motor de filtro y la llamada debe recibir información sobre cada filtro del motor de filtros que especifica la llamada para la acción del filtro, el controlador de llamada debe llamar a las funciones de administración adecuadas para enumerar todos los filtros del motor de filtros. El controlador de llamada debe ordenar por la lista resultante de todos los filtros para buscar esos filtros que especifican la llamada para la acción del filtro. Consulte Llamar a otras funciones de plataforma de filtrado de Windows para obtener más información sobre cómo llamar a estas funciones.
Eliminación de filtros
Cuando se elimina un filtro que especifica una llamada para la acción del filtro del motor de filtros, el motor de filtros llama a la función de llamada notifyFn de la llamada y pasa FWPS_CALLOUT_NOTIFY_DELETE_FILTER en el parámetro notifyType y NULL en el parámetro filterKey . El motor de filtros llama a la función de llamada notifyFn de la llamada para cada filtro eliminado del motor de filtros que especifica la llamada para la acción del filtro. Esto incluye los filtros que se agregaron al motor de filtros antes de que el controlador de llamada registrara la llamada con el motor de filtro. Por lo tanto, una llamada podría recibir notificaciones de eliminación de filtro para los filtros para los que no recibió notificaciones de adición de filtros.
Si la función de llamada notifyFn de la llamada no reconoce el tipo de notificación que se pasa en el parámetro notifyType , debe omitir la notificación y devolver STATUS_SUCCESS.
Un controlador de llamada puede especificar un contexto que se asociará a un filtro cuando se agregue el filtro al motor de filtros. Este contexto es opaco para el motor de filtro. La función de llamada classifyFn de la llamada puede usar este contexto para guardar la información de estado la próxima vez que el motor de filtro llame a ella. Cuando el filtro se elimina del motor de filtros, el controlador de llamada realiza cualquier limpieza necesaria del contexto.
Por ejemplo:
// Context structure to be associated with the filters
typedef struct FILTER_CONTEXT_ {
.
. // Driver-specific content
.
} FILTER_CONTEXT, *PFILTER_CONTEXT;
// Memory pool tag for filter context structures
#define FILTER_CONTEXT_POOL_TAG 'fcpt'
// notifyFn callout function
NTSTATUS NTAPI
NotifyFn(
IN FWPS_CALLOUT_NOTIFY_TYPE notifyType,
IN const GUID *filterKey,
IN const FWPS_FILTER0 *filter
)
{
PFILTER_CONTEXT context;
ASSERT(filter != NULL);
// Switch on the type of notification
switch(notifyType) {
// A filter is being added to the filter engine
case FWPS_CALLOUT_NOTIFY_ADD_FILTER:
// Allocate the filter context structure
context =
(PFILTER_CONTEXT)ExAllocatePoolWithTag(
NonPagedPool,
sizeof(FILTER_CONTEXT),
FILTER_CONTEXT_POOL_TAG
);
// Check the result of the memory allocation
if (context == NULL) {
// Return error
return STATUS_INSUFFICIENT_RESOURCES;
}
// Initialize the filter context structure
...
// Associate the filter context structure with the filter
filter->context = (UINT64)context;
break;
// A filter is being removed from the filter engine
case FWPS_CALLOUT_NOTIFY_DELETE_FILTER:
// Get the filter context structure from the filter
context = (PFILTER_CONTEXT)filter->context;
// Check whether the filter has a context
if (context) {
// Cleanup the filter context structure
...
// Free the memory for the filter context structure
ExFreePoolWithTag(
context,
FILTER_CONTEXT_POOL_TAG
);
}
break;
// Unknown notification
default:
// Do nothing
break;
}
return STATUS_SUCCESS;
}