EX_CALLBACK_FUNCTION função de retorno de chamada (wdm.h)
A rotina RegistryCallback de um driver de filtro pode monitorar, bloquear ou modificar uma operação do Registro.
Sintaxe
EX_CALLBACK_FUNCTION ExCallbackFunction;
NTSTATUS ExCallbackFunction(
[in] PVOID CallbackContext,
[in, optional] PVOID Argument1,
[in, optional] PVOID Argument2
)
{...}
Parâmetros
[in] CallbackContext
O valor que o driver passou como o parâmetro Context para CmRegisterCallback ou CmRegisterCallbackEx quando registrou essa rotina RegistryCallback .
[in, optional] Argument1
Um valor de tipo REG_NOTIFY_CLASS que identifica o tipo de operação do Registro que está sendo executada e se a rotina RegistryCallback está sendo chamada antes ou depois que a operação do Registro é executada.
[in, optional] Argument2
Um ponteiro para uma estrutura que contém informações específicas para o tipo de operação do Registro. O tipo de estrutura depende do valor de tipo REG_NOTIFY_CLASS para Argument1, conforme mostrado na tabela a seguir. Para obter informações sobre quais valores do tipo REG_NOTIFY_CLASS estão disponíveis para quais versões do sistema operacional, consulte REG_NOTIFY_CLASS.
A partir do Windows 7, a estrutura de dados real passada quando a classe notify é RegNtPreCreateKeyEx ou RegNtPreOpenKeyEx é a versão V1 dessa estrutura, REG_CREATE_KEY_INFORMATION_V1 ou REG_OPEN_KEY_INFORMATION_V1, respectivamente. Verifique o membro Reservado para determinar a versão da estrutura.
Número de versão | Nome da estrutura |
---|---|
0 | REG_CREATE_KEY_INFORMATION e REG_OPEN_KEY_INFORMATION |
1 | REG_CREATE_KEY_INFORMATION_V1 e REG_OPEN_KEY_INFORMATION_V1 |
Retornar valor
Para obter mais informações sobre quando uma rotina RegistryCallback deve retornar cada um desses valores status, consulte Filtrando chamadas do Registro.
Comentários
Para ser notificado sobre as operações do Registro, um componente do modo kernel (como o componente de driver de um pacote de software antivírus) pode chamar CmRegisterCallback ou CmRegisterCallbackEx para registrar uma rotina RegistryCallback .
A rotina RegistryCallback pode inspecionar o conteúdo dos buffers de entrada e saída fornecidos para operações do Registro. Uma operação de registro pode ser iniciada por um aplicativo de modo de usuário que chama uma rotina de registro no modo de usuário (como RegCreateKeyEx ou RegOpenKeyEx) ou por um driver que chama uma rotina de registro no modo kernel (como ZwCreateKey ou ZwOpenKey). Um buffer de entrada é um buffer de memória fornecido pelo iniciador do qual o registro lê dados de entrada para a operação. Um buffer de saída é um buffer fornecido pelo iniciador no qual o registro grava dados de saída solicitados pelo iniciador.
Antes de chamar a rotina RegistryCallback , o kernel investiga (para verificar o alinhamento e a acessibilidade) todos os membros das estruturas Argument2 que apontam para buffers de saída na memória do modo de usuário, mas não capturam buffers de saída no modo de usuário na memória do sistema. A rotina de retorno de chamada deve incluir qualquer acesso de um buffer de saída em um bloco try/, exceto . Se a rotina de retorno de chamada precisar passar um ponteiro de buffer de saída para uma rotina do sistema (por exemplo, ZwOpenKey) e o buffer estiver na memória do modo de usuário, a rotina de retorno de chamada deverá primeiro capturar o buffer.
O tratamento de buffers de entrada depende da versão do Windows. Começando com Windows 8, o kernel captura todos os buffers de entrada apontados por membros das estruturas Argument2 na memória do sistema antes de chamar a rotina RegistryCallback. Em versões do Windows antes de Windows 8, o kernel investiga todos os membros das estruturas Argument2 que apontam para buffers de entrada na memória do modo de usuário, mas captura apenas alguns desses buffers na memória do sistema. Nessas versões anteriores do Windows, a rotina de retorno de chamada deve incluir qualquer acesso de um buffer de entrada em um bloco try/, exceto . Além disso, se a rotina de retorno de chamada precisar passar um ponteiro de buffer de entrada para uma rotina do sistema (por exemplo, ZwOpenKey) e o buffer estiver na memória do modo de usuário, a rotina de retorno de chamada deverá primeiro capturar o buffer.
A tabela a seguir resume os requisitos para acessos de buffer pela rotina RegistryCallback .
Tipo de buffer | Versão do Windows | Ponteiro de buffer passado para a rotina de retorno de chamada | Seguro para a rotina de retorno de chamada acessar diretamente? | Seguro para passar para rotinas do sistema (como ZwOpenKey)? |
---|---|---|---|---|
Entrada no modo de usuário | Windows 8 e posterior | Aponta para dados capturados. | Yes | Yes |
Entrada no modo de usuário | Windows 7 e anteriores | Aponta para dados capturados ou buffer de modo de usuário original. | Não. Deve ler em try/except. | Não. Deve alocar memória do kernel, copiar dados do buffer original em try/except e passar os dados copiados para a rotina do sistema. |
Saída do modo de usuário | Tudo | Aponta para o buffer de modo de usuário original. | Não. Deve gravar em try/except. | Não. Deve alocar memória do kernel, passar a memória do kernel para a rotina do sistema e copiar os resultados de volta para o buffer original em try/except. |
Entrada e saída do modo kernel | Tudo | Aponta para o buffer do modo kernel original. | Yes | Yes |
Para obter mais informações sobre rotinas registryCallback e drivers de filtro de registro, consulte Filtrando chamadas do Registro.
Um RegistryCallback é executado em IRQL = PASSIVE_LEVEL e no contexto do thread que está executando a operação do Registro.
Exemplos
Para definir uma rotina de retorno de chamada registryCallback , primeiro você deve fornecer uma declaração de função que identifique o tipo de rotina de retorno de chamada que você está definindo. O Windows fornece um conjunto de tipos de função de retorno de chamada para drivers. Declarar uma função usando os tipos de função de retorno de chamada ajuda a Análise de Código para Drivers, SDV ( Verificador de Driver Estático ) e outras ferramentas de verificação a encontrar erros e é um requisito para gravar drivers para o sistema operacional Windows.
Por exemplo, para definir uma rotina de retorno de chamada RegistryCallback chamada MyRegistryCallback
, use o tipo EX_CALLBACK_FUNCTION conforme mostrado neste exemplo de código:
EX_CALLBACK_FUNCTION MyRegistryCallback;
Em seguida, implemente sua rotina de retorno de chamada da seguinte maneira:
_Use_decl_annotations_
NTSTATUS
MyRegistryCallback(
PVOID CallbackContext,
PVOID Argument1,
PVOID Argument2
)
{
// Function body
}
O tipo de função EX_CALLBACK_FUNCTION é definido no arquivo de cabeçalho Wdm.h. Para identificar erros com mais precisão ao executar as ferramentas de análise de código, adicione a anotação Use_decl_annotations à sua definição de função. A anotação Use_decl_annotations garante que as anotações aplicadas ao tipo de função EX_CALLBACK_FUNCTION no arquivo de cabeçalho sejam usadas. Para obter mais informações sobre os requisitos para declarações de função, consulte Declarando funções usando tipos de função de função para drivers WDM. Para obter informações sobre Use_decl_annotations, consulte Anotando o comportamento da função.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Com suporte a partir do Windows XP (consulte a seção Valor retornado). |
Plataforma de Destino | Área de Trabalho |
Cabeçalho | wdm.h (include Wdm.h, Ntddk.h, Ntifs.h) |
IRQL | Chamado em PASSIVE_LEVEL (consulte a seção Comentários). |