Windows驅(qū)動(dòng)程序設(shè)計(jì)入門.ppt
《Windows驅(qū)動(dòng)程序設(shè)計(jì)入門.ppt》由會(huì)員分享,可在線閱讀,更多相關(guān)《Windows驅(qū)動(dòng)程序設(shè)計(jì)入門.ppt(49頁珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
Windows驅(qū)動(dòng)程序設(shè)計(jì)入門,2,Windows的虛擬內(nèi)存管理,3,Windows的虛擬內(nèi)存管理,Windows的虛擬內(nèi)存管理機(jī)制為應(yīng)用程序和驅(qū)動(dòng)程序提供了兩種服務(wù):使每個(gè)進(jìn)程都擁有自己獨(dú)立的內(nèi)存地址空間;對(duì)于32位Windows而言,每個(gè)任務(wù)可尋址的內(nèi)存地址空間都為0 x00000000~0 xFFFFFFFF(232,4GB)當(dāng)物理內(nèi)存不夠4GB時(shí),虛擬內(nèi)存管理模塊會(huì)用磁盤空間模擬內(nèi)存空間,并且該模擬過程對(duì)應(yīng)用程序是透明的。,4,用戶地址空間與內(nèi)核地址空間,Windows將每個(gè)進(jìn)程的4GB的獨(dú)立地址空間又劃分為用戶地址空間(0 x00000000~0 x7FFFFFFF)和內(nèi)核地址空間(0 x80000000~0 xFFFFFFFF)兩部分。操作系統(tǒng)內(nèi)核代碼和數(shù)據(jù)存放在內(nèi)核地址空間;每個(gè)進(jìn)程自己私有的代碼和數(shù)據(jù)存放在用戶地址空間雖然Windows的內(nèi)核代碼和數(shù)據(jù)被映射到了每個(gè)進(jìn)程的地址空間中(所有進(jìn)程看到的內(nèi)容是相同的),但在實(shí)際的物理內(nèi)存中,只有內(nèi)核代碼和數(shù)據(jù)的一份拷貝。,5,用戶地址空間與內(nèi)核地址空間,6,用戶模式與內(nèi)核模式,為了更好地保護(hù)系統(tǒng),Windwos規(guī)定了兩種處理器工作模式:用戶模式和內(nèi)核模式。工作在用戶模式的程序只能使用CPU支持指令集的一個(gè)子集,只能訪問用戶空間中的內(nèi)存,并且不能直接訪問硬件。工作在內(nèi)核模式的程序不受任何限制,可以使用CPU支持的任意指令,可以訪問任意的內(nèi)存空間,可以直接訪問硬件。所有的Windows應(yīng)用程序都工作于用戶模式,Windows內(nèi)核程序都工作于內(nèi)核模式。也可以認(rèn)為:位于用戶空間的代碼都工作于用戶模式,位于內(nèi)核空間的代碼都工作于內(nèi)核模式。應(yīng)用程序只能通過Windows規(guī)定的一些API訪問內(nèi)核模式的代碼和數(shù)據(jù)。,7,Windows系統(tǒng)結(jié)構(gòu),8,什么是Windows驅(qū)動(dòng)程序?,Windows驅(qū)動(dòng)程序是一種位于內(nèi)核地址空間并且工作于內(nèi)核模式的一種特殊的程序類型(.sys文件)。驅(qū)動(dòng)程序是操作系統(tǒng)信任的一個(gè)內(nèi)核擴(kuò)展模塊。驅(qū)動(dòng)程序和操作系統(tǒng)之間遵循的是容器與插件模型。OS負(fù)責(zé)管理Driver的生命周期;Driver是一種被動(dòng)的軟件模塊。驅(qū)動(dòng)程序類似于DLL程序,它是一個(gè)回調(diào)函數(shù)(子程序)的集合體,這些函數(shù)由OS在適當(dāng)?shù)臅r(shí)候調(diào)用驅(qū)動(dòng)程序也可以通過Windows內(nèi)核API獲得OS的一些服務(wù)。,9,編驅(qū)動(dòng)程序用什么編程語言?,C語言C++語言%1的情況下會(huì)用到匯編語言目前還不能用其它高級(jí)語言編寫驅(qū)動(dòng)程序。,10,編驅(qū)動(dòng)程序用什么開發(fā)工具?,WDK(WindowsDriverKit)(可以到微軟網(wǎng)站上免費(fèi)下載)DriverStudio(CompuwareNuMega公司的產(chǎn)品)+DDKWinDriver+DDK,11,WDK中包含什么?,與Windows內(nèi)核API函數(shù)相關(guān)的頭文件(如ddk.h,wdm.h等)與Windows內(nèi)核API函數(shù)相關(guān)的導(dǎo)入庫(wdm.lib等)內(nèi)核專用C運(yùn)行時(shí)間庫的頭文件和導(dǎo)入庫關(guān)于驅(qū)動(dòng)程序編程模型和內(nèi)核API函數(shù)的幫助文檔C++編譯器和鏈接器,綜合創(chuàng)建工具內(nèi)核調(diào)試工具、分析工具,12,內(nèi)核模式下我們能調(diào)用哪些函數(shù)?,Windows內(nèi)核輸出的內(nèi)核API函數(shù);WDK提供的運(yùn)行時(shí)間庫其它驅(qū)動(dòng)程序提供的服務(wù),13,內(nèi)核模式下我們不能調(diào)用哪些函數(shù)?,Windows的用戶模式API函數(shù);ISO規(guī)定的C/C++標(biāo)準(zhǔn)函數(shù)庫,14,最簡(jiǎn)單的NT式驅(qū)動(dòng)程序,extern“C”{#include}extern"C"NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath){NTSTATUSstatus=STATUS_UNSUCCESSFUL;/*KdPrint將輸入字符串發(fā)送到一個(gè)特殊內(nèi)存區(qū),利用DbgView工具可以觀察該內(nèi)存區(qū)的內(nèi)容*/KdPrint(("HelloWorld!!!!"));returnstatus;},15,關(guān)于最簡(jiǎn)單驅(qū)動(dòng)的問題,第一個(gè)extern“C”的作用是什么?第二個(gè)extern“C”的作用是什么?typedeflongNTSTATUS;#defineIN#ifdefDBG#defineKdPrint(a)DbgPrint##a#else#defineKdPrint(a)#endif,16,驅(qū)動(dòng)程序的入口函數(shù),NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath){…………returnstatus;},參數(shù)DriverObject表示指向驅(qū)動(dòng)對(duì)象的指針;參數(shù)RegistryPath表示該驅(qū)動(dòng)所對(duì)應(yīng)的注冊(cè)表服務(wù)鍵的子目錄返回值表示初始化是否成功,17,DDK中一個(gè)驅(qū)動(dòng)型工程的組成,MAKEFILE文件,一般不作改動(dòng)Sources文件:(1)指示了整個(gè)工程由哪些源程序和資源文件構(gòu)成;(2)包含了主要的編譯參數(shù),指導(dǎo)編譯器和鏈接器的工作。.cpp文件和.h文件如何build驅(qū)動(dòng)工程?用DDK中的build工具。build工具會(huì)根據(jù)MAKEFILE文件和Sources文件以及相關(guān)環(huán)境變量的指示編譯并鏈接工程中的.cpp文件和.h文件,18,如何安裝NT型驅(qū)動(dòng)程序?,方法1:在注冊(cè)表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services下增加一個(gè)新的項(xiàng)目。可以將該服務(wù)指定為開機(jī)自啟動(dòng),也可以指定為按需啟動(dòng)。如果是按需啟動(dòng),則可以用netstart命令啟動(dòng),用netstop命令停止。方法2:編寫另外的用戶模式程序利用SCM函數(shù)按需啟動(dòng)。方法3:在調(diào)試階段可以利用第三方的工具如:DriverMoniter和IntallDriver隨時(shí)安裝和卸載。,19,如何調(diào)試驅(qū)動(dòng)程序?,方法1:打印調(diào)試信息。即用DbgPrint函數(shù)打印調(diào)試信息,然后在驅(qū)動(dòng)運(yùn)行時(shí)用Dbgview等工具觀察這些信息。方法2:分析內(nèi)存轉(zhuǎn)儲(chǔ)(dump)文件。方法3:使用WinDbg、SoftICE等高級(jí)調(diào)試工具。,20,用WinDbg+VMWare進(jìn)行雙機(jī)調(diào)試,Step1:安裝WinDbg和VMWare,并在VMWare中安裝好WindowsXP。Step2:設(shè)置好WMWare的虛擬串口Step3:將虛擬機(jī)中的WindowsXP設(shè)置為調(diào)試運(yùn)行模式。(修改boot.ini文件)Step4:以調(diào)試方式啟動(dòng)虛擬機(jī)中的WindowsXPStep5:?jiǎn)?dòng)WinDbgStep6:設(shè)置WinDbg的Symbol文件路徑,設(shè)置C源程序路徑。Step7:設(shè)置斷點(diǎn),監(jiān)視變量,21,HelloWorld版的WDM驅(qū)動(dòng)程序,extern“C”{#include“wdm.h”}extern"C"NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath){NTSTATUSstatus=STATUS_DEVICE_CONFIGURATION_ERROR;KdPrint(("HellowWorld!!!!"));returnstatus;},22,如何安裝WDM驅(qū)動(dòng)程序?,必須編寫一個(gè)安裝指示文件(.inf)指導(dǎo)Windows將驅(qū)動(dòng)程序安裝到指定位置(一般安裝在windows\system32\drivers子目錄下),并在注冊(cè)表中進(jìn)行登記。對(duì)于即插即用類設(shè)備的驅(qū)動(dòng),操作系統(tǒng)會(huì)自動(dòng)發(fā)現(xiàn)該設(shè)備并調(diào)用“添加新硬件”程序向用戶詢問相應(yīng)的inf文件的位置。對(duì)于非即插即用類設(shè)備的驅(qū)動(dòng),用戶必須自己手動(dòng)調(diào)用“添加新硬件”程序,并通過告訴該程序inf文件的位置。,23,inf文件主要包含了哪些內(nèi)容?,設(shè)備類型、設(shè)備型號(hào)、廠商信息、程序版本號(hào)…。對(duì)操作系統(tǒng)版本和CPU類型的要求…源文件(.sys文件)的文件名和所在位置安裝目標(biāo)子目錄在注冊(cè)表中添加哪些內(nèi)容硬件配置信息安全配置信息,24,驅(qū)動(dòng)對(duì)象(DriverObject),在操作系統(tǒng)首次裝載一個(gè)驅(qū)動(dòng)程序之后,它會(huì)創(chuàng)建一個(gè)數(shù)據(jù)結(jié)構(gòu)用來記錄該驅(qū)動(dòng),該數(shù)據(jù)結(jié)構(gòu)我們稱為驅(qū)動(dòng)對(duì)象(DriverObject)。驅(qū)動(dòng)對(duì)象記錄與驅(qū)動(dòng)程序本身相關(guān)的信息,它主要包含了除了DriverEntry之外的其它驅(qū)動(dòng)程序入口函數(shù)的入口地址。(驅(qū)動(dòng)程序是一種具有多個(gè)入口函數(shù)的程序)驅(qū)動(dòng)對(duì)象是由操作系統(tǒng)創(chuàng)建,然后作為DriverEntry的第一個(gè)參數(shù)傳遞給你的程序。在獲得驅(qū)動(dòng)對(duì)象的指針之后,你的程序需要對(duì)其中的一些字段進(jìn)行初始化。,25,驅(qū)動(dòng)對(duì)象(DriverObject),驅(qū)動(dòng)對(duì)象在DDK的頭文件(ntddk.h)中按如下方式定義:。,typedefstruct_DRIVER_OBJECT{CSHORTType;CSHORTSize;……}DRIVER_OBJECT,*PDRIVER_OBJECT;,由上面的定義可以看成,驅(qū)動(dòng)對(duì)象不同于C++中的Class,它只是一個(gè)Struct。,26,,27,驅(qū)動(dòng)對(duì)象的一些關(guān)鍵字段(一),DriverStartIo(PDRIVER_STARTIO):指向StartIO入口函數(shù)的指針.DriverUnload(PDRIVER_UNLOAD):指向DriverUnload入口函數(shù)的指針。在驅(qū)動(dòng)程序被從內(nèi)存中卸載時(shí),DriverUnload入口函數(shù)會(huì)被操作系統(tǒng)調(diào)用,你應(yīng)該在該函數(shù)內(nèi)部做一些與DriverEntry向?qū)?yīng)的資源清除工作。MajorFunction(一個(gè)數(shù)組,數(shù)組中每一元素又是一個(gè)指向函數(shù)的指針PDRIVER_DISPATCH):數(shù)組中每一個(gè)指針指向一個(gè)入口函數(shù)。在接收到不同的請(qǐng)求包(IRP)時(shí),OS會(huì)調(diào)用不同的入口函數(shù)。,28,驅(qū)動(dòng)對(duì)象的一些關(guān)鍵字段(二),DeviceObject(PDEVICE_OBJECT):指向一個(gè)鏈表的指針,該鏈表中每一個(gè)節(jié)點(diǎn)都存儲(chǔ)了一個(gè)FDO對(duì)象。每一個(gè)FDO都代表一個(gè)由該驅(qū)動(dòng)維護(hù)的硬件設(shè)備實(shí)例。在WDM模型中,該鏈表由OS自動(dòng)維護(hù)。DriverExtension(PDRIVER_EXTENSION):指向另外一個(gè)結(jié)構(gòu)體,該結(jié)構(gòu)體中唯一有用的字段為AddDevice。AddDevice字段指向一個(gè)入口函數(shù)。在操作系統(tǒng)發(fā)現(xiàn)一個(gè)新的設(shè)備實(shí)例時(shí),它會(huì)自動(dòng)調(diào)用AddDevice函數(shù),你應(yīng)該在該函數(shù)中做一些與設(shè)備實(shí)例相關(guān)的初始化工作。,29,DriverEntry函數(shù)的主要工作,在操作系統(tǒng)創(chuàng)建的驅(qū)動(dòng)對(duì)象中填寫其它入口函數(shù)的地址,使得操作系統(tǒng)在必要的時(shí)候能夠找到這些入口函數(shù)并調(diào)用它們。創(chuàng)建一個(gè)或多個(gè)設(shè)備對(duì)象,并將這些對(duì)象掛接在驅(qū)動(dòng)對(duì)象所指示的鏈表上。(只針對(duì)NT型驅(qū)動(dòng))與該設(shè)備相關(guān)的其他初始化工作,VOID(*PDRIVER_UNLOAD)(INPDRIVER_OBJECTDriverObject);VOID(*PDRIVER_STARTIO)(INPDEVICE_OBJECTDeviceObject,INPIRPIrp);NTSTATUS(*PDRIVER_DISPATCH)(INPDEVICE_OBJECTDeviceObject,INPIRPIrp);NTSTATUS(*PDRIVER_ADD_DEVICE)(INPDRIVER_OBJECTDriverObject,INPDEVICE_OBJECTPhysicalDeviceObject);,30,DriverUnload函數(shù)的主要工作,刪除以鏈表形式掛接在驅(qū)動(dòng)對(duì)象上的一個(gè)或多個(gè)設(shè)備對(duì)象。(只針對(duì)NT型驅(qū)動(dòng))進(jìn)行與DriverEntry函數(shù)中相對(duì)應(yīng)的反初始化工作。例如如果在DriverEntry函數(shù)中申請(qǐng)了堆內(nèi)存,那么在DriverUnload函數(shù)中應(yīng)該釋放該堆內(nèi)存。,VOIDDriverUnload(PDRIVER_OBJECTDriverObject){RtlFreeUnicodeString(},31,第二簡(jiǎn)單的驅(qū)動(dòng)程序,extern“C”{#include}VOIDHelloDDKUnload(INPDRIVER_OBJECTpDriverObject);NTSTATUSHelloDDKDispatchRoutine(INPDEVICE_OBJECTpDevObj,INPIRPpIrp);extern"C"NTSTATUSDriverEntry(INPDRIVER_OBJECTpDriverObject,INPUNICODE_STRINGpRegistryPath){NTSTATUSstatus=STATUS_SUCCESS;KdPrint(("EnterDriverEntry\n"));KdPrint(("RegistryPath:%wZ\n",pRegistryPath));pDriverObject->DriverUnload=HelloDDKUnload;pDriverObject->MajorFunction[IRP_MJ_CREATE]=HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_CLOSE]=HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_WRITE]=HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_READ]=HelloDDKDispatchRoutine;KdPrint(("LeaveDriverEntry\n"));returnstatus;},32,第二簡(jiǎn)單的驅(qū)動(dòng)程序(續(xù)),VOIDHelloDDKUnload(INPDRIVER_OBJECTpDriverObject){KdPrint(("EnterDriverUnload\n"));KdPrint(("LeaveDriverUnload\n"));}NTSTATUSHelloDDKDispatchRoutine(INPDEVICE_OBJECTpDevObj,INPIRPpIrp){NTSTATUSstatus=STATUS_SUCCESS;KdPrint(("EnterHelloDDKDispatchRoutine\n"));KdPrint(("LeaveHelloDDKDispatchRoutine\n"));returnstatus;},33,設(shè)備對(duì)象(DeviceObject),針對(duì)每一個(gè)硬件設(shè)備,Windows都需要用一個(gè)數(shù)據(jù)結(jié)構(gòu)來記錄它的相關(guān)信息,這個(gè)數(shù)據(jù)結(jié)構(gòu)就叫做設(shè)備對(duì)象(DevcieObject)。因?yàn)橐粋€(gè)驅(qū)動(dòng)程序可以同時(shí)管理多個(gè)同類型的硬件設(shè)備,因此一個(gè)驅(qū)動(dòng)對(duì)象可以對(duì)應(yīng)多個(gè)設(shè)備對(duì)象。對(duì)應(yīng)同一個(gè)驅(qū)動(dòng)對(duì)象的多個(gè)設(shè)備對(duì)象構(gòu)成一個(gè)鏈表掛接在驅(qū)動(dòng)對(duì)象的DeviceObject字段上。設(shè)備對(duì)象由驅(qū)動(dòng)程序負(fù)責(zé)創(chuàng)建和初始化,由操作系統(tǒng)負(fù)責(zé)保存和管理。設(shè)備對(duì)象可以有名字,其他驅(qū)動(dòng)程序或應(yīng)用程序可以通過該名字找到該設(shè)備對(duì)象。,34,,TheDeviceObject,35,設(shè)備對(duì)象的一些關(guān)鍵字段(一),DriverObject(PDRIVER_OBJECT):指向與該設(shè)備對(duì)象相對(duì)應(yīng)的驅(qū)動(dòng)對(duì)象的指針。NextDevice(PDEVICE_OBJECT):指向下一個(gè)設(shè)備對(duì)象的指針,利用該字段與同一個(gè)驅(qū)動(dòng)對(duì)象對(duì)應(yīng)的多個(gè)設(shè)備對(duì)象就可以構(gòu)成一個(gè)單鏈表,該鏈表最后掛接在驅(qū)動(dòng)對(duì)象的DeviceObject字段上。,36,設(shè)備對(duì)象的一些關(guān)鍵字段(二),Flags(ULONG):保存了一些標(biāo)志位,這些標(biāo)志位指示了該設(shè)備的一些工作方式。,37,設(shè)備對(duì)象的一些關(guān)鍵字段(三),Characteristics(ULONG):另外一組標(biāo)志位集合。DeviceExtension(PVOID):指向一個(gè)擴(kuò)展內(nèi)存區(qū),該內(nèi)存區(qū)的大小和使用方式由程序員規(guī)定。一般在該區(qū)域存放一個(gè)自定義的結(jié)構(gòu)體,用于存儲(chǔ)硬件設(shè)備特有的信息。今后稱該結(jié)構(gòu)體為設(shè)備擴(kuò)展對(duì)象。該擴(kuò)展內(nèi)存區(qū)由操作系統(tǒng)負(fù)責(zé)創(chuàng)建并維護(hù)。DeviceType(DEVICE_TYPE):一個(gè)枚舉型變量,指明該設(shè)備的類型(FILE_DEVICE_UNKNOWN)AlignmentRequirement(ULONG):指定該設(shè)備使用內(nèi)存時(shí)的對(duì)齊方式(FILE_BYTE_ALIGNMENT、FILE_WORD_ALIGNMENT…FILE_512_BYTE_ALIGNMENT),38,如何創(chuàng)建設(shè)備對(duì)象,,利用內(nèi)核API函數(shù)IoCreateDevice創(chuàng)建設(shè)備對(duì)象。OS負(fù)責(zé)申請(qǐng)并管理設(shè)備對(duì)象所需內(nèi)存,并對(duì)其中的一些字段按照輸入?yún)?shù)做了初始化,最后將其掛接在設(shè)備對(duì)象鏈表上。,NTSTATUSIoCreateDevice(INPDRIVER_OBJECTDriverObject,//設(shè)備對(duì)象所對(duì)應(yīng)的驅(qū)動(dòng)對(duì)象INULONGDeviceExtensionSize,//設(shè)備擴(kuò)展區(qū)的大小INPUNICODE_STRINGDeviceNameOPTIONAL,//設(shè)備對(duì)象名稱INDEVICE_TYPEDeviceType,//設(shè)備類型INULONGDeviceCharacteristics,//設(shè)備對(duì)象特征INBOOLEANExclusive,//一般設(shè)為FALSEOUTPDEVICE_OBJECT*DeviceObject//由操作系統(tǒng)創(chuàng)建的設(shè)備對(duì)象//的起始地址利用該參數(shù)返回);,39,如何刪除設(shè)備對(duì)象,,在WDM驅(qū)動(dòng)中,如果接收到IRP_MN_REMOVE_DEVICE消息,則應(yīng)刪除設(shè)備對(duì)象;在NT式驅(qū)動(dòng)中,在DriverUnload函數(shù)中刪除設(shè)備對(duì)象。在創(chuàng)建設(shè)備對(duì)象之后如果出錯(cuò)也應(yīng)該及時(shí)刪除對(duì)象。通過調(diào)用內(nèi)核API函數(shù)IoDeleteDevice刪除設(shè)備對(duì)象,NTSTATUSstatus=IoCreateDevice(...);if(!NT_SUCCESS(status))returnstatus;………….if(){IoDeleteDevice(pdo);returnstatus;},40,設(shè)備對(duì)象的命名,Windows系統(tǒng)中有一個(gè)稱為“對(duì)象管理器”的執(zhí)行模塊復(fù)雜集中管理系統(tǒng)中所有的內(nèi)核對(duì)象,其中包括驅(qū)動(dòng)對(duì)象和設(shè)備對(duì)象。對(duì)象管理器給大多數(shù)內(nèi)核對(duì)象都起了名字,并把這些名字組織為具有樹形結(jié)構(gòu)的命名空間。設(shè)備對(duì)象一般都位于該命名空間的\Device子目錄下其他內(nèi)核模塊和驅(qū)動(dòng)程序都可以通過設(shè)備的名字獲得該設(shè)備對(duì)象的指針(利用IoGetDeviceObjectPointer),并通過該指針向驅(qū)動(dòng)對(duì)象發(fā)送IRP。用戶模式的應(yīng)用程序?qū)Device子目錄沒有訪問權(quán),41,設(shè)備對(duì)象的命名(續(xù)),為了給自己的設(shè)備對(duì)象命名,必須將名字存放在一個(gè)UNCODE_STRING型的字符串中,并將其作為IoCreateDevice的第3個(gè)參數(shù)傳入。,UNICODE_STRINGdevname;RtlInitUnicodeString(,42,設(shè)備對(duì)象名與符號(hào)鏈接,因?yàn)閼?yīng)用程序只能訪問Windows內(nèi)核對(duì)象空間中的“\??”子目錄,而對(duì)對(duì)\Device子目錄沒有訪問權(quán)限,因此必須在“\??”子目錄中創(chuàng)建一個(gè)符號(hào)鏈接,將其指向\Device子目錄中的名字。符號(hào)鏈接就類似于Windows文件系統(tǒng)中的快捷方式創(chuàng)建符號(hào)鏈接的方法是調(diào)用IoCreateSymbolicLink,43,設(shè)備對(duì)象名與符號(hào)鏈接(續(xù)),UNICODE_STRINGdevname;UNICODE_STRINGlinkname;RtlInitUnicodeString(,44,應(yīng)用程序如何通過設(shè)備名打開設(shè)備,在用戶模式下“\??”子目錄叫做“\\.\”子目錄,因此通過“\\.\”子目錄下的符號(hào)鏈接名就可以找到設(shè)備對(duì)象,并打開指向設(shè)備對(duì)象的句柄。,hDevice=CreateFile("\\\\.\\Simple1",GENERIC_WRITE|GENERIC_READ,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);ReadFile(hDevice,lpBuffer,……..);WriteFile(hDevice,lpBuffer,……..);………..,45,創(chuàng)建完設(shè)備對(duì)象后還需做什么,設(shè)置設(shè)備擴(kuò)展對(duì)象的內(nèi)容設(shè)置設(shè)備對(duì)象的flags字段設(shè)定該設(shè)備的工作方式。,fdo->AlignmentRequirement=….fdo->Flags│=DO_BUFFERED_IO│DO_POWER_PAGABLE;,創(chuàng)建設(shè)備對(duì)象棧(可選)等所有準(zhǔn)備工作做完之后一定要清除flags字段的DO_DEVICE_INITIALIZING標(biāo)志告訴OS可以接收IRP了,fdo->Flags,46,第三個(gè)例子程序,47,基于I/O請(qǐng)求包(IRP)的工作方式,48,應(yīng)用程序與驅(qū)動(dòng)程序的通信,Windows應(yīng)用程序與WDM通信的一般過程是:應(yīng)用程序先用CreateFile函數(shù)打開設(shè)備,然后用ReadFile從WDM中讀取數(shù)據(jù),用WriteFile函數(shù)向WDM寫數(shù)據(jù),用DeviceIoControl函數(shù)向WDM發(fā)送自定義的控制信息,最后用CloseHandle函數(shù)關(guān)閉設(shè)備。對(duì)于異步IO請(qǐng)求還可以用CancelIo函數(shù)取消。這些函數(shù)調(diào)用使得IO管理器產(chǎn)生相應(yīng)的IRP發(fā)送給驅(qū)動(dòng)程序,49,第四個(gè)例子程序,- 1.請(qǐng)仔細(xì)閱讀文檔,確保文檔完整性,對(duì)于不預(yù)覽、不比對(duì)內(nèi)容而直接下載帶來的問題本站不予受理。
- 2.下載的文檔,不會(huì)出現(xiàn)我們的網(wǎng)址水印。
- 3、該文檔所得收入(下載+內(nèi)容+預(yù)覽)歸上傳者、原創(chuàng)作者;如果您是本文檔原作者,請(qǐng)點(diǎn)此認(rèn)領(lǐng)!既往收益都?xì)w您。
下載文檔到電腦,查找使用更方便
9.9 積分
下載 |
- 配套講稿:
如PPT文件的首頁顯示word圖標(biāo),表示該P(yáng)PT已包含配套word講稿。雙擊word圖標(biāo)可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國(guó)旗、國(guó)徽等圖片,僅作為作品整體效果示例展示,禁止商用。設(shè)計(jì)者僅對(duì)作品中獨(dú)創(chuàng)性部分享有著作權(quán)。
- 關(guān) 鍵 詞:
- Windows 驅(qū)動(dòng)程序 設(shè)計(jì) 入門
鏈接地址:http://m.hcyjhs8.com/p-12668277.html