Usando versões Nt e Zw das rotinas dos Serviços de Sistema Nativo

A API de serviços do sistema operacional nativo do Windows é implementada como um conjunto de rotinas executadas no modo kernel. Essas rotinas têm nomes que começam com o prefixo Nt ou Zw. Os drivers no modo kernel podem chamar essas rotinas diretamente. Os aplicativos no modo de usuário podem acessar essas rotinas usando chamadas do sistema.

Com algumas exceções, cada rotina de serviços do sistema nativo tem duas versões ligeiramente diferentes que têm nomes semelhantes, mas prefixos diferentes. Por exemplo, as chamadas para NtCreateFile e ZwCreateFile executam operações semelhantes e são, de fato, atendidas pela mesma rotina do sistema no modo kernel. Para chamadas do sistema do modo de usuário, as versões Nt e Zw de uma rotina se comportam de forma idêntica. Para chamadas de um driver no modo kernel, as versões Nt e Zw de uma rotina diferem na forma como lidam com os valores de parâmetro que o chamador passa para a rotina.

Um driver no modo kernel chama a versão Zw de uma rotina de serviços do sistema nativo para informar a rotina de que os parâmetros vêm de uma origem confiável no modo kernel. Nesse caso, a rotina pressupõe que pode usar com segurança os parâmetros sem antes validá-los. No entanto, se os parâmetros puderem ser de uma origem do modo de usuário ou de uma origem no modo kernel, o driver chamará a versão Nt da rotina, o que determina, com base no histórico do thread de chamada, se os parâmetros se originaram no modo de usuário ou no modo kernel. Para obter mais informações sobre como a rotina distingue os parâmetros do modo de usuário dos parâmetros do modo kernel, consulte PreviousMode.

Quando um aplicativo de modo de usuário chama a versão Nt ou Zw de uma rotina de serviços do sistema nativo, a rotina sempre trata os parâmetros que recebe como valores provenientes de uma fonte de modo de usuário que não é confiável. A rotina valida completamente os valores de parâmetro antes de usar os parâmetros. Em particular, a rotina investiga todos os buffers fornecidos pelo chamador para verificar se os buffers estão localizados na memória válida do modo de usuário e estão alinhados corretamente.

As rotinas de serviços do sistema nativo fazem suposições adicionais sobre os parâmetros que recebem. Se uma rotina receber um ponteiro para um buffer alocado por um driver de modo kernel, a rotina pressupõe que o buffer foi alocado na memória do sistema, não na memória do modo de usuário. Se a rotina receber um identificador aberto por um aplicativo de modo de usuário, a rotina procurará o identificador na tabela de identificadores do modo usuário, não na tabela de identificadores do modo kernel.

Em algumas instâncias, o significado de um valor de parâmetro difere mais significativamente entre chamadas do modo de usuário e do modo kernel. Por exemplo, a rotina ZwNotifyChangeKey (ou seu equivalente NtNotifyChangeKey ) tem um par de parâmetros de entrada, ApcRoutine e ApcContext, que significam coisas diferentes, dependendo se os parâmetros são de uma origem de modo de usuário ou kernel. Para uma chamada do modo de usuário, ApcRoutine aponta para uma rotina de APC e ApcContext aponta para um valor de contexto que o sistema operacional fornece quando chama a rotina de APC. Para uma chamada do modo kernel, ApcRoutine aponta para uma estrutura WORK_QUEUE_ITEM e ApcContext especifica o tipo de item de fila de trabalho descrito pela estrutura WORK_QUEUE_ITEM .

Esta seção inclui os tópicos a seguir:

PreviousMode

Bibliotecas e cabeçalhos

O que significa o prefixo Zw?

Especificando direitos de acesso

Rotinas NtXxx