Compartir a través de


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.

REG_NOTIFY_CLASS valor Tipo de estructura
RegNtDeleteKey REG_DELETE_KEY_INFORMATION
RegNtPreDeleteKey REG_DELETE_KEY_INFORMATION
RegNtPostDeleteKey de REG_POST_OPERATION_INFORMATION
regNtSetValueKey REG_SET_VALUE_KEY_INFORMATION
RegNtPreSetValueKey de REG_SET_VALUE_KEY_INFORMATION
regNtPostSetValueKey de REG_POST_OPERATION_INFORMATION
RegNtDeleteValueKey REG_DELETE_VALUE_KEY_INFORMATION
RegNtPreDeleteValueKey de REG_DELETE_VALUE_KEY_INFORMATION
RegNtPostDeleteValueKey de REG_POST_OPERATION_INFORMATION
RegNtSetInformationKey de REG_SET_INFORMATION_KEY_INFORMATION
RegNtPreSetInformationKey de REG_SET_INFORMATION_KEY_INFORMATION
RegNtPostSetInformationKey REG_POST_OPERATION_INFORMATION
RegNtRenameKey REG_RENAME_KEY_INFORMATION
RegNtPreRenameKey REG_RENAME_KEY_INFORMATION
RegNtPostRenameKey REG_POST_OPERATION_INFORMATION
regNtEnumerateKey REG_ENUMERATE_KEY_INFORMATION
RegNtPreEnumerateKey REG_ENUMERATE_KEY_INFORMATION
RegNtPostEnumerateKey REG_POST_OPERATION_INFORMATION
regNtEnumerateValueKey REG_ENUMERATE_VALUE_KEY_INFORMATION
RegNtPreEnumerateValueKey REG_ENUMERATE_VALUE_KEY_INFORMATION
regNtPostEnumerateValueKey REG_POST_OPERATION_INFORMATION
regNtQueryKey REG_QUERY_KEY_INFORMATION
RegNtPreQueryKey de REG_QUERY_KEY_INFORMATION
RegNtPostQueryKey REG_POST_OPERATION_INFORMATION
RegNtQueryValueKey REG_QUERY_VALUE_KEY_INFORMATION
RegNtPreQueryValueKey REG_QUERY_VALUE_KEY_INFORMATION
RegNtPostQueryValueKey de REG_POST_OPERATION_INFORMATION
regNtQueryMultipleValueKey REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION
RegNtPreQueryMultipleValueKey REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION
RegNtPostQueryMultipleValueKey REG_POST_OPERATION_INFORMATION
RegNtPreCreateKey REG_PRE_CREATE_KEY_INFORMATION
RegNtPreCreateKeyEx REG_CREATE_KEY_INFORMATION**
RegNtPostCreateKey REG_POST_CREATE_KEY_INFORMATION
RegNtPostCreateKeyEx REG_POST_OPERATION_INFORMATION
RegNtPreOpenKey REG_PRE_OPEN_KEY_INFORMATION**
RegNtPreOpenKeyEx REG_OPEN_KEY_INFORMATION
RegNtPostOpenKey de REG_POST_OPEN_KEY_INFORMATION
RegNtPostOpenKeyEx REG_POST_OPERATION_INFORMATION
RegNtKeyHandleClose REG_KEY_HANDLE_CLOSE_INFORMATION
RegNtPreKeyHandleClose REG_KEY_HANDLE_CLOSE_INFORMATION
RegNtPostKeyHandleClose REG_POST_OPERATION_INFORMATION
RegNtPreFlushKey REG_FLUSH_KEY_INFORMATION
RegNtPostFlushKey REG_POST_OPERATION_INFORMATION
RegNtPreLoadKey REG_LOAD_KEY_INFORMATION
RegNtPostLoadKey de REG_POST_OPERATION_INFORMATION
RegNtPreUnLoadKey REG_UNLOAD_KEY_INFORMATION
RegNtPostUnLoadKey de REG_POST_OPERATION_INFORMATION
RegNtPreQueryKeySecurity REG_QUERY_KEY_SECURITY_INFORMATION
RegNtPostQueryKeySecurity REG_POST_OPERATION_INFORMATION
RegNtPreSetKeySecurity REG_SET_KEY_SECURITY_INFORMATION
RegNtPostSetKeySecurity REG_POST_OPERATION_INFORMATION
RegNtCallbackObjectContextCleanup REG_CALLBACK_CONTEXT_CLEANUP_INFORMATION
RegNtPreRestoreKey REG_RESTORE_KEY_INFORMATION
RegNtPostRestoreKey de REG_POST_OPERATION_INFORMATION
RegNtPreSaveKey de REG_SAVE_KEY_INFORMATION
RegNtPostSaveKey REG_POST_OPERATION_INFORMATION
RegNtPreReplaceKey REG_REPLACE_KEY_INFORMATION
RegNtPostReplaceKey REG_POST_OPERATION_INFORMATION
RegNtPreQueryKeyName REG_QUERY_KEY_NAME
RegNtPostQueryKeyName REG_POST_OPERATION_INFORMATION
RegNtPreSaveMergedKey REG_SAVE_MERGED_KEY_INFORMATION
RegNtPostSaveMergedKey REG_POST_OPERATION_INFORMATION

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.
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.

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).

Consulte también

CmRegisterCallback

CmUnRegisterCallback

probeForRead

REG_NOTIFY_CLASS

ZwOpenKey