http://huapingjiang.blogcn.com/diary,9089662.shtml
Window Driver 安装 |
Windows driver安装 关于setup class Windows driver的安装是比较复杂的,需要写很多注册表的参数。有些参数是在inf文件里设定,有些是Windows安装程序默认帮你写到注册表里面的。卸载的时候同样也必须卸载掉注册表中driver相关信息。 Inf文件里面一个非常重要的GUID是安装类GUIID(setup class GUID)。它跟driver中定义的GUID,称为接口GUID(Interface GUID)。Interface GUID是driver提供给application,使得application可以跟driver通信。而Setup class GUID是表示设备所属的类的,比如你的设备是USB设备类的,或者modem类的。例如我写了一个modem driver,在它的inf文件里我要指定它的setup class GUID是4D36E96D-E325-11CE-BFC1-08002BE10318,这样modem driver安装以后就会在HLM/SYSTEM/CurrentControlSet/Control/Class/4D36E96D-E325-11CE-BFC1-08002BE10318下面看到modem driver的一个子建,里面记录虚拟的COM口,moden的初始化命令,inf文件的path等等信息。有些时候卸载不完全,这里就会有残留的记录。多次安装过驱动程序,或者安装过很多版本的的驱动,有些时候新版本的驱动就安装不上了。这时就需要去这里看看有没有残留。 我就有一次遇到了问题,设备插上去之后发现安装不上,设备管理器里面就是没有响应(因为我做了class coinstall,所以不会弹出发现新硬件的对话框),发现里面有很多版本的驱动的残留,我清除了这些之后,驱动就可以安装了。
关于Co-installer 对co-installer的认识是从一个老外那里开始的,他是一个senior engineer。当时我们的设备是一个多接口的USB设备,所以会出现多个新设备的安装。为了简化安装过程,需要写一个coinstaller,原来我们打算安装DDK里面关于co-installer的说明来写的。后来证明不能那样做。我们就写了一个application来把所有需要的sys文件和inf文件复制到system目录下,inf文件还做了转化。因为Windows如果在注册表中找不到驱动信息,先回去system目录下搜索驱动的pnf文件(inf文件的二进制表示)。 这样我们的application就起作用了,安装起来就比较方便。Application执行完之后只要插上设备就可以了,但是由于我们的driver没过WHQL认证,所以在WINDOW 2K下面OK,而在WINDOWS XP下面不行。 由于Windows XP在发现没有认证过的驱动之后,在弹出“发现新硬件”之前,会依次调用class co-installer和device co-installer,而且会把SP_DRVINFO_DATA结构里面的Rank值指定为非0(通过认证它的值是0),后来我们就写了一个class co-installer来修改Rank的值为0。相关处理代码如下: case DIF_SELECTBESTCOMPATDRV: DbgOut("DIF_SELECTBESTCOMPATDRV"); if (DeviceInfoData) { SP_DRVINFO_DATA sDrvInfoData; DWORD MemberIndex = 0; BOOL bRet = FALSE; memset((void*)&sDrvInfoData, 0, sizeof(SP_DRVINFO_DATA)); sDrvInfoData.cbSize = sizeof(SP_DRVINFO_DATA); bRet = SetupDiEnumDriverInfo(DeviceInfoSet, DeviceInfoData, SPDIT_COMPATDRIVER, MemberIndex++, &sDrvInfoData); if (bRet) { SP_DRVINSTALL_PARAMS sDrvInstallParams; memset((void*)&sDrvInstallParams, 0, sizeof(SP_DRVINSTALL_PARAMS)); sDrvInstallParams.cbSize = sizeof(SP_DRVINSTALL_PARAMS); OutputDebugString(sDrvInfoData.Description); SetupDiGetDriverInstallParams(DeviceInfoSet, DeviceInfoData, &sDrvInfoData, &sDrvInstallParams); sDrvInstallParams.Rank = 0; SetupDiSetDriverInstallParams(DeviceInfoSet, DeviceInfoData, &sDrvInfoData, &sDrvInstallParams); } } else {DbgOut("DeviceInfoData is null!"); } break;
|