第十五章.驱动程序的安装
方便的,自动的和容易的安装一个设备驱动程序对于用户来说是一个重要的步骤。对于提供给用户容易的设备管理的即插即用驱动程序, 安装程序是最基本的。 安装一个驱动程序 一个后缀是INF的文本文件控制设备驱动程序自动的安装。INF格式类似于WIN 3.x下的老式的.INI文件,但是复杂些。一个INF文件允许自动的或者在对话框的帮助下安装驱动程序文件。 驱动程序安装结束后对系统产生两个持久的影响: 1. 描述驱动程序的系统注册表入口,它的加载顺序和任何适当的配置数据。 2. 驱动程序文件被拷贝到适当的系统路径。 INF文件是影响这些改变的标准的机制,它可以提供定制安装。 使用INF文件自动安装 INF文件随着硬件和驱动程序一起提供,INF文件的结构和内容是驱动程序作者的责任。 INF文件结构 INF文件是被分(section)成几个部分的文本文件,每个部分被指定一个标识符号﹐它被中括号([])括起来﹒一些部分的命名是必须的﹐而其它部分是驱动程序特定的﹒每个部分是一些安装动作﹐或者连接或者列举其它部分﹒ 文件中各个部分的顺序是不重要的﹐因为每个部分都是被命名和连接的﹒一个部分继续直到另一个部分或者遇到文件结束﹒每个部分的标识符号是独一无二的名字﹐为了保持与WIN98的兼容﹐它的长度被限制在28个字符之内﹐可以包含下划线和圆点字符﹐在引用整个名字的前提下﹐可以包含空格字符﹒ 文件内容的一般格式如下: entry = value [, value...] entry是指令﹐关键词或者文件名﹐value是entry被应用的属性﹒ 图15.1. INF文件各部分的连接 entry或者value名字可以指定为一个使用百分号(%)的代替一些具体数据的字符串﹐分割INF文件的[Strings]提供一个特殊语言ID的值﹒ Version 部分 一个有效的INF文件从一个命名为[Version]的部分开始﹐它像一个INF文件的头和标识﹒
Entry | Value |
Signature | “$Windows NT$" "$Windows 95$" "$Chicago$"的其中一个 |
Class | 驱动程序的整个家族的类名﹒一些名字是预先确定的﹐例如﹐Net或者Display |
ClassGuid | 一个类的独一无二的GUID |
Provider | INF文件提供者的名字 |
LayoutFile | 只有在系统支持的INF文件中使用﹐OEM支持的INF文件用SourceDisksNames 和 SourceDisksFiles代替 |
DriverVer | mm/dd/yyyy[,x,y,v,z],必须的条目﹐包含可选的版本信息 |
Entry | Value |
DriverVer | mm/dd/yyyy[,x,y,v,z]﹐必须的条目﹐包含可选择的版本号码 |
CopyFiles | 另一个指定需要复制的文件列表的部分或者一个单独的有”@”为前缀的文件名 |
AddReg | 必须的﹐另一个包含需要的注册表信息的部分 |
Include | 指向其它的INF文件名指针列表 |
Needs | Include条目的子集﹐列出了它的INF文件中需要的部分 |
DelFiles | 指定另一个需要删除的文件列表的部分(一般是升级的目的) |
RenFiles | 指定另一个需要重命名的文件列表的部分(一般是存储安装之前的状态) |
DelReg | 指定另一个需要删除的系统注册表信息的部分 |
ProfileItems | 指定另一个需要更改系统开始菜单的部分 |
二进制值 | 符号名 | 描述 |
0x0400 | COPYFLG_REPLACEONLY | 如果已经有目标文件﹐则复制 |
0x0800 | COPYFLG_NODECOMP | 不解压﹐直接复制 |
0x0008 | COPYFLG_FORCE_FILE_IN_USE | 复制源文件为临时的名字﹐强制重新激活﹐ 重命名临时文件 |
0x0010 | COPYFLG_NO_OVERWRITE | 不替换已存在的文件 |
0x1000 | COPYFLG_REPLACE_BOOT_FILE | 文件是系统加载的一部分﹐强制重新激活 |
0x2000 | COPYFLG_NOPRUNE | 强制复制﹐甚至安装者认为不需要 |
0x0020 | COPYFLG_NO_VERSION_DIALOG | 不重写更新的文件 |
0x0004 | COPYFLG_NOVERSIONCHECK | 总是重写目标文件 |
0x0040 | COPYFLG_OVERWRITE_ OLDER_ONLY | 重写老的目标文件 |
0x0001 | COPYFLG_WARN_IF_SKIP | 如果用户跳过文件﹐则警告 |
0x0002 | COPYFLG_NOSKIP | 不允许用户跳过文件 |
缩写 | 意义 |
HKCR | HKEY_CLASSES_ROOT |
HKCU | HKEY_CURRENT_USER |
HKLM | HKEY_LOCAL_MACHINE |
HKU | HKEY_USERS |
HKR | 设备安装的硬件子键 |
二进制值 | 符号 | 意义 |
0x00000 | FLG_ADDREG_TYPE_SZ | 以零为结束的字符串 |
0x00001 | FLG_ADDREG_BINVALUETYPE | 二进制数据 |
0x00002 | FLG_ADDREG_NOCLOBBER | 不替换现有的值 |
0x00004 | FLG_ADDREG_DELVALUE | 删除子键或者值的名字 |
0x00010 | FLG_ADDREG_KEYONLY | 创建子键﹐不顾值 |
0x00020 | FLG_ADDREG_OVERWRITEONLY | 如果值存在﹐替换它﹐否则什幺也不作 |
0x10000 | FLG_ADDREG_TYPE_MULTI_SZ | REG_MULTI_SZ值(数组) |
0x00008 | FLG_ADDREG_APPEND | 附加到存在的REG_MULTI_SZ数组 |
0x20000 | FLG_ADDREG_TYPE_EXPAND_SZ | REG_EXPAND_SZ数据 |
0x10001 | FLG_ADDREG_TYPE_DWORD | DWORD值 |
0x20001 | FLG_ADDREG_TYPE_NONE | REG_NONE值 |
值 | 意义 |
12 | %windir%\system32\drivers 对于 Windows 2000 %windir%\system\IoSubsys 对于 Windows 98 |
10 | %windir% |
11 | %windir%\system32 对于 Windows 2000﹐ %windir%\system对于 Windows 98 |
30 | 根驱动器的根路径 |
54 | Windows 2000的根路径 |
01 | 这个INF文件的路径 |
17 | INF文件的路径 |
20 | Fonts的路径 |
51 | 假脱机的路径 |
52 | 假脱机的驱动程序路径 |
55 | 打印机处理机路径 |
23 | Color (ICM) |
-1 | 绝对路径 |
21 | Viewers路径 |
53 | User Profile路径 |
24 | 应用软件路径 |
25 | 共享路径 |
18 | 帮助路径 |
16406 | All Users\Start Menu |
16407 | All Users\Start Menu\Programs |
16408 | All Users\Start Menu\Programs\Startup |
16409 | All Users\Desktop |
16415 | All Users\Favorites |
16419 | All Users\Application Data |
16422 | Program Files |
16427 | Program Files\Common |
16429 | All Users\Templates |
16430 | All Users\Documents |
二进制值 | 符号名 | 意义 |
0x0002 | ASSOCSERVICE | 驱动程序是一个FDO﹐不是滤波驱动程序 |
0x0008 | NOCLOBBER_DISPLAYNAME | 不重写friendly名字 |
0x0100 | NOCLOBBER_DESCRIPTION | 不重写Description |
0x0010 | NOCLOBBER_STARTTYPE | 不重写starttype |
0x0020 | NOCLOBBER_ERRORCONTROL | 不重写错误控制 |
条目 | 值 |
DisplayName | 驱动程序的Friendly名字﹐显示在设备管理器中 |
Description | 简短的描述驱动程序或者服务的目的﹐显示在设备管理器中 |
ServiceType | 驱动程序类型: 0x01 -内核驱动程序﹐0x02 -文件系统驱动程序 |
StartType | 何时驱动程序加载: 0 -引导时﹐1 -系统开始时 2 -系统开始后自动加载﹐3 -需要时手动﹐4 -禁止使用 |
ErrorControl | 驱动程序加载时错误部署: 0 -忽视所有错误﹐1 -显示错误给用户﹐ 2 -使用最后的良好状态重新激活﹐忽视错误﹐ 3 -使用最后的良好状态重新激活﹐调试错误 |
ServiceBinary | 驱动程序的全路径名﹐可能包含dirid值 |
;Copyfiles=BULKUSB.Files.Ext, BULKUSB.Files.Inf
;AddReg=BULKUSB.AddReg [Manufacturer] ; 普通的安装软件的.INF文件中,不包括[Manufacturer] 与[Manufacturer Name] 节,
;即使包含,也不会执行它们,这2 个节仅仅 用于硬件的设备驱动中起作用 。W2KDriverBook=MyMfgName ; 唤起model部 [MyMfgName] ; 开始一个Models部分 "ISA Missile Launcher"=InstallLauncher,ISA\Launcher ; 我们的设备列表 ; "ISA Missile Launcher"表对要安装的设备的描述,如果此设备被安装,那么此名字是出现在设备管理器中的名字 ; InstallLauncher是此设备的安装节点 ;,ISA\Launcher 是指设备ID [InstallLauncher] ; 开始DDInstall 部分 CopyFiles=CopyLaunchFiles ; 唤起CopyFiles 部分. CopyFiles=CopyLaunchHelp ; 另一个是help的 AddReg=LaunchRegSection ; 唤起AddReg 部分 [CopyLaunchFiles] ; 开始CopyFiles部分 Launcher.sys [CopyLaunchHelp] ; Help文件的CopyFiles部分 Launcher.hlp [LaunchRegSection] ; 开始AddReg 部分 HKR,"Parameters","Coordinates",FLG_ADDREG_TYPE_DWORD,0 ; 给设备提供一个是0的DWORD值 [SourceDisksNames] ; 这个部分不是真的需要﹐ 1="Missile Launcher Driver Files" ; 因为只有两个文件并且在同一个磁盘上 [SourceDisksFiles] Launcher.sys=1 ; 类似的﹐因为它们在同一个磁盘上﹐ Launcher.hlp=1 ;所以不是真正的需要这个部分 [InstallLauncher.Services] ; DDInstall.Services部分 AddService=Launcher,2,LaunchService [LaunchService] ; 设置SCM﹐这样驱动程序就可以运行了 ServiceType=1 ; 驱动程序 StartType=3 ; 需要时手动加载 ErrorControl=1 ; 汇报错误 ServiceBinary=%12%\Launcher.sys ; 驱动程序路径 使用INF文件 一旦驱动程序的INF创建完成﹐必须处理它﹐使它有用﹒ 手动安装 手动的处理INF文件﹐必须使用Windows的文件管理器选择INF文件﹐右击这个文件﹐选择安装﹒ 在真正的即插即用环境中﹐插入或者移除设备触发相应的驱动程序的安装﹐加载和卸载﹒因此﹐保留手动的安装是为了最初的测试和调试驱动程序﹒ 自动安装 当一个即插即用的设备被插入到一个系统﹐数个子系统相互作用来加载新的驱动程序﹒ 1. 当设备被插入﹐硬件使用自动侦测和自动配置﹐告诉总线驱动程序设备出现﹒依赖于总线硬件﹐这可能涉及通知总线驱动程序一个新的总线设备列举发生﹒在这一步的最后﹐驱动程序发现新的设备出现并且有一个指定的设备ID﹒ 2. 内核模式PnP管理器通知用户模式PnP管理器一个新的有一个指定ID的设备出现在系统中﹒ 3. 用户模式PnP管理器使用WIN2000的Setup API库为新的设备提供一个类似的驱动程序列表﹒为了合适的驱动程序﹐系统使用新设备的class和model查找系统的INF目录(例如﹐WINNT\INF)﹒ 4. 如果不能找到合适的INF文件﹐系统不进行进一步的动作直到一个有特权的用户进入系统﹒用户被提供一个新的硬件向导﹒用户提供驱动程序的位置和合适的INF文件位置﹒ 5. 一旦找到INF文件﹐它被使用CfgMgr API库处理﹒驱动程序文件和注册表条目被安装和修改﹒内核模式的PnP管理器主要执行这个步骤﹒ 6. 基于INF文件的指导﹐内核模式PnP管理器加载任何低层的滤波驱动程序﹐然后是functional驱动程序﹐最后是高层的驱动程序﹒在堆栈中的高层的驱动程序然后发送适当的PnP信息﹐包括IRP_MN_START_DEVICE. 添加/移除硬件向导 在安装过程中﹐主要的与用户的交互是添加新硬件向导﹒注意有一个制造商的列表(来自于INF文件的[Manufacturers]部分)﹐和Models列表(来自于INF文件的[Models]部分)﹒ 通常﹐用户手动选择适当的驱动程序去安装和加载﹒如果驱动程序被安装﹐它的DriverEntry和AddDevice例程必须仍然有效﹐这样使请求驱动的硬件满意新代码的设置﹒换句话说﹐手动的选择可能成功的安装﹐但是初始化是失败的﹒ Class名字和设备IDs 即插即用设备自动安装的过程很大程度上依赖安装程序的 定位合适驱动程序的INF文件和文件中各个部分的能力 ﹒这个部分文章的目的是解释Class名字和设备Ids﹐还有定位INF文件的过程﹒ 每个即插即用设备应该有一个 唯一的指定硬件模型的标识符号 ﹒因此提供设备ID给即插即用总线硬件和总线驱动程序﹒当然﹐总线驱动程序在新的设备被插入后的很短时间内请求设备ID﹒设备ID的形式与总线类型有关﹒但是﹐一般看起来是: <enumerator>\<enumerator-specific-device-ID> (例如﹐PCI\VEN_1000&DEV_0001&SUBSYS_00000000&REV_02) 对于驱动程序代码﹐ 一个硬件设备可能汇报多个设备ID ﹐ 它是设备功能上的与很多models兼容的陈述﹒因为INF文件的[Models]部分包含一个hw-id值 ﹐所以﹐寻找与新安装的设备返回的设备ID相匹配的INF文件中的条目非常简单﹒同样的INF条目允许相兼容硬件的列表的规范有附加的设备Ids形式﹒如果设备ID不能在INF文件中定位精确的匹配﹐就使用兼容的ID﹒ 另一个为设备定位合适的驱动程序的关键元素是 安装类(Setup Class) 的观念﹒一系列相关的设备可以共享分层的驱动程序 (例如﹐upper或者lower滤波器)﹐甚至在堆栈中个别的驱动程序﹒安装类被GUID 和name唯一的标识﹒微软定义了一系列驱动程序类﹐新的类可能被定义新的硬件组﹒创建新的组之前﹐必须选择一个新的GUID和class名字﹒
类名 | 意义 | GUID |
1394 | 1394火线控制器 | {6bdd1fc1-810f-11d0-bec7-08002be2092f} |
Battery | 电池设备 | {72631e54-78a4-11d0-bcf7-00aa00b7b32a} |
CDROM | CD-ROM设备 | {4d36e965-e325-11ce-bfc1-08002be10318} |
DiskDrive | 磁盘设备 | {4d36e967-e325-11ce-bfc1-08002be10318} |
Display | 显示适配器 | {4d36e968-e325-11ce-bfc1-08002be10318} |
FloppyDisk | 软盘控制器 | {4d36e980-e325-11ce-bfc1-08002be10318} |
HDC | 硬盘控制器 | {4d36e96a-e325-11ce-bfc1-08002be10318} |
HIDClass | 人性化的输入设备 | {745a17a0-74d3-11d0-b6fe-00a0c90f57da} |
Image | 成像设备 | {6bdd1fc6-810f-11d0-bec7-08002be2092f} |
Infrared | IrDA设备 | {6bdd1fc5-810f-11d0-bec7-08002be2092f} |
Keyboard | 键盘 | {4d36e96b-e325-11ce-bfc1-08002be10318} |
MTD | 存储器技术驱动程序 | {4d36e970-e325-11ce-bfc1-08002be10318} |
Media | 多媒体设备 | {4d36e96c-e325-11ce-bfc1-08002be10318} |
Modem | 调制解调器 | {4d36e96d-e325-11ce-bfc1-08002be10318} |
Monitor | 监视器 | {4d36e96e-e325-11ce-bfc1-08002be10318} |
Mouse | 鼠标器 | {4d36e96f-e325-11ce-bfc1-08002be10318} |
Multifunction | 多功能设备 | {4d36e971-e325-11ce-bfc1-08002be10318} |
Network | 网络适配器 | {4d36e972-e325-11ce-bfc1-08002be10318} |
NetClient | 网络客户机 | {4d36e973-e325-11ce-bfc1-08002be10318} |
NetService | 网络服务器 | {4d36e974-e325-11ce-bfc1-08002be10318} |
NetTrans | 网络传输 | {4d36e975-e325-11ce-bfc1-08002be10318} |
PCMCIA | PCMCIA适配器 | {4d36e977-e325-11ce-bfc1-08002be10318} |
Ports | 端口(COM & LPT) | {4d36e978-e325-11ce-bfc1-08002be10318} |
Printer | 打印机设备 | {4d36e979-e325-11ce-bfc1-08002be10318} |
Volume | 存储卷 | {71a27cdd-812a-11d0-bec7-08002be2092f} |
System | 系统设备 | {4d36e97d-e325-11ce-bfc1-08002be10318} |
USB | USB | {36fc9e60-c465-11cf-8056-444553540000} |
2, 注册表
INF文件中的内容会在注册表中有所体现
硬件子键
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/{设备管理器该设备属性的详细信息}
类子键
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{GUID}
服务子键
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/{Driver名称}
3, 安装流程
Step 1
Step 2
Step 3
Step 4
Step 5
注 * 从磁盘安装
Step 6
Step 7
Step 8
Step 9
安装完成
Step 10
在设备管理器中查看
Step 11
查看属性
4, 给出一个已经编译好的驱动(包括INF文件,符号文件和源代码)
代码就是《驱动开发技术详解》光盘中第一章的代码。
可以使用WinDBG和VMWare进行简单的调试练习。
关于WinDBG的使用会在下一篇Blog中描述。
来自CSDN网站chenyujing1234博客