jununfly
驱动牛犊
驱动牛犊
  • 注册日期2008-10-17
  • 最后登录2010-06-01
  • 粉丝0
  • 关注0
  • 积分86分
  • 威望560点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:5527回复:7

Windows Streams——文件系统中的流

楼主#
更多 发布于:2009-01-09 11:43
 终于有点时间看点东西了,作为牛犊,什么缓冲时间都没就一个人直接上架,道路很曲折,体味良多,
所以希望对大家有所帮助,这次不再用英文名,直接用ID。请老牛们不吝赐教,共同建立高质量的交流~

Windows Streams - An Introduction to File System Streams The NT Insider, Vol 13, Issue 2, March - April 2006 | Published: 17-Apr-06| Modified: 17-Apr-06
 
声明:原文来自www.osr.com,所有权利归原作者所有,翻译并贴在驱动开发网的目的只为学习和交流,除了商用你可以随意地使用这篇译文。但请不要删除声明。
——by jununfly

对那些不熟悉文件系统空间的人来说,流的概念也是陌生的。虽然在1993年Windows NT首次投入使用的时候,NTFS已经实现并使用了流,但即使到了今天应用程序也很少使用到这一特色。然而,随着Win32接口新增加了一些用于探测和列举流的设计(Windows Server 2003引入了FindFirstStream和FindNextStream APIs),这些APIs在将来的应用程序中出现的频率将愈来愈高。

对内核级文件系统设计来说,理解流的概念非常重要,因为流是设计像过滤器管理器(Fileter Manager)这样的接口的组成部分。比如,过滤器管理器明确地使用流上下文的概念而不是文件上下文。当然,从本文完稿日起过滤器管理器中已经不支持文件上下文。然而,我们期望未来版本的过滤器管理器将会支持文件级上下文。

从历史角度来看关联文件的附加信息对使用数据的应用程序透明是有用的。理想的是,像这样的结合只作为文件的一个更多的部分。因此,举个例子,假如用户复制这个文件,附加信息也连同文件的用户数据部分一起移动。早期像这样的附加信息被包含在资源分支中(resource fork,它是一种属性,被添加到Macintosh上来关联一个指定的应用程序到给定的数据文件上)。在Windows 中这种结合是传统地基于文件名完成的(它的扩展)。然而,在Macintosh的世界里它是文件固有的一部分,这就意味着两个使用同一扩展名的文件能实际上调用不同的应用程序。

在OS/2中微软和IBM添加了一个应用级属性机制名为扩展属性(extended attributes). 为了保持OS/2的传统,当Windows NT 3.1首次投入使用时,它本属的(native)三个读/写文件系统都支持扩展属性。NTFS和HPFS在文件结构中给予了本属的支持, 而FAT使用根目录中的一个隐藏文件来跟踪扩展属性。即使到了今天IFS Kit (和现在的WDK)中的FAT文件系统代码中依然有需要支持FAT-12和FAT-16格式的文件系统中的扩展属性的痕迹。然而FAT-32格式不支持扩展属性。

NTFS的设计包括一个组合式概念,那就是文件是一个或多个流的容器。任何一个流都能拥有一个属性集来描述指定流的特征。对NTFS来说,这个模型的一大好处是它们能为了利用Macintosh的服务而支持Macintosh资源分支(resource forks)。仔细回顾下CDFS源代码 – 也在IFS Kit和WDK中 – 那里面也有对Macintosh资源分支的支持。这个组合概念也为允许应用程序和其他系统组件来关联信息到文件上提供了一个普遍的扩展机制。

一个可能的动机或许已经对处在同一时期的OLE团队起作用了。那时,OLE团队在文件中藏入一个文件系统来允许对藏入来自不同应用程序的数据元素的透明的支持。虽然这个方案本身对应用程序来说不透明,但它被封装到应用程序能使用的库中,这使它”看起来”是透明的。虽然我们无法确定是不是这个动机,但是想在文件系统层直接添加对这种分离的支持对文件系统开发人员来说是一个巨大的诱惑。当然,在Windows 2000的开发期间,存在通过使用NTFS流机制来实现结构化存储(implement structured)的一个短暂的尝试。

已经提供了流的一个基本的动机,我们仍然没有真正地概念性地描述流是什么。以下图表(看 图1)试图通过一个概念模型来解释一个单一文件如何能包含多个流的数据。虽然模糊地基于NTFS模型,但我们不说这是NTFS模型,读者也不应该据此得出NTFS或任何其他的文件系统如何实现流的任何推论。


图1 – 流的概念模型    

因此,从理论上讲一个单一”文件”由多个截然不同的组件组成。其中一些应用于整个文件的属性。例如,这可能包含安全描述符,文件的扩展属性列表和文件上的时间戳。每一个流都有名字,其缺省名为零长度字符串比如上图中使用的NULL名。预备流有有一个非零长度的字符串名。任何一个流名都是唯一的,但可能有许多不同的流。文件系统负责在名上放置一切限制,比如流名的大小。一个单独的流有它自己关联的data属性。 上图中我们使用$DATA名是因为当我们开始解释NTFS使用的命名方法时会非常轻松。因为流关联了数据,文件系统也必须像流的本地信息、数据元素的大小、任何现存的列表和位图或者其他对给定的流来说可能是唯一的控制结构一样维护流的附加信息。

流可以被用来存储几乎任何东西.因为它们仅仅是文件的另一个元素,当流存在时应用程序能要么忽略它要么使用它。系统应用能被构造来保存流。例如, Win32 API CopyFileW 知道文件的流且复制那些流。类似的,Win32 Backup API知道流且”把它们封装”到一个由<stream header>+<stream data>+ 等等组成的单独的流中,这就允许以一个对Backup应用程序透明的样子来备份整个文件的内容。在引入Windows Server 2003中的FindFirstStream API前, Backup API是文件流存在的充分证据。在这个语境中”documented”意味着有一篇微软基础知识文章描述了如何使用Backup API来寻找文件的流。

为了允许应用程序打开一个文件的流,NTFS扩展了名支持(包括’:’字符的使用)来从文件名中分离出流的名。这类似于用来从文件的名中分离出目录名的’\’。FAT不支持文件名中的’:’,因此在FAT文件系统上不可能正常地打开流。虽然其他文件系统不支持流,一个应用程序员应该根据以下来决定流支持:
试图打开一个文件流.
查询文件系统特征并检查FILE_NAMED_STREAMS属性.
应用程序不应该使用文件系统的名因为这将引起一个长期的应用程序兼容性的问题。其他的文件系统(除了NTFS)支持流和流的概念。

“不认识流”的应用程序正常地通过名打开文件。然后此应用程序获得了默认数据流。因此,打开文件foo.txt 与打开流foo.txt::$DATA 一样(就是说,名为NULL的流的数据属性)。然而,如果你在许多应用程序中尝试这样做你会发现它失败了 – 不是因为流没有正常起作用,而是因为不认识流的应用程序可能设法通过访问目录使文件的存在生效。既然目录不列出文件的流,那么应用程序将会决定指定的名不存在。在图2中通过使用命令行演示了这种行为的一个例子。


图2 – 应用程序中意识到的流的变化    

注意使用完全受限的名包括流后缀的更多应用(more utility)/* ?这个名词或许是说功能更多的应用程序*/不会工作,但当没有用一个流标识符来访问文件时,从名中重定向输入会适当地工作。一个指定的应用程序在一个有多个流的文件上的如何行动依赖于这个应用程序的实现。

通过使用filespy我们有可能”看见” 更多应用的真正的问题是它试图在目录中使文件生效。对第一条命令的跟踪的部分如图3.


图3 – 用FileSpy观察更多的东西    

注意它调用了IRP_MJ_DIRECTORY_CONTROL (IRP_MN_QUERY_DIRECTORY,用信息FileBothDirectory),返回值是STATUS_NO_SUCH_FILE。虽然在跟踪中还不是完全清楚,但我们可以断言这就是因为实际上它正在寻找的文件的全名包括了流的部分。如果我们间接地这样做它就不会以同一方式起作用了。

经证实访问流的最好的应用是低应用(lowly utility,对应上面的more utility)notepad。取代询问目录,notepad通过打开指定的对象来决定流是否存在。

图4演示了使用命令行应用来用两个数据流创建一个单一文件。

图4 – 一个文件...两个流    

 
第一行是”缺省地”创建默认数据流因为它不是指定的。第二行是创建一个名为bar的数据流。 下一步我们分别重获每个流的内容。最后,我们注意到目录入口仅仅报告了默认数据流中的数据大小。

现在我们已经描述了文件上的流,你能很轻易地推理出NTFS也支持目录上的预备流。把没有出现在目录内容列表中的信息嵌入到目录中的能力对存储目录辅助信息比如一个backup程序的目录级策略来说是一种恐怖的方式。在NTFS中一个目录的默认数据流不能被使用,因为它被用于存储真实的目录内容。

当应用程序打开一个文件,Windows OS创建一个相应的FILE_OBJECT来表示文件的打开实例。通过对流的介绍,名的数据结构不会改变但是它们惯于(常常)会改变。这个概念会混淆那些刚刚开始在内核环境下工作的人。

传统意义上,文件系统用FILE_OBJECT的域FsContext关联一个指定的文件状态到文件对象上。通常提及它们的时候就是File Control Block或Stream Control Block。后一个名字反映了(它是)文件系统中支持流的最好的实体。这点很重要因为通常(例如,在过滤驱动中)如果两个FILE_OBJECT有相同的FsContext指针值我们会把这两个文件对象结合到一起。然而,如果底层文件系统支持流,那么这两个值真正的意义是它们表示同一流而非同一文件。

为了论证我们的观点,图5图形化地论证了当一个文件系统支持流时组织文件系统数据结构的一个可能的模型。


图5 - 支持流的文件系统组织数据结构的模型    

对文件系统过滤器来说文件对象的SectionObjectPointers和FsContext值都可见,但Stream Context和File Context 则完全是文件系统内部的了。因此,不存在简单的方法来关联这些。

达成这个目的的一个方法是获得文件级属性 – 据报道是与一个给定文件的所有流一样的东西。举个例子,NTFS中我们通常使用File ID 因为这个64位值对一个给定卷上的一个给定文件来说是唯一的。如果我们发现两个流有相同的File ID 值,我们就知道它们表示同一文件即使FsContext域不相同。在这种情况下,我们直到同一文件上有不同的流。

因此,不是所有的文件系统都支持这个特征。举个例子,同一文件的不同流CIFS/SMB转向器 不会返回相同的File ID,即使远程文件系统是NTFS,因为转向器会产生这样的一个File ID。因此,设法关联经由转向器的同一文件的不同流是一个更大的挑战 – 也超出了本文的范围。

不幸的是,这意味着在这个问题上没有一个通用目的的解决方案。虽然过滤器管理器允诺在将来的某个版本中会有一个解决方案,但是我们可以预料那个支持很有可能会在未来的Windows版本中受限,而这使其会最终成为一个"go away"问题但在可预见的未来中很有可能会遗留给我们。

已经描述了流的基本机制和从内核文件系统/过滤驱动级如何看待它们,我们认为提供使用流的额外的动机会比较有用。当今,搜索有关流的信息和它们在NTFS中的使用会让人小气馁一把,因为几乎每篇文章都说到流如何是潜在的安全隐患。这个特点使流有用(事实上它们不直接可见,它们不影响被报告的默认数据流的大小等等)也令它们对不希望流存在的用户来说是个潜在的安全隐患。希望未来版本的Windows会包括监视流的应用(例如,右键点击来"列举这个文件上的流"),对Explorer来说这可能会是有用的扩展。

现在,以下列出的是流的一些现有的用途:
Internet Explorer 关联地带信息(zone information)到给定的文件上。当文件从Internet上下载下来的时候这个信息跟踪文件的来源,以便后来对这个文件的访问能采取合适的安全措施。
Windows 2000中的Internet Explorer 为图形的图像(image)内含一个thumbnail来加速目录内容的表现。在Windows XP中这个thumbnail因为性能原因被移到一个分离的文件中。这个改变暴露了一个安全隐患。
Macintosh的服务为资源分支继续使用流尽管SFM的使用在这些天遭到抨击。
SQL Server 2005 在流中存储数据库信息。
然而,构造流的其他可能的使用情景不是十分困难的事情。以下是一些例子:
加密驱动能存储”加密头”信息到一个与数据分离的流中,这就保留了原始数据的大小和数据规划。
部分常驻的文件可能有额外的控制信息,比如经由一个描述什么在文件中存在或不存在的HSM产品。
文件数据有效性驱动能存储文件块上的检验和到一个分离的数据流中。这样的检验和能探测端到端数据失败,这Exchange用来使它自己的数据生效的技术相似。
数字权限信息能关联文件。
Backup过滤器能跟踪一个文件的个别因上次backup而已经改变的块,允许只一个backup装置只捕获增加的更新资料。
审计应用程序可能存储设计规则到一个分离的流中比如目录级流。
应用程序可能会发现通过存储新版本的扩展信息到预备数据流中提供”向后兼容”的功能很有用。
流为关联信息到一个文件的数据内容上提供一个虽然模糊但非常有用的机制。随着Win32 APIs的创造,和在未来版本的Windows中更多支持流的文件系统的出现,我们期待看到流的更多应用。

 文件系统的流.rar

最新喜欢:

greenpeacegreenp...
jununfly
驱动牛犊
驱动牛犊
  • 注册日期2008-10-17
  • 最后登录2010-06-01
  • 粉丝0
  • 关注0
  • 积分86分
  • 威望560点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2009-01-09 11:45
网页上没有正常显示示意图,RAR中的WORD文档里面有,希望时间能多点让我多看多共享。
AirpLus
驱动牛犊
驱动牛犊
  • 注册日期2007-11-25
  • 最后登录2011-11-29
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望111点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2009-06-12 10:43
谢谢
喜欢破解,喜欢逆向工程
ronaldo
驱动小牛
驱动小牛
  • 注册日期2004-12-17
  • 最后登录2011-08-02
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望277点
  • 贡献值0点
  • 好评度104点
  • 原创分0分
  • 专家分0分
地板#
发布于:2010-01-11 14:34
翻译水平有待提高,我认为你并没有把文件流这个概念翻译清楚,但你的劳动值得肯定
firfor
驱动牛犊
驱动牛犊
  • 注册日期2009-11-10
  • 最后登录2016-01-09
  • 粉丝1
  • 关注0
  • 积分121分
  • 威望451点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分1分
地下室#
发布于:2010-01-15 15:56
先下了。回去上不了网。先谢谢了。我的e文也不行。
vitha
驱动牛犊
驱动牛犊
  • 注册日期2006-11-22
  • 最后登录2013-09-22
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望111点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2010-01-20 15:45
希望结合例子和实际开发讲得详细点,多谢楼主分享!
樱花看雨,淘宝精品厨卫诚信卖家
gongxp123456
驱动牛犊
驱动牛犊
  • 注册日期2004-12-15
  • 最后登录2013-10-10
  • 粉丝0
  • 关注0
  • 积分617分
  • 威望383点
  • 贡献值1点
  • 好评度59点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2010-01-26 20:29
多谢楼主!!!!!
Pegram
论坛版主
论坛版主
  • 注册日期2005-12-03
  • 最后登录2013-08-23
  • 粉丝13
  • 关注5
  • 积分1333分
  • 威望4717点
  • 贡献值1点
  • 好评度78点
  • 原创分0分
  • 专家分2分
7楼#
发布于:2010-05-01 21:19
值得肯定。我觉得驱网应该办翻译子版。
《寒江独钓》与《竹林蹊径》的合作作者。精通USB开发,设计了CY001 USB驱动套件(http://bbs.driverdevelop.com/read.php?tid-119314.html)。
游客

返回顶部