在开发Windows平台上的驱动程序之前,必须先安装DDK(Device Development Kit,设备开发工具包),目前DDK最新版本同时支持WDM与WDF两种架构。
为了大量减轻驱动程序开发人员的负担,微软公司不断地改进驱动程序的开发软件与架构,从早期复杂深晦的VxD,到Windows XP上的WDM(Windows Driver Model,Windows驱动程序模型)开发架构,如今WDF(Windows Driver Foundation,Windows驱动程序基础)已成为新一代的Windows平台驱动程序发展架构,这个架构大量简化了驱动程序的开发流程,更符合面向对象的精神,此架构包含了User Mode Driver Framework(用户模式驱动程序框架)与Kernel Mode DriverFramework(内核模式驱动程序框架)两种开发模式。
1.DDK安装
(1)Windows 98 DDK的安装
这一部分描述安装Windows98 DDK的方法。约定%98DDK%为安装的Windows 98 DDK的根目录;%MSTOOLS%为微软SDK平台的根目录;%VCPPDEV%为安装的VC++的根目录开发环境。
使用DDK的软件平台通常为Windows98操作系统和VisualC++各版本,若要编译视频捕获,则需要VC++5.0以上版本。在安装Windows 98 DDK之前,必须先安装VC++编译器/开发环境,否则运行时,Windows98DDK的Setenv.bat批处理文件将不能建立正确的环境。安装DDK资料需要IE4.01或以上版本,如果是从光盘或测试驱动程序则需要光驱,16MB内存是不可少的,完整安装需要82MB硬盘容量。
包括Windows98DDK在内的所有例子驱动程序都不需要在安装的SDK平台下构造。不过,如果开发自己的驱动程序,可能需要的不是Windows98DDK中的头文件,而是SDK平台中的头文件,因此可以考虑两种方法:复制所需的头文件或SDK平台的文件到%98DDK%和%VCPPDEV%下适当的Include目录中;也可以直接安装SDK平台,在%98DDK%\BIN中编辑Setenv.bat文件,并运行安装在%MSTOOLS%里的Setenv.bat文件。
用Setup程序安装DDK,步骤为:
1)运行Windows98DDK中的SETUP.EXE文件,安装Windows98DDK到C:\98DDK。
2)安装VC++5.0到C:\VCPPDEV。
3)修改CONFIG.SYS增大环境变量空间。在CONFIG.SYS文件最后加入一行:
SHELL=C:\WINDOWS\COMMAND.COM/E:4096/P
在安装Windows 98 DDK之前,必须先安装VC++编译器/开发环境,否则运行时,Windows98 DDK的Setenv.bat批处理文件将不能建立正确的环境。
(2)Windows 95 DDK的安装
安装Windows 95 DDK一般需要先安装Win32SDK,因为Windows95DDK需要Win32 SDK的16位资源编译器。但是Win32 SDK很大(一整张光盘的容量),而且国内难以买到,下面介绍一种安装Win-dows95DDK的简单方法:
1)修改注册表,仿真Win32 SDK已经安装的情况。建立一个名为WIN32SDK.REG的注册表文件,内容为:
REGEDIT4
[HKEY_USERS\.Default\Software\Microsoft\Win32SDK]
[HKEY_USERS\.Default\Software\Microsoft\Win32SDK\Directories]
"InstallDir"="C:\MSTOOLS"
在资源管理器中双击此文件,将此文件中的内容添加到注册表。就可以安装Windows 95 DDK了。
2)运行Windows 95 DDK中的SETUP.EXE文件,安装Windows95 DDK到C:\DDK。
3)安装MASM6.11到C:\MASM611。安装完成后再将未安装的Windows 95 DDK中的MASM611C目录下的文件覆盖到C:\MASM611\BIN。
4)安装VC++5.0到C:\Program Files\DevStudio\VC。
5)建立C:\MSTOOLS\BINW16目录,复制资源编译器。
Windows 95 DDK需要一个能将Win32资源的源文件编译成16位资源的资源编译器。如果有Win32SDK,可以将BINW16目录下的文件直接复制到C:\MSTOOLS\BINW16;如果没有Win32 SDK,则可以使用第三方的资源编译器,这里以使用Borland的资源编译器为例:
首先准备一套Turbo MASM 5.0,用UNPAK工具解压缩CMDLINE.PAK文件,找到下面三个文件:BRC.EXE、BRCC32.EXE、RW32CORE.DLL。将这三个文件复制到C:\MSTOOLS\BINW16,并将BRC.EXE改名为RC.EXE即可。
6)修改CONFIG.SYS增大环境变量空间。在CONFIG.SYS文件最后加入一行:
SHELL=C:\WINDOWS\COMMAND.COM/E:8192/P
7)进入Windows95的MS-DOS方式,初始化编译环境,最好建立一个批处理文件DDKSET-UP.BAT,内容编辑为:
setSDKROOT=C:\95SDK
call new-vars.bat(MASM611的环境)
call ddkenv.bat(DDK的环境)
call vcvars32.bat(VC++的环境)
C:\MASM611\BINR\NEW-VARS.BAT
C:\DDK\DDKINIT.BAT32BASE
C:\Program Files\DevStudio\VC\bin\VCV ARS32.BAT
编辑好之后就可以使用Windows 95 DDK了,连接时出现的警告可以不理会。
有的DDK里面没有DDKENV.bat的批处理,如果DDK是CD版的,注意保存DDK自带的DDK-ENV.bat,否则需要自建。DDKENV.bat内容如下:
set DDKROOT=e:\95ddk
set INCLUDE=%INCLUDE%;%DDKROOT%\INC32;%DDKROOT%\INC16
set LIB=%LIB%;%DDKROOT%\LIB
(3)NTDDK的安装
需要准备下列软件:Win32 SDK或者PLATFORM SDK、NT DDK、VC++5.0。具体安装步骤如下:
1)安装Win32SDK或者PLATFORM SDK到C:\MSTOOLS。
2)如果是安装PLATFORMSDK,安装完成后请修改注册表:HKEY_CURRENT_USER\Environ-ment,添加一个“MSTOOLS”字符串,值为C:\MSTOOLS。
3)安装VC++5.0。
4)安装NTDDK到C:\NTDDK。
2.构造环境
下面以Windows 98驱动程序构造环境为例介绍建立WDM驱动程序构造环境的方法。
(1)用SETENV.bat来安装驱动程序构造环境
创建一个名为“Development Kits\Windows 98 DDK”的程序目录。这个目录包括自由构造环境项和检查构造环境项。每次重启操作系统,在构造驱动程序前,单击这些程序文件夹中合适的一项。这些项调用%98DDK%\BIN里的Setenv.bat批处理文件来创建正确的环境变量的驱动程序构造环境。
(2)手工运行SETENV.bat
在MS-DOS提示符下,或在“开始/运行”中使用下列语句:
setenv%98DDK%[free|checked]
例如,在C:\98ddk\bin>提示符下,键入setenvC:\98ddkfree,其中第一个参数指定DDK被安装的文件夹,注意就默认的安装来说,目的地是\98ddk;可选的第二个参数说明目标构造环境,默认类型是free。(www.xing528.com)
(3)构造WDM驱动程序
使用一套规则以指定驱动程序怎样被创建,所构造的实用程序可用来在Windows 98和Windows NT上建造WDM驱动程序平台。
在Windows98DDK被安装之后,WDM驱动程序构造树的工作例子和组成部分文件在硬盘上就可以得到了。驱动程序构造树根目录在%98DDK%\src。查看%98DDK%\inc里Makefile.def文件的内容,以及贯穿驱动程序构造树的各种的Dirs文件和源文件的内容,可以利用这些代码作为工作实例。
(4)构造驱动程序
在当前目录的驱动程序构造树中创建一个子目录,然后运行构造实用程序。在构造树的当前目录中,构造实用程序可以自动创建出驱动程序的源代码。构造实用程序在Windows98DDK例子驱动程序构造树的根目录下(%98DDK%\src)运行。例如,如果仅仅对为声音设备类构造的例子驱动程序有兴趣,可以设置当前目录到%98DDK%\src\audio上,然后运行构造实用程序。
(5)检查Windows 98 DDK的安装
经常使用的构造指令形式为build-cZ,从而使构造实用程序做相关文件的扫描,执行完整的创建,并生成错误记录。
检查安装的方法为:在\<destination>\src目录运行build-cZ,构造安装的例子驱动程序源代码的完整集。这个实用程序在构造驱动程序之前构造全部相关文件,自动建立文件关联关系。如果构造没有完成或报告过多的编译错误,则需要确认是否正确执行了以上的安装步骤。
3.设计开发
(1)Windows 3.x驱动程序
随着计算机硬件的快速发展,功能强大的Microsoft Windows得到越来越广泛的应用,软件环境由Windows替代DOS是大势所趋。增强模式的虚拟设备驱动程序文件VxD(.386文件)是人们能够编写的最强大的Windows应用程序,但却它是Windows编程中一个艰难且高度专业化的分支,而且一般用户应用程序独享自制外部设备硬件资源。Windows 3.x采用非抢先式多任务消息驱动运行机制,所以Win-dows下如何解决实时高速数据采集问题,便显得非常重要。Windows3.x应用程序虽然可以运行在保护模式下,享有多于1MB的内存,但它并未脱离实模式的DOS。在实时获取和控制系统中,为快速响应外界变化而编写DOS设备驱动程序是简单而有效的选择。显而易见,必须解决实模式的DOS设备驱动程序与保护模式的Windows进程之间的通信问题。
利用Windows提供的DPMI(DOS保护模式接口)功能,以及内核函数GlobalDosAlloc(),就可以实现由DOS设备驱动程序直接访问Windows应用程序动态申请的缓冲区的目的。这个函数可以分配既能够被Windows应用程序存取,也能被DOS设备驱动程序访问的内存块。
Windows3.x通常运行于386增强模式,亦即对应着DOS环境下的保护模式。在增强模式下,由于增加了虚拟内存管理,由描述符表(GDT和LDT)得到的线性地址与物理地址之间并没有必然的联系。它们之间只有一种类似于表格的对应关系,所以需要利用DOS保护模式接口(DPMI)来完成这项工作。
所谓DPMI,是由Microsoft、Intel、IBM等多家公司联合建立的一种约定,它规定了一组服务程序,并可以在保护模式下使用INT31h来调用它们。这些服务程序的提供者(如Windows3.1)被称为DPMI服务(Server)程序;而这些服务程序的使用者(如保护模式下的DOS扩展程序)被称为客户(Cli- ent)程序。在同一个程序里,当需要由保护模式访问实模式的驱动程序或者TSR程序时,除了DPMI之外,别无选择。
在DOS提示符下运行DOSDRV.EXE程序,从而完成将被WINCOMM.EXE调用的设备驱动程序的安装。一旦Windows被加载,即可运行Wincomm.exe程序以实现通信。
利用Windows内核函数GlobalDosAlloc()所获得的内存对于Windows虚拟机来说是局部的,因此其他的虚拟机不能够访问该段内存。这种方法作为DOS设备驱动程序与Windows应用程序之间进行通信的一种模式,如经稍加改进,可以实现多个Windows进程共同拥有一个DOS设备驱动程序,而相互之间互不干扰。当然也可以实现Windows进程之间的通信。
(2)Windows95/98/Me驱动程序
Windows3.x和Windows 9x使用共同的设备驱动程序模型,而WindowsNT却使用另一种新的模型,这两种模型之间不兼容。
对Windows3.x/9x来说实际上有两种驱动程序。在Windows3.x下,驱动程序通常以.386为扩展名,在Windows启动时装入,在Windows 9x下,它通常以.VXD为扩展名,它可以在系统启动时装入,也可以动态装入。虚拟设备驱动程序(VxDs)运行于特权级,它可以看做是操作系统的一个DLL,因为运行在特权级,所以它可以直接访问硬件,也可以直接访问DOS、Windows或保护模型应用程序的地址空间。
Windows 9x使用的结构和Windows 3.x下使用的结构一样,因此在Windows3.x下的驱动程序可以在Windows9x下使用。但是Windows9x加入了上百条新的功能(服务),并对VxD的结构加以扩展使之可以动态装入,具有可分页的代码和数据,可以访问系统注册表等功能。在Windows9x下编写的驱动程序不能用于Windows3.x系统下。除了VxDs外,Windows3.x/9x还支持非特权级(3级)通信和打印机驱动程序,这些驱动程序一般以.DRV扩展名结束。
虚拟设备驱动程序被简称为VxD。x代表各种设备的名字,如虚拟键盘驱动程序(vkd)、虚拟鼠标驱动程序(vmd)等。VxD程序是硬件成功初始化的途径。记得DOS程序认为它们拥有系统的一切,当它们在虚拟机中运行时,Windows需要给它们一个实机器的替身。VxD程序就是这些替身。VxD程序通常虚拟一些硬件设备,所以,例如当一个DOS程序认为它在同键盘通信时,实际是虚拟键盘驱动程序在和DOS程序通信。一个VxD程序通常控制真正的硬件设备并对该设备在各个虚拟机之间的共享进行管理。尽管如此,并不是说每个VxD程序必须和一个硬件设备相连。虽然VxD程序是用来虚拟硬件设备的,但是也可以把VxD程序看作是在第0级别的dll。例如,如果你需要做一些只有在第0级别才能做的工作,你就可以编一个VxD程序来为你完成这个工作。这样,由于此VxD程序并没有虚拟任何设备,你就可以把它仅仅看做是你的程序的扩展。
VxD程序是Windows9x特有的,它在WindowsNT下不能运行。所以如果某程序是依靠VxD的,它就不能被移植到WindowsNT平台上去。
VxD是系统中权力最大的实体。由于它们可以对系统做任何事情,所以它们是极度危险的。一个恶意的/错误的VxD程序可以毁掉整个系统。对于恶意的/错误的VxD程序没有任何的保护措施。
Windows9x下有静态VxD和动态VxD。静态VxD是那些从系统启动就被加载,在系统关闭之前一直存在于内存中的VxD程序。这种VxD可以追溯至Windows3.x的时代。动态VxD时只有Windows9x下才有的。动态VxD程序可以在需要时被加载/卸载。这些程序大多数都是用来控制设置管理器和输入输出监视器加载的即插即用设备的。可以在win32应用程序里加载或卸载动态VxD程序。
(3)WindowsNT/2000/XP/Vista/7驱动程序
WindowsNT使用新的驱动程序体系结构,这种结构称为“内核模型驱动程序”,VxDs与Windows NT不兼容。为了在WindowsNT和Windows 95/3.x系统之间提供兼容性,Microsoft提供了“微端口驱动程序”。微端口可以使开发者使用在WindowsNT和Windows 9x/3.x系统上都提供的接口编写驱动程序。Microsoft为SCSI、打印机和显示设备提供微端口驱动程序。
Windows NT的驱动一般都是.sys文件类型,Windows 2000可以兼容WindowsNT驱动,但一般不能在Windows 9x下使用。
如果都要支持Windows 9x和WindowsNT,需要编写两类驱动程序。
4.编译安装
(1)编译
安装DDK后,在DDK程序组下有Check和Free两个编译环境,Check环境用于编译带调试信息的驱动程序,Free则是编译正式发布版本的环境。通常情况下设备驱动程序的编译采用命令行的方式。通过一定的设置可以在VC++的集成环境下编译。
编译的基本步骤:
1)首先进入check或free编译环境,初始化DDK编译环境。
2)运行VC安装目录下bin目录下的vcvars32.bat,初始化VC++编译环境。
3)运行Build.exe进行编译。
一般来说,成功编译一个最基本的设备驱动程序需要四个文件,第一个是驱动程序,即C语言源程序文件(例如vdisk.c,注意下面所有的例子都是以vdisk来说明);第二个是RC文件(例如vdisk.rc);第三个是sources文件;第四个文件是makefile.rc文件。sources文件和make文件类似,用来指定需要编译的文件以及需要连接的库文件。这三个辅助文件都很简单,在DDKsamples的每个例程里都有三个这样的文件,依样画瓢就能理解它们的结构和意义。
(2)安装
下面以WindowsNT的驱动程序为例说明其安装的过程。
首先添加注册表中的键值。WindowsNT在引导时,通过扫描注册表构造驱动程序列表。这个列表既包括自启动的驱动程序,也包括需要手工启动的驱动程序。这个列表其实就是控制面板中设备Applet所列出来的所有设备。所有的设备驱动程序应该在注册表的HKEY_LOCAL_MACHINE\System\Cur-rentControlSet\Services\下有相应的键值。下面以vdisk为例来说明如何添加键值。首先在HKEY_LO-CAL_MACHINE\System\CurrentControlSet\Services\下添加一个子项vdisk,注意这里的名称应该和驱动程序名称一致,例如驱动程序名称是vdisk.sys,那么这里的子项名称就是vdisk。然后在vdisk下添加表7-7所示键值。
表7-7 vdisk键值
注:1.type值为1表示内核模式驱动程序;为2表示文件系统驱动程序。
2.errorcontrol值为0表示日志记录错误并忽略;值为1表示日志记录错误并显示一个对话框;值为2表示日志记录错误,并用最后的正确配置重新启动;值为3表示日志记录错误,如果已经使用过正确配置,返回失败。
在任何一个设备驱动程序中,表7-7中的前三项参数都是必需的。
然后控制驱动程序的装入次序。有时候控制多个驱动程序的装入次序是必要的。例如一套驱动程序中包括三个驱动程序,分别是jbChanger.sys、changerDisk.sys和vdisk.sys。jbChanger和changerDisk是两个SCSI类驱动程序,它们都依赖SCSI小端口(miniport驱动程序),同时changerDisk必须在jbChanger启动之后启动。vdisk是虚拟的磁盘驱动程序,它必须在jbChanger和changerDisk都启动之后才能启动成功。
接着定义驱动程序的start值。上面注册表中驱动程序的start值控制驱动程序在系统启动的时间。目前,start可以取以下值,此外为该值留有扩展余地,以适用于新的要求:
1)0x0(SERVICE_BOOT_START):该值指定本驱动程序应该由操作系统装入程序启动。一般的驱动程序不会采用本值,因为系统在这个时候几乎还没有启动,大部分系统尚不可用。
2)0x1(SERVICE_SYSTEM_START):该值表示在操作系统装入后但同时初始化它自己时启动驱动程序。
3)0x2(SERVICE_AUTO_START):该值表示在整个系统启动并运行后由服务控制管理器装入。
4)0x3(SERVICE_DEMAND_START):该值表示该驱动程序必须手工启动。可以通过控制面板的设备applet或者使用WIN32API编程来启动。
5)0x4(SERVICE_DISABLED):表示本驱动程序被禁用。
注意在调试驱动程序时,最好将start值设置为3以手工启动,这是因为如果设置为自动启动,而驱动程序在启动的过程中又发生了异常错误,则可能导致系统不能启动。
第四步是修改注册表。在注册表里这些值可以手工修改,也可以自己编程利用WIN32API进行添加,同时也可以用ini文件的方式来添加。在注册表里添加好这些项后,必须重新启动系统,这样所添加的设备驱动程序才能在控制面板的设备applet中列出来,再进行其他操作。
最后是启动设备驱动程序。在添加修改好注册表后,重新启动系统,如果选择的start值是0、1、2,若一切正常,驱动程序就应该已经启动起来了。可以观察控制面板的设备applet中的设备列表。如果选择的start值是3,则可以直接启动。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。