版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
匯報(bào)人:邢成婧玉軟工(實(shí))11401Windows設(shè)備驅(qū)動程序前言Linux是一種日趨成熟完善的操作系統(tǒng).越來越多的軟硬件廠商開始使用Linux平臺來開發(fā)自己的產(chǎn)品,因而對基于該平臺的設(shè)備驅(qū)動程序的需求也愈來愈多。同時PCI總線作為一個具有兼容性強(qiáng)、平臺無關(guān)性等特點(diǎn)從的計(jì)算機(jī)總線標(biāo)準(zhǔn)。日前得到了廣泛的應(yīng)用。目錄0304編寫驅(qū)動程序的基礎(chǔ)知識驅(qū)動中使用鏈表01驅(qū)動開發(fā)環(huán)境的創(chuàng)建02驅(qū)動程序結(jié)構(gòu)1驅(qū)動開發(fā)環(huán)境的搭建01OPTION關(guān)于DDK02OPTION關(guān)于驅(qū)動程序的編譯03OPTION關(guān)于驅(qū)動程序的運(yùn)行關(guān)于DDK開發(fā)驅(qū)動程序必備的一個東西就是DDK(DeviceDevelopmentKit,設(shè)備驅(qū)動開發(fā)包),它跟我們在ring3常聽到的SDK差不多,只不過它們分別支持開發(fā)不同的程序而已。DDK和微軟其他的產(chǎn)品一樣,具有良好的向后兼容性,比如你用DDK2000開發(fā)的驅(qū)動在DDKXP里面同樣可以編譯,但反之卻不能保證DriverStudio之類的驅(qū)動開發(fā)工具,其實(shí)那只是對DDK的簡單封裝,跟SDK與MFC的關(guān)系差不多,不過DriverStudio不僅僅是對DDK的封裝,而是個完整的開發(fā)工具包,它提供了很多有用的工具用于驅(qū)動程序的開發(fā)和調(diào)試,不過這些工具可以單獨(dú)提取出來使用?!?sys”文件,同時還需要自己編寫makefile和sources文件。對于使用VC開始學(xué)習(xí)編程的人們來說,makefile概念有點(diǎn)可能有點(diǎn)陌生。實(shí)際上VC本身只是個框架,“編譯”這個工作還是由一個名為“cl.exe”的命令行工具執(zhí)行的,VC不過是通過一個良好的界面幫我們完成了一些參數(shù)設(shè)置的工作。使用VC來編譯驅(qū)動程序是可行的。VC6.0到新的VS2008都沒有被遺漏。
使用EasySys這個小工具,可以通過簡單的設(shè)置生成一個完整的“.dsw”工程。關(guān)于驅(qū)動程序的編譯關(guān)于驅(qū)動程序的運(yùn)行通常生成的驅(qū)動程序格式都是“.sys”,雖然它也是PE格式,但不能直接運(yùn)行,必須被加載到系統(tǒng)中。因此編寫好一個驅(qū)動程序后,如果想運(yùn)行查看結(jié)果,則必須使用一些工具來進(jìn)行加載。使用一個名為“KmdManager”的小工具來加載驅(qū)動。運(yùn)行界面如圖2驅(qū)動程序結(jié)構(gòu)01驅(qū)動程序頭文件02驅(qū)動程序入口點(diǎn)03創(chuàng)建設(shè)備歷程04卸載驅(qū)動歷程
NT式驅(qū)動需要導(dǎo)入的頭文件是“ntddk.h”,而WDM式驅(qū)動需要導(dǎo)入的“wdm.h”,即:#include“ntddk.h”;。在驅(qū)動中用到的變量或函數(shù)都需要指定分配在分頁或非分頁內(nèi)存中,分頁內(nèi)存在物理內(nèi)存不夠的情況下可能會被交換出去,對于一些需要高IRQL的例程絕對不能被交換出頁面,因此它們必須被定義為非分頁內(nèi)存。通常來說在驅(qū)動程序的自定義頭文件中都是定義了一些宏或函數(shù)聲明。驅(qū)動程序頭文件驅(qū)動程序入口點(diǎn)在驅(qū)動對象DriverObject中,有個函數(shù)指針數(shù)組MajorFunction,它里面的每一個元素都記錄著一個函數(shù)的地址對應(yīng)著相應(yīng)的IRP,我們可以通過簡單地設(shè)置這個數(shù)組將IRP與相應(yīng)的派遣函數(shù)關(guān)聯(lián)起來。由于在進(jìn)入DriverEntry之前,I/O管理器會_IopInvalidDeviceRequest的地址填滿整個MajorFunction數(shù)組,因此除了我們自行設(shè)置過的IRP之外,其他的IRP都與系統(tǒng)默認(rèn)的_IopInvalidDeviceRequest函數(shù)關(guān)聯(lián)。
驅(qū)動中的例程實(shí)際上就是函數(shù)的另外一種說法,實(shí)際上例程與函數(shù)還是有所區(qū)別的。創(chuàng)建設(shè)備是在DriverEntry中完成的創(chuàng)建設(shè)備歷程創(chuàng)建設(shè)備歷程//創(chuàng)建設(shè)備對象
RtlInitUnicodeString(&ntDeviceName,TEST_DEVICE_NAME_W);Status=IoCreateDevice(DriverObject,sizeof(DEVICE_EXTENSION),//DeviceExtensionSize&ntDeviceName,//DeviceNameFILE_DEVICE_TEST,//DeviceType0,//DeviceCharacteristicsTRUE,//Exclusive&deviceObject//[OUT]);
if(!NT_SUCCESS(Status))
{KdPrint(("[Test]IoCreateDeviceErrorCode=0x%X\n",Status));returnStatus;}deviceExtension=(PDEVICE_EXTENSION)deviceObject->DeviceExtension;//創(chuàng)建符號鏈接RtlInitUnicodeString(&dosDeviceName,TEST_DOS_DEVICE_NAME_W);Status=IoCreateSymbolicLink(&dosDeviceName,&ntDeviceName);if(!NT_SUCCESS(Status)){KdPrint(("[Test]IoCreateSymbolicLinkErrorCode=0x%X\n",Status));IoDeleteDevice(deviceObject);returnStatus;
}卸載驅(qū)動例程是我們在DriverEntry中自己定義的,當(dāng)驅(qū)動被卸載時I/O管理器負(fù)責(zé)調(diào)用該例程,它主要做一些掃尾處理的工作。相關(guān)代碼如下所示:UNICODE_STRINGdosDeviceName;
//釋放其他資源
//刪除符號鏈接
RtlInitUnicodeString(&dosDeviceName,TEST_DOS_DEVICE_NAME_W);IoDeleteSymbolicLink(&dosDeviceName);//刪除設(shè)備對象
IoDeleteDevice(DriverObject->DeviceObject);KdPrint(("[Test]Unloaded"));要想輸出一些信息,就需要調(diào)用DbgPrint函數(shù),不過這個函數(shù)輸出的信息我們無法直接看到,需要使用一些專門的工具,比如DbgView等。有些內(nèi)容我們只想在調(diào)試版輸出,在發(fā)行版忽略,因此DDK中定義了一個宏KdPrint,它在發(fā)行版不被編譯,只在調(diào)試版才會運(yùn)行。KdPrint的用法很奇怪,由于它的定義:#defineKdPrint(_x_)DbgPrint_x_,這就導(dǎo)致了它的用法很奇怪,在使用時外層要有兩個連續(xù)的括號。卸載設(shè)備例程編寫驅(qū)動程序的基礎(chǔ)知識ABCD示例程序內(nèi)核模式下的字符串操作內(nèi)核模式下各種開頭函數(shù)的區(qū)別關(guān)系內(nèi)核模式下的字符串操作內(nèi)核模式與用戶模式一樣都是有ANSI和UNICODE兩種字符串,Windows內(nèi)核是使用Unicode編碼的,ANSI只在很少的特殊場合才會使用,而這種場合往往是非常罕見的,因此不考慮ANSI字符串。Unicode字符串有一個結(jié)構(gòu)體定義如下:
typedefstruct_UNICODE_STRING{USHORTLength;//字符串的長度(字節(jié)數(shù))USHORTMaximumLength;//字符串緩沖區(qū)的長度(字節(jié)數(shù))
PWSTRBuffer;//字符串緩沖區(qū)
}UNICODE_STRING,*PUNICODE_STRING;需要注意的是,當(dāng)我們定義了一個UNICODE_STRING變量之后,它的Buffer域還沒有分配空間,因此我們不能直接賦值,好的做法是使用微軟提供的Rtl系列函數(shù)。
UNICODE_STRINGstr;RtlInitUnicodeString(&str,L"myfirststring!");或者如下所示:
#include<ntdef.h>UNICODE_STRINGstr=RTL_CONSTANT_STRING(L"myfirststring!");UNICODE字符串并不是以“\0”來表示字符串結(jié)束的,而是依靠UNICODE_STRING的Length域來確定。在驅(qū)動開發(fā)的過程中,可能遇到很多不同開頭的函數(shù),如前面遇到過的Rtl和Io系列,此外還有比如Ex、Ps、Nt等等。常見的函數(shù)開頭及其含義如下表所示。內(nèi)核模式下各種開頭函數(shù)區(qū)別NativeAPI從用戶模式穿越進(jìn)入到內(nèi)核模式調(diào)用系統(tǒng)服務(wù),這個穿越過程是通過軟中斷的方式進(jìn)入的。這個軟中斷的實(shí)現(xiàn)方法在不同版本的Windows實(shí)現(xiàn)方式略有不同,在Win2K下是通過“int2eh”實(shí)現(xiàn)的,在WinXP是通過“sysenter”指令完成的。
軟中斷會將NativeAPI的參數(shù)和系統(tǒng)服務(wù)號的參數(shù)一起傳進(jìn)內(nèi)核模式,不同的NativeAPI會對應(yīng)不同的系統(tǒng)服務(wù)號,這個過程是由SSDT輔助完成的。
系統(tǒng)服務(wù)函數(shù)一般和NativeAPI具有相同的名字,例如都是NtCreateFile,但它們的實(shí)現(xiàn)不同,系統(tǒng)服務(wù)調(diào)用是在“ntoskrnl.exe”導(dǎo)出的。
示例程序關(guān)系在驅(qū)動中使用鏈表內(nèi)存的分配與釋放設(shè)備驅(qū)動分層使用LISTENTRY設(shè)備驅(qū)動內(nèi)存的分配與釋放傳統(tǒng)的C語言中,分配內(nèi)存常常使用的函數(shù)是malloc,但在驅(qū)動開發(fā)過程中這個函數(shù)不再有效。驅(qū)動中分配內(nèi)存,常用的是調(diào)用ExAllocatePoolWithTag或ExAllocatePool。
//定義一個內(nèi)存分配標(biāo)記
#defineMEM_TAG‘MyTt’//目標(biāo)字符串,接下來它需要分配空間。
UNICODE_STRINGdst={0};//分配空間給目標(biāo)字符串。根據(jù)源字符串的長度。dst.Buffer=(PWCHAR)ExAllocatePoolWithTag(NonpagedPool,src->Length,MEM_TAG);if(dst.Buffer==NULL){//錯誤處理status=STATUS_INSUFFICIENT_RESOUCRES;
}dst.Length=dst.MaximumLength=src->Length;ExAllocatePoolWithTag的第一個參數(shù)NonpagedPool表明分配的內(nèi)存是非分頁內(nèi)存,這樣它們可以永遠(yuǎn)存在于物理內(nèi)存,而不會被分頁交換到硬盤上去;第二個參數(shù)是長度;第三個參數(shù)是一個所謂的“內(nèi)存分配標(biāo)記”。Windows內(nèi)核提供了一個雙向鏈表結(jié)構(gòu)LIST_ENTRY,此外還有一些其他的結(jié)構(gòu),比如SINGLE_LIST_ENTRY(單向鏈表).LIST_ENTRY是一個雙向鏈表結(jié)構(gòu),但直接使用它將毫無任何意義,通常的做法是自定義一個結(jié)構(gòu)體,將LIST_ENTRY作為該結(jié)構(gòu)體的一個子域,這樣給予了大限度的靈活性,因?yàn)閿?shù)據(jù)需求千差萬別,只要簡單修改一下便可利用LIST_E
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025公司經(jīng)營承包合同書范本
- 新型功能性過濾器項(xiàng)目可行性研究報(bào)告
- 特種蔬菜種植基地項(xiàng)目可行性研究報(bào)告建議書
- 2024-2030年中國無線網(wǎng)絡(luò)設(shè)備行業(yè)市場發(fā)展監(jiān)測及投資戰(zhàn)略規(guī)劃報(bào)告
- 2025年速凍草莓項(xiàng)目可行性研究報(bào)告-20250101-212507
- 2024-2030年中國嬰兒吸鼻器行業(yè)發(fā)展監(jiān)測及投資方向研究報(bào)告
- 2019-2025年中國名片印刷行業(yè)市場供需格局及未來發(fā)展趨勢報(bào)告
- 山東省逆變焊機(jī)生產(chǎn)項(xiàng)目可行性研究報(bào)告
- 2025裝修設(shè)計(jì)師勞動合同范本
- 2025房屋買賣合同書標(biāo)準(zhǔn)范本
- 浙江省杭州市余杭區(qū)2023-2024學(xué)年五年級上學(xué)期期末英語試卷
- 中醫(yī)調(diào)節(jié)內(nèi)分泌的方法
- 2020年山西省公務(wù)員錄用考試《行測》真題及答案
- JTG 3441-2024公路工程無機(jī)結(jié)合料穩(wěn)定材料試驗(yàn)規(guī)程
- JJF(新) 106-2023 微波消解儀溫度、壓力參數(shù)校準(zhǔn)規(guī)范
- 《廚政管理說課》課件
- 安徽省合肥市包河區(qū)四十八中學(xué)2023-2024學(xué)年數(shù)學(xué)七年級第一學(xué)期期末學(xué)業(yè)質(zhì)量監(jiān)測試題含解析
- 春節(jié)家族祭祀活動策劃方案
- 空氣源熱泵冷暖空調(diào)、熱水項(xiàng)目施工方案
- 《行政組織學(xué)》期末復(fù)習(xí)指導(dǎo)
- 廣東省佛山市2022-2023學(xué)年高一上學(xué)期期末考試英語試題(含答案)
評論
0/150
提交評論