windows-nt/Source/XPSP1/NT/net/tcpip/services/telnet/admin/tnadmutl.cpp
2020-09-26 16:20:57 +08:00

2196 lines
75 KiB
C++

//-------------------------------------------------------------------
// Copyright (c) 1999-2000 Microsoft Corporation
//
// tnadminutils.cpp
//
// Vikram/Manoj Jain/Srivatsan K/Harendra
//
// Functions to do administration of telnet daemon.
// (May-2000)
//-------------------------------------------------------------------
#include "telnet.h"
#include "common.h"
#include "resource.h" //resource.h should be before any other .h file that has resource ids.
#include "admutils.h"
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <shlwapi.h>
#include <wbemidl.h>
#include <wchar.h>
#include <windns.h>
#include <winnlsp.h>
#include "tnadminy.h"
//this file has utility functions to set authentication...
#include "tlntsvr.h"
#define L_TELNETSERVER_TEXT "tlntsvr"
#define MAX_VALUE_MAXCONN 2147483647
//Global variables
wchar_t* g_arCLASSname[ _MAX_CLASS_NAMES_ ];
//array to store the different class object paths
HKEY g_arCLASShkey[_MAX_CLASS_NAMES_];
HKEY g_hkeyHKLM=NULL;
int g_arNUM_PROPNAME[_MAX_PROPS_];
WCHAR g_szMsg[MAX_BUFFER_SIZE] = {0} ;
HMODULE g_hResource;
HANDLE g_stdout;
extern HMODULE g_hXPResource;
BOOL g_fWhistler = FALSE;
// Don't even think about changing the two strings -- BaskarK, they NEED to be in sync with tlntsvr\enclisvr.cpp
// the separators used to identify various portions of a session as well as session begin/end
WCHAR *session_separator = L",";
WCHAR *session_data_separator = L"\\";
extern BSTR bstrLogin;
extern BSTR bstrPasswd;
extern BSTR bstrNameSpc;
extern SERVICE_STATUS g_hServiceStatus;
//wchar_t *g_szCName=NULL; (See the comment in the PrintSettings() function
//all three files extern
#ifdef __cplusplus
extern "C" {
#endif
extern long int g_nConfigOptions;
extern int g_nError; //Error indicator, initialsed to no error.:-)
extern wchar_t* g_arVALOF[_MAX_PROPS_];
extern int g_nPrimaryOption;
//option indicator.
extern int g_nTimeoutFlag; //o means in hh:mm:ss 1 means ss format.
extern int g_nSesid;
extern BSTR g_bstrMessage;
extern ConfigProperty g_arPROP[_MAX_PROPS_][_MAX_NUMOF_PROPNAMES_];
extern int g_nAuditOff;
extern int g_nAuditOn;
extern int g_nSecOff;
extern int g_nSecOn;
#ifdef __cplusplus
}
#endif
IManageTelnetSessions* g_pIManageTelnetSessions = NULL;
// Pointer to the Session Manager Interface;-)
int g_nNumofSessions=0;
wchar_t** g_ppwzSessionInfo=NULL;
//will be allocated in ListUsers.An array of session infosize=g_nNumofSessions.
// The following function is a replica of SafeCoInitialize() from Commfunc library
// Please check with the header of function there.
// Why a local copy? We are not checking in the comm func library sources
// for Whistler - hence we can not link to that library for telnet.
HRESULT Telnet_SafeCoInitializeEx()
{
HRESULT hCoIni = S_OK;
// Initialize the COM library on this thread.
hCoIni = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if(S_OK!=hCoIni)
{
if (S_FALSE == hCoIni)
{
// The COM library is already initialized on this thread
// This is not an error as we already have what
// we are asking for.
// But this code should never get executed - Safe programming
}
else
return hCoIni;
}
return S_OK;
}
// The following two functions are copied from commfunc.cpp. Any change made in
// these functions in commfunc.cpp should be copied here.
// This function calls LoadLibrary() after framing the complete path of the dll.
// Arguments:
// wzEnvVar [IN] : Environment Variable which needs to be expanded.
// wzSubDir [IN] : Sub directory under which the dll is located. This will
// concatenated to the expanded env var. This field can
// be null. You should not specify "\" here.
// wzDllName [IN] : Name of the DLL to be loaded in widechars
// pdwRetVal [OUT]: Pointer to a DWord to hold the return value.
//
// Return Value:
// On success returns handle to the library.
// On failure returns NULL;
// Notes: Please check the pdwRetVal parameter incase this function returns NULL
//
// Possible values for dwRetVal:
//
// =============================================================
// | ERROR_SUCCESS Successful loading of library. |
// | ERROR_INSUFFICIENT_BUFFER If the buffer is not sufficient to hold the |
// | dll name. |
// | ERROR_ENVVAR_NOT_FOUND If the environment variable is not found. |
// | ERROR_INVALID_DATA If the environment variable is absent. |
// | GetLastError() If LoadLibrary() fails. |
// =============================================================
//
HMODULE TnSafeLoadLibraryViaEnvVarW(WCHAR *wzEnvVar, WCHAR* wzSubDir, WCHAR *wzDllName, DWORD* pdwRetVal)
{
HMODULE hLibrary = NULL;
WCHAR wzDllPath[3*MAX_PATH+1] = {0};
DWORD dwNoOfCharsUsed = 0;
// Validate the input.
if (NULL == pdwRetVal)
goto Abort;
if( (NULL == wzEnvVar) || (0==wcscmp(wzEnvVar,L"")) || (NULL == wzDllName) || (0==wcscmp(wzDllName,L"")))
{
*pdwRetVal=ERROR_INVALID_DATA;
goto Abort;
}
*pdwRetVal = ERROR_SUCCESS;
dwNoOfCharsUsed=GetEnvironmentVariableW(wzEnvVar, wzDllPath, ARRAYSIZE(wzDllPath)-1);
if(0!=dwNoOfCharsUsed)
{
// Add the last '\' if absent
if(wzDllPath[dwNoOfCharsUsed-1]!=L'\\')
{
wzDllPath[dwNoOfCharsUsed]=L'\\';
dwNoOfCharsUsed++;
// Check for buffer overflow.
if(dwNoOfCharsUsed > ARRAYSIZE(wzDllPath)-1)
{
*pdwRetVal = ERROR_INSUFFICIENT_BUFFER;
goto Abort;
}
}
// If SubDir is present, frame the path as %EnvVar%SubDir\DllName
// else %EnvVar%DllName
if(NULL!=wzSubDir)
{
if(_snwprintf(wzDllPath+dwNoOfCharsUsed,
ARRAYSIZE(wzDllPath)-dwNoOfCharsUsed-1,
L"%s\\%s",
wzSubDir,
wzDllName) < 0)
{
// _snwprintf failed
*pdwRetVal = ERROR_INSUFFICIENT_BUFFER;
goto Abort;
}
}
else
{
wcsncpy(wzDllPath+dwNoOfCharsUsed, wzDllName, ARRAYSIZE(wzDllPath)-dwNoOfCharsUsed-1);
}
// ensuring null termination
wzDllPath[ARRAYSIZE(wzDllPath)-1]=L'\0';
}
else
{
// The system could not find the environment variable.
*pdwRetVal = ERROR_ENVVAR_NOT_FOUND;
goto Abort;
}
// Load the library
hLibrary = LoadLibraryExW(wzDllPath,NULL,LOAD_LIBRARY_AS_DATAFILE);
if(NULL == hLibrary)
*pdwRetVal = GetLastError();
Abort:
return hLibrary;
}
// This function calls ZeroMemory() and makes sure that this call is not optimized
// out by the compiler.
// Arguments:
// Destination [IN] : Pointer to the starting address of the block of memory
// to fill with zeros
// cbLength [IN] : Size, in bytes, of the block of memory to fill with zeros.
// Return Value:
// void function.
// Author: srivatsk
void TnSfuZeroMemory(PVOID Destination, SIZE_T cbLength)
{
ZeroMemory(Destination, cbLength);
*(volatile char*)Destination; // this is dummy statement to prevent optimization
// Why *(volatile char*)Destination? To make sure that the compiler doesn't optimize
// away the ZeroMemory() call thinking that we are not going
// to access this memory anymore :)
return;
}
// The following two functions are copied from allutils.cpp. Any change made in
// these functions in allutils.cpp should be copied here.
// This function loads the resource dll "Cladmin.dll" from %SFUDIR%\common
// and stores the handle in global variable g_hResource.
// Add code here to take care of loading resources for non-english locales.
// This function has been changed to load XPSP1RES.DLL in case it is present.
// This is only tlntadmn.exe specific change and should not be copied back to
// allutils.cpp. If present, XPSP1RES.DLL will be present in %SystemRoot%\System32
DWORD TnLoadResourceDll()
{
//Load the Strings library "cladmin.dll".
// if not found, it should get the English resources from the exe.
DWORD dwRetVal = ERROR_SUCCESS;
OSVERSIONINFOEX osvi = { 0 };
g_hXPResource = NULL;
// No need to check for the dwRetVal field of SafeLoadSystemLibrary; As incase of
// failure, we will default to English resources from the exe.
// We need to add check here while taking care of non-english locales.
if (NULL == g_hResource)
{
g_hResource = GetModuleHandle(NULL);
}
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if ( !GetVersionEx((OSVERSIONINFO *) &osvi ) )
{
//OSVERSIONINFOEX is supported from NT4 SP6 on. So GetVerEx() should succeed.
goto Done;
}
//Load XPSPxRes.dll only if OS is XP and Service pack is x where 'x' is service pack number
//e.g. 1 in case of XPSP1
if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.wProductType == VER_NT_WORKSTATION && osvi.wServicePackMajor > 0)
{
//OS is Windows XP.
g_hXPResource = LoadLibraryExW(L"xpsp1res.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
}
//no need to see if the the LoadLibrary failed. It will succeed only on XPSP1 in which case,
//some resources may need to be loaded from the dll.
Done:
return ERROR_SUCCESS;
}
// This function is used to clear the passwd and should be called once you no
// longer require the passwd field. This function also frees the memory and makes
// it null so that nobody else call make use of it in the future.
// Zeroing the memory is done by calling SfuZeroMemory() which makes sure
// that ZeroMemory() call is not optimized away by the compiler.
void TnClearPasswd()
{
if(g_arVALOF[_p_PASSWD_])
{
TnSfuZeroMemory(g_arVALOF[_p_PASSWD_], wcslen(g_arVALOF[_p_PASSWD_])*sizeof(WCHAR));
free(g_arVALOF[_p_PASSWD_]);
g_arVALOF[_p_PASSWD_]=NULL;
}
}
/* --
int Initialize(void) function initialises the class-object-paths,
and also property class dependency.
Then gets a handle to WbemLocator,
Connects to the server and gets a handle to WbemServices
with proper authentication.
Note that: if the passed in namespace is null then, it defaults to
"root\\sfuadmin"
--*/
int Initialize(void)
{
int i;
for(i=0;i<_MAX_CLASS_NAMES_;i++)
{
g_arCLASShkey[i]=NULL;
g_arCLASSname[i]=NULL;
}
int j;
for(i=0;i<_MAX_PROPS_;i++)
{ for(j=0;j<_MAX_NUMOF_PROPNAMES_;j++)
{
g_arPROP[i][j].fDontput=0;
g_arPROP[i][j].propname=NULL;
}
g_arVALOF[i]=NULL;
g_arNUM_PROPNAME[i]=0;
}
//Load the Strings library "cladmin.dll".
// if not found, it should get the English resources from the exe.
DWORD dwRetVal = TnLoadResourceDll();
if(ERROR_SUCCESS!=dwRetVal)
{
return dwRetVal;
}
HRESULT hCoIni = Telnet_SafeCoInitializeEx();
if (S_OK!=hCoIni)
// Oops! This function can not return hResult :( and so returning -1 to indicate
// error. but unfortunately none of the callers are using the return value of this
// function.
return -1;
g_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
// Set the flag so that we call CoUnint...()
g_fCoInitSuccess = TRUE;
//Default values can be set over here.
g_nConfigOptions=0;
//Defining the class object paths for tnadmin....
g_arCLASSname[0]=L"SOFTWARE\\Microsoft\\TelnetServer\\1.0";
g_arCLASSname[1]=L"SOFTWARE\\Microsoft\\TelnetServer\\1.0\\ReadConfig";
g_arCLASSname[2]=L"SOFTWARE\\Microsoft\\Services For Unix\\AppsInstalled\\Telnet Server";
//Assigning different properties to their respective classes...
g_arPROP[_p_CTRLAKEYMAP_][0].classname=0;
g_arPROP[_p_TIMEOUT_][0].classname=0;
g_arPROP[_p_MAXCONN_][0].classname=0;
g_arPROP[_p_PORT_][0].classname=0;
g_arPROP[_p_MAXFAIL_][0].classname=0;
g_arPROP[_p_KILLALL_][0].classname=0;
g_arPROP[_p_MODE_][0].classname=0;
g_arPROP[_p_AUDITLOCATION_][0].classname=0;
g_arPROP[_p_SEC_][0].classname=0;
g_arPROP[_p_DOM_][0].classname=0;
g_arPROP[_p_AUDIT_][0].classname=0;
g_arPROP[_p_TIMEOUTACTIVE_][0].classname=0;
g_arPROP[_p_FNAME_][0].classname=0;
g_arPROP[_p_FSIZE_][0].classname=0;
g_arPROP[_p_DEFAULTS_][0].classname=1;
g_arPROP[_p_INSTALLPATH_][0].classname=2;
//these two come from Active X, so will take care separately..
//CLASSOF_AR[_p_SESSID_]=;
//CLASSOF_AR[_p_STATE_]=;
//giving properties number of names they are actually associated with....
g_arNUM_PROPNAME[_p_CTRLAKEYMAP_]=1;
g_arNUM_PROPNAME[_p_TIMEOUT_]=2;
g_arNUM_PROPNAME[_p_MAXCONN_]=1;
g_arNUM_PROPNAME[_p_PORT_]=1;
g_arNUM_PROPNAME[_p_MAXFAIL_]=1;
g_arNUM_PROPNAME[_p_KILLALL_]=1;
g_arNUM_PROPNAME[_p_MODE_]=1;
g_arNUM_PROPNAME[_p_AUDITLOCATION_]=2;
g_arNUM_PROPNAME[_p_SEC_]=1;
g_arNUM_PROPNAME[_p_DOM_]=1;
g_arNUM_PROPNAME[_p_AUDIT_]=3;
g_arNUM_PROPNAME[_p_TIMEOUTACTIVE_]=2;
g_arNUM_PROPNAME[_p_FNAME_]=1;
g_arNUM_PROPNAME[_p_FSIZE_]=1;
g_arNUM_PROPNAME[_p_DEFAULTS_]=1;
g_arNUM_PROPNAME[_p_INSTALLPATH_]=1;//not used
//giving properties their actual property_names as in the registry....
g_arPROP[_p_CTRLAKEYMAP_][0].propname=L"AltKeyMapping";
g_arPROP[_p_TIMEOUT_][0].propname=L"IdleSessionTimeout";
g_arPROP[_p_TIMEOUT_][1].propname=L"IdleSessionTimeoutBkup";
g_arPROP[_p_MAXCONN_][0].propname=L"MaxConnections";
g_arPROP[_p_PORT_][0].propname=L"TelnetPort";
g_arPROP[_p_MAXFAIL_][0].propname=L"MaxFailedLogins";
g_arPROP[_p_KILLALL_][0].propname=L"DisconnectKillAllApps";
g_arPROP[_p_MODE_][0].propname=L"ModeOfOperation";
g_arPROP[_p_AUDITLOCATION_][0].propname=L"EventLoggingEnabled";
g_arPROP[_p_AUDITLOCATION_][1].propname=L"LogToFile";
g_arPROP[_p_SEC_][0].propname=L"SecurityMechanism";
g_arPROP[_p_DOM_][0].propname=L"DefaultDomain";
g_arPROP[_p_AUDIT_][0].propname=L"LogAdminAttempts";
g_arPROP[_p_AUDIT_][1].propname=L"LogNonAdminAttempts";
g_arPROP[_p_AUDIT_][2].propname=L"LogFailures";
g_arPROP[_p_TIMEOUTACTIVE_][0].propname=L"IdleSessionTimeout";
g_arPROP[_p_TIMEOUTACTIVE_][1].propname=L"IdleSessionTimeoutBkup";
g_arPROP[_p_FNAME_][0].propname=L"LogFile";
g_arPROP[_p_FSIZE_][0].propname=L"LogFileSize";
g_arPROP[_p_DEFAULTS_][0].propname=L"Defaults";
g_arPROP[_p_INSTALLPATH_][0].propname=L"InstallPath";//not used
//giving the properties their type.
V_VT(&g_arPROP[_p_CTRLAKEYMAP_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_TIMEOUT_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_TIMEOUT_][1].var)=VT_I4;
V_VT(&g_arPROP[_p_MAXCONN_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_PORT_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_MAXFAIL_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_KILLALL_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_MODE_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_AUDITLOCATION_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_AUDITLOCATION_][1].var)=VT_I4;
V_VT(&g_arPROP[_p_SEC_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_DOM_][0].var)=VT_BSTR;
V_VT(&g_arPROP[_p_AUDIT_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_AUDIT_][1].var)=VT_I4;
V_VT(&g_arPROP[_p_AUDIT_][2].var)=VT_I4;
V_VT(&g_arPROP[_p_TIMEOUTACTIVE_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_TIMEOUTACTIVE_][1].var)=VT_I4;
V_VT(&g_arPROP[_p_FNAME_][0].var)=VT_BSTR;
V_VT(&g_arPROP[_p_FSIZE_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_DEFAULTS_][0].var)=VT_I4;
V_VT(&g_arPROP[_p_INSTALLPATH_][0].var)=VT_BSTR;
return 0;
}
/*--
DoTnadmindoes the actual work corresponding the command line,
Depending upon the option given.
--*/
HRESULT DoTnadmin(void)
{
int nProperty,nj;
SCODE sc;
SCODE hRes;
SetThreadUILanguage(0);
if(g_nError)
return E_FAIL;
if(_HELP==g_nPrimaryOption)
{
#ifdef WHISTLER_BUILD
PrintMessageEx(g_stdout,IDR_NEW_TELNET_USAGE,TEXT("\nUsage: tlntadmn [computer name] [common_options] start | stop | pause | continue | -s | -k | -m | config config_options \n\tUse 'all' for all sessions.\n\t-s sessionid List information about the session.\n\t-k sessionid\t Terminate a session. \n\t-m sessionid\t Send message to a session. \n\n\tconfig\t Configure telnet server parameters.\n\ncommon_options are:\n\t-u user\t Identity of the user whose credentials are to be used\n\t-p password\t Password of the user\n\nconfig_options are:\n\tdom = domain\t Set the default domain for user names\n\tctrlakeymap = yes|no\t Set the mapping of the ALT key\n\ttimeout = hh:mm:ss\t Set the Idle Session Timeout\n\ttimeoutactive = yes|no Enable idle session timeout.\n\tmaxfail = attempts\t Set the maximum number of login failure attempts\n\tbefore disconnecting.\n\tmaxconn = connections\t Set the maximum number of connections.\n\tport = number\t Set the telnet port.\n\tsec = [+/-]NTLM [+/-]passwd\n\t Set the authentication mechanism\n\tmode = console|stream\t Specify the mode of operation.\n"));
#else
PrintMessageEx(g_stdout,IDR_NEW_TELNET_USAGE,TEXT("\nUsage: tnadmin [computer name] [common_options] start | stop | pause | continue | -s | -k | -m | config config_options \n\tUse 'all' for all sessions.\n\t-s sessionid List information about the session.\n\t-k sessionid\t Terminate a session. \n\t-m sessionid\t Send message to a session. \n\n\tconfig\t Configure telnet server parameters.\n\ncommon_options are:\n\t-u user\t Identity of the user whose credentials are to be used\n\t-p password\t Password of the user\n\nconfig_options are:\n\tdom = domain\t Set the default domain for user names\n\tctrlakeymap = yes|no\t Set the mapping of the ALT key\n\ttimeout = hh:mm:ss\t Set the Idle Session Timeout\n\ttimeoutactive = yes|no Enable idle session timeout.\n\tmaxfail = attempts\t Set the maximum number of login failure attempts\n\tbefore disconnecting.\n\tmaxconn = connections\t Set the maximum number of connections.\n\tport = number\t Set the telnet port.\n\tsec = [+/-]NTLM [+/-]passwd\n\t Set the authentication mechanism\n\tmode = console|stream\t Specify the mode of operation.\n"));
#endif
hRes = S_OK;
return hRes;
}
//remote execution
if(NULL!=g_arVALOF[_p_CNAME_]&&(0==_wcsicmp(g_arVALOF[_p_CNAME_],L"localhost")||0==_wcsicmp(g_arVALOF[_p_CNAME_],L"\\\\localhost")))
{
free(g_arVALOF[_p_CNAME_]);
g_arVALOF[_p_CNAME_]=NULL;
// g_szCName=NULL; Not used any more
}
if(FAILED(hRes=CheckForPassword())) //Get password if not specified
return hRes;
//Checking if the telnet server exists
if(FAILED(sc=(DoNetUseAdd(g_arVALOF[_p_USER_],g_arVALOF[_p_PASSWD_],g_arVALOF[_p_CNAME_]))))
return sc;
// We don't have to keep the password anymore except while handling sessions
// related options.
if((g_nPrimaryOption!=_S)&&(g_nPrimaryOption!=_K)&&(g_nPrimaryOption!=_M))
{
TnClearPasswd();
}
if(FAILED(hRes=(GetConnection(g_arVALOF[_p_CNAME_]))))
goto End;
if(FAILED(hRes = IsWhistlerTheOS(&g_fWhistler)))
goto End;
// If the telnet server is not of Whistler and SFU, then it would be from Win2K
// We do not support remote administration for this. So need to special case ...
if(FALSE == g_fWhistler)
{
if(FAILED(hRes=GetClassEx(_p_INSTALLPATH_, 0, false, MAXIMUM_ALLOWED)))
{
ShowError(IDR_INVALID_TELNET_SERVER_VERSION);
hRes = E_FAIL;
goto End;
}
else
{
if(g_arCLASShkey[g_arPROP[_p_INSTALLPATH_][0].classname] != NULL &&
RegCloseKey(g_arCLASShkey[g_arPROP[_p_INSTALLPATH_][0].classname]) != ERROR_SUCCESS)
{
hRes = GetLastError();
goto End;
}
g_arCLASShkey[g_arPROP[_p_INSTALLPATH_][0].classname] = NULL;
}
}
if(FALSE == g_fWhistler)
if(S_OK!=(hRes=GetSerHandle(L"tlntsvr",GENERIC_READ,SERVICE_QUERY_STATUS,FALSE))||S_OK!=(hRes=CloseHandles()))
goto End;
switch (g_nPrimaryOption)
{
case _START :
hRes=StartSfuService(L"tlntsvr");
break;
case _STOP :
hRes=ControlSfuService(L"tlntsvr",SERVICE_CONTROL_STOP);
break;
case _PAUSE :
hRes=ControlSfuService(L"tlntsvr",SERVICE_CONTROL_PAUSE);
break;
case _CONTINUE:
hRes=ControlSfuService(L"tlntsvr",SERVICE_CONTROL_CONTINUE);
break;
case _S :
ShowSession();
break;
case _K :
TerminateSession();
break;
case _M :
MessageSession();
break;
case _CONFIG:
if(g_nConfigOptions)
{
g_nConfigOptions=SetBit(g_nConfigOptions,_p_DEFAULTS_);
for(nProperty=0;nProperty<_MAX_PROPS_;nProperty++)
{if(GetBit(g_nConfigOptions,nProperty))
{
for(nj=0;nj<g_arNUM_PROPNAME[nProperty];nj++)
{
if(FAILED(hRes=GetClass(nProperty,nj)))
goto End;
if(FAILED(hRes=GetCorrectVariant(nProperty,nj,&g_arPROP[nProperty][nj].var)))
goto End;
}
}
}
if(g_nError)
break;
for(nProperty=0;nProperty<_MAX_PROPS_;nProperty++)
if(GetBit(g_nConfigOptions,nProperty))
{
for(nj=0;nj<g_arNUM_PROPNAME[nProperty];nj++)
if(FAILED(hRes=PutProperty(nProperty,nj,&g_arPROP[nProperty][nj].var)))
goto End;
}
if(FAILED(hRes=PutClasses()))
goto End;
PrintMessage(g_stdout,IDR_SETTINGS_UPDATED);
break;
}
default :
for(nProperty=0;nProperty<_MAX_PROPS_;nProperty++)
{
if(nProperty==_p_INSTALLPATH_)
continue;
for(nj=0;nj<g_arNUM_PROPNAME[nProperty];nj++)
{
if(FAILED(hRes=GetClass(nProperty,nj)))
goto End;
if(FAILED(hRes=GetProperty(nProperty,nj,&g_arPROP[nProperty][nj].var)))
goto End;
}
}
if(FAILED(hRes=PutClasses()))
goto End;
if(FAILED(hRes=QuerySfuService(L"tlntsvr")))
goto End;
hRes=PrintSettings();
break;
}
End:
(void)DoNetUseDel(g_arVALOF[_p_CNAME_]);
return hRes;
}
/*--
The function GetCorrectVariant makes a variant out of the wchar_t * of
the value of each option and returns the variant
this function is called by DoTnadmin(), to get the correct variants
and they are put using PutProperty() function.
This function also performs checks as to if the input is valid or not.
such as : if the input is in valid range or not, etc.
Note that Variant is malloced here, so has to be freed once used.
--*/
HRESULT GetCorrectVariant(int nProperty,int nPropattrib, VARIANT* pvarVal)
{
VARIANT vVar={0};
HRESULT hRes=ERROR_SUCCESS;
int fValid=0;
WCHAR sztempDomain[_MAX_PATH];
switch (nProperty)
{
case _p_CTRLAKEYMAP_ :
case _p_KILLALL_ :
V_VT(pvarVal)=VT_I4;
if(_wcsicmp(g_arVALOF[nProperty],L"yes")>=0)
V_I4(pvarVal)=1;
else
V_I4(pvarVal)=0;
break;
case _p_MAXCONN_ :
V_VT(pvarVal)=VT_I4;
V_I4(pvarVal)=_wtoi(g_arVALOF[nProperty]);
// Why checking for MaxInt? We are anyway checking it for <0?
// Answer: _wtoi() function may end up giving us a positive number
// whose value is < MAXINT when we give a very long input.
// Hence checking for MaxINT leaves us in the safe side.
if(FAILED(hRes=CheckForMaxInt(g_arVALOF[nProperty],IDR_MAXCONN_VALUES)))
break;
// We have decided to allow as many connections as possible on Whistler
// too making it no different than Win2K
/* if(!IsMaxConnChangeAllowed()) //Checking for Whistler and SFU not installed.
{ //We allow him to make it 1 or 0
if((V_I4(pvarVal)>2) || (V_I4(pvarVal)<0)) //less than zero for cases where the integer value is greater than 2147483647
{
ShowError(IDR_MAXCONN_VALUES_WHISTLER);
break;
}
}*/
if((V_I4(pvarVal)<0) || (V_I4(pvarVal)>MAX_VALUE_MAXCONN)) //Incase the value exceeds the maximum limit that an integer can store
{ //then it is converted as a negative number
ShowError(IDR_MAXCONN_VALUES);
break;
}
break;
case _p_PORT_ :
V_VT(pvarVal)=VT_I4;
V_I4(pvarVal)=_wtoi(g_arVALOF[nProperty]) ;
if(FAILED(hRes=CheckForMaxInt(g_arVALOF[nProperty],IDR_TELNETPORT_VALUES)))
break;
if((V_I4(pvarVal)>1023)||(V_I4(pvarVal)<=0))
ShowError(IDR_TELNETPORT_VALUES);
break;
case _p_MAXFAIL_ :
V_VT(pvarVal)=VT_I4;
V_I4(pvarVal)=_wtoi(g_arVALOF[nProperty]) ;
if(FAILED(hRes=CheckForMaxInt(g_arVALOF[nProperty],IDR_MAXFAIL_VALUES)))
break;
if((V_I4(pvarVal)>100)||(V_I4(pvarVal)<=0))
ShowError(IDR_MAXFAIL_VALUES);
break;
case _p_FSIZE_ :
V_VT(pvarVal)=VT_I4;
hRes=GetProperty(_p_FNAME_,0,&vVar);
if(FAILED(hRes))
return hRes;
// The first check in the following condition (V_BSTR(&vVar)==NULL) is added to avoid
// deferencing of NULL pointer in _wcsicmp(). But this can NEVER be null as we check
// for the error case in GetProperty() - added to get rid of Prefix issue
if(((V_BSTR(&vVar)==NULL) || (_wcsicmp(V_BSTR(&vVar),L"")==NULL)) && ((wchar_t*)V_BSTR(&g_arPROP[_p_FNAME_][0].var)==NULL))
{
ShowError(IDR_NOFILENAME);
break;
}
V_I4(pvarVal)=_wtoi(g_arVALOF[nProperty]);
if(FAILED(hRes=CheckForMaxInt(g_arVALOF[nProperty],IDR_FILESIZE_VALUES)))
break;
if((V_I4(pvarVal)<0)||(V_I4(pvarVal)>4096))
ShowError(IDR_FILESIZE_VALUES);
break;
case _p_MODE_ :
V_VT(pvarVal)=VT_I4;
if(_wcsicmp(g_arVALOF[nProperty],L"stream")<0)
//Since console<stream.
V_I4(pvarVal)=1;
else
V_I4(pvarVal)=2;
break;
case _p_AUDITLOCATION_ :
V_VT(pvarVal)=VT_I4;
if(nPropattrib==0)
if(_wcsicmp(g_arVALOF[nProperty],L"file")<0)
V_I4(pvarVal)=1;
else
V_I4(pvarVal)=0;
else
if(_wcsicmp(g_arVALOF[nProperty],L"eventlog")<0||_wcsicmp(g_arVALOF[nProperty],L"file")>=0)
V_I4(pvarVal)=1;
else
V_I4(pvarVal)=0;
break;
#if 0 // This option has been removed
case _p_FNAME_ :
{
wchar_t* wzFile=(wchar_t*)malloc(3*sizeof(wchar_t));
if(wzFile==NULL)
return E_OUTOFMEMORY;
wzFile[0]=g_arVALOF[_p_FNAME_][0];
if((wzFile[1]=g_arVALOF[_p_FNAME_][1])!=L':'||(wzFile[2]=g_arVALOF[_p_FNAME_][2])!=L'\\')
{ShowError(IDR_ERROR_DRIVE_NOT_SPECIFIED);free(wzFile);break;}
//file[3]=g_arVALOF[_p_FNAME_][3];
wzFile[3]=L'\0';
if(DRIVE_FIXED!=GetDriveType(wzFile))
ShowError(IDR_ERROR_DRIVE_NOT_EXIST);
free(wzFile);
wchar_t* wzFileName=_wcsdup(g_arVALOF[_p_FNAME_]);
if(FAILED(hRes=CreateFileIfNotExist(wzFileName)))
{
free(wzFileName);
return hRes;
}
free(wzFileName);
}
#endif
case _p_DOM_ :
if( nProperty==_p_DOM_ )
{
if(wcsncmp(g_arVALOF[nProperty],SLASH_SLASH,2)==0)
{
ShowError(IDR_INVALID_NTDOMAIN);
break;
}
if(FAILED(hRes=IsValidDomain(g_arVALOF[nProperty],&fValid)))
return hRes;
if(fValid == 0)
{
// try again with '\\' at the beginning - don't modify the original function that returns
// the local machine name with '\\' appended to it
wcscpy(sztempDomain,SLASH_SLASH);
wcsncat(sztempDomain,g_arVALOF[nProperty],_MAX_PATH -sizeof(SLASH_SLASH)-sizeof(WCHAR));
if(FAILED(hRes=IsValidDomain(sztempDomain,&fValid)))
return hRes;
}
if(fValid==0)
{
ShowError(IDR_INVALID_NTDOMAIN);
break;
}
}
V_VT(pvarVal)=VT_BSTR;
V_BSTR(pvarVal)=SysAllocString(g_arVALOF[nProperty]);
break;
case _p_AUDIT_ :
V_VT(pvarVal)=VT_I4;
if(nPropattrib==0)
if(GetBit(g_nAuditOff,ADMIN_BIT))
V_I4(pvarVal)=0;
else if(GetBit(g_nAuditOn,ADMIN_BIT))
V_I4(pvarVal)=1;
else
g_arPROP[_p_AUDIT_][0].fDontput=1;
else if(nPropattrib==1)
if(GetBit(g_nAuditOff,USER_BIT))
V_I4(pvarVal)=0;
else if(GetBit(g_nAuditOn,USER_BIT))
V_I4(pvarVal)=1;
else
g_arPROP[_p_AUDIT_][1].fDontput=1;
else
if(GetBit(g_nAuditOff,FAIL_BIT))
V_I4(pvarVal)=0;
else if(GetBit(g_nAuditOn,FAIL_BIT))
V_I4(pvarVal)=1;
else
g_arPROP[_p_AUDIT_][2].fDontput=1;
break;
case _p_TIMEOUTACTIVE_ :
if(nPropattrib==1) // Do not meddle with the backup property.
{g_arPROP[_p_TIMEOUTACTIVE_][nPropattrib].fDontput=1;break;}
V_VT(pvarVal)=VT_I4;
if(0==_wcsicmp(g_arVALOF[nProperty],L"yes"))
{
if(FAILED(hRes=GetProperty(_p_TIMEOUTACTIVE_,1,&vVar)))
return hRes;
V_I4(pvarVal)=V_I4(&vVar);
}
else
V_I4(pvarVal)=-1;
break;
case _p_TIMEOUT_: //By this time timeoutactive is already set or put.
if(GetBit(g_nConfigOptions,_p_TIMEOUTACTIVE_)&&(_wcsicmp(g_arVALOF[_p_TIMEOUTACTIVE_],L"yes")<0))
{
g_arPROP[_p_TIMEOUT_][nPropattrib].fDontput=1;
ShowError(IDR_TIMEOUTACTIVE_TIMEOUT_MUTUAL_EXCLUSION);
return E_FAIL;//Check this return Value
}
V_VT(pvarVal)=VT_I4;
if(g_nTimeoutFlag)
{
V_I4(pvarVal)=_wtoi(g_arVALOF[nProperty]);
}
else
{
if(CheckForInt(nProperty))
{
int nSeconds;
if(0==nPropattrib)
{
ConvertintoSeconds(nProperty,&nSeconds);
V_I4(pvarVal)=nSeconds;
}
// Now that we have destroyed whatever value we had in the global
// variable by the use of wcstok, we need to copy from the already
// computed value
else //incase nPropattrib is 1
V_I4(pvarVal)=V_I4(& g_arPROP[nProperty][0].var);
}
}
if(V_I4(pvarVal)>60*60*2400||V_I4(pvarVal)<=0)
{
ShowError(IDR_TIMEOUT_INTEGER_VALUES);
hRes=E_FAIL;
}
break;
case _p_SEC_ :
V_VT(pvarVal)=VT_I4;
if(FAILED(hRes=GetProperty(_p_SEC_,0,&vVar)))
return hRes;
if(GetBit(g_nSecOn,PASSWD_BIT))//+passwd
if(GetBit(g_nSecOn,NTLM_BIT)) //+ntlm
V_I4(pvarVal)=6;
else if(GetBit(g_nSecOff,NTLM_BIT)) //-ntlm
V_I4(pvarVal)=4;
else
{
if(V_I4(&vVar)!=2)
g_arPROP[nProperty][nPropattrib].fDontput=1;
else
V_I4(pvarVal)=6;
}
else if(GetBit(g_nSecOff,PASSWD_BIT)) //-passwd
if(GetBit(g_nSecOn,NTLM_BIT)) //+ntlm
V_I4(pvarVal)=2;
else if(GetBit(g_nSecOff,NTLM_BIT)) //-ntlm
{
ShowError(IDR_NO_AUTHENTICATION_MECHANISM);
g_arPROP[nProperty][nPropattrib].fDontput=1;
}
else
{
if(V_I4(&vVar)==4)
{
ShowError(IDR_NO_AUTHENTICATION_MECHANISM);
g_arPROP[nProperty][nPropattrib].fDontput=1;
}
else if(V_I4(&vVar)==2)
g_arPROP[_p_SEC_][nPropattrib].fDontput=1;
else
V_I4(pvarVal)=2;
}
else
if(GetBit(g_nSecOn,NTLM_BIT)) //+ntlm
{
if(V_I4(&vVar)!=4)
g_arPROP[nProperty][nPropattrib].fDontput=1;
else
V_I4(pvarVal)=6;
}
else if(GetBit(g_nSecOff,NTLM_BIT)) //-ntlm
{
if(V_I4(&vVar)==2)
{
ShowError(IDR_NO_AUTHENTICATION_MECHANISM);
g_arPROP[nProperty][nPropattrib].fDontput=1;
}
else if(V_I4(&vVar)==4)
g_arPROP[_p_SEC_][nPropattrib].fDontput=1;
else
V_I4(pvarVal)=4;
}
else
{
ShowError(IDR_NO_AUTHENTICATION_MECHANISM);
g_arPROP[nProperty][nPropattrib].fDontput=1;
}
break;
case _p_DEFAULTS_ :
if(nPropattrib==0)
{
if(FAILED(hRes=GetProperty(nProperty,0, &vVar)))
{
g_nError=1;
//error occurred in getting the value.
//error in notification
break;
}
V_I4(pvarVal)=((V_I4(&vVar)>0) ? 0 : 1);
}
else
g_arPROP[nProperty][nPropattrib].fDontput=1;
break;
case _p_CNAME_ :
case _p_INSTALLPATH_ :
default :
g_arPROP[nProperty][nPropattrib].fDontput=1;
break;
}
return hRes;
}
/*--
PrintSettings Gets the present values int the registry corresponding to the
tnadmin and prints it out.
--*/
HRESULT PrintSettings(void)
{
int nLen=0, temp_count;
int nCheck=0;
WCHAR wzDomain[DNS_MAX_NAME_BUFFER_LENGTH];
WCHAR szTemp[MAX_BUFFER_SIZE] = { 0 };
nLen=LoadString(g_hResource,IDR_MACHINE_SETTINGS, szTemp, MAX_BUFFER_SIZE );
if(0 == nLen) return GetLastError();
_putws(L"\n");
_snwprintf(g_szMsg, MAX_BUFFER_SIZE -1, szTemp,(NULL == g_arVALOF[_p_CNAME_]) ? L"localhost" : g_arVALOF[_p_CNAME_]);
MyWriteConsole(g_stdout, g_szMsg, wcslen(g_szMsg));
// The following line(commented out) is used when we had g_szCName to
// store the computer name as g_arVALOF[_p_CNAME_] stores the same in
// the IP address format.
// But we decided not to go for it as it will lead to serious perf issues
nLen = 0;
nCheck=LoadString(g_hResource, IDR_ALT_KEY_MAPPING, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
//ctrlakeymap
if(V_I4(&g_arPROP[_p_CTRLAKEYMAP_][0].var))
{
nCheck=TnLoadString(IDR_YES, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tYES\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
else
{
nCheck=TnLoadString(IDR_NO, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tYES\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
//timeout
nCheck=LoadString(g_hResource, IDR_IDLE_SESSION_TIMEOUT, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
if(V_I4(&g_arPROP[_p_TIMEOUT_][0].var)==-1)
{
nCheck=TnLoadString(IDR_MAPPING_NOT_ON, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tNot On\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
else
{
int nTime=V_I4(&g_arPROP[_p_TIMEOUT_][0].var);
int nQuotient=nTime/3600;
nTime=nTime-nQuotient*3600;
if(nQuotient)
{
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"\t%d ",nQuotient);
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
nCheck=TnLoadString(IDR_TIME_HOURS, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("hours"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
nQuotient=nTime/60;
nTime=nTime-nQuotient*60;
if(nQuotient)
{
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L" %d ",nQuotient);
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
nCheck=TnLoadString(IDR_TIME_MINUTES, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("minutes"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L" %d ",nTime);
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
nCheck=TnLoadString(IDR_TIME_SECONDS, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("seconds\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
else if(nTime)
{
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L" %d ",nTime);
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
nCheck=TnLoadString(IDR_TIME_SECONDS, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("seconds\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
else
{
wcsncpy(g_szMsg+nLen, L"\n", ARRAYSIZE(g_szMsg)-nLen-1);
g_szMsg[ARRAYSIZE(g_szMsg)-1]=L'\0';
nLen += 1; // for L"\n"
if (nLen >= ARRAYSIZE(g_szMsg))
return ERROR_INSUFFICIENT_BUFFER;
}
}
else if(nTime)
{
nQuotient=nTime/60;
nTime=nTime-nQuotient*60;
if(nQuotient)
{
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"\t%d ",nQuotient);
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
nCheck = TnLoadString(IDR_TIME_MINUTES, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("minutes"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L" %d ",nTime);
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
nCheck = TnLoadString(IDR_TIME_SECONDS, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("seconds\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
else
{
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1, L"\t%d ",nTime);
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
nCheck = TnLoadString(IDR_TIME_SECONDS, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("seconds\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
}
else
{
wcsncpy(g_szMsg+nLen, L"\t0 ", ARRAYSIZE(g_szMsg)-nLen-1);
g_szMsg[ARRAYSIZE(g_szMsg)-1]=L'\0';
nLen += wcslen(L"\t0 ");
if (nLen >= ARRAYSIZE(g_szMsg)) {
return ERROR_INSUFFICIENT_BUFFER;
}
nCheck = TnLoadString(IDR_TIME_SECONDS, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("seconds\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
}
//maxconnections
nCheck = LoadString(g_hResource, IDR_MAX_CONNECTIONS, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"\t%d\n",V_I4(&g_arPROP[_p_MAXCONN_][0].var));
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
//port
nCheck = LoadString(g_hResource, IDR_TELNET_PORT, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"\t%d\n",V_I4(&g_arPROP[_p_PORT_][0].var));
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
//maxfail
nCheck = LoadString(g_hResource, IDR_MAX_FAILED_LOGIN_ATTEMPTS, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"\t%d\n",V_I4(&g_arPROP[_p_MAXFAIL_][0].var));
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
//kill on disconnect
nCheck = LoadString(g_hResource, IDR_END_TASKS_ON_DISCONNECT, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
if(V_I4(&g_arPROP[_p_KILLALL_][0].var)==1)
{
nCheck = TnLoadString(IDR_YES, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tYES\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
else
{
nCheck = TnLoadString(IDR_NO, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tNO\n"));
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
//mode
nCheck = LoadString(g_hResource, IDR_MODE_OF_OPERATION, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1, L"\t%s\n",(V_I4(&g_arPROP[_p_MODE_][0].var)==1) ? L"Console" : L"Stream");
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
MyWriteConsole(g_stdout,g_szMsg,wcslen(g_szMsg));
//sec
nLen=0;
nLen = LoadString(g_hResource,IDR_AUTHENTICATION_MECHANISM, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(0 == nLen) return GetLastError();
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
switch(V_I4(&g_arPROP[_p_SEC_][0].var))
{
case 2 :
wcsncpy(g_szMsg+nLen, L"\tNTLM\n", ARRAYSIZE(g_szMsg)-nLen-1);
g_szMsg[ARRAYSIZE(g_szMsg)-1]=L'\0';
nLen += wcslen(L"\tNTLM\n");
if (nLen >= ARRAYSIZE(g_szMsg)) {
return ERROR_INSUFFICIENT_BUFFER;
}
break;
case 4 :
wcsncpy(g_szMsg+nLen, L"\tPassword\n", ARRAYSIZE(g_szMsg)-nLen-1);
g_szMsg[ARRAYSIZE(g_szMsg)-1]=L'\0';
nLen += wcslen(L"\tPassword\n");
if (nLen >= ARRAYSIZE(g_szMsg)) {
return ERROR_INSUFFICIENT_BUFFER;
}
break;
default :
wcsncpy(g_szMsg+nLen, L"\tNTLM, Password\n", ARRAYSIZE(g_szMsg)-nLen-1);
g_szMsg[ARRAYSIZE(g_szMsg)-1]=L'\0';
nLen += wcslen(L"\tNTLM, Password\n");
if (nLen >= ARRAYSIZE(g_szMsg)) {
return ERROR_INSUFFICIENT_BUFFER;
}
break;
}
//default domain
nCheck=LoadString(g_hResource, IDR_DEFAULT_DOMAIN, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
if(NULL==wcscmp(V_BSTR(&g_arPROP[_p_DOM_][0].var), L"."))
{
if(setDefaultDomainToLocaldomain(wzDomain))
{
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1, L"\t%s\n",wzDomain);
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
}
else
{
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1, L"\t%s\n",V_BSTR(&g_arPROP[_p_DOM_][0].var));
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
}
}
else
{
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"\t%s\n",V_BSTR(&g_arPROP[_p_DOM_][0].var));
if (temp_count < 0) {
return ERROR_INSUFFICIENT_BUFFER;
}
nLen += temp_count;
}
//state of the service
nCheck = LoadString(g_hResource, IDR_STATE, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen);
if(nCheck==0) return GetLastError();
nLen += nCheck;
// check whether we have room left in the buffer.
if (nLen >= ARRAYSIZE(g_szMsg))
{
return ERROR_INSUFFICIENT_BUFFER;
}
switch(g_hServiceStatus.dwCurrentState)
{
case SERVICE_STOPPED :
nCheck = TnLoadString(IDR_STATUS_STOPPED, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tStopped\n"));
if(nCheck==0) return GetLastError();
break;
case SERVICE_RUNNING :
nCheck = TnLoadString(IDR_STATUS_RUNNING, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tRunning\n"));
if(nCheck==0) return GetLastError();
break;
case SERVICE_PAUSED :
nCheck = TnLoadString(IDR_STATUS_PAUSED, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tPaused\n"));
if(nCheck==0) return GetLastError();
break;
case SERVICE_START_PENDING:
nCheck = TnLoadString(IDR_STATUS_START_PENDING, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tStart Pending\n"));
if(nCheck==0) return GetLastError();
break;
case SERVICE_STOP_PENDING :
nCheck = TnLoadString(IDR_STATUS_STOP_PENDING, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tStop Pending\n"));
if(nCheck==0) return GetLastError();
break;
case SERVICE_CONTINUE_PENDING:
nCheck = TnLoadString(IDR_STATUS_CONTINUE_PENDING, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tContinue Pending\n"));
if(nCheck==0) return GetLastError();
break;
case SERVICE_PAUSE_PENDING:
nCheck = TnLoadString(IDR_STATUS_PAUSE_PENDING, g_szMsg+nLen, MAX_BUFFER_SIZE-nLen,_T("\tPause Pending\n"));
if(nCheck==0) return GetLastError();
break;
default :
nCheck = 0;
break;
}
nLen += nCheck;
MyWriteConsole(g_stdout,g_szMsg,wcslen(g_szMsg));
return S_OK;
}
/*--
SesidInit() functions gets the handle to the session
manager interface.
--*/
#define FOUR_K 4096
HRESULT SesidInit()
{
HRESULT hr = S_OK;
COSERVERINFO serverInfo = { 0 };
MULTI_QI qi = {&IID_IManageTelnetSessions, NULL, S_OK};
CLSCTX server_type_for_com = CLSCTX_LOCAL_SERVER;
COAUTHINFO com_auth_info = { 0 };
COAUTHIDENTITY com_auth_identity = { 0 };
wchar_t full_user_name[FOUR_K + 1] = { 0 }; // hack for now
if (g_arVALOF[_p_CNAME_]) // a remote box has been specified
{
server_type_for_com = CLSCTX_REMOTE_SERVER;
serverInfo.pwszName = g_arVALOF[_p_CNAME_];
// printf("BASKAR: Remote Machine name added\n");
}
if (g_arVALOF[_p_USER_]) // A user name has been specified, so go with it
{
wchar_t *delimited;
wcsncpy(full_user_name, g_arVALOF[_p_USER_], FOUR_K);
delimited = StrStrIW(full_user_name, L"\\");
if (delimited)
{
*delimited = L'\0';
delimited ++;
com_auth_identity.Domain = full_user_name;
com_auth_identity.User = delimited;
// printf("BASKAR: Domain\\User name added\n");
}
else
{
com_auth_identity.User = full_user_name;
// printf("BASKAR: Just User name added\n");
}
com_auth_identity.UserLength = lstrlenW(com_auth_identity.User);
if (com_auth_identity.Domain)
{
com_auth_identity.DomainLength = lstrlenW(com_auth_identity.Domain);
}
if (g_arVALOF[_p_PASSWD_])
{
com_auth_identity.Password = g_arVALOF[_p_PASSWD_];
com_auth_identity.PasswordLength = lstrlenW(com_auth_identity.Password);
// printf("BASKAR: Password added\n");
}
com_auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
com_auth_info.dwAuthnSvc = RPC_C_AUTHN_WINNT;
com_auth_info.dwAuthzSvc = RPC_C_AUTHZ_NONE;
com_auth_info.pwszServerPrincName = NULL;
com_auth_info.dwAuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
com_auth_info.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
com_auth_info.pAuthIdentityData = &com_auth_identity;
com_auth_info.dwCapabilities = EOAC_NONE;
serverInfo.pAuthInfo = &com_auth_info;
// printf("BASKAR: Auth Info added\n");
}
// No need to worry about the CoInitialize() as we have done that in Initialize()
// function.
hr = CoCreateInstanceEx(
CLSID_EnumTelnetClientsSvr,
NULL,
server_type_for_com,
&serverInfo,
1,
&qi
);
// We no longer require password - clear it
TnClearPasswd();
if( SUCCEEDED(hr) && SUCCEEDED(qi.hr) )
{
// if (g_arVALOF[_p_USER_])
// {
// hr = CoSetProxyBlanket(
// (IUnknown*)qi.pItf, // This is the proxy interface
// com_auth_info.dwAuthnSvc,
// com_auth_info.dwAuthzSvc,
// com_auth_info.pwszServerPrincName,
// com_auth_info.dwAuthnLevel,
// com_auth_info.dwImpersonationLevel,
// &com_auth_identity,
// com_auth_info.dwCapabilities
// );
// }
// Now get the interface
g_pIManageTelnetSessions = ( IManageTelnetSessions* )qi.pItf;
}
else
{
g_pIManageTelnetSessions= NULL;
if (hr == E_ACCESSDENIED)
{
ShowError(IDS_E_CANNOT_MANAGE_TELNETSERVER);
}
else
{
ShowError(IDS_E_CANNOT_CONTACT_TELNETSERVER);
}
hr = E_FAIL;
}
return hr;
}
#undef FOUR_K
/*--
This function gets a handle to session manager interface
using sesidinit and also gets all the sessions into an array.
--*/
HRESULT ListUsers()
{
BSTR bstrSessionInfo;
HRESULT hRes=S_OK;
wchar_t *wzAllSession;
//List Users gets all the session Info into this BSTR.
if(g_pIManageTelnetSessions == NULL )
{
if(FAILED(hRes=SesidInit()))
return hRes;
}
// DebugBreak();
if(g_pIManageTelnetSessions == NULL )
{
// Still you didn't get the interface handle
// what else can we do? In case of any error in getting the handle, we would
// have printed the error message in SesidInit(). So just bail out here.
// This code path should never get executed.
return S_FALSE;
}
hRes =g_pIManageTelnetSessions->GetTelnetSessions(&bstrSessionInfo);
if( FAILED( hRes ) || (NULL == bstrSessionInfo))
{
_tprintf( TEXT("Error: GetEnumClients(): 0x%x\n"), hRes );
//Load a String here.
return hRes;
}
wzAllSession=(wchar_t *)bstrSessionInfo;
//parsing the bstrSessionInfo into each session and placing it into the
//global array g_ppwzSessionInfo for other functions to use it.
g_nNumofSessions=_wtoi(wcstok(wzAllSession,session_separator));
if(!g_nNumofSessions)
{
return hRes;
}
if((g_ppwzSessionInfo=(wchar_t**)malloc(g_nNumofSessions*sizeof(wchar_t*)))==NULL)
{
ShowError(IDS_E_OUTOFMEMORY);//BB
return E_OUTOFMEMORY;
}
for(int i=0;i<g_nNumofSessions;i++)
{
g_ppwzSessionInfo[i]=wcstok(NULL,session_separator);
}
return hRes;
}
/*--
TerminateSession terminates all sessions or given sessionid's session.
--*/
HRESULT TerminateSession(void )
{
HRESULT hRes=S_OK;int i;
if(FAILED(hRes=ListUsers()))
goto End;
if(g_nNumofSessions==0)
{
if(LoadString(g_hResource,IDR_NO_ACTIVE_SESSION,g_szMsg,MAX_BUFFER_SIZE)==0)
return GetLastError();
MyWriteConsole(g_stdout,g_szMsg,wcslen(g_szMsg));
return S_OK;
}
if(g_nSesid!=-1&&CheckSessionID()==0)
{ ShowError(IDR_INVALID_SESSION);
return S_OK;
}
for(i=0;i<g_nNumofSessions;i++)
{
wchar_t* wzId=wcstok(g_ppwzSessionInfo[i],session_data_separator);
if(g_nSesid!=-1)
if(g_nSesid!=_wtoi(wzId))
continue;
hRes= g_pIManageTelnetSessions->TerminateSession(_wtoi(wzId));
}
if( FAILED( hRes ) )
{
_tprintf( TEXT("Error: GetEnumClients(): 0x%x\n"), hRes );
//Load a String here.
return E_FAIL;
}
End:
return hRes;
}
/*--
This function gets a handle to session manager interface
using sesidinit and list users and sends message to the
corresponding sessions.
--*/
HRESULT MessageSession(void)
{
HRESULT hRes=S_OK;
int i=0;
if(FAILED(hRes=ListUsers()))
goto End;
if(g_nNumofSessions==0)
{
if(LoadString(g_hResource,IDR_NO_ACTIVE_SESSION,g_szMsg,MAX_BUFFER_SIZE)==0)
return GetLastError();
MyWriteConsole(g_stdout,g_szMsg,wcslen(g_szMsg));
return S_OK;
}
if(g_nSesid!=-1&&CheckSessionID()==0)
{
ShowError(IDR_INVALID_SESSION);
return S_OK;
}
if(g_nSesid!=-1)
hRes = g_pIManageTelnetSessions->SendMsgToASession(g_nSesid,g_bstrMessage);
else
{
for(i=0;i<g_nNumofSessions;i++)
{
wchar_t* wzId=wcstok(g_ppwzSessionInfo[i],session_data_separator);
if(g_nSesid!=-1)
if(g_nSesid!=_wtoi(wzId))
continue;
hRes= g_pIManageTelnetSessions->SendMsgToASession(_wtoi(wzId),g_bstrMessage);
}
}
if( FAILED( hRes ) )
{
_tprintf( TEXT("Error: GetEnumClients(): 0x%x\n"), hRes );
//Load a String here.
return E_FAIL;
}
if(0==LoadString(g_hResource,IDR_MESSAGE_SENT,g_szMsg,MAX_BUFFER_SIZE))
return GetLastError();
MyWriteConsole(g_stdout,g_szMsg,wcslen(g_szMsg));
End:
return hRes;
}
/*--
This function gets a handle to session manager interface
using sesidinit and list users and shows all the corresponding sessions.
--*/
HRESULT ShowSession(void)
{
HRESULT hRes=S_OK;
int nLen=0, temp_count;
int nCheck=0,i;
if(FAILED(hRes=ListUsers()))
goto Error;
if(g_nNumofSessions==0)
{
if(LoadString(g_hResource,IDR_NO_ACTIVE_SESSION,g_szMsg,MAX_BUFFER_SIZE)==0)
return GetLastError();
MyWriteConsole(g_stdout,g_szMsg,wcslen(g_szMsg));
return S_OK;
}
if(g_nSesid!=-1&&CheckSessionID()==0)
{ ShowError(IDR_INVALID_SESSION);
return S_OK;
}
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"\n%d",g_nNumofSessions);
if (temp_count < 0) {
return E_FAIL;
}
nLen += temp_count;
nCheck = LoadString(g_hResource,IDR_TELNET_SESSIONS,g_szMsg+nLen,MAX_BUFFER_SIZE-nLen);
if (nCheck == 0) {
return E_FAIL;
}
nLen += nCheck;
MyWriteConsole(g_stdout,g_szMsg,wcslen(g_szMsg));
// The following buffers are used to get the strings and print. They can not exceed Max_Path
WCHAR szMsg1[MAX_PATH+1];
WCHAR szMsg2[MAX_PATH+1];
WCHAR szMsg3[MAX_PATH+1];
WCHAR szMsg4[MAX_PATH+1];
WCHAR szMsg5[MAX_PATH+1];
WCHAR szTemp[MAX_BUFFER_SIZE] = { 0 };
if(LoadString(g_hResource,IDR_DOMAIN,szMsg1, ARRAYSIZE(szMsg1)-1)==0)
return E_FAIL;
if(LoadString(g_hResource,IDR_USERNAME,szMsg2,ARRAYSIZE(szMsg2)-1)==0)
return E_FAIL;
if(LoadString(g_hResource,IDR_CLIENT,szMsg3,ARRAYSIZE(szMsg3)-1)==0)
return E_FAIL;
if(LoadString(g_hResource,IDR_LOGONDATE,szMsg4,ARRAYSIZE(szMsg4)-1)==0)
return E_FAIL;
//IDR_LOGONDATE itself contains the IDR_LOGONTIME also
// if(LoadString(g_hResource,IDR_LOGONTIME,szMsg5,ARRAYSIZE(szMsg5)-1)==0)
// return E_FAIL;
if(LoadString(g_hResource,IDR_IDLETIME,szMsg5,ARRAYSIZE(szMsg5)-1)==0)
return E_FAIL;
/*
Getting some problem with this LoadString and swprintf interleaving here...hence the above
brute force approach.
nLen+=LoadString(g_hResource,IDR_DOMAIN,szMsg+nLen,MAX_BUFFER_SIZE-nLen);
nLen+=_snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"%s",",");
nLen+=LoadString(g_hResource,IDR_USERNAME,szMsg+nLen,MAX_BUFFER_SIZE-nLen);
nLen+=_snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"%s",L",");
nLen+=LoadString(g_hResource,IDR_CLIENT,szMsg+nLen,MAX_BUFFER_SIZE-nLen);
nLen+=_snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L",");
nLen+=LoadString(g_hResource,IDR_LOGONDATE,szMsg+nLen,MAX_BUFFER_SIZE-nLen);
nLen+=_snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L",");
nLen+=LoadString(g_hResource,IDR_LOGONTIME,szMsg+nLen,MAX_BUFFER_SIZE-nLen);
nLen+=_snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L",");
nLen+=LoadString(g_hResource,IDR_IDLETIME,szMsg+nLen,MAX_BUFFER_SIZE-nLen);
_putws(szMsg);
*/
//Stores the Formatted headed in the g_szMsg
formatShowSessionsDisplay();
_snwprintf(szTemp,MAX_BUFFER_SIZE-1,g_szMsg,L"ID",szMsg1,szMsg2,szMsg3,szMsg4,szMsg5);
MyWriteConsole(g_stdout,szTemp,wcslen(szTemp));
nLen = _snwprintf(szTemp,MAX_BUFFER_SIZE-1,g_szMsg,L" ",L" ",L" ",L" ",L" ",L"(hh:mm:ss)");
MyWriteConsole(g_stdout,szTemp,wcslen(szTemp));
for(i=1;i<nLen;i++)
putwchar(L'-');
nLen=0;
for(i=0;i<g_nNumofSessions;i++)
{
wchar_t* wzId=wcstok(g_ppwzSessionInfo[i],session_data_separator);
if(g_nSesid!=-1)
if(g_nSesid!=_wtoi(wzId))
continue;
wchar_t* wzDomain=wcstok(NULL,session_data_separator);
wchar_t* wzUser=wcstok(NULL,session_data_separator);
wchar_t* wzClient=wcstok(NULL,session_data_separator);
if (NULL == wzDomain)
{
wzDomain = L"";
}
if (NULL == wzUser)
{
wzUser = L"";
}
if (NULL == wzClient)
{
wzClient = L"";
}
wchar_t* wzYear=wcstok(NULL,session_data_separator);
wchar_t* wzMonth=wcstok(NULL,session_data_separator);
wchar_t* wzDayOfWeek=wcstok(NULL,session_data_separator);
wchar_t* wzDay=wcstok(NULL,session_data_separator);
wchar_t* wzHour=wcstok(NULL,session_data_separator);
wchar_t* wzMinute=wcstok(NULL,session_data_separator);
wchar_t* wzSecond=wcstok(NULL,session_data_separator);
BSTR wzLocalDate;
if(FAILED(hRes=ConvertUTCtoLocal(wzYear,wzMonth,wzDayOfWeek,wzDay,wzHour,wzMinute,wzSecond,& wzLocalDate)))
goto Error;
wchar_t* wzIdleTimeInSeconds=wcstok(NULL,session_data_separator); //There is a constant that not required and hence that is skipped
wzIdleTimeInSeconds=wcstok(NULL,session_data_separator);//Getting the Idle time in seconds
wchar_t wzIdleTime[MAX_PATH + 1]; // To store time. CAN NOT EXCEED MAX_PATH
wzHour=_itow(_wtoi(wzIdleTimeInSeconds)/3600,wzHour,10);
int RemSeconds=_wtoi(wzIdleTimeInSeconds)%3600;
wchar_t local_minute[3];
wchar_t local_second[3];
wzMinute=(wchar_t*) local_minute;
wzSecond=(wchar_t*) local_second;
wzMinute=_itow(RemSeconds/60,wzMinute,10);
RemSeconds=_wtoi(wzIdleTimeInSeconds)%60;
wzSecond=_itow(RemSeconds,wzSecond,10);
if(1==wcslen(wzMinute)) //Add one more zero, if it is of single digit
{
wcscat(wzMinute,L"0"); //append at the last and reverse it
wzMinute=_wcsrev(wzMinute);
}
if(1==wcslen(wzSecond))
{
wcscat(wzSecond,L"0");
wzSecond=_wcsrev(wzSecond);
}
_snwprintf(wzIdleTime, ARRAYSIZE(wzIdleTime)-1, L"%s:%s:%s", wzHour, wzMinute, wzSecond);
wzIdleTime[ARRAYSIZE(wzIdleTime)-1] = L'\0'; // ensure NULL termination
putwchar(L'\n');
_snwprintf(szTemp,MAX_BUFFER_SIZE-1,g_szMsg,wzId,wzDomain,wzUser,wzClient,wzLocalDate,wzIdleTime);
MyWriteConsole(g_stdout,szTemp,wcslen(szTemp));
//free the memory allotted
if (wzLocalDate) SysFreeString(wzLocalDate);
}
Error:
return hRes;
}
/*--
CheckSessionID checks if the given session-Id is valid or not.
Should be called only when Session id is given by the user.
--*/
int CheckSessionID(void)
{
for(int i=0;i<g_nNumofSessions;i++)
{
wchar_t* wzStr=_wcsdup(g_ppwzSessionInfo[i]);
int wzID=_wtoi(wcstok(wzStr,session_data_separator));
if(g_nSesid==wzID)
return 1;
free(wzStr);
}
return 0;
}
/*--
To free any allocated memories.
--*/
void Quit(void)
{
if(g_bstrMessage)
SysFreeString(g_bstrMessage);
if(bstrLogin)
SysFreeString(bstrLogin);
if(bstrPasswd)
SysFreeString(bstrPasswd);
if(bstrNameSpc)
SysFreeString(bstrPasswd);
for(int i=0;i<_MAX_PROPS_;i++)
if(g_arVALOF[i])
free(g_arVALOF[i]);
if(V_BSTR(&g_arPROP[_p_DOM_][0].var))
SysFreeString(V_BSTR(&g_arPROP[_p_DOM_][0].var));
if(V_BSTR(&g_arPROP[_p_FNAME_][0].var))
SysFreeString(V_BSTR(&g_arPROP[_p_FNAME_][0].var));
if(g_hResource)
FreeLibrary(g_hResource);
if(g_hXPResource)
FreeLibrary(g_hXPResource);
if(g_fCoInitSuccess)
CoUninitialize();
}
HRESULT ConvertUTCtoLocal(WCHAR *wzUTCYear, WCHAR *wzUTCMonth, WCHAR *wzUTCDayOfWeek, WCHAR *wzUTCDay, WCHAR *wzUTCHour, WCHAR *wzUTCMinute, WCHAR *wzUTCSecond, BSTR * bLocalDate)
{
HRESULT hRes=S_OK;
SYSTEMTIME UniversalTime = { 0 },
LocalTime = { 0 };
DATE dtCurrent = { 0 };
DWORD dwFlags = VAR_VALIDDATE;
UDATE uSysDate = { 0 }; //local time
*bLocalDate = NULL;
UniversalTime.wYear = (WORD)_wtoi(wzUTCYear);
UniversalTime.wMonth = (WORD)_wtoi(wzUTCMonth);
UniversalTime.wDayOfWeek = (WORD)_wtoi(wzUTCDayOfWeek);
UniversalTime.wDay = (WORD)_wtoi(wzUTCDay);
UniversalTime.wDay = (WORD)_wtoi(wzUTCDay);
UniversalTime.wMinute = (WORD)_wtoi(wzUTCMinute);
UniversalTime.wHour = (WORD)_wtoi(wzUTCHour);
UniversalTime.wSecond = (WORD)_wtoi(wzUTCSecond);
UniversalTime.wMilliseconds = 0;
SystemTimeToTzSpecificLocalTime(NULL,&UniversalTime,&LocalTime);
memcpy(&uSysDate.st,&LocalTime,sizeof(SYSTEMTIME));
hRes = VarDateFromUdate( &uSysDate, dwFlags, &dtCurrent );
if(SUCCEEDED(hRes))
{
hRes=VarBstrFromDate( dtCurrent,
MAKELCID( MAKELANGID( LANG_NEUTRAL, SUBLANG_SYS_DEFAULT ), SORT_DEFAULT ),
LOCALE_NOUSEROVERRIDE, bLocalDate);
}
return hRes;
}
//This function is to notify whether the user is allowed to change the maximum number of connections that could be established
//on the Telnet Server. It is to be noted that the user is not allowed to change the maximum number of connections to more than
//two(2 is default) if he is using Whistler and SFU is not installed.
// Commented out this function, as no more use it.
// WE HAVE DECIDED TO MAKE THE BEHAVIOR SIMILAR TO WIN2K AND NO DIFFERENT
// SO NO SPL. CHECK REQUIRED FOR WHISTLER (WINDOWS XP)
/*int IsMaxConnChangeAllowed()
{
BOOL fAllow=TRUE;
if(IsWhistlerTheOS())
if(!IsSFUInstalled())
fAllow=FALSE;
return fAllow;
}*/
HRESULT IsWhistlerTheOS(BOOL *fWhistler)
{
HKEY hReg=NULL;
DWORD nSize = 256;
DWORD nType=REG_SZ;
TCHAR szDataBuffer[256];
HRESULT hRes = S_OK;
*fWhistler = FALSE;
if(NULL==g_hkeyHKLM)
{
// Connect to the registry if not already done
if(FAILED(hRes = GetConnection(g_arVALOF[_p_CNAME_])))
goto End;
}
if(ERROR_SUCCESS==(hRes=RegOpenKeyEx(g_hkeyHKLM,
_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
0,
KEY_QUERY_VALUE,
&hReg)))
if(ERROR_SUCCESS == (hRes=RegQueryValueEx(hReg,
_T("CurrentBuildNumber"),
NULL,
&nType,
(LPBYTE)szDataBuffer,
&nSize)))
{
if(wcscmp(szDataBuffer,L"2195")>0)
*fWhistler=TRUE;
}
// Print the error message.
if(FAILED(hRes))
PrintFormattedErrorMessage(LONG(hRes));
if(hReg)
RegCloseKey(hReg);
End:
return hRes;
}
BOOL IsSFUInstalled()
{
HKEY hRegistry=NULL;
HKEY hHive=NULL;
DWORD nSize;
char *szDataBuffer;
BOOL fSFU=FALSE;
if(ERROR_SUCCESS == RegConnectRegistry(g_arVALOF[_p_CNAME_],
HKEY_LOCAL_MACHINE,
&hRegistry))
{
if(ERROR_SUCCESS== RegOpenKeyEx(hRegistry,
_T("SOFTWARE\\Microsoft\\Services For UNIX"),
0,
KEY_READ,
&hHive))
fSFU=TRUE;
}
if(hHive)
RegCloseKey(hHive);
if(hRegistry)
RegCloseKey(hRegistry);
return fSFU;
}
//This is only for the display and this will not change the current registry value;
//The value in the registry is retained. (Which is ".")
BOOL setDefaultDomainToLocaldomain(WCHAR wzDomain[])
{
if(S_OK!=GetDomainHostedByThisMc(wzDomain))
return FALSE;
return TRUE;
}
void formatShowSessionsDisplay()
{
int i,temp_count;
int nLen=0;
wchar_t* ppwzSessionInfo=NULL;
unsigned int nMaxDomainFieldLength=0;
unsigned int nMaxUserFieldLength=0;
unsigned int nMaxClientFieldLength=0;
for(i=0;i<g_nNumofSessions;i++)
{
ppwzSessionInfo=_wcsdup(g_ppwzSessionInfo[i]);
wcstok(ppwzSessionInfo,session_data_separator);
WCHAR* wzDomain=wcstok(NULL,session_data_separator);
WCHAR* wzUser=wcstok(NULL,session_data_separator);
WCHAR* wzClient=wcstok(NULL,session_data_separator);
/*
For some strange reason wcstok on : returns NULL if there us an empty string between ::
so any of the above tokens could be NULL
*/
if (wzDomain && (nMaxDomainFieldLength < wcslen(wzDomain)))
{
nMaxDomainFieldLength=wcslen(wzDomain);
}
if (wzUser && (nMaxUserFieldLength < wcslen(wzUser)))
{
nMaxUserFieldLength=wcslen(wzUser);
}
if (wzClient && (nMaxClientFieldLength < wcslen(wzClient)))
{
nMaxClientFieldLength=wcslen(wzClient);
}
free(ppwzSessionInfo);
}
nMaxDomainFieldLength+=2; //adding 2 for spaces (arbit)
nMaxUserFieldLength+=2;
nMaxClientFieldLength+=2;
/// "\n%-3s%-11s%-14s%-11s%-11s%-11s%-4s\n"
/// id domain user client logondate time idletime
/// Hard code to 11 and 14 so that they have a good look
if(nMaxDomainFieldLength < 11)
nMaxDomainFieldLength=11;
if(nMaxUserFieldLength < 14)
nMaxUserFieldLength=14;
if(nMaxClientFieldLength < 11)
nMaxClientFieldLength=11;
_putws(L"\n");
nLen=wcslen(wcscpy(g_szMsg,L"%-6s"));
temp_count = _snwprintf(g_szMsg+nLen, MAX_BUFFER_SIZE-nLen-1,L"%%-%ds%%-%ds%%-%ds",nMaxDomainFieldLength,nMaxUserFieldLength,nMaxClientFieldLength);
if (temp_count < 0) {
return;
}
nLen += temp_count;
wcscpy(g_szMsg+nLen,L"%-22s%-4s\n");
//IDR_SESSION_HEADER_FORMAT
}
//The function queries the registry and returns whether the OS belongs to ServerClass.
BOOL IsServerClass()
{
HKEY hReg=NULL;
DWORD nSize = 256;
DWORD nType=REG_SZ;
TCHAR szDataBuffer[256];
LONG LError;
BOOL fServerClass=FALSE;
if(ERROR_SUCCESS== RegOpenKeyEx(g_hkeyHKLM,
_T("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"),
0,
KEY_QUERY_VALUE,
&hReg))
if(ERROR_SUCCESS == (LError=RegQueryValueEx(hReg,
_T("ProductType"),
NULL,
&nType,
(LPBYTE)szDataBuffer,
&nSize)))
{
if((NULL==_wcsicmp(szDataBuffer,L"ServerNT")) || (NULL == _wcsicmp(szDataBuffer,L"LanmanNT")))
fServerClass=TRUE;
}
if(hReg)
RegCloseKey(hReg);
return fServerClass;
}