首页
社区
课程
招聘
[原创]提前拜年:浅谈内核LPC开发多向通讯+简单框架结构+私人送个简单的通讯协议
发表于: 2013-2-8 13:03 12763

[原创]提前拜年:浅谈内核LPC开发多向通讯+简单框架结构+私人送个简单的通讯协议

2013-2-8 13:03
12763
kd> dt e1320030 _LPCP_PORT_OBJECT
nt!_LPCP_PORT_OBJECT
   +0x000 ConnectionPort   : 0xe12ca458 _LPCP_PORT_OBJECT  ------> 由服务器调用NtCreatePort所创建的连接端口
   +0x004 ConnectedPort    : 0xe10f3388 _LPCP_PORT_OBJECT  ------> 已经建立连接后,对方通讯端口的对象
   +0x008 MsgQueue         : _LPCP_PORT_QUEUE              ------> 消息队列
   +0x018 Creator          : _CLIENT_ID
   +0x020 ClientSectionBase : (null) 
   +0x024 ServerSectionBase : (null) 
   +0x028 PortContext      : (null) 
   +0x02c ClientThread     : (null) 
   +0x030 SecurityQos      : _SECURITY_QUALITY_OF_SERVICE
   +0x03c StaticSecurity   : _SECURITY_CLIENT_CONTEXT
   +0x078 LpcReplyChainHead : _LIST_ENTRY [ 0xe13200a8 - 0xe13200a8 ]
   +0x080 LpcDataInfoChainHead : _LIST_ENTRY [ 0xe13200b0 - 0xe13200b0 ]
   +0x088 ServerProcess    : (null) 
   +0x088 MappingProcess   : (null) 
   +0x08c MaxMessageLength : 0x148
   +0x08e MaxConnectionInfoLength : 0
   +0x090 Flags            : 0x80000004
   +0x094 WaitEvent        : _KEVENT
    //
    // 对于创建得到的连接端口和客户端连接后得到的数据通讯端口,服务器调用
    // NtReplyWaitReceivePortEx始终在监听NtCreatePort得到的连接端口
    //
    if ((PortObject->Flags & PORT_TYPE) != CLIENT_COMMUNICATION_PORT) {
        if (PortObject->ConnectionPort == PortObject) {
            ConnectionPort = ReceivePort = PortObject;
            ObReferenceObject (ConnectionPort);
        } else {
            LpcpAcquireLpcpLockByThread(CurrentThread);
            ConnectionPort = ReceivePort = PortObject->ConnectionPort;
            if (ConnectionPort == NULL) {
                LpcpReleaseLpcpLock();
                ObDereferenceObject( PortObject );
                return STATUS_PORT_DISCONNECTED;
            }
            ObReferenceObject( ConnectionPort );
            LpcpReleaseLpcpLock();
        }
    //
    // 对于客户端来说,调用NtReplyWaitReceivePortEx监听的总是自己连接上服务器
    // 得到的通讯端口。所以在设计中,监听自身通讯端口,可以将发起权交给服务器
    //
    } else {
        ReceivePort = PortObject;
    }
    // ...............
    Status = KeWaitForSingleObject( ReceivePort->MsgQueue.Semaphore,
                                    WrLpcReceive,
                                    WaitMode,
                                    FALSE,
                                    Timeout );
		//
		// 对于客户端来说,调用NtRequestWaitReplyPort总是把请求消息插入到
		// NtCreatePort所创建的连接端口对象的消息队列中。。。
		//
    LpcpAcquireLpcpLockByThread(CurrentThread);
    Msg->PortContext = NULL;
    if ((PortObject->Flags & PORT_TYPE) != SERVER_CONNECTION_PORT) {
        QueuePort = PortObject->ConnectedPort;
        if (QueuePort == NULL) {
            LpcpFreeToPortZone( Msg, LPCP_MUTEX_OWNED | LPCP_MUTEX_RELEASE_ON_RETURN );
            ObDereferenceObject( PortObject );
            return STATUS_PORT_DISCONNECTED;
        }
        RundownPort = QueuePort;
        if ((PortObject->Flags & PORT_TYPE) == CLIENT_COMMUNICATION_PORT) {
            Msg->PortContext = QueuePort->PortContext;
            ConnectionPort = QueuePort = PortObject->ConnectionPort;
            if (ConnectionPort == NULL) {
                LpcpFreeToPortZone( Msg, LPCP_MUTEX_OWNED | LPCP_MUTEX_RELEASE_ON_RETURN );
                ObDereferenceObject( PortObject );
                return STATUS_PORT_DISCONNECTED;
            }
        } else if ((PortObject->Flags & PORT_TYPE) != SERVER_COMMUNICATION_PORT) {
            ConnectionPort = QueuePort = PortObject->ConnectionPort;
            if (ConnectionPort == NULL) {
                LpcpFreeToPortZone( Msg, LPCP_MUTEX_OWNED | LPCP_MUTEX_RELEASE_ON_RETURN );
                ObDereferenceObject( PortObject );
                return STATUS_PORT_DISCONNECTED;
            }
        }
        if (ConnectionPort) {
            ObReferenceObject( ConnectionPort );
        }
    //
    // 对于服务器来说,调用NtRequestWaitReplyPort就是将消息插入调用者指定的端口对象的
    // 消息队列。所以在设计中可以利用这个特点,自己给自己发请求来退出监控线程的。
    //
    } else {
        QueuePort = PortObject;
        RundownPort = PortObject;
    }
		// ............
		InsertTailList( &QueuePort->MsgQueue.ReceiveHead, &Msg->Entry );
    InsertTailList( &RundownPort->LpcReplyChainHead, &CurrentThread->LpcReplyChain );

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (7)
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
春节快乐!

顺便把你帖编辑了 一下,文中放图片建议用这个方法:
http://bbs.pediy.com/showpost.php?postid=292659
2013-2-8 14:05
0
雪    币: 216
活跃值: (144)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
3
呵呵,辛苦看雪老大啦。。太久没有在看雪发帖了,操作生疏啦。。。
2013-2-8 14:12
0
雪    币: 74
活跃值: (748)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
支持一下
2013-2-8 14:47
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
5
友情客串~~
2013-2-8 14:57
0
雪    币: 97697
活跃值: (200824)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
6
Thanks for share.
2013-2-9 00:25
0
雪    币: 1895
活跃值: (1657)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
好贴~~学习了。谢谢。
2013-2-9 10:23
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
國外的免費空間,壓力山大啊。。。
2013-2-9 16:06
0
游客
登录 | 注册 方可回帖
返回
//