在我们MiniFilter上下文框架中,我们可以指定一个 Context结构体数组. 哪里的上下文就是i这里所说的上下文.
何为上下文?
上下文其实就是附着与某个对象上的一段内存.内存的缓存相关数据. 这块内存是自己定义的. 跟设备扩展一样,本质上也是我们自己定义的. 上下文是附着于目标对象的.所以目标对象是什么那么上下文是什么.
目标对象有很多.
文件对象
设备对象
实例对象
卷设备对象
等等.
API如下
FltAllocateContext FltReleaseContext
举例子:
typdef {xxx}INSTANCE_CONTEXT; status = FltAllocateContext( g_pFilter, FLT_INSTANCE_CONTEXT, sizeof(INSTANCE_CONTEXT),//大小是结构体大小 PagedPool, &pcontext); //成功后的传出参数.
例子就是在为Instance实例进行上下文内存申请. 申请后需要设置到实例中.进行绑定.
例子:
FltSetInstanceContext( FltObjects->Instance, FLT_SET_CONTEXT_REPLACE_IF_EXISTS, pContext, NULL);
instance是与卷一一对应的.所以我们申请的上下文可以存储卷的一些信息. 比如扇区大小等等.
获取访问
FltGetInstanceContext(FltObjects->Instance,&pcontext);
总结:
总结来说设置上下文总共四个函数调用. 上下文是我们自定义结构.
FltAllocateContext 申请一个上下文 FltSetInstanceContext 将上下文绑定到一个对象中 FltGetInstanceContext 从绑定的对象中获取一个上下文 FltReleaseContext 释放申请的上下文
流上下文(Stream Context)
所谓流上下文就是我们常用过的FCB块(File Control Block) 文件和FCB是一一对应的关系.
所谓FCB就是在打开文件的时候会为其创建一块缓存.这块缓存就叫做FCB
操作的API如下:
FltGetStreamContext() FltSetStreamContext()
流句柄上下文(Stream Handle Context)
文件对象称为 FileObject 一个文件可以有多个FileObject .
操作API
FltGetStreamHandleContext() FltSetStreamHandleContext()
最常用的上下文应该是这个.因为文件对象我们用的很多.
实例上下文(instance Context)
参考1.1节例子
卷上下文(Volume Context)
卷就是我们常见到C D E F盘.以及网络重定向器. 一般情况下一个卷对应一个过滤器实例对象.
实战操作中经常使用 实例上下文来代替 卷上下文. 因为实例和卷是一一对应的所以使用实例即可.
API
FltGetVolumeContext() FltSetVolumeContext()
文件上下文
在Vista之后 MiniFilter还提供了文件上下文.
FltGetFileContext() FltSetFileContext()
如果需要使用查询下WDK帮助文档.
在WDK中的scanner例子中可以看到上下文是怎么使用的.
如下:
const FLT_CONTEXT_REGISTRATION ContextRegistration[] = { { FLT_STREAMHANDLE_CONTEXT, 0, NULL, sizeof(SCANNER_STREAM_HANDLE_CONTEXT), 'chBS' }, { FLT_CONTEXT_END } }; const FLT_REGISTRATION FilterRegistration = { sizeof( FLT_REGISTRATION ), // Size FLT_REGISTRATION_VERSION, // Version 0, // Flags ContextRegistration, // Context Registration. Callbacks, // Operation callbacks ScannerUnload, // FilterUnload ScannerInstanceSetup, // InstanceSetup ScannerQueryTeardown, // InstanceQueryTeardown NULL, // InstanceTeardownStart NULL, // InstanceTeardownComplete NULL, // GenerateFileName NULL, // GenerateDestinationFileName NULL // NormalizeNameComponent };
还可以在FLT_CONTEXT_REGISTRATION
为每一个上下文提供要给清理函数.
如果前提是我们用到了上下文就可以释放了.
释放: 这里的释放不是要 使用
FltReleaseContext
来释放上下文内存.而是释放我们上下文结构中的资源,比如保存的事件同步的句柄.以及保存的指针指针指向的内存. 而不是直接释放上下文内存.
如下:
const FLT_CONTEXT_REGISTRATION ContextRegistration[] = { { FLT_STREAMHANDLE_CONTEXT, 0, ContextCleanup, CTX_STREAMHANDLE_CONTEXT_SIZE, CTX_STREAMHANDLE_CONTEXT_TAG }, { FLT_INSTANCE_CONTEXT, 0, ContextCleanup, CTX_INSTANCE_CONTEXT_SIZE, CTX_INSTANCE_CONTEXT_TAG }, { FLT_FILE_CONTEXT, 0, ContextCleanup, CTX_FILE_CONTEXT_SIZE, CTX_FILE_CONTEXT_TAG }, { FLT_STREAM_CONTEXT, 0, ContextCleanup, CTX_STREAM_CONTEXT_SIZE, CTX_STREAM_CONTEXT_TAG }, { FLT_CONTEXT_END}
在MiniFilter中使用的内核文件操作API不再是Zwxxxx了.而是重新定义封装的FltXXXX了.
不使用ZwXXX是防止重入. 比如我们本身就是过滤文件了.你还使用文件API. 那么我们就捕获到API操作了.就会导致重入了.
API如下:
API | 作用 |
---|---|
FltCreateFile | 打开或者创建文件 |
FltReadFile | 读取文件 |
FltWriteFile | 写文件 |
FltClose | 关闭文件句柄 |
FltQueryXxx | 查询文件信息等查询函数 |
FltSetXxx | 设置文件信息等设置函数 |
FltGetXxx | 获取文件一些信息 |
FltPerformXxx | 确认例程通知 |
这些API的操作与Zw操作不同的是前两个参数是新加的,都与MiniFilter相关联.
举例:
ntStatus = FltCreateFile( pFilter, pDstInstance, &hDstFile, GENERIC_WRITE | SYNCHRONIZE, &objDstAttrib, &ioStatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_CREATE, CreateOptions, NULL,0,0);
参数1 MiniFilter的句柄,在注册的时候得出的.
参数2 实例
其他参数与Zw参数一样,查询API文档即可.
未完待续