如何寫驅(qū)動程序_第1頁
如何寫驅(qū)動程序_第2頁
如何寫驅(qū)動程序_第3頁
如何寫驅(qū)動程序_第4頁
如何寫驅(qū)動程序_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、我這里重點的介紹如何寫驅(qū)動程序,對于一些應用程序我就不做介紹了,因 為 我對于那些高層的東西寫得很少。倘若再講,有班門弄斧之嫌,呵呵!作為WIN98和WIN2K4薦的一項新技術來說,USB的驅(qū)動程序和以往的直接跟硬件 打交道的WIN95勺VXD的方式的驅(qū)動程序不同,它應該是 WD類型的。USB的 WD接口框圖如下(這個圖可以說是 USB軟件總體框圖)HIDCUS.SYSOttierJS0Drivernterface USB Drwer HIDLSBSYS |ClientsUSBHUB-SYSUS&DSYSUSB Driver SlackUHCO SYSOpenHClSrSF*Cl Ehumeo

2、torUSBBu對于HID的設備,就可以采用上圖左上邊的結(jié)構(gòu),其它類的話采用右上的結(jié)構(gòu),其實右邊的結(jié)構(gòu)可以又細分成兩層,一層是 Class Driver ,一層是Miniport Driver。而倒數(shù)第三行的 UHC和OpenHC分別是由INTEL和COMPA兩位老大 定 的一個和硬件有關的底層驅(qū)動程序標準,各位可以根據(jù)所需要的選擇。對于USB的驅(qū)動程序,大家還得去了解 WDMg動程序的寫法,或者早些時候 的 NT驅(qū)動程序,其實 WD驅(qū)動程序可以看做是NT驅(qū)動程序的一個update,只是 增加了一些新的特性?!皩戲?qū)動程序是一個很漫長和繁瑣的工作,在此之前,你最好要熟悉硬件,熟悉C/C+,還要用

3、過DDK會用一些調(diào)試程序,如SOFTICE和 WINDBGL類。女口 果一切就緒,你就可以開始寫驅(qū)動程序,工作的進程有時侯會取決于你的運 氣”。(這是一位留美的朋友對我說的,我寫出來和大家共享)下面是我從一個朋友那里得到的一篇文章的摘要:NT驅(qū)動程序的分層 結(jié)構(gòu)驅(qū)動程序是指管理某個外圍設備的一段程序代碼。NT采用更靈活的分層驅(qū)動方法,允許雜應用程序和硬件之間存在幾個驅(qū)動程序?qū)哟?。分層機制允許 NT更加廣泛地定義驅(qū)動程序,包括文件系統(tǒng)、邏輯卷管理器和各種網(wǎng)絡組件,各種物理設備驅(qū)動程序等等。1、設備驅(qū)動程序這些是管理實際數(shù)據(jù)傳輸和控制特定類型的物理設備的操作的驅(qū)動程序,包括開始和完成I/O操作,處

4、理中斷和執(zhí)行特定的設備要求的任何差錯處理。2、中間驅(qū)動程序NT允許在物理設備 驅(qū)動程序上分層任意數(shù)目的中間驅(qū)動程序。這些中間層次提 供擴展 I/O 系統(tǒng)的功能一種方法,而不必修改底層的驅(qū)動程序。這也是微軟 鼓 吹的他們的系統(tǒng)靈活的一面!實際上我覺得這樣反而犧牲了一些效率上的東 西3、文件系統(tǒng)驅(qū)動程序 (FSD)FSD是一類比較特殊的驅(qū)動程序,通常負責維護各種文件 系統(tǒng) 所需要的磁盤結(jié) 構(gòu)。注意我們并不能使用 DDK來開發(fā)FSD而必須使用 Microsoft的文件系統(tǒng) 開發(fā)人員工具包。一般比較少寫中間過濾驅(qū)動程序,過濾驅(qū)動程序它截獲和修改高層發(fā)送給類 驅(qū) 動程序的請求。這樣就允許利用現(xiàn)有類驅(qū)動程

5、序的功能,而不必從頭開始寫 所 有程序。NT內(nèi)核模式對象在我們的實際開發(fā)過程中的對 象是設備,由于端口 驅(qū)動程序已經(jīng)隱藏了硬件控制操作,因此我在這里不講述跟硬件相關的部份 。 如果今后的開發(fā)對象不同,需要對硬件進行操作的時候,可能會對中斷、DMA等有比較詳細的了解,這些內(nèi)容可以參考 DDK幫助。NT使用對象技術管理所有的數(shù)據(jù),下面分別對一般驅(qū)動程序所涉及的一些對象 做一介紹。不過在介紹這些對象之前,有必要先對驅(qū)動程序的結(jié)構(gòu)做一介紹 驅(qū)動程序結(jié)構(gòu)NT驅(qū)動程序和一般的DOS/WindowsC語言程序不一樣,它沒有 main()或者 WinMain()函數(shù)入口。和DLL類似地,它向操作系統(tǒng)顯露一個名

6、稱為 DriverEntry() 的函數(shù),在啟動驅(qū)動程 序的時候,操作系統(tǒng)將調(diào)用這個入口。 DriverEntry 除了做一些必要的設備初始化工作外,還初 始化一些 Dispatch 例 程入口。我們知道,NT應用和設備驅(qū)動程序打交道主要是通過 CreateFile、ReadFile、WriteFile 和 DeviceIoControl 等 Win32 API 來進行的。這些 API 其 實都對應著驅(qū)動程序的一些 Dispatch 例程。 而驅(qū)動程序除了 DriverEntry 以 外, 主要就是由這些 Dispatch 例程組 成的。例如調(diào)用 Win32 API CreateFile的時候

7、,操作系統(tǒng)最終轉(zhuǎn)化為對驅(qū)動程序IRP_MJ_CREAT功能代碼所對應的 Dispatch 例程的調(diào) 用,如果驅(qū)動程序沒有提供該例程, CreateFile 調(diào)用就會 失敗。NT中一些常用的功能代碼和Win32 API的對象關系如下所示。 功能代碼說明IRP_MJ_CREATE打開設備 CreateFileIRP_MJ_CLEANUP在關閉設備時,取消掛起的 I/O 請求 CloseHandleIRP_MJ_CLOSE關閉設備 CloseHandleIRP_MJ_READ從設備獲得數(shù)據(jù) ReadFileIRP_MJ_WRITE 向 設備發(fā)送數(shù)據(jù) WriteFileIRP_MJ_DEVICE_CO

8、NTROL 對用戶模式或內(nèi)核 模式客戶程序可用的控制操作 DeviceIoControl IRP_MJ_INTERNAL_DEVICE_CONTROL只對內(nèi)核模式客戶程序可用的控制操作IRP_MJ_QUERY_INFORMATIONGetFileLengthIRP_MJ_SET_INFORMATIONSetFileLengthIRP_MJ_FLUSH_BUFFERS丟棄輸入緩沖區(qū)FlushFileBuffersFlushConsoleInputBufferPurgeCommIRP_MJ_SHUTDOWNInitialSystemShutdown和上面的驅(qū)動程序支持的功能代碼相對應, 樣子。Dr

9、iverEntry()/ 驅(qū)動程序入口得到文件的長度設置文件的長度寫輸出緩沖區(qū)或系統(tǒng)關閉般的驅(qū)動程序看起來就象下面 的DeviceObject-MajorFunctionIRP_MJ_CREATE = XXDriverCreateClose; /XX 對應的是你自 己給你的驅(qū)動程序的命名 DeviceObject- MajorFunctionIRP_MJ_CLOSE = XXDriverCreateClose; DeviceObject-MajorFunctionIRP_MJ_READ = XXDriverReadWrite; DeviceObject-MajorFunctionIRP_MJ_

10、WRITE = XXDriverReadWrite;XXDriverCreateClose()/ 對應 IRP_MJ_CREATE IRP_MJ_CLOS的例程 / .XXDriverDeviceControl()對應 IRP_MJ_DEVICE_CONTRO例程/ .XXDriverReadWrite()/ 對應 IRP_MJ_REA和 IRP_MJ_WRIT的例程/ .一個驅(qū)動程序并不需要支持所有的功能代碼,比如如果一個驅(qū)動程序根本就不必要與用戶模式客戶程序交互,那么就不用支持irp_mj_createIRP_MJ_CLOSE又如設備不支持設備讀寫,就不用支持 IRP_MJ_REA和IRP

11、_MJ_WRITE驅(qū)動程序?qū)ο笫窃诓僮飨到y(tǒng)啟動驅(qū)動程序、在調(diào)用驅(qū)動程序入口 DriverEntry 之前就已經(jīng)創(chuàng)建好了的,并且作為 DriverEntry 函數(shù)的參數(shù)傳 遞給驅(qū)動程序。如果驅(qū)動程序啟動失敗,操作系統(tǒng)將刪除該對象。該對象的數(shù)據(jù)結(jié)構(gòu)如下。注意下表并不是完整地列出了ntddk.h中的DEVICE_OBJECT構(gòu)體的所有數(shù)據(jù)項,這里僅列出了一般驅(qū)動程序可能使用到的數(shù)據(jù)項。Driver對象數(shù)據(jù)項說明PDEVICE_OBJECTDeviceObject由本驅(qū)動程序創(chuàng)建的Device對象 的鏈表ULONG FlagsPDRIVER_INITIALIZEDriverl nit驅(qū)動程序初始化例程

12、(一般較少用)PDRIVER_STARTIOriverStartIoStartlo例程入口,一般該例程對 低層設備驅(qū)動程序用得較多,高層 驅(qū)動程序較少使用本例程。PDRIVER_UNLOADriverU nload卸載驅(qū)動程序例程,如果想在控制面 版的設備里停止該設備,應該提供本 例程。PDRIVER_DISPATCHMajorFu nctio n IRP_MJ_MAXIMUM_FUNCTIO + 1)N驅(qū)動程序的Dispatch例程表在上面提到過驅(qū)動程序是管理同類型的所有設備,所以上面的結(jié)構(gòu)中 DeviceObject指向的就不是單個的設備對象,而是一個對象鏈表,這個鏈表的 維護在下面介紹

13、Device對象時可以看到。Device對象與Device Extension驅(qū)動程序在調(diào)用loCreateDevice函數(shù)成功后就創(chuàng)建了一個 Device對象。下面 對Device對象幾個比較重要的數(shù)據(jù)做 一介紹。Device對象數(shù)據(jù)項說明PVOID DeviceExte nsion指向Device Extension結(jié)構(gòu)的指針PDRIVER_OBJECTDriverObject指向這個設備的Driver對象的指針,loCreateDevice 會自動填寫本數(shù)據(jù)。ULONG Flags指定這個設備的緩沖策略PDEVICE_OBJECT NextDevice指向?qū)儆谶@個驅(qū)動程序的下一個設備對象

14、,依靠本數(shù)據(jù) 來維護設備對象鏈表CCHAR StackSize發(fā)送到這個設備的IRP需要的I/O堆棧單元的最小數(shù)目, 一般對分層驅(qū)動程序來說,本數(shù)據(jù)應該比其下層設備的 大1ULONGAlig nmen tRequireme nt緩沖區(qū)要求的內(nèi)存對齊,一般對分層驅(qū)動程序來說,本 值應該和其下層設備的對齊一致Device記錄著設備 的特徵和狀態(tài)信息,對系統(tǒng)上的每個虛擬的、邏輯的和物理 的設備都有一個Device對象。例如對一個硬盤驅(qū)動程序,對一個物理硬盤有一 個名稱為PartitionO 的Device對象,對應整個物理磁盤,同時對硬盤的每個分區(qū),也都有一個 Device對象,它們的名稱分別為 P

15、artitionX(X 從1開始, 每個分區(qū)對應一個數(shù)字)。Device Extension是連接到Device對象的一個很重要的數(shù)據(jù)結(jié)構(gòu),它的數(shù)據(jù) 結(jié)構(gòu)是由驅(qū)動程序設計者自己來確定的,在調(diào)用 loCreateDevice的時候應該指 定它的大小,Device Exte nsion其實是由操作系統(tǒng)在非份頁內(nèi)存池中為每個 Device對象分配的一塊內(nèi)存。由于驅(qū) 動程序必須是完全可重入的,因此使用任何全局變量和靜態(tài)變量都不是好的辦法,一般來說和設備有關的任何需要保持的信息都應該放到Device Extension里去。設備的緩沖策略也必須提一下,這里的 Flag的緩沖策略主要 決定設備讀寫(功 能

16、代碼IRP_MJ_REA和IRP_MJ_WRITE時候的緩沖策略,另外功能代碼 IRP_MJ_DEVICE_CONTRO候的緩沖策略是由IOCTL控制代碼本身來決定的。 兩者不能混為一談。在下面我將專門用一節(jié)來討論I/O的緩沖策略。I/O請求包(IRP)在上面的結(jié)構(gòu)里面已經(jīng)出現(xiàn)了 IRP 了,在這里對它做一說明。 在NT中,幾乎 所有的I/O都是包驅(qū)動的,可以說驅(qū)動程序和操作系統(tǒng)其他部份都是通過I/O請求包來進行交互的。我們 來看看一個I/O請求的執(zhí)行過程。(1) 操作系統(tǒng)的I/O管理器從非分頁內(nèi)存分配一個IRP,響應一個I/O請求。 基于由客戶指定的I/O函數(shù),I/O管理器將該IRP傳遞給合

17、適的驅(qū)動程序的 Dispatch 例程。(2) Dispatch例程檢查請求的參數(shù)是否有效,如果有效,驅(qū)動程序根據(jù)請求的 內(nèi)容進行一系列的操作。否則設置錯誤狀態(tài)信息直接返回。操作完成時,將數(shù)據(jù)(如果有)和狀態(tài)信息存放到IRP中并返回給I/O管理 器。(4) I/O管理器對返回的IRP進行適當?shù)奶幚砗髮⒆詈鬆顟B(tài)和數(shù)據(jù)(如果有)返回給用戶。一個IRP的主要數(shù)據(jù)項如下表所示。IRP包括一個IRP頭和一個IRP stack的區(qū)域。由于 WD的模式下都是包驅(qū)動 的,所里IRP可以說是一個非常重要的東東。還有那個該死的URB(GoddamnURB!)人一輩子真的很過癮,有些人或有些事你明明不喜歡或做不來,

18、可是有時侯你又不得不硬著頭皮去做,就像一大堆球迷圍著一堆狗屎般的中國足球,那班傻兒真是要錢不要臉,丟咱中國人的臉RP主要數(shù)據(jù)項說明O STATUS BLOC6tatus存放I/O請求的狀態(tài)PVOIDAssociatedlrp.SystemBuffer如果設備執(zhí)行緩沖I/O ,則為指向系統(tǒng)空間緩 沖 區(qū)的指針。否則為NULLPMDL MdlAddress如果設備執(zhí)行直接I/O ,指向用戶空間緩沖區(qū)的內(nèi)存描述表的指針PVOID UserBufferI/O緩沖區(qū)的用戶空間地址BOOLEAN Cancel扌曰示IRP已被取消關于 Associatedlrp.SystemBuffer 、MdlAddre

19、ss 和 UserBuffer 將在下面的 I/O緩沖區(qū)策略里面更詳細地討論。NT還有更多其他的 對象,例如中斷對象、Controller對象、定時器對象等等, 但在我們開發(fā)的驅(qū)動程序中并沒有用到,因此在這里不做介紹。I/O緩沖策略很明顯的,驅(qū)動程序和客戶應用程序經(jīng)常需要進行數(shù)據(jù)交換,但我們知道驅(qū)動程序和客戶應用程序可能不在同一個地址空間,因此操作系統(tǒng)必須解決兩者之間的數(shù)據(jù)交換。這就就設計到設備的I/O緩沖策略。讀寫請求的I/O緩沖策略前面說到通過設置Device對象的Flag可以選擇控制處理讀寫請求的I/O緩沖 策略。下面對這些緩沖策略分別做一介紹。1、緩沖 l/O(DO_BUFFERED_

20、IO)在讀寫請求的一開始,I/O管理器檢查用戶緩沖區(qū)的可訪 問性,然后分配與調(diào) 用者的緩沖區(qū)一樣大的非分頁池,并把它的地址放在IRP的Associatedlrp.SystemBuffer 域中。驅(qū)動程序就利用這個域來進行實際數(shù)據(jù)的 傳輸。對于IRP_MJ_REA讀請求,I/O管理器還把IRP的UserBuffer域設置成調(diào)用者 緩沖區(qū)的用戶空間地址。當請求完成時,I/O管理器利用 這個地址將數(shù)據(jù)從驅(qū) 動程序的系統(tǒng)空間拷貝回調(diào)用者的緩沖區(qū)。對于IRP_MJ_WRIT寫請求,UserBuffer被設置為NULL并把用戶緩沖 區(qū)的數(shù)據(jù)拷貝到系統(tǒng)緩沖區(qū)中。2、直接 I/O(DO_DIRECT_IO)I

21、/O管理器首先檢查用戶緩沖區(qū)的可訪問性,并在物理內(nèi)存中鎖定它。然后它為該緩沖區(qū)創(chuàng)建一個內(nèi)存描述表(MDL),并把MDL的地址存放在IRP的MdlAddress 域中。AssociatedIrp.SystemBuffer 和 UserBuffer 都被設置為 NULL驅(qū)動程序可以調(diào)用函數(shù) MmGetSystemAddressForMd得到用戶緩沖區(qū)的 系統(tǒng)空間地址,從而 進行數(shù)據(jù)操作。這個函數(shù)將調(diào)用者的緩沖區(qū)映射到非份頁 的地址空間。驅(qū)動程序完成I/O請求后,系統(tǒng)自動從系統(tǒng)空間解除緩沖區(qū)的 映 射。3、這兩種方法都不是這種情況比較少用,因為這需要驅(qū)動程序自己來處理緩沖問題。I/O管理器僅把調(diào)用者

22、緩沖區(qū)的用戶空間地址放到IRP的UserBuffer域中。我們并不推薦這種方式。IOCTL緩沖區(qū)的緩沖策略IOCTL請求涉及來自調(diào)用者的輸入緩沖區(qū)和返回到調(diào)用者的輸出 緩沖區(qū)。為了理解IOCTL請求,我們先來看看 WIN32 API DeviceIoControl函數(shù)的原型。 BOOLDeviceIoC on trol (HANDLE hDevice, / 設備句柄DWORD dwIoC on trolCode,/ IOCTL 請求操作代碼LPVOID lpInBuffer, / 輸入緩沖區(qū)地址 DWORDnInBufferSize, / 輸入緩沖區(qū)大小 LPVOID lpOutBuffer,

23、 / 輸 出緩沖區(qū)地址 DWORDnOutBufferSize, / 輸 出緩沖區(qū)大小 LPDWORD lpBytesReturned, / 存放返回字節(jié)數(shù)的指 針 LPOVERLAPPElpDOverlapped / 用于同步操作的 Overlapped 結(jié)構(gòu)體指針 );IOCTL請求有四種緩沖策略,下面一一介紹。1、 輸入輸出緩沖 I/O(METHOD_BUFFERED)I/O 管理器首先分配一個非分頁池,它足夠大地存放調(diào)用者的輸入或輸出緩 沖 區(qū)(不管哪個更大)。非分頁緩沖區(qū)的地址放在IRP的Associatedlrp.SystemBuffer 域中,然后把IOCTL的輸入數(shù)據(jù)拷貝到這個

24、非份 頁緩沖區(qū)中,并把IRP的UserBuffer域設置成調(diào)用者輸出緩沖區(qū)的用戶空間地 址。當驅(qū)動程序完成IOCTL請求時,I/O管理器將這個非份頁緩沖區(qū)中的數(shù)據(jù) 拷貝到調(diào)用者的輸出緩沖區(qū)。注意這里同一個非份頁池同時用于輸入和輸出 緩 沖區(qū),因此驅(qū)動程序在向緩沖區(qū)寫東西之前應該把輸入的所有數(shù)據(jù)讀出來。2、直接輸入緩沖輸出 I/O(METHOD_IN_DIRECT)I/O 管理器首先檢查調(diào)用者輸入緩沖區(qū)的可訪問性,并在 物理內(nèi)存中將其鎖定。 然后為該輸入緩沖區(qū)創(chuàng)建一個MDL并把指定該MDL的指針存放到IRP的 MdlAddress域中。同時,I/O管理器還在非份頁池中分配一輸出緩沖區(qū),并把這個緩

25、沖區(qū)的地址存放在 IRP 的 AssociatedIrp.SystemBuffer 域中,并把 IRP 的 UserBuffer 域設置成調(diào)用者輸出緩沖區(qū)的用戶空間地 址。當驅(qū)動程序完成 IOCTL 請求時, I/O 管理器將非份頁緩沖區(qū)中的數(shù)據(jù)拷貝到調(diào)用者的輸出緩沖區(qū)。3、緩沖輸入直接輸出 I/O(METHOD_OUT_DIRECT)I/O 管理器首先檢查調(diào)用者輸出緩沖區(qū)的可訪問性,并在 物理內(nèi)存中將其鎖定。 然后為該輸出緩沖區(qū)創(chuàng)建一個MDL并把指定該MDL的指針存放到IRP的 MdlAddress域中。同時,I/O管理器還在非份頁池中分配一輸入緩沖區(qū),并把 這個緩沖區(qū)的地址存放在 IRP

26、的 AssociatedIrp.SystemBuffer 域中 ,同時把調(diào) 用者用戶輸入緩沖區(qū)中的數(shù)據(jù)拷貝到系統(tǒng)緩沖區(qū)中,并把IRP的UserBuffer域設置為 NULL。4、上面三種方法都不是 (METHOD_NEITHER)I/O管理器把調(diào)用者的輸入緩沖區(qū)的地址放到IRP當前I/O堆棧單元的Parameters.Devi ceIoControl.TypeInputBuffer 域中,把輸出緩沖 區(qū)的地址 存放到IRP的UserBuffer域中。這兩個地址都是用戶空間地 址。 從上面的說 明可以看出,在執(zhí)行緩沖 I/O 時, I/O 管理器將在非份頁池 中分配 內(nèi)存,如果 調(diào)用者的緩沖區(qū)比

27、較大時,分配的非份頁池也將比較大。非份頁 池 是系統(tǒng)比較 寶貴的資源,因此,如果調(diào)用者的緩 沖區(qū)比較大時,我們一般采用 直接 I/O 的 方式(例如磁盤讀寫請求等 ) ,這樣不僅節(jié)省系統(tǒng)資源,另一方面 由 于省去了 I/O 管理器在系統(tǒng)緩沖 區(qū)和調(diào)用者緩沖區(qū)之間的數(shù)據(jù)拷貝,也提高了 效率,這 對存在大量數(shù)據(jù)傳送的驅(qū)動程序尤其明顯??梢宰⒁獾紻DK中的Samples下,幾乎所有的例程的讀寫請求都是直接I/O的,而對于IOCTL請求則是緩沖區(qū)I/O的居多。開始驅(qū)動程序設計下面的文字是從 Microsoft的DDK幫助中節(jié)選出來的,它讓我們明白在開始設計驅(qū)動程序應該注意些什么問題,這些都是具有普遍

28、意義的開發(fā)準則。應該支 持哪些 I/O 請求在開始寫任何代碼之前, 應該首先確定我們的驅(qū)動程序應該處 理哪些 IRP 例程。如果你在設計一個設備驅(qū)動程序,你應該支持和其他相同類型設備的NT驅(qū)動程序相同的IRP_MJ_XXX口 IOCTL請求代碼。如果你是在設計一個中間層 NT驅(qū)動程序,應該首先確認你下層 驅(qū)動程序所管 理的設備,因為一個高層的驅(qū)動程序必須具有低層驅(qū)動程序絕大多數(shù)IRP_MJ_XXX例程入口。高層驅(qū)動程序在接到I/O請求時,在確定自身IRP當前 堆棧單元參數(shù)有效的前提下,設置好IRP中下一個低層驅(qū)動程序的堆棧單元, 然后再調(diào)用 IoCallDriver 將請求傳遞給下層 驅(qū)動程序

29、處理。 一旦決定好了你的驅(qū)動程序應該處理哪些IRP_MJ_XX,X 就可以開始 確定驅(qū)動程序應該有多少個Dispatch例程。當然也可以考慮把某些RP_MJ_XX處理的 例程合并為同一例程處理。例如在 ChangerDisk 和 VDisk 里,對IRP_MJ_CREATE IRP_MJ_CLOS處理的例程就是同一函數(shù)。對 IRP_MJ_REA和 IRP_MJ_WRIT處理的例程也是同一個函數(shù)。應該有多少個 Device 對象? 一個驅(qū)動程序必須為它所管理的每個可能成為 I/O 請求的目標的物理和邏輯 設 備創(chuàng)建一個命名 Device 對象。一些低層的驅(qū)動程 序還可能要創(chuàng)建一些不確定數(shù) 目的

30、Device 對象。例如一個硬盤驅(qū)動程序必須為每一個 物理硬盤創(chuàng)建一個 Device 對象,同時 還必須為每個物理磁盤上的每個邏輯分區(qū)創(chuàng)建一個 Device 對 象。一個高層驅(qū)動驅(qū)動程序必須為它所代表的虛擬設備創(chuàng)建一個 Device 對象,這 樣更高層的驅(qū)動程序才能連接它們的 Device 對象到這個驅(qū)動程序的 Device 對 象。另外,一個高層驅(qū)動程序通常為它低層驅(qū)動程序所創(chuàng)建的 Device 對象創(chuàng)建 一系列的虛擬或邏輯 Device 對象。 盡管你可以分階段來設計你的驅(qū)動程序,因此一個處在開發(fā)階段的驅(qū)動程序 不 必 一開始就創(chuàng)建出所有它將要處理的所有 Device 對象。但從一開始就確

31、定好你 最 終要創(chuàng)建的所有 Device 對象將有助于設計者所 要解決的任何同步問題。另外, 確 定所要創(chuàng)建的 Device 對象還有助于你定義 Device 對象的 Device Extension 的內(nèi) 容和數(shù)據(jù)結(jié)構(gòu)。開始驅(qū)動程序開發(fā)驅(qū)動程序的開發(fā)是一個從粗到細逐步求精的過程。 NT DDK的目錄下有一個龐大的樣板代碼,幾乎覆蓋了所有類型的設備驅(qū)動程序、高層驅(qū)動程序和 過 濾器驅(qū)動程序。在開始開發(fā)你的驅(qū)動程序之前,你應該在這個樣板庫下面尋 找 是否有和你所要開發(fā)的類似類型的例程。例如我們所開發(fā)的驅(qū)動程序,雖然DDK對USB苗述得不是很詳細,我們還是可以在 srcstorage class目

32、錄發(fā)現(xiàn) 很多和USB設備有關的驅(qū)動程序。下面我們來看開發(fā)驅(qū)動程序的基本步驟。最簡的驅(qū)動程序框架1、 寫一個 DriverEntry 例程,在里面調(diào)用 IoCreateDevice 創(chuàng)建 一個 Device 對象。1、寫一個處理IRP_MJ_CREATt求的Dispatch例程的基本框架(參見DDK Kernel-Mode Drivers 4.4.3 描述的一個 DispatchCreate 例程所要完成的最基 本工作。當然寫了 DispatchCreate例程后,要在DriverEntry 例程為 IRP_MJ_CREATE始化例程入口)。如果驅(qū)動程序創(chuàng)建了多于一個 Device對象, 則必須

33、為IRP_MJ_CLOS請求寫一個例程,該例程通常情況下可 以和DispatchCreate 共用一個例程,參見參見 DDK Kernel-Mode Drivers 443。 3、編譯連接你的驅(qū)動程序。用下面的方法來測試你的驅(qū)動程序。首先按上面介紹的方法安裝好驅(qū)動程序。其次我們還得為NT邏輯設備名稱和目標Device對象名稱之間建立 起符號連接, 我們在前面已經(jīng)知道Device對象名稱對WIN32用戶模式是不可見的,是不能直 接通過API來訪問的,WIN 32 API只能訪問NT邏輯設備名稱。我們可以通 過 修 改注冊表來建立這兩種名稱之間的符號連接。運行REGEDT32.EX在SystemSessi onManager DOS Devices下建立起符號連接(這種符號連接也可以在驅(qū)動程序里調(diào) 用函數(shù) loCreateSymbolicLi nk來創(chuàng)建)。重新啟動系統(tǒng)。編寫一個簡單的測試程序調(diào)用 WIN32API CreateFile函數(shù)以剛才你命名的 NT邏 輯設備名打開這個設備。如果打開成功,那么你也就成功地寫出了一個最簡單的驅(qū)動程序了。支持更多的設備I/O請求例如你的驅(qū)動程序可能需要對IRP_MJ_REA請求做出響應(完成后可用WIN32API ReadFile函數(shù)進行測試)。如果你的驅(qū)動程序需要能夠手工卸載,

溫馨提示

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

評論

0/150

提交評論