//
//
对于客户端来说,调用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 );