Window Driver 安装

来源:互联网 发布:旭旭宝宝 知乎 编辑:程序博客网 时间:2024/05/29 13:10

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,称为接口GUIDInterface GUID)。Interface GUIDdriver提供给application,使得application可以跟driver通信。而Setup class GUID是表示设备所属的类的,比如你的设备是USB设备类的,或者modem类的。例如我写了一个modem driver,在它的inf文件里我要指定它的setup class GUID4D36E96D-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-installerdevice 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;