EX_CALLBACK_FUNCTION función de devolución de llamada (wdm.h)
Una rutina del controlador de filtro RegistryCallback 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 de a CmRegisterCallback o cmRegisterCallbackEx cuando registró esta rutina de RegistryCallback.
[in, optional] Argument1
Valor de tipo REG_NOTIFY_CLASSque 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 realizar 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_CLASSde Argument1, como se muestra en la tabla siguiente. Para obtener información sobre qué valores de tipo 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 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 de registryCallback de debe devolver cada uno de estos valores de estado, consulte Filtrado de llamadas al Registro.
Observaciones
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 de RegistryCallback.
La rutina de 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 (por ejemplo, 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 de, el kernel sondea (para comprobar la alineación y accesibilidad) todos los miembros del Argument2 estructuras que apuntan a búferes de salida en la memoria del modo de usuario, pero no captura los búferes de salida en modo de usuario en la memoria del sistema. La rutina de devolución de llamada debe incluir cualquier acceso de un búfer de salida en un pruebe/excepto bloque. Si la rutina de devolución de llamada debe 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 de usuario, la rutina de devolución de llamada debe capturar primero el búfer.
El control de 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 de Argument2 en la memoria del sistema antes de llamar a la rutina RegistryCallback de. En versiones de Windows anteriores a Windows 8, el kernel sondea todos los miembros del Argument2 estructuras 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 pruebe/excepto 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 memoria en modo de usuario, la rutina de devolución de llamada primero debe capturar el búfer.
En la tabla siguiente se resumen los requisitos para los accesos de búfer por la rutina de 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 original del modo de usuario. | 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 | Todo | Apunta al búfer original en modo de usuario. | No. Debe escribir en try/except. | No. Debe asignar memoria del kernel, pasar memoria del kernel a la rutina del sistema y copiar los resultados en el búfer original en try/except. |
Entrada y salida en modo kernel | Todo | Apunta al búfer en modo kernel original. | Sí | Sí |
Para obtener más información sobre RegistryCallback rutinas y controladores de filtro del Registro, consulte Filtrado de llamadas del Registro.
Un RegistryCallback se ejecuta en IRQL = PASSIVE_LEVEL y en el contexto del subproceso que realiza la operación del Registro.
Ejemplos
Para definir un RegistryCallback rutina de devolución de llamada, 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 Análisis de código para controladores, comprobador de controladores estáticos (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 un RegistryCallback rutina de devolución de llamada denominada MyRegistryCallback
, use el tipo EX_CALLBACK_FUNCTION tal 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, vea Anotación del comportamiento de la función.
Requisitos
Requisito | Valor |
---|---|
cliente mínimo admitido | Se admite a partir de Windows XP (consulte la sección Valor devuelto). |
de la plataforma de destino de | Escritorio |
encabezado de | wdm.h (include Wdm.h, Ntddk.h, Ntifs.h) |
irQL | Se llama en PASSIVE_LEVEL (consulte la sección Comentarios). |