Visual Studio 2013开发 mini-filter driver step by step 应用层与内核通讯(8)
應(yīng)用層與內(nèi)核通訊是通過通訊端口來進(jìn)行的,下面的這個(gè)API就是內(nèi)核用來創(chuàng)建一個(gè)內(nèi)核端口的。
NTSTATUS FltCreateCommunicationPort(_In_??????PFLT_FILTER Filter,_Out_?????PFLT_PORT *ServerPort,_In_??????POBJECT_ATTRIBUTES ObjectAttributes,_In_opt_??PVOID ServerPortCookie,_In_??????PFLT_CONNECT_NOTIFY ConnectNotifyCallback,_In_??????PFLT_DISCONNECT_NOTIFY DisconnectNotifyCallback,_In_opt_??PFLT_MESSAGE_NOTIFY MessageNotifyCallback,_In_??????LONG MaxConnections );
這里面有重要的三個(gè)回調(diào)函數(shù),ConnectNotifyCallback,DisconnectNotifyCallback,MessageNotifyCallback。
ConnectNotifyCallback:當(dāng)應(yīng)用層調(diào)用FilterConnectCommunicationPort 來與minifilter driver建立連接的時(shí)候,Filter Manager 會調(diào)用這個(gè)回調(diào)函數(shù)。
Pointer to a caller-supplied callback routine to be called whenever the user-mode handle count for the client port reaches zero or when the minifilter driver is about to be unloaded。
The Filter Manager calls this routine, at IRQL?=?PASSIVE_LEVEL, whenever a user-mode application callsFilterSendMessage to send a message to the minifilter driver through the client port.
學(xué)習(xí)最有效,最快的方式不是看書和看文檔,而是實(shí)戰(zhàn),來看看示例代碼:
NTSTATUS
SSMFInitializeCommPort()
{
?NTSTATUS status = STATUS_SUCCESS;
?PSECURITY_DESCRIPTOR sd;
?OBJECT_ATTRIBUTES oa;
?UNICODE_STRING uniString;
?status = FltBuildDefaultSecurityDescriptor(&sd,
??FLT_PORT_ALL_ACCESS);
?if (!NT_SUCCESS(status))
?{
??return status;
?}
?RtlInitUnicodeString(&uniString, SSMF_PORT_NAME);
?InitializeObjectAttributes(&oa,
??&uniString,
??OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
??NULL,
??sd);
?status = FltCreateCommunicationPort(gFilterHandle,
??&gServerPort,
??&oa,
??NULL,
??SSMFConnect,
??SSMFDisconnect,
??SSMFMessage,
??1);
?FltFreeSecurityDescriptor(sd);
?return status;
}
這個(gè)SSMFInitializeCommPort函數(shù)就是創(chuàng)建了一個(gè)內(nèi)核端口供應(yīng)用層連接,當(dāng)然還有那三個(gè)重要的函數(shù)要實(shí)現(xiàn),在這里我們只是簡單的輸出一下log信息和返回一些簡單的數(shù)據(jù)。
NTSTATUS
SSMFConnect(
_In_ PFLT_PORT ClientPort,
_In_ PVOID ServerPortCookie,
_In_reads_bytes_(SizeOfContext) PVOID ConnectionContext,
_In_ ULONG SizeOfContext,
_Flt_ConnectionCookie_Outptr_ PVOID *ConnectionCookie
)
{
?PAGED_CODE();
?UNREFERENCED_PARAMETER(ServerPortCookie);
?UNREFERENCED_PARAMETER(ConnectionContext);
?UNREFERENCED_PARAMETER(SizeOfContext);
?UNREFERENCED_PARAMETER(ConnectionCookie);
?PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("SSMF!SSMFConnect entered"));
?gClientPort = ClientPort;
?return STATUS_SUCCESS;
}
VOID
SSMFDisconnect(
_In_opt_ PVOID ConnectionCookie
)
{
?PAGED_CODE();
?UNREFERENCED_PARAMETER(ConnectionCookie);
?//
?//? Close our handle
?//
?PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("SSMF!SSMFDisconnect entered"));
?FltCloseClientPort(gFilterHandle, &gClientPort);
}
NTSTATUS
SSMFMessage(
_In_ PVOID ConnectionCookie,
_In_reads_bytes_opt_(InputBufferSize) PVOID InputBuffer,
_In_ ULONG InputBufferSize,
_Out_writes_bytes_to_opt_(OutputBufferSize, *ReturnOutputBufferLength) PVOID OutputBuffer,
_In_ ULONG OutputBufferSize,
_Out_ PULONG ReturnOutputBufferLength
)
{
?
?NTSTATUS status = STATUS_SUCCESS;
?PAGED_CODE();
?UNREFERENCED_PARAMETER(ConnectionCookie);
?UNREFERENCED_PARAMETER(InputBuffer);
?UNREFERENCED_PARAMETER(OutputBuffer);
?UNREFERENCED_PARAMETER(OutputBufferSize);
?UNREFERENCED_PARAMETER(ReturnOutputBufferLength);
?UNREFERENCED_PARAMETER(InputBufferSize);
?if (InputBuffer)
?{
??char* data = (char*)InputBuffer;
??PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("The message data is %s",data));
?}
?if (OutputBuffer != NULL && OutputBufferSize > 4)
?{
??RtlCopyMemory(OutputBuffer, "1234", 4);
??*ReturnOutputBufferLength = 4;
?}
?PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("SSMF!SSMFMessage entered"));
?return status;
}
下面我們來看看應(yīng)用層怎么來與內(nèi)核通訊并且傳遞數(shù)據(jù):
HANDLE port = INVALID_HANDLE_VALUE;
?printf("Connecting to filter's port...\n");
?HRESULT hResult = FilterConnectCommunicationPort(SSMF_PORT_NAME,
??0,
??NULL,
??0,
??NULL,
??&port);
?if (hResult != S_OK)
?{
??return false;
?}
?printf("connected to the filter's port\n");
?//send message
?char buffer[100] = { 0 };
?strcpy_s(buffer, "abcdefg");
?char out_buf[100] = { 0 };
?DWORD ret_size = 0;
?hResult = FilterSendMessage(port, buffer, strlen(buffer), out_buf, 100, &ret_size);
?if (hResult == S_OK)
?{
??printf("The data is %s,len is %d\n", out_buf,ret_size);
?}
?CloseHandle(port);
總結(jié)
以上是生活随笔為你收集整理的Visual Studio 2013开发 mini-filter driver step by step 应用层与内核通讯(8)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Visual Studio 2013开发
- 下一篇: Visual Studio 2013开发