日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

2 《Undocumented Windows 2000 Secrets》翻譯 --- 第三章( 三 )


// END OF FILE
// =================================================================
列表 3-3 和 列表 3-4 給出的驅(qū)動程序的 C 代碼中包含了幾乎所有 Kernel-mode Driver 都需要的基本代碼 。我會盡量使該驅(qū)動向?qū)в懈玫目啥ㄖ菩?。你可以自由的更改向?qū)峁┑哪0逦募?。對于想保留原有代碼的人,下面的章節(jié)會為你提供該向?qū)У囊恍﹥?nèi)部細節(jié)的簡要介紹 。
該向?qū)傻尿?qū)動模塊的進入點是 DriverEntry()。像所有的 Windows 2000 模塊的進入點一樣,這個名字并不時必須的 。你可以使用任何你喜歡的名稱,但是你必須告訴鏈接器你所使用的進入點名稱,通過鏈接器的命令行選項 /entry 可以做到這一點 。對于前面提及的 TestDriver,向?qū)б呀?jīng)很好的完成了這項工作 。在 w2k_wiz.tp 模板或生成的 TestDrv.dsp 文件中,你會在鏈接器的命令行中找到 /entry:”DriverEntry@8” 這樣的字符串 。@8 后綴表示 DriverEntry() 接受 8 個字節(jié)的參數(shù)(這些參數(shù)位于棧中),這和 列表 3-1 提供的 DriverEntry() 的原型一致:兩個指針參數(shù),每個占據(jù) 32 個位,共使用 64 個二進制位,即 8 字節(jié) 。
DriverEntry() 做的第一件事是調(diào)用 DriverInitialize(),該函數(shù)將創(chuàng)建一個設備對象( Device Object )和該對象的一個符號鏈接( Symbolic link ),在稍后你可能在用戶模式的程序中使用該符號鏈接來與設備通訊 。要想找到 IoCreateDevice() 和 IoCreateSymbolicLink() 所使用的名字就有些許的困難,因為它們都是依賴 DrvzInfo.h (位于本書光盤的 srccommoninclude 目錄)中的宏定義 。如果你想更多的了解這個技巧,請參考 TestDrv.h (前面的 列表 3-4 已列出)中的 PROGRAM IDENTIFICATION 一節(jié),并跟蹤形如 DRV_* 的定義,它們以多種方式成組的出現(xiàn)在 DrvInfo.h 中 。例如,一個完整的 VERSIONINFO 資源就是由多個小的宏構(gòu)成的 。在別處,還定義了 DRV_DEVICE 和 DRV_LINK 常量,在這里,它們分別等價于 DeviceTestDrv 和 DosDeviceTestDrv。注意,很多內(nèi)核 API 函數(shù),如 IoCreateDevice() 和 IoCreateSymbolickLinke() 不接受一個以零結(jié)尾的字符串,僅支持一個特殊的結(jié)構(gòu)體 ---UNICODE_STRING,該結(jié)構(gòu)在第二章已經(jīng)介紹過,列表 3-5 再次給出了該結(jié)構(gòu)的定義 。定義于 DrvInfo.h 中的宏 ----PRESET_UNICODE_STRING (應用于 TestDrv.c 的 GLOBAL DATA Section )從一個簡單的 Unicode 字符串常量創(chuàng)建出一個靜態(tài)的 UNICODE_STRING 結(jié)構(gòu) 。這是針對 UNICODE_STRING 結(jié)構(gòu)的一個方便的速記符號 。
在成功的創(chuàng)建完設備對象及其符號鏈接后,DriverInitialize() 將設備對象指針和設備上下文( Device Context )的指針保存在一個靜態(tài)全局變量中 。Device Context 是設備的一個私有結(jié)構(gòu),該結(jié)構(gòu)可以有任意的大小和結(jié)構(gòu) 。本書提供的驅(qū)動程序骨架附帶了一個簡單的 DEVICE_CONTEXT 結(jié)構(gòu),該結(jié)構(gòu)定義于 TestDrv.h 中 。該結(jié)構(gòu)僅包含分別指向設備和設備驅(qū)動程序?qū)ο蟮膬蓚€指針 。你可以擴展該結(jié)構(gòu)來保存設備驅(qū)動程序所特有的數(shù)據(jù) 。系統(tǒng)針對驅(qū)動程序接收到的每個 I/O 請求包( I/O Request Packet, IRP )提供相應的 Device Context。
在 DriverInitialize() 成功完成并返回后,DriverEntry() 將建立一個重要的數(shù)組,該數(shù)組由系統(tǒng)傳入,并做為驅(qū)動程序?qū)ο蠼Y(jié)構(gòu) ----pDriverObject 的一部分 。該數(shù)組為驅(qū)動程序期望的所有 IRP 提供空間,同時 DriverEntry() 還為所有希望得到控制的 IRP 寫入對應的 CallBack 函數(shù)的指針 。本書提供的驅(qū)動程序骨架遵循此種設計,它保存了一個 DriverDispatcher() 指針,并提供了可存放 28 個 IRP 的空間,如 表 3-2 所示 。稍后,DriverDispatcher() 將決定需要注意那些類型的 IRP,并針對所有不感興趣的 IRP 返回 STATUS_NOT_IMPLEMENTED。需要注意的是,Windows NT 和 Windows 2000 的 IRP 處理例程數(shù)組的布局有一些微妙的差別 。在 表 3-2 中,這種差別以黑體標識出來 。

推薦閱讀