首页
社区
课程
招聘
[旧帖] 关于学习驱动的几个简单概念问题!!! 0.00雪花
发表于: 2010-4-28 14:16 5009

[旧帖] 关于学习驱动的几个简单概念问题!!! 0.00雪花

2010-4-28 14:16
5009
我想问几个简单的问题,如有帮助,可+分:
拿键盘按下为事件
当键盘按下时(io系统服务之前省略)i/o管理器创建irp
固定部分: MdlAddress
              Flages
              Associatedirp.*****
              .........
i/ostack:i/o Stack Location2
             i/o Stack Location1
问题1:irp中的i/o堆栈是根据设么组建的?比如说这个键盘按下的majorfunction是irp_mj_key 那么他是去找所有的dispatch函数的功能?要是这样的话,怎么判断谁在location1,谁在location2?根据什么判断的?
问题2:当这个irp传到我所处理的分发函数时,我是不知道按下什么键的,对不对? 那么如果我要是想得到按键信息,必须设定IoSetCompletionRoutine(),
         那么是不是在location2的要比location1的先得到按键信息?(假设都设置了这个函数)
问题3:如何判断我多附加的device所在location位置?  
谢谢!!  小弟新手 望大虾们不吝赐教!!!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 168
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
???没人啊
2010-4-28 18:11
0
雪    币: 28
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
- -~!好高。。没看明白
2010-4-28 18:14
0
雪    币: 168
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
.....怎么真没人告诉啊
2010-5-1 08:48
0
雪    币: 168
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
顶上去啊!!
2010-5-1 09:33
0
雪    币: 204
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
你还是买本基础书看看学一下吧,舍不得花钱网上也有很多的电子书
2010-5-1 15:45
0
雪    币: 168
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我会了  帮后来人吧~  
问题1:根据绑定的设备来+location的 一般越往后就越高
问题2:对的,是的
问题3:可以用irptracing来看
2010-5-4 09:56
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
建议买本相关专业书或从网上仔细搜集相关书籍
2010-5-5 14:28
0
雪    币: 97
活跃值: (43)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
对于你的问题我也用键盘驱动来对你一一说明:
普通的PS/2键盘有下面几个驱动(不考虑你的机器装过其他的键盘过滤驱动)
        顶层的Kbdclass产生的设备对象  
            中间层的i8042prt产生的设备驱动
            底层APCI产生的设备驱动
你提到过设备栈问题:
一般的WDM驱动程序都是分层的,拿键盘驱动来说,
底层的APCI是总线驱动程序,PS/2接口是挂在APCI上的,总线驱动负责枚举总线上的设备并且分配相应资源,对于编程来说不太关心这个。

中间层的i8042prt:负责响应键盘的中断,然后把数据(键盘扫描码)取出来放在自己的缓冲区,在触发DPC,在DPC中调用上层设备驱动(Kbdclass)的回调函数,取走数据

上层Kbdclass:是真正的键盘驱动程序(我机器上的驱动名为KeyboardClass0),负责处理数据,把数据交给相应的请求,完成IRP。

那么设备栈是什么一个概念呢?IO_STACK_LOCATION是他的数据结构,在每个创建的IRP中都会有一个这个结构的指针。如果没有别的键盘过滤驱动程序,那么正常情况的设备栈是:

Kdbclass 的 IO_STACK_LOCATION1
i8042prt的IO_STACK_LOCATION2
在正常的键盘数据处理时,APCI一般不太关心

首先必须明白Kdbclass是位于上层应用层win32k!RawInputThread和硬件i8042之间。而win32k!RawInputThread 总是发一个 IRP_MJ_READ 的 IRP 到键盘设备栈的顶端(Kdbclass),等待着来自键盘的数据(也就是说他是一个死循环的线程,一直等待用户键盘输入)。当i8042有数据要键盘驱动取走的时候,就会触发中断,这个中断的中断服务例程是键盘驱动中的函数,于是键盘驱动就可以从i8042读取数据,经过一系列处理最终完成那个等待的 IRP。

那么现在就可以回答你的问题了:
问题1:irp中的i/o堆栈是根据设么组建的?比如说这个键盘按下的majorfunction是irp_mj_key 那么他是去找所有的dispatch函数的功能?要是这样的话,怎么判断谁在location1,谁在location2?根据什么判断的?
回答:IRP的I/O堆栈是由负责创建IRP包的模块创建的,一般用户层的请求如ReadFile,都是通过I /O管理器来完成创建的。但是并不是绝对,你也可以在你的驱动程序的分发函数中使用IoAllocateIrp创建IRP,那么这个时候你需要自己创建I/O堆栈了,那么你可能会问,创建多少个I/O设备栈,这个值由DEVICE_OBJECT中的StackSize决定(自己构建IRP的情况是很多的,如驱动和驱动之间的通信)。那么我需要纠正你的是键盘按下的是没有你说的这个:majorfunction是irp_mj_key 。用户按键就是产生中断(组合键也是一样),用户按键首先被i8042的中断捕获到,然后把相应的数据放到缓冲区中,同时在DPC中使用回调函数告诉上层的键盘驱动(Kdbclass)读取数据,然后再做一些数据的处理。那么IRP的发起者一定是上层的,如应用层调用相应的API(ReadFile,WriteFile等),或者是中间层的驱动创建IRP。而不是硬件产生。

刚开始说了应用层win32k!RawInputThread负责发起IRP并且一直死循环等待键盘驱动对IRP的完成,有键盘输入,那么就会对应的IRP完成,所以,在这里的IRP的流向是Kdbclass的Location1再到8042的Location2,一般IRP不会跨栈传递。


问题2:当这个irp传到我所处理的分发函数时,我是不知道按下什么键的,对不对? 那么如果我要是想得到按键信息,必须设定IoSetCompletionRoutine(),
         那么是不是在location2的要比location1的先得到按键信息?(假设都设置了这个函数)

答案:你说的必须建立在读取设备驱动的IRP,记住,越靠近底层设备的驱动程序,越早获得设备的的数据,也就是Location2要比Location1先得到数据。但是若是写的IRP那就不是这样的(你自己理解一下,比方说我要把数据写到U盘上,我编写一个文件过滤驱动,我完全可以直接返回No,那么低层的磁盘驱动根本就得不到我的数据)。

问题3:如何判断我多附加的device所在location位置?

这个就是你想编写一个过滤器驱动,然后想挂载到相应的驱动程序上面了。想查看你的驱动程序的位置,这个我没做过,但我可以给你几点意见:
方法1:用DeviceTree软件查看
方法2:在自己的设备驱动中,使用AddDevice挂载设备后,打印DEVICE_OBJECT中的StackSize,它的值就是你的设备所处的设备栈的位置。


其实从你的问题衍生出来的问题是,你如何想最早获得数据。。。自己可以想想

周末有个好心情
2010-5-9 12:08
0
雪    币: 355
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
向楼上的学习
2010-5-9 12:40
0
雪    币: 15
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
努力学习中ing
2010-5-9 12:45
0
雪    币: 97
活跃值: (43)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
补充一点:回答第一点时有点乱:按键按下是不产生IRP的,按键按下只产生中断,然后读取数据。IRP的产生一般是用户层调用几个固定的API函数,如:CreateFile,DeviceIoControl,CloseHandle等。这些函数的调用,会直接用I/O管理器负责创建相应的IRP,另外一种是自己构建IRP,使用内核函数,一般是以Io开头的,例如:IoAllocateIrp,IoBuildAsynchronousFsdRequest等一些函数。所以你的:“比如说这个键盘按下的majorfunction是irp_mj_key 那么他是去找所有的dispatch函数的功能”是错的。但是我明白你的意思,你是想问,内核中那么多设备驱动,I/O管理器是如何知道IRP应该发给谁。这个你不用担心,首先你在应用程序调用的ReadFile函数中有一个设备句柄(由CreateFile打开相应的设备驱动获得),那么第一个IRP就是传递到这个设备驱动,但是,如果一旦这个设备驱动被过来驱动挂载,那么他就会先被过滤驱动获取到。因为IRP的流向设备栈的流向的。这个都是由I/O管理起来完成的。你不用担心,你只需要在你的过滤程序的相应派遣函数中设置完成例程进一步捕获数据。。。。表达能力有点差,请见谅,若对你有误导,请参考相关的书籍,都会讲解关于设备栈的
2010-5-9 17:05
0
游客
登录 | 注册 方可回帖
返回
//