Condividi tramite


Uso delle versioni Nt e Zw delle routine dei servizi di sistema nativi

L'API dei servizi del sistema operativo nativo windows viene implementata come un set di routine eseguite in modalità kernel. Queste routine hanno nomi che iniziano con il prefisso Nt o Zw. I driver in modalità kernel possono chiamare direttamente queste routine. Le applicazioni in modalità utente possono accedere a queste routine tramite chiamate di sistema.

Con alcune eccezioni, ogni routine dei servizi di sistema nativi ha due versioni leggermente diverse con nomi simili ma prefissi diversi. Ad esempio, le chiamate a NtCreateFile e ZwCreateFile eseguono operazioni simili e sono, infatti, gestite dalla stessa routine di sistema in modalità kernel. Per le chiamate di sistema dalla modalità utente, le versioni Nt e Zw di una routine si comportano in modo identico. Per le chiamate da un driver di modalità kernel, le versioni Nt e Zw di una routine differiscono nel modo in cui gestiscono i valori dei parametri passati dal chiamante alla routine.

Un driver in modalità kernel chiama la versione Zw di una routine dei servizi di sistema nativa per informare la routine che i parametri provengono da un'origine attendibile in modalità kernel. In questo caso, la routine presuppone che possa usare in modo sicuro i parametri senza prima convalidarli. Tuttavia, se i parametri potrebbero essere provenienti da un'origine in modalità utente o da un'origine in modalità kernel, il driver chiama invece la versione di Nt della routine, che determina, in base alla cronologia del thread chiamante, se i parametri hanno avuto origine in modalità utente o in modalità kernel. Per altre informazioni su come la routine distingue i parametri in modalità utente dai parametri in modalità kernel, vedere PreviousMode.

Quando un'applicazione in modalità utente chiama la versione Nt o Zw di una routine dei servizi di sistema nativa, la routine considera sempre i parametri ricevuti come valori provenienti da un'origine in modalità utente non attendibile. La routine convalida accuratamente i valori dei parametri prima di usare i parametri. In particolare, la routine analizza i buffer forniti dal chiamante per verificare che i buffer si trovino nella memoria valida in modalità utente e siano allineati correttamente.

Le routine dei servizi di sistema nativi presupmettono altri presupposti sui parametri ricevuti. Se una routine riceve un puntatore a un buffer allocato da un driver in modalità kernel, la routine presuppone che il buffer venga allocato nella memoria di sistema, non nella memoria in modalità utente. Se la routine riceve un handle aperto da un'applicazione in modalità utente, la routine cerca l'handle nella tabella handle in modalità utente, non nella tabella handle in modalità kernel.

In alcuni casi, il significato di un valore di parametro differisce in modo più significativo tra le chiamate dalla modalità utente e dalla modalità kernel. Ad esempio, la routineZwNotifyChangeKey (o la relativa routine NtNotifyChangeKey) ha una coppia di parametri di input, ApcRoutine e ApcContext, che significano cose diverse, a seconda che i parametri provenano da un'origine in modalità utente o kernel. Per una chiamata dalla modalità utente, ApcRoutine punta a una routine APC e ApcContext punta a un valore di contesto fornito dal sistema operativo quando chiama la routine APC. Per una chiamata dalla modalità kernel, ApcRoutine punta a una struttura WORK_QUEUE_ITEM e ApcContext specifica il tipo di elemento della coda di lavoro descritto dalla struttura WORK_QUEUE_ITEM.

Questa sezione include gli articoli seguenti:

ModalitàPrecedente

Librerie e Intestazioni

Cosa significa il prefisso Zw?

Specifica dei diritti di accesso

routine NtXxx