基本介绍
1.设备与驱动的关系
设备由驱动去创建,访问一个设备,是首先得访问驱动。如果驱动在卸载的时候没有删除符号,r3下也是不能去访问设备的。
摘自http://www.cnblogs.com/mydomain/archive/2010/10/20/1857070.html
驱动程序和系统其他组件之间的交互是通过给设备发送或者接受发给设备的请求来交互的。换句话说,一个没有任何设备的驱动是不能按规范方式和系统交互的。当然也不会收到任何IRP,分发函数也失去了意义。如果驱动程序要和应用程序之间通信,则需要生成设备。此外还必须为设备生成应用程序可以访问的符号链接。
也就是说,应用程序与驱动的交互是通过设备来完成的,设备成了中间桥梁。下文中的符号链接又成了设备名的中间桥梁。记住,核心中介是设备。其他都是为他们的通信提供的机制。
2.设备符号链接名与设备名
Ring3不能直接访问设备,需要中间桥梁。这个中间桥梁是Ring0驱动为设备名注册的链接符号(Symbol Link)。
ps:中间的图解释换做r0(r3)下设备管理器中的设备符号链接更好
从图中可以看出,R3要访问设备,是通过设备符号名去访问设备的,而R3应用层下的设备符号名和设备管理器中的设备符号名有出入,必须,也只能写成\\.\设备符号名
的方式 ,系统会自动转为\??\设备符号名
,紧接着通过设备符号名这个中间桥梁可以转化为真正的R0下的设备名。
也就是说,符号链接名在应用层只是简单的符号转化过程,有些类似宏定义,设备符号名主体是相同的。而设备名和设备符号名可以不相同。因为设备符号名仅仅是个中间桥梁。
来使用WinObj.exe 查看一下:
从图上可以看出:设备符号名'\(GLOBAL)??\test
和设备名\Device\MyDevice
可以不一致。
所以有以下说法:
R3下不能直接访问设备,只能用设备符号名去访问设备,但是也不能直接使用
\??\设备符号名
去获得设备名。R3要访问设备,必须使用
\\.\设备符号名
,这个设备符号名由R0给定。R0下的设备名格式为
\Device\自定义设备名
R0下的设备符号名格式为
\??\自定义符号名
,其中自定义符号名
和自定义设备名
可以不一致。可以看出,最终的目的都是为了访问R0下的设备
\device\自定义设备名
。
通信机制
综述
应用程序和驱动程序的通信是通过IRP (i/o request packet) (IO请求包)
来完成的。
//PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
//证明object中含有majorFunction.
//in wdm.h
typedef _DRIVER_OBJECT DRIVER_OBJECT;
//in windbg:
lkd> dt _driver_object
nt!_DRIVER_OBJECT
+0x000 Type : Int2B
+0x002 Size : Int2B
+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT
+0x008 Flags : Uint4B
+0x00c DriverStart : Ptr32 Void
+0x010 DriverSize : Uint4B
+0x014 DriverSection : Ptr32 Void
+0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING
+0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
+0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
+0x02c DriverInit : Ptr32 long
+0x030 DriverStartIo : Ptr32 void
+0x034 DriverUnload : Ptr32 void
+0x038 MajorFunction : [28] Ptr32 long // here
驱动程序通过注册 派遣函数例程 来完成响应,在每一个驱动对象中有一个成员MajorFunction
,这个成员是个数组指针数组,