Posted on 2010-02-19 14:32
S.l.e!ep.¢% 閱讀(1017)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
Windows WDM
驅(qū)動(dòng)的入口 DriverEntry() 函數(shù)
NTSTATUS?DriverEntry(IN?PDRIVER_OBJECT?DriverObject,?IN?PUNICODE_STRING?RegistryPath)
{
}
1. 驅(qū)動(dòng)對(duì)象 DriverObject
DRIVER_OBJECT 對(duì)應(yīng) .sys? 文件?
DRIVER_OBJECT?對(duì)象是操作系統(tǒng)在加載驅(qū)動(dòng)時(shí)所分配的.
RegisteryPath 也是操作系統(tǒng)用于記錄驅(qū)動(dòng)相關(guān)參數(shù)的注冊(cè)表路徑.
DriverObject 重要之處,在于它有一組函數(shù)指針,稱之為 dispatch functions
開發(fā)驅(qū)動(dòng)的主要任務(wù)就是自己實(shí)現(xiàn)這些 dispatch functions, 當(dāng)系統(tǒng)用到你的驅(qū)動(dòng)時(shí),就會(huì)向你的驅(qū)動(dòng)發(fā)送 IRP, 可以在 dispatch functions 中處理這些 IRP, 可以讓IRP 失敗,也可以讓它返回成功,甚至可以修改或自己發(fā)出IRP。(如何把驅(qū)動(dòng)關(guān)聯(lián)到系統(tǒng)中,讓它可以通知到呢?)
2. 設(shè)備對(duì)象 DeviceObject 簡(jiǎn)稱?DO?
IRP 是由 DeviceObject 發(fā)出的,只有針對(duì)該驅(qū)動(dòng)所生成的 DeviceObject? 的 IRP,操作系統(tǒng)才會(huì)發(fā)給該驅(qū)動(dòng)來(lái)處理。具體的 dispatch function 決定于 DeviceObject? 下的 DriverObject 成員
3. 文件系統(tǒng) File System 簡(jiǎn)稱 FS
4. 控制設(shè)備 Control Device Object?簡(jiǎn)稱 CDO
??? CDO主要任務(wù)是修改整個(gè)驅(qū)動(dòng)的內(nèi)部配置,因此一個(gè)驅(qū)動(dòng)只對(duì)應(yīng)一個(gè) CDO
5. Symbolic Link 符號(hào)鏈接
??? 可以通過(guò) Symbolic links viewer 工具查看操作系統(tǒng)的所有符號(hào)鏈接
??? 可以看到 C:?? 對(duì)應(yīng) \Device\HarddiskVolume1
??? 這里可以看出,文件系統(tǒng)驅(qū)動(dòng)是針對(duì)每個(gè) Volume 來(lái)生成一個(gè) DeviceObject ,則不是針對(duì)文件。實(shí)際上對(duì)某個(gè) Volume? 的文件讀寫,都發(fā)到這個(gè) Volume 設(shè)備對(duì)象上面去了.
6. 可以使用 IoCreateDevice() 函數(shù)來(lái)創(chuàng)建 控制設(shè)備對(duì)象(控制設(shè)備對(duì)象的作用?)
7. 指定 DriverObject 的處理函數(shù)
??? for(i = 0; i<= IRP_MJ_MAXIMUM_FUNCTION; i++)
??? {
??????? DriverObject->MajorFunction[i] = SfPassThrough;
??? }
??? 處理函數(shù)里面最簡(jiǎn)單的處理就是什么都不做,傳給操作系統(tǒng)的其它驅(qū)動(dòng)處理,使用下面的代碼
??? IoSkipCurrentIrpStackLocation(Irp);
??? return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp);
8. 文件系統(tǒng)的驅(qū)動(dòng),除了要處理正常的IRP之外,還要處理 FastIo
??? (a. FastIo 是操作系統(tǒng)的 Cache Manager 調(diào)用所觸發(fā)的沒(méi)有 IRP 的請(qǐng)求
???? b. FastIo 是獨(dú)立于普通IRP分發(fā)函數(shù)之外的另一組接口,作用跟普通的IRP是一樣的
???? c. 如果是一個(gè)文件過(guò)濾驅(qū)動(dòng),那么普通的IRP分發(fā)函數(shù) 和 FastIo 都有可能被調(diào)用,所以最好是同時(shí)過(guò)濾這兩套接口
???? d. fastio 的分發(fā)函數(shù)直接返回 FALSE 不做任何事,這樣這些請(qǐng)求都會(huì)通過(guò)IRP重新發(fā)送,有一定的效率損失,但不是很大。? )
???
FastIo 的函數(shù)可以通過(guò) Driver->FastIoDispatch 來(lái)指定
9. 驅(qū)動(dòng)中的內(nèi)存分配
??? 并不是簡(jiǎn)單的 new, 而是調(diào)用函數(shù) ExAllocatePoolWithTag() 函數(shù)來(lái)分配
??? 內(nèi)存清零則使用 RtlZeroMemory() 函數(shù)
10. 操作系統(tǒng) 保存了 目前所有的驅(qū)動(dòng)設(shè)備對(duì)象,并且用類似于“鏈表”的方式,這個(gè)“鏈表”稱為設(shè)備棧
任何來(lái)自應(yīng)用層(Ring3)的請(qǐng)求,都會(huì)被 Windows?系統(tǒng)的 IO管理器翻譯成 IRP,然后發(fā)給設(shè)備棧中最頂端的那個(gè)設(shè)備
原始 IRP????????????????????????? IRP????????????????????????????? IRP
-------------->???????????? ----------->????????????????? --------->
??????????????????? 最頂端的設(shè)備?????????? 排第二的設(shè)備??????????????? ....
<--------------???????????? <-----------????????????????? <---------
原始IRP返回????????????????? IRP返回???????????????????? IRP返回
箭頭表示IRP請(qǐng)求的發(fā)送過(guò)程
a.?只要我們?cè)谶@個(gè)設(shè)備棧的頂端再綁定一個(gè)設(shè)備,那么發(fā)給這個(gè)設(shè)備的請(qǐng)求,自然就會(huì)先發(fā)給我們的設(shè)備來(lái)處理(可以通過(guò) IoAttachDeviceToDeviceStack)
11. 某些 dispatch function 里開頭有 PAGED_CODE();?的作用是?
?????
12. 先用 IoCreateDevice() 創(chuàng)建一個(gè) Device Object?, 然后調(diào)用 IoAttachDeviceToDeviceStack() 綁定到? \Device\HarddiskVolume1? 這個(gè)設(shè)備,那么所有發(fā)給 C:\ 的IRP,都必然先發(fā)送給我們的驅(qū)動(dòng),這樣一來(lái)就可以捕獲所有對(duì)文件的操作了。
13. 當(dāng)一個(gè)新的存儲(chǔ)媒介被系統(tǒng)發(fā)現(xiàn)(如U盤)并生成一個(gè)Volume的過(guò)程稱為? Mounting, 此時(shí),文件系統(tǒng)的CDO會(huì)得到一個(gè)IRP, 這個(gè)IRP是 IRP_MJ_FILE_SYSTEM_CONTROL, MinorFunctionCode == IRP_MN_MOUNT
14. IoRegisterFsRegistrationChange() 注冊(cè)一個(gè)回調(diào)函數(shù),當(dāng)操作系統(tǒng)中有任何文件系統(tǒng)被激活或者是被注銷時(shí),注冊(cè)過(guò)的回調(diào)函數(shù)會(huì)被調(diào)用。
(注意,這里說(shuō)的文件系統(tǒng)是指 NTFS, FAT32, CDFS 這些文件系統(tǒng)
win2k以前的系統(tǒng),對(duì)已經(jīng)激活的文件系統(tǒng)不會(huì)調(diào)用回調(diào),但2K以后的系統(tǒng)會(huì)對(duì)已經(jīng)存在的文件系統(tǒng)重新枚舉一次, 所以在2K下需要自己枚舉已經(jīng)加載的文件系統(tǒng))
(注冊(cè)這個(gè)回調(diào)有什么作用?直接綁定 RawDisk 和處理 IRP_MN_MOUNT
?不就得了?)
15. 當(dāng)收到文件系統(tǒng)的 notify 時(shí),綁定設(shè)備前,需要一個(gè)宏的判斷是否是文件系統(tǒng)類型的設(shè)備
#define IS_DESIRED_DEVICE_TYPE(_type) \
??? (((_type) == FILE_DEVICE_DISK_FILE_SYSTEM) || \
???? ((_type) == FILE_DEVICE_CD_ROM_FILE_SYSTEM) || \
???? ((_type) == FILE_DEVICE_NETWORK_FILE_SYSTEM))
(難道阿貓阿狗的設(shè)備增加時(shí),都會(huì)觸發(fā) fs system notify?)
15. 初始化完后,需要設(shè)置一個(gè)標(biāo)志位
????? DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
????? 作用?原因?