WinXp文件过滤驱动入门-建立框架
- 格式:doc
- 大小:60.50 KB
- 文档页数:7
[版权所有] 本文作者是楚狂人,代码来源于开源工程tdifw与DDK的例子, 有问题欢迎与我联系讨论。
mail:******************* QQ: 16191935 msn:************************----------------------------------------------------------- Windows TDI过滤驱动开发 目 录(0) TDI概要(1) 准备工作(2) TDI设备与驱动入手(3) 绑定设备(4) 简单的处理请求(5) 基础过滤框架(6) 主要过滤的请求类型(7) CREATE的过滤(8) 准备解析ip地址与端口(9) 获取生成的IP地址和端口(10) 连接终端的生成与相关信息的保存(11) TDI_ASSOCIATE_ADDRESS的过滤(12) TDI_CONNECT的过滤(13) TDI_SEND,TDI_RECEIVE,TDI_SEND_DATAGRAM,TDI_RECEIVE_DATAGRAM(14) 设置事件(15) TDI_EVENT_CONNECT类型的设置事件的过滤(16) 一个传说中的问题(17) 收尾与清理的工作(0) TDI概要 最早出现的网络驱动应该是网卡驱动,这是Windows的理所当然的需求,为了进一步分割应用程序的网络数据传输与下层协议直到下层硬件的关系,又出现了协议驱动,后来微软和硬件商联合制定了NDIS标准,作为从硬件到协议的内核驱动程序的调用接口标准,而协议驱动与应用层的API之间,则出现了TDI接口。
最近国内安全软件的开发兴起,网络驱动的开发在其中有不少的应用,如果我们学习TDI接口的话,可能有以下一些目的: 自己要开发协议驱动,向上提供TDI接口,这种可能性存在,但不广泛。
我们想自己调用TDI接口,来进行网络数据传输,意义不大。
我们对TDI进行协议层过滤,开发防火墙或类似安全监控软件,这种应用还是比较多的。
xp框架安装教程XP框架(也称为Extreme Programming框架)是一种敏捷软件开发方法论,最早由美国软件工程师肯特·贝克和罗恩·杰弗里斯在1990年代初提出。
该框架的目标是提高软件开发的效率和质量,通过强调团队协作、迭代开发和快速反馈来实现。
XP框架包括许多实践方法,如持续集成、测试驱动开发、用户故事、迭代计划等。
在安装XP框架之前,需要确保团队成员都理解和接受这些方法,并愿意在项目中遵循它们。
下面是一个XP框架的安装教程,以帮助你开始应用这种敏捷开发方法。
1. 确定团队角色:XP框架中的团队由开发人员、测试人员和客户代表组成。
每个角色都有不同的职责和责任。
开发人员负责编写代码,测试人员负责验证代码的正确性,客户代表与开发团队密切合作,提供需求和反馈。
2. 创建用户故事:用户故事是XP框架中的一个重要概念,它描述了用户的需求、期望和使用场景。
在项目开始之前,团队成员应该与客户代表一起制定用户故事,并确定它们的优先级。
3. 迭代计划:在XP框架中,开发工作被分解成多个小的迭代周期,以便更快地交付可用的软件。
每个迭代通常持续一到两周,并包括多个用户故事。
团队成员应该一起制定迭代计划,确定每个迭代中要实现的用户故事和开发任务。
4. 持续集成:在XP框架中,持续集成是一种重要的实践方法。
它要求开发人员频繁地将代码集成到主干开发分支,并利用自动化工具进行编译、测试和部署。
团队应该建立一个持续集成环境,并确保所有开发人员都能够正确使用它。
5. 测试驱动开发:测试驱动开发(TDD)是XP框架中的另一个关键实践方法。
它要求在编写代码之前先编写测试用例,并通过不断迭代的方式进行开发和测试。
团队成员应该学会如何编写和运行测试用例,以及如何根据测试用例来开发代码。
6. 快速反馈:XP框架强调及时获取反馈和不断改进。
团队应该建立有效的反馈机制,如代码评审、用户反馈和指标跟踪,以帮助识别和解决问题。
实现⼀个具有还原功能的磁盘卷过滤驱动磁盘过滤驱动的概念1.设备过滤和类过滤在之前的⽂章⾥,我们已经介绍过滤的概念,所谓过滤技术就是在本来已有的设备栈中加⼊⾃⼰的⼀个设备。
由于Windows向任何⼀个设备发送IRP请求都会⾸先发送给这个设备所在设备栈的最上层设备,然后再依次传递下去,这就使得加⼊的设备在⽬标设备之前获取Irp请求称为可能,这时候就可以加⼊⾃⼰的处理流程。
在这⾥把插⼊设备栈的⽤户设备叫做过滤设备,建⽴这个设备并使其具有特殊功能的驱动叫做过滤驱动。
在前⾯已经展⽰了如何去建⽴⼀个过滤设备并将其绑定在⼀个有名字的设备上,这叫做设备过滤,这是对某个特定设备加以过滤的⽅法。
但是在实际应⽤中,这种⽅法还存在⼀些问题,例如,Windows中有很多即插即⽤设备,如何在这些设备加⼊系统的时候就⾃动对他们进⾏绑定呢?实际上,在Windows的过滤驱动框架中,还有⼀种叫做类过滤驱动的驱动程序,能够在某⼀类特定的设备建⽴时有Pnp Manager调⽤指定的过滤驱动代码,并且允许⽤户对此时这⼀类设备进⾏绑定。
根据⽤户设备在整个设备栈中的位置可以分为上层过滤和下层过滤。
2.磁盘设备和磁盘卷设备过滤驱动在Windows的存储系统中,最底层的是磁盘,⽽在磁盘上⾯⼜有卷,卷虽然只是逻辑上的⼀个概念,但是Windows仍然为其建⽴了设备,所以在Windows的存储系统⾥有磁盘设备和磁盘卷设备两种类型的设备。
如果⼀个磁盘卷位于某个磁盘上,那么对于磁盘卷的访问最终也会体现在相应的磁盘上。
但是这并不意味着他们在⼀个设备栈上,irp不会原封不动从磁盘卷设备栈上⼀直传到磁盘设备栈上,更何况Windows中还存在着跨磁盘的卷,软RAID卷等不能对应到唯⼀磁盘上的卷。
从驱动的⾓度上来讲,这两种设备受到读/写请求都是针对与磁盘⼤⼩或者卷⼤⼩范围之内的请求,都是以扇区⼤⼩对齐,处理起来也没有什么太⼤的区别。
在此我们选⽤磁盘卷设备的上层类过滤驱动。
Windows文件系统的过滤器驱动程序设计西安电子科技大学李新摘要:某些应用程序对文件系统的性能有较高要求。
例如媒体播放器需要满足最小数据传输率才能保证视觉上的流畅。
由于Windows文件系统本身没有提供这样的保证,需要编写过滤器驱动程序添加这项功能。
本文首先介绍系统驱动体系和文件系统工作机制,然后分析文件系统过滤器驱动程序的功能特点,最后介绍一种满足此类应用程序传输带宽的总体解决方案(来源于文献1)。
关键词:文件系统过滤器驱动程序设备对象堆栈一.基础知识1.系统组件Windows NT操作系统含有许多功能相互独立的内核模式组件。
如内核I/O管理器、硬件抽象层、存储管理器、配置管理器、对象管理器、运行支持和过程结构等组件。
Windows 2000在此基础上增加了即插即用管理器和电源管理器。
两种系统分别采用不同的驱动模型。
本文整体上以Windows 2000的文档为主。
不过文件系统具有特殊性(非WDM),在两个系统中的运行机制基本相似。
在这些内核组件中,I/O管理器最为关键,它由文件系统、中间层驱动程序和最低层设备驱动程序三部分组成,对所有的核心态驱动程序提供统一的通信接口IRP(I/O请求包方式)。
应用程序的I/O操作都是通过这种方式调用I/O管理器的服务完成的。
主要服务有:配置管理、内存管理、对象管理、安全监视等等。
2.驱动程序驱动程序实质是能被操作系统加载调用,为系统设备实现相应功能的内核模式的动态链接库。
形式上可以看作是一个包含许多例程的容器。
当第一次安装时,由I/O管理器调用驱动程序入口函数DriverEntry,驱动程序在此进行自身初始化,设置其它例程的进入点,使操作系统接下来可以调用这些服务例程。
驱动程序加载时机与它的启动类型和启动组设置有关。
启动类型有五种,通常文件系统及其过滤器驱动程序属于SERVICE_BOOT_START或SERVICE_DEMAND_START。
驱动体系是分层的。
收稿日期:2002209203.作者简介:李 凡(19432),男,教授;武汉,华中科技大学计算机科学与技术学院(430074).基金项目:国家高性能计算基金资助项目(00303).WindowsN T 内核下文件系统过滤驱动程序开发李 凡 刘学照 卢 安华中科技大学计算机科学与技术学院谢四江北京电子科技学院科研中心摘要:分析了基于N T 内核的WindowsN T/2000/XP 操作系统下文件系统过滤驱动程序的开发原理、步骤和应用,以实现动态的病毒扫描、透明的文件加密解密、文件保护和系统恢复等功能,保障了文件系统的信息安全.给出了一个实现透明的文件加解密的过滤驱动程序实例.关 键 词:WindowsN T 内核;过滤驱动;文件系统;IRP中图分类号:TP311.5 文献标识码:A 文章编号:167124512(2003)0120019203 在WindowsN T 和基于N T 内核的Windows 2000/XP 操作系统中,通常需要通过开发文件系统过滤驱动程序来保证文件系统的信息安全运行,主要包括动态病毒扫描、透明文件加密解密、文件保护和系统恢复等功能.文件系统驱动程序(File System Driver ,简称FSD )管理文件系统格式.WindowsN T 的文件系统驱动程序是I/O 子系统的一个组件,为用户提供在磁盘或者磁带等非易失性存储介质上存取数据服务.WindowsN T 的文件系统驱动程序和其他的设备驱动程序的一个主要的区别就在于文件系统驱动程序和内存管理器、高速缓存管理器有机的结合在一起,有着密不可分的关系.为了提高系统性能,FSD 通常使用高速缓存(Cache )管理器以高速缓存文件数据.FSD 还和内存管理器结合起来,以使内存映射文件能被正确实现[1].本文首先探讨文件系统过滤驱动程序开发的原理和步骤,然后给出一个实现文件透明加密解密的实例.由于WindowsN T/2000/XP 操作系统的文件系统过滤驱动程序开发有着很类似的方面,下文中如果没有特别说明,则是针对以N T 内核为基础的WindowsN T/2000/XP 操作系统而言的.1 文件系统过滤驱动程序开发 WindowsN T 的I/O 管理器是一个可扩展的结构,通过开发过滤驱动程序可以扩展I/O 子系统的功能.I/O 管理器支持分层驱动程序模型,每个I/O 请求包(IRP )的处理分别经过各层驱动程序,直到某层驱动程序完成这个请求.这样第三方开发的驱动程序就有机会插入到这个层次结构中并获得截获及处理来自上层的操作请求的机会,把这种驱动程序称为过滤驱动程序[2].文件系统过滤驱动程序是针对文件系统而言的.WindowsN T 的I/O 管理器根据用户的文件操作请求构造IRP 发到文件系统驱动程序,文件系统驱动程序把相应于文件系统的操作转换为相应于存储设备驱动程序的操作并通过I/O 管理器来调用存储设备驱动程序[3].I/O 管理器在发送操作请求到目标设备之前会检查是否有其他的设备附着于目标设备对象之上.通过构造附加的设备对象附着在文件系统或者存储设备对象之上,并为该设备对象指定专门的驱动程序,I/O 管理器就会把要发送到目标设备的请求先发到附加的过滤设备,在该设备对应的过滤驱动程序中对原始请求加入附加的处理来实现对文件系统操作的截取、监控甚至替换.文件系统过滤驱动程序可以附着在文件系统驱动程序之上,也可以加入到文件系统驱动程序和存储设备驱动程序之间,如图1所示.具体实现一个过滤驱动程序的基本步骤包括:构造一个设备对象(过滤设备)附着在目标设备上;在这个过滤设备对应的驱动程序(过滤驱动程序)中截取发送到目标设备的操作;在过滤操作中可能需要构造新的IRP 来驱动下层驱动程序,也可能需要为某个IRP 指定对应的完成例程以第31卷第1期 华 中 科 技 大 学 学 报(自然科学版) Vol.31 No.12003年 1月 J.Huazhong Univ.of Sci.&Tech.(Nature Science Edition ) Jan. 2003图1 文件系统过滤驱动程序在系统中的位置便这个IRP被下层驱动程序完成返回后调用;在合适的时候可以断开过滤程序[3].2 文件透明加密解密的过滤器实例 下面给出一个在WindowsN T下进行文件加密解密的过滤器具体实现过程.用户的数据在存储到磁盘上设定的安全区域(例如安全文件夹)之前经过了加密处理,读取时经过解密返回给用户,这个过程对用户来说是透明的.对这个安全区域访问时先要通过认证处理,这样就保证了安全区域里的数据安全.对于现有的Windows N T/ 2000/XP系列操作系统的文件系统本身来说,只是对Windows2000/XP支持的5.0版本以上的N TFS文件系统本身实现了加密文件系统(EFS).对所有文件系统分区的文件实现透明的加密解密并采用特殊的加密算法,就需要通过文件系统过滤驱动程序来实现.在文件系统驱动程序和硬盘驱动程序之间加入过滤驱动程序.当文件系统驱动程序写硬盘的时候,过滤驱动程序首先对数据进行加密然后再调用硬盘驱动程序.当文件系统驱动程序读硬盘的时候,过滤驱动程序先调用硬盘驱动程序读取数据并对从硬盘返回的已加密数据进行解密,然后再返回给文件系统驱动程序.过滤器在系统中位于文件系统驱动程序和磁盘驱动程序之间.要实现这个过滤器,首先需要把过滤器挂接在某个硬盘分区之上,可以在过滤驱动程序的Driver Entry例程或者应用程序中调用DeviceIo2 Control发送一个IOCTL请求驱动程序来挂接到硬盘上.该过程的函数调用过程为:由ZwCreate2 File得到硬盘分区的设备句柄,再用ObRefer2 enceObjectByHandle得到对应的FIL E-OBJ ECT 指针(WindowsN T把每个设备当作一个文件来看待,并有一个对应的FIL E-OBJ ECT结构描述其属性),调用Io G et RelatedDeviceObject得到硬盘分区设备对象指针.然后调用IoCreateDevice来构造代表过滤器的一个设备并为它指定驱动程序也就是过滤驱动程序.最后调用IoAttachDe2 viceByPointer把该设备挂接在硬盘分区设备上.这样文件系统驱动程序发送到这个硬盘分区设备的所有请求都会先经过过滤器.硬盘驱动程序由Driver Entry提供一系列的IRP处理函数供高层驱动程序调用.在过滤驱动程序中实现加密解密是通过截取IRP-MJ-READ和IRP-MJ-WRITE来实现的.在过滤驱动程序的Driver Entry例程中指定处理函数: DriverObject→MajorFunction[IRP-MJ-WRITE]=MyFilterWrite;DriverObject→MajorFunction[IRP-MJ-READ]=MyFilterRead.在IRP-MJ-WRITE的处理函数中如果需要加密处理就在非分页内存中分配一段与待写数据空间大小相同的内存,并把待写数据拷贝到这段内存中,对这段内存数据调用加密处理,建立这段内存的内存描述符MDL,更新IRP结构中的Irp→MdlAddress指向这个新建立的MDL,并记住原先的值.为这个IPR指定一个完成例程,接着调用下层的硬盘驱动程序写入已加密数据.硬盘驱动程序完成这个写操作并返回后,系统会调用指定的这个完成例程.在完成例程中恢复Irp→MdlAddress为原来的值并且释放原先分配的那段内存.在IRP-MJ-READ的处理函数中解密是一个近似相反的过程.先直接调用硬盘驱动程序取得数据,然后在它的完成例程中对读取的数据进行解密返回上层驱动程序.3 主要应用和展望基于文件系统过滤驱动程序可以实现动态的病毒扫描.文件系统针对病毒的安全措施有两种:一种是以杀为主的静态反病毒措施,另一种是以防为主的动态反病毒措施.动态的反病毒措施也就是对病毒实时监控,这个可以通过文件系统过滤驱动程序来实现.基本方法是在文件系统驱动程序上面加入一个过滤驱动程序来过滤被病毒感染的文件.这个过滤驱动程序先于文件系统看到I/O操作请求,在截取到上层传下来的写操作请求时如果侦测到病毒特征就拒绝这个请求,保证02 华 中 科 技 大 学 学 报(自然科学版) 第31卷硬盘数据的安全.另外,利用文件系统过滤驱动程序可以实现分级的存储管理.举例来说,一个系统中有两个存储设备,一个存取速度很快价格很昂贵;另一个存取速度较慢但是价格便宜.可以作一个过滤驱动程序附着在文件系统驱动程序之上来优化系统性能.把不常用的数据放在慢速设备上,当截取到对这些数据的操作请求时先把这些数据转移到快速设备然后再向下传递原来的操作请求到文件系统驱动程序,这样就可以在现有设备不变的情况下获得更好的系统性能.开发文件系统过滤驱动程序的用途在于它可以扩展、修改、甚至替代现有文件系统的操作而不用重新开发新的文件系统驱动程序.随着信息技术的发展和WindowsN T 应用的普及,文件系统过滤驱动程序的开发会有着更广泛的应用.参考文献[1]S olomon D A ,Russinovich M E.Inside microsoft win 2dows 2000,third edition.New Y ork :Microsoft Press ,2001.[2]Chris Cant.Windows WDM 设备驱动程序开发指南.孙 义,马莉波等译.北京:机械工业出版社,2000.[3]Nagar R.Windows N T file system internals.NewY ork :O.Reilly &Associates ,1998.Development of f ilter driver of f ile systeminside Windows NT kernelL i f an L i u X uez hao L u A n Xie S ijiangAbstract :The analysis of the principle ,process and application of the development of File System Filter Driver (FSFD )inside WindowsN T \2000\XP operating system based on WindowsN T kernel were made to achieve dynamic virus scan ,transparent file encryption/decryption ,file protection ,system recovery and ensure the information security of file system.An instance of realizing transparent encryption/decryption of disk file was given.K ey w ords :WindowsN T kernel ;filter diver ;file system ;IRPLi fan Prof.;College of Computer Sci.&Tech.,Huazhong Univ.of Sci.&Tech.,Wuhan 430074,China.韩国材料科学代表团来我校访问2002年12月5日,以中韩联委会委员、浦项科技大学Lee Sung Hak 教授为团长,韩国科学与工程基金会R &D 项目主任Sung Nak Won 教授、釜山国立大学Park Ik Min 教授、浦项科技大学K im Nack Joon 教授和汉阳大学Shin Dong Huuk 教授组成的韩国材料科学代表团一行5人访问我校.王乘副校长会见了来访客人.在化学系、材料学院共同组织的研讨会上,Sung Nak Won 教授介绍了韩国科学与工程基金会的情况,中韩两国的教授们还就新材料、新技术方面的研究进行了热烈交流和讨论.会后,代表团参观了化学系实验室、模具技术国家重点实验室和快速制造中心.12第1期 李 凡等:WindowsN T 内核下文件系统过滤驱动程序开发 。
文件系统过滤驱动基础知识一、何谓文件系统过滤驱动?文件系统过滤驱动是一种可选的,为文件系统提供具有附加值功能的驱动程序。
文件系统过滤驱动是一种核心模式组件,它作为Windows NT执行体的一部分运行。
文件系统过滤驱动可以过滤一个或多个文件系统或文件系统卷的I/O操作。
按不同的种类划分,文件系统过滤驱动可以分成日志记录、系统监测、数据修改或事件预防几类。
通常,以文件系统过滤驱动为核心的应用程序有防毒软件、加密程序、分级存储管理系统等。
二、文件系统过滤驱动并不是设备驱动设备驱动是用来控制特定硬件I/O设备的软件组件。
例如:DVD存储设备驱动是一个DVD 驱动。
相反,文件系统过滤驱动与一个或多个文件系统协同工作来处理文件I/O操作。
这些操作包括:创建、打开、关闭、枚举文件和目录;获取和设置文件、目录、卷的相关信息;向文件中读取或写入数据。
另外,文件系统过滤驱动必须支持文件系统特定的功能,例如缓存、锁定、稀疏文件、磁盘配额、压缩、安全、可恢复性、还原点和卷装载等。
下面两部分详细的阐述了文件系统过滤驱动和设备驱动之间的相似点与不同点。
三、安装文件系统过滤驱动对于Windows XP和后续操作系统来说,可以通过INI文件或安装应用程序来安装文件系统过滤驱动(对于Windows 2000和更早的操作系统,过滤驱动通常通过服务控制管理器Service Control Manager来进行安装)。
四、初始化文件系统过滤驱动与设备驱动类似,文件系统过滤驱动也使用DriverEntry例程进行初始化工作。
在驱动程序加载后,加载驱动相同的组件将通过调用驱动程序的DriverEntry例程来对驱动程序进行初始化工作。
对于文件系统过滤驱动来说,加载和初始化过滤驱动的系统组件为I/O管理器。
DriverEntry例程运行于系统线程上下文中,其IRQL = PASSIVE_LEVEL。
本例程可分页,详细信息参见MmLockPagableCodeSection。
微过滤器驱动开发指南0.译者序对我来说,中文永远是最美,最简洁,最精确和最高雅的文字。
本文翻译仅仅用做交流学习。
我不打算保留任何版权或者承担任何责任。
不要引用到赢利出版物中给您带来版权官司。
本文的翻译者是楚狂人,如果有任何问题,,或者是QQ16191935,或者是MSN 。
我翻译此文出于对文件系统技术的兴趣。
这就是新的文件系统过滤接口。
其实也不算什么新的东西,微软开发了另一个“旧模型的”过滤驱动,称之为过滤管理器<Filter Manager)。
从而提供了一系列新的接口来让你开发新的过滤器。
确实这套接口变简单清晰了。
你至少避免了包含无数个信息的IRP,避免了请求在各个部件中循环的发来发去,一个分发例程中处理无数中情况,一不小心系统崩溃。
我不知道花了多少时间才弄明白一个简单的缓冲读请求从用户到过滤到文件系统和缓冲管理器,虚拟内存管理器之间的关系!现在你也许不需要再管他们了,仅仅做好自己的过滤工作就可以。
这套接口强大吗?能实现你想要的功能吗?你很快就发现你没有研究过sfilter就看不懂Minifilter,或者是还得从sfilter开始做起更灵活一点。
微软就是这样,拿僵硬而且也不简单的东西来“简化”强大灵活但是设计上一团糟的东西,对于你来说是两者都必须学习,最后你的脑子被微软塞得满满的,不过没关系,我们已经习惯了.此文的原文是《Filter Driver Development Guide》,出自微软的网站。
我在以下这个地址下载得到此文:我尽量在翻译中使文章保持原貌。
如果您认为此文无法理解,建议您首先阅读旧的文件过滤驱动的相关资料。
我认为必须有文件系统和windows驱动的相关知识,才能阅读此文。
我未必总是使用规范的名词,但我总是使用最容易理解的名词。
一些常用的可能不翻译,比如IRP,MDL,有驱动开发经验的人应该可以理解。
另一些可能采用中文<英文)的方式。
一些解释如下:例程<Routine):我不懂得例程和函数有什么不同。
xp框架使用教程XP框架是一种轻量级的PHP框架,旨在帮助开发者快速构建高性能的Web应用程序。
本教程将向您介绍如何使用XP框架来创建基本的Web应用程序。
第一步是安装XP框架。
您可以通过从XP框架的官方网站上下载最新版本来进行安装。
下载完成后,将框架解压到您的Web服务器的根目录下。
安装完成后,您需要配置XP框架的基本设置。
打开`config.php`文件并根据您的需求进行配置。
您可以设置数据库连接、日志路径、路由规则等。
接下来,您需要创建一个新的路由文件来处理URL请求。
在`public`目录下创建一个名为`index.php`的文件,并将以下代码添加到文件中:```php<?phprequire_once __DIR__.'/../vendor/autoload.php';use xp\web\Application;$app = new Application();$app->get('/', function() {return 'Hello, World!';});$app->run();```在这段代码中,首先我们引入了XP框架的自动加载文件,然后创建了一个新的应用程序实例。
`$app->get()`方法用于处理GET请求,第一个参数是URL路径,第二个参数是一个回调函数来处理请求并返回响应。
在这个例子中,我们返回了一个简单的“Hello, World!”消息。
完成上述步骤后,您可以在浏览器中访问`http://localhost/`来查看应用程序的运行情况。
接下来,我们将介绍如何使用XP框架来处理数据库操作。
首先,您需要在`config.php`文件中配置数据库连接信息。
然后,您可以使用`$app->db()`方法来获取数据库连接实例,从而进行数据库查询操作。
下面的代码片段展示了如何在XP框架中执行简单的数据库查询:```php$app->get('/users', function($app) {$db = $app->db();$result = $db->query('SELECT * FROM users');return $result->fetchAll();});```在这个例子中,我们通过使用`$app->db()`方法获取数据库连接实例,然后执行了一个简单的SELECT查询,将结果返回给用户。
Windows XP文件系统过滤驱动程序入门——建立框架微笑的撒旦(william.xue@)2007-7-6 万事开头难,新手写一个File System Filter Driver,更难!而其实,走过之后回头再看,却是简单。
这篇文章的目标,是希望可以通过结合代码的方式,向初学者阐述一些必要的细节。
只是试图领大家跨过一个门槛,至于今后的成就,就看个人的修行了。
代码参考了ddk的sfilter。
虽然文中贴出了代码的片段,但阅读的时候最好还是参考源代码。
所以,阅读时的参考顺序是这样的:本文档->本驱动的source code->sfilter的source code->DDK文档->Google。
本文对读者的要求是有接触过WDM的驱动就行。
为求简单,我们将要讲的驱动,仅仅只是针对Windows XP系统。
如何兼容Windows 2000等系统,算入后来各自努力的目标之中,不在本文计划之内,在次不涉及。
1. 控制设备对象(control device object)CDO这个东西,就是由你的driver创建出来的device object,它在设备堆栈中代表了你的驱动程序——或者说,代表了你的驱动程序所对应的设备(其实它没有什么实际的设备,它只是个过滤型驱动而已。
可是哪怕是过滤型驱动,也得有东西在设备堆栈中占个位置,这样才可以和Application交互。
)在DriverEntry中,通过如下的代码创建一个control device object://// create the control device object//RtlInitUnicodeString(&sz_name_string,L"\\FileSystem\\Filters\\RedirectCDO");PDEVICE_OBJECT p_filter_ctrl_dev_obj = NULL;// create the device object for the driver object// this is only the control device object.status = IoCreateDevice(DriverObject, // driver objectNULL, // device extension size &sz_name_string, // device nameFILE_DEVICE_DISK_FILE_SYSTEM, // device typeFILE_DEVICE_SECURE_OPEN, // device characteristicsFALSE, // exclusive&p_filter_ctrl_dev_obj); // device objectif (STATUS_OBJECT_PATH_NOT_FOUND == status){return status;}"\\FileSystem\\Filters\\"是Windows XP的文件系统过滤驱动所在的路径,"RedirectCDO"是本CDO的名字。
使用sysinternals出品的WinObj工具,可以看到该路径。
当安装上本驱动后,也可以看到该设备的名字。
不需要为CDO分配extension。
我曾想是否有必要在此解释下CDO,即control device object。
不过我想简单提一下就可以了。
所谓CDO,在此代表了文件系统,也许叫它FSDO比较不容易混淆试听。
不过我们也不必在此瞎猜当初命名的出发点,暂时把它当成FSDO来看待就是。
2. 文件系统和卷试图写File System Filter Driver的人,平时日常应用中,绝对不会搞混这两个概念。
但是在刚开始学习File System Filter Driver,实际看代码的时候却不大会注意到。
一堆的DO (Device Object),搞不清谁是谁。
我们先来说说文件系统。
文件系统驱动程序创建两个东西:一个是上面已经接触过概念的CDO (Control Device Object),只是上面创建的那个,是我们自己filter的CDO。
另一个,叫做VDO,即Volume Device Object。
如果说CDO代表了文件系统,那个VDO就代表了卷。
(这里我不想深究卷的概念。
如果实在不了解什么是卷,就当它是你的硬盘分区吧——反正一开始,这个概念也差不多。
)既然一个文件系统驱动程序(filesystem driver)创建了两个东西,那个一个文件系统过滤驱动(File System Filter Driver)就需要过滤(我是说Attach)两个东西:其一是文件系统;其二是卷。
3. 如何挂入文件系统(how to attach the filter driver to filesystem)这个地方的文件系统,又分为两种情况:其一,文件系统已经加载;其二,文件系统尚未加载。
比如说,你的Windows XP启动完了,文件系统都是NTFS的。
然后你安装了你的filter driver。
现在你又把其中的一个分区格式化成了FAT32的……你当然想既能找到已经存在的NTFS,又能接到FAT32加入的通知。
这个简单的想法,实现起来却不是那么简单。
呃,我是说,Windows XP实现起来相对简单,而Windows 2000,我们就不管它了——这也是我为什么选WindowsXP做例子的原因,简单嘛!Windows XP下有一个函数,IoRegisterFsRegistrationChange,调用它,既能枚举已经安装的文件系统,又能在有新的文件系统加入的时候通知调用者。
(Windows 2000下,这个函数只有后半段的功能。
Windows 2000 SP4下,可以使用IoRegisterFsRegistrationChangeEx,有和Windows XP下相同效果。
)status = IoRegisterFsRegistrationChange(DriverObject, RDFsNotification);这个函数只是给你弄到一个文件系统,怎么Attach上去,就要看RDFsNotification的实现了:VOID RDFsNotification(IN PDEVICE_OBJECT DeviceObject,IN BOOLEAN FsActive)先来讲一下这个函数的参数,我在DDK中没有找到解释。
但是从某些代码中可以推测,DeviceObject代表了一个文件系统。
或许有时间,你可以自己跟踪一下IoRegisterFileSystem。
// attach to file system deviceif (FILE_DEVICE_DISK_FILE_SYSTEM != DeviceObject->DeviceType){return;}Again,简单!我们只对磁盘文件系统做处理。
接下来创建DO:PDEVICE_OBJECT p_fs_filter_dev_obj = NULL;status = IoCreateDevice(g_p_rdfilter_dev_ext->p_this_drv_obj,sizeof(RDFILTER_DEVICE_EXTENSION),NULL,DeviceObject->DeviceType,0,FALSE,&p_fs_filter_dev_obj);if (!NT_SUCCESS(status)){return;}创建一个device object,g_p_rdfilter_dev_ext->p_this_drv_obj指向本filter driver,就是DriverEntry的第一个参数。
代码中会有很多的driver object和device object,要注意分清楚啊!把刚才创建的那个device object,Attach上这个文件系统(DeviceObject):// attachPRDFILTER_DEVICE_EXTENSION p_fs_filter_dev_ext =(PRDFILTER_DEVICE_EXTENSION)p_fs_filter_dev_obj->DeviceExtension;status = IoAttachDeviceToDeviceStackSafe(p_fs_filter_dev_obj,DeviceObject,&(p_fs_filter_dev_ext->p_parent_dev_obj));p_fs_filter_dev_ext->p_parent_dev_obj返回的是,到底是这个filesystem中的哪个DO被Attach上了。
最后,是枚举这个文件系统上的卷:status = EnumerateAndAttachToExistVolumes(DeviceObject);这个函数是自己实现的啦!继续!4. 如何挂入卷算法很简单:1.)找出这个File System中的所有Device Object,挑出我们需要的2.)创建一个设备3.)把创建的设备Attach到Device Object上。
status = IoEnumerateDeviceObjectList(p_fs_dev_obj->DriverObject,p_p_dev_list,(ul_volumes * sizeof(PDEVICE_OBJECT)),&ul_volumes);这个函数就是用来枚举Device Object,实现步骤1.)的。
// create a filter device object for the volumePDEVICE_OBJECT p_flt_vlm_dev_obj = NULL;status = IoCreateDevice(g_p_rdfilter_dev_ext->p_this_drv_obj,sizeof(RDFILTER_DEVICE_EXTENSION),NULL,p_p_dev_list[i]->DeviceType,0,FALSE,&p_flt_vlm_dev_obj);这个是实现步骤2.)的。
status = AttachToMountedVolume(p_p_dev_list[i],p_flt_vlm_dev_obj);这个是用来实现步骤3.)的。
很不幸,这个函数需要自己实现。
所以,继续!NTSTATUS AttachToMountedVolume(IN PDEVICE_OBJECT p_parent_dev_obj,IN PDEVICE_OBJECT p_vlm_filter_dev_obj){NTSTATUS status = STATUS_SUCCESS;PRDFILTER_DEVICE_EXTENSION p_filter_dev_ext =(PRDFILTER_DEVICE_EXTENSION)p_vlm_filter_dev_obj->DeviceExtension;SetFlag(p_vlm_filter_dev_obj->Flags,FlagOn(p_parent_dev_obj->Flags,(DO_BUFFERED_IO | DO_DIRECT_IO | DO_SUPPORTS_TRANSACTIONS)));SetFlag(p_vlm_filter_dev_obj->Characteristics,FlagOn(p_parent_dev_obj->Characteristics,(FILE_DEVICE_SECURE_OPEN)));// we try 8 timesfor (int i = 0; i < 8; i++){LARGE_INTEGER li_interval;……//// clear initilizing flag now//p_vlm_filter_dev_obj->Flags &= ~(DO_DEVICE_INITIALIZING);break;}return status;}来看下省略号的东西:status = IoAttachDeviceToDeviceStackSafe(p_vlm_filter_dev_obj,p_parent_dev_obj,&(p_filter_dev_ext->p_parent_dev_obj));if (!NT_SUCCESS(status)){li_interval.QuadPart = -(50 * 1000 * 10);KeDelayExecutionThread(KernelMode, FALSE, &li_interval);continue;}这个函数已经接触过了。