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文檔即可.
未完待續