Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

400 lines
12 KiB

/*++
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:
--*/
#include "os2srv.h"
#define NTOS2_ONLY
#include "sesport.h"
#include "os2win.h"
extern OS2_SES_GROUP_PARMS ServerSesGrp;
VOID
Os2SessionHandleConnectionRequest(
POS2SESREQUESTMSG Message
)
{
NTSTATUS Status;
HANDLE Os2SessionCommPortHandle;
APIRET Rc;
POS2_THREAD Thread;
POS2_SESSION Session;
POS2_PROCESS Process;
BOOLEAN AcceptConnection;
POS2SESCONNECTINFO ConnectionInfoIn = &Message->ConnectionRequest;
REMOTE_PORT_VIEW ClientView;
HANDLE TmpWin32ForegroundWindow;
//
// sync with other server threads
//
Os2AcquireStructureLock();
TmpWin32ForegroundWindow = ConnectionInfoIn->In.Win32ForegroundWindow;
if (ConnectionInfoIn->In.ExpectedVersion > OS2_SS_VERSION)
{
KdPrint(( "OS2SRV: Os2SessionHandleConnectionRequest received old version (%u intead of %u)\n",
ConnectionInfoIn->In.ExpectedVersion, OS2_SS_VERSION));
AcceptConnection = FALSE;
} else
{
AcceptConnection = TRUE;
#if DBG
if (ConnectionInfoIn->In.SessionDbg)
{
Os2Debug |= OS2_DEBUG_BRK;
KdPrint(( "OS2SRV: Breakpoint caused by OS2 /B\n" ));
DbgBreakPoint();
} else
{
Os2Debug &= ~(OS2_DEBUG_BRK);
}
#endif // DBG
ConnectionInfoIn->Out.CurrentVersion = OS2_SS_VERSION;
}
if ( !AcceptConnection )
{
// Reject
failConnect:
Status = NtAcceptConnectPort(
&Os2SessionCommPortHandle,
NULL,
(PPORT_MESSAGE)Message,
(BOOLEAN)FALSE,
NULL,
NULL
);
} else
{
//
// See if this Unique Id already exist (execed by DosExecPgm)
// if not, create a new session and give it as a port handle
//
Thread = Os2LocateThreadByClientId( NULL, &Message->h.ClientId );
if (Thread == NULL)
{
//
// new session
//
Session = Os2AllocateSession(NULL, 0L, &Rc);
ConnectionInfoIn->Out.SessionUniqueID = (ULONG)Session;
if (Session == NULL)
{
KdPrint(( "OS2SRV: Os2SessionHandleConnectionRequest fails to allocate session\n"));
goto failConnect;
}
ConnectionInfoIn->Out.IsNewSession = OS2SS_NEW_SESSION;
if ((Process = Os2AllocateProcess()) == NULL)
{
// free the session
KdPrint(( "OS2SRV: Os2SessionHandleConnectionRequest fails to allocate process\n"));
goto failConnect;
}
Session->Process = Process;
ConnectionInfoIn->Out.ProcessUniqueID = (ULONG)Process;
} else
{
/*
* a child session
*/
if ((Process = Thread->Process) == NULL)
{
// free the session
KdPrint(( "OS2SRV: Os2SessionHandleConnectionRequest fails to find process for child session\n"));
goto failConnect;
}
Session = Process->Session;
if (Session == NULL)
{
KdPrint(( "OS2SRV: Os2SessionHandleConnectionRequestfails to find child session\n"));
goto failConnect;
}
//
// This process was execed by os/2, use process handle as uniqueid
//
ConnectionInfoIn->Out.SessionUniqueID = (ULONG)Session;
ConnectionInfoIn->Out.ProcessUniqueID = (ULONG)Process;
//
// indicate to os2.exe that this is not a new session
//
if( Session->Process == NULL )
{
/*
* a child session
*/
ASSERT(Session->ReferenceCount == 1);
Session->Process = Process;
ConnectionInfoIn->Out.IsNewSession = OS2SS_CHILD_SESSION;
} else
{
/*
* a child process
*/
//
// indicate to os2.exe that this is not a new session
//
ConnectionInfoIn->Out.IsNewSession = OS2SS_CHILD_PROCESS;
}
}
Session->Win32ForegroundWindow = TmpWin32ForegroundWindow;
ConnectionInfoIn->Out.Os2SrvId = GetCurrentProcessId();
ConnectionInfoIn->Out.Od2Debug = 0;
#if DBG
ConnectionInfoIn->Out.Od2Debug = Os2Debug;
#endif
/*
* Os2SessionCommPortHandle is not used for Reply. Instead,
* the port is created with ReceiveAny==TRUE and we wait
* on the connection port.
*/
ClientView.Length = sizeof( ClientView );
ClientView.ViewSize = 0;
ClientView.ViewBase = 0;
Status = NtAcceptConnectPort(
& Os2SessionCommPortHandle,
(PVOID)Process,
(PPORT_MESSAGE)Message,
(BOOLEAN)TRUE,
NULL,
&ClientView
);
#if DBG
IF_OS2_DEBUG( LPC )
{
KdPrint(( "OS2SRV: listen - ClientView: Base=%lx, Size=%lx, PortHandle %lx\n",
ClientView.ViewBase, ClientView.ViewSize, Os2SessionCommPortHandle));
}
#endif
Process->ClientPort = Os2SessionCommPortHandle;
Process->ClientViewBase = (PCH)ClientView.ViewBase;
Process->ClientViewBounds = (PCH)ClientView.ViewBase + ClientView.ViewSize;
if ( !NT_SUCCESS(Status) )
{
// free the session
Os2DereferenceSession((POS2_SESSION)ConnectionInfoIn->Out.SessionUniqueID, NULL, (BOOLEAN)TRUE);
if ((Thread != NULL) && (Thread->Process->Session->ReferenceCount != 1))
{
// BUGBUG: free the process
}
} else
{
Status = NtCompleteConnectPort( Os2SessionCommPortHandle );
ASSERT( NT_SUCCESS( Status) );
}
}
Os2ReleaseStructureLock();
}
NTSTATUS
CheckOs2Port(POS2SESREQUESTMSG pReceiveMsg)
{
NTSTATUS Status;
SCCONNECTINFO ConnectionInfoOut;
ULONG ConnectionInfoOutLength, i;
UNICODE_STRING SessionPortName_U;
SECURITY_QUALITY_OF_SERVICE DynamicQos;
WCHAR SessionName_U[U_OS2_SES_BASE_PORT_NAME_LENGTH];
POS2_SES_GROUP_PARMS SesGrp;
HANDLE SectionHandle;
ULONG ViewSize;
OBJECT_ATTRIBUTES ObjectAttributes;
POS2_SESSION Session = (POS2_SESSION)(pReceiveMsg->Session);
HANDLE SessionPortHandle;
//
// Connect to the OS2SES port, then call it with
// the ommunication to be used during the session
// to call os2ses
//
ConnectionInfoOutLength = sizeof( ConnectionInfoOut );
CONSTRUCT_U_OS2_SES_NAME(SessionName_U, U_OS2_SES_BASE_PORT_PREFIX, (ULONG)(pReceiveMsg->Session));
RtlInitUnicodeString( &SessionPortName_U, SessionName_U );
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 os2ses.exe for this session.
//
Status = NtConnectPort( &SessionPortHandle,
&SessionPortName_U,
&DynamicQos,
NULL,
NULL,
NULL,
(PVOID) &ConnectionInfoOut,
& ConnectionInfoOutLength
);
if (!NT_SUCCESS( Status ))
{
#if DBG
KdPrint(( "OS2SS: Unable to connect to OS2 - Status == %X\n",
Status
));
#endif
Os2DereferenceSession(Session, NULL, (BOOLEAN)TRUE);
return(Status);
}
//
// A new session - save handles to process and thread
//
Session->ConsolePort = SessionPortHandle;
SessionPortName_U.Buffer[sizeof(U_OS2_SES_BASE_PORT_NAME) / 2] = U_OS2_SES_GROUP_PREFIX;
InitializeObjectAttributes( &ObjectAttributes,
&SessionPortName_U,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenSection ( &SectionHandle,
SECTION_MAP_WRITE,
&ObjectAttributes);
if ( !NT_SUCCESS( Status ) )
{
#if DBG
KdPrint(( "OS2SRV: Os2CheckPort can't open SesGrp section - Status == %X\n",
Status));
#endif
Os2DereferenceSession(Session, NULL, (BOOLEAN)TRUE);
return(Status);
}
/*
* Let MM locate the view
*/
SesGrp = (POS2_SES_GROUP_PARMS)NULL;
ViewSize = 0L;
Status = NtMapViewOfSection( SectionHandle,
NtCurrentProcess(),
(PVOID *)&SesGrp,
0L,
0L,
NULL,
&ViewSize,
ViewUnmap,
0L,
PAGE_READWRITE);
if ( !NT_SUCCESS( Status ) )
{
#if DBG
KdPrint(( "OS2SRV: Os2CheckPort can't map view of SesGrp section - Status == %X\n",
Status));
#endif
Os2DereferenceSession(Session, NULL, (BOOLEAN)TRUE);
NtClose (SectionHandle);
return(Status);
}
/*
* copy data to session
*/
for ( i = 0 ; i < sizeof(OS2_SES_GROUP_PARMS) ; i++ )
{
if (((PUCHAR)&ServerSesGrp)[i])
{
((PUCHAR)SesGrp)[i] = ((PUCHAR)&ServerSesGrp)[i];
}
}
Session->SesGrpAddress = (PVOID)SesGrp;
Session->SesGrpHandle = SectionHandle;
return(Status);
}
VOID
HandleOs2ConRequest(IN PVOID pApiReceiveMsg,
OUT PVOID *PReplyMsg
)
{
POS2SESREQUESTMSG pReceiveMsg = pApiReceiveMsg;
NTSTATUS Status = STATUS_SUCCESS;
*PReplyMsg = pApiReceiveMsg;
switch ( pReceiveMsg->Request)
{
case SesCheckPortAndConCreate:
//
// Connect to the OS2SES port, then call it with
// the ommunication to be used during the session
// to call os2ses
//
Status = CheckOs2Port(pReceiveMsg);
if ( !NT_SUCCESS( Status ) )
{
break;
}
case SesConCreate:
Status = Os2CreateConSession(
pReceiveMsg
);
break;
case SesConSignal:
Status = Os2CtrlSignalHandler(
pReceiveMsg,
NULL);
break;
case SesConFocus:
Status = Os2SessionFocusSet(
pReceiveMsg);
break;
default:
Status = 0;
#if DBG
KdPrint(( "OS2SS: Unknown Session request = %X\n",
pReceiveMsg->Request));
#endif
}
pReceiveMsg->Status = Status;
return;
}