![和本節(jié)對應(yīng)的例子代碼見KmdKitexamplessimpleBeepe_第1頁](http://file4.renrendoc.com/view/f87a5d22e7b7f596a1b6fc2bc5b5acab/f87a5d22e7b7f596a1b6fc2bc5b5acab1.gif)
![和本節(jié)對應(yīng)的例子代碼見KmdKitexamplessimpleBeepe_第2頁](http://file4.renrendoc.com/view/f87a5d22e7b7f596a1b6fc2bc5b5acab/f87a5d22e7b7f596a1b6fc2bc5b5acab2.gif)
![和本節(jié)對應(yīng)的例子代碼見KmdKitexamplessimpleBeepe_第3頁](http://file4.renrendoc.com/view/f87a5d22e7b7f596a1b6fc2bc5b5acab/f87a5d22e7b7f596a1b6fc2bc5b5acab3.gif)
![和本節(jié)對應(yīng)的例子代碼見KmdKitexamplessimpleBeepe_第4頁](http://file4.renrendoc.com/view/f87a5d22e7b7f596a1b6fc2bc5b5acab/f87a5d22e7b7f596a1b6fc2bc5b5acab4.gif)
![和本節(jié)對應(yīng)的例子代碼見KmdKitexamplessimpleBeepe_第5頁](http://file4.renrendoc.com/view/f87a5d22e7b7f596a1b6fc2bc5b5acab/f87a5d22e7b7f596a1b6fc2bc5b5acab5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、2.服務(wù)和本節(jié)對應(yīng)的例子代碼見KmdKitexamplessimpleBeeper讀者也許有點(diǎn)疑惑:用戶模式的服務(wù)關(guān)內(nèi)核模式的驅(qū)動(dòng)程序什么事呀?事實(shí)上,兩者的確風(fēng)馬牛不相及,但是如果我們要和設(shè)備驅(qū)動(dòng)程序通訊的話,我們必須首先安裝它,啟動(dòng)它,而和設(shè)備驅(qū)動(dòng)程序通訊的界面剛好和服務(wù)通訊的界面是類似的。Windows服務(wù)WindowsNT使用某種機(jī)制來啟動(dòng)進(jìn)程,并讓它們不和某個(gè)具體的交互式的用戶界面相關(guān)聯(lián),這些進(jìn)程就被稱為服務(wù)(service),服務(wù)的一個(gè)很好的例子就是Web服務(wù)器,這些Web服務(wù)都沒有用戶界面,服務(wù)是唯一以這種方式運(yùn)行的應(yīng)用程序(注:指沒有用戶界面,當(dāng)然,嚴(yán)格地說病毒、木馬以及所有不
2、想見光的程序也是這樣的),服務(wù)可以在系統(tǒng)啟動(dòng)的時(shí)候自動(dòng)啟動(dòng),也可以被手工啟動(dòng),從這一點(diǎn)來看,設(shè)備驅(qū)動(dòng)程序和服務(wù)是類似的。WindowsNT還支持驅(qū)動(dòng)程序服務(wù),只要使用的時(shí)候遵循設(shè)備驅(qū)動(dòng)程序協(xié)議就可以了,這和用戶模式的服務(wù)類似,所以,服務(wù)一詞既可以指用戶模式的服務(wù)進(jìn)程或者內(nèi)核模式的設(shè)備驅(qū)動(dòng)程序,微軟不知何故沒有明確地區(qū)分兩者的概念,所以下面的敘述可能看起來有點(diǎn)讓人疑惑??赡苡械牡胤轿視?huì)說到driver詞,但在其他的文章中可能說到service詞,但既然這篇教程講的是如何編寫內(nèi)核設(shè)備驅(qū)動(dòng)程序,那么我們就約定無論說到service還是driver,我們的意思都是指驅(qū)動(dòng)程序,當(dāng)?shù)拇_需要提及服務(wù)的時(shí)候,
3、我會(huì)明確地指出來的。另外,請讀者時(shí)刻記得,文檔中關(guān)于服務(wù)管理的函數(shù)其實(shí)是敘述得相當(dāng)含糊的,因?yàn)檫@些函數(shù)既能用于驅(qū)動(dòng)程序也能用于服務(wù),在下面的文章中,我們只強(qiáng)調(diào)它們在驅(qū)動(dòng)方面的用途和忽略服務(wù)方面的用途。WindowsNT中有三個(gè)組件和服務(wù)管理相關(guān):服務(wù)控制管理器(ServiceControlManager/SCM)-用于啟動(dòng)服務(wù)以及和它通訊服務(wù)控制程序(ServiceControlProgram/SCP)-用于和SCM進(jìn)行通訊,告訴它何時(shí)啟動(dòng)或者停止服務(wù)(咦!第三個(gè)哪里去了,我也不知道,原文就這么兩個(gè)呀,可能后面會(huì)提到吧)服務(wù)程序中包含可執(zhí)行代碼,這兩個(gè)組件對服務(wù)和驅(qū)動(dòng)程序的處理方式是相同的。我
4、們先來看看前面兩個(gè)組件,在后面再講述驅(qū)動(dòng)程序。服務(wù)控制管理器(SCM)SCM的代碼位于%SystemRoot%System32Services.exe中,當(dāng)系統(tǒng)啟動(dòng)的時(shí)候,SCM被WinLogon進(jìn)程啟動(dòng),然后它掃描注冊表中HKLMSYSTEMCurrentControlSetServices鍵下的相關(guān)內(nèi)容,根據(jù)這些內(nèi)容創(chuàng)建一個(gè)服務(wù)數(shù)據(jù)庫,數(shù)據(jù)庫中包括所有服務(wù)的相關(guān)參數(shù),如果服務(wù)或者驅(qū)動(dòng)被標(biāo)為自動(dòng)啟動(dòng)的,那么啟動(dòng)它們并檢測啟動(dòng)中是否出錯(cuò)。為了更深入一步,我們可以用注冊表編輯器regedit.exe來打開并觀察注冊表中的HKLMSYSTEMCurrentControlSetServices下面的
5、內(nèi)容。想要查看系統(tǒng)中安裝了哪些服務(wù)(注意不是驅(qū)動(dòng)),可以在控制面板中選擇管理工具,再打開服務(wù)來查看。要查看系統(tǒng)中安裝了哪些驅(qū)動(dòng),可以在控制面板中選擇管理工具,再打開計(jì)算機(jī)管理,在系統(tǒng)信息下的軟件環(huán)境中,你可以看到所有驅(qū)動(dòng)的列表,但是不幸的是,在WindowsXP中,這個(gè)功能被取消了。仔細(xì)對比一下上面三個(gè)地方的內(nèi)容,我們可以發(fā)現(xiàn)這些內(nèi)容是很一致的。HKLMSYSTEMCurrentControlSetServices下面有很多子鍵,表示一個(gè)服務(wù)的內(nèi)部名稱,每個(gè)子鍵下包含了和這個(gè)服務(wù)相關(guān)的參數(shù)?,F(xiàn)在來考察一下安裝一個(gè)服務(wù)所需的最低數(shù)量的參數(shù),我們拿beeper.sys來舉例,以后再來討論這個(gè)驅(qū)動(dòng)本
6、身。圖2.1beeper.sys驅(qū)動(dòng)的注冊表鍵值這些參數(shù)的含義如下:DisplayName-用戶程序訪問服務(wù)時(shí)使用的名稱,如果為空,那么注冊表的鍵名會(huì)被作為它的名稱ErrorControl如果SCM啟動(dòng)服務(wù)的時(shí)候驅(qū)動(dòng)報(bào)錯(cuò),這個(gè)值決定了SCM如何對付這個(gè)錯(cuò)誤,我們對兩種取值有點(diǎn)興趣:SERVICE_ERROR_IGNORE(0)1/0管理器忽略這個(gè)錯(cuò)誤,不作記錄SERVICE_ERROR_NORMAL(1)如果驅(qū)動(dòng)被裝入的時(shí)候報(bào)錯(cuò),系統(tǒng)將給用戶顯示一個(gè)告警框,并將錯(cuò)誤記錄到系統(tǒng)日志中你可以在控制面板中的管理工具中選擇事件查看器來查看系統(tǒng)日志,例如,beeper.sys驅(qū)動(dòng)在初始化的時(shí)候做完了所有
7、該做的事(這個(gè)例子會(huì)讓喇叭發(fā)聲音,但是發(fā)聲功能是在初始化函數(shù)DriverEntry中做的,初始化函數(shù)執(zhí)行完,后面就沒什么事了),所以它就返回一個(gè)錯(cuò)誤,系統(tǒng)就會(huì)將它從內(nèi)存中卸載。但是這里的ErrorControl參數(shù)等于SERVICE_ERROR_IGNORE,所以系統(tǒng)日志中并沒有錯(cuò)誤記錄。ImagePath-指驅(qū)動(dòng)文件的全路徑文件名,如果該參數(shù)沒有指定路徑,那么系統(tǒng)會(huì)在%SystemRoot%Drivers目錄下查找Start-指明何時(shí)裝載驅(qū)動(dòng),這里我們關(guān)心的也是兩個(gè)取值SERVICE_AUTO_START(2)驅(qū)動(dòng)在系統(tǒng)啟動(dòng)的時(shí)候裝載SERVICE_DEMAND_START(3)驅(qū)動(dòng)由SCM
8、根據(jù)用戶要求裝載如果驅(qū)動(dòng)的Start參數(shù)為SERVICE_AUTO_START(2),那么SCM會(huì)在系統(tǒng)啟動(dòng)的時(shí)候就裝載它,這樣的驅(qū)動(dòng)被稱為自動(dòng)啟動(dòng)的服務(wù),如果驅(qū)動(dòng)的執(zhí)行依賴于其他的驅(qū)動(dòng),SCM也會(huì)把其他的驅(qū)動(dòng)也啟動(dòng)起來(要控制設(shè)備驅(qū)動(dòng)被裝載的順序,可以使用Group、Tag和DependOnGroup等參數(shù)值;要控制服務(wù)被裝載的順序,可以使用Group和DependOnService參數(shù))。Start參數(shù)還有其他的取值,如SERVICE_BOOT_START(0),但這個(gè)參數(shù)只能供設(shè)備驅(qū)動(dòng)程序使用,I/O管理器將在用戶模式的進(jìn)程啟動(dòng)之前把裝載這些驅(qū)動(dòng)程序,這時(shí)SCM還沒有啟動(dòng)呢!Type-用
9、于指定服務(wù)的類型,既然我們這里講的是KMD的編程,那么我們只對一個(gè)取值感興趣,那就是SERVICE_KERNEL_DRIVER(1)仔細(xì)觀察圖2.1后,你對beeper.sys有什么要說的嗎?好的,我們看到beeper這個(gè)內(nèi)核模式驅(qū)動(dòng)程序位于C:masm32RingOKmdArticle2beeper目錄下,它的名稱為NiceMelodyBeeper,由用戶控制啟動(dòng),出錯(cuò)信息不被記錄。Path前面的?前綴的含義你下面就會(huì)知道!如果我們要啟動(dòng)SCM數(shù)據(jù)庫中不存在的驅(qū)動(dòng)程序,那么可以在任何時(shí)刻在SCP的幫助下動(dòng)態(tài)裝入(也許稱為DCP/devicecontrolprogram更為貼切,但是微軟的術(shù)語
10、庫中并沒有這個(gè)詞)。2.3服務(wù)控制程序(SCP)從名稱理解,服務(wù)控制程序(servicecontrolprogram/SCP)可以控制服務(wù)或者設(shè)備驅(qū)動(dòng)程序,這些功能是在SCM的管理下,通過調(diào)用適當(dāng)?shù)暮瘮?shù)來完成的,這些函數(shù)位于%SystemRoot%System32advapi.dll(AdvancedAPI)中。這里是一段關(guān)于使用SCP來控制beeper.sys驅(qū)動(dòng)的代碼例子ServiceControlProgramforbeeperdriver.386.modelflat,stdcalloptioncasemap:noneINCLUDEFILESincludemasm32includewin
11、dows.incincludemasm32includekernel32.incincludemasm32includeuser32.incincludemasm32includeadvapi32.incincludelibmasm32libkernel32.libincludelibmasm32libuser32.libincludelibmasm32libadvapi32.libincludemasm32MacrosStrings.mac.codestartproclocalhSCManager:HANDLElocalhService:HANDLElocalacDriverPathMAX_
12、PATH:CHARinvokeOpenSCManager,NULL,NULL,SC_MANAGER_CREATE_SERVICE.ifeax!=NULLmovhSCManager,eaxpusheaxinvokeGetFullPathName,$CTA0(beeper.sys),sizeofacDriverPath,addracDriverPath,esppopeaxinvokeCreateService,hSCManager,$CTA0(beeper),$CTA0(NiceMelodyBeeper),SERVICE_START+DELETE,SERVICE_KERNEL_DRIVER,SER
13、VICE_DEMAND_START,SERVICE_ERROR_IGNORE,addracDriverPath,NULL,NULL,NULL,NULL,NULL.ifeax!=NULLmovhService,eaxinvokeStartService,hService,0,NULLinvokeDeleteService,hServiceinvokeCloseServiceHandle,hService.elseinvokeMessageBox,NULL,$CTA0(Cantregisterdriver.),NULL,MB_ICONSTOP.endifinvokeCloseServiceHand
14、le,hSCManager.elseinvokeMessageBox,NULL,$CTA0(CantconnecttoServiceControlManager.),NULL,MB_ICONSTOP.endifinvokeExitProcess,0startendpendstart2.3.1建立到SCM的連接在上面的例子中,我們首先要做的事情是使用OpenSCManager函數(shù)來建立到SCM的連接,以便在指定的計(jì)算機(jī)上打開服務(wù)數(shù)據(jù)庫。OpenSCManagerprotolpMachineName:LPSTR,lpDatabaseName:LPSTR,dwDesiredAccess:DWORD函
15、數(shù)使用的參數(shù)說明如下:lpMachineName指向需要打開的計(jì)算機(jī)名字符串,字符串以NULL結(jié)尾,如果參數(shù)指定為NULL,表示連接到本機(jī)上的SCMlpDatabaseName指向以NULL結(jié)尾的包含SCM數(shù)據(jù)庫名稱的字符串,字符串應(yīng)該指定為ServicesActive,如果參數(shù)指定為NULL,則默認(rèn)打開ServicesActive.constszActiveDatabasedbServicesActive,0SERVICES_ACTIVE_DATABASEequoffsetszActiveDatabase現(xiàn)在我們要打開的就是這個(gè)當(dāng)前被激活的數(shù)據(jù)庫,所以我們使用了NULL參數(shù)dwDesired
16、Access-指定訪問SCM的權(quán)限,這個(gè)參數(shù)告訴SCM我們需要進(jìn)行什么樣的操作,常用的取值有三個(gè):SC_MANAGER_CONNECT允許連接到SCM,這個(gè)取值是默認(rèn)值,它的定義就是0SC_MANAGER_CREATE_SERVICE允許創(chuàng)建服務(wù)SC_MANAGER_ALL_ACCESS允許進(jìn)行所有的操作我們可以使用下面的代碼連接到SCM:invokeOpenSCManager,NULL,NULL,SC_MANAGER_CREATE_SERVICE.ifeax!=NULLmovhSCManager,eax如果OpenSCManager函數(shù)執(zhí)行成功,那么返回值就是被連接的SCM的句柄,我們在以后
17、使用其他函數(shù)在對SCM數(shù)據(jù)庫進(jìn)行操作的時(shí)候會(huì)用到這個(gè)句柄。另外,忘了提醒大家,安裝內(nèi)核模式驅(qū)動(dòng)程序需要超級(jí)用戶的權(quán)限,為了安全起見,普通權(quán)限的用戶沒有被授權(quán)的話是無法執(zhí)行特權(quán)代碼的。當(dāng)然,本文的例子總是假設(shè)你是有超級(jí)用戶權(quán)限的。安裝一個(gè)新的驅(qū)動(dòng)打開SCM后,我們可以用CreateService函數(shù)將驅(qū)動(dòng)添加到服務(wù)數(shù)據(jù)庫中,這里是該函數(shù)的原型,CreateService函數(shù)遠(yuǎn)不止三個(gè)參數(shù),但不要害怕,這些參數(shù)都是很簡單的:CreateServiceprotohSCManager:HANDLE,lpServiceName:LPSTR,lpDisplayName:LPSTR,dwDesiredAcc
18、ess:DWORD,dwServiceType:DWORD,dwStartType:DWORD,dwErrorControl:DWORD,lpBinaryPathName:LPSTR,lpLoadOrderGroup:LPSTR,lpdwTagId:LPDWORD,lpDependencies:LPSTR,lpServiceStartName:LPSTR,lpPassword:LPSTR參數(shù)說明如下:hSCManager-不用說了吧?就是上一節(jié)中得到的SCM句柄lpServiceName-指向一個(gè)以0字符結(jié)尾的表示服務(wù)名稱的字符串,字符串的最大長度是256個(gè)字符,名稱中不允許使用/或者字符(因
19、為這些字符會(huì)和注冊表的路徑表示方式?jīng)_突),這個(gè)值和注冊表中的鍵名是相對應(yīng)的lpDisplayName-指向一個(gè)以0字符結(jié)尾表示服務(wù)名稱的字符串,這個(gè)名稱是供用戶界面程序識(shí)別函數(shù)時(shí)使用的,同樣,它的最大長度也是256個(gè)字符。這個(gè)值和注冊表中的DisplayName鍵的值是相對應(yīng)的dwDesiredAccess-指定需要訪問服務(wù)的操作,可以有以下取值:SERVICE_ALL_ACCESS可以進(jìn)行所有操作SERVICE_START允許調(diào)用StartService函數(shù)來啟動(dòng)服務(wù)SERVICE_STOP允許調(diào)用ControlService函數(shù)來停止服務(wù)DELETE-允許調(diào)用DeleteService函數(shù)
20、來刪除服務(wù)在這里我們只需要做兩件事情:啟動(dòng)驅(qū)動(dòng)和刪除驅(qū)動(dòng),所以例子中使用了SERVICE_START和DELETE,我們不需要停止服務(wù)的操作,因?yàn)樯厦嬉呀?jīng)說過,這個(gè)驅(qū)動(dòng)在初始化的時(shí)候就會(huì)返回錯(cuò)誤(所以它不會(huì)有已經(jīng)啟動(dòng)的狀態(tài))。dwServiceType-服務(wù)的類型,我們的教程中只用得到SERVICE_KERNEL_DRIVER,這個(gè)值和注冊表中的Type鍵的值是相對應(yīng)的dwStartType-表示在什么時(shí)候啟動(dòng)服務(wù),如果我們需要手動(dòng)啟動(dòng)驅(qū)動(dòng)的話,那么使用SERVICE_DEMAND_START參數(shù),如果驅(qū)動(dòng)程序需要在系統(tǒng)啟動(dòng)的時(shí)候就被啟動(dòng),那么使用SERVICE_AUTO_START參數(shù),這個(gè)
21、取值和注冊表中的Start鍵的取值是相對應(yīng)的dwErrorControl-表示當(dāng)驅(qū)動(dòng)初始化的時(shí)候出錯(cuò)該如何處理,取值SERVICE_ERROR_IGNORE表示忽略錯(cuò)誤,取值SERVICE_ERROR_NORMAL表示將錯(cuò)誤記錄到系統(tǒng)日志中去,這個(gè)取值和注冊表中的ErrorControl鍵值是相對應(yīng)的lpBinaryPathName-指向以0結(jié)尾的表示驅(qū)動(dòng)程序文件名的字符串,這個(gè)值和注冊表中的ImagePath的鍵值是相對應(yīng)的lpLoadOrderGroup-指向以0結(jié)尾的表示組名稱的字符串,表示該驅(qū)動(dòng)屬于哪個(gè)組,既然我們的例子程序不屬于任何組,那么這里就用NULL好了lpdwTagld指向一
22、個(gè)32位的緩沖區(qū),用來接收驅(qū)動(dòng)在lpLoadOrderGroup參數(shù)指定的組中的唯一的標(biāo)識(shí),我們的例子中不需要用到這個(gè)表示,所以參數(shù)指定為NULLlpDependencies對于驅(qū)動(dòng)程序來說,這個(gè)參數(shù)沒什么用途,設(shè)置為NULL好了lpServiceStartName-指向一個(gè)以0結(jié)尾的表示帳號(hào)名稱的字符串,用于指定服務(wù)允許在哪個(gè)帳號(hào)下運(yùn)行,如果服務(wù)類型是SERVICE_KERNEL_DRIVER的話,該帳號(hào)就是系統(tǒng)裝入服務(wù)的模塊名稱,我們在這里使用NULL,表示由默認(rèn)的模塊裝入lpPassword對于驅(qū)動(dòng)程序來說,這個(gè)參數(shù)沒什么用途,設(shè)置為NULL好了現(xiàn)在來總結(jié)一下,最后的5個(gè)參數(shù)總是設(shè)置為N
23、ULL,我們就把它拋到腦后去好了,第一個(gè)參數(shù)是SCM句柄,而dwDesiredAccess參數(shù)也是很好理解的,剩下的參數(shù)是什么?聰明的你一定已經(jīng)猜到了-它們實(shí)際上就是和注冊表里面的鍵一一對應(yīng)的!看看下表就明白了:CreateService函數(shù)的參數(shù)注冊表lpServiceNamelpDisplayNamedwServiceTypedwStartTypedwErrorControllpBinaryPathName鍵名DisplayNameTypeStartErrorControlImagePath表2.1參數(shù)和注冊表鍵的對應(yīng)關(guān)系好了,現(xiàn)在回過頭來看看例子代碼:pusheaxinvokeGetFu
24、llPathName,$CTA0(beeper.sys),sizeofacDriverPath,addracDriverPath,esppopeaxinvokeCreateService,hSCManager,$CTA0(beeper),$CTA0(NiceMelodyBeeper),SERVICE_START+DELETE,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,addracDriverPath,NULL,NULL,NULL,NULL,NULL.ifeax!=NULLmovhService,eax首先,我
25、們調(diào)用GetFullPathName函數(shù)來獲取全路徑的驅(qū)動(dòng)程序文件名,并把它傳遞給CreateService函數(shù)。然后CreateService函數(shù)將這個(gè)驅(qū)動(dòng)程序加入到SCM的數(shù)據(jù)庫中,并創(chuàng)建對應(yīng)的注冊表鍵,正如表2.1所示的,所有這些鍵將被CreateService函數(shù)加入到注冊表中,如果你在源代碼中把DeleteService行去掉,將csp.asm重新編譯并執(zhí)行,就可以驗(yàn)證我說的了。不要認(rèn)為使用RegXXX之類的函數(shù)將相同的信息寫入注冊表就可以達(dá)到相同的結(jié)果,這樣操作的話,鍵值是寫到注冊表里面了,但是SCM的數(shù)據(jù)庫里面可什么都沒有哦!如果SCM數(shù)據(jù)庫中指定的設(shè)備驅(qū)動(dòng)程序已經(jīng)存在,那么Cr
26、eateService函數(shù)會(huì)返回一個(gè)錯(cuò)誤,這時(shí)可以調(diào)用GetLastError函數(shù)獲取具體原因,上例中會(huì)得到ERROR_SERVICE_EXISTS。如果CreateService函數(shù)成功地將驅(qū)動(dòng)加入到了SCM數(shù)據(jù)庫中,函數(shù)的返回值就是驅(qū)動(dòng)的句柄,這個(gè)句柄在后面的驅(qū)動(dòng)管理函數(shù)中將會(huì)被用到。啟動(dòng)驅(qū)動(dòng)程序下一步要調(diào)用的函數(shù)是StartService,它的原型申明如下:StartServiceprotohService:HANDLE,dwNumServiceArgs:DWORD,lpServiceArgVectors:LPSTR參數(shù)說明如下:hService-就是上一小節(jié)中由CreateServic
27、e返回的驅(qū)動(dòng)的句柄dwNumServiceArgs-用于驅(qū)動(dòng)程序的時(shí)候,這個(gè)參數(shù)總是設(shè)置為NULLlpServiceArgVectors-同上,也為NULL啟動(dòng)驅(qū)動(dòng)的方法就是這樣的:invokeStartService,hService,0,NULLStartService函數(shù)的執(zhí)行過程和裝入用戶模式的DLL的過程類似,驅(qū)動(dòng)程序文件的映像被裝入到系統(tǒng)的地址空間中,文件可以被裝入到任何地址中,然后系統(tǒng)會(huì)根據(jù)PE文件中的重定位表對其進(jìn)行重定位操作,這樣驅(qū)動(dòng)程序的內(nèi)存映像就被準(zhǔn)備好了,接下來系統(tǒng)調(diào)用驅(qū)動(dòng)的入口函數(shù),也就是DriverEntry子程序,和裝入DLL不同的是,DriverEntry子程序
28、的執(zhí)行是在系統(tǒng)進(jìn)程的上下文中進(jìn)行的。StartService函數(shù)的調(diào)用是同步執(zhí)行的,也就是說,只有驅(qū)動(dòng)程序的DriverEntry過程返回后,函數(shù)才會(huì)返回(回想一下,如果函數(shù)不等人家執(zhí)行完就直接返回了,那叫什么那是異步!)。如果驅(qū)動(dòng)初始化成功,那么DriverEntry過程應(yīng)該返回STATUS_SUCCESS,這樣StartService會(huì)返回一個(gè)非0值,這時(shí),我們又回到了調(diào)用StartService的用戶模式的上下文中了。在這個(gè)例子中,我們并不關(guān)心StartService函數(shù)的返回值,理由前面已經(jīng)說過了,那就是beeper驅(qū)動(dòng)程序在DriverEntry中進(jìn)行了發(fā)聲音功能的演示,并返回一個(gè)錯(cuò)誤碼,后面再?zèng)]
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年馬拉松比賽合作協(xié)議書
- 人教版地理八年級(jí)下冊6.4《祖國的首都-北京》聽課評課記錄2
- 【部編版】七年級(jí)歷史上冊 《中國早期人類的代表-北京人》公開課聽課評課記錄
- 豬欄承包協(xié)議書(2篇)
- 生產(chǎn)工人中介合同(2篇)
- 人教版數(shù)學(xué)九年級(jí)上冊《構(gòu)建知識(shí)體系級(jí)習(xí)題訓(xùn)練》聽評課記錄1
- 北師大版道德與法治九年級(jí)上冊4.1《經(jīng)濟(jì)發(fā)展新階段》聽課評課記錄
- 八年級(jí)思想讀本《5.1奉法者強(qiáng)則國強(qiáng)》聽課評課記錄
- 五年級(jí)上冊數(shù)學(xué)聽評課記錄《4.2 認(rèn)識(shí)底和高》(3)-北師大版
- 湘教版數(shù)學(xué)八年級(jí)上冊2.3《等腰(邊)三角形的判定》聽評課記錄
- 城市隧道工程施工質(zhì)量驗(yàn)收規(guī)范
- 2025年湖南高速鐵路職業(yè)技術(shù)學(xué)院高職單招高職單招英語2016-2024年參考題庫含答案解析
- 五 100以內(nèi)的筆算加、減法2.筆算減法 第1課時(shí) 筆算減法課件2024-2025人教版一年級(jí)數(shù)學(xué)下冊
- 2025江蘇太倉水務(wù)集團(tuán)招聘18人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2024-2025學(xué)年人教新版高二(上)英語寒假作業(yè)(五)
- 2025年八省聯(lián)考陜西高考生物試卷真題答案詳解(精校打印)
- 2025脫貧攻堅(jiān)工作計(jì)劃
- 借款人解除合同通知書(2024年版)
- 《血小板及其功能》課件
- 江蘇省泰州市靖江市2024屆九年級(jí)下學(xué)期中考一模數(shù)學(xué)試卷(含答案)
- 沐足店長合同范例
評論
0/150
提交評論