|
可定制的驱动程序向导
开发内核驱动程序的主要困难在于 Visual C/C++ 没有提供此种类型的工程向导。幸运的是, MSDN 里有一系列不错的关于 Windows NT 内核驱动开发的文章,是 Ruediger R.Asche. 在 1994 至 1995 年编写的。其中的两篇文章( Asche 1995a , 1995b )详细说明了如何在 Visual C/C++ 中加入自定义的驱动程序向导,这些文章给了我很大的帮助,尽管原始向导的输出文件不能满足我的所有需求,但这是一个很好的开始。我提供的内核驱动向导将基于 Ruediger Asche 的原始向导产生的输出文件。
我提供的驱动向导的所有源代码位于本书光盘的 \src\w2k_wiz 目录。通过阅读这些代码,你会发现它实际的标题“ SBS Windows 2000 Code Wizard ”。事实上,这是一个一般性的 Windows 2000 程序骨架生成器,该生成器可以产生多种类型的程序,包括 Win32 DLL 和应用程序。不过,光盘中的配置文件针对内核驱动开发做了一定的修改。基本上来说,我提供的向导是一个文件转换器,它读取一组文件,然后按照一些简单的规则将它们进行转换,最后将结果写入另一组文件中。输入文件是模板,输出文件是 C 工程文件。通过修改模板文件,该向导可以变成一个 DLL 向导等等。必须提供 7 个模板文件(如果丢失了某一个,会产生错误):
l 扩展名为 .tw 的文件是 workspace 模板,此种文件将会被保存为 Visual Studio 的工程文件 .dsw 。
l 扩展名为 .tp 的文件是工程模板,此种文件将被保存为 .dsp 文件。工程文件由于之关联的 workspace 文件引用,工程文件还包含生成工程的所有配置选项。
l 扩展名为 .tc 、 .th 、 .tr 和 .td 的文件都是 C 代码文件,这些文件最后会变成相应的 .c 、 .h 、 .rc 和 .def 文件。
l 扩展名为 .ti 的是 icon 文件,该文件会被直接保存为 .ico 文件。
这七个文件是一个新工程所必需的。 .def 文件以一种较老风格的方法从 DLL 中导出 API 函数,不过我更喜欢 __declspec(dllexport) 方式。因为驱动程序通常不导出函数,所以我省略了 .td 模板,导致的结果是,在开始时,向导会报告一个错误。我还省略了资源脚本和 icon 文件,不过经验告诉我,最好提供它们。采用的转换规则也非常简单,仅包含一个很短的字符串替换列表。在扫描模板文件时,转换器查找以 % 号开始的转义符。当它找到后,会根据 % 后的字符来决定执行什么样的动作。 表 3-1 列出了验证过的转义符。

表 3-1 中有几处需参考配置文件 ---w2k_wiz.ini 。 示例 3-1 给出了其默认设置。在使用向导之前,你应该将光盘 \src\w2k_wiz\release 目录下的 w2k_wiz.exe 、 w2k_wiz.ini 和所有的 w2k_wiz.t* 模板文件复制到你的硬盘上,然后编辑配置文件,将对应内容改为你自己的设置。你还需要修改 Include 、 Free 和 Checked ,使其和你的 DDK 安装相匹配。如果你使用 Visual C/C++ 6.0 ,可以不改变 Root 的值。如果不,则将其设为你存放工程文件的根目录。如果以一个反斜线结尾,它将作为默认值。在 示例 3-1 中,其键值为: HKEY_CURRENT_USER\SoftWare\Microsofto\DevStudio\6.0\Directories ,而 WorkspaceDir 用来存放基本的工作目录。
键入 w2k_wiz MyDriver 来执行该向导,它会当前目录下创建名为 MyDriver 的工程目录,该目录将存放向导生成的 MyDriver.dsw 、 MyDriver.dsp 、 MyDriver.c 、 MyDriver.h 、 MyDriver.rc 和 MyDriver.ico 文件。如果你指定了具体的路径,则会在你指定的路径下创建该目录。另一个合法的命令选项是星号,如: w2k_wiz *MyDriver 。在此种情况下,向导不会在当前目录下创建工程目录,而是去查找 Visual C/C++ 维护的默认的工程根目录,即 w2k_wiz.ini 中的 Root 所指向的位置。
; w2k_wiz.ini
; 08-27-2000 Sven B. Schreiber
; sbs@orgon.com
[Settings]
Text = <SBS Windows 2000 Code Wizard Project>
Company = <MyCompany>
Author = <MyName>
Email = <my@email>
Prefix = <MyPrefix>
Include = E:\NTDDK\inc
Free = E:\NTDDK\libfre\i386
Checked = E:\NTDDK\libchk\i386
Root = HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Directories\WorkspaceDir
示例 3-1. 向导支持的自定义选项
运行驱动向导
现在,来试试这个驱动向导。 示例 3-2 给出了在 Windows 2000 控制台下执行 w2k_wiz *TestDrv 后的输出。这将在 Visual C/C++ 默认的工程根目录下创建一个名为 TestDrv 的工程目录。

显然,除了将 .td 模板转换为 .def 时出了错,其余转换都成功的完成了。因为该向导生成的驱动程序骨架不需要 .def 文件,所以不需要提供 .td 模板文件。现在,用 Visual C/C++ 打开一个新的 WorkSpace ,然后你会发现一个名为 TestDrv 的新目录,该目录中包含一个名为 TestDrv.dsw 的 WorkSpace 文件。该文件可以被正确的打开。接下来,你因该为生成项目选择活动的配置信息。驱动向导生成的 .dsp 文件提供了如下两个可用配置:
1. Win2k Kernel-mode Driver(debug)
2. Win2k Kernel-mode Driver(release)
默认情况下,将使用 debug 配置来生成项目,但是你可在任何时候从 Visual C/C++ 菜单 Build/Set Active Configuration 来选择不同的项目配置。最后,你要将光盘中的 \src\common\include\DrvInfo.h 复制到你自己的头文件目录中。在打开 TestDrv.rc 时,应使用文本模式来打开(如 图 3-3 所示),这是因为该文件使用了来自 DrvInfo.h 中的复杂的宏定义,这些宏会导致资源编辑器异常退出。这个错误从 Visual C/C++ 5.0 开始,在我印象中,一直没有被改正过。和编辑器不同,资源编译器( Resource Compiler )可以正常的处理这些宏。

图 3-3. 以文本模式打开 TestDrv.c 、 TestDrv.h 和 TestDrv.rc
现在,已经为第一次编译做好了所有准备。在示例 3-3 中,我通过选择 Build/Rebuild 菜单来建立 Driver 的 Release 版,看起来一切都正常。顺便说一下,头两行末尾的省略号表示我截断了 Build 命令的输出。
链接器会在 Debug 或 Release 目录下创建了一个名为 TestDrv.sys 的可执行文件,这依赖于你的生成配置。 Test Driver 的 Release 版大小为 5.5KB ,其 Debug 版为 8KB 。你可以使用本书光盘中的 MFVDasm 或 PEView 来验证 TestDrv.sys 是否包含有效的代码和数据。

上一页 [1] [2] [3] 下一页 |