Freigeben über


In nativen Anwendungen

Mark Russinovich Veröffentlichungsdatum: 1. November 2006

Einführung

Wenn Sie ein wenig mit der Architektur von NT vertraut sind, wissen Sie wahrscheinlich, dass die API, die Win32-Anwendungen verwenden, nicht die „echte“ NT-API ist. Die Betriebssystemumgebungen von NT, zu denen POSIX, OS/2 und Win32 gehören, kommunizieren mit ihren Clientanwendungen über ihre eigenen APIs. Für die Kommunikation mit NT verwenden sie aber die „native“ NT-API. Die native API ist größtenteils nicht dokumentiert: Im Windows NT Device Driver Kit werden nur etwa 25 ihrer 250 Funktionen beschrieben.

Was die meisten aber nicht wissen: Es gibt „native“ Anwendungen unter NT, die keine Clients einer der Betriebsumgebungen sind. Diese Programme kommunizieren mit der nativen NT-API und können keine Betriebsumgebungs-APIs wie Win32 verwenden. Warum werden solche Programme benötigt? Jedes Programm, das ausgeführt werden muss, bevor das Win32-Subsystem gestartet wird (ungefähr zu der Zeit, zu der das Anmeldefeld angezeigt wird), muss eine native Anwendung sein. Das sichtbarste Beispiel für eine native Anwendung ist das Programm „Autochk“, das Chkdsk während des Initialisierungsbluescreens ausführt. Dabei handelt es sich um das Programm, dass die Punkte (.) auf dem Bildschirm ausgibt. Natürlich muss auch der Win32-Betriebsumgebungsserver „CSRSS.EXE“ (Client-Server-Runtime-Subsystem) eine native Anwendung sein.

In diesem Artikel erfahren Sie, wie native Anwendungen erstellt werden und wie sie funktionieren.

Wie wird Autochk ausgeführt?

Autochk wird zwischen dem Laden der Boot- und Systemstarttreiber von NT und dem Aktivieren des Pagings ausgeführt. An diesem Punkt in der Startsequenz wird die Benutzermodusumgebung von NT durch den Sitzungs-Manager (smss.exe) initiiert, und es sind keine anderen Programme aktiv. Der MULTI_SZ-Wert HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute enthält die Namen und Argumente von Programmen, die durch den Sitzungs-Manager ausgeführt werden, und ist der Ort, an dem Autochk angegeben wird. In der Regel finden Sie Folgendes vor, wenn Sie sich diesen Wert ansehen. Hier wird an Autochk ein Sternchen (*) als Argument übergeben:

Autocheck Autochk *

Der Sitzungs-Manager sucht im Verzeichnis „<winnt>\system32“ nach den ausführbaren Dateien, die in diesem Wert aufgeführt sind. Wenn Autochk ausgeführt wird, sind keine Dateien geöffnet, sodass Autochk jedes Volume (auch das Startlaufwerk) im RAW-Modus öffnen und die zugehörigen Datenstrukturen auf dem Datenträger bearbeiten kann. Dies wäre zu einem späteren Zeitpunkt nicht möglich.

Erstellen nativer Anwendungen

Microsoft dokumentiert das zwar nicht, aber das Build-Hilfsprogramm des NT DDK kann native Anwendungen erstellen (und wird wahrscheinlich zum Kompilieren von Autochk verwendet). Sie geben genau wie bei Gerätetreibern Informationen in einer SOURCES-Datei an, die die Anwendung definiert. Anstatt jedoch gegenüber Build anzugeben, dass Sie einen Treiber benötigen, geben Sie in der SOURCES-Datei an, dass Sie eine native Anwendung erstellen möchten:

TARGETTYPE=PROGRAM

Zur Steuerung verwendet das Hilfsprogramm Build ein Standard-Makefile (\ddk\inc\makefile.def), das beim Kompilieren nativer Anwendungen nach einer Laufzeitbibliothek namens „nt.lib“ sucht. Leider stellt Microsoft diese Datei nicht standardmäßig im DDK bereit. (Im Server 2003 DDK ist sie zwar enthalten, aber ich vermute, dass Ihre native Anwendung nicht unter XP oder Windows 2000 funktioniert, wenn Sie eine Verknüpfung mit dieser Version herstellen.) Sie können dieses Problem jedoch umgehen, indem Sie eine Zeile in „makefile.def“ einfügen, die die Auswahl von „nt.lib“ außer Kraft setzt, indem Sie die Visual C++-Laufzeitbibliothek „msvcrt.lib“ angeben.

Wenn Sie Build in der DDK-Umgebung „Überprüfter Build“ ausführen, wird eine native Anwendung mit vollständigen Debuginformationen unter „%BASEDIR%\lib%CPU%\checked“ (Beispiel: c:\ddk\lib\i386\checked\native.exe) erstellt. Wenn Sie Build in der Umgebung „Freier Build“ aufrufen, wird eine Releaseversion des Programms in „%BASEDIR%\lib%CPU%\free“ platziert. Das sind die gleichen Orte, an denen Gerätetreiberimages von Build platziert werden.

Native Anwendungen haben die Dateierweiterung „.exe“, können aber nicht wie ausführbare Dateien von win32 ausgeführt werden. Wenn Sie es versuchen, erhalten Sie folgende Meldung:

Die Anwendung kann nicht im Windows NT-Modus ausgeführt werden.

Einblicke in eine native Anwendung

Anstelle von winmain oder main ist ntProcessStartup der Einstiegspunkt für native Anwendungen. Anders als bei den anderen Win32-Einstiegspunkten müssen native Anwendungen außerdem auf eine Datenstruktur zugreifen, die als einziger Parameter übergeben wird, um Befehlszeilenargumente zu finden.

Der Großteil der Laufzeitumgebung einer nativen Anwendung wird von „NTDLL.DLL“ (der nativen API-Exportbibliothek von NT) bereitgestellt. Native Anwendungen müssen mithilfe von RtlCreateHeap, einer NTDLL-Funktion, einen eigenen Heap erstellen, aus dem Speicher zugeordnet werden kann. Arbeitsspeicher wird aus einem Heap mit RtlAllocateHeap zugeordnet und mit RtlFreeHeap freigegeben. Wenn eine native Anwendung etwas auf dem Bildschirm ausgeben möchte, muss sie die Funktion NtDisplayString verwenden, deren Ausgabe im Initialisierungsbluescreen angezeigt wird.

Native Anwendungen kehren nicht einfach von ihrer Startfunktion zurück wie Win32-Programme, da es keinen Laufzeitcode gibt, zu dem zurückgekehrt werden kann. Stattdessen müssen sie sich durch Aufrufen von NtProcessTerminate selbst beenden.

Die NTDLL-Runtime besteht aus Hunderten von Funktionen, die es nativen Anwendungen ermöglichen, Datei-E/A-Vorgänge auszuführen, mit Gerätetreibern zu interagieren und prozessübergreifend zu kommunizieren. Doch wie bereits erwähnt, ist leider der Großteil dieser Funktionen nicht dokumentiert.