发布时间:2014-6-11 14:52
分类名称:Driver
当一个设备插入到计算机总线后,总线驱动检测到设备插入,然后给设备分配一串硬件ID(hardware identifier (ID))。
例如,插入一个USB Key插入到电脑后,分配的硬件ID为:
USB\VID_096E&PID_0807&REV_0100
USB\VID_096E&PID_0807
Windows就靠此ID来寻找最优的那个驱动安装包。
硬件ID的格式如下:
Hardware ID
A hardware ID is a vendor-defined identification string that Windows uses to match a device to an INF file. In most cases, a device has associated with it a list of hardware IDs. (However, there are exceptions ? see Identifiers for 1394 Devices). When an enumerator reports a list of hardware IDs for a device, the hardware IDs should be listed in order of decreasing suitability.
通过MSND中的解释可以了解到:硬件ID是一组ID值,如上面例子中的两列字符串。
Device ID
A device ID is a string reported by a device's enumerator. A device has only one device ID. A device ID has the same format as a hardware ID.
设备ID不是一组ID值,只有一个唯一ID值,他唯一标识了此类设备,设备ID和硬件ID的格式一样,硬件ID中最能严格定义此类设备的ID值就为设备ID。如上面两条ID值中,第一条能更加准确的定义此类设备,所以第一条也叫设备ID。
Compatible ID
A compatible ID is a vendor-defined identification string that Windows uses to match a device to an INF file. A device can have associated with it a list of compatible IDs. The compatible IDs should be listed in order of decreasing suitability. If Windows cannot locate an INF file that matches one of a device's hardware IDs, it uses compatible IDs to locate an INF file. Compatible IDs have the same format as hardware IDs. However, compatible IDs are typically more generic than hardware IDs.
关于设备ID,硬件ID,兼容ID等概念,可以参考MSDN:http://msdn.microsoft.com/EN-US/library/windows/hardware/ff541224(v=vs.85).aspx,或者《竹林蹊径:深入浅出Windows驱动开发》中的第十二章。这里不需要深入了解。
在设备管理器中,可以浏览硬件ID:
可以看到,硬件ID不只一个,它是一组ID,其中,最严格定义了该类设备的ID也被称作设备ID。如上图中,第一个条USB\VID_096E&PID_0807&REV_100为设备ID。
第一步得到硬件IDs,Windows开始搜索驱动安装包。这节解决几个问题:
每个驱动安装包中,都有一个INF文件,此文件记录了厂商定义的设备信息等内容。以某个厂商的智能卡私有驱动为例,其INF片段如下:
[Manufacturer]
%MFGNAME1%=DeviceListMfg1,NTamd64
[DeviceListMfg1.NTamd64]
%USB\VID_08E6&PID_3437.DeviceDesc% =DriverInstall64, USB\VID_08E6&PID_3437 ;
%USB\VID_08E6&PID_3438.DeviceDesc% =DriverInstall64, USB\VID_08E6&PID_3438 ;
%USB\VID_08E6&PID_3480.DeviceDesc% =DriverInstall64, USB\VID_08E6&PID_3480 ;
%USB\VID_08E6&PID_34EC.DeviceDesc% =DriverInstall64, USB\VID_08E6&PID_34EC ;
可以看到[DeviceListMfg1.NTamd64]中,定义了每个产品的VID,PID信息,诸如:USB\VID_08E6&PID_3437,就是厂商自己定义的硬件ID,Windows搜索INF这个区域,对比第一步得到的硬件IDs和INF中的硬件ID,如果能精确匹配,那说明此驱动包符合安装条件。
我们接着分析微软的通用智能卡驱动是如何实现的,我们知道,微软不可能知道我们的设备的硬件ID信息,也就说,在INF中,不能将全世界厂商的硬件ID全部记录在INF文件中。所以,微软引入了兼容ID(compatible ID)。兼容ID和硬件ID的格式一样,但它更加通用,能囊括一大类设备。它被厂商定义在INF文件中。如果Windows没有找到对应的硬件ID,它会去比对INF中的兼容ID,找到对应的驱动安装包。
以微软XP的CCID驱动为例,usbccid.inf中的片段:
[Manufacturer]
%CCID%=CCID,NTamd64
[CCID.NTamd64]
%USBCCID.DeviceDesc% = USBCCID.Install,USB\Class_0B&SubClass_00
此处的USB\Class_0B&SubClass_00,就是兼容ID,在设备管理器中也能显示兼容ID:
Windows搜索INF文件的位置,是按照一定规则来执行的,不同的操作系统,搜索顺序会有所不同:
Search phase | Windows Server 2003, Windows XP, and Windows 2000 | Windows Vista and | Windows 7 and later versions of Windows |
Without user interaction | DevicePath | Windows Update DevicePath | |
With user interaction | Prompt for distribution media Windows Update | DevicePath Windows Update Prompt for distribution media | Not applicable |
DevicePath对应的路径存储在注册里:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion下,定义了DevicePath字符串键值。通常,对应的目录为 Windows\inf。
Driver store在Vista以后,对应的路径为:Windows\System32\DriverStore\FileRepository。Vista以前的系统,路径为:Windows\Driver Cache。从Vista以后的系统,系统开始重用Driver Store,如果找到一个匹配的驱动包,第一步就是先把这个安装包拷贝到Driver Store中,然后安装过程在Driver Store中进行。
下面举例说明:
当前系统如果为Vista,当一个用户插入一个智能卡到USB hub中时:
选择联机搜索,Windows搜索顺序如下:
当前系统如果为Win7,当一个用户插入一个智能卡到USB hub中时:
Win7不会自动运行安装向导来让用户选择驱动包,但这个向导仍然存在,在设备管理器中,选择未识别的设备,右键,选择更新驱动,同样能够达到安装的目的。
搜索完成后,可能会有多个驱动包匹配成功,如不同版本号的驱动都匹配成功了。如何进一步筛选,选出最优驱动包?
如何给驱动打分,有一套规则,规则比较复杂,打分在vista之前和vista之后会有所不同,可以参考MSDN:http://msdn.microsoft.com/EN-US/library/ff686700(v=VS.85,d=hv.2).aspx
这里大致说明一下,影响分值有几个因素:
下面摘自《竹林蹊径:深入浅出Windows驱动开发》一个解释片段:
选择好了驱动,就开始安装驱动了,安装驱动的步骤如下: