|
|
// --------------------------------------------------------------------------
// Module Name: SystemSettings.cpp
//
// Copyright (c) 1999-2000, Microsoft Corporation
//
// A class to handle opening and reading/writing from the Winlogon key.
//
// History: 1999-09-09 vtan created
// 1999-11-16 vtan separate file
// 2000-02-01 vtan moved from Neptune to Whistler
// --------------------------------------------------------------------------
#include "StandardHeader.h"
#include "SystemSettings.h"
#include <regstr.h>
#include <safeboot.h>
#include <winsta.h>
#include <allproc.h> // TS_COUNTER
#include <shlwapi.h>
#include "RegistryResources.h"
const TCHAR CSystemSettings::s_szSafeModeKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option"); const TCHAR CSystemSettings::s_szSafeModeOptionValueName[] = TEXT("OptionValue"); const TCHAR CSystemSettings::s_szWinlogonKeyName[] = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"); const TCHAR CSystemSettings::s_szSystemPolicyKeyName[] = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies\\system"); const TCHAR CSystemSettings::s_szTerminalServerKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"); const TCHAR CSystemSettings::s_szTerminalServerPolicyKeyName[] = TEXT("SOFTWARE\\Policies\\Microsoft\\Windows NT\\Terminal Services"); const TCHAR CSystemSettings::s_szNetwareClientKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order"); const TCHAR CSystemSettings::s_szLogonTypeValueName[] = TEXT("LogonType"); const TCHAR CSystemSettings::s_szBackgroundValueName[] = TEXT("Background"); const TCHAR CSystemSettings::s_szMultipleUsersValueName[] = TEXT("AllowMultipleTSSessions"); const TCHAR CSystemSettings::s_szDenyRemoteConnectionsValueName[] = TEXT("fDenyTSConnections");
int CSystemSettings::s_iIsSafeModeMinimal = -1; int CSystemSettings::s_iIsSafeModeNetwork = -1;
// --------------------------------------------------------------------------
// CSystemSettings::IsSafeMode
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Was the machine started in safe mode (minimal or network) ?
//
// History: 2000-03-06 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsSafeMode (void)
{ return(IsSafeModeMinimal() || IsSafeModeNetwork()); }
// --------------------------------------------------------------------------
// CSystemSettings::IsSafeModeMinimal
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Was the machine started in safe mode minimal?
//
// History: 1999-09-13 vtan created
// 2000-05-25 vtan cache result in static member variable
// --------------------------------------------------------------------------
bool CSystemSettings::IsSafeModeMinimal (void)
{ if (-1 == s_iIsSafeModeMinimal) { bool fResult; CRegKey regKey;
fResult = false; if (ERROR_SUCCESS == regKey.Open(HKEY_LOCAL_MACHINE, s_szSafeModeKeyName, KEY_QUERY_VALUE)) { DWORD dwValue, dwValueSize;
dwValueSize = sizeof(dwValue); if (ERROR_SUCCESS == regKey.GetDWORD(s_szSafeModeOptionValueName, dwValue)) { fResult = (dwValue == SAFEBOOT_MINIMAL); } } s_iIsSafeModeMinimal = fResult; } return(s_iIsSafeModeMinimal != 0); }
// --------------------------------------------------------------------------
// CSystemSettings::IsSafeModeNetwork
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Was the machine started in safe mode with networking?
//
// History: 1999-11-09 vtan created
// 2000-05-25 vtan cache result in static member variable
// --------------------------------------------------------------------------
bool CSystemSettings::IsSafeModeNetwork (void)
{ if (-1 == s_iIsSafeModeNetwork) { bool fResult; CRegKey regKey;
fResult = false; if (ERROR_SUCCESS == regKey.Open(HKEY_LOCAL_MACHINE, s_szSafeModeKeyName, KEY_QUERY_VALUE)) { DWORD dwValue, dwValueSize;
dwValueSize = sizeof(dwValue); if (ERROR_SUCCESS == regKey.GetDWORD(s_szSafeModeOptionValueName, dwValue)) { fResult = (dwValue == SAFEBOOT_NETWORK); } } s_iIsSafeModeNetwork = fResult; } return(s_iIsSafeModeNetwork != 0); }
// --------------------------------------------------------------------------
// CSystemSettings::IsNetwareActive
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether this machine is a workstation running
// Netware client services or not.
//
// History: 2001-05-16 cevans created
// --------------------------------------------------------------------------
bool CSystemSettings::IsNetwareActive (void) { bool fResult; LONG lErrorCode; TCHAR szProviders[MAX_PATH] = {0}; CRegKey regKey;
fResult = false; lErrorCode = regKey.Open(HKEY_LOCAL_MACHINE, s_szNetwareClientKeyName, KEY_QUERY_VALUE); if (ERROR_SUCCESS == lErrorCode) { if((regKey.GetString(TEXT("ProviderOrder"), szProviders, ARRAYSIZE(szProviders)) == ERROR_SUCCESS)) { if (StrStrI(szProviders, TEXT("NWCWorkstation")) != NULL) { fResult = true; } else if (StrStrI(szProviders, TEXT("NetwareWorkstation")) != NULL) { fResult = true; } } } return fResult; }
// --------------------------------------------------------------------------
// CSystemSettings::IsWorkStationProduct
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether this machine is a workstation product vs.
// a server product.
//
// History: 2000-08-30 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsWorkStationProduct (void)
{ OSVERSIONINFOEXA osVersionInfo;
ZeroMemory(&osVersionInfo, sizeof(osVersionInfo)); osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo); return((GetVersionExA(reinterpret_cast<OSVERSIONINFOA*>(&osVersionInfo)) != FALSE) && (VER_NT_WORKSTATION == osVersionInfo.wProductType)); }
// --------------------------------------------------------------------------
// CSystemSettings::IsDomainMember
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Is this machine a member of a domain? Use the LSA to get this
// information.
//
// History: 1999-09-14 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsDomainMember (void)
{ bool fResult; int iCounter; NTSTATUS status; OBJECT_ATTRIBUTES objectAttributes; LSA_HANDLE lsaHandle; SECURITY_QUALITY_OF_SERVICE securityQualityOfService; PPOLICY_DNS_DOMAIN_INFO pDNSDomainInfo;
fResult = false; securityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); securityQualityOfService.ImpersonationLevel = SecurityImpersonation; securityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; securityQualityOfService.EffectiveOnly = FALSE; InitializeObjectAttributes(&objectAttributes, NULL, 0, NULL, NULL); objectAttributes.SecurityQualityOfService = &securityQualityOfService; iCounter = 0; do { status = LsaOpenPolicy(NULL, &objectAttributes, POLICY_VIEW_LOCAL_INFORMATION, &lsaHandle); if (RPC_NT_SERVER_TOO_BUSY == status) { Sleep(10); } } while ((RPC_NT_SERVER_TOO_BUSY == status) && (++iCounter < 10)); if (NT_SUCCESS(status)) { status = LsaQueryInformationPolicy(lsaHandle, PolicyDnsDomainInformation, reinterpret_cast<void**>(&pDNSDomainInfo)); if (NT_SUCCESS(status) && (pDNSDomainInfo != NULL)) { fResult = ((pDNSDomainInfo->DnsDomainName.Length != 0) || (pDNSDomainInfo->DnsForestName.Length != 0) || (pDNSDomainInfo->Sid != NULL)); TSTATUS(LsaFreeMemory(pDNSDomainInfo)); } TSTATUS(LsaClose(lsaHandle)); } return(fResult); }
// --------------------------------------------------------------------------
// CSystemSettings::IsActiveConsoleSession
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether current process session is the active console
// session.
//
// History: 2001-03-04 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsActiveConsoleSession (void)
{ return(NtCurrentPeb()->SessionId == USER_SHARED_DATA->ActiveConsoleId); }
// --------------------------------------------------------------------------
// CSystemSettings::IsTerminalServicesEnabled
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Does this machine have an enabled terminal services service?
// This function is for Windows 2000 and later ONLY.
//
// History: 2000-03-02 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsTerminalServicesEnabled (void)
{ OSVERSIONINFOEX osVersionInfo; DWORDLONG dwlConditionMask;
dwlConditionMask = 0; ZeroMemory(&osVersionInfo, sizeof(osVersionInfo)); osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo); osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL | VER_SUITE_SINGLEUSERTS; VER_SET_CONDITION(dwlConditionMask, VER_SUITENAME, VER_OR); return((VerifyVersionInfo(&osVersionInfo, VER_SUITENAME, dwlConditionMask) != FALSE) && !IsSCMTerminalServicesDisabled()); }
// --------------------------------------------------------------------------
// CSystemSettings::IsFriendlyUIActive
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Read the registry HKLM\Software\Microsoft\Windows NT\ // CurrentVersion\Winlogon\LogonType and if this value is 0x01
// then activate the external UI host. This function returns the
// setting. This can never be true for domain member machines.
//
// History: 2000-02-04 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsFriendlyUIActive (void)
{ int iResult;
return((!IsDomainMember() || IsForceFriendlyUI()) && IsMicrosoftGINA() && !IsNetwareActive() && (ERROR_SUCCESS == GetEffectiveInteger(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, s_szSystemPolicyKeyName, s_szLogonTypeValueName, iResult)) && (iResult != 0)); }
// --------------------------------------------------------------------------
// CSystemSettings::IsMultipleUsersEnabled
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Read the registry HKLM\Software\Microsoft\Windows NT\ // CurrentVersion\Winlogon\AllowMultipleTSSessions and if the
// value is 0x01 *AND* terminal services is installed on this
// machine then the conditions are satisfied.
//
// History: 2000-03-02 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsMultipleUsersEnabled (void)
{ int iResult;
return(IsTerminalServicesEnabled() && !IsSafeMode() && (ERROR_SUCCESS == GetEffectiveInteger(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, s_szSystemPolicyKeyName, s_szMultipleUsersValueName, iResult)) && (iResult != 0)); }
// --------------------------------------------------------------------------
// CSystemSettings::IsRemoteConnectionsEnabled
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Read the registry HKLM\System\CurrentControlSet\Control\ // Terminal Server\fDenyTSConnections and returns the
// value back to the caller.
//
// History: 2000-07-28 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsRemoteConnectionsEnabled (void)
{ int iResult; CRegKey regKey;
return(IsTerminalServicesEnabled() && (ERROR_SUCCESS == GetEffectiveInteger(HKEY_LOCAL_MACHINE, s_szTerminalServerKeyName, s_szTerminalServerPolicyKeyName, s_szDenyRemoteConnectionsValueName, iResult)) && (iResult == 0)); }
// --------------------------------------------------------------------------
// CSystemSettings::IsRemoteConnectionPresent
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether there is a remote connection active on the
// current system.
//
// History: 2000-07-28 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsRemoteConnectionPresent (void)
{ bool fRemoteConnectionPresent; HANDLE hServer; PLOGONID pLogonID, pLogonIDs; ULONG ul, ulEntries;
fRemoteConnectionPresent = false;
// Open a connection to terminal services and get the number of sessions.
hServer = WinStationOpenServerW(reinterpret_cast<WCHAR*>(SERVERNAME_CURRENT)); if (hServer != NULL) { if (WinStationEnumerate(hServer, &pLogonIDs, &ulEntries) != FALSE) {
// Iterate the sessions looking for active and shadow sessions only.
for (ul = 0, pLogonID = pLogonIDs; !fRemoteConnectionPresent && (ul < ulEntries); ++ul, ++pLogonID) { if ((pLogonID->State == State_Active) || (pLogonID->State == State_Shadow)) { fRemoteConnectionPresent = (lstrcmpi(pLogonID->WinStationName, TEXT("console")) != 0); } }
// Free any resources used.
(BOOLEAN)WinStationFreeMemory(pLogonIDs); } (BOOLEAN)WinStationCloseServer(hServer); }
// Return result.
return(fRemoteConnectionPresent); }
// --------------------------------------------------------------------------
// CSystemSettings::IsShutdownWithoutLogonAllowed
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Read the registry HKLM\Software\Microsoft\Windows NT\ // CurrentVersion\Winlogon\ShutdownWithoutLogon and returns the
// value back to the caller.
//
// History: 2000-04-27 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsShutdownWithoutLogonAllowed (void)
{ int iResult;
return((ERROR_SUCCESS == GetEffectiveInteger(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, s_szSystemPolicyKeyName, TEXT("ShutdownWithoutLogon"), iResult)) && (iResult != 0)); }
// --------------------------------------------------------------------------
// CSystemSettings::IsUndockWithoutLogonAllowed
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Read the registry HKLM\Software\Microsoft\Windows NT\ // CurrentVersion\Winlogon\UndockWithoutLogon and returns the
// value back to the caller.
//
// History: 2001-03-17 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsUndockWithoutLogonAllowed (void)
{ int iResult;
return((ERROR_SUCCESS == GetEffectiveInteger(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, s_szSystemPolicyKeyName, REGSTR_VAL_UNDOCK_WITHOUT_LOGON, iResult)) && (iResult != 0)); }
// --------------------------------------------------------------------------
// CSystemSettings::IsForceFriendlyUI
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Read the registry HKLM\Software\Microsoft\Windows NT\ // CurrentVersion\Winlogon\ForceFriendlyUI and returns the
// value back to the caller.
//
// History: 2000-04-27 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsForceFriendlyUI (void)
{ int iResult;
return((ERROR_SUCCESS == GetEffectiveInteger(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, s_szSystemPolicyKeyName, TEXT("ForceFriendlyUI"), iResult)) && (iResult != 0)); }
// --------------------------------------------------------------------------
// CSystemSettings::GetUIHost
//
// Arguments: pszPath = TCHAR array to receive UI host path.
//
// Returns: LONG
//
// Purpose: Read the registry HKLM\Software\Microsoft\Windows NT\ // CurrentVersion\Winlogon\UIHost and returns the value.
//
// History: 2000-04-12 vtan created
// --------------------------------------------------------------------------
LONG CSystemSettings::GetUIHost (TCHAR *pszPath)
{ return(GetEffectivePath(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, s_szSystemPolicyKeyName, TEXT("UIHost"), pszPath)); }
// --------------------------------------------------------------------------
// CSystemSettings::IsUIHostStatic
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Read the registry HKLM\Software\Microsoft\Windows NT\ // CurrentVersion\Winlogon\UIHostStatic and returns the
// value.
//
// History: 2000-04-12 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsUIHostStatic (void)
{ int iResult;
return((ERROR_SUCCESS == GetEffectiveInteger(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, s_szSystemPolicyKeyName, TEXT("UIHostStatic"), iResult)) && (iResult != 0)); }
// --------------------------------------------------------------------------
// CSystemSettings::EnableFriendlyUI
//
// Arguments: fEnable = Enable friendly UI.
//
// Returns: bool
//
// Purpose: Enable friendly UI. This should only be allowed on workgroup
// machines. Check the machine status to enforce this.
//
// ERROR_NOT_SUPPORTED is returned when the machine is joined to
// a domain.
//
// History: 2000-08-01 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::EnableFriendlyUI (bool fEnable)
{ LONG lErrorCode;
if (!IsDomainMember() || !fEnable) { CRegKey regKey;
lErrorCode = regKey.Open(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, KEY_SET_VALUE); if (ERROR_SUCCESS == lErrorCode) { lErrorCode = regKey.SetDWORD(s_szLogonTypeValueName, fEnable); if (fEnable) { lErrorCode = regKey.SetString(s_szBackgroundValueName, TEXT("0 0 0")); } else { (LONG)regKey.DeleteValue(s_szBackgroundValueName); } } } else { lErrorCode = ERROR_NOT_SUPPORTED; } SetLastError(static_cast<DWORD>(lErrorCode)); return(ERROR_SUCCESS == lErrorCode); }
// --------------------------------------------------------------------------
// CSystemSettings::EnableMultipleUsers
//
// Arguments: fEnable = Enable multiple users.
//
// Returns: bool
//
// Purpose: Enable the multiple users feature. This sets
// AllowMultipleTSSessions to 1 but only does so if remote
// connections are disabled. This allows multiple console
// sessions but no remote sessions. If there is a remote
// connection active this call is rejected.
//
// ERROR_ACCESS_DENIED is returned when there are more than one
// users active and being disabled.
//
// ERROR_CTX_NOT_CONSOLE is returned when being disabled from
// a remote session (disabling only allowed from the console).
//
// ERROR_NOT_SUPPORTED is returned when being disabled from
// the console, remote connections are enabled, and the current
// session is not session 0.
//
// History: 2000-07-28 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::EnableMultipleUsers (bool fEnable)
{ LONG lErrorCode;
// If disabling multiple users with more than one users active
// reject the call. Return ERROR_ACCESS_DENIED.
if (!fEnable && (GetLoggedOnUserCount() > 1)) { lErrorCode = ERROR_ACCESS_DENIED; }
// If disabling and not on the console, reject the call.
// Return ERROR_CTX_NOT_CONSOLE.
else if (!fEnable && !IsActiveConsoleSession()) { lErrorCode = ERROR_CTX_NOT_CONSOLE; }
// If disabling from the console and remote connections are enabled and
// the current session is not session 0, reject the call. Otherwise, a
// a remote connection with FUS disabled causes strange results because
// it expects to connect to session 0.
// Return ERROR_NOT_SUPPORTED.
else if (!fEnable && IsRemoteConnectionsEnabled() && NtCurrentPeb()->SessionId != 0) { lErrorCode = ERROR_NOT_SUPPORTED; } else { CRegKey regKey; lErrorCode = regKey.Open(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, KEY_SET_VALUE); if (ERROR_SUCCESS == lErrorCode) { lErrorCode = regKey.SetDWORD(s_szMultipleUsersValueName, fEnable); if (ERROR_SUCCESS == lErrorCode) { (DWORD)AdjustFUSCompatibilityServiceState(NULL); } } } SetLastError(static_cast<DWORD>(lErrorCode)); return(ERROR_SUCCESS == lErrorCode); }
// --------------------------------------------------------------------------
// CSystemSettings::EnableRemoteConnections
//
// Arguments: fEnable = Enable remote connections.
//
// Returns: bool
//
// Purpose: Enable the remote connections feature. This sets
// fDenyTSConnections to 0 but only does so if there is a one
// user logged onto the system. This allows the single
// connection to be remotely connected but not allow multiple
// console sessions. This conforms to the single user per CPU
// license of the workstation product. To get multiple users
// you need the server product.
//
// ERROR_NOT_SUPPORTED is returned when enabling remote
// connections with FUS disabled and the current session != 0.
//
// History: 2000-07-28 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::EnableRemoteConnections (bool fEnable)
{ LONG lErrorCode;
// If enabling remote connections, FUS is disabled, and we are not on
// session 0 (can happen immediately after disabling FUS), then a remote
// connection will fail. With FUS disabled, the connection must go to
// session 0. This is a fringe case, but disallow enabling remote
// connections if it happens.
if (fEnable && !IsMultipleUsersEnabled() && NtCurrentPeb()->SessionId != 0) { lErrorCode = ERROR_NOT_SUPPORTED; } else { CRegKey regKey;
lErrorCode = regKey.Open(HKEY_LOCAL_MACHINE, s_szTerminalServerKeyName, KEY_SET_VALUE); if (ERROR_SUCCESS == lErrorCode) { lErrorCode = regKey.SetDWORD(s_szDenyRemoteConnectionsValueName, !fEnable); } } SetLastError(static_cast<DWORD>(lErrorCode)); return(ERROR_SUCCESS == lErrorCode); }
// --------------------------------------------------------------------------
// CSystemSettings::GetLoggedOnUserCount
//
// Arguments: <none>
//
// Returns: int
//
// Purpose: Returns the count of logged on users on this machine. Ripped
// straight out of shtdndlg.c in msgina.
//
// History: 2000-03-29 vtan created
// 2000-04-21 vtan copied from taskmgr
// 2000-07-28 vtan moved from userlist.cpp
// --------------------------------------------------------------------------
int CSystemSettings::GetLoggedOnUserCount (void)
{ int iCount; HANDLE hServer;
iCount = 0;
// Open a connection to terminal services and get the number of sessions.
hServer = WinStationOpenServerW(reinterpret_cast<WCHAR*>(SERVERNAME_CURRENT)); if (hServer != NULL) { TS_COUNTER tsCounters[2] = {0};
tsCounters[0].counterHead.dwCounterID = TERMSRV_CURRENT_DISC_SESSIONS; tsCounters[1].counterHead.dwCounterID = TERMSRV_CURRENT_ACTIVE_SESSIONS;
if (WinStationGetTermSrvCountersValue(hServer, ARRAYSIZE(tsCounters), tsCounters)) { int i;
for (i = 0; i < ARRAYSIZE(tsCounters); i++) { if (tsCounters[i].counterHead.bResult) { iCount += tsCounters[i].dwValue; } } }
(BOOLEAN)WinStationCloseServer(hServer); }
// Return result.
return(iCount); }
// --------------------------------------------------------------------------
// CSystemSettings::CheckDomainMembership
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Checks the consistency of domain membership and allowing
// multiple TS sessions. The check is only for domain membership
// true not false.
//
// History: 2000-04-12 vtan created
// --------------------------------------------------------------------------
NTSTATUS CSystemSettings::CheckDomainMembership (void)
{ if (IsDomainMember() && !IsForceFriendlyUI() && IsProfessionalTerminalServer()) { TBOOL(EnableFriendlyUI(false)); (BOOL)EnableMultipleUsers(false); } return(STATUS_SUCCESS); }
// --------------------------------------------------------------------------
// CSystemSettings::AdjustFUSCompatibilityServiceState
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Turns on or off the FUS compatbility service based on the
// FUS configuration.
//
// History: 2001-02-12 vtan created
// --------------------------------------------------------------------------
DWORD WINAPI CSystemSettings::AdjustFUSCompatibilityServiceState (void *pV)
{ UNREFERENCED_PARAMETER(pV);
#ifdef _X86_
if (IsWorkStationProduct()) { bool fMultipleUsersEnabled; SC_HANDLE hSCManager;
fMultipleUsersEnabled = IsMultipleUsersEnabled();
// Connect to the service control manager.
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager != NULL) { SC_HANDLE hSCService;
// Open the "FastUserSwitchingCompatibility" service.
hSCService = OpenService(hSCManager, TEXT("FastUserSwitchingCompatibility"), SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS); if (hSCService != NULL) { SERVICE_STATUS serviceStatus;
// Find out the status of the service.
if (QueryServiceStatus(hSCService, &serviceStatus) != FALSE) { if (fMultipleUsersEnabled && (serviceStatus.dwCurrentState == SERVICE_STOPPED)) {
// If it's supposed to be started and it is not
// running then start the service. This can fail
// because the service is set to disabled. Ignore it.
(BOOL)StartService(hSCService, 0, NULL); } else if (!fMultipleUsersEnabled && (serviceStatus.dwCurrentState == SERVICE_RUNNING)) {
// If it's supposed to be stopped and it is
// running then stop the service.
TBOOL(ControlService(hSCService, SERVICE_CONTROL_STOP, &serviceStatus)); } } TBOOL(CloseServiceHandle(hSCService)); } TBOOL(CloseServiceHandle(hSCManager)); } }
#endif /* _X86_ */
return(0); }
// --------------------------------------------------------------------------
// CSystemSettings::GetEffectiveInteger
//
// Arguments: hKey = HKEY to read.
// pszKeyName = Subkey name to read.
// pszPolicyKeyName = Policy subkey name to read.
// pszValueName = Value name in subkey to read.
// iResult = int result.
//
// Returns: LONG
//
// Purpose: Reads the effective setting from the registry. The effective
// setting is whatever the user chooses as the regular setting
// overriden by policy. The policy setting is always returned if
// present.
//
// History: 2000-04-12 vtan created
// --------------------------------------------------------------------------
LONG CSystemSettings::GetEffectiveInteger (HKEY hKey, const TCHAR *pszKeyName, const TCHAR *pszPolicyKeyName, const TCHAR *pszValueName, int& iResult)
{ CRegKey regKey;
// Start with a typical initialized value.
iResult = 0;
// First check the regular location.
if (ERROR_SUCCESS == regKey.Open(hKey, pszKeyName, KEY_QUERY_VALUE)) { (LONG)regKey.GetInteger(pszValueName, iResult); }
// Then check the policy.
if (ERROR_SUCCESS == regKey.Open(hKey, pszPolicyKeyName, KEY_QUERY_VALUE)) { (LONG)regKey.GetInteger(pszValueName, iResult); }
// Always return ERROR_SUCCESS.
return(ERROR_SUCCESS); }
// --------------------------------------------------------------------------
// CSystemSettings::GetEffectivePath
//
// Arguments: hKey = HKEY to read.
// pszKeyName = Subkey name to read.
// pszPolicyKeyName = Policy subkey name to read.
// pszValueName = Value name in subkey to read.
// pszPath = TCHAR array to receive effect path.
//
// Returns: LONG
//
// Purpose: Reads the effective setting from the registry. The effective
// setting is whatever the user chooses as the regular setting
// overriden by policy. The policy setting is always returned if
// present. The buffer must be at least MAX_PATH characters.
//
// History: 2000-04-12 vtan created
// --------------------------------------------------------------------------
LONG CSystemSettings::GetEffectivePath (HKEY hKey, const TCHAR *pszKeyName, const TCHAR *pszPolicyKeyName, const TCHAR *pszValueName, TCHAR *pszPath)
{ LONG lErrorCode;
if (IsBadWritePtr(pszPath, MAX_PATH * sizeof(TCHAR))) { lErrorCode = ERROR_INVALID_PARAMETER; } else { LONG lPolicyErrorCode; CRegKey regKey;
// Start with a typical initialized value.
*pszPath = TEXT('\0');
// First check the regular location.
lErrorCode = regKey.Open(hKey, pszKeyName, KEY_QUERY_VALUE); if (ERROR_SUCCESS == lErrorCode) { lErrorCode = regKey.GetPath(pszValueName, pszPath); }
// Then check the policy.
lPolicyErrorCode = regKey.Open(hKey, pszPolicyKeyName, KEY_QUERY_VALUE); if (ERROR_SUCCESS == lPolicyErrorCode) { lPolicyErrorCode = regKey.GetPath(pszValueName, pszPath); }
// If either error code is ERROR_SUCCESS then return that
// error code. Otherwise return the non policy error code.
if ((ERROR_SUCCESS == lErrorCode) || (ERROR_SUCCESS == lPolicyErrorCode)) { lErrorCode = ERROR_SUCCESS; } } return(lErrorCode); }
// --------------------------------------------------------------------------
// CSystemSettings::IsProfessionalTerminalServer
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether this machine is a personal terminal server.
// That is workstation with single user TS.
//
// History: 2000-08-09 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsProfessionalTerminalServer (void)
{ OSVERSIONINFOEX osVersion;
ZeroMemory(&osVersion, sizeof(osVersion)); osVersion.dwOSVersionInfoSize = sizeof(osVersion); return((GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&osVersion)) != FALSE) && (osVersion.wProductType == VER_NT_WORKSTATION) && ((osVersion.wSuiteMask & VER_SUITE_PERSONAL) == 0) && ((osVersion.wSuiteMask & VER_SUITE_SINGLEUSERTS) != 0)); }
// --------------------------------------------------------------------------
// CSystemSettings::IsMicrosoftGINA
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether the current GINA is the Microsoft GINA.
//
// History: 2001-01-05 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsMicrosoftGINA (void)
{ bool fResult; LONG lErrorCode; TCHAR szGinaDLL[MAX_PATH]; CRegKey regKey;
fResult = true; lErrorCode = regKey.Open(HKEY_LOCAL_MACHINE, s_szWinlogonKeyName, KEY_QUERY_VALUE); if (ERROR_SUCCESS == lErrorCode) { fResult = (regKey.GetString(TEXT("GinaDLL"), szGinaDLL, ARRAYSIZE(szGinaDLL)) != ERROR_SUCCESS); } return(fResult); }
// --------------------------------------------------------------------------
// CSystemSettings::IsSCMTerminalServicesDisabled
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether terminal services is disabled via the service
// control manager.
//
// History: 2001-04-13 vtan created
// --------------------------------------------------------------------------
bool CSystemSettings::IsSCMTerminalServicesDisabled (void)
{ bool fResult; SC_HANDLE hSCManager;
fResult = false; hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager != NULL) { SC_HANDLE hSCService;
hSCService = OpenService(hSCManager, TEXT("TermService"), SERVICE_QUERY_CONFIG); if (hSCService != NULL) { DWORD dwBytesNeeded; QUERY_SERVICE_CONFIG *pQueryServiceConfig;
(BOOL)QueryServiceConfig(hSCService, NULL, 0, &dwBytesNeeded); pQueryServiceConfig = static_cast<QUERY_SERVICE_CONFIG*>(LocalAlloc(LMEM_FIXED, dwBytesNeeded)); if (pQueryServiceConfig != NULL) { fResult = ((QueryServiceConfig(hSCService, pQueryServiceConfig, dwBytesNeeded, &dwBytesNeeded) != FALSE) && (pQueryServiceConfig->dwStartType == SERVICE_DISABLED)); (HLOCAL)LocalFree(pQueryServiceConfig); } TBOOL(CloseServiceHandle(hSCService)); } TBOOL(CloseServiceHandle(hSCManager)); } return(fResult); }
|