原文鏈接
1你画、驅(qū)動對象:
一個驅(qū)動對象代表了一個驅(qū)動程序蜜宪。或者說一個內(nèi)核模塊汇竭。驅(qū)動對象的結(jié)構(gòu)如下(這個結(jié)構(gòu)的定義取自 WDK中的 wdm.h)葱蝗。下面有一些域用省略號代替穴张。
<code>typedef struct _DRIVER_OBJECT {
// 結(jié)構(gòu)的類型和大小。
CSHORT Type;
CSHORT Size;
// 設(shè)備對象两曼,這里實際上是一個設(shè)備對象的鏈表的開始皂甘。因為 DeviceObject
// 中有相關(guān)鏈表信息。讀下一小節(jié)“設(shè)備對象”會得到更多的信息合愈。
PDEVICE_OBJECT DeviceObject;
……
// 驅(qū)動的名字
UNICODE_STRING DriverName;
……
// 快速 IO分發(fā)函數(shù)
PFAST_IO_DISPATCH FastIoDispatch;
……
// 驅(qū)動的卸載函數(shù)
PDRIVER_UNLOAD DriverUnload;
// 普通分發(fā)函數(shù)
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
} DRIVER_OBJECT;
</code>
2叮贩、設(shè)備對象:
設(shè)備對象是內(nèi)核中的重要對象。 其重要性不亞于在WindowsGUI編程中的窗口 (Wnd)佛析。進行過 Windows 窗口應(yīng)用程序開發(fā)的讀者知道益老,窗口是唯一可以接收消息的東西。任何消息都是發(fā)送給一個窗口的寸莫。而在內(nèi)核的世界里捺萌,大部分“消息”以“請求” (IRP)的方式傳遞。而設(shè)備對象(DEVICE_OBJECT)是唯一可以接受請求的的實體膘茎。任何一個“請求”(IRP)都是發(fā)送給某個設(shè)備對象的桃纯。 設(shè)備對象的結(jié)構(gòu)是 DEVICE_OBJECT,常常被簡稱為 DO披坏。一個 DO 可能代表許多東西态坦。淺顯的例子是:一個DO可以代表一個實際的硬盤。這很明顯:硬盤可以被讀棒拂,或者被寫伞梯。所以這個 DO 將接受讀和寫兩種請求(實際還有更多) 。但是一個 DO 也可能代表一個和硬件毫無關(guān)系的東西帚屉。比如說內(nèi)核中可能有一個設(shè)備谜诫,實現(xiàn)類似“管道”的功能。一個進程打開這個設(shè)備對象進行讀攻旦,另一個進程打開這個設(shè)備進行寫喻旷,就把數(shù)據(jù)從一個進程傳遞到了另一個進程。為了接受來自用戶進程的請求牢屋,我們不得不生成了一個 DO且预。這個 DO和實際硬件沒什么關(guān)系。 因為我們總是在內(nèi)核程序中生成一個 DO,而一個內(nèi)核程序是用一個驅(qū)動對象表示的烙无。所以一個設(shè)備對象總是屬于一個驅(qū)動對象锋谐。 在 WDK中的 wdm.h 中可以看到結(jié)構(gòu)定義如下 (我省略了許多現(xiàn)在讀者不需要了解的域)
<code>
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT {
// 和驅(qū)動對象一樣
CSHORT Type;
USHORT Size;
// 引用計數(shù)
ULONG ReferenceCount;
// 這個設(shè)備所屬的驅(qū)動對象
struct _DRIVER_OBJECT *DriverObject;
// 下一個設(shè)備對象。在一個驅(qū)動對象中有n 個設(shè)備皱炉,這些設(shè)備用這個指針連接
// 起來作為一個單向的鏈表怀估。
struct _DEVICE_OBJECT *NextDevice;
// 設(shè)備類型
DEVICE_TYPE DeviceType;
// IRP棧大小
HAR StackSize;
……
}DEVICE_OBJECT;
</code>
從這個結(jié)構(gòu)來看狮鸭,讀者應(yīng)該發(fā)現(xiàn)驅(qū)動對象(DRIVER_OBJECT)和設(shè)備對象(DEVICE_OBJECT) 之間的聯(lián)系合搅。 這非常重要多搀。驅(qū)動對象生成多個設(shè)備對象。而 Windows在向設(shè)備對象發(fā)送請求灾部。但是這些請求如何處理呢康铭?實際上,這些請求是被驅(qū)動對象的分發(fā)函數(shù)所捕獲的赌髓。當(dāng) Windows內(nèi)核向一個設(shè)備發(fā)送一個請求時从藤,驅(qū)動對象的分發(fā)函數(shù)中的某一個會被調(diào)用。分發(fā)函數(shù)原型如下:
<code>
// 一個典型的分發(fā)函數(shù)锁蠕,第一個參數(shù) device 是請求的目標(biāo) device,第二個參數(shù) irp 是
// 請求的指針夷野。
NTSTATUS MyDispatch(PDEVICE_OBJECT deivce, PIRP irp);
</code>
至于究竟如何處理,由內(nèi)核模塊的開發(fā)者在這個函數(shù)中編寫荣倾。