我們在進行win32開發的時候,肯定都接觸過windows的訊息機制,訊息會被封裝成乙個結構體:msg。我們做驅動開發的時候,訊息被封裝成了另外乙個結構體,也就是irp(i/o request package)。我們用windbg工具檢視一下irp結構體:
kd> dt _irp
nt!_irp
+0x000 type : int2b
+0x002 size : uint2b
+0x004 mdladdress : ptr32 _mdl
+0x008 flags : uint4b
+0x00c associatedirp :
+0x010 threadlistentry : _list_entry
+0x018 iostatus : _io_status_block
+0x020 requestormode : char
+0x021 pendingreturned : uchar
+0x022 stackcount : char
+0x023 currentlocation : char
+0x024 cancel : uchar
+0x025 cancelirql : uchar
+0x026 apcenvironment : char
+0x027 allocationflags : uchar
+0x028 useriosb : ptr32 _io_status_block
+0x02c userevent : ptr32 _kevent
+0x030 overlay :
+0x038 cancelroutine : ptr32 void
+0x03c userbuffer : ptr32 void
+0x040 tail :
我們對irp有了乙個初步的了解以後,就可以建立乙個裝置物件了。至於裝置物件要記住這一點,在進行應用程式和驅動程式互動的時候必須要提供乙個裝置物件。建立裝置物件**如下:
ntstatus createdevice
(pdriver_object pdriverobject)
// do_buffered_io作業系統將應用程式提供緩衝區的資料複製到核心模式下的位址中。
pdeviceobj->flags |
= do_buffered_io;
//建立符號鏈結,通過符號鏈結能夠找到相應的裝置物件,如下圖
rtlinitunicodestring
(&ussymname, l"\\??\\littlefish");
status =
iocreatesymboliclink
(&ussymname,
&usdevname);if
(!nt_success
(status)
)return status_success;
}
建立好裝置物件以後,使用winobj進行檢視,這樣是我們一下明白很多
建立好裝置物件以後,開始設定irp與派遣函式。派遣函式的設定是在_driver_object中majorfunction成員,majorfunction一般是處理一些常用的請求,例如讀寫,建立,關閉等等。下面我們看下**:
ntstatus driverentry
(pdriver_object pdriver, punicode_string preg)
else
//設定派遣函式
pdriver->majorfunction[irp_mj_create]
= createcompleteroutine;
pdriver->majorfunction[irp_mj_close]
= closecompleteroutine;
pdriver->majorfunction[irp_mj_read]
= readcompleteroutine;
pdriver->majorfunction[irp_mj_write]
= writeompleteroutine;
pdriver->driverunload = unloaddriver;
return status_success;
}
void
checkdriver()
closehandle
(hfile)
;}
核心層完整**如下:
#include
void unloaddriver
(pdriver_object pdriver)
}//建立裝置物件
ntstatus createdevice
(pdriver_object pdriverobject)
pdeviceobj->flags |
= do_buffered_io;
//建立符號鏈結
rtlinitunicodestring
(&ussymname, l"\\??\\littlefish");
status =
iocreatesymboliclink
(&ussymname,
&usdevname);if
(!nt_success
(status)
)return status_success;
}//派遣函式的固定寫法
ntstatus createcompleteroutine
(pdevice_object pdeviceobject, pirp pirp)
ntstatus closecompleteroutine
(pdevice_object pdeviceobject, pirp pirp)
ntstatus readcompleteroutine
(pdevice_object pdeviceobject, pirp pirp)
ntstatus writeompleteroutine
(pdevice_object pdeviceobject, pirp pirp)
ntstatus driverentry
(pdriver_object pdriver, punicode_string preg)
else
//派遣函式
pdriver->majorfunction[irp_mj_create]
= createcompleteroutine;
pdriver->majorfunction[irp_mj_close]
= closecompleteroutine;
pdriver->majorfunction[irp_mj_read]
= readcompleteroutine;
pdriver->majorfunction[irp_mj_write]
= writeompleteroutine;
pdriver->driverunload = unloaddriver;
return status_success;
}
應用層完整**:
#include
#include
void
checkdriver()
closehandle
(hfile);}
intmain()
Linux驅動之網路驅動應用
include include include printk include kmalloc include error codes include size t include mark bh include include struct device,and other headers incl...
Windows驅動之PNP狀態轉換
即插即用 plug and play pnp 管理器使用主功能碼為irp mj pnp的irp與裝置驅動程式交換資訊和請求。在wdm中,pnp請求扮演了兩個角色。在第乙個角色中,這些請求指示驅動程式何時以及如何配置或取消其硬體或自身的設定。pnp請求的第二個角色是指導驅動程式完成一系列狀態轉換。我們...
Windows核心原理與實現之驅動物件和裝置物件
當 i o 管理器載入乙個裝置驅動程式時,它會建立乙個驅動程式物件,該物件在物件管理器目錄中的路徑為 driver 或 filesystem 如果是檔案系統型別的驅動程式,則該物件被放置在 filesystem 目錄下,否則放在 driver 目錄下。因此,驅動程式可粗略地分為檔案系統驅動程式和非檔...