Uvnitř nativních aplikací

Mark Russinovich publikováno: 1. listopadu 2006

Úvod

Pokud znáte architekturu NT, pravděpodobně víte, že rozhraní API, které aplikace Win32 používají, není "skutečným" rozhraním NT API. Operační prostředí NT, která zahrnují POSIX, OS/2 a Win32, komunikují s klientskými aplikacemi prostřednictvím vlastních rozhraní API, ale komunikují s NT pomocí "nativního" rozhraní API. Nativní API z velké části není zdokumentováno, přičemž ve Windows NT Device Driver Kit je popsáno pouze asi 25 z jeho 250 funkcí.

Většina lidí ale neví, že v nt existují "nativní" aplikace, které nejsou klienty žádného operačního prostředí. Tyto programy používají nativní rozhraní NT API a nemohou používat rozhraní API prostředí operačního systému, jako je Win32. Proč by takové programy byly potřeba" Každý program, který musí běžet před spuštěním subsystému Win32 (po zobrazení přihlašovacího pole) musí být nativní aplikací. Nejnázornějším příkladem nativní aplikace je program „autochk“, který během úvodní modré obrazovky spouští nástroj chkdsk (je to program, který na obrazovku vypisuje tečky). Přirozeně i server operačního prostředí Win32, CSRSS.EXE (klientský/serverový subsystém běhového prostředí), musí být rovněž nativní aplikací.

V tomto článku popíšem, jak se vytvářejí nativní aplikace a jak fungují.

Jak se Autochk spouští

Autochk se spouští v době mezi načtením spouštěcích ovladačů systému NT a systémových ovladačů spouštěných při startu a zapnutím stránkování. V tomto bodě spouštěcí sekvence Správce relací (smss.exe) spouští uživatelské prostředí systému NT a žádné jiné programy nejsou aktivní. Hodnota HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute , MULTI_SZ, obsahuje názvy a argumenty programů spuštěných správcem relací a je tam, kde je zadána funkce Autochk. Zde je uvedeno, co obvykle najdete, když se podíváte na tuto hodnotu a programu „Autochk“ je jako argument předán znak „*“:

Autocheck Autochk *

Správce relací hledá v adresáři <winnt>\system32 spustitelné soubory uvedené v této hodnotě. Když autochk spustí, nejsou otevřené žádné soubory, takže Autochk může otevřít libovolný svazek v nezpracovaném režimu, včetně spouštěcí jednotky, a manipulovat s datovými strukturami na disku. To by později nebylo možné.

Vytváření nativních aplikací

Microsoft ho nezdokumentuje, ale nástroj NT DDK Build ví, jak vytvářet nativní aplikace (a pravděpodobně se používá ke kompilaci Autochk). Informace zadáte v souboru SOURCES, který definuje aplikaci, stejně jako u ovladačů zařízení. Místo toho, abyste nástroji Build sdělili, že chcete ovladač, uvedete v souboru SOURCES, že chcete nativní aplikaci, takto:

TARGETTYPE=PROGRAM

Nástroj Build používá standardní makefile, \ddk\inc\makefile.def, který při kompilaci nativních aplikací vyhledává běhovou knihovnu s názvem nt.lib. Bohužel Microsoft tento soubor nedoručí s DDK (jeho součástí v sadě Server 2003 DDK, ale myslím, že pokud propojete s touto verzí, vaše nativní aplikace nebude běžet na XP nebo Windows 2000). Tento problém však můžete obejít zahrnutím řádku v souboru makefile.def, který přepíše výběr nt.lib zadáním knihovny runtime jazyka Visual C++, msvcrt.lib.

Pokud spustíte Build v prostředí DDK „Checked Build“, vytvoří nativní aplikaci s úplnými ladicími informacemi v umístění %BASEDIR%\lib%CPU%\Checked (např. c:\ddk\lib\i386\checked\native.exe), a pokud jej spustíte v prostředí „Free Build“, verze programu pro vydání se vytvoří v %BASEDIR%\lib%CPU%\Free. Jedná se o stejná místa, kam se během sestavení umísťují obrazy ovladačů zařízení.

Nativní aplikace mají přípony souborů ".exe", ale nemůžete je spustit jako Win32 .exe's. Pokud se pokusíte, zobrazí se zpráva:

Aplikaci nelze spustit v režimu Windows NT.

Uvnitř nativní aplikace

Místo winmain nebo main je vstupním bodem nativních aplikací NtProcessStartup. Na rozdíl od ostatních vstupních bodů Win32 se nativní aplikace musí spojit s datovou strukturou předanou jako jediný parametr pro vyhledání argumentů příkazového řádku.

Většinu běhového prostředí nativní aplikace poskytuje knihovna NTDLL.DLL, která exportuje nativní rozhraní API systému NT. Nativní aplikace musí vytvořit vlastní haldu, z níž budou přidělovat paměť, pomocí funkce RtlCreateHeap z knihovny NTDLL. Paměť je přidělena z haldy s RtlAllocateHeap a uvolněna pomocí RtlFreeHeap. Pokud chce nativní aplikace vypsat něco na obrazovku, musí použít funkci NtDisplayString, která provede výstup na modrou obrazovku během inicializace.

Nativní aplikace se neukončují pouhým návratem ze své spouštěcí funkce, jako je tomu u programů Win32, protože neexistuje žádný běhový kód, do kterého by se mohly vrátit. Místo toho se musí samy ukončit voláním NtProcessTerminate.

Modul runtime NTDLL se skládá ze stovek funkcí, které umožňují nativním aplikacím provádět vstupně-výstupní operace souborů, pracovat s ovladači zařízení a provádět interprocesovou komunikaci. Bohužel, jak jsem uvedl dříve, velká většina těchto funkcí je nezdokumentována.