Windows驅動程序設計入門.ppt_第1頁
Windows驅動程序設計入門.ppt_第2頁
Windows驅動程序設計入門.ppt_第3頁
Windows驅動程序設計入門.ppt_第4頁
Windows驅動程序設計入門.ppt_第5頁
已閱讀5頁,還剩44頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Windows驅動程序設計入門,2,Windows的虛擬內存管理,3,Windows的虛擬內存管理,Windows的虛擬內存管理機制為應用程序和驅動 程序提供了兩種服務: 使每個進程都擁有自己獨立的內存地址空間;對于32位Windows而言,每個任務可尋址的內存地址空間都為0 x00000000 0 xFFFFFFFF(232, 4GB) 當物理內存不夠4GB時,虛擬內存管理模塊會用磁盤空間模擬內存空間,并且該模擬過程對應用程序是透明的。,4,用戶地址空間與內核地址空間,Windows將每個進程的4GB的獨立地址空間又劃分為用戶地址空間(0 x00000000 0 x7FFFFFFF)和 內核

2、地址空間(0 x80000000 0 xFFFFFFFF)兩部分。 操作系統(tǒng)內核代碼和數據存放在內核地址空間;每個進程自己私有的代碼和數據存放在用戶地址空間 雖然Windows的內核代碼和數據被映射到了每個進程的地址空間中(所有進程看到的內容是相同的),但在實際的物理內存中,只有內核代碼和數據的一份拷貝。,5,用戶地址空間與內核地址空間,6,用戶模式與內核模式,為了更好地保護系統(tǒng),Windwos規(guī)定了兩種處理器工作模式:用戶模式和內核模式。 工作在用戶模式的程序只能使用CPU支持指令集的一個子集,只能訪問用戶空間中的內存,并且不能直接訪問硬件。 工作在內核模式的程序不受任何限制,可以使用CPU

3、支持的任意指令,可以訪問任意的內存空間,可以直接訪問硬件。 所有的Windows應用程序都工作于用戶模式,Windows內核程序都工作于內核模式。 也可以認為:位于用戶空間的代碼都工作于用戶模式,位于內核空間的代碼都工作于內核模式。 應用程序只能通過Windows規(guī)定的一些API訪問內核模式的代碼和數據。,7,Windows 系統(tǒng)結構,8,什么是Windows驅動程序?,Windows驅動程序是一種位于內核地址空間并且 工作于內核模式的一種特殊的程序類型(.sys文件)。 驅動程序是操作系統(tǒng)信任的一個內核擴展模塊。 驅動程序和操作系統(tǒng)之間遵循的是容器與插件模型。OS負責管理Driver的生命周

4、期;Driver是一種被動的軟件模塊。 驅動程序類似于DLL程序,它是一個回調函數(子程序)的集合體,這些函數由OS在適當的時候調用 驅動程序也可以通過Windows內核API獲得OS的一些服務。,9,編驅動程序用什么編程語言?,C語言 C+語言 1的情況下會用到匯編語言 目前還不能用其它高級語言編寫驅動程序。,10,編驅動程序用什么開發(fā)工具?,WDK (Windows Driver Kit) (可以到微軟網站上免費下載) Driver Studio(Compuware NuMega公司的產品)DDK WinDriver DDK,11,WDK中包含什么?,與Windows內核API函數相關的頭

5、文件(如ddk.h, wdm.h等) 與Windows內核API函數相關的導入庫(wdm.lib等) 內核專用C運行時間庫的頭文件和導入庫 關于驅動程序編程模型和內核API函數的幫助文檔 C+編譯器和鏈接器,綜合創(chuàng)建工具 內核調試工具、分析工具,12,內核模式下我們能調用哪些函數?,Windows內核輸出的內核API函數; WDK提供的運行時間庫 其它驅動程序提供的服務,13,內核模式下我們不能調用哪些函數?,Windows的用戶模式API函數; ISO規(guī)定的C/C+標準函數庫,14,最簡單的NT式驅動程序,extern “C” #include extern C NTSTATUS Drive

6、rEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) NTSTATUS status = STATUS_UNSUCCESSFUL; /* KdPrint將輸入字符串發(fā)送到一個特殊內存區(qū), 利用DbgView工具可以觀察該內存區(qū)的內容*/ KdPrint(Hello World!); return status; ,15,關于最簡單驅動的問題,第一個extern “C” 的作用是什么? 第二個extern “C” 的作用是什么? typedef long NTSTATUS; #define IN #ifde

7、f DBG #define KdPrint(a) DbgPrint#a #else #define KdPrint(a) #endif,16,驅動程序的入口函數,NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) return status; ,參數DriverObject表示指向驅動對象的指針; 參數RegistryPath表示該驅動所對應的注冊表服務鍵的子目錄 返回值表示初始化是否成功,17,DDK中一個驅動型工程的組成,MAKEFILE文件,一般不作改動 Sources

8、文件:(1) 指示了整個工程由哪些源程序和資源文件構成; (2) 包含了主要的編譯參數,指導編譯器和鏈接器的工作。 .cpp文件和.h文件 如何build驅動工程? 用DDK中的build工具。build工具會根據MAKEFILE文件和Sources文件以及相關環(huán)境變量的指示編譯并鏈接工程中的.cpp文件和.h文件,18,如何安裝NT型驅動程序?,方法1:在注冊表HKEY_LOCAL_MACHINE SYSTEMCurrentControlSetServices下增加一個新的項目。可以將該服務指定為開機自啟動,也可以指定為按需啟動。如果是按需啟動,則可以用net start命令啟動,用net

9、stop命令停止。 方法2:編寫另外的用戶模式程序利用SCM函數按需啟動。 方法3:在調試階段可以利用第三方的工具如:DriverMoniter和IntallDriver隨時安裝和卸載。,19,如何調試驅動程序?,方法1:打印調試信息。即用DbgPrint函數打印調試信息,然后在驅動運行時用Dbgview等工具觀察這些信息。 方法2:分析內存轉儲(dump)文件。 方法3:使用WinDbg、SoftICE等高級調試工具。,20,用WinDbg+VMWare進行雙機調試,Step1:安裝WinDbg和VMWare,并在VMWare中安裝好Windows XP。 Step2:設置好WMWare的虛

10、擬串口 Step3:將虛擬機中的Windows XP設置為調試運行模式。(修改boot.ini 文件) Step4:以調試方式啟動虛擬機中的Windows XP Step5:啟動WinDbg Step6:設置WinDbg的Symbol文件路徑,設置C源程序路徑。 Step7:設置斷點,監(jiān)視變量,21,HelloWorld版的WDM驅動程序,extern “C” #include “wdm.h” extern C NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) NTSTAT

11、US status = STATUS_DEVICE_CONFIGURATION_ERROR; KdPrint(Hellow World!); return status; ,22,如何安裝WDM驅動程序?,必須編寫一個安裝指示文件(.inf)指導Windows將驅動程序安裝到指定位置(一般安裝在windowssystem32drivers子目錄下),并在注冊表中進行登記。 對于即插即用類設備的驅動,操作系統(tǒng)會自動發(fā)現該設備并調用“添加新硬件”程序向用戶詢問相應的inf文件的位置。 對于非即插即用類設備的驅動,用戶必須自己手動調用“添加新硬件”程序,并通過告訴該程序inf文件的位置。,23,in

12、f文件主要包含了哪些內容?,設備類型、設備型號、廠商信息、程序版本號。 對操作系統(tǒng)版本和CPU類型的要求 源文件(.sys文件)的文件名和所在位置 安裝目標子目錄 在注冊表中添加哪些內容 硬件配置信息 安全配置信息,24,驅動對象(Driver Object),在操作系統(tǒng)首次裝載一個驅動程序之后,它會創(chuàng)建一個數據結構用來記錄該驅動,該數據結構我們稱為驅動對象(Driver Object)。 驅動對象記錄與驅動程序本身相關的信息,它主要包含了除了DriverEntry之外的其它驅動程序入口函數的入口地址。(驅動程序是一種具有多個入口函數的程序) 驅動對象是由操作系統(tǒng)創(chuàng)建,然后作為DriverEn

13、try的第一個參數傳遞給你的程序。 在獲得驅動對象的指針之后,你的程序需要對其中的一些字段進行初始化。,25,驅動對象(Driver Object),驅動對象在DDK的頭文件(ntddk.h)中按如下方式定義:。,typedefstruct_DRIVER_OBJECT CSHORTType; CSHORTSize; DRIVER_OBJECT,*PDRIVER_OBJECT;,由上面的定義可以看成,驅動對象不同于C+中的Class,它只是一個Struct。,26,27,驅動對象的一些關鍵字段(一),DriverStartIo (PDRIVER_STARTIO) : 指向StartIO入口函數的

14、指針. DriverUnload (PDRIVER_UNLOAD) :指向DriverUnload入口函數的指針。在驅動程序被從內存中卸載時,DriverUnload入口函數會被操作系統(tǒng)調用,你應該在該函數內部做一些與DriverEntry向對應的資源清除工作。 MajorFunction (一個數組,數組中每一元素又是一個指向函數的指針 PDRIVER_DISPATCH):數組中每一個指針指向一個入口函數。在接收到不同的請求包(IRP)時,OS會調用不同的入口函數。,28,驅動對象的一些關鍵字段(二),DeviceObject (PDEVICE_OBJECT) : 指向一個鏈表的指針,該鏈表

15、中每一個節(jié)點都存儲了一個FDO對象。每一個FDO都代表一個由該驅動維護的硬件設備實例。在WDM模型中,該鏈表由OS自動維護。 DriverExtension (PDRIVER_EXTENSION) :指向另外一個結構體,該結構體中唯一有用的字段為 AddDevice 。AddDevice字段指向一個入口函數。在操作系統(tǒng)發(fā)現一個新的設備實例時,它會自動調用AddDevice函數,你應該在該函數中做一些與設備實例相關的初始化工作。,29,DriverEntry函數的主要工作,在操作系統(tǒng)創(chuàng)建的驅動對象中填寫其它入口函數的地址,使得操作系統(tǒng)在必要的時候能夠找到這些入口函數并調用它們。 創(chuàng)建一個或多個設

16、備對象,并將這些對象掛接在驅動對象所指示的鏈表上。(只針對NT型驅動) 與該設備相關的其他初始化工作,VOID (*PDRIVER_UNLOAD) ( IN PDRIVER_OBJECT DriverObject); VOID (*PDRIVER_STARTIO) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS (*PDRIVER_DISPATCH) (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS (*PDRIVER_ADD_DEVICE) ( IN PDRIVE

17、R_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject );,30,DriverUnload函數的主要工作,刪除以鏈表形式掛接在驅動對象上的一個或多個 設備對象。(只針對NT型驅動) 進行與DriverEntry函數中相對應的反初始化工作。例如如果在DriverEntry函數中申請了堆內存,那么在DriverUnload函數中應該釋放該堆內存。,VOID DriverUnload(PDRIVER_OBJECT DriverObject) RtlFreeUnicodeString( ,31,第二簡單的驅動程序,extern “C

18、” #include VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject); NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp); extern C NTSTATUS DriverEntry ( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) NTSTATUS status = STATUS_SUCCESS; KdPrint(Enter DriverEntryn

19、); KdPrint(RegistryPath: %wZn, pRegistryPath); pDriverObject-DriverUnload = HelloDDKUnload; pDriverObject-MajorFunctionIRP_MJ_CREATE = HelloDDKDispatchRoutine; pDriverObject-MajorFunctionIRP_MJ_CLOSE = HelloDDKDispatchRoutine; pDriverObject-MajorFunctionIRP_MJ_WRITE = HelloDDKDispatchRoutine; pDrive

20、rObject-MajorFunctionIRP_MJ_READ = HelloDDKDispatchRoutine; KdPrint(Leave DriverEntryn); return status; ,32,第二簡單的驅動程序(續(xù)),VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject) KdPrint(Enter DriverUnloadn); KdPrint(Leave DriverUnloadn); NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PI

21、RP pIrp) NTSTATUS status = STATUS_SUCCESS; KdPrint(Enter HelloDDKDispatchRoutinen); KdPrint(Leave HelloDDKDispatchRoutinen); return status; ,33,設備對象(Device Object),針對每一個硬件設備,Windows都需要用一個數據結構來記錄它的相關信息,這個數據結構就叫做 設備對象(Devcie Object)。 因為一個驅動程序可以同時管理多個同類型的硬件設備,因此一個驅動對象可以對應多個設備對象。 對應同一個驅動對象的多個設備對象構成一個鏈表掛

22、接在驅動對象的DeviceObject字段上。 設備對象由驅動程序負責創(chuàng)建和初始化,由操作系統(tǒng)負責保存和管理。 設備對象可以有名字,其他驅動程序或應用程序可以通過該名字找到該設備對象。,34,The Device Object,35,設備對象的一些關鍵字段(一),DriverObject (PDRIVER_OBJECT) :指向與該設備對象相對應的驅動對象的指針。 NextDevice (PDEVICE_OBJECT):指向下一個設備對象的指針,利用該字段與同一個驅動對象對應的多個設備對象就可以構成一個單鏈表,該鏈表最后掛接在驅動對象的DeviceObject字段上。,36,設備對象的一些關鍵

23、字段(二),Flags (ULONG):保存了一些標志位,這些標志位指示了該設備的一些工作方式。,37,設備對象的一些關鍵字段(三),Characteristics (ULONG) : 另外一組標志位集合。 DeviceExtension (PVOID) :指向一個擴展內存區(qū),該內存區(qū)的大小和使用方式由程序員規(guī)定。一般在該區(qū)域存放一個自定義的結構體,用于存儲硬件設備特有的信息。今后稱該結構體為設備擴展對象。該擴展內存區(qū)由操作系統(tǒng)負責創(chuàng)建并維護。 DeviceType (DEVICE_TYPE):一個枚舉型變量,指明該設備的類型 (FILE_DEVICE_UNKNOWN) AlignmentRe

24、quirement (ULONG):指定該設備使用內存時的對齊方式( FILE_BYTE_ALIGNMENT、 FILE_WORD_ALIGNMENT FILE_512_BYTE_ALIGNMENT ),38,如何創(chuàng)建設備對象,利用內核API函數 IoCreateDevice創(chuàng)建設備對象。OS負責申請并管理設備對象所需內存,并對其中的一些字段按照輸入參數做了初始化,最后將其掛接在設備對象鏈表上。,NTSTATUS IoCreateDevice( IN PDRIVER_OBJECT DriverObject, /設備對象所對應的驅動對象 IN ULONG DeviceExtensionSize,

25、 /設備擴展區(qū)的大小 IN PUNICODE_STRING DeviceName OPTIONAL, /設備對象名稱 IN DEVICE_TYPE DeviceType, /設備類型 IN ULONG DeviceCharacteristics, /設備對象特征 IN BOOLEAN Exclusive, / 一般設為FALSE OUT PDEVICE_OBJECT *DeviceObject /由操作系統(tǒng)創(chuàng)建的設備對象 / 的起始地址利用該參數返回 );,39,如何刪除設備對象,在WDM驅動中,如果接收到 IRP_MN_REMOVE_DEVICE 消息,則應刪除設備對象;在NT式驅動中,在D

26、riverUnload函數中刪除設備對象。 在創(chuàng)建設備對象之后如果出錯也應該及時刪除對象。 通過調用內核API函數IoDeleteDevice 刪除設備對象,NTSTATUS status = IoCreateDevice(.); if (!NT_SUCCESS(status) return status; . if () IoDeleteDevice(pdo); return status; ,40,設備對象的命名,Windows系統(tǒng)中有一個稱為“對象管理器”的執(zhí)行模塊復雜集中管理系統(tǒng)中所有的內核對象,其中包括驅動對象和設備對象。 對象管理器給大多數內核對象都起了名字,并把這些名字組織為具有

27、樹形結構的命名空間。 設備對象一般都位于該命名空間的Device子目錄下 其他內核模塊和驅動程序都可以通過設備的名字獲得該設備對象的指針(利用IoGetDeviceObjectPointer),并通過該指針向驅動對象發(fā)送IRP。 用戶模式的應用程序對Device子目錄沒有訪問權,41,設備對象的命名(續(xù)),為了給自己的設備對象命名,必須將名字存放在一個UNCODE_STRING型的字符串中,并將其作為IoCreateDevice的第3個參數傳入。,UNICODE_STRING devname; RtlInitUnicodeString(,42,設備對象名與符號鏈接,因為應用程序只能訪問Windows內核對象空間中的“?”子目錄,而對對Device子目錄沒有訪問權限,因此必須在“?”子目錄中創(chuàng)建一個符號鏈接,將其指向D

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論