1 《Undocumented Windows 2000 Secrets》翻译 --- 第三章

第三章 编写内核模式驱动程序
翻译: Kendiv
更新: Monday, February 07, 2005
在下一章中,我们会经常访问那些仅在内核模式下才有效的系统资源 。大量的示例代码都被设计为内核驱动例程( Kernel-mode driver routine ) 。因此,需要有关开发此种软件的基本知识 。因为我不能假定所有读者都有这方面的经验,我会在此简要地介绍一下内核模式驱动程序编程,不过这仅集中在如何使用驱动开发向导(在本书光盘上) 。
本章还将讨论 Windows 2000 服务控制管理器( Service Control Manager,SCM )的基本知识,这包括 SCM 如何允许在运行时加载、控制和卸载驱动程序,resulting in wonderfully short change-build-test turnaround cycles。本章的题目或许会让人有些误解,驱动一词通常与控制硬件的底层软件相关 。事实上,很多内核程序员每天都在做这些事情 。不过,Windows 2000 的驱动程序分层模式允许做比这更多的事情 。内核驱动程序可以完成任意复杂的任务,若不考虑它们运行于更高的 CPU 特权级别上而且使用不同的开发接口,那它们很像用户模式下的 DLL。在此,我们将使用这种强大的开发技术来侦测 Windows 2000 的内部秘密,使用内核驱动程序就像驾驶从狭小的用户模式飞往 Windows 2000 内核的太空飞船 。
创建一个驱动程序的骨架
即使长时间开发 Win32 应用程序和库的开发人员,在首次编写内核驱动程序时,也会感觉像是一个绝对的初学者 。这是因为,内核模式下的代码运行在一个完全不同的操作系统环境中 。Win32 开发人员的工作仅局限在属于 Windows 2000 Win32 子系统的几个系统组件上 。其他开发人员可能编写 POSI 或 OS/2 应用程序,Windows 2000 的附加子系统为它们提供支持 。感谢子系统这个概念,Windows 2000 就像一个变色龙 --- 它可通过这些子系统(前面提及的)导出不同的应用程序开发接口来模拟不同的操作系统 。与此相反,内核模式的代码可以看到“真实”的 Windows 2000 操作系统 。它们使用的接口可以称之为“最终边界” 。当然,这并不是说,内核模式完全摆脱了子系统 。在第二章中,我们看到 win32k.sys 就是 Win32 GUI 和窗口管理器在内核模式下的分支,将它们放在内核是出于性能考虑 。然而,win32k.sys 导出的 API 函数集合中只有一小部分出现在了 gdi32.dll 和 user32.dll 中,这也意味着只有这一小部分函数可以作为 Win32 API 函数来使用,因此,Win32K 决不只是 Win32 踏入内核世界的一脚,实际上,应把它看作是一个高性能的内核模式的图形引擎 。
Windows 2000 DDK ( Device Driver Kit )
由于内核模式下的编程使用了不同的系统接口,在 Win32 编程中经常使用的头文件和库都将无法在内核模式下使用 。针对 Win32 开发,微软提供了 Platform Software Development Kit ( SDK ) 。而与内核模式的驱动开发相关的是,Windows 2000 Device Driver Kit ( DDK ) 。随文档一起,DDK 还提供了特殊的头文件和导入库,这些都是 Windows 2000 内核模块必须的接口 。安装完 DDK 之后,接下来你应该打开 Visual C/C,把 DDK 的路径加入到编译器和链接器的目录列表中 。在主菜单中选择 Tools à Options,然后单击 DirectorIEs。在目录选择下拉列表中选择 Include files,然后将 DDK 的适当路径加入,如 图 3-1 所示 。默认情况下,DDK 将安装到 NTDDK 目录下,included 文件位于 NTDDKinc 子目录中 。需要注意的是,请将新添加的路径置于原有路径的上方,这样就会使用新的头文件或者库 。
图 3-1 添加 DDK 头文件路径
图 3-2 添加 DDK 导入库路径
在添加完 DDK 头文件路径后,用同样的方法添加导入库的路径 。DDK 包含两组导入库,一组叫做 free ( release ) builds,另一组叫做 checked ( debug ) builds。其对应的目录为: NTDDKlibfrei386 和 NTDDKlibchki386,参见 图 3-2。

推荐阅读