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.
515 lines
13 KiB
515 lines
13 KiB
//*************************************************************
|
|
//
|
|
// 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);
|
|
}
|
|
|