LPC通信

服务端

DWORD WINAPI ServerThread1(LPVOID)
{
    SECURITY_DESCRIPTOR sd;
    OBJECT_ATTRIBUTES ObjAttr;              // Object attributes for the name
    UNICODE_STRING PortName;
    NTSTATUS Status;
    HANDLE LpcPortHandle = NULL;
    BYTE RequestBuffer[sizeof(PORT_MESSAGE) + MAX_LPC_DATA];
    BOOL WeHaveToStop = FALSE;
    int nError;

    __try     // try-finally
    {
        //
        // Initialize security descriptor that will be set to
        // "Everyone has the full access"
        //

        if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
        {
            nError = GetLastError();
            __leave;
        }

        //
        // Set the empty DACL to the security descriptor
        //

        if(!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
        {
            nError = GetLastError();
            __leave;
        }

        //
        // Initialize attributes for the port and create it
        //

        RtlInitUnicodeString(&PortName, LpcPortName);
        InitializeObjectAttributes(&ObjAttr, &PortName, 0, NULL, &sd);

        _tprintf(_T("Server: Creating LPC port \"%s\" (NtCreatePort) ...\n"), LpcPortName);
        Status = NtCreatePort(&LpcPortHandle,
                              &ObjAttr,
                               NULL,
                               sizeof(PORT_MESSAGE) + MAX_LPC_DATA,
                               0);
        _tprintf(_T("Server: NtCreatePort result 0x%08lX\n"), Status);

        if(!NT_SUCCESS(Status))
            __leave;

        //
        // Process all incoming LPC messages
        //

        while(WeHaveToStop == FALSE)
        {
            PTRANSFERRED_MESSAGE LpcMessage = NULL;
            HANDLE ServerHandle = NULL;

            //
            // Create the data buffer for the request
            //

            LpcMessage = (PTRANSFERRED_MESSAGE)RequestBuffer;
            _tprintf(_T("Server: ------------- Begin loop ----------------------0x%x\n"), Status);

            //
            // Listen to the port. This call is blocking, and cannot be interrupted,
            // even if the handle is closed. The only way how to stop the block is to send
            // an LPC request which will be recognized by server thread as "Stop" command
            //

            if(NT_SUCCESS(Status))
            {
                _tprintf(_T("Server: Listening to LPC port (NtListenPort) ...%s\n"), LpcPortName);
				//监听客户端连接  在此阻塞
                Status = NtListenPort(LpcPortHandle,
                                     &LpcMessage->Header);
                _tprintf(_T("Server: NtListenPort result 0x%08lX\n"), Status);
            }

            //
            // Accept the port connection
            //

            if(NT_SUCCESS(Status))
            {
                _tprintf(_T("Server: Accepting LPC connection (NtAcceptConnectPort)%s ...\n"), LpcPortName);
				//该函数执行完毕客户端NtConnectPort 结束阻塞
                Status = NtAcceptConnectPort(&ServerHandle,
                                              NULL,
                                             &LpcMessage->Header,
                                              TRUE,
                                              NULL,
                                              NULL);
                _tprintf(_T("Server: NtAcceptConnectPort result 0x%08lX\n"), Status);
            }

            //
            // Complete the connection
            //

            if(NT_SUCCESS(Status))
            {
                _tprintf(_T("Server: Completing LPC connection (NtCompleteConnectPort) %s...\n"), LpcPortName);
                Status = NtCompleteConnectPort(ServerHandle);
                _tprintf(_T("Server: NtCompleteConnectPort result 0x%08lX\n"), Status);
            }

            //
            // Now accept the data request coming from the port.
            //

            if(NT_SUCCESS(Status))
            {
                _tprintf(_T("Server: Receiving LPC data (NtReplyWaitReceivePort)%s ...\n"), LpcPortName);
				//等待 客户端调用NtRequestPort 或者 NtRequestWaitReplyPort 发送消息过来
                Status = NtReplyWaitReceivePort(ServerHandle,
                                                NULL,
                                                NULL,
                                               &LpcMessage->Header);
                _tprintf(_T("Server: NtReplyWaitReceivePort result 0x%08lX\n"), Status);
            }

            //
            // Get the data sent by the client 
            //

            if(NT_SUCCESS(Status))
            {
                // If a request has been received, answer to it.
                switch(LpcMessage->Command)
                {
                    case LPC_COMMAND_REQUEST_NOREPLY:
						//第一次通信,客户端发送了一段内容,服务器接收.服务器没有向客户端回复内容
                        _tprintf(_T("Server: Received request \"%s\"\n"), LpcMessage->MessageText);
                        break;      // Nothing more to do

                    case LPC_COMMAND_REQUEST_REPLY:
                        _tprintf(_T("Server: Received request \"%s\"\n"), LpcMessage->MessageText);
                        _tprintf(_T("Server: Sending reply (NtReplyPort) %s...\n"), LpcPortName);
                        Status = NtReplyPort(LpcPortHandle, &LpcMessage->Header);
                        _tprintf(_T("Server: NtReplyPort result 0x%08lX\n"), Status);
                        break;

                    case LPC_COMMAND_STOP:      // Stop the work
                        _tprintf(_T("Server: Stopping ...\n"));
                        WeHaveToStop = TRUE;
                        break;
                }
            }

            //
            // Close the server connection handle
            //

            if(ServerHandle != NULL)
            {
                _tprintf(_T("Server: Closing the request handle (NtClose) %s...\n"), LpcPortName);
                Status = NtClose(ServerHandle);
                _tprintf(_T("Server: NtClose result 0x%08lX\n"), Status);
            }

            _tprintf(_T("Server: ------------- End loop ---------------------- %x\n"), Status);
        }
    }

    __finally
    {
        if(LpcPortHandle != NULL)
            NtClose(LpcPortHandle);
    }
    
    return 0;
}

客户端

DWORD WINAPI ServerThread1(LPVOID)
{
    SECURITY_DESCRIPTOR sd;
    OBJECT_ATTRIBUTES ObjAttr;              // Object attributes for the name
    UNICODE_STRING PortName;
    NTSTATUS Status;
    HANDLE LpcPortHandle = NULL;
    BYTE RequestBuffer[sizeof(PORT_MESSAGE) + MAX_LPC_DATA];
    BOOL WeHaveToStop = FALSE;
    int nError;

    __try     // try-finally
    {
        //
        // Initialize security descriptor that will be set to
        // "Everyone has the full access"
        //

        if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
        {
            nError = GetLastError();
            __leave;
        }

        //
        // Set the empty DACL to the security descriptor
        //

        if(!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
        {
            nError = GetLastError();
            __leave;
        }

        //
        // Initialize attributes for the port and create it
        //

        RtlInitUnicodeString(&PortName, LpcPortName);
        InitializeObjectAttributes(&ObjAttr, &PortName, 0, NULL, &sd);

        _tprintf(_T("Server: Creating LPC port \"%s\" (NtCreatePort) ...\n"), LpcPortName);
        Status = NtCreatePort(&LpcPortHandle,
                              &ObjAttr,
                               NULL,
                               sizeof(PORT_MESSAGE) + MAX_LPC_DATA,
                               0);
        _tprintf(_T("Server: NtCreatePort result 0x%08lX\n"), Status);

        if(!NT_SUCCESS(Status))
            __leave;

        //
        // Process all incoming LPC messages
        //

        while(WeHaveToStop == FALSE)
        {
            PTRANSFERRED_MESSAGE LpcMessage = NULL;
            HANDLE ServerHandle = NULL;

            //
            // Create the data buffer for the request
            //

            LpcMessage = (PTRANSFERRED_MESSAGE)RequestBuffer;
            _tprintf(_T("Server: ------------- Begin loop ----------------------0x%x\n"), Status);

            //
            // Listen to the port. This call is blocking, and cannot be interrupted,
            // even if the handle is closed. The only way how to stop the block is to send
            // an LPC request which will be recognized by server thread as "Stop" command
            //

            if(NT_SUCCESS(Status))
            {
                _tprintf(_T("Server: Listening to LPC port (NtListenPort) ...%s\n"), LpcPortName);
                Status = NtListenPort(LpcPortHandle,
                                     &LpcMessage->Header);
                _tprintf(_T("Server: NtListenPort result 0x%08lX\n"), Status);
            }

            //
            // Accept the port connection
            //

            if(NT_SUCCESS(Status))
            {
                _tprintf(_T("Server: Accepting LPC connection (NtAcceptConnectPort)%s ...\n"), LpcPortName);
                Status = NtAcceptConnectPort(&ServerHandle,
                                              NULL,
                                             &LpcMessage->Header,
                                              TRUE,
                                              NULL,
                                              NULL);
                _tprintf(_T("Server: NtAcceptConnectPort result 0x%08lX\n"), Status);
            }

            //
            // Complete the connection
            //

            if(NT_SUCCESS(Status))
            {
                _tprintf(_T("Server: Completing LPC connection (NtCompleteConnectPort) %s...\n"), LpcPortName);
                Status = NtCompleteConnectPort(ServerHandle);
                _tprintf(_T("Server: NtCompleteConnectPort result 0x%08lX\n"), Status);
            }

            //
            // Now accept the data request coming from the port.
            //

            if(NT_SUCCESS(Status))
            {
                _tprintf(_T("Server: Receiving LPC data (NtReplyWaitReceivePort)%s ...\n"), LpcPortName);
                Status = NtReplyWaitReceivePort(ServerHandle,
                                                NULL,
                                                NULL,
                                               &LpcMessage->Header);
                _tprintf(_T("Server: NtReplyWaitReceivePort result 0x%08lX\n"), Status);
            }

            //
            // Get the data sent by the client 
            //

            if(NT_SUCCESS(Status))
            {
                // If a request has been received, answer to it.
                switch(LpcMessage->Command)
                {
                    case LPC_COMMAND_REQUEST_NOREPLY:
                        _tprintf(_T("Server: Received request \"%s\"\n"), LpcMessage->MessageText);
                        break;      // Nothing more to do

                    case LPC_COMMAND_REQUEST_REPLY:
                        _tprintf(_T("Server: Received request \"%s\"\n"), LpcMessage->MessageText);
                        _tprintf(_T("Server: Sending reply (NtReplyPort) %s...\n"), LpcPortName);
                        Status = NtReplyPort(LpcPortHandle, &LpcMessage->Header);
                        _tprintf(_T("Server: NtReplyPort result 0x%08lX\n"), Status);
                        break;

                    case LPC_COMMAND_STOP:      // Stop the work
                        _tprintf(_T("Server: Stopping ...\n"));
                        WeHaveToStop = TRUE;
                        break;
                }
            }

            //
            // Close the server connection handle
            //

            if(ServerHandle != NULL)
            {
                _tprintf(_T("Server: Closing the request handle (NtClose) %s...\n"), LpcPortName);
                Status = NtClose(ServerHandle);
                _tprintf(_T("Server: NtClose result 0x%08lX\n"), Status);
            }

            _tprintf(_T("Server: ------------- End loop ---------------------- %x\n"), Status);
        }
    }

    __finally
    {
        if(LpcPortHandle != NULL)
            NtClose(LpcPortHandle);
    }
    
    return 0;
}

流程图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值