windows驱动文件流上下文操作一

概述

  文件流上下文在微过滤器(Minifilter)程序中能够为文件相关的操作存储有用的信息,在微过滤器的每个文件处理阶段从指向驱动实例的之阵中获取对应文件的文件上下文信息,为驱动中处理文件提供了巨大的便利也提升了驱动处理文件的效率,试想没有文件流上下文,对同一个文件的属性判断要在每个IRP操作中重复判断,那是多么浪费性能。
  上下文是系统为驱动实例和处理对象(文件句柄,文件流,卷设备)存储其关联信息而动态开辟的一块内存
  本文主要在基于Minifilter基础上,介绍一下文件流上下文如何创建,储存信息,获取上下文,释放上下文。主要操作参考自微软官方例程。

文件流上下文和流句柄上下文区别

  学会了如何创建上下文之后,将通过一组实验来说明流上下文和句柄上下文之间的区别,这里先列出结论如下:对于一个上下文的流,可以存在许多流句柄上下文。

注册流上下文

  首先要在注册过滤器结构体中定义上下文对象,关注下面的Contexts数组,示例如下:

CONST FLT_REGISTRATION FilterRegistration = {

	sizeof(FLT_REGISTRATION),           //  Size
	FLT_REGISTRATION_VERSION,           //  Version
	0,                                  //  Flags

	Contexts,                           //  Context
	Callbacks,                          //  Operation callbacks

	Unload,                            //  MiniFilterUnload

	InstanceSetup,                      //  InstanceSetup
	NULL,								//  InstanceQueryTeardown
	NULL,								//  InstanceTeardownStart
	NULL,								//  InstanceTeardownComplete

	NULL,                               //  GenerateFileName
	NULL,                               //  GenerateDestinationFileName
	NULL,                               //  NormalizeNameComponent
	NULL
};

  具体Contexts数组根据需要进行声明,示例定义如下(该示例中定义了文件流上下文和卷上下文):

CONST FLT_CONTEXT_REGISTRATION Contexts[] = {
	{ 
		FLT_VOLUME_CONTEXT,     // 定义上下文类型,这里为卷上下文
		0,                      // 定义新的上下文如何从旁视链表中分配内存的方式,定义为0,表明仅当请求申请的大小等于定义的结构长度时才分配内存,一般这里选择0就可以了 
		CleanupContext,         // 上下文清理回调函数,这里需要根据自己操作上下文的情况在这个回调函数中释放相应的内存
		sizeof(VOLUME_CONTEXT), // 卷上下文结构体大小 
		MEM_CALLBACK_TAG        // 定义申请的上下文内存池标记,一般为1-4个ascii字符
	},
	{ 
		FLT_STREAM_CONTEXT, // 定义上下文类型,这里为流上下文
		0,                  // 同上
		CleanupContext,     // 同上
		sizeof(STREAM_CONTEXT),  // 流上下文结构大小
		MEM_FILE_TAG             // 同上
	},
	{ FLT_CONTEXT_END }  // 必须这样结尾
};

  可以参考上面的注释理解这个上下文注册数组的定义
  其中CleanupContext也给出如下示例代码,该回调函数可以拿到上下文的类型,可以根据类型来对不同的上下文进行内存释放

VOID
TransEncCleanupContext(
	__in PFLT_CONTEXT pcContext,
	__in FLT_CONTEXT_TYPE pctContextType
)
{
	PVOLUME_CONTEXT pVolumeContext = NULL;
	PSTREAM_CONTEXT pStreamContext = NULL;

	PAGED_CODE();

	switch (pctContextType) {
	case FLT_VOLUME_CONTEXT:
	{
		pVolumeContext = (PVOLUME_CONTEXT)pcContext;
		// 释放上下文,定义你自己的释放函数
		MyFctFreeVolumeContext(pVolumeContext );
	}
	break;
	case FLT_STREAM_CONTEXT:
	{
		pStreamContext = (PSTREAM_CONTEXT )pcContext;
		// 释放上下文,定义你自己的释放函数
		MyFctFreeStreamContext(pStreamContext );
	}
	break;
	}
}

创建流上下文

status = FltAllocateContext(
      FltObjects->Filter,           // 过滤器驱动实例
      FLT_STREAM_CONTEXT,           // 类型
      sizeof(STREAM_CONTEXT),       // 上下文结构体的大小,根据自己的定义
      NonPagedPool,                 // 非分页内存
      pStreamContext);              // 返回值,返回的上下文对象指针

创建上下文一定要关联一个释放上下文的函数,释放在下面示例中;
在返回的上下文指针中,就可以进行自己上下文内容相关的操作了,比如记住文件的相关属性信息,或者自己有用的标识

特别注意

  在NTFS和FAT文件系统中,不支持预创建(IRP_MJ_CREATE-PRE)、关闭后(IRP_MJ_CLOSE-POST)操作中的文件流上下文操作,文件句柄上下文也是不支持的,所以在实际使用上下文的过程中,建议在创建后(IRP_MJ_CREATE-POST)中获取或者创建文件流上下文

设置流上下文

	status = FltSetStreamContext(
		pFltObjects->Instance, 
		pFltObjects->FileObject,
		FLT_SET_CONTEXT_KEEP_IF_EXISTS,
		pStreamContext,
		(PFLT_CONTEXT *)&pOldStreamContext);

  为流上下文申请空间后,便可以将上下文设置进去,和驱动实例和文件对象进行关联,和文件关联的流上下文自此就有了,可以在后续步骤中获取到流上下文了。

获取流上下文

	status = FltGetStreamContext(
	 	FltObjects->Filter,    			// 过滤器驱动实例
 		FltObjects->FileObject,    	    // 文件对象
                pStreamContext);        //Context
	...
	if (pStreamContext!= NULL) {
 		FltReleaseContext(pStreamContext);
	}

释放(Release)文件流上下文

	if (pStreamContext!= NULL) { // pStreamContext为指向流上下文的指针
 		FltReleaseContext(pStreamContext);
	}

  这里的释放上下文仅仅是对上下文的引用计数减1,并没有实际释放上下文所占用的内存,实际释放内存是在注册时的回调函数cleanup函数中进行。在内核中,很多时候用Release标识应用计数减1,带有Free的API是真正将内存清空的操作。

  如有谬误,烦请指正,谢谢!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
NexusFile 是一个双窗格文件管理器。它看起来很简单,但功能强大。 存档,FTP,高级重命名和更多功能。您可以使用皮肤和列表颜色设置自定义外观。您也可以自定义快捷方式。当然,大眼仔也给大家提供的有其它类似的 Windows 文件管理器,也可以搜索下载。 Windows Windows 双窗格文件管理器 NexusFile 文版Windows 双窗格文件管理器 NexusFile 文版 这是 NexusFile 的便携式版本-强大的文件管理器,支持两个窗格和多个选项卡。 由于不需要安装,因此可以将 Portable NexusFile 放在可移动驱动器上,将其插入任何计算机,然后直接运行其可执行文件。更重要的是您的 Windows 注册表项将保持不变。 文件管理器的界面醒目且易于浏览。因此,您可以使用资源管理器上下文菜单的功能,编辑文件以及将其复制或移动到特定位置。 但是,您还可以更改文件的属性,添加或编辑注释,压缩文件或切碎并删除它们,使用高级重命名工具以及计算文件的校验和。 此外,您可以创建和组织收藏夹列表,设置工作文件夹,复制完整路径,使用特定掩码选择所有文件,使用搜索功能,更改界面语言和外观,禁用双窗口模式,更改列表样式并排序文件。 此外,您可以通过 FTP 连接,映射网络驱动器,跳转到文档,音乐或图片,完全自定义界面(例如文件夹树,颜色),重新配置键盘快捷键,设置默认文件夹路径(例如音乐,视频,下载),和别的。 文件管理器在少量到等的系统资源上运行,具有很好的响应时间,并且在我们的测试过程没有冻结,崩溃或弹出错误。不幸的是,没有可用的帮助文件。但是,即使如此,我们还是强烈建议所有用户级别使用 Portable NexusFile。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风里雨里守护着你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值