Minifilter 基于 port的通信 以及实战代码操作.
一丶MiniFilter上下文讲解
1.1 Context上下文 与instance上下文例子
在我们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 释放申请的上下文
1.2 其它上下文
-
流上下文(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帮助文档.
1.3 上下文清理函数简介 以及例子
在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中的文件操作
在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文档即可.
未完待续