流驱动是如何加载的?(收集于CSDN论坛)

  以前看很多教科书,都只是说流驱动是通过device.exe来加载的,但是具体是怎么加载,注册表的几要素到底有什么作用我一无所知,刚才在论坛看到一些眉目,现在收集下来,造福you and me。同时感谢songtitan

 

songtitan引用楼主 wangxin_801115 的帖子:
在CE下电源管理 MDD层代码中:
  电池驱动对外接口函数没有“BAT_”前缀,因为HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Battery/Flags注册表项设置了DEVFLAGS_NAKEDENTRIES属性,表示“Init”代替“BAT_Init”,这样修改注册表“Prefix”项的值时不需要修改驱动代码。

[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Battery]
"Prefix"="BAT"
"Dll"="battdrvr.dll"
"Flags"=dword:8                      ; DEVFLAGS_NAKEDENTRIES…

所有的流式驱动都是XXX_Init...其中XXX必须在注册表中定义,这样device.exe才会根据注册表的prefix值去load制定dll并call其中的Prefix+Init函数。
但是,当用DEVFLAGS_NAKEDENTRIES时,说明将使用未修饰的入口点名称,即自己定义的接口函数。这样的话,device.exe就不会按照之前的Prefix+Init的方式了,就是Init。

还是代码说明问题:
D:/WINCE500/PRIVATE/WINCEOS/COREOS/DEVICE/DEVCORE/devload.c中的CreateDevice函数中有如下判断:

if((dwFlags & DEVFLAGS_NAKEDENTRIES) == 0) {
                if(lpszPrefix[0] != 0) {
                    DEBUGCHK(lpszBusPrefix[0] == 0 || wcsicmp(lpszBusPrefix, lpszPrefix) == 0);
                    pEffType = lpszPrefix;      // use standard prefix decoration
                } else if(lpszBusPrefix[0] != 0 && lpdev->pszBusName != NULL) {
                    pEffType = lpszBusPrefix;  // no standard prefix, use bus prefix decoration
                } else {
                    if(lpdev->pszDeviceName != NULL) {
                        // device is expected to have a device or bus name, but we don't know
                        // how to look for its entry points
                        DEBUGMSG(ZONE_ACTIVE || ZONE_ERROR,
                            (_T("DEVICE!CreateDevice: no entry point information for '%s' can't load '%s'/r/n"),
                            lpszLib, lpdev->pszDeviceName));
                        dwStatus = ERROR_INVALID_FUNCTION;
                    }
                }
            }
           
            lpdev->fnInit = (pInitFn)GetDMProcAddr(pEffType,L"Init",lpdev->hLib);
            lpdev->fnPreDeinit = (pDeinitFn)GetDMProcAddr(pEffType,L"PreDeinit",lpdev->hLib);
            lpdev->fnDeinit = (pDeinitFn)GetDMProcAddr(pEffType,L"Deinit",lpdev->hLib);
            lpdev->fnOpen = (pOpenFn)GetDMProcAddr(pEffType,L"Open",lpdev->hLib);
            lpdev->fnPreClose = (pCloseFn)GetDMProcAddr(pEffType,L"PreClose",lpdev->hLib);
            lpdev->fnClose = (pCloseFn)GetDMProcAddr(pEffType,L"Close",lpdev->hLib);
            lpdev->fnRead = (pReadFn)GetDMProcAddr(pEffType,L"Read",lpdev->hLib);
            lpdev->fnWrite = (pWriteFn)GetDMProcAddr(pEffType,L"Write",lpdev->hLib);
            lpdev->fnSeek = (pSeekFn)GetDMProcAddr(pEffType,L"Seek",lpdev->hLib);
            lpdev->fnControl = (pControlFn)GetDMProcAddr(pEffType,L"IOControl",lpdev->hLib);
            lpdev->fnPowerup = (pPowerupFn)GetDMProcAddr(pEffType,L"PowerUp",lpdev->hLib);
            lpdev->fnPowerdn = (pPowerupFn)GetDMProcAddr(pEffType,L"PowerDown",lpdev->hLib);

 

又查了一下MSDN和代码,只说明可以使用不加前缀的入口函数,即
当DEVFLAGS_NAKEDENTRIES 时,pEffType = NULL;
所以下面这些函数都会直接call Init...而不是Prefix_Init
自己定义接口函数应该不行。

        lpdev->fnInit = (pInitFn)GetDMProcAddr(pEffType,L"Init",lpdev->hLib);
            lpdev->fnPreDeinit = (pDeinitFn)GetDMProcAddr(pEffType,L"PreDeinit",lpdev->hLib);
            lpdev->fnDeinit = (pDeinitFn)GetDMProcAddr(pEffType,L"Deinit",lpdev->hLib);
            lpdev->fnOpen = (pOpenFn)GetDMProcAddr(pEffType,L"Open",lpdev->hLib);
            lpdev->fnPreClose = (pCloseFn)GetDMProcAddr(pEffType,L"PreClose",lpdev->hLib);
            lpdev->fnClose = (pCloseFn)GetDMProcAddr(pEffType,L"Close",lpdev->hLib);
            lpdev->fnRead = (pReadFn)GetDMProcAddr(pEffType,L"Read",lpdev->hLib);
            lpdev->fnWrite = (pWriteFn)GetDMProcAddr(pEffType,L"Write",lpdev->hLib);
            lpdev->fnSeek = (pSeekFn)GetDMProcAddr(pEffType,L"Seek",lpdev->hLib);
            lpdev->fnControl = (pControlFn)GetDMProcAddr(pEffType,L"IOControl",lpdev->hLib);
            lpdev->fnPowerup = (pPowerupFn)GetDMProcAddr(pEffType,L"PowerUp",lpdev->hLib);
            lpdev->fnPowerdn = (pPowerupFn)GetDMProcAddr(pEffType,L"PowerDown",lpdev->hLib);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值