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