CE5.0关于设备管理器的源码分析(偶很懒!)

[复制链接]
2787|4
 楼主| high 发表于 2007-11-22 02:48 | 显示全部楼层 |阅读模式
原来认真写**是多么辛苦的事啊!佩服老hot那么高产...<br />大家有空请指正.<br />----------<br /><br />系统下面许多设备,比如键盘,串口,触摸屏,硬盘......这些设备什么时候被系统使用的?这些设备怎样被系统使用的?加载过程是怎么样的?设备如何加入系统协同工作的?为什么系统能检测到并使用即插即用的设备(如usb鼠标)?系统是怎么控制设备的电源的?<br /><br />CE管理设备的程序叫做DEVICE.EXE,这是一个独立的用户级进程,它主要负责跟踪,维护系统的设备信息并对设备资源进行调配.设备管理器包括即插即用设备管理,电源管理,io资源管理等等.<br /><br />结构示意图:<br /><br /><br />目录树:c:\WINCE500\PRIVATE\WINCEOS\COREOS\DEVICE\<br /><br />[DEVCORE]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;设备管理器的核心代码部分.<br />Devapi.c<br />Devcore.c<br />Devfile.c<br />Devfsd.c<br />Devload.c<br />De***p.c<br />Celogdev.h<br />[DEVMAIN]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;程序入口点.<br />devmain.c<br />[INC]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;头文件<br />Devmgrif.h<br />Devmgrp.h<br />Devzones.h<br />Iormif.h<br />Pmif.h<br />[IORM]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;io资源管理<br />Iorm.c<br />[NOPMIF]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;电源管理模块接口(这里是不要电源管理模块的'空'接口)<br />Nopmif.c<br />[PMIF]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;电源管理模块接口<br />Pmif.c<br /><br /><br />源码分析:(按照先后执行顺序来分析源代码.)<br /><br />在[DEVMAIN]中有一个devmain.c的代码,这是device.exe的入口点.如同标准c的main()函数所在,因为是windows所以入口点是WinMain()这样的函数.在WinMain()内没有其他内容,只调用了StartDeviceManager()这个函数.<br />int&nbsp;WINAPI&nbsp;WinMain(HINSTANCE&nbsp;hInst,&nbsp;HINSTANCE&nbsp;hPrevInst,&nbsp;LPWSTR&nbsp;lpCmdLine,&nbsp;int&nbsp;nCmdShow)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;status;<br />&nbsp;&nbsp;&nbsp;&nbsp;status&nbsp;=&nbsp;StartDeviceManager(hInst,&nbsp;hPrevInst,&nbsp;lpCmdLine,&nbsp;nCmdShow);<br />&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;status;<br />}<br /><br /><br /><br />前面WinMain()调用的StartDeviceManager()函数位于devcore.c.&nbsp;这个函数初始化设备管理器,电源管理器,IO资源管理,然后启动设备管理器,开始负责设备驱动的加载和卸载工作.<br /><br />int&nbsp;WINAPI&nbsp;<br />StartDeviceManager(HINSTANCE&nbsp;hInst,&nbsp;HINSTANCE&nbsp;hPrevInst,&nbsp;LPWSTR&nbsp;lpCmdLine,&nbsp;int&nbsp;nCmShow)<br />{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;HINSTANCE&nbsp;hCeddkDll;<br />&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hEvent;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(IsAPIReady(SH_DEVMGR_APIS))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;DEBUGREGISTER(NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_BOOTSEQ,&nbsp;(TEXT(&quot;DEVICE:&nbsp;Starting&nbsp;boot&nbsp;phase&nbsp;1\n&quot;)));<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;PHASE&nbsp;1<br />&nbsp;&nbsp;&nbsp;&nbsp;g_BootPhase&nbsp;=&nbsp;1;&nbsp;//用一个全局变量来表示现在处于启动的哪个阶段.一共有3个阶段.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;0表示还没有开始启动;1表示在搜索注册表的值;2表示在加载设备;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;3表示已经开始正常运行了.<br />&nbsp;&nbsp;&nbsp;&nbsp;InitOOMSettings();&nbsp;//&nbsp;初始化OOM.<br />&nbsp;&nbsp;&nbsp;&nbsp;InitializeListHead(&g_DevChain);&nbsp;&nbsp;//&nbsp;初始化常规状态设备列表<br />&nbsp;&nbsp;&nbsp;&nbsp;InitializeListHead(&g_ActivatingDevs);&nbsp;//&nbsp;初始化激活的已经注册的设备列表<br />&nbsp;&nbsp;&nbsp;&nbsp;InitializeListHead(&g_DyingDevs);&nbsp;//&nbsp;初始化消亡状态的设备列表<br />&nbsp;&nbsp;&nbsp;&nbsp;InitializeListHead(&g_CandidateDevs);&nbsp;//&nbsp;初始化正在加载的设备驱动列表.<br />&nbsp;&nbsp;&nbsp;&nbsp;g_hCleanEvt&nbsp;=&nbsp;CreateEvent(NULL,&nbsp;FALSE,&nbsp;FALSE,&nbsp;NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;g_hDevApiHandle&nbsp;=&nbsp;CreateAPISet(&quot;WFLD&quot;,&nbsp;NUM_FDEV_APIS,&nbsp;FDevApiMethods,&nbsp;FDevApiSigs);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;向系统注册api<br />&nbsp;&nbsp;&nbsp;&nbsp;g_hDevFileApiHandle&nbsp;=&nbsp;CreateAPISet(&quot;W32D&quot;,&nbsp;NUM_FAPIS,&nbsp;DevFileApiMethods,&nbsp;DevFileApiSigs);&nbsp;//&nbsp;向系统注册api<br />&nbsp;&nbsp;&nbsp;&nbsp;RegisterAPISet(g_hDevFileApiHandle,&nbsp;HT_FILE&nbsp;|&nbsp;REGISTER_APISET_TYPE);<br />&nbsp;&nbsp;&nbsp;&nbsp;InitializePnPNotifications();&nbsp;//&nbsp;这个程序将调用StartDeviceNotifyThread()<br />//&nbsp;这将启动一个线程.它的具体实现在de***p.c文件中.<br />&nbsp;&nbsp;&nbsp;&nbsp;InitializeCriticalSection(&g_devcs);&nbsp;//&nbsp;初始化临界区.<br />&nbsp;&nbsp;&nbsp;&nbsp;ResourceInitModule();&nbsp;//&nbsp;初始化一个全局变量gdwMaxDenseResources<br />//&nbsp;根据注册表来初始化设备管理资源&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;ResourceInitFromRegistry(TEXT(&quot;Drivers\\Resources&quot;));<br /><br />SetPowerOffHandler((FARPROC)&nbsp;DevMgrPowerOffHandler);<br />&nbsp;&nbsp;&nbsp;&nbsp;RegisterAPISet(g_hDevApiHandle,&nbsp;SH_DEVMGR_APIS);<br />&nbsp;&nbsp;&nbsp;&nbsp;InitDeviceFilesystems();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Indicate&nbsp;that&nbsp;the&nbsp;device&nbsp;manager&nbsp;is&nbsp;up&nbsp;and&nbsp;running<br />&nbsp;&nbsp;&nbsp;&nbsp;hEvent&nbsp;=&nbsp;OpenEvent(EVENT_ALL_ACCESS,&nbsp;FALSE,&nbsp;_T(&quot;SYSTEM/DevMgrApiSetReady&quot;));<br />&nbsp;&nbsp;&nbsp;&nbsp;DEBUGCHK(hEvent&nbsp;!=&nbsp;NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(hEvent&nbsp;!=&nbsp;NULL)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetEvent(hEvent);&nbsp;&nbsp;//&nbsp;设置一个全局事件.通知别的程序设备管理器api已经准备好了.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;在其他的应用里面,使用设备管理器api前,如果希望确认设备管理器<br />&nbsp;&nbsp;&nbsp;//&nbsp;的api已经注册好,它会等待这样一个事件.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hEvent);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Calibrate&nbsp;stall&nbsp;counter&nbsp;that&nbsp;is&nbsp;used&nbsp;for&nbsp;StallExecution<br />//&nbsp;以下代码调用ceddk.dll里面的fnCalibrateStall()函数.<br />&nbsp;&nbsp;&nbsp;&nbsp;hCeddkDll&nbsp;=&nbsp;LoadLibrary&nbsp;(TEXT(&quot;ceddk.dll&quot;));<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(NULL&nbsp;!=&nbsp;hCeddkDll)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pCalibrateStallFn&nbsp;fnCalibrateStall&nbsp;=&nbsp;(pCalibrateStallFn)\<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetProcAddress(hCeddkDll,&nbsp;TEXT(&quot;CalibrateStallCounter&quot;));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!fnCalibrateStall)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_BOOTSEQ,&nbsp;&nbsp;(L&quot;GetProcAddress&nbsp;failed&nbsp;on&nbsp;ceddk.dll\r\n&quot;));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeLibrary(hCeddkDll);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fnCalibrateStall();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Call&nbsp;the&nbsp;power&nbsp;manager&nbsp;initialization&nbsp;entry&nbsp;point<br />&nbsp;&nbsp;&nbsp;&nbsp;PM_Init();&nbsp;//&nbsp;初始化电源管理模块.电源管理模块是一个pm.dll.它也被device.exe调用.这里&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;暂时不打算涉及电源管理部分.简单来说:在PM_Init()函数里面会启动3个线程,<br />//&nbsp;PnpThreadProc,ResumeThreadProc,&nbsp;ActivityTimersThreadProc<br />//&nbsp;它们各自负责监控即插即用,Resume,和激活定时器<br />&nbsp;&nbsp;&nbsp;&nbsp;PM_SetSystemPowerState(NULL,&nbsp;POWER_STATE_ON,&nbsp;POWER_FORCE);//设置系统电源开.<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;See&nbsp;if&nbsp;we&nbsp;are&nbsp;going&nbsp;to&nbsp;have&nbsp;two&nbsp;boot&nbsp;phases<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;根据注册表内容,决定采用怎样的加载过程.<br />//&nbsp;如果存在SYSTEM/BootPhase1.分2个步骤来加载:<br />//&nbsp;先DevloadInit()加载一次,然后等待通知后,继续调用InitDevice()加载.<br />//&nbsp;如果没有SYSTEM/BootPhase1,则调用DevloadInit()一次完成.<br />//&nbsp;也许是满足一些需要2次加载设备的情况,所以留下这个功能.<br />&nbsp;&nbsp;&nbsp;&nbsp;hEvent&nbsp;=&nbsp;OpenEvent(EVENT_ALL_ACCESS,&nbsp;FALSE,&nbsp;_T(&quot;SYSTEM/BootPhase1&quot;));<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(hEvent&nbsp;!=&nbsp;NULL)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Load&nbsp;phase&nbsp;1&nbsp;drivers&nbsp;from&nbsp;the&nbsp;boot&nbsp;registry<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DevloadInit();&nbsp;//&nbsp;加载设备.DevloadInit()函数位于devload.c,它首先删除注册表里面<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Device\Active,然后调用InitDevices()函数加载设备驱动.<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Signal&nbsp;boot&nbsp;phase&nbsp;1&nbsp;complete<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetEvent(hEvent);&nbsp;//&nbsp;发出通知,阶段1已经完成.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hEvent);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Wait&nbsp;for&nbsp;phase&nbsp;2&nbsp;of&nbsp;the&nbsp;boot&nbsp;to&nbsp;begin<br />//&nbsp;等待通知后进入阶段2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hEvent&nbsp;=&nbsp;OpenEvent(EVENT_ALL_ACCESS,&nbsp;FALSE,&nbsp;TEXT(&quot;SYSTEM/BootPhase2&quot;));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEBUGCHK(hEvent);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(hEvent)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_BOOTSEQ,&nbsp;(TEXT(&quot;DEVICE:&nbsp;Started,&nbsp;waiting&nbsp;for&nbsp;boot&nbsp;phase&nbsp;2\r\n&quot;)));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WaitForSingleObject(hEvent,&nbsp;INFINITE);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hEvent);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Load&nbsp;any&nbsp;new&nbsp;drivers&nbsp;from&nbsp;the&nbsp;persistent&nbsp;registry.&nbsp;&nbsp;Since&nbsp;the&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;registry&nbsp;may&nbsp;have&nbsp;changed,&nbsp;update&nbsp;the&nbsp;power&nbsp;state&nbsp;for&nbsp;any&nbsp;devices<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;that&nbsp;need&nbsp;it.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_BOOTSEQ,&nbsp;(TEXT(&quot;DEVICE:&nbsp;Second-phase&nbsp;driver&nbsp;load\r\n&quot;)));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_BootPhase&nbsp;=&nbsp;2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PM_SetSystemPowerState(NULL,&nbsp;POWER_STATE_ON,&nbsp;POWER_FORCE);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InitDevices(NULL);&nbsp;//&nbsp;DevInit()加载会先清空注册表Acitve下的内容,<br />&nbsp;&nbsp;&nbsp;//&nbsp;第二次加载不能把前面一次的清空,所以这里不能用DevInit().<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_BOOTSEQ,&nbsp;(TEXT(&quot;DEVICE:&nbsp;Startup&nbsp;sequence&nbsp;complete\r\n&quot;)));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SignalStartedUsingReg();&nbsp;//&nbsp;SignalStarted&nbsp;call&nbsp;with&nbsp;the&nbsp;right&nbsp;args<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_BOOTSEQ,&nbsp;(TEXT(&quot;DEVICE:&nbsp;No&nbsp;boot&nbsp;registry&nbsp;-&nbsp;skipping&nbsp;to&nbsp;boot&nbsp;phase&nbsp;2\n&quot;)));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_BootPhase&nbsp;=&nbsp;2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DevloadInit();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SignalStarted(_wtol(lpCmdLine));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Boot&nbsp;phase&nbsp;3&nbsp;isn't&nbsp;any&nbsp;different&nbsp;from&nbsp;phase&nbsp;2;&nbsp;just&nbsp;marks&nbsp;that&nbsp;we&nbsp;got&nbsp;here.<br />&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_BOOTSEQ,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(TEXT(&quot;DEVICE:&nbsp;Finished&nbsp;loading&nbsp;primary&nbsp;drivers&nbsp;-&nbsp;entering&nbsp;boot&nbsp;phase&nbsp;3\n&quot;)));<br />&nbsp;&nbsp;&nbsp;&nbsp;g_BootPhase&nbsp;=&nbsp;3;&nbsp;//&nbsp;进入阶段3,同时也标志设备管理器开始运行了.<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;CELOG_DeviceFinished&nbsp;();&nbsp;//&nbsp;记录日志.<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(1)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WaitForSingleObject(g_hCleanEvt,&nbsp;INFINITE);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;check&nbsp;for&nbsp;auto-deregister&nbsp;devs&nbsp;first&nbsp;as&nbsp;they&nbsp;may&nbsp;end&nbsp;up&nbsp;queuing&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;themselves&nbsp;on&nbsp;the&nbsp;dying&nbsp;devs&nbsp;list<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessAutoDeregisterDevs();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessDyingDevs();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessDyingOpens();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;should&nbsp;not&nbsp;ever&nbsp;be&nbsp;reached<br />}<br /><br /><br /><br />加载设备的函数,DevloadInit()事实上也是调用InitDevices来实现,只不过事先清空了Acitve下的注册表内容<br /><br />void&nbsp;DevloadInit(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_INIT,&nbsp;(TEXT(&quot;DEVICE!DevloadInit\r\n&quot;)));<br />#define&nbsp;PHASE_1_BUSNAME&nbsp;TEXT(&quot;BuiltInPhase1&quot;)<br />&nbsp;&nbsp;&nbsp;&nbsp;//<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Delete&nbsp;the&nbsp;HLM\Drivers\Active&nbsp;key&nbsp;since&nbsp;there&nbsp;are&nbsp;no&nbsp;active&nbsp;devices&nbsp;at<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;init&nbsp;time.<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;清空注册表Active下的内容.<br />&nbsp;&nbsp;&nbsp;&nbsp;RegDeleteKey(HKEY_LOCAL_MACHINE,&nbsp;s_ActiveKey);<br /><br />#ifdef&nbsp;DEBUG<br />&nbsp;&nbsp;&nbsp;&nbsp;v_NextDeviceNum&nbsp;=&nbsp;0xFFFFFFF0;&nbsp;&nbsp;&nbsp;//&nbsp;expect&nbsp;wraparound<br />#else&nbsp;&nbsp;&nbsp;//&nbsp;DEBUG<br />&nbsp;&nbsp;&nbsp;&nbsp;v_NextDeviceNum&nbsp;=&nbsp;1;<br />#endif&nbsp;&nbsp;//&nbsp;DEBUG<br />&nbsp;&nbsp;&nbsp;&nbsp;g_bSystemInitd&nbsp;=&nbsp;FALSE;<br />&nbsp;&nbsp;&nbsp;&nbsp;InitDevices(PHASE_1_BUSNAME);<br />}<br /><br /><br /><br />InitDevices(LPCTSTR&nbsp;lpBusName&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;HKEY&nbsp;RootKey;<br />&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;status;<br />&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;ValType;<br />&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;ValLen;<br />&nbsp;&nbsp;&nbsp;&nbsp;TCHAR&nbsp;RootKeyPath[REG_PATH_LEN];<br />&nbsp;&nbsp;&nbsp;&nbsp;TCHAR&nbsp;BusName[DEVKEY_LEN];<br />&nbsp;&nbsp;&nbsp;&nbsp;REGINI&nbsp;reg[1];<br />&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;dwRegCount=0;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Open&nbsp;HLM\Drivers&nbsp;key<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;打开注册表HLM\Drivers.<br />&nbsp;&nbsp;&nbsp;&nbsp;status&nbsp;=&nbsp;RegOpenKeyEx(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HKEY_LOCAL_MACHINE,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEVLOAD_DRIVERS_KEY,&nbsp;//&nbsp;&nbsp;DEVLOAD_DRIVERS_KEY=&nbsp;&quot;Drivers&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&RootKey);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(status&nbsp;!=&nbsp;ERROR_SUCCESS)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(ZONE_ROOT|ZONE_ERROR,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(TEXT(&quot;DEVICE!InitDevices&nbsp;RegOpenKeyEx(%s)&nbsp;returned&nbsp;%d.\r\n&quot;),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEVLOAD_DRIVERS_KEY,&nbsp;status));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Look&nbsp;for&nbsp;root&nbsp;key&nbsp;value;&nbsp;if&nbsp;not&nbsp;found&nbsp;use&nbsp;current&nbsp;Root&nbsp;Key&nbsp;as&nbsp;default,<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;otherwise&nbsp;open&nbsp;new&nbsp;root&nbsp;key<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;查询注册表中&nbsp;RootKey的值,一般这个值是Devices\BuildIn.将查询的值保存到RootKeyPath.<br />//&nbsp;如果没有指定,则使用Devices来替代.<br />&nbsp;&nbsp;&nbsp;&nbsp;ValLen&nbsp;=&nbsp;sizeof(RootKeyPath);<br />&nbsp;&nbsp;&nbsp;&nbsp;status&nbsp;=&nbsp;RegQueryValueEx(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RootKey,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEVLOAD_ROOTKEY_VALNAME,&nbsp;//&nbsp;&nbsp;DEVLOAD_ROOTKEY_VALNAME&nbsp;=RootKey<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&ValType,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(PUCHAR)RootKeyPath,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&ValLen);<br />&nbsp;&nbsp;&nbsp;&nbsp;RootKeyPath[ARRAYSIZE(RootKeyPath)&nbsp;-&nbsp;1]&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(status&nbsp;!=&nbsp;ERROR_SUCCESS)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Root&nbsp;key&nbsp;value&nbsp;not&nbsp;found,&nbsp;thus&nbsp;root&nbsp;key&nbsp;is&nbsp;Drivers<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tcscpy(RootKeyPath,&nbsp;DEVLOAD_DRIVERS_KEY);&nbsp;//&nbsp;没有找到,使用Devices来替代.<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Close&nbsp;previous&nbsp;root&nbsp;key<br />&nbsp;&nbsp;&nbsp;&nbsp;RegCloseKey(RootKey);<br />&nbsp;&nbsp;&nbsp;&nbsp;DEBUGMSG(1,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(L&quot;DEVICE!InitDevices:&nbsp;Root&nbsp;Key&nbsp;is&nbsp;%s.\r\n&quot;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RootKeyPath));<br />//&nbsp;为ActiveDeviceEx准备参数reg.&nbsp;如果输入参数lpBusName指定了,则从参数lpBusName获得,<br />//&nbsp;否则从注册表中读取.<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(lpBusName!=NULL)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg[0].lpszVal&nbsp;=&nbsp;DEVLOAD_BUSNAME_VALNAME;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg[0].dwType&nbsp;&nbsp;=&nbsp;DEVLOAD_BUSNAME_VALTYPE;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg[0].pData&nbsp;&nbsp;&nbsp;=&nbsp;(PBYTE)&nbsp;lpBusName&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg[0].dwLen&nbsp;&nbsp;&nbsp;=&nbsp;(_tcslen(&nbsp;lpBusName&nbsp;)&nbsp;+&nbsp;1)&nbsp;*&nbsp;sizeof(TCHAR);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwRegCount&nbsp;=&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status&nbsp;=&nbsp;RegOpenKeyEx(&nbsp;HKEY_LOCAL_MACHINE,&nbsp;RootKeyPath,0,0,&nbsp;&RootKey);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(status&nbsp;==&nbsp;ERROR_SUCCESS&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValLen&nbsp;=&nbsp;sizeof(&nbsp;BusName);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status&nbsp;=&nbsp;RegQueryValueEx(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RootKey,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEVLOAD_BUSNAME_VALNAME,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&ValType,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(PUCHAR)BusName,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&ValLen);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(status&nbsp;==&nbsp;ERROR_SUCCESS&nbsp;&&&nbsp;ValType==DEVLOAD_BUSNAME_VALTYPE)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;We&nbsp;found&nbsp;Bus&nbsp;Name.&nbsp;This&nbsp;is&nbsp;new&nbsp;bus&nbsp;driver&nbsp;model.&nbsp;So&nbsp;we&nbsp;use&nbsp;new&nbsp;format.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BusName[DEVKEY_LEN-1]&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg[0].lpszVal&nbsp;=&nbsp;DEVLOAD_BUSNAME_VALNAME;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg[0].dwType&nbsp;&nbsp;=&nbsp;DEVLOAD_BUSNAME_VALTYPE;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg[0].pData&nbsp;&nbsp;&nbsp;=&nbsp;(PBYTE)BusName;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg[0].dwLen&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;ValLen;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwRegCount&nbsp;=&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Close&nbsp;previous&nbsp;root&nbsp;key<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RegCloseKey(RootKey);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Someday&nbsp;we'll&nbsp;want&nbsp;to&nbsp;track&nbsp;the&nbsp;handle&nbsp;returned&nbsp;by&nbsp;ActivateDevice&nbsp;so&nbsp;that<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;we&nbsp;can&nbsp;potentially&nbsp;deactivate&nbsp;it&nbsp;later.&nbsp;But&nbsp;since&nbsp;this&nbsp;code&nbsp;refers&nbsp;only&nbsp;to<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;builtin&nbsp;(ie,&nbsp;static)&nbsp;devices,&nbsp;we&nbsp;can&nbsp;just&nbsp;throw&nbsp;away&nbsp;the&nbsp;key.<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(dwRegCount)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActivateDeviceEx(RootKeyPath,reg,dwRegCount,NULL);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActivateDevice(RootKeyPath,&nbsp;0);<br />}&nbsp;&nbsp;&nbsp;//&nbsp;InitDevices<br /><br />至此,已经明确了系统是通过InitDevice()来加载驱动,更具体的InitDevice()会调用ActivateDeviceEx()来加载驱动,但是,这里只加载了一个驱动啊,难道系统就只加载一次?<br />这个唯一被加载的驱动是BusEnum.dll(在CE4.2是RegEnum.dll)这个驱动位于public下,它枚举了BuiltIn下所有的设备,逐个加载,并在Active下记录成功加载的设备.
 楼主| high 发表于 2007-11-22 02:56 | 显示全部楼层

写的不好.写完发现来龙去脉没有交代清楚.

  
hotpower 发表于 2007-11-22 06:35 | 显示全部楼层

强烈要求红衣教主穿裤子~~~

  
McuPlayer 发表于 2007-11-22 09:43 | 显示全部楼层

强烈要求菜鸟先去锻炼身体再来看老High的此帖

  
hqgboy 发表于 2007-12-4 10:45 | 显示全部楼层

呵呵...开始行动了...顶.

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

1078

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部