驅動層的步驟
1. 創建通信端口
FltCreateCommunicationPort
對於安全對象,必須設置OBJ_KERNEL_HANDLE。
ServerPort 監聽客戶端連接請求的端口。
第三個參數ObjectAttributes 通過InitializeObjectAttributes初始化,其中包含了端口名稱。方便應用層打開。
ConnectNotifyCallback 用戶態連接回調,這里對多個連接進行一些區別操作。
比如ClientPort,表示用戶態與內核建立的新連接的客戶端端口句柄。
minifilter必須把該句柄傳遞FltSendMessage之類的函數,作為第二個參數。
與FltCreateCommunicationPort返回的ServerPort 不同。
並且一般在DisconnectNotifyCallback 中調用FltCloseClientPort釋放。
DisconnectNotifyCallback 客戶端所有連接端口中斷,或者minifilter卸載時的回調。
***MessageNotifyCallback 用戶態消息處理回調。
用戶態通過FilterReplyMessage發送的消息,都在這里處理。
2. 關閉通信端口
FltCloseCommunicationPort
====================================================================
應用層的步驟
1. 創建連接
FilterConnectCommunicationPort 打開一個新的通信服務器端口的連接。該微端口在驅動中創建。
端口名類似L"\\MyFilterPort"
應用程序通過返回的端口句柄與minifilter通信。
2. 發送數據
FilterSendMessage 發送message給內核minifilter
message發送到minifilter的消息通知回調函數中,在這里處理消息。
這些回調函數在內核創建通信端口時指定 MessageNotifyCallback。
該操作是同步的。調用者處於等待狀態,直到消息被傳遞並收到minifilter的replay。
當然如果希望有replay,那么outbuffer參數不能為空。
3. 接受數據
FilterGetMessage 從minifilter取得一個message
注意參數lpMessageBuffer,必須包含FILTER_MESSAGE_HEADER 結構。
如果是同步操作,會一直等待直到收到消息。
如果是異步操作,返回ERROR_IO_PENDING,通過重疊結構的事件來得知消息是否被傳遞。
FilterReplyMessage
注意參數lpReplyBuffer,必須包含FILTER_REPLY_HEADER 結構。
***特別注意,FltSendMessage 與FilterReplyMessage的buffersize,由於padding的緣故,需要精確指定大小。
typedef struct _REPLY_STRUCT
{
FILTER_REPLY_HEADERHeader;
MY_STRUCTUREData;// The structure to be sent to the minifilter.
} REPLY_STRUCT, *PREPLY_STRUCT;
sizeof(REPLY_STRUCT) 可能比sizeof(FILTER_REPLY_HEADER) + sizeof(MY_STRUCT)大。
所以建議使用后面的方式。