在本机应用程序中

Mark Russin进行发布:2006 年 11 月 1 日

简介

如果你对 NT 的体系结构有一定的了解,你可能知道 Win32 应用程序使用的 API 不是"真实"的 NT API。 NT 的操作系统环境(包括 POSIX、OS/2 和 Win32)通过其自己的 API 与客户端应用程序对话,但使用 NT"本机"API 与 NT 对话。 本机 API 主要未记录,其 250 个函数中只有大约 25 个在 Windows NT 驱动程序工具包中所述。

但是,大多数人不知道的是,NT 上存在"本机"应用程序,这些应用程序不是任何操作环境的客户端。 这些程序使用本机 NT API,并且不能使用 Win32 等操作环境 API。 为什么需要此类程序"在启动 Win32 子系统之前必须运行的任何程序 (登录框出现时) 必须是本机应用程序。 本机应用程序的最明显示例是在初始化蓝屏期间运行 chkdsk 的"autochk"程序 (它是打印"."的程序。位于屏幕) 。 当然,Win32 操作环境服务器(CSRSS.EXE (客户端-服务器运行时子系统) )也必须是本机应用程序。

本文介绍如何生成本机应用程序及其工作。

如何执行 Autochk

Autochk 在加载 NT 启动驱动程序和系统启动驱动程序到启用分页之间运行。 此时,在启动序列会话管理器 (smss.exe) NT 的用户模式环境已启动,并且其他程序没有处于活动状态。 HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute值 MULTI_SZ 包含由会话管理器执行的程序的名称和参数,并指定 Autochk。 下面是查看此值时通常会发现的值,其中"Autochk"作为参数传递"*":

Autocheck Autochk *

会话管理器 winnt > \system32 目录中查找此值中列出的可执行文件。 Autochk 运行时,不会打开任何文件,因此 Autochk 可以在原始模式下打开任何卷(包括启动驱动器)并操作其磁盘上的数据结构。 这以后将不可能实现。

生成本机应用程序

Microsoft 不会记录它,但 NT DDK 生成实用工具知道如何使本机应用程序 (并且它可能用于编译Autochk) 。 在定义应用程序的 SOURCES 文件中指定信息,与为设备驱动程序指定的信息相同。 但是,不要指示"生成"需要驱动程序,而是告诉它在 SOURCES 文件中需要一个本机应用程序,如下所示:

TARGETTYPE=PROGRAM

生成实用工具使用标准生成文件 \ddk\inc\makefile.def 来指导它,该实用工具在编译本机应用程序时查找名为 nt.lib 的运行时库。 遗憾的是,Microsoft 未将此文件与 DDK (包含在 Server 2003 DDK 中,但怀疑如果链接到该版本,则本机应用程序不会在 XP 或 Windows 2000) 上运行。 但是,可以通过在 makefile.def 中包含一行来解决此问题,该行通过指定 Visual C++ 的运行时库 msvcrt.lib 来替代 nt.lib 的选择

如果在 DDK 的"已检查生成"环境中运行生成,它将生成一个本机应用程序,该应用程序在 %BASEDIR%\lib%CPU%\Checked (下具有完整的调试信息,例如 c:\ddk\lib\i386\checked\native.exe) ;如果在"免费生成"环境中调用它,则程序的发布版本将最终在 %BASEDIR%\lib%CPU%\Free 中。 这些位置与生成放置设备驱动程序映像的位置相同。

本机应用程序具有".exe"文件扩展名,但不能像 Win32 .exe一样运行它们。 如果尝试,将收到以下消息:

应用程序无法在运行模式下Windows NT运行。

在本机应用程序中

本机应用程序的 入口点不是 winmain,而是 NtProcessStartup。 此外,与其他 Win32 入口点不同,本机应用程序必须访问作为唯一参数传递的数据结构,以查找命令行参数。

大多数本机应用程序的运行时环境由 NT 的NTDLL.DLL API 导出库提供。 本机应用程序必须使用 RtlCreateHeap(NTDLL函数)创建自己的堆来分配存储。 内存从具有 RtlAllocateHeap 的堆中分配,使用 RtlFreeHeap 释放。 如果本机应用程序希望将某些内容打印到屏幕上,则必须使用 函数 NtDisplayString,该函数将输出到初始化蓝屏。

本机应用程序不只是从启动函数(如 Win32 程序)返回,因为没有任何运行时代码可返回。 相反,它们必须通过调用 NtProcessTerminate 终止自身

NTDLL 运行时由数百个函数组成,这些函数允许本机应用程序执行文件 I/O、与设备驱动程序交互和执行进程间通信。 遗憾的是,如我前面所述,这些函数中的绝大多数都是未记录的。