现在的位置: 首页 > 综合 > 正文

Windows文件系统过滤管理器之微过滤器驱动开发指南

2013年11月29日 ⁄ 综合 ⁄ 共 5012字 ⁄ 字号 评论关闭

Windows文件系统过滤管理器之

微过滤器驱动开发指南

 

 

 

0.译者序

 

对我来说,中文永远是最美,最简洁,最精确和最高雅的文字。

 

本文翻译仅仅用做交流学习。我不打算保留任何版权或者承担任何责任。不要引用到赢利出版物中给您带来版权官司。本文的翻译者是楚狂人,如果有任何问题,你可以通过邮箱MFC_Tan_Wen@163.com,或者是QQ16191935,或者是MSN walled_river@hotmail.com与我交流。

 

我翻译此文出于对文件系统技术的兴趣。这就是新的文件系统过滤接口。其实也不算什么新的东西,微软开发了另一个旧模型的过滤驱动,称之为过滤管理器(Filter Manager)。从而提供了一系列新的接口来让你开发新的过滤器。确实这套接口变简单清晰了。你至少避免了包含无数个信息的IRP,避免了请求在各个部件中循环的发来发去,一个分发例程中处理无数中情况,一不小心系统崩溃。我不知道花了多少时间才弄明白一个简单的缓冲读请求从用户到过滤到文件系统和缓冲管理器,虚拟内存管理器之间的关系!现在你也许不需要再管他们了,仅仅做好自己的过滤工作就可以。

 

这套接口强大吗?能实现你想要的功能吗?你很快就发现你没有研究过sfilter就看不懂Minifilter,或者是还得从sfilter开始做起更灵活一点。微软就是这样,拿僵硬而且也不简单的东西来简化强大灵活但是设计上一团糟的东西,对于你来说是两者都必须学习,最后你的脑子被微软塞得满满的,不过没关系,我们已经习惯了.

 

此文的原文是《Filter Driver Development Guide》,出自微软的网站。我在以下这个地址下载得到此文:

http://download.microsoft.com/download/e/b/a/eba1050f-a31d-436b-9281-92cdfeae4b45/FilterDriverDeveloperGuide.doc

我尽量在翻译中使文章保持原貌。如果您认为此文无法理解,建议您首先阅读旧的文件过滤驱动的相关资料。我认为必须有文件系统和windows驱动的相关知识,才能阅读此文。

 

我未必总是使用规范的名词,但我总是使用最容易理解的名词。一些常用的可能不翻译,比如IRP,MDL,有驱动开发经验的人应该可以理解。另一些可能采用中文(英文)的方式。

 

一些解释如下:

例程(Routine):我不懂得例程和函数有什么不同。我认为例程就是函数。称为Routine而不是Function可能是为了避免其他c程序员理解得太容易。

接口(Api):编程开发接口,一个提供给你调用的函数。

Stream):如果你写过文件系统驱动那么你一定知道FileObject,对你来说一个流就是一个FileObject

文件(File):一个文件可能有多个流,因为可能多次打开,多个FileObject可能对应一个文件。

域(Field):一个数据结构中的一个数据成员。喜欢数据库的人可能称为字段。喜欢面向对象的称为数据成员。

透明transparence):看不见意味着也不需要管。不过请注意透明的反意词绝对不是不透明opacity

不透明opacity):不知道的。比如空指针。因为空指针指向的是什么,从空指针本身是了解不到的。所以称为不透明的指针。

回调(Callback)函数:一个由系统调用而且原则上你不能自己调的函数。

预操作(pre-operation)回调:如果打算过滤一个操作,那么这个回调出现在操作完成之前。

后操作(post-operation)回调:如果打算过滤一个操作,那么这个回调出现在操作完成之后。

 

1.概述

 

这个文档用于I/O管理器和基本文件系统之间的过滤驱动。文件系统可能是本地或者网络的。这个文档不涉及文件系统和存储设备之间的过滤驱动,比如FtDisk和DMIO.

 

我们将主要讨论一种新的文件系统过滤驱动模型,所谓的微过滤器(minfiter).

 

以前的文件系统过滤基于一个例子sfilter.使用IRP和设备对象进行过滤。我们现在称之为旧过滤模型

 

新的架构中一个关键的组件其实是一个旧过滤模型的文件系统过滤驱动,被称为过滤管理器(Filter Manger).在未来,微软发行的操作系统将默认安装这个驱动。(译者注:现在,你得手工安装。)这个驱动通过提供一些库供微过滤器调用来管理所有的微过滤器。必要的头文件,库和二进制代码都在微过滤器IFSKit中。

 

为何要开发一个微文件系统过滤驱动?

 .通过更少的工作量,得到更简单的,更可靠的过滤驱动.

 .动态加载和卸载,绑定和解除绑定.

 .在过滤栈中,绑定到一个合理确定的位置。

 .上下文管理。快捷,干净,可靠的上下文管理,用于文件对象,流,文件,实例和卷.

 .一组有用的调用.包括根据文件名寻找,高效存取,和用户态程序之间的通信,以及io排队.

 .支持非回环I/O.这样,一个微过滤器发起的I/O请求可以轻松的只让栈中更下面的微过滤器以及文件系统看到了。

 .仅仅过滤感兴趣的操作。不象旧过滤模型那样必须挂接每个操作入口以便把操作传递到下层.

 

2.术语

 

在过滤管理器架构中,定义了一些新的对象。为了搞清这些,这里将列出一些定义:

 

过滤器:在文件系统上执行一些过滤操作的一种驱动.

 

卷:在本地文件系统,这个对象指文件系统所管理的逻辑卷.对于网络重定向文件系统,指所有网络请求被重定向的目的。卷直接对应文件系统(无论本地或者网络)旧过滤模型中的设备对象(DEVICE_OBJECT).

 

实例:一个过滤器在一个卷上唯一的某层上生成的一个实例化对象。过滤管理器把所有的IO请求发到卷上的实例栈上。一个微过滤器在一个卷上可能不止一个实例.规范的例子是FileSpy.有时候把FileSpy的两个实例分别绑定在另一个过滤器的上边和下边。此时每个实例有一个私有的上下文.这个上下文包含IO操作的日志.可以用来比较一个过滤器上下的IO操作有什么不同。

 

文件:文件系统保存在一个磁盘上的可能包含若干个流的有名字的数据对象.

流:指一个文件中的物理数据流.

 

文件对象(FileObject):用来描述一个用户对一个文件中的一个物理数据流的一次打开。

 

回调数据(CallbackData):过滤管理器中的一种数据结构,包含了一个操作中的所有信息。对应于旧过滤模型中的IRP.

 

3.微过滤器安装

 

微过滤器可以通过一个INF文件安装。INF文件指出了这个微过滤器所支持的实例.实例的具体说明在第5节.每个实例有一组标志,还有一个唯一的数值固定了它在过滤栈中的位置。

 

INF文件中有一个表标明了每个实例的层级.这用来给文件系统过滤的开发商装载他们的微过滤器.有标记标明了这个微过滤器是否需要"自动的绑定".如果是,那么每个新的卷出现的时候,微过滤器都回收到一个通知.它可以在此绑定他们.绑定的时候,inf文件中的层级决定了绑定到什么层次上。

 

在微过滤器运行时,文件系统过滤开发商也可以在某个指定的层级上动态的生成一个实例,这可以使用FilterAttachAtAltitude()调用.这对于开发者来说可以用来进行测试和排除bug.

 

4.微过滤器注册

 

微过滤器是内核驱动。因此它必须导出一个名为DriverEntry的函数。在驱动加载的时候这个函数第一个被调用.很多微过滤器在DriverEntry()中调用FltRegisterFilter().

 

FilterRegisterFilter()需要传入一个参数。是一个FLT_REGISTRATION结构.包含了:一个卸载例程.实例通知回调,一组上下文回调指针,一组文件系统操作回调指针.一般情况下,微过滤过器只捕获一部分操作,因此文件系统操作回调指针可能并不多。

 

对于某一种操作,微过滤器可以指定一些附加的标记来指明它是否在所有的情况下都收到它们.比如,如果FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO被指定了,微过滤器就不会收到任何此类IRP的paging I/O操作。

 

同样的,如果FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO被指定了,那么只有这类操作的非缓冲请求能看见.(比如说,指定了IRP_MJ_READ类操作,那么所有的缓冲读就都不会被微过滤器捕获了。

 

5.开始过滤

 

当一个微过滤器注册自己,它就应该在某个时间调用函数FltStartFiltering()来开始过滤。并不一定要在DriverEntry中调用。不过大多数微过滤器可能是这样做的。

 

这个函数将激发必要的通知,导致微过滤器绑定到卷上然后开始过滤I/O操作。为此,过滤管理器会通过微过滤器的inf文件遍历它注册过的所有的实例。

 

每个示例都有一个层级。一个层级是一个唯一的字符串,(如"100.123456"),这个定义了微过滤器的这个实例在栈上的位置。商业版本的微过滤器层级将由微软公司来分配。

 

层级的数字越高,这个微过滤器绑定在栈上的位置就越高。一些示例层级提供给开发者用来实现微过滤器。这些是仅有的不会被分配的层级。层级有两个作用:一是确定两个微过滤器之间的顺序关系,尤其是有时得实现一些不用去考虑个别微过滤器什么时候加载的功能。

 

比如说,一个加密解密过滤器必须安装在一个防病毒的过滤的下边。否则,防病毒过滤器无法从已经加密的内容中发现病毒。另外就是提供了一个最小的测试矩阵,用来测试这些过滤驱动的互容性。如果这些驱动实例都是按一个指定的顺序在栈中的,那么测试的时候就不用再考虑排列各种不同的顺序了。

 

在inf文件中,一个实例和一个标记联系在一起。如果第1个位标记了,那么微过滤器不会在卷出现在系统中的时候得到通知。这样的实例应该通过过滤管理器编程接口来手工的绑定。如果第2位被设置了,即使手工的发送了一个绑定请求,微过滤器也不会收到通知来要求绑定一个实例到一个卷。

 

6.实例的通知

 

当一个实例生成的时候,一组回调函数提供来通知微过滤器。通过这些回调,微过滤器可以决定它的实例在什么时候绑定到卷上和从卷上解除了绑定。

 

6.1. 安装一个实例

 

回调例程InstatanceSetupCallback()在下列情况下被调用:

.当一个微过滤器加载的时候,每个存在的卷都会导致这个调用。

.当一个新的卷被mount.

.当FltAttachVolume被调用(内核模式)

.当FltAttachVolumeAtAltitude()被调用(内核模式)

.当FilterAttach()被调用(用户模式)

.当FilterAttachAtAltitude()被调用(用户模式)

 

在这个过程中,微过滤器决定是否在这个卷上生成实例。这个回调的原型如下:

typedef NTSTATUS

(*PFLT_INSTANCE_SETUP_CALLBACK) (

    IN PCFLT_RELATED_OBJECTS FltObjects,

    IN FLT_INSTANCE_SETUP_FLAGS Flags,

    IN DEVICE_TYPE VolumeDeviceType,

    IN FLT_FILESYSTEM_TYPE VolumeFilesystemType

);

FltObjects结构喊有指向微过滤器和实例的指针。这个实例指将要在InstanceSetupCallback()函数中生成的实例。Flags标记是什么操作导致激发了InstanceSetupCallback():

FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT:  这是一个微过滤器注册的时候,一个自动的绑定通知。过滤管理器为每个刚加载的微过滤器枚举所有的卷。如果是一个使用者明确的指定一个实例绑定到某一个卷,不会设置有这个标记。

FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT:  通过调用FilterAttach()(用户态)或者是FilterAttachVolumeAtAltitude()(用户态)或者是FltAttachVolume()(内核态)所发起的一个手工的请求。

FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME:  文件系统刚刚挂载

抱歉!评论已关闭.