windows-nt/Source/XPSP1/NT/base/subsys/posix/psxss/conthrds.c
2020-09-26 16:20:57 +08:00

202 lines
5.4 KiB
C

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
conthrds.c
Abstract:
This module contains the Server Listen&Request threads
procedures for the Console Session.
Author:
Avi Nathan (avin) 17-Jul-1991
Revision History:
Ellen Aycock-Wright (ellena) 15-Sept-1991 Modified for POSIX
--*/
#include <stdio.h>
#include "psxsrv.h"
#define NTPSX_ONLY
#include "sesport.h"
NTSTATUS
PsxSessionHandleConnectionRequest(
IN PPSXSESREQUESTMSG Message
)
{
NTSTATUS Status;
PPSXSESCONNECTINFO ConnectionInfoIn = &Message->ConnectionRequest;
SCCONNECTINFO ConnectionInfoOut;
ULONG ConnectionInfoOutLength;
STRING SessionPortName;
UNICODE_STRING SessionPortName_U;
SECURITY_QUALITY_OF_SERVICE DynamicQos;
CHAR SessionName[PSX_SES_BASE_PORT_NAME_LENGTH];
HANDLE SessionPort;
HANDLE PsxSessionCommPort;
int Id;
ConnectionInfoOutLength = sizeof(ConnectionInfoOut);
Id = ConnectionInfoIn->In.SessionUniqueId;
PSX_GET_SESSION_PORT_NAME(SessionName, Id);
RtlInitAnsiString(&SessionPortName, SessionName);
Status = RtlAnsiStringToUnicodeString(&SessionPortName_U,
&SessionPortName, TRUE);
if (!NT_SUCCESS(Status)) {
return Status;
}
DynamicQos.ImpersonationLevel = SecurityImpersonation;
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
DynamicQos.EffectiveOnly = TRUE;
//
// Get the session communication port handle. This handle will
// be used to send session requests to psxses.exe for this
// session.
//
Status = NtConnectPort(&SessionPort, &SessionPortName_U,
&DynamicQos, NULL, NULL, NULL,
(PVOID)&ConnectionInfoOut, &ConnectionInfoOutLength);
RtlFreeUnicodeString(&SessionPortName_U);
if (!NT_SUCCESS(Status)) {
NTSTATUS st2;
// Reject
st2 = NtAcceptConnectPort(&PsxSessionCommPort, NULL,
(PPORT_MESSAGE)Message, FALSE, NULL, NULL);
if (NT_SUCCESS(st2)) {
NtClose(PsxSessionCommPort);
}
return Status;
}
// Accept the connection
ConnectionInfoIn->Out.SessionPortHandle = SessionPort;
//
// PsxSessionCommPort is not used for Reply. Instead,
// the port is created with ReceiveAny==TRUE and we wait
// on the connection port.
//
Status = NtAcceptConnectPort(&PsxSessionCommPort, NULL,
(PPORT_MESSAGE)Message, TRUE, NULL, NULL);
ASSERT(NT_SUCCESS(Status));
//
// Add an entry to the ConnectingSessions list, saying
// that the session exists but has not yet asked to have
// a process created to be the session leader.
//
Status = AddConnectingTerminal(Id, PsxSessionCommPort, SessionPort);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = NtCompleteConnectPort(PsxSessionCommPort);
ASSERT(NT_SUCCESS(Status));
return Status;
}
// for debug
int DbgBadRQ;
NTSTATUS
PsxSessionRequestThread(
PVOID Parameter
)
{
NTSTATUS Status;
PSXSESREQUESTMSG ReceiveMsg, *pReplyMsg;
int MessageType;
pReplyMsg = NULL;
for (;;) {
Status = NtReplyWaitReceivePort(PsxSessionPort, NULL,
(PPORT_MESSAGE)pReplyMsg, (PPORT_MESSAGE)&ReceiveMsg);
if (!NT_SUCCESS(Status)) {
KdPrint(("PSXSS: NtReplyWaitReceivePort: 0x%x\n",
Status));
if (STATUS_INVALID_HANDLE == Status ||
STATUS_OBJECT_TYPE_MISMATCH == Status) {
DbgBadRQ = ReceiveMsg.Request;
KdPrint(("PSXSS: SessionRequestThread exits, "
"rq was %d.\n", ReceiveMsg.Request));
break;
}
pReplyMsg = NULL;
continue;
}
MessageType = ReceiveMsg.h.u2.s2.Type;
if (MessageType == LPC_CONNECTION_REQUEST) {
PsxSessionHandleConnectionRequest( &ReceiveMsg );
pReplyMsg = NULL;
continue;
}
if (MessageType == LPC_CLIENT_DIED ||
MessageType == LPC_PORT_CLOSED
) {
pReplyMsg = NULL;
continue;
}
if (MessageType == LPC_DEBUG_EVENT ||
MessageType == LPC_ERROR_EVENT ||
MessageType == LPC_EXCEPTION
) {
pReplyMsg = NULL;
continue;
}
if (MessageType != LPC_REQUEST) {
KdPrint(("PSXSS: SesRqThread got type %d\n",
MessageType));
pReplyMsg = NULL;
continue;
} else {
switch (ReceiveMsg.Request) {
case SesConCreate:
Status = PsxCreateConSession(&ReceiveMsg);
break;
case SesConSignal:
Status = PsxCtrlSignalHandler(&ReceiveMsg);
break;
default:
Status = 0;
KdPrint(("PSXSS: Unknown Session request: %d\n",
ReceiveMsg.Request));
}
pReplyMsg = &ReceiveMsg;
pReplyMsg->Status = Status;
}
}
return Status;
}