Windows2003-3790/termsrv/rdpwsx/rdpex/tsrv.c
2020-09-30 16:53:55 +02:00

516 lines
13 KiB
C

//*************************************************************
//
// File name: TSrv.c
//
// Description: Contains routines to support remote
// terminals
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1991-1997
// All rights reserved
//
//*************************************************************
#include <regapi.h>
#include <TSrv.h>
#include <TSrvTerm.h>
#include <TSrvCom.h>
#include <TSrvInfo.h>
#include <TSrvVC.h>
#include <McsLib.h>
#include "stdio.h"
#include "_tsrvinfo.h"
#include <tlsapi.h>
// Data declarations
HINSTANCE g_hDllInstance = NULL; // DLL instance
HANDLE g_hMainThread = NULL; // Main work thread
HANDLE g_hReadyEvent = NULL; // Ready event
BOOL g_fShutdown = FALSE; // TSrvShare shutdown flag
HANDLE g_hIcaTrace; // system wide trace handle
HANDLE g_MainThreadExitEvent = NULL;
extern HANDLE g_hVCAddinChangeEvent;
extern HKEY g_hAddinRegKey; // handle to Addins reg subkey
#define CERTIFICATE_INSTALLATION_INTERVAL 900000
LICENSE_STATUS GetServerCertificate(CERT_TYPE CertType,
LPBYTE * ppbCertificate,
LPDWORD pcbCertificate );
//*************************************************************
//
// DllMain()
//
// Purpose: Dll entry point.
//
// Parameters: IN [hInstance] -- Dll hInstance.
// IN [dwReason] -- Call reason
// IN [lpReserved] -- Reserved.
//
// Return: TRUE if successful
// FALSE if not
//
// History: 07-17-97 BrianTa Created
//
//*************************************************************
BOOL WINAPI _CRT_INIT(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
BOOL
WINAPI
TShareDLLEntry(
IN HINSTANCE hInstance,
IN DWORD dwReason,
IN LPVOID lpReserved)
{
BOOL fSuccess;
// DbgBreakPoint();
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: DllMain entry\n"));
TRACE((DEBUG_TSHRSRV_DEBUG,
"TShrSRV: hInstance 0x%x, dwReason 0x%x\n",
hInstance, dwReason));
fSuccess = TRUE;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
if (!_CRT_INIT(hInstance, dwReason, lpReserved))
return(FALSE);
TRACE((DEBUG_TSHRSRV_NORMAL,
"TShrSRV: DLL attach\n"));
// Disable thread library calls and save off
// the DLL instance handle
DisableThreadLibraryCalls(hInstance);
g_hDllInstance = hInstance;
TSRNG_Initialize();
//
// init TShare util library.
//
if (TSUtilInit() != ERROR_SUCCESS)
{
fSuccess = FALSE;
break;
}
//
// invoke mcsmux library first.
//
if (!MCSDLLInit())
{
fSuccess = FALSE;
break;
}
//
// Invoke TShareSRV initialization
//
if (!TSRVStartup())
{
fSuccess = FALSE;
break;
}
//
// additional init routines go here.
//
break;
case DLL_PROCESS_DETACH:
TRACE((DEBUG_TSHRSRV_NORMAL,
"TShrSRV: DLL deattach\n"));
//
// Invoke TShareSRV shutdown
//
TSRVShutdown();
//
// invoke mcsmux cleanup routine.
//
MCSDllCleanup();
TSUtilCleanup();
TSRNG_Shutdown();
if (!_CRT_INIT(hInstance, dwReason, lpReserved))
return(FALSE);
break;
default:
TRACE((DEBUG_TSHRSRV_DEBUG,
"TShrSRV: Unknown reason code\n"));
break;
}
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: DllMain exit - 0x%x\n",
fSuccess));
return (fSuccess);
}
//*************************************************************
//
// TSRVStartup()
//
// Purpose: Performs startup processing.
//
// Parameters: void
//
// Return: TRUE if successful
// FALSE if not
//
// Notes: This routine is called by DLLMain to perform the
// most basic initialization
//
// History: 07-17-97 BrianTa Created
//
//*************************************************************
BOOL
TSRVStartup(void)
{
DWORD err;
LONG rc;
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSRVStartup entry\n"));
g_hMainThread = NULL;
g_MainThreadExitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
if( NULL == g_MainThreadExitEvent )
{
err = GetLastError();
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSRVStartup exit - 0x%x\n",
err));
return FALSE;
}
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TSRV_VC_KEY,
0,
KEY_READ,
&g_hAddinRegKey);
if (rc == ERROR_SUCCESS)
{
g_hVCAddinChangeEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
if( NULL == g_hVCAddinChangeEvent )
{
//
// This is not catastrophic, so we just trace and continue.
//
err = GetLastError();
TRACE((DEBUG_TSHRSRV_ERROR,
"TShrSRV: Failed to create VC Addin Change event - 0x%x\n",
err));
}
}
else
{
// This is not catastrophic either.
TRACE((DEBUG_TSHRSRV_ERROR,
"TShrSRV: Failed to open key %S, rc %d\n",
TSRV_VC_KEY, rc));
}
g_hReadyEvent = CreateEvent(NULL, // security attributes
FALSE, // manual-reset event
FALSE, // initial state
NULL); // event-object name
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSRVStartup exit - 0x%x\n",
g_hReadyEvent ? TRUE : FALSE));
return (g_hReadyEvent ? TRUE : FALSE);
}
//*************************************************************
//
// TSRVShutdown()
//
// Purpose: Performs shutdown processing.
//
// Parameters: void
//
// Return: void
//
// History: 07-17-97 BrianTa Created
//
//*************************************************************
void
TSRVShutdown(void)
{
DWORD dwWaitStatus;
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSRVShutdown entry\n"));
// Denote that we are no longer ready to service any
// new requests
TSrvReady(FALSE);
// If we were able to launch our main worker thread, then
// we may need to terminate conferences, etc.
if (g_hMainThread)
{
// Tell the system that we are terminating. This will cause
// TSrvMainThread to exit once it has finished servicing all
// outstanding posted work items.
TSrvTerminating(TRUE);
// Wait for TSrvMainThread to exit
TRACE((DEBUG_TSHRSRV_NORMAL,
"TShrSRV: Waiting for TSrvMainThread to exit\n"));
SetEvent( g_MainThreadExitEvent );
dwWaitStatus = WaitForSingleObject(g_hMainThread, 600000);
if( WAIT_OBJECT_0 != dwWaitStatus )
{
//
// The thread did not terminate within allowable time
//
TRACE((DEBUG_TSHRSRV_DEBUG,
"TShrSRV: TSrvMainThread refused to exit, killing\n"));
TerminateThread( g_hMainThread, 0 );
}
CloseHandle( g_hMainThread );
g_hMainThread = NULL;
CloseHandle( g_MainThreadExitEvent );
g_MainThreadExitEvent = NULL;
CloseHandle( g_hVCAddinChangeEvent );
g_hVCAddinChangeEvent = NULL;
if (g_hAddinRegKey)
{
RegCloseKey(g_hAddinRegKey);
g_hAddinRegKey = NULL;
}
// Get the VC code to free its stuff
TSrvTermVC();
TLSShutdown();
}
else
{
TSrvTerminating(TRUE);
}
// Inform GCC we no longer want to be a Node Controller
TSrvUnregisterNC();
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSRVShutdown exit\n"));
}
//*************************************************************
//
// TSrvMainThread()
//
// Purpose: Main worker thread for TShareSRV.
//
// Parameters: void
//
// Return: 0
//
// Notes: This thread is spawned by DLLMain. It performs
// the vast majority of TShareSRV initialization
// and then waits for work items to be posted to it.
//
// History: 07-17-97 BrianTa Created
//
//*************************************************************
DWORD
WINAPI
TSrvMainThread(LPVOID pvContext)
{
LPBYTE pX509Cert;
DWORD dwX509CertLen;
DWORD dwWaitStatus;
LICENSE_STATUS Status;
LARGE_INTEGER DueTime = {0,0};
HANDLE rghWait[4] = {0};
DWORD dwCount = 0;
DWORD dwWaitExit = 0xFFFFFFFF;
DWORD dwWaitVCAddin = 0xFFFFFFFF;
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSrvMainThread entry\n"));
if (TSrvInitialize())
{
TSrvReady(TRUE);
TRACE((DEBUG_TSHRSRV_NORMAL,
"TShrSRV: Entering TSrvMainThread worker loop\n"));
if (g_MainThreadExitEvent)
{
dwWaitExit = WAIT_OBJECT_0 + dwCount;
rghWait[dwCount] = g_MainThreadExitEvent;
dwCount++;
TRACE((DEBUG_TSHRSRV_DEBUG, "TShrSRV: Added exit event\n"));
}
if (g_hVCAddinChangeEvent)
{
//
// The addin change notification was set up earlier, when we read
// the addins information from the registry.
//
dwWaitVCAddin = WAIT_OBJECT_0 + dwCount;
rghWait[dwCount] = g_hVCAddinChangeEvent;
dwCount++;
}
while (1)
{
dwWaitStatus = WaitForMultipleObjects(dwCount,
rghWait,
FALSE,
INFINITE);
if( dwWaitExit == dwWaitStatus )
{
//
// time to exit the thread
//
TRACE((DEBUG_TSHRSRV_NORMAL,
"TShrSRV: TSrvMainThread got EXIT event\n"));
break;
}
else if (dwWaitVCAddin == dwWaitStatus)
{
//
// The Virtual Channel Addins registry key has changed.
// We need to kick off a refresh of our data.
//
TRACE((DEBUG_TSHRSRV_WARN,
"TShrSRV: TSrvMainThread got VC ADDINS CHANGED event\n"));
TSrvGotAddinChangedEvent();
}
else
{
TS_ASSERT(dwWaitStatus == WAIT_FAILED);
TRACE((DEBUG_TSHRSRV_DEBUG,
"TShrSRV: Wait failed, so we'll just exit\n"));
//
// Wait failed, just bail
//
break;
}
}
TSrvReady(FALSE);
}
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSrvMainThread exit - 0x%x\n",
0));
return (0);
}
//*************************************************************
//
// TSrvInitialize()
//
// Purpose: Main routine for TSrvShare initialization
//
// Parameters: void
//
// Return: TRUE if successful
// FALSE if not
//
// History: 07-17-97 BrianTa Created
//
//*************************************************************
BOOL
TSrvInitialize(void)
{
BOOL fSuccess;
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSrvInitialize entry\n"));
fSuccess = FALSE;
// Initialize TSrvInfo data structs
if (TSrvInitGlobalData())
{
if (TSrvInitVC())
{
// Register TShareSRV as GCC node controller
if (TSrvRegisterNC())
{
if (ERROR_SUCCESS == TLSInit())
{
fSuccess = TRUE;
}
}
}
}
TRACE((DEBUG_TSHRSRV_FLOW,
"TShrSRV: TSrvInitialize exit - 0x%x\n", fSuccess));
return (fSuccess);
}