1561 lines
42 KiB
C++
1561 lines
42 KiB
C++
|
// Copyright (c) 1998 - 1999 Microsoft Corporation
|
||
|
|
||
|
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include <iostream.h>
|
||
|
#include <fstream.h>
|
||
|
#include <strstrea.h>
|
||
|
#include <dsrole.h>
|
||
|
|
||
|
|
||
|
//
|
||
|
// global utilities and veraibles.
|
||
|
//
|
||
|
|
||
|
char szOutput[2048];
|
||
|
ostrstream szMoreInfo(szOutput, 4096);
|
||
|
|
||
|
|
||
|
TCHAR *ReturnBuffer()
|
||
|
{
|
||
|
static TCHAR szReturnTchar[512];
|
||
|
return szReturnTchar;
|
||
|
}
|
||
|
|
||
|
|
||
|
const OSVERSIONINFOEX *GetOSVersionInfo()
|
||
|
{
|
||
|
static OSVERSIONINFOEX gOsVersion;
|
||
|
static bGotOnce = FALSE;
|
||
|
if (!bGotOnce)
|
||
|
{
|
||
|
ZeroMemory(&gOsVersion, sizeof(OSVERSIONINFOEX));
|
||
|
gOsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||
|
GetVersionEx( (LPOSVERSIONINFO ) &gOsVersion);
|
||
|
bGotOnce = TRUE;
|
||
|
}
|
||
|
|
||
|
return &gOsVersion;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// #include <strstream>
|
||
|
#include "winsock2.h"
|
||
|
|
||
|
|
||
|
// ostringstream sz
|
||
|
|
||
|
#ifndef UNREFERENCED_PARAMETER
|
||
|
#define UNREFERENCED_PARAMETER(P) (P)
|
||
|
#endif
|
||
|
|
||
|
#define OLD_VER_SET_CONDITION(_m_,_t_,_c_) _m_=(_m_|(_c_<<(1<<_t_)))
|
||
|
|
||
|
|
||
|
BOOL CheckifBinaryisSigned (TCHAR *szFile); // from tscert.cpp
|
||
|
BOOL EnumerateLicenseServers (); // from timebomb.cpp
|
||
|
TCHAR *IsBetaSystem ();
|
||
|
BOOL HasLicenceGracePeriodExpired (); // from timebomb.cpp
|
||
|
BOOL ExtractAllTSEvents();
|
||
|
|
||
|
|
||
|
BOOL ValidateProductSuite (LPSTR SuiteName);
|
||
|
BOOL IsTerminalServicesEnabled ( VOID );
|
||
|
DWORD IsStringInMultiString(HKEY hkey, LPCTSTR szkey, LPCTSTR szvalue, LPCTSTR szCheckForString, BOOL *pbFound);
|
||
|
BOOL DoesHydraKeysExists ();
|
||
|
TCHAR *IsServer ();
|
||
|
BOOL IsKernelTSEnable ();
|
||
|
BOOL TSEnabled ();
|
||
|
BOOL DoesProductSuiteContainTS ();
|
||
|
BOOL IsTerminalServerRegistryOk ();
|
||
|
TCHAR *IsTerminalServiceStartBitSet ();
|
||
|
BOOL IsTermDDStartBitSet ();
|
||
|
BOOL GetTSOCLogFileName (char *strFileName, UINT uiSize);
|
||
|
BOOL DidTsOCgetCompleteInstallationMessage ();
|
||
|
BOOL FileExists (char *pszFullNameAndPath);
|
||
|
BOOL IsTSOClogPresent ();
|
||
|
BOOL DidOCMInstallTSEnable();
|
||
|
TCHAR *IsClusteringInstalled ();
|
||
|
BOOL IsRemoteAdminMode ();
|
||
|
BOOL CheckModeRegistry (BOOL bAppCompat);
|
||
|
BOOL IsTerminalServiceRunning ();
|
||
|
BOOL CheckVideoKeys ();
|
||
|
BOOL CheckModePermissions(DWORD *pdwSecurtyMode);
|
||
|
BOOL IsFile128Bit(LPTSTR szFile, BOOL *pb128Bit);
|
||
|
ULONG RDPDRINST_DetectInstall(); // defined in drdetect.cpp
|
||
|
BOOL IsAudioOk( VOID );
|
||
|
|
||
|
|
||
|
TCHAR *aszStack[] = {
|
||
|
// _T("noexport\%SystemRoot%\\system32\\drivers\\rdpwdd.sys"),
|
||
|
_T("%SystemRoot%\\system32\\drivers\\termdd.sys"),
|
||
|
_T("%SystemRoot%\\system32\\drivers\\tdasync.sys"),
|
||
|
_T("%SystemRoot%\\system32\\drivers\\tdipx.sys"),
|
||
|
_T("%SystemRoot%\\system32\\drivers\\tdnetb.sys"),
|
||
|
_T("%SystemRoot%\\system32\\drivers\\tdpipe.sys"),
|
||
|
_T("%SystemRoot%\\system32\\drivers\\tdspx.sys"),
|
||
|
_T("%SystemRoot%\\system32\\drivers\\tdtcp.sys"),
|
||
|
_T("%SystemRoot%\\system32\\drivers\\rdpwd.sys"),
|
||
|
_T("%SystemRoot%\\system32\\rdpdd.dll"),
|
||
|
_T("%SystemRoot%\\system32\\rdpwsx.dll")
|
||
|
};
|
||
|
|
||
|
TCHAR Version[256];
|
||
|
TCHAR *GetTSVersion()
|
||
|
{
|
||
|
CRegistry oRegTermsrv;
|
||
|
DWORD cbVersion = 0;
|
||
|
LPTSTR szVersion = NULL;
|
||
|
|
||
|
if ((ERROR_SUCCESS == oRegTermsrv.OpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"), KEY_READ)) &&
|
||
|
(ERROR_SUCCESS == oRegTermsrv.ReadRegString(_T("ProductVersion"), &szVersion, &cbVersion)))
|
||
|
{
|
||
|
_tcscpy(Version, szVersion);
|
||
|
return Version;
|
||
|
}
|
||
|
|
||
|
return _T("Error finding Version.");
|
||
|
}
|
||
|
|
||
|
BOOL IsIt50TS()
|
||
|
{
|
||
|
return (0 == _tcsicmp(Version, _T("5.0")));
|
||
|
}
|
||
|
|
||
|
BOOL IsIt51TS()
|
||
|
{
|
||
|
return (0 == _tcsicmp(Version, _T("5.1")));
|
||
|
}
|
||
|
|
||
|
|
||
|
TCHAR *IsLicenceGracePeriodOk ()
|
||
|
{
|
||
|
return (HasLicenceGracePeriodExpired () ? _T("Yep, Its expired") : _T("Its Not expired"));
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL Check_termdd()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\drivers\\termdd.sys"));
|
||
|
}
|
||
|
BOOL Check_tdasync()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\drivers\\tdasync.sys"));
|
||
|
}
|
||
|
BOOL Check_tdipx()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\drivers\\tdipx.sys"));
|
||
|
}
|
||
|
BOOL Check_tdnetb()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\drivers\\tdnetb.sys"));
|
||
|
}
|
||
|
BOOL Check_tdpipe()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\drivers\\tdpipe.sys"));
|
||
|
}
|
||
|
BOOL Check_tdspx()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\drivers\\tdspx.sys"));
|
||
|
}
|
||
|
BOOL Check_tdtcp()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\drivers\\tdtcp.sys"));
|
||
|
}
|
||
|
BOOL Check_rdpwd()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\drivers\\rdpwd.sys"));
|
||
|
}
|
||
|
BOOL Check_rdpdd()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\rdpdd.dll"));
|
||
|
}
|
||
|
BOOL Check_rdpwsx()
|
||
|
{
|
||
|
return CheckifBinaryisSigned(_T("%SystemRoot%\\system32\\rdpwsx.dll"));
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL IsRdpDrInstalledProperly ()
|
||
|
{
|
||
|
return RDPDRINST_DetectInstall();
|
||
|
}
|
||
|
|
||
|
|
||
|
TCHAR *GetModePermissions()
|
||
|
{
|
||
|
CRegistry reg;
|
||
|
DWORD dwSecurityMode;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"), KEY_READ))
|
||
|
{
|
||
|
if ( ERROR_SUCCESS == reg.ReadRegDWord( _T("TSUserEnabled"), &dwSecurityMode))
|
||
|
{
|
||
|
if (dwSecurityMode == 0)
|
||
|
{
|
||
|
return _T("Its W2k Compatible");
|
||
|
}
|
||
|
else if (dwSecurityMode == 1)
|
||
|
{
|
||
|
return _T("Its TS4 Compatible");
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "SYSTEM\\CurrentControlSet\\Control\\Terminal Server/TSUserEnabled has wrong value" << dwSecurityMode << endl;
|
||
|
return NULL;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL CheckModePermissions (DWORD *pdwSecurtyMode)
|
||
|
{
|
||
|
// PERM_WIN2K = 0,
|
||
|
// PERM_TS4 = 1
|
||
|
|
||
|
CRegistry reg;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"), KEY_READ))
|
||
|
{
|
||
|
if ( ERROR_SUCCESS == reg.ReadRegDWord( _T("TSUserEnabled"), pdwSecurtyMode))
|
||
|
{
|
||
|
return (*pdwSecurtyMode== 0) || (*pdwSecurtyMode== 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
TCHAR *GetCypherStrenthOnRdpwd ()
|
||
|
{
|
||
|
BOOL bFile128bit;
|
||
|
if ( IsFile128Bit(_T("%SystemRoot%\\system32\\drivers\\rdpwd.sys"), &bFile128bit) )
|
||
|
{
|
||
|
return bFile128bit ? _T("128 Bit") : _T("56 Bit");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL IsFile128Bit(LPTSTR szFile, BOOL *pb128Bit)
|
||
|
{
|
||
|
USES_CONVERSION;
|
||
|
DWORD dwHandle;
|
||
|
|
||
|
TCHAR szFullFile[MAX_PATH +1];
|
||
|
|
||
|
BOOL bSuccess = FALSE;
|
||
|
|
||
|
if (ExpandEnvironmentStrings(szFile, szFullFile, MAX_PATH))
|
||
|
{
|
||
|
if (FileExists(T2A(szFullFile)))
|
||
|
{
|
||
|
DWORD dwSize = GetFileVersionInfoSize(szFullFile, &dwHandle);
|
||
|
if (dwSize > 0)
|
||
|
{
|
||
|
BYTE *pbData = new BYTE[dwSize];
|
||
|
if (pbData)
|
||
|
{
|
||
|
if (GetFileVersionInfo(szFullFile, 0, dwSize, pbData))
|
||
|
{
|
||
|
TCHAR *szFileDescription;
|
||
|
UINT uiLen = 0;
|
||
|
if (VerQueryValue(pbData, _T("\\StringFileInfo\\040904B0\\FileDescription"), (LPVOID *)&szFileDescription, &uiLen))
|
||
|
{
|
||
|
if (_tcsstr(szFileDescription, _T("Not for Export")))
|
||
|
{
|
||
|
*pb128Bit = TRUE;
|
||
|
bSuccess = TRUE;
|
||
|
|
||
|
}
|
||
|
else if (_tcsstr(szFileDescription, _T("Export Version")))
|
||
|
{
|
||
|
*pb128Bit = FALSE;
|
||
|
bSuccess = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delete [] pbData;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bSuccess;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL ValidateProductSuite (LPSTR SuiteName)
|
||
|
{
|
||
|
BOOL rVal = FALSE;
|
||
|
LONG Rslt;
|
||
|
HKEY hKey = NULL;
|
||
|
DWORD Type = 0;
|
||
|
DWORD Size = 0;
|
||
|
LPSTR ProductSuite = NULL;
|
||
|
LPSTR p;
|
||
|
|
||
|
Rslt = RegOpenKeyA(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
"System\\CurrentControlSet\\Control\\ProductOptions",
|
||
|
&hKey
|
||
|
);
|
||
|
|
||
|
if (Rslt != ERROR_SUCCESS)
|
||
|
goto exit;
|
||
|
|
||
|
Rslt = RegQueryValueExA( hKey, "ProductSuite", NULL, &Type, NULL, &Size );
|
||
|
if (Rslt != ERROR_SUCCESS || !Size)
|
||
|
goto exit;
|
||
|
|
||
|
ProductSuite = (LPSTR) LocalAlloc( LPTR, Size );
|
||
|
if (!ProductSuite)
|
||
|
goto exit;
|
||
|
|
||
|
Rslt = RegQueryValueExA( hKey, "ProductSuite", NULL, &Type,
|
||
|
(LPBYTE) ProductSuite, &Size );
|
||
|
if (Rslt != ERROR_SUCCESS || Type != REG_MULTI_SZ)
|
||
|
goto exit;
|
||
|
|
||
|
p = ProductSuite;
|
||
|
while (*p)
|
||
|
{
|
||
|
if (lstrcmpA( p, SuiteName ) == 0)
|
||
|
{
|
||
|
rVal = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
p += (lstrlenA( p ) + 1);
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
if (ProductSuite)
|
||
|
LocalFree( ProductSuite );
|
||
|
|
||
|
if (hKey)
|
||
|
RegCloseKey( hKey );
|
||
|
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL IsTerminalServicesEnabled( VOID )
|
||
|
{
|
||
|
BOOL bResult = FALSE;
|
||
|
DWORD dwVersion;
|
||
|
OSVERSIONINFOEXA osVersionInfo;
|
||
|
DWORDLONG dwlConditionMask = 0;
|
||
|
HMODULE hmodK32 = NULL;
|
||
|
typedef ULONGLONG (*PFnVerSetConditionMask) ( ULONGLONG, ULONG, UCHAR );
|
||
|
typedef BOOL (*PFnVerifyVersionInfoA) (POSVERSIONINFOEXA, DWORD, DWORDLONG);
|
||
|
PFnVerSetConditionMask pfnVerSetConditionMask;
|
||
|
PFnVerifyVersionInfoA pfnVerifyVersionInfoA;
|
||
|
|
||
|
|
||
|
dwVersion = GetVersion();
|
||
|
|
||
|
/* are we running NT ? */
|
||
|
if (!(dwVersion & 0x80000000))
|
||
|
{
|
||
|
// Is it NT 50 or greater ?
|
||
|
if (LOBYTE(LOWORD(dwVersion)) > 4)
|
||
|
{
|
||
|
/* In NT5 we need to use the Product Suite APIs
|
||
|
Don't static link because it won't load on non-NT5 systems */
|
||
|
|
||
|
hmodK32 = GetModuleHandleA( "KERNEL32.DLL" );
|
||
|
if (hmodK32)
|
||
|
{
|
||
|
pfnVerSetConditionMask = (PFnVerSetConditionMask )GetProcAddress( hmodK32, "VerSetConditionMask");
|
||
|
|
||
|
if (pfnVerSetConditionMask)
|
||
|
{
|
||
|
/* get the condition mask. */
|
||
|
dwlConditionMask = (*pfnVerSetConditionMask)(dwlConditionMask, VER_SUITENAME, VER_AND);
|
||
|
|
||
|
pfnVerifyVersionInfoA = (PFnVerifyVersionInfoA)GetProcAddress( hmodK32, "VerifyVersionInfoA") ;
|
||
|
|
||
|
if (pfnVerifyVersionInfoA != NULL)
|
||
|
{
|
||
|
|
||
|
ZeroMemory(&osVersionInfo, sizeof(osVersionInfo));
|
||
|
osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo);
|
||
|
osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
|
||
|
bResult = (*pfnVerifyVersionInfoA)(
|
||
|
&osVersionInfo,
|
||
|
VER_SUITENAME,
|
||
|
dwlConditionMask);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* This is NT 40 */
|
||
|
bResult = ValidateProductSuite( "Terminal Server" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
/*--------------------------------------------------------------------------------------------------------
|
||
|
* DWORD IsStringInMultiString(HKEY hkey, LPCTSTR szkey, LPCTSTR szvalue, LPCTSTR szCheckForString, BOOL *pbFound)
|
||
|
* checks if parameter string exists in given multistring.
|
||
|
* returns error code.
|
||
|
* -------------------------------------------------------------------------------------------------------*/
|
||
|
DWORD IsStringInMultiString(HKEY hkey, LPCTSTR szkey, LPCTSTR szvalue, LPCTSTR szCheckForString, BOOL *pbFound)
|
||
|
{
|
||
|
ASSERT(szkey && *szkey);
|
||
|
ASSERT(szvalue && *szvalue);
|
||
|
ASSERT(szCheckForString&& *szCheckForString);
|
||
|
ASSERT(*szkey != '\\');
|
||
|
ASSERT(pbFound);
|
||
|
|
||
|
// not yet found.
|
||
|
*pbFound = FALSE;
|
||
|
|
||
|
CRegistry reg;
|
||
|
DWORD dwError = reg.OpenKey(hkey, szkey, KEY_READ); // open up the required key.
|
||
|
if (dwError == NO_ERROR)
|
||
|
{
|
||
|
LPTSTR szSuiteValue;
|
||
|
DWORD dwSize;
|
||
|
dwError = reg.ReadRegMultiString(szvalue, &szSuiteValue, &dwSize);
|
||
|
if (dwError == NO_ERROR)
|
||
|
{
|
||
|
LPCTSTR pTemp = szSuiteValue;
|
||
|
while(_tcslen(pTemp) > 0 )
|
||
|
{
|
||
|
if (_tcscmp(pTemp, szCheckForString) == 0)
|
||
|
{
|
||
|
*pbFound = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
pTemp += _tcslen(pTemp) + 1; // point to the next string within the multistring.
|
||
|
if ( DWORD(pTemp - szSuiteValue) > (dwSize / sizeof(TCHAR)))
|
||
|
break; // temporary pointer passes the size of the szSuiteValue something is wrong with szSuiteValue.
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return dwError;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL DoesHydraKeysExists()
|
||
|
{
|
||
|
BOOL bStringExists = FALSE;
|
||
|
DWORD dw = IsStringInMultiString(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
_T("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"),
|
||
|
_T("ProductSuite"),
|
||
|
_T("Terminal Server"),
|
||
|
&bStringExists);
|
||
|
|
||
|
return (dw == ERROR_SUCCESS) && bStringExists;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
TCHAR *IsItAppServer ()
|
||
|
{
|
||
|
return ((GetOSVersionInfo()->wSuiteMask & VER_SUITE_TERMINAL) &&
|
||
|
!(GetOSVersionInfo()->wSuiteMask & VER_SUITE_SINGLEUSERTS)) ? _T("Yes") : _T("No");
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL IsItServer ()
|
||
|
{
|
||
|
return GetOSVersionInfo()->wProductType != VER_NT_WORKSTATION;
|
||
|
}
|
||
|
|
||
|
|
||
|
TCHAR *GetProductType ()
|
||
|
{
|
||
|
BYTE wProductType = GetOSVersionInfo()->wProductType;
|
||
|
_tcscpy(ReturnBuffer(), _T(""));
|
||
|
|
||
|
if (wProductType == VER_NT_WORKSTATION)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_NT_WORKSTATION "));
|
||
|
}
|
||
|
|
||
|
if (wProductType == VER_NT_DOMAIN_CONTROLLER)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_NT_DOMAIN_CONTROLLER"));
|
||
|
}
|
||
|
|
||
|
if (wProductType == VER_NT_SERVER)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_NT_SERVER"));
|
||
|
}
|
||
|
|
||
|
return ReturnBuffer();
|
||
|
|
||
|
}
|
||
|
|
||
|
TCHAR *GetProductSuite ()
|
||
|
{
|
||
|
WORD wProductSuite = GetOSVersionInfo()->wSuiteMask;
|
||
|
_tcscpy(ReturnBuffer(), _T(""));
|
||
|
|
||
|
if (wProductSuite & VER_SERVER_NT)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SERVER_NT "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_WORKSTATION_NT)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_WORKSTATION_NT "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_SMALLBUSINESS)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_SMALLBUSINESS "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_ENTERPRISE)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_ENTERPRISE "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_BACKOFFICE)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_BACKOFFICE "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_COMMUNICATIONS)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_COMMUNICATIONS "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_TERMINAL)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_TERMINAL "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_SMALLBUSINESS_RESTRICTED)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_SMALLBUSINESS_RESTRICTED "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_EMBEDDEDNT)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_EMBEDDEDNT "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_DATACENTER)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_DATACENTER "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_SINGLEUSERTS)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_SINGLEUSERTS "));
|
||
|
|
||
|
}
|
||
|
if (wProductSuite & VER_SUITE_PERSONAL)
|
||
|
{
|
||
|
_tcscat(ReturnBuffer(), _T("VER_SUITE_PERSONAL "));
|
||
|
|
||
|
}
|
||
|
return ReturnBuffer();
|
||
|
}
|
||
|
|
||
|
|
||
|
TCHAR *IsServer ()
|
||
|
{
|
||
|
return IsItServer() ? _T("Its a Server") : _T("Its a WorkStation");
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL IsKernelTSEnable ()
|
||
|
{
|
||
|
return IsTerminalServicesEnabled();
|
||
|
}
|
||
|
|
||
|
BOOL TSEnabled ()
|
||
|
{
|
||
|
|
||
|
CRegistry reg;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"), KEY_READ))
|
||
|
{
|
||
|
DWORD dwTSEnabled = 0;
|
||
|
if ( ERROR_SUCCESS == reg.ReadRegDWord( _T("TSEnabled"), &dwTSEnabled))
|
||
|
{
|
||
|
return dwTSEnabled == 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL DoesProductSuiteContainTS ()
|
||
|
{
|
||
|
return DoesHydraKeysExists ();
|
||
|
}
|
||
|
|
||
|
BOOL IsTerminalServerRegistryOk ()
|
||
|
{
|
||
|
CRegistry reg1;
|
||
|
CRegistry reg2;
|
||
|
CRegistry reg3;
|
||
|
|
||
|
return
|
||
|
(ERROR_SUCCESS == reg1.OpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"), KEY_READ)) &&
|
||
|
(ERROR_SUCCESS == reg2.OpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations"), KEY_READ)) &&
|
||
|
(ERROR_SUCCESS == reg3.OpenKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server"), KEY_READ));
|
||
|
}
|
||
|
|
||
|
TCHAR *GetWinstationList ()
|
||
|
{
|
||
|
TCHAR szWinstationList[256];
|
||
|
BOOL bFoundNonConsoleWinstation = FALSE;
|
||
|
_tcscpy(szWinstationList, _T(""));
|
||
|
CRegistry reg2;
|
||
|
if (ERROR_SUCCESS == reg2.OpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations"), KEY_READ))
|
||
|
{
|
||
|
LPTSTR szWinstation;
|
||
|
DWORD dwSize;
|
||
|
BOOL bFirst = TRUE;
|
||
|
|
||
|
if (ERROR_SUCCESS == reg2.GetFirstSubKey(&szWinstation, &dwSize))
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
if (0 != _tcsicmp(szWinstation, _T("Console")))
|
||
|
{
|
||
|
bFoundNonConsoleWinstation = TRUE;
|
||
|
}
|
||
|
|
||
|
if (!bFirst)
|
||
|
{
|
||
|
_tcscat(szWinstationList, _T(", "));
|
||
|
}
|
||
|
|
||
|
_tcscat(szWinstationList, szWinstation);
|
||
|
bFirst = FALSE;
|
||
|
}
|
||
|
while (ERROR_SUCCESS == reg2.GetNextSubKey(&szWinstation, &dwSize));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (_tcslen(szWinstationList) == 0)
|
||
|
{
|
||
|
_tcscpy(szWinstationList, _T("Error, No winstations found."));
|
||
|
}
|
||
|
|
||
|
if (!bFoundNonConsoleWinstation)
|
||
|
{
|
||
|
szMoreInfo << "ERROR, No non Console Winstation not found" << endl;
|
||
|
}
|
||
|
|
||
|
_tcscpy(ReturnBuffer(), szWinstationList);
|
||
|
return ReturnBuffer();
|
||
|
|
||
|
}
|
||
|
|
||
|
TCHAR *IsTerminalServiceStartBitSet ()
|
||
|
{
|
||
|
|
||
|
CRegistry reg;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\TermService"), KEY_READ))
|
||
|
{
|
||
|
DWORD dwTermServStartBit = 0;
|
||
|
if ( ERROR_SUCCESS == reg.ReadRegDWord( _T("Start"), &dwTermServStartBit))
|
||
|
{
|
||
|
switch (dwTermServStartBit)
|
||
|
{
|
||
|
case 2:
|
||
|
return _T("AutoStart");
|
||
|
break;
|
||
|
|
||
|
case 3:
|
||
|
return _T("Manual Start");
|
||
|
break;
|
||
|
|
||
|
case 4:
|
||
|
return _T("Error, Disabled");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return _T("ERROR:Wrong value for startbit");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return _T("Error, Reading startbig");
|
||
|
}
|
||
|
|
||
|
BOOL IsTermDDStartBitSet ()
|
||
|
{
|
||
|
CRegistry reg;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\TermDD"), KEY_READ))
|
||
|
{
|
||
|
DWORD dwTermDDStartBit = 0;
|
||
|
if ( ERROR_SUCCESS == reg.ReadRegDWord( _T("Start"), &dwTermDDStartBit))
|
||
|
{
|
||
|
return dwTermDDStartBit == 2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
TCHAR *AreEffectiveConnectionAllowed ()
|
||
|
{
|
||
|
HMODULE hmodRegAPI = LoadLibrary( _T("RegApi.dll") );
|
||
|
|
||
|
if (hmodRegAPI)
|
||
|
{
|
||
|
|
||
|
typedef BOOLEAN (*PFDenyConnectionPolicy) ();
|
||
|
PFDenyConnectionPolicy pfnDenyConnectionPolicy;
|
||
|
|
||
|
pfnDenyConnectionPolicy = (PFDenyConnectionPolicy) GetProcAddress( hmodRegAPI, "RegDenyTSConnectionsPolicy");
|
||
|
if (pfnDenyConnectionPolicy)
|
||
|
{
|
||
|
return (*pfnDenyConnectionPolicy)() ? _T("Not Allowed") : _T("Allowed");
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "Failed to get proc RegDenyTSConnectionsPolicy" << endl;
|
||
|
return _T("Failed");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "Failed to Load regapi.dll" << endl;
|
||
|
return _T("Failed");
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
TCHAR *AreConnectionsAllowed ()
|
||
|
{
|
||
|
DWORD dwError;
|
||
|
CRegistry oRegTermsrv;
|
||
|
|
||
|
dwError = oRegTermsrv.OpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"), KEY_READ);
|
||
|
if (ERROR_SUCCESS == dwError)
|
||
|
{
|
||
|
DWORD dwDenyConnect;
|
||
|
dwError = oRegTermsrv.ReadRegDWord(_T("fDenyTSConnections"), &dwDenyConnect);
|
||
|
if (ERROR_SUCCESS == dwError)
|
||
|
{
|
||
|
return dwDenyConnect ? _T("No, Not allowed") : _T("Yes");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// could not read registry, It means - for 51 connection not allowed. For 50 Connections allowed.
|
||
|
//
|
||
|
|
||
|
return IsIt51TS() ? _T("Error, Value not found") : _T("Yes");
|
||
|
}
|
||
|
|
||
|
BOOL GetTSOCLogFileName(char *strFileName, UINT uiSize)
|
||
|
{
|
||
|
if (!GetSystemWindowsDirectoryA(strFileName, uiSize))
|
||
|
return FALSE;
|
||
|
|
||
|
strcat(strFileName, "\\tsoc.log");
|
||
|
ASSERT(strlen(strFileName) < uiSize);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
char *IncompleteMessage = "Error:TSOC Did not get OC_COMPLETE_INSTALLATION.";
|
||
|
BOOL DidTsOCgetCompleteInstallationMessage ()
|
||
|
{
|
||
|
|
||
|
if (!IsTSOClogPresent())
|
||
|
{
|
||
|
szMoreInfo << "tsoc.log does not exist." << endl;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
char strTSOCLog[256];
|
||
|
GetTSOCLogFileName(strTSOCLog, 256);
|
||
|
|
||
|
ifstream ifSrc(strTSOCLog);
|
||
|
if(!ifSrc)
|
||
|
{
|
||
|
szMoreInfo << "Failed to open tsoc.log file." << endl;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
char tempSrc[256];
|
||
|
while(!ifSrc.eof())
|
||
|
{
|
||
|
ifSrc.getline(tempSrc, 256);
|
||
|
if (strstr(tempSrc, IncompleteMessage))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL FileExists(char *pszFullNameAndPath)
|
||
|
{
|
||
|
ASSERT(pszFullNameAndPath);
|
||
|
|
||
|
if (pszFullNameAndPath && pszFullNameAndPath[0])
|
||
|
{
|
||
|
HANDLE hFile = CreateFileA(pszFullNameAndPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
|
||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
CloseHandle(hFile);
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL IsTSOClogPresent ()
|
||
|
{
|
||
|
char strTSOCLog[256];
|
||
|
GetTSOCLogFileName(strTSOCLog, 256);
|
||
|
return FileExists(strTSOCLog);
|
||
|
}
|
||
|
|
||
|
BOOL DidOCMInstallTSEnable()
|
||
|
{
|
||
|
CRegistry reg;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\SubComponents"), KEY_READ))
|
||
|
{
|
||
|
DWORD dwTSEnabled = 0;
|
||
|
if ( ERROR_SUCCESS == reg.ReadRegDWord( _T("tsenable"), &dwTSEnabled))
|
||
|
{
|
||
|
return dwTSEnabled == 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
TCHAR *IsClusteringInstalled ()
|
||
|
{
|
||
|
DWORD dwClusterState;
|
||
|
if (ERROR_SUCCESS == GetNodeClusterState(NULL, &dwClusterState))
|
||
|
{
|
||
|
if (dwClusterState != ClusterStateNotInstalled)
|
||
|
{
|
||
|
return _T("***Failed. Clustering is installed, this is not compatible with Terminal Server.");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return _T("Passed");
|
||
|
}
|
||
|
|
||
|
|
||
|
TCHAR *GetTSMode (void)
|
||
|
{
|
||
|
return IsRemoteAdminMode() ? _T("Remote Admin") : _T("Application Server");
|
||
|
}
|
||
|
|
||
|
BOOL IsRemoteAdminMode ()
|
||
|
{
|
||
|
// HKLM ,"SYSTEM\CurrentControlSet\Control\Terminal Server","TSAppCompat",0x00010001,0x0
|
||
|
CRegistry reg;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"), KEY_READ))
|
||
|
{
|
||
|
DWORD dwAppCompat = 1;
|
||
|
if ( ERROR_SUCCESS == reg.ReadRegDWord( _T("TSAppCompat"), &dwAppCompat))
|
||
|
{
|
||
|
return dwAppCompat == 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// if the registry TSAppCompat does not exist it means we are in app server mode.
|
||
|
return FALSE;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "ERROR:SYSTEM\\CurrentControlSet\\Control\\Terminal Server not found!" << endl;
|
||
|
}
|
||
|
|
||
|
// this return is bogus.
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL VerifyModeRegistry()
|
||
|
{
|
||
|
return CheckModeRegistry(!IsRemoteAdminMode());
|
||
|
}
|
||
|
|
||
|
BOOL CheckModeRegistry (BOOL bAppCompat)
|
||
|
{
|
||
|
USES_CONVERSION;
|
||
|
BOOL bOk = TRUE;
|
||
|
|
||
|
CRegistry reg;
|
||
|
|
||
|
if (IsItServer())
|
||
|
{
|
||
|
CRegistry reg1;
|
||
|
|
||
|
// check registry value
|
||
|
// for appcompat mode
|
||
|
//HKLM ,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","AppSetup",0x00000000,"UsrLogon.Cmd"
|
||
|
// and for remote admin mode
|
||
|
//HKLM ,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","AppSetup",0x00000000,""
|
||
|
|
||
|
|
||
|
if ( ERROR_SUCCESS == reg1.OpenKey( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), KEY_READ))
|
||
|
{
|
||
|
LPTSTR str;
|
||
|
DWORD dwSize;
|
||
|
if (ERROR_SUCCESS == reg1.ReadRegString(_T("AppSetup"), &str, &dwSize))
|
||
|
{
|
||
|
if (bAppCompat)
|
||
|
{
|
||
|
if (_tcsicmp(str, _T("UsrLogon.Cmd")) != 0)
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR: Wrong value (" << T2A(str) << ") for AppSetup, contact makarp/breenh" << endl;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (_tcslen(str) != 0)
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR: Wrong value (" << T2A(str) << ") for AppSetup, contact makarp/breenh" << endl;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "ERROR reading appsetup registry" << endl;
|
||
|
bOk = FALSE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "ERROR:reading SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon" << endl;
|
||
|
bOk = FALSE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// check registry value
|
||
|
// for appcompat mode
|
||
|
//HKLM ,"SYSTEM\CurrentControlSet\Control\PriorityControl","Win32PrioritySeparation", 0x00010001,0x26
|
||
|
// and for remote admin mode
|
||
|
//HKLM ,"SYSTEM\CurrentControlSet\Control\PriorityControl","Win32PrioritySeparation", 0x00010001,0x18
|
||
|
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\PriorityControl"), KEY_READ))
|
||
|
{
|
||
|
DWORD dwPriority;
|
||
|
if (ERROR_SUCCESS == reg.ReadRegDWord(_T("Win32PrioritySeparation"), &dwPriority))
|
||
|
{
|
||
|
if (bAppCompat)
|
||
|
{
|
||
|
if (0x26 != dwPriority)
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR: Wrong Win32PrioritySeparation (" << dwPriority << ")" << endl;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else if (IsItServer())
|
||
|
{
|
||
|
if (0x18 != dwPriority)
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR: Wrong Win32PrioritySeparation (" << dwPriority << ")" << endl;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR:Reading Win32PrioritySeparation registry" << endl;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR:Reading PriorityControl registry" << endl;
|
||
|
}
|
||
|
|
||
|
|
||
|
// check registry value
|
||
|
// for appcompat mode
|
||
|
//HKLM ,"SYSTEM\CurrentControlSet\Control\Terminal Server","IdleWinStationPoolCount",0x00010001,0x2
|
||
|
// and for remote admin mode
|
||
|
//HKLM ,"SYSTEM\CurrentControlSet\Control\Terminal Server","IdleWinStationPoolCount",0x00010001,0x0
|
||
|
|
||
|
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"), KEY_READ))
|
||
|
{
|
||
|
DWORD dwIdleWinstations;
|
||
|
if (ERROR_SUCCESS == reg.ReadRegDWord(_T("IdleWinStationPoolCount"), &dwIdleWinstations))
|
||
|
{
|
||
|
if (bAppCompat)
|
||
|
{
|
||
|
if (0x2 != dwIdleWinstations)
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR: Wrong IdleWinStationPoolCount (" << dwIdleWinstations << ")" << endl;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (0 != dwIdleWinstations)
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR: Wrong IdleWinStationPoolCount (" << dwIdleWinstations << ")" << endl;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "ERROR:Reading IdleWinStationPoolCount registry" << endl;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bOk = FALSE;
|
||
|
szMoreInfo << "SYSTEM\\CurrentControlSet\\Control\\Terminal Server" << endl;
|
||
|
}
|
||
|
|
||
|
return bOk;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL IsTerminalServiceRunning ()
|
||
|
{
|
||
|
|
||
|
BOOL bReturn = FALSE;
|
||
|
|
||
|
SC_HANDLE hServiceController = OpenSCManager(NULL, NULL, GENERIC_READ);
|
||
|
if (hServiceController)
|
||
|
{
|
||
|
|
||
|
SC_HANDLE hTermServ = OpenService(hServiceController, _T("TermService"), SERVICE_QUERY_STATUS);
|
||
|
if (hTermServ)
|
||
|
{
|
||
|
SERVICE_STATUS tTermServStatus;
|
||
|
if (QueryServiceStatus(hTermServ, &tTermServStatus))
|
||
|
{
|
||
|
bReturn = (tTermServStatus.dwCurrentState == SERVICE_RUNNING);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "Failed to get service status, Error = " << GetLastError() << endl;
|
||
|
|
||
|
}
|
||
|
|
||
|
VERIFY(CloseServiceHandle(hTermServ));
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "Failed to open TermServ service, Error = " << GetLastError() << endl;
|
||
|
}
|
||
|
|
||
|
VERIFY(CloseServiceHandle(hServiceController));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "Failed to Open Service Controller, Error = " << GetLastError() << endl;
|
||
|
}
|
||
|
|
||
|
return bReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CheckVideoKeys ()
|
||
|
{
|
||
|
// HKLM ,"SYSTEM\CurrentControlSet\Control\Terminal Server\VIDEO\rdpdd","VgaCompatible",0x00000000,"\Device\Video0"
|
||
|
// HKLM ,"SYSTEM\CurrentControlSet\Control\Terminal Server\VIDEO\rdpdd","\Device\Video0",0x00000000,"\REGISTRY\Machine\System\ControlSet001\Services\RDPDD\Device0"
|
||
|
|
||
|
CRegistry reg;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\VIDEO\\rdpdd"), KEY_READ))
|
||
|
{
|
||
|
LPTSTR str = 0;
|
||
|
DWORD dwSize = 0;
|
||
|
if (ERROR_SUCCESS == reg.ReadRegString(_T("VgaCompatible"), &str, &dwSize))
|
||
|
{
|
||
|
if (0 == _tcsicmp(str, _T("\\Device\\Video0")))
|
||
|
{
|
||
|
if (ERROR_SUCCESS == reg.ReadRegString(_T("\\Device\\Video0"), &str, &dwSize))
|
||
|
{
|
||
|
if ((0 == _tcsicmp(str, _T("\\REGISTRY\\Machine\\System\\ControlSet001\\Services\\RDPDD\\Device0"))) ||
|
||
|
(0 == _tcsicmp(str, _T("\\REGISTRY\\Machine\\System\\CurrentControlSet\\Services\\RDPDD\\Device0"))))
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
TCHAR szCompName[256];
|
||
|
TCHAR *GetCompName ()
|
||
|
{
|
||
|
DWORD dwCompName = 256;
|
||
|
|
||
|
if (GetComputerName(szCompName, &dwCompName))
|
||
|
{
|
||
|
return szCompName;
|
||
|
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
TCHAR szDomNameWorkgroup[] = _T("<Workgroup>");
|
||
|
TCHAR szDomNameUnknown[] = _T("<Unknown>");
|
||
|
TCHAR *GetDomName ()
|
||
|
{
|
||
|
DSROLE_PRIMARY_DOMAIN_INFO_BASIC *pDomainInfo = NULL;
|
||
|
DWORD dwErr;
|
||
|
|
||
|
//
|
||
|
// Check if we're in a workgroup
|
||
|
//
|
||
|
dwErr = DsRoleGetPrimaryDomainInformation(NULL,
|
||
|
DsRolePrimaryDomainInfoBasic,
|
||
|
(PBYTE *) &pDomainInfo);
|
||
|
|
||
|
if (ERROR_SUCCESS != dwErr)
|
||
|
return szDomNameUnknown;
|
||
|
|
||
|
switch (pDomainInfo->MachineRole)
|
||
|
{
|
||
|
case DsRole_RoleStandaloneWorkstation:
|
||
|
case DsRole_RoleStandaloneServer:
|
||
|
return szDomNameWorkgroup;
|
||
|
break; // just in case
|
||
|
}
|
||
|
|
||
|
if (pDomainInfo->DomainNameFlat)
|
||
|
return pDomainInfo->DomainNameFlat;
|
||
|
else if (pDomainInfo->DomainNameDns)
|
||
|
return pDomainInfo->DomainNameDns;
|
||
|
else
|
||
|
return szDomNameUnknown;
|
||
|
}
|
||
|
|
||
|
WCHAR wszIPAddress[128] = L"<error>";
|
||
|
TCHAR *GetIPAddress ()
|
||
|
{
|
||
|
//get host address
|
||
|
WORD wVersionRequested = MAKEWORD( 1, 1 );
|
||
|
WSADATA wsaData;
|
||
|
if (0 == WSAStartup(wVersionRequested,&wsaData))
|
||
|
{
|
||
|
char szHostName[256];
|
||
|
|
||
|
if (0 == gethostname ( szHostName , 256 ))
|
||
|
{
|
||
|
hostent *h;
|
||
|
if (NULL != (h=gethostbyname ( szHostName )))
|
||
|
{
|
||
|
in_addr *inaddr=(struct in_addr *)*h->h_addr_list;
|
||
|
|
||
|
MultiByteToWideChar(CP_ACP,0,inet_ntoa(*inaddr),-1,wszIPAddress,128);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return wszIPAddress;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
TCHAR *IsRDPNPinNetProviders ()
|
||
|
{
|
||
|
TCHAR NEWORK_PROVIDER_ORDER_KEY[] = _T("SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order");
|
||
|
TCHAR PROVIDER_ORDER_VALUE[] = _T("ProviderOrder");
|
||
|
TCHAR RDPNP_ENTRY[] = _T("RDPNP");
|
||
|
BOOL bRdpNpExists = FALSE;
|
||
|
|
||
|
// read network privider key.
|
||
|
CRegistry regNetOrder;
|
||
|
LPTSTR szOldValue;
|
||
|
DWORD dwSize;
|
||
|
if ((ERROR_SUCCESS == regNetOrder.OpenKey(HKEY_LOCAL_MACHINE, NEWORK_PROVIDER_ORDER_KEY), KEY_READ) &&
|
||
|
(ERROR_SUCCESS == regNetOrder.ReadRegString(PROVIDER_ORDER_VALUE, &szOldValue, &dwSize)))
|
||
|
{
|
||
|
bRdpNpExists = (_tcsstr(szOldValue, RDPNP_ENTRY) != NULL);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (TSEnabled () == bRdpNpExists)
|
||
|
{
|
||
|
return (_T("Passed"));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (bRdpNpExists)
|
||
|
{
|
||
|
return _T("Error: RDPNP, exists in ProviderOrder, but TS is disabled!");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (IsIt50TS())
|
||
|
{
|
||
|
// rdp np is only for 51+ so its ok if its missing for 50.
|
||
|
return _T("Passed");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _T("ERROR, RDPNP is missing from ProviderOrder");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
TCHAR *IsMultiConnectionAllowed ()
|
||
|
{
|
||
|
// SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","AllowMultipleTSSessions
|
||
|
CRegistry regWL;
|
||
|
DWORD dwAllowMultipal;
|
||
|
if ((ERROR_SUCCESS == regWL.OpenKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), KEY_READ)) &&
|
||
|
(ERROR_SUCCESS == regWL.ReadRegDWord(_T("AllowMultipleTSSessions"), &dwAllowMultipal)))
|
||
|
{
|
||
|
return dwAllowMultipal ? _T("Yes") : _T("No");
|
||
|
}
|
||
|
|
||
|
if (IsIt50TS())
|
||
|
{
|
||
|
return _T("Yes");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _T("ERROR, registry missing");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TCHAR *LogonType ()
|
||
|
{
|
||
|
if (0 == _tcsicmp(GetDomName(), szDomNameWorkgroup))
|
||
|
{
|
||
|
CRegistry regWL;
|
||
|
DWORD dwLogonType;
|
||
|
if ((ERROR_SUCCESS == regWL.OpenKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), KEY_READ)) &&
|
||
|
(ERROR_SUCCESS == regWL.ReadRegDWord(_T("LogonType"), &dwLogonType)))
|
||
|
{
|
||
|
return dwLogonType == 0 ? _T("Classic Gina") : _T("New Fancy");
|
||
|
}
|
||
|
|
||
|
if (IsIt50TS())
|
||
|
{
|
||
|
return _T("Classic");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _T("ERROR, registry missing");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _T("Classic Gina");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL IsTermSrvInSystemContext ()
|
||
|
{
|
||
|
USES_CONVERSION;
|
||
|
CRegistry reg;
|
||
|
if ( ERROR_SUCCESS == reg.OpenKey( HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\TermService"), KEY_READ))
|
||
|
{
|
||
|
TCHAR *szObjectName;
|
||
|
DWORD dwSize;
|
||
|
if ( ERROR_SUCCESS == reg.ReadRegString( _T("ObjectName"), &szObjectName, &dwSize))
|
||
|
{
|
||
|
if (0 == _tcsicmp(szObjectName, _T("LocalSystem")))
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "ERROR:Termsrv is set to run using (" << T2A(szObjectName) << ") context." << endl;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "failed to read Objectname" << endl;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szMoreInfo << "failed to open termsrv registry" << endl;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL DontRun ()
|
||
|
{
|
||
|
szMoreInfo << "test not run because its not required." << endl;
|
||
|
return FALSE;
|
||
|
}
|
||
|
BOOL DoRun ()
|
||
|
{
|
||
|
szMoreInfo << "this test must be run." << endl;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
TCHAR *SystemDirectory()
|
||
|
{
|
||
|
TCHAR sysdir[MAX_PATH];
|
||
|
sysdir[0] = '\0';
|
||
|
if (GetSystemDirectory(sysdir, MAX_PATH) >= MAX_PATH) {
|
||
|
sysdir[MAX_PATH -1] = '\0';
|
||
|
}
|
||
|
_tcscpy(ReturnBuffer(), sysdir);
|
||
|
return ReturnBuffer();
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
#if !defined(_MIPS_) && !defined(_ALPHA_) && !defined(_PPC_)
|
||
|
_cdecl
|
||
|
#endif
|
||
|
main( int argc , char ** /* argv */)
|
||
|
{
|
||
|
typedef BOOL (PFN_BOOL)(void);
|
||
|
typedef TCHAR * (PFN_TestSubjective)(void);
|
||
|
|
||
|
|
||
|
USES_CONVERSION;
|
||
|
|
||
|
struct TVerificationTest
|
||
|
{
|
||
|
char szTestName[256]; // descriptive name of the test
|
||
|
PFN_BOOL *pfnNeedRunTest; // pointer to function that will be called to decide if the test need run, test is run if NULL.
|
||
|
PFN_TestSubjective *pfnSubTest; // pointer to function if the test returns TCHAR *
|
||
|
PFN_BOOL *pfnObjTest; // pointer to function if the test returns BOOL
|
||
|
}
|
||
|
theTests[] =
|
||
|
{
|
||
|
// {"DontRun...............................", DontRun, GetCompName, NULL},
|
||
|
// {"DoRun...............................", DoRun, GetCompName, NULL},
|
||
|
|
||
|
{"Machine Name...............................", NULL, GetCompName, NULL},
|
||
|
{"Domain Name................................", NULL, GetDomName, NULL},
|
||
|
{"IP Address.................................", NULL, GetIPAddress, NULL},
|
||
|
{"System Dir.................................", NULL, SystemDirectory, NULL},
|
||
|
{"ProductType................................", NULL, GetProductType, NULL},
|
||
|
{"ProductSuite...............................", NULL, GetProductSuite, NULL},
|
||
|
{"TS Version.................................", NULL, GetTSVersion, NULL},
|
||
|
{"Is this a server machine?..................", NULL, IsServer, NULL},
|
||
|
{"Is tsoc.log Present?.......................", NULL, NULL, IsTSOClogPresent},
|
||
|
{"Did TsOC get CompleteInstallationMessage...", NULL, NULL, DidTsOCgetCompleteInstallationMessage},
|
||
|
{"Is Clustering Services installed...........", NULL, IsClusteringInstalled, NULL},
|
||
|
{"Does ProductSuite Contain TS?..............", NULL, NULL, DoesProductSuiteContainTS},
|
||
|
{"Did OCM Install TSEnable...................", IsIt50TS, NULL, DidOCMInstallTSEnable},
|
||
|
{"Is TSEnabled registry alright?.............", NULL, NULL, TSEnabled},
|
||
|
{"Is Kernel TSEnabled?.......................", IsItServer, NULL, IsKernelTSEnable},
|
||
|
{"Is Terminal Server Registry Ok?............", NULL, NULL, IsTerminalServerRegistryOk},
|
||
|
{"GetWinstationList..........................", NULL, GetWinstationList, NULL},
|
||
|
{"Is TermServ Start Bit Ok?..................", NULL, IsTerminalServiceStartBitSet, NULL},
|
||
|
{"Is TermServ service running?...............", NULL, NULL, IsTerminalServiceRunning},
|
||
|
{"Is TermSrv in System Context?..............", NULL, NULL, IsTermSrvInSystemContext},
|
||
|
{"AreEffectiveConnectionAllowed..............", IsIt51TS, AreEffectiveConnectionAllowed, NULL },
|
||
|
{"Are Connections Allowed?...................", IsIt51TS, AreConnectionsAllowed, NULL},
|
||
|
{"Is RdpDr Installed Properly?...............", NULL, NULL, IsRdpDrInstalledProperly},
|
||
|
{"Is RdpNP in NetProviders?..................", IsIt51TS, IsRDPNPinNetProviders, NULL},
|
||
|
{"Are Multipal Connections Allowed...........", IsIt51TS, IsMultiConnectionAllowed, NULL},
|
||
|
{"Logon UI type..............................", IsIt51TS, LogonType, NULL},
|
||
|
{"Are Video keys setup right?................", NULL, NULL, CheckVideoKeys},
|
||
|
{"What mode is Terminal Server set in?.......", NULL, GetTSMode, NULL},
|
||
|
{"Is mode specific registry ok?..............", NULL, NULL, VerifyModeRegistry},
|
||
|
{"What is permission Mode set to?............", NULL, GetModePermissions, NULL},
|
||
|
{"Check termdd signature.....................", NULL, NULL, Check_termdd},
|
||
|
{"Check tdpipe signature.....................", NULL, NULL, Check_tdpipe},
|
||
|
{"Check tdtcp signature......................", NULL, NULL, Check_tdtcp},
|
||
|
{"Check rdpwd signature......................", NULL, NULL, Check_rdpwd},
|
||
|
{"Check rdpdd signature......................", NULL, NULL, Check_rdpdd},
|
||
|
{"Check rdpwsx signature.....................", NULL, NULL, Check_rdpwsx},
|
||
|
{"Is it 56 bit or 128?.......................", NULL, GetCypherStrenthOnRdpwd, NULL},
|
||
|
{"Is this a Beta System?.....................", NULL, IsBetaSystem, NULL},
|
||
|
{"Has Licence GracePeriod Expired............", NULL, IsLicenceGracePeriodOk, NULL},
|
||
|
{"Audio test.................................", IsIt51TS, NULL, IsAudioOk}
|
||
|
};
|
||
|
|
||
|
BOOL bEverythingOk = TRUE;
|
||
|
for (int i=0; i < sizeof(theTests)/sizeof(theTests[0]); i++)
|
||
|
{
|
||
|
ASSERT(theTests[i].pfnObjTest || theTests[i].pfnSubTest);
|
||
|
ASSERT(!(theTests[i].pfnObjTest && theTests[i].pfnSubTest));
|
||
|
|
||
|
if (theTests[i].pfnNeedRunTest && !(*(theTests[i].pfnNeedRunTest))())
|
||
|
{
|
||
|
// we asre asked to skip the test.
|
||
|
cout << theTests[i].szTestName << "Skipped Test" << endl;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (theTests[i].pfnObjTest)
|
||
|
{
|
||
|
BOOL bResult = (*(theTests[i].pfnObjTest))();
|
||
|
cout << theTests[i].szTestName << (bResult ? "Passed" : "Failed") << endl;
|
||
|
if (!bResult)
|
||
|
bEverythingOk = FALSE;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
char *szStr = T2A((*(theTests[i].pfnSubTest))());
|
||
|
if (szStr)
|
||
|
{
|
||
|
cout << theTests[i].szTestName << szStr << endl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// if previous test had any details to tell us
|
||
|
//
|
||
|
|
||
|
if (szMoreInfo.pcount())
|
||
|
{
|
||
|
char *pStr = szMoreInfo.str();
|
||
|
cout << " Details:" << pStr;
|
||
|
cout << "------------------------------------------------" << endl;
|
||
|
|
||
|
bEverythingOk = FALSE;
|
||
|
ZeroMemory(pStr, 512);
|
||
|
szMoreInfo.seekp(ios::beg);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
cout << endl;
|
||
|
|
||
|
|
||
|
|
||
|
if (argc == 1 ) // if some argumnent is provided skip these time consuming test.
|
||
|
{
|
||
|
|
||
|
cout << "Enumerating Licensing Servers (May take some time)...";
|
||
|
cout.flush();
|
||
|
if (EnumerateLicenseServers())
|
||
|
{
|
||
|
cout << ".....Passed, Found Some!" << endl;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cout << ".....Failed. No License Server Found." << endl;
|
||
|
}
|
||
|
|
||
|
cout << "Extracting Related Events from Event Log...";
|
||
|
cout.flush();
|
||
|
if (ExtractAllTSEvents())
|
||
|
{
|
||
|
cout << ".....Found Some. See if they give any clue." << endl;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cout << ".....Found None." << endl;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
cout << endl;
|
||
|
if (bEverythingOk)
|
||
|
{
|
||
|
cout << endl;
|
||
|
cout << "**************************************************************" << endl;
|
||
|
cout << "*** Nothing wrong with TS could detected by this utility. ***" << endl;
|
||
|
cout << "*** If you think something is wrong contact the developer. ***" << endl;
|
||
|
cout << "**************************************************************" << endl;
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
|
||
|
}
|
||
|
|