|
|
/*++
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; }
|