EX_CALLBACK_FUNCTION función de devolución de llamada (wdm.h)
Una rutina RegistryCallback del controlador de filtro puede supervisar, bloquear o modificar una operación del Registro.
Sintaxis
EX_CALLBACK_FUNCTION ExCallbackFunction;
NTSTATUS ExCallbackFunction(
[in] PVOID CallbackContext,
[in, optional] PVOID Argument1,
[in, optional] PVOID Argument2
)
{...}
Parámetros
[in] CallbackContext
Valor que el controlador pasó como parámetro Context a CmRegisterCallback o CmRegisterCallbackEx cuando registró esta rutina RegistryCallback .
[in, optional] Argument1
Valor REG_NOTIFY_CLASS tipo que identifica el tipo de operación del Registro que se está realizando y si se llama a la rutina RegistryCallback antes o después de que se realice la operación del Registro.
[in, optional] Argument2
Puntero a una estructura que contiene información específica del tipo de operación del Registro. El tipo de estructura depende del valor con tipo REG_NOTIFY_CLASS para Argument1, como se muestra en la tabla siguiente. Para obtener información sobre qué valores con tipo de REG_NOTIFY_CLASS están disponibles para las versiones del sistema operativo, consulte REG_NOTIFY_CLASS.
A partir de Windows 7, la estructura de datos real pasada cuando la clase notify es RegNtPreCreateKeyEx o RegNtPreOpenKeyEx es la versión V1 de esta estructura, REG_CREATE_KEY_INFORMATION_V1 o REG_OPEN_KEY_INFORMATION_V1, respectivamente. Compruebe el miembro Reservado para determinar la versión de la estructura.
Número de la versión | Nombre de la estructura |
---|---|
0 | REG_CREATE_KEY_INFORMATION y REG_OPEN_KEY_INFORMATION |
1 | REG_CREATE_KEY_INFORMATION_V1 y REG_OPEN_KEY_INFORMATION_V1 |
Valor devuelto
Para obtener más información sobre cuándo una rutina RegistryCallback debe devolver cada uno de estos valores de estado, consulte Filtrado de llamadas al Registro.
Comentarios
Para recibir una notificación de las operaciones del Registro, un componente en modo kernel (como el componente de controlador de un paquete de software antivirus) puede llamar a CmRegisterCallback o CmRegisterCallbackEx para registrar una rutina RegistryCallback .
La rutina RegistryCallback puede inspeccionar el contenido de los búferes de entrada y salida que se proporcionan para las operaciones del Registro. Una operación del Registro se puede iniciar mediante una aplicación en modo de usuario que llama a una rutina del Registro en modo de usuario (como RegCreateKeyEx o RegOpenKeyEx) o mediante un controlador que llama a una rutina del Registro en modo kernel (como ZwCreateKey o ZwOpenKey). Un búfer de entrada es un búfer de memoria proporcionado por el iniciador desde el que el registro lee los datos de entrada de la operación. Un búfer de salida es un búfer proporcionado por el iniciador en el que el registro escribe los datos de salida solicitados por el iniciador.
Antes de llamar a la rutina RegistryCallback , el kernel sondea (para comprobar la alineación y accesibilidad) todos los miembros de las estructuras Argument2 que apuntan a búferes de salida en memoria en modo usuario, pero no captura búferes de salida en modo usuario en memoria del sistema. La rutina de devolución de llamada debe incluir cualquier acceso de un búfer de salida en un bloqueexcepto en un intento/. Si la rutina de devolución de llamada necesita pasar un puntero de búfer de salida a una rutina del sistema (por ejemplo, ZwOpenKey) y el búfer está en memoria en modo usuario, la rutina de devolución de llamada debe capturar primero el búfer.
El control de los búferes de entrada depende de la versión de Windows. A partir de Windows 8, el kernel captura todos los búferes de entrada a los que apuntan los miembros de las estructuras Argument2 en la memoria del sistema antes de llamar a la rutina RegistryCallback. En versiones de Windows antes de Windows 8, el kernel sondea todos los miembros de las estructuras Argument2 que apuntan a búferes de entrada en memoria en modo de usuario, pero captura solo algunos de estos búferes en la memoria del sistema. En estas versiones anteriores de Windows, la rutina de devolución de llamada debe incluir cualquier acceso de un búfer de entrada en un intento/excepto el bloque . Además, si la rutina de devolución de llamada necesita pasar un puntero de búfer de entrada a una rutina del sistema (por ejemplo, ZwOpenKey) y el búfer está en modo de usuario, la rutina de devolución de llamada debe capturar primero el búfer.
En la tabla siguiente se resumen los requisitos para el acceso de búfer mediante la rutina RegistryCallback .
Tipo de búfer | Versión de Windows | Puntero de búfer pasado a la rutina de devolución de llamada | ¿Es seguro para que la rutina de devolución de llamada acceda directamente? | ¿Es seguro pasar a rutinas del sistema (como ZwOpenKey)? |
---|---|---|---|---|
Entrada en modo de usuario | Windows 8 y versiones posteriores | Apunta a los datos capturados. | Sí | Sí |
Entrada en modo de usuario | Windows 7 y versiones anteriores | Apunta a los datos capturados o al búfer en modo usuario original. | No. Debe leer en try/except. | No. Debe asignar memoria del kernel, copiar datos del búfer original en try/except y pasar los datos copiados a la rutina del sistema. |
Salida en modo de usuario | All | Apunta al búfer del modo de usuario original. | No. Debe escribir en try/except. | No. Debe asignar memoria del kernel, pasar memoria del kernel a la rutina del sistema y volver a copiar los resultados en el búfer original en try/except. |
Entrada y salida en modo kernel | All | Apunta al búfer en modo kernel original. | Sí | Sí |
Para obtener más información sobre las rutinas registryCallback y los controladores de filtro del Registro, consulte Filtrado de llamadas al Registro.
RegistryCallback se ejecuta en IRQL = PASSIVE_LEVEL y en el contexto del subproceso que realiza la operación del Registro.
Ejemplos
Para definir una rutina de devolución de llamada registryCallback , primero debe proporcionar una declaración de función que identifique el tipo de rutina de devolución de llamada que está definiendo. Windows proporciona un conjunto de tipos de función de devolución de llamada para controladores. Declarar una función mediante los tipos de función de devolución de llamada ayuda a Code Analysis for Drivers, Static Driver Verifier (SDV) y otras herramientas de comprobación encuentran errores y es un requisito para escribir controladores para el sistema operativo Windows.
Por ejemplo, para definir una rutina de devolución de llamada RegistryCallback denominada MyRegistryCallback
, use el tipo de EX_CALLBACK_FUNCTION como se muestra en este ejemplo de código:
EX_CALLBACK_FUNCTION MyRegistryCallback;
A continuación, implemente la rutina de devolución de llamada de la siguiente manera:
_Use_decl_annotations_
NTSTATUS
MyRegistryCallback(
PVOID CallbackContext,
PVOID Argument1,
PVOID Argument2
)
{
// Function body
}
El tipo de función EX_CALLBACK_FUNCTION se define en el archivo de encabezado Wdm.h. Para identificar con más precisión los errores al ejecutar las herramientas de análisis de código, asegúrese de agregar la anotación Use_decl_annotations a la definición de función. La anotación Use_decl_annotations garantiza que se usen las anotaciones que se aplican al tipo de función EX_CALLBACK_FUNCTION en el archivo de encabezado. Para obtener más información sobre los requisitos de las declaraciones de función, vea Declarar funciones mediante tipos de rol de función para controladores WDM. Para obtener información sobre Use_decl_annotations, consulte Anotación del comportamiento de la función.
Requisitos
Requisito | Value |
---|---|
Cliente mínimo compatible | Se admite a partir de Windows XP (consulte la sección Valor devuelto). |
Plataforma de destino | Escritorio |
Encabezado | wdm.h (incluya Wdm.h, Ntddk.h, Ntifs.h) |
IRQL | Se llama en PASSIVE_LEVEL (consulte la sección Comentarios). |