ImageVerifierCode 换一换
格式:DOCX , 页数:9 ,大小:18.36KB ,
资源ID:9434006      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9434006.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(07Windows文件系统过滤驱动程序教程7.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

07Windows文件系统过滤驱动程序教程7.docx

1、07Windows文件系统过滤驱动程序教程7Windows文件系统过滤驱动开发教程(7)7.IRP完成函数,中断级,如何超越中断级别的限制 先讨论一下Volumne设备是如何得到的.首先看以下几个函数: / -wdf.h 中的内容 - typedef VPB wd_vpb; _inline wd_vpb * wd_dev_vbp(wd_dev *dev) return dev-Vpb; _inline wd_dev * wd_vbp_dev(wd_vpb *vpb) return vpb-DeviceObject; VPB是Volume parameter block.一个数据结构.它的主要作

2、用是把实际存储媒介设备对象和文件系统上的卷设备对象联系起来. wd_dev_vbp可以让你从一个Storage Device Object得到一个VPB,而wd_vbp_dev这个函数可以得到这个VPB所对应的Volmue设备. 现在首先要得到Storage Device Object.实际上这个东西保存在当前IO_STACK_LOCATION中. / -wdf.h 中的内容 - _inline wd_dev *wd_irpsp_mount_storage(wd_io_stack *irpsp) return irpsp-Parameters.MountVolume.Vpb-RealDevic

3、e; ; 那么,从irp出发,我最终可以通过以下的方式得到Volumue设备: wd_irpsp *irpsp = wd_cur_io_stack(irp); wd_dev *storage_dev = wd_irpsp_mount_storage(irp); wd_vpb *vpb = wd_dev_vbp(storage_dev); wd_dev *volume_dev = wd_vbp_dev(vpb); 不过实际情况并不这么简单.这里的IRP是一个MOUNT请求.而volume设备对象实际上是这个请求完成之后的返回结果.因此,在这个请求还没有完成之前,我们就试图去获得Volume设备对

4、象,当然是竹篮打水一场空了. 这里,你可以直接拷贝当前IO_STACK_LOCATION,然后向下发送请求,但在此之前,要先给irp分配一个完成函数.irp一旦完成,你的完成函数将被调用.这样的话,你可以在完成函数中得到Volume设备,并实施你的绑定过程. 这里要讨论一下中断级别的问题.常常碰到人问某函数只能在Passive Level调用是什么意思.总之我们的任何代码执行的时候,总是处在某个当前的中断级之中.某些系统调用只能在低级别中断级中执行.请注意,如果一个调用可以在高处运行,那么它能在低处运行,反过来则不行. 我们需要知道的只是我们关心Passive Level和Dispatch L

5、evel.而且Dispatch Level的中断级较高.一般ddk上都会标明,如果注明irq level=dispatch,那么你就不能在passive level的代码中调用它们了. 那么你如何判断当前的代码在哪个中断级别中呢?我一般是这么判断的:如果你的代码执行是由于应用程序(或者说上层)的调用而引发的,那么应该在Passive Level.如果你的代码执行是由于下层硬件而引发的,那么则可能在dispatch level. 希望不要机械的理解我的话!以上只是极为粗略的便于记忆的理解方法.实际的应用应该是这样的:所有的dispatch functions由于是上层发来的irp而导致的调用,所

6、以应该都是Passive Level,在其中你可以调用绝大多数系统调用.而如网卡的OnReceive,硬盘读写完毕,返回而导致的完成函数,都有可能在Dispatch级.注意都是有可能,而不是绝对是.但是一旦有可能,我们就应该按就是考虑. 好,现在我们发现,我们已经注册了完成函数,并且这个函数执行中可能是dispatch level. 现在面临的问题是,我们已经决定在完成函数中调用 IoAttachDeviceToDeviceStack来绑定Volume.而DDK说明有:Callers of IoAttachDeviceToDeviceStack must be running at IRQL

7、WorkerRoutine)(item-Parameter); 任务是一个数据结构,已经被我重定义为wd_work_item,wd_work_init能初始化它.初始化的时候你只需要填写一个你的任务的函数.同时一个context用来记录上下相关参数.(这是个空指针,你可以只想你任何想要的参数类型). 一般这个任务会自动执行,但是有时我们也想不插入队列,我们自己执行它.那么调用wd_work_run即可. 然后调用wd_work_queque插入工作者队列,之后会被执行.插入类型这里选择wd_work_delay. 希望你没有被这一串东西搞糊涂.现在我会写一个设置完成函数的函数.执行后,自动在P

8、assive Level级执行你的完成函数.希望不会把你搞得晕头转向的:). / 完成例程上下文。好几个fsctl需要注册完成例程。而例程中的工作可能 / 只能在passive level中运行,因此不得不加入一个work_item,把任务塞 / 入工作线程等待完成 typedef struct _my_fsctl_comp_con wd_work_item work; wd_dev *dev; wd_irp *irp; wd_dev *new_dev; / 这个元素仅仅用于mount的时候。因为我 / 们要生成一个新设备来绑定vdo. my_fsctl_comp_con; wd_bool m

9、y_fsctl_set_comp(wd_dev *dev, wd_irp *irp, wd_dev *new_dev, wd_irp_comp_func complete, wd_work_func work_complete) my_fsctl_comp_con *context; context = (wdff_fsctl_comp_con *)wd_malloc(wd_false, sizeof(wdff_fsctl_comp_con); if(context = NULL) wd_printf0(fsctl set comp: failed to malloc context.rn);

10、 return wd_false; / 初始化工作细节 wd_work_init(&context-work, work_complete, context); context-dev = dev; context-irp = irp; context-new_dev = new_dev; / 设置irp完成例程 wd_irp_comp(irp,complete,context); return wd_true; / 以下函数作为以上complete的参数被使用 wd_stat my_fsctl_comp(in wd_dev *dev, in wd_irp *irp, in wd_void *

11、context) wd_printf0(fsctl_comp: come in!rn); UNREFERENCED_PARAMETER(dev); UNREFERENCED_PARAMETER(irp); / 判断当前中断级 if(wd_get_cur_irql() wd_irql_passive) wd_printf0(fsctl_comp:into quque!rn); / 如果在passive更低的中断级别,必须插入延迟队列中运行 wd_work_queue(wd_work_item *)context,wd_work_delay); else / 否则可以直接执行 wd_printf0

12、(fsctl_comp:run directly!rn); wd_work_run(wd_work_item *)context); return wd_stat_more_processing; 我想以上的过程应该已经可以理解了!注册了基本的完成历程complete函数(也就是我最后写的函数my_fsctl_comp后),irp执行完毕回调my_fsctl_comp,而我事先已经把已经做好的任务(wd_work_item)写在上下文指针中(context)中.一回调这个函数,我就wd_work_queque插入队列.结果wd_work_item中记录的work_complete函数显然会在P

13、assive level中执行.我们的系统也将保持稳定. work_complete函数将从context上下文指针中得到足够的参数,来完成对Volume的绑定. 希望你没有被弄昏头:),我们下回再分解.她含着笑,切着冰屑悉索的萝卜,她含着笑,用手掏着猪吃的麦糟,她含着笑,扇着炖肉的炉子的火,她含着笑,背了团箕到广场上去晒好那些大豆和小麦,大堰河,为了生活,在她流尽了她的乳液之后,她就用抱过我的两臂,劳动了。大堰河,深爱着她的乳儿;在年节里,为了他,忙着切那冬米的糖,为了他,常悄悄地走到村边的她的家里去,为了他,走到她的身边叫一声“妈”,大堰河,把他画的大红大绿的关云长贴在灶边的墙上,大堰河,

14、会对她的邻居夸口赞美她的乳儿;大堰河曾做了一个不能对人说的梦:在梦里,她吃着她的乳儿的婚酒,坐在辉煌的结彩的堂上,而她的娇美的媳妇亲切的叫她“婆婆”大堰河,深爱她的乳儿!大堰河,在她的梦没有做醒的时候已死了。她死时,乳儿不在她的旁侧,她死时,平时打骂她的丈夫也为她流泪,五个儿子,个个哭得很悲,她死时,轻轻地呼着她的乳儿的名字,大堰河,已死了,她死时,乳儿不在她的旁侧。大堰河,含泪的去了!同着四十几年的人世生活的凌侮,同着数不尽的奴隶的凄苦,同着四块钱的棺材和几束稻草,同着几尺长方的埋棺材的土地,同着一手把的纸钱的灰,大堰河,她含泪的去了。这是大堰河所不知道的:她的醉酒的丈夫已死去,大儿做了土匪,第二个死在炮火的烟里,第三,第四,第五而我,我是在写着给予这不公道的世界的咒语。当我经了长长的飘泊回到故土时,在山腰里,田野上,兄弟们碰见时,是比六七年

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1