Windows2003-3790/termsrv/wmi/tscfgwmi/terminal.cpp
2020-09-30 16:53:55 +02:00

3640 lines
119 KiB
C++

/******************************************************************
Copyright (C) 2000 Microsoft Corp.
Terminal.CPP -- WMI provider class implementation
Generated by Microsoft WMI Code Generation Engine
TO DO: - See individual function headers
- When linking, make sure you link to framedyd.lib &
msvcrtd.lib (debug) or framedyn.lib & msvcrt.lib (retail).
Description:
******************************************************************/
#include "stdafx.h"
#include <fwcommon.h>
#include "Terminal.h"
#include "registry.h"
#include "smartptr.h"
#include <windows.h>
#include <Iphlpapi.h>
#include "cfgbkend_i.c"
#define TS_PATH TEXT("SYSTEM\\ControlSet\\Control\\Terminal Server")
#define TS_LOGON_PATH TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
#define TS_ACTIVEDESKTOP TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies")
#define TERMINAL_SERVICE_PARAM_DISCOVERY TEXT("SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters")
#define TERMINAL_SERVICE_PARAM_DISCOVERY_SERVERS TEXT("SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters\\LicenseServers")
#define GUID_LENGTH 40
extern TCHAR tchErrorMessage[ 80 ];
#define ARRAYSIZE( rg ) sizeof( rg ) / sizeof( rg[0] )
// TO DO: Replace "NameSpace" with the appropriate namespace for your
// provider instance. For instance: "root\\default or "root\\cimv2".
//===================================================================
// Property names
//===============
// Property names
//===============
const static WCHAR* pErrorClass = L"\\\\.\\root\\cimv2:TerminalServiceSettingError";
CStackClass::CStackClass ( )
{
HRESULT hr;
m_pCfg = NULL;
m_pCfgComp = NULL;
hr = CoGetClassObject(CLSID_CfgComp, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&m_pCfg);
TRC2((TB, "StackClass@Constructor: CoGetClassObject of IClassFactory ret 0x%x", hr));
if( SUCCEEDED ( hr ) && m_pCfg != NULL )
{
hr = m_pCfg->CreateInstance(NULL, IID_ICfgComp, (void **)&m_pCfgComp);
TRC2((TB, "StackClass@Constructor: CoCreateInstance of ICfgComp ret 0x%x", hr));
if( SUCCEEDED ( hr ) && m_pCfgComp != NULL )
{
hr = m_pCfgComp->Initialize( );
}
else
{
m_pCfgComp = NULL;
}
}
else
{
m_pCfgComp = NULL;
m_pCfg = NULL;
}
}
//=--------------------
/******************************************************************************************************
*
*DESCRIPTION : CWin32_TSProvider class is a base class from which all other classes are derived.
* The destructor releases the CfgBkEnd interface pointer.
*
********************************************************************************************************/
CStackClass::~CStackClass ()
{
if ( NULL != m_pCfgComp )
{
m_pCfgComp->Release();
TRC2((TB, "StackClass@Destructor for ICfgComp: succeeded"));
}
if ( NULL != m_pCfg )
{
m_pCfg->Release();
TRC2((TB, "StackClass@Destructor for IClassFactory: succeeded"));
}
}
//------------------------
/*****************************************************************************
*
* FUNCTION : CWin32_TerminalServiceSetting::CWin32_TerminalServiceSetting
* This class reads and sets the Server Settings such as Terminal
* server mode, license type, active desktop state, temp folders,
* logon and Help.
*
*****************************************************************************/
CWin32_TerminalServiceSetting::CWin32_TerminalServiceSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider( lpwszName, lpwszNameSpace )
{
if ( g_hInstance != NULL)
{
TRC2((TB, "CWin32_TerminalServiceSetting_ctor"));
_tcscpy(m_szServerName, _T("ServerName"));
_tcscpy(m_szMode, _T("TerminalServerMode"));
_tcscpy(m_szLicensingName, _T("LicensingName"));
_tcscpy(m_szLicensingDescription, _T("LicensingDescription"));
_tcscpy(m_szActiveDesktop, _T("ActiveDesktop"));
_tcscpy(m_szUserPerm, _T("UserPermission"));
_tcscpy(m_szDeleteTempFolders, _T("DeleteTempFolders"));
_tcscpy(m_szUseTempFolders, _T("UseTempFolders"));
_tcscpy(m_szLogons, _T("Logons"));
_tcscpy(m_szHelp, _T("Help"));
_tcscpy(m_szValue, _T("Value"));
_tcscpy(m_szPropertyName, _T("PropertyName"));
_tcscpy(m_szChangeMode, _T("ChangeMode"));
_tcscpy(m_szLicensingType, _T("LicensingType"));
_tcscpy(m_szSetPolicyPropertyName, _T("SetPolicyPropertyName"));
_tcscpy(m_szAllowTSConnections, _T("AllowTSConnections"));
_tcscpy(m_szSetAllowTSConnections, _T("SetAllowTSConnections"));
_tcscpy(m_szSingleSession, _T("SingleSession"));
_tcscpy(m_szSetSingleSession, _T("SetSingleSession"));
_tcscpy(m_szProfilePath, _T("ProfilePath"));
_tcscpy(m_szHomeDirectory, _T("HomeDirectory"));
_tcscpy(m_szSetProfilePath, _T("SetProfilePath"));
_tcscpy(m_szSetHomeDirectory, _T("SetHomeDirectory"));
_tcscpy(m_szDirectConnectLicenseServers, _T("DirectConnectLicenseServers"));
_tcscpy(m_szAddDirectConnectLicenseServer, _T("AddDirectConnectLicenseServer"));
_tcscpy(m_szDeleteDirectConnectLicenseServer, _T("DeleteDirectConnectLicenseServer"));
_tcscpy(m_szLicenseServerName, _T("LicenseServerName"));
_tcscpy(m_szTimeZoneRedirection, _T("TimeZoneRedirection"));
_tcscpy(m_szSetTimeZoneRedirection, _T("SetTimeZoneRedirection"));
_tcscpy(m_szDisableForcibleLogoff, _T("DisableForcibleLogoff"));
_tcscpy(m_szSetDisableForcibleLogoff, _T("SetDisableForcibleLogoff"));
}
RegGetMachinePolicy(&m_gpPolicy);
}
//=-------------
/*****************************************************************************
*
* FUNCTION : CWin32_TerminalServiceSetting::~CWin32_TerminalServiceSetting
*****************************************************************************/
CWin32_TerminalServiceSetting::~CWin32_TerminalServiceSetting ()
{
}
//=-------------
/*****************************************************************************
*
* FUNCTION : CWin32_TerminalServiceSetting::EnumerateInstances
*
* DESCRIPTION : Returns all the instances of this class.
*
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
* A long that contains the flags described in
* IWbemServices::CreateInstanceEnumAsync. Note that the following
* flags are handled by (and filtered out by) WinMgmt:
* WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY,
* WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
* RETURNS : WBEM_S_NO_ERROR if successful
*
* COMMENTS : All instances on the machine are returned here and
* all properties that this class knows how to populate must
* be filled in. If there are no instances, return
* WBEM_S_NO_ERROR.
*****************************************************************************/
HRESULT CWin32_TerminalServiceSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
HRESULT hr = WBEM_E_INVALID_PARAMETER;
CInstance* pInstance = CreateNewInstance(pMethodContext);
if( pInstance != NULL )
{
TRC2((TB, "TerminalServiceSetting@EnumerateInstances: CreateNewInstance succeeded"));
hr = LoadPropertyValues(pInstance, BIT_ALL_PROPERTIES);
if( SUCCEEDED( hr ))
{
hr = pInstance->Commit();
}
pInstance->Release( );
}
return hr ;
}
//=---------
/*****************************************************************************
*
* FUNCTION : CWin32_TerminalServiceSetting::GetObject
*
* DESCRIPTION : Find a single instance based on the key property, the TerminalName.
*
* INPUTS : A pointer to a CInstance object containing the key properties.
* A long that contains the flags described in
* IWbemServices::GetObjectAsync.
*
* RETURNS : WBEM_S_NO_ERROR if the instance can be found
* WBEM_E_NOT_FOUND if the instance described by the key properties
* could not be found
* WBEM_E_FAILED if the instance could be found but another error
* occurred.
*
*****************************************************************************/
HRESULT CWin32_TerminalServiceSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
HRESULT hr = WBEM_S_NO_ERROR;
DWORD dwMode = 0; // Mode
BOOL bActivate ;
DWORD dwStatus = 0;
CRegistry oRegObject;
DWORD dwData = 0;
DWORD dwRequiredProperties = 0;
if( Query.IsPropertyRequired(m_szServerName))
dwRequiredProperties |= BIT_SERVERNAME;
if (Query.IsPropertyRequired(m_szMode))
dwRequiredProperties |= BIT_MODE;
if (Query.IsPropertyRequired(m_szActiveDesktop))
dwRequiredProperties |= BIT_ACTIVEDESKTOP;
if (Query.IsPropertyRequired(m_szDeleteTempFolders))
dwRequiredProperties |= BIT_DELETETEMPDIRS;
if (Query.IsPropertyRequired(m_szLicensingType))
dwRequiredProperties |= BIT_LICENSING;
if (Query.IsPropertyRequired(m_szLicensingName))
dwRequiredProperties |= BIT_LICENSING;
if (Query.IsPropertyRequired(m_szLicensingDescription))
dwRequiredProperties |= BIT_LICENSING;
if (Query.IsPropertyRequired(m_szLogons))
dwRequiredProperties |= BIT_LOGONS;
if (Query.IsPropertyRequired(m_szUserPerm))
dwRequiredProperties |= BIT_USERPERM;
if (Query.IsPropertyRequired(m_szUseTempFolders))
dwRequiredProperties |= BIT_PERSESSIONTEMPDIR;
if (Query.IsPropertyRequired(m_szHelp))
dwRequiredProperties |= BIT_HELP;
if (Query.IsPropertyRequired(m_szAllowTSConnections))
dwRequiredProperties |= BIT_ALLOWTSCONNECTIONS;
if (Query.IsPropertyRequired(m_szSingleSession))
dwRequiredProperties |= BIT_SINGLESESSION;
if (Query.IsPropertyRequired(m_szProfilePath))
dwRequiredProperties |= BIT_PROFILEPATH;
if (Query.IsPropertyRequired(m_szHomeDirectory))
dwRequiredProperties |= BIT_HOMEDIRECTORY;
if (Query.IsPropertyRequired(m_szDirectConnectLicenseServers))
dwRequiredProperties |= BIT_DIRECTCONNECTLICENSESERVERS;
if (Query.IsPropertyRequired(m_szTimeZoneRedirection))
dwRequiredProperties |= BIT_TIMEZONEREDIRECTION;
if (Query.IsPropertyRequired(m_szDisableForcibleLogoff))
dwRequiredProperties |= BIT_DISABLEFORCIBLELOGOFF;
hr = LoadPropertyValues(pInstance, dwRequiredProperties);
return S_OK ;
}
//=---------
/*****************************************************************************
*
* FUNCTION : CWin32_TerminalServiceSetting::ExecQuery
*
* DESCRIPTION : The method context is passed for use in the creation of
* instances that satisfy the query, and a CFrameworkQuery
* which describes the query. Create and populate all
* instances which satisfy the query. You may return more
* instances or more properties than are requested and WinMgmt
* will post filter out any that do not apply.
*
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
* A query object describing the query to satisfy.
* A long that contains the flags described in
* IWbemServices::CreateInstanceEnumAsync. Note that the following
* flags are handled by (and filtered out by) WinMgmt:
* WBEM_FLAG_FORWARD_ONLY
* WBEM_FLAG_BIDIRECTIONAL
* WBEM_FLAG_ENSURE_LOCATABLE
*
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if queries not supported for
* this class or if the query is too complex for this class
* to interpret. The framework will call the EnumerateInstances
* function instead and let Winmgmt post filter.
* WBEM_E_FAILED if the query failed
* WBEM_S_NO_ERROR if query was successful
*
* COMMENTS : TO DO: Most providers will not need to implement this method. If you don't, WinMgmt
* will call your enumerate function to get all the instances and perform the
* filtering for you. Unless you expect SIGNIFICANT savings from implementing
* queries, you should remove this method. You should also remove this method
* if you are implementing a 'method only' provider.
*
*****************************************************************************/
HRESULT CWin32_TerminalServiceSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
HRESULT hr = WBEM_E_NOT_FOUND;
DWORD dwRequiredProperties = 0;
CHStringArray asNames;
DWORD dwMode = 0;
DWORD dwStatus = 0;
CStackClass StackObj;
if( StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
// Method 2
Query.GetValuesForProp(m_szServerName, asNames);
BOOL bGetAllInstances = asNames.GetSize() == 0;
// Method 1
if (Query.IsPropertyRequired(m_szServerName))
dwRequiredProperties |= BIT_SERVERNAME;
if (Query.IsPropertyRequired(m_szMode))
dwRequiredProperties |= BIT_MODE;
if (Query.IsPropertyRequired(m_szActiveDesktop))
dwRequiredProperties |= BIT_ACTIVEDESKTOP;
if (Query.IsPropertyRequired(m_szDeleteTempFolders))
dwRequiredProperties |= BIT_DELETETEMPDIRS;
if (Query.IsPropertyRequired(m_szLicensingType))
dwRequiredProperties |= BIT_LICENSING;
if (Query.IsPropertyRequired(m_szLogons))
dwRequiredProperties |= BIT_LOGONS;
if (Query.IsPropertyRequired(m_szUserPerm))
dwRequiredProperties |= BIT_USERPERM;
if (Query.IsPropertyRequired(m_szUseTempFolders))
dwRequiredProperties |= BIT_PERSESSIONTEMPDIR;
if (Query.IsPropertyRequired(m_szHelp))
dwRequiredProperties |= BIT_HELP;
if (Query.IsPropertyRequired(m_szAllowTSConnections))
dwRequiredProperties |= BIT_ALLOWTSCONNECTIONS;
if (Query.IsPropertyRequired(m_szSingleSession))
dwRequiredProperties |= BIT_SINGLESESSION;
if (Query.IsPropertyRequired(m_szProfilePath))
dwRequiredProperties |= BIT_PROFILEPATH;
if (Query.IsPropertyRequired(m_szHomeDirectory))
dwRequiredProperties |= BIT_HOMEDIRECTORY;
if (Query.IsPropertyRequired(m_szDirectConnectLicenseServers))
dwRequiredProperties |= BIT_DIRECTCONNECTLICENSESERVERS;
if (Query.IsPropertyRequired(m_szTimeZoneRedirection))
dwRequiredProperties |= BIT_TIMEZONEREDIRECTION;
if (Query.IsPropertyRequired(m_szDisableForcibleLogoff))
dwRequiredProperties |= BIT_DISABLEFORCIBLELOGOFF;
ISettingsComp *pSettings = NULL;
hr = StackObj.m_pCfgComp->QueryInterface( IID_ISettingsComp , ( PVOID * )&pSettings ) ;
do
{
if( SUCCEEDED( hr ) && pSettings != NULL )
{
// Method 2
CInstance* pInstance = CreateNewInstance(pMethodContext);
if( pInstance == NULL)
{
ERR((TB, "TerminalServiceSetting@ExecQuery: CreateNewInstance failed"));
hr = WBEM_E_OUT_OF_MEMORY;
break;
}
hr = LoadPropertyValues(pInstance, dwRequiredProperties);
if( SUCCEEDED( hr ) )
{
hr = pInstance->Commit();
}
pInstance->Release();
}
}while (0);
if ( pSettings != NULL )
{
pSettings->Release();
}
return hr;
}
//=--------------
BOOL CWin32_TerminalServiceSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
DWORD dwSize = asArray.GetSize();
for (DWORD x=0; x < dwSize; x++)
{
if( asArray[x].CompareNoCase(pszString) == 0 )
{
return TRUE;
}
}
return FALSE;
}
//=---------
/*************************************************************************************
*
* FUNCTION : CWin32_TerminalServiceSetting::PutInstance
*
* DESCRIPTION : PutInstance is in provider classes that can
* write instance information back to the registry.
*
* INPUTS : A pointer to a CInstance object containing the key
* property - TerminalServerMode.
*
* A long that contains the flags described in
* IWbemServices::PutInstanceAsync.
*
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available
* WBEM_E_FAILED if there is an error delivering the instance
* WBEM_E_INVALID_PARAMETER if any of the instance properties
* are incorrect.
* WBEM_S_NO_ERROR if instance is properly delivered
*
* COMMENTS : ActiveDesktop state, UserPerm and Logon are configurable through
* this method as they are not Group Policy based nor server-overridable.
*
***************************************************************************************/
HRESULT CWin32_TerminalServiceSetting::PutInstance ( const CInstance &Instance, long lFlags)
{
HRESULT hr = 0;
DWORD dwMode = 0;
DWORD dwlicensing = 0; // Licensing mode
DWORD dwActiveDesktop = 0; // Active Desktop Enabled or Disabled
DWORD dwUserPerm = 0; // Application Compatibility
DWORD dwDeleteTempFolders = 0; // Delete Temporary Directories on Exit
DWORD dwUseTempFolders = 0;
DWORD dwData = 0;
DWORD dwStatus = 0;
CHString chData;
CRegistry oRegObject;
OSVERSIONINFOW OsVersionInfo;
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
TCHAR tch[MAX_PATH] = {0};
ICfgComp *pCfgComp = NULL;
HKEY hKey = NULL;
HKEY hOutKey = NULL;
hr = WBEM_S_NO_ERROR;
CStackClass StackObj;
if(StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
ISettingsComp *pSettings = NULL;
hr = StackObj.m_pCfgComp->QueryInterface( IID_ISettingsComp , ( PVOID * )&pSettings ) ;
do
{
if( SUCCEEDED (hr) && pSettings != NULL )
{
if( Instance.GetDWORD(m_szActiveDesktop, dwActiveDesktop ) )
{
hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TS_ACTIVEDESKTOP ,
0,
KEY_READ ,
&hKey );
if( ERROR_SUCCESS == hr )
{
hr = RegCreateKeyEx( hKey ,
L"Explorer",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hOutKey ,
&dwData );
}
if( dwActiveDesktop != 0 && dwActiveDesktop != 1 )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
pSettings->SetActiveDesktopState( dwActiveDesktop, &dwStatus );
TRC2((TB, "TerminalServiceSetting@PutInstance: SetActiveDesktopState returned 0x%x\n" , dwStatus));
}
if( Instance.GetDWORD( m_szUserPerm, dwUserPerm ) )
{
if( dwUserPerm != 0 && dwUserPerm != 1 )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
pSettings->SetUserPerm(dwUserPerm, &dwStatus );
TRC2((TB, "TerminalServiceSetting@PutInstance: SetUserPerm returned 0x%x\n" , dwStatus));
}
hr = oRegObject.OpenKey(HKEY_LOCAL_MACHINE, TS_LOGON_PATH);
chData.Empty();
if( SUCCEEDED( hr ) )
{
if( GetVersionEx( &OsVersionInfo) )
{
if( OsVersionInfo.dwMajorVersion == 5 && OsVersionInfo.dwMinorVersion == 0 )
{
TRC2((TB, "TerminalServiceSetting@GetObject GetVersionInfo is Win2000"));
if( Instance.GetCHString(m_szLogons, chData ) )
{
if( chData.IsEmpty() || ((lstrcmp ((LPCTSTR)chData, L"0") != 0 ) && (lstrcmp ((LPCTSTR) chData, L"1") != 0)) )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
// Todo: Add this for Beta2 to reverse logic
/*
if( lstrcmp ((LPCTSTR)chData, L"0") == 0 )
{
chData.Empty();
chData = L"1";
}
else
{
chData.Empty();
chData = L"0";
}
*/
hr = oRegObject.WriteRegString(L"WinStationsDisabled", (LPTSTR) (LPCTSTR) chData);
TRC2((TB, "TerminalServiceSetting@PutInstance WinStationsDisabled returned 0x%x\n" , hr));
}
}
else
{
TRC2((TB, "TermServiceSetting@PutInstance GetVersionInfo is Whistler"));
if( Instance.GetCHString(m_szLogons, chData ) )
{
if( chData.IsEmpty() || ((lstrcmp ((LPCTSTR)chData, L"0") != 0 ) && (lstrcmp ((LPCTSTR) chData, L"1") != 0)) )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
/*
if( lstrcmp ((LPCTSTR)chData, L"0") == 0 )
{
chData.Empty();
chData = L"1";
}
else
{
chData.Empty();
chData = L"0";
}
*/
hr = oRegObject.WriteRegString(L"WinStationsDisabled", (LPTSTR) (LPCTSTR) chData);
TRC2((TB, "TermServiceSetting@PutInstance WinStationDisabled returned 0x%x\n" , hr));
}
}
}
}
// ForceUpdate() is called explicitly to update WinstationsDisabled in the registry.
if( SUCCEEDED( hr ) )
{
StackObj.m_pCfgComp->ForceUpdate();
}
}
}while(0);
if( NULL != hKey)
{
RegCloseKey(hKey);
}
if( NULL != hOutKey)
{
RegCloseKey(hOutKey);
}
if( pSettings != NULL )
{
pSettings->Release();
}
return hr;
}
//=---------
/*****************************************************************************
*
* FUNCTION : CWin32_TerminalServiceSetting::DeleteInstance
*
* DESCRIPTION : DeleteInstance, like PutInstance, actually writes information
* to the software or hardware. For most hardware devices,
* DeleteInstance should not be implemented, but for software
* configuration, DeleteInstance implementation is plausible.
*
* INPUTS : A pointer to a CInstance object containing the key properties.
* A long that contains the flags described in
* IWbemServices::DeleteInstanceAsync.
*
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if DeleteInstance is not available.
* WBEM_E_FAILED if there is an error deleting the instance.
* WBEM_E_INVALID_PARAMETER if any of the instance properties
* are incorrect.
* WBEM_S_NO_ERROR if instance is properly deleted.
*
* COMMENTS : TO DO: If you don't intend to support deleting instances or are
* creating a 'method only' provider, remove this method.
*
*****************************************************************************/
HRESULT CWin32_TerminalServiceSetting::DeleteInstance ( const CInstance &Instance, long lFlags )
{
return (WBEM_E_PROVIDER_NOT_CAPABLE);
}
//=---------
/*****************************************************************************
*
* FUNCTION : CWin32_TerminalServiceSetting::ExecMethod
*
* DESCRIPTION : Override this function to provide support for methods.
* A method is an entry point for the user of your provider
* to request your class perform some function above and
* beyond a change of state. (A change of state should be
* handled by PutInstance() )
*
* INPUTS : A pointer to a CInstance containing the instance the method was executed against.
* A string containing the method name
* A pointer to the CInstance which contains the IN parameters.
* A pointer to the CInstance to contain the OUT parameters.
* A set of specialized method flags
*
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if not implemented for this class
* WBEM_S_NO_ERROR if method executes successfully
* WBEM_E_FAILED if error occurs executing method
*
* COMMENTS : Provides method to configure the License type base on
* the Terminal server mode, UseTempFolders, DeleteTempFolders
* and Help that are group policy based.
*
*****************************************************************************/
HRESULT CWin32_TerminalServiceSetting::ExecMethod ( const CInstance& Inst,
const BSTR bstrMethodName,
CInstance *pInParams,
CInstance *pOutParams,
long lFlags)
{
DWORD dwMode = 0;
DWORD dwLicensing = 0;
DWORD dwStatus = 0;
DWORD dwNewStatus = 0;
DWORD dwData = 0;
HANDLE hServer = NULL;
BOOL fRet = FALSE;
CHString chData;
bool fData;
bool bRet;
CRegistry oRegObject;
HRESULT hr = WBEM_E_INVALID_PARAMETER;
CStackClass StackObj;
HKEY hKey = NULL;
HKEY hOutKey = NULL;
if(StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
ISettingsComp *pSettings = NULL;
if(pInParams == NULL)
{
return WBEM_E_INVALID_METHOD_PARAMETERS;
}
hr = StackObj.m_pCfgComp->QueryInterface( IID_ISettingsComp , ( PVOID * )&pSettings ) ;
do
{
if( SUCCEEDED (hr) && pSettings != NULL )
{
if( _wcsicmp(bstrMethodName, m_szChangeMode) == 0 )
{
// Configures License type based on the Terminal Server Mode. {None, Remote Administration} for "Remote Admin",
// {Per Seat, Per CPU, ICL} for "Application Server" and {Personal Terminal Server} for "Personal Terminal Server".
// uint32 ChangeMode([In] uint32 LicensingType);
hr = WBEM_S_NO_ERROR ;
bRet = pInParams->GetDWORD(m_szLicensingType, dwLicensing);
if ( !bRet )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hServer = ServerLicensingOpen(NULL);
if (NULL != hServer)
{
dwStatus = ServerLicensingSetPolicy(hServer, dwLicensing, &dwNewStatus);
TRC2( (TB, "TermServiceSetting@ExecMethod:ChangeMode ServerLicensingSetPolicy ret old: 0x%x new: 0x%x\n" , dwStatus, dwNewStatus) );
if( ERROR_SUCCESS == dwStatus && ERROR_SUCCESS == dwNewStatus && pOutParams != NULL )
{
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
}
else if( ERROR_SUCCESS != dwStatus || ERROR_SUCCESS != dwNewStatus )
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
}
else if( _wcsicmp( bstrMethodName, m_szSetAllowTSConnections ) == 0 )
{
dwData = 0;
dwStatus = 0;
bRet;
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyDenyTSConnections == 0 )
{
TRC2((TB, "Condition to update fPolicyDenyTSConnections satisfied"));
bRet = pInParams->GetDWORD(m_szAllowTSConnections, dwData);
if ( !bRet || (dwData != 0 && dwData != 1 ))
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
// The bit is negated because it calls the function SetDenyTSConnections which is negative logic.
if( dwData == 0 )
{
dwData = 1;
}
else if( dwData == 1 )
{
dwData = 0;
}
hr = pSettings->SetDenyTSConnections( dwData , &dwStatus );
if( SUCCEEDED( hr ) && pOutParams != NULL )
{
hr = StackObj.m_pCfgComp->ForceUpdate();
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
TRC2((TB,"TerminalServiceSetting@ExecMethod: SetAllowTSConnections ret 0x%x\n" , hr ));
}
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( _wcsicmp( bstrMethodName, m_szSetTimeZoneRedirection ) == 0 )
{
dwData = 0;
dwStatus = 0;
bRet;
RegGetMachinePolicy(&m_gpPolicy);
//todo: change the policy name
if( m_gpPolicy.fPolicyEnableTimeZoneRedirection == 0 )
{
TRC2((TB, "Condition to update fPolicyEnableTimeZoneRedirection satisfied"));
bRet = pInParams->GetDWORD(m_szTimeZoneRedirection, dwData);
if ( !bRet || (dwData != 0 && dwData != 1 ))
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hr = pSettings->SetTimeZoneRedirection( dwData , &dwStatus );
if( SUCCEEDED( hr ) && pOutParams != NULL )
{
hr = StackObj.m_pCfgComp->ForceUpdate();
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
TRC2((TB,"TerminalServiceSetting@ExecMethod: SetTimeZoneRedirection ret 0x%x\n" , hr ));
}
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( _wcsicmp( bstrMethodName, m_szSetSingleSession ) == 0 )
{
dwData = 0;
dwStatus = 0;
bRet;
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicySingleSessionPerUser == 0 )
{
TRC2((TB, "Condition to update fSingleSessionPerUser satisfied"));
bRet = pInParams->GetDWORD(m_szSingleSession, dwData);
if ( !bRet || (dwData != 0 && dwData != 1 ))
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hr = pSettings->SetSingleSessionState( dwData , &dwStatus );
if( SUCCEEDED( hr ) && pOutParams != NULL )
{
hr = StackObj.m_pCfgComp->ForceUpdate();
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
TRC2((TB,"TerminalServiceSetting@ExecMethod: SetSingleSession ret 0x%x\n" , hr ));
}
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( _wcsicmp( bstrMethodName, m_szSetProfilePath ) == 0 )
{
BSTR bstrVal = NULL;
dwStatus = 0;
bRet;
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyWFProfilePath == 0 )
{
TRC2((TB, "Condition to update WFProfilePath satisfied"));
bRet = pInParams->GetCHString(m_szProfilePath, chData);
if ( !bRet )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
bstrVal = SysAllocString((LPTSTR) (LPCTSTR) (chData));
if(bstrVal != NULL)
{
hr = pSettings->SetProfilePath( bstrVal , &dwStatus );
if( SUCCEEDED( hr ) && pOutParams != NULL )
{
hr = StackObj.m_pCfgComp->ForceUpdate();
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
TRC2((TB,"TerminalServiceSetting@ExecMethod: SetProfilePath ret 0x%x\n" , hr ));
}
}
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( _wcsicmp( bstrMethodName, m_szSetHomeDirectory ) == 0 )
{
BSTR bstrVal = NULL;
dwStatus = 0;
bRet;
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyWFHomeDir == 0 )
{
TRC2((TB, "Condition to update WFProfilePath satisfied"));
bRet = pInParams->GetCHString(m_szHomeDirectory, chData);
if ( !bRet )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
bstrVal = SysAllocString((LPTSTR) (LPCTSTR) (chData));
if(bstrVal != NULL)
{
hr = pSettings->SetHomeDir( bstrVal , &dwStatus );
if( SUCCEEDED( hr ) && pOutParams != NULL )
{
hr = StackObj.m_pCfgComp->ForceUpdate();
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
TRC2((TB,"TerminalServiceSetting@ExecMethod: SetHomeDirectory ret 0x%x\n" , hr ));
}
}
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( _wcsicmp( bstrMethodName, m_szSetDisableForcibleLogoff ) == 0 )
{
dwData = 0;
dwStatus = 0;
bRet;
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyDisableForcibleLogoff == 0 )
{
TRC2((TB, "Condition to update fDisableForcibleLogoff satisfied"));
bRet = pInParams->GetDWORD(m_szDisableForcibleLogoff, dwData);
if ( !bRet || (dwData != 0 && dwData != 1 ))
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hr = pSettings->SetDisableForcibleLogoff( dwData , &dwStatus );
if( SUCCEEDED( hr ) && pOutParams != NULL )
{
hr = StackObj.m_pCfgComp->ForceUpdate();
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
TRC2((TB,"TerminalServiceSetting@ExecMethod: SetDisableForcibleLogoff ret 0x%x\n" , hr ));
}
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( _wcsicmp(bstrMethodName, m_szSetPolicyPropertyName) == 0 )
{
// PropertyName is an enumeration of the properties:
// DeleteTempFolders, UseTempFolders and Help which are flags that are either set
// to False or True according as whether Value is set to 0 or 1 respectively.
//
// uint32 SetPolicyPropertyName([In] string PropertyName, [In] boolean Value) ;
bRet = 0;
RegGetMachinePolicy(&m_gpPolicy);
pInParams->GetCHString(m_szPropertyName, chData);
if( chData.CompareNoCase(m_szDeleteTempFolders) == 0 )
{
bRet = pInParams->Getbool(m_szValue, fData);
TRC2((TB, "m_gpPolicy.fPolicyDeleteTempFoldersOnExit ret 0x%x\n", m_gpPolicy.fPolicyDeleteTempFoldersOnExit));
if( m_gpPolicy.fPolicyDeleteTempFoldersOnExit == 0 )
{
TRC2((TB, "Condition to update fPolicyDeleteTempFoldersOnExit satisfied"));
if( !bRet || (fData != 0 && fData != 1 ))
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hr = pSettings->SetDelDirsOnExit(fData);
TRC2((TB, "TerminalServiceSetting@PutInstance: SetDelDirsOnExit"));
if( pOutParams != NULL )
{
pOutParams->SetDWORD(L"ReturnValue", hr);
}
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( chData.CompareNoCase(m_szUseTempFolders) == 0 )
{
bRet = 0;
bRet = pInParams->Getbool(L"Value", fData);
TRC2((TB, "m_gpPolicy.fPolicyTempFoldersPerSession ret 0x%x\n", m_gpPolicy.fPolicyTempFoldersPerSession));
if( m_gpPolicy.fPolicyTempFoldersPerSession == 0 )
{
TRC2((TB, "Condition to update fPolicyTempFoldersPerSession satisfied"));
if( !bRet || ( fData != 0 && fData != 1 ))
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hr = pSettings->SetUseTempDirPerSession(fData );
TRC2((TB, "TerminalServiceSetting@ExecMethod: SetUseTempDirPerSession"));
if( pOutParams != NULL )
{
pOutParams->SetDWORD(L"ReturnValue", hr);
}
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( chData.CompareNoCase(m_szHelp) == 0 )
{
bRet = 0;
hr = oRegObject.OpenKey(HKEY_LOCAL_MACHINE, TS_POLICY_SUB_TREE);
if( SUCCEEDED (hr) )
{
if( ERROR_SUCCESS != oRegObject.ReadRegDWord(POLICY_TS_REMDSK_ALLOWTOGETHELP, &dwData) )
{
bRet = pInParams->Getbool(m_szValue, fData);
TRC2((TB, "Condition to update fAllowToGetHelp satisfied"));
if( !bRet || (fData != 0 && fData != 1 ))
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hr = pSettings->SetSalemHelpMode(fData, &dwStatus );
TRC2((TB, "TerminalServiceSetting@ExecMethod: Help"));
if( pOutParams != NULL && dwStatus == ERROR_SUCCESS )
{
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
}
}
else
{
hr = WBEM_E_INVALID_METHOD_PARAMETERS;
break;
}
}
else if( _wcsicmp( bstrMethodName, m_szAddDirectConnectLicenseServer ) == 0 )
{
DWORD dwReturn = 0;
bRet = pInParams->GetCHString(m_szLicenseServerName, chData);
if( chData.IsEmpty() || (chData.GetLength() >= OPAQUESETTINGS_LENGTH) )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TERMINAL_SERVICE_PARAM_DISCOVERY ,
0,
KEY_READ ,
&hKey );
if( ERROR_SUCCESS == hr )
{
hr = RegCreateKeyEx( hKey ,
L"LicenseServers",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hOutKey ,
&dwReturn );
if( ERROR_SUCCESS == hr )
{
hr = RegCreateKeyEx( hOutKey ,
chData.LockBuffer(),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hOutKey ,
&dwReturn );
chData.UnlockBuffer();
TRC2((TB, "Win32_TerminalServiceSetting@ExecMethod: AddLicenseServer ret 0x%x" , hr));
}
if( hr == ERROR_SUCCESS )
{
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
}
chData.Empty();
}
}
else if( _wcsicmp( bstrMethodName, m_szDeleteDirectConnectLicenseServer ) == 0 )
{
DWORD dwReturn = 0;
bRet = pInParams->GetCHString(m_szLicenseServerName, chData );
if( chData.IsEmpty() || (chData.GetLength() >= OPAQUESETTINGS_LENGTH) )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TERMINAL_SERVICE_PARAM_DISCOVERY_SERVERS,
0,
KEY_ALL_ACCESS ,
&hKey );
if( ERROR_SUCCESS == hr )
{
hr = RegDeleteKey( hKey ,
chData.LockBuffer() );
TRC2((TB, "Win32_TerminalServiceSetting@ExecMethod: DeleteLicenseServer ret 0x%x" , hr));
if( hr == ERROR_SUCCESS )
{
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
}
chData.UnlockBuffer();
chData.Empty();
}
else
{
hr = S_OK;
}
}
}
}while (0);
if( NULL != hKey )
{
RegCloseKey(hKey);
}
if(NULL != hOutKey)
{
RegCloseKey(hOutKey);
}
if( NULL != hServer )
{
ServerLicensingClose(hServer);
}
if( pSettings != NULL )
{
pSettings->Release();
}
return hr;
}
//=---------
HRESULT CWin32_TerminalServiceSetting::LoadPropertyValues( CInstance *pInstance, DWORD dwRequiredProperties)
{
int Licensing;
DWORD dwMode = 0;
DWORD dwData = 0;
ULONG ulMode = 0;
CRegistry oRegObject;
DWORD dwSize = 0;
BOOL bData = 0;
BOOL bActivate = 0;
DWORD dwStatus = 0;
DWORD dwType = 0;
HANDLE hServer = NULL;
BYTE bbyte;
OSVERSIONINFOW OsVersionInfo;
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
LPTSTR lpLogon;
int iData;
LPLCPOLICYINFO_V1W pPolicyInfo = NULL;
ULONG ulInfoStructVersion = LCPOLICYINFOTYPE_CURRENT;
CHString chLogon;
CHString chData;
HKEY hParamKey = NULL;
HRESULT hr = WBEM_E_INVALID_PARAMETER;
CHString chServerName;
chServerName.Format(L"%s", (LPCTSTR)GetLocalComputerName());
CStackClass StackObj;
if(StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
if( pInstance == NULL )
{
ERR((TB, "TermServiceSetting@LoadPropertyValues: invalid interface"));
return E_FAIL;
}
ISettingsComp *pSettings = NULL;
hr = StackObj.m_pCfgComp->QueryInterface( IID_ISettingsComp , ( PVOID * )&pSettings ) ;
if( SUCCEEDED (hr) && pSettings != NULL )
{
if( dwRequiredProperties & BIT_SERVERNAME )
{
pInstance->SetCHString(m_szServerName, chServerName);
}
if( dwRequiredProperties & BIT_MODE )
{
pSettings->GetTermSrvMode(&dwMode , &dwStatus );
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetTermSrvMode returned 0x%x\n" , dwStatus));
if( ERROR_SUCCESS == dwStatus )
{
pInstance->SetDWORD(m_szMode, dwMode);
}
}
if( dwRequiredProperties & BIT_LICENSING )
{
hServer = ServerLicensingOpen(NULL);
if (NULL != hServer)
{
if( ServerLicensingGetPolicy( hServer, &ulMode ) )
{
TRC2((TB, "TermServiceSetting@LoadPropertyValues: ServerLicensingGetPolicy ret 0x%x\n" , dwStatus));
pInstance->SetDWORD(m_szLicensingType, (DWORD &)ulMode);
if( ServerLicensingGetPolicyInformation( hServer, ulMode, &ulInfoStructVersion,
(LPLCPOLICYINFOGENERIC *) &pPolicyInfo ))
{
pInstance->SetCHString(m_szLicensingName, pPolicyInfo->lpPolicyName );
pInstance->SetCHString(m_szLicensingDescription, pPolicyInfo->lpPolicyDescription );
ServerLicensingFreePolicyInformation((LPLCPOLICYINFOGENERIC *)&pPolicyInfo);
}
}
ServerLicensingClose(hServer);
}
}
if( dwRequiredProperties & BIT_ACTIVEDESKTOP )
{
pSettings->GetActiveDesktopState(&bActivate , &dwStatus );
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetActiveDesktopState returned 0x%x\n" , dwStatus));
if( ERROR_SUCCESS == dwStatus )
{
pInstance->SetDWORD(m_szActiveDesktop, (DWORD &)bActivate);
}
if( ERROR_FILE_NOT_FOUND == dwStatus )
{
pInstance->SetDWORD(m_szActiveDesktop, 1);
}
}
if( dwRequiredProperties & BIT_USERPERM )
{
pSettings->GetUserPerm(&bActivate , &dwStatus );
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetUserPerm returned 0x%x\n" , dwStatus));
if( ERROR_SUCCESS == dwStatus )
{
pInstance->SetDWORD(m_szUserPerm, bActivate);
}
}
if( dwRequiredProperties & BIT_DELETETEMPDIRS )
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyDeleteTempFoldersOnExit != 0 )
{
bActivate = m_gpPolicy.fDeleteTempFoldersOnExit;
}
else
{
pSettings->GetDelDirsOnExit( &bActivate );
}
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetDelDirsOnExit returned 0x%x\n" , hr));
pInstance->SetDWORD(m_szDeleteTempFolders, bActivate);
}
if( dwRequiredProperties & BIT_PERSESSIONTEMPDIR )
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyTempFoldersPerSession != 0 )
{
bActivate = m_gpPolicy.fTempFoldersPerSession;
}
else
{
pSettings->GetUseTempDirPerSession(&bActivate );
}
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetUseTempDirsPerSession returned 0x%x\n" , hr));
pInstance->SetDWORD(m_szUseTempFolders, bActivate);
}
if( dwRequiredProperties & BIT_LOGONS )
{
hr = oRegObject.OpenKey(HKEY_LOCAL_MACHINE, TS_LOGON_PATH);
if( SUCCEEDED( hr ) )
{
if( GetVersionEx( &OsVersionInfo) )
{
if( OsVersionInfo.dwMajorVersion == 5 && OsVersionInfo.dwMinorVersion == 0 )
{
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetVersionInfo is Win2000"));
dwData = 0;
hr = oRegObject.ReadRegDWord(L"WinStationsDisabled", &dwData);
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetWinStationsDisabled returned 0x%x\n" , hr));
if( SUCCEEDED (hr) )
{
if( dwData == 0 )
{
pInstance->SetCharSplat(m_szLogons, L"0");
}
else
{
pInstance->SetCharSplat(m_szLogons, L"1");
}
}
}
else
{
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetVersionInfo is Whistler"));
hr = oRegObject.ReadRegString(L"WinStationsDisabled", &lpLogon, &dwData);
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetWinStationsDisabled returned 0x%x\n" , hr));
if( SUCCEEDED( hr ) )
{
pInstance->SetCharSplat(m_szLogons, lpLogon);
}
}
}
}
}
if( dwRequiredProperties & BIT_HELP )
{
hr = pSettings->GetSalemHelpMode(&iData, &dwStatus );
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetHelp returned 0x%x" , dwStatus));
if( S_OK == dwStatus )
{
pInstance->SetDWORD(m_szHelp, iData);
}
else
{
pInstance->SetDWORD(m_szHelp, 0);
}
}
if( dwRequiredProperties & BIT_ALLOWTSCONNECTIONS )
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyDenyTSConnections != 0 )
{
iData = m_gpPolicy.fDenyTSConnections;
}
else
{
hr = pSettings->GetDenyTSConnections(&iData, &dwStatus );
TRC2((TB, "TermServiceSetting@LoadPropertyValues: GetAllowTSConnections returned 0x%x" , dwStatus));
}
// The bit is negated because it calls the function GetDenyTSConnections which is negative logic.
if( iData == 0)
{
iData = 1;
}
else if( iData == 1)
{
iData = 0;
}
pInstance->SetDWORD(m_szAllowTSConnections, iData);
TRC2((TB,"TerminalServiceSetting@LoadPropertyValues: AllowTSConnections" ));
}
if( dwRequiredProperties & BIT_TIMEZONEREDIRECTION )
{
RegGetMachinePolicy(&m_gpPolicy);
//todo: change policy name
if( m_gpPolicy.fPolicyEnableTimeZoneRedirection != 0 )
{
iData = m_gpPolicy.fEnableTimeZoneRedirection;
}
else
{
hr = pSettings->GetTimeZoneRedirection(&iData, &dwStatus );
if(dwStatus != ERROR_SUCCESS)
{
iData = 0;
}
TRC2((TB, "TerminalServiceSetting@LoadPropertyValues: GetTimeZoneRedirection returned 0x%x" , dwStatus));
}
pInstance->SetDWORD(m_szTimeZoneRedirection, iData);
TRC2((TB,"TerminalServiceSetting@LoadPropertyValues: TimeZoneRedirection" ));
}
if( dwRequiredProperties & BIT_SINGLESESSION)
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicySingleSessionPerUser != 0 )
{
bData = m_gpPolicy.fSingleSessionPerUser;
}
else
{
hr = pSettings->GetSingleSessionState( &bData, &dwStatus);
}
dwData = bData;
pInstance->SetDWORD(m_szSingleSession, dwData);
TRC2((TB,"TermServiceSetting@LoadPropertyValues: SingleSession" ));
}
if( dwRequiredProperties & BIT_DISABLEFORCIBLELOGOFF)
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyDisableForcibleLogoff != 0 )
{
bData = m_gpPolicy.fDisableForcibleLogoff;
}
else
{
hr = pSettings->GetDisableForcibleLogoff( &bData, &dwStatus);
}
dwData = bData;
pInstance->SetDWORD(m_szDisableForcibleLogoff, dwData);
TRC2((TB,"TermServiceSetting@LoadPropertyValues: DisableForcibleLogoff" ));
}
if( dwRequiredProperties & BIT_PROFILEPATH)
{
BSTR bstrData = NULL;
chData.Empty();
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyWFProfilePath != 0 )
{
chData.Format(L"%s", m_gpPolicy.WFProfilePath);
}
else
{
hr = pSettings->GetProfilePath( &bstrData, &dwStatus);
if( bstrData != NULL)
{
chData.Format(L"%s", (LPCWSTR)(bstrData));
SysFreeString(bstrData);
}
}
pInstance->SetCHString(m_szProfilePath, chData);
TRC2((TB,"TermServiceSetting@LoadPropertyValues: ProfilePath" ));
}
if( dwRequiredProperties & BIT_HOMEDIRECTORY)
{
BSTR bstrData = NULL;
chData.Empty();
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicyWFHomeDir != 0 )
{
chData.Format(L"%s", m_gpPolicy.WFHomeDir);
}
else
{
hr = pSettings->GetHomeDir( &bstrData, &dwStatus);
if(bstrData != NULL)
{
chData.Format(L"%s", (LPCWSTR)(bstrData));
SysFreeString(bstrData);
}
}
pInstance->SetCHString(m_szHomeDirectory, chData);
TRC2((TB,"TermServiceSetting@LoadPropertyValues: HomeDirectory" ));
}
if( dwRequiredProperties & BIT_DIRECTCONNECTLICENSESERVERS)
{
DWORD dwValueType;
DWORD cbValue = 0, dwDisp;
LONG lReturn;
DWORD cbServer;
DWORD cServers;
DWORD cchServerMax;
LPWSTR szServer;
DWORD i, j;
CHString chServers;
chServers.Empty();
do
{
lReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TERMINAL_SERVICE_PARAM_DISCOVERY_SERVERS,
0,
KEY_READ,
&hParamKey );
if (ERROR_SUCCESS != lReturn)
{
break;
}
lReturn = RegQueryInfoKey(hParamKey,
NULL,
NULL,
NULL,
&cServers,
&cchServerMax,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
if (ERROR_SUCCESS != lReturn)
{
RegCloseKey( hParamKey );
break;
}
if (0 == cServers)
{
RegCloseKey( hParamKey );
hParamKey = NULL;
break;
}
// Add one for null terminator
cchServerMax++;
szServer = (LPWSTR) LocalAlloc(LPTR,cchServerMax * sizeof(WCHAR));
if(NULL == szServer)
{
LocalFree(szServer);
RegCloseKey( hParamKey );
hParamKey = NULL;
break;
}
for (i = 0; i < cServers; i++)
{
if(!chServers.IsEmpty())
{
chServers+=L"; ";
}
cbServer = cchServerMax * sizeof(WCHAR);
lReturn = RegEnumKeyEx(hParamKey,
i,
szServer,
&cbServer,
NULL,
NULL,
NULL,
NULL);
if (ERROR_SUCCESS != lReturn)
{
LocalFree(szServer);
RegCloseKey( hParamKey );
hParamKey = NULL;
break;
}
chServers+= szServer;
}
if(szServer)
{
LocalFree(szServer);
}
pInstance->SetCHString(m_szDirectConnectLicenseServers, chServers);
}while(0);
}
}
if(hParamKey)
{
RegCloseKey(hParamKey);
}
if( pSettings != NULL )
{
pSettings->Release();
}
return S_OK;
}
//=---------
/*************************************************************************************
*
* DESCRIPTION : CWin32_TerminalService class is subclassed from the Win32_Service
* class in CIM schema. It provides live information such as Total
* sessions, Disconnected sessions, Resource constraint and
* Raw session capacity.
*
***************************************************************************************/
CWin32_TerminalService::CWin32_TerminalService (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider( lpwszName, lpwszNameSpace )
{
if (g_hInstance != NULL)
{
TRC2((TB, "CWin32_TerminalService_ctor"));
_tcscpy(m_szName, _T("Name"));
_tcscpy(m_szCaption, _T("Caption"));
_tcscpy(m_szTotalSessions, _T("TotalSessions"));
_tcscpy(m_szDisconnectedSessions, _T("DisconnectedSessions"));
/*
_tcscpy(m_szEstimatedSessionCapacity, _T("EstimatedSessionCapacity"));
_tcscpy(m_szResourceConstraint, _T("ResourceConstraint"));
_tcscpy(m_szRawSessionCapacity, _T("RawSessionCapacity"));
*/
}
}
//=-----------------
CWin32_TerminalService::~CWin32_TerminalService ()
{
}
//=--------------------
/************************************************************************************
*
* DESCRIPTION : Find a single instance based on the key property, "Name".
*
* INPUTS : A pointer to a CInstance object containing the key property, "Name".
* A long that contains the flags described in
* IWbemServices::GetObjectAsync.
*
* RETURNS : WBEM_S_NO_ERROR if the instance can be found
* WBEM_E_NOT_FOUND if the instance described by the key properties
* could not be found
* WBEM_E_FAILED if the instance could be found but another error
* occurred.
*
**************************************************************************************/
HRESULT CWin32_TerminalService::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
HRESULT hr = WBEM_E_NOT_FOUND;
CHString chServerName;
TCHAR tchServer[MAX_PATH] = {0};
HANDLE hServerName = SERVERNAME_CURRENT;
ULONG CurrentLogonId = (ULONG) -1;
WINSTATIONLOADINDICATORDATA LIData;
ULONG Length = 0;
DWORD dwRequiredProperties = 0;
CHString chName;
pInstance->GetCHString(m_szName, chName);
pInstance->SetCHString(m_szCaption, chName);
if( chName.CompareNoCase(L"TermService") == 0 )
{
chServerName.Format(L"%s", (LPCTSTR)GetLocalComputerName());
wcscpy (tchServer, chServerName);
bool bRet = 0;
if (Query.IsPropertyRequired(m_szTotalSessions))
dwRequiredProperties |= BIT_TOTALSESSIONS;
if (Query.IsPropertyRequired(m_szDisconnectedSessions))
dwRequiredProperties |= BIT_DISCONNECTEDSESSIONS;
/*
if (Query.IsPropertyRequired(m_szEstimatedSessionCapacity))
dwRequiredProperties |= BIT_ESTIMATEDSESSIONCAPACITY;
if (Query.IsPropertyRequired(m_szResourceConstraint))
dwRequiredProperties |= BIT_RESOURCECONSTRAINT;
if (Query.IsPropertyRequired(m_szRawSessionCapacity))
dwRequiredProperties |= BIT_RAWSESSIONCAPACITY;
*/
hServerName = WinStationOpenServer (tchServer);
CurrentLogonId = GetCurrentLogonId();
if( hServerName != NULL )
{
bRet = WinStationQueryInformation(hServerName, CurrentLogonId,
WinStationLoadIndicator,
&LIData,
sizeof(LIData), &Length) ;
if( bRet )
{
hr = LoadPropertyValues(pInstance, dwRequiredProperties, LIData);
}
}
else
{
ERR((TB, "Win32_TerminalService@GetObject: WinStationQueryInformation GetLastError returned: 0x%x\n" ,GetLastError()));
}
}
return hr;
}
//=------------------
/*****************************************************************************
*
* FUNCTION : CWin32_TerminalService::EnumerateInstances
*
* DESCRIPTION : Returns all the instances of this class.
*
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
* A long that contains the flags described in
* IWbemServices::CreateInstanceEnumAsync. Note that the following
* flags are handled by (and filtered out by) WinMgmt:
* WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY,
* WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
* RETURNS : WBEM_S_NO_ERROR if successful
*
* COMMENTS : All instances on the machine are returned here and
* all properties that this class knows how to populate must
* be filled in. If there are no instances, return
* WBEM_S_NO_ERROR.
*
*****************************************************************************/
HRESULT CWin32_TerminalService::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
return WBEM_S_NO_ERROR;
// Commented as implementation is protocol dependent
/*
CHString chServerName;
TCHAR tchServer[MAX_PATH] = {0};
HANDLE hServer = SERVERNAME_CURRENT;
WINSTATIONLOADINDICATORDATA LIData;
ULONG CurrentLogonId = (ULONG) -1;
ULONG Length;
chServerName.Format(L"%s", (LPCTSTR)GetLocalComputerName());
wcscpy (tchServer, chServerName);
hServer = WinStationOpenServer (tchServer);
bool bRet = 0;
CurrentLogonId = GetCurrentLogonId();
if (hServer != NULL)
{
bRet = WinStationQueryInformation(hServer, CurrentLogonId,
WinStationLoadIndicator,
&LIData,
sizeof(LIData), &Length);
TRC2((TB, "Win32_TerminalService@EnumerateInstances: WinStationQueryInformation bRet: 0x%x\n" , bRet));
if (bRet)
{
CInstance* pInstance = CreateNewInstance(pMethodContext);
if( pInstance != NULL )
{
pInstance->SetCHString(m_szServerName, chServerName);
hr = LoadPropertyValues(pInstance, BIT_ALL_PROPERTIES, LIData);
if ( SUCCEEDED( hr ))
{
hr = pInstance->Commit();
}
pInstance->Release();
}
}
}
else
{
TRC2((TB, "Win32_TerminalService@EnumerateInstances: WinStationQueryInformation GetLastError returned: 0x%x\n" , hr));
}
return hr;
*/
}
//=-------------
HRESULT CWin32_TerminalService::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
HRESULT hr = WBEM_S_NO_ERROR;
DWORD dwRequiredProperties = 0;
CHStringArray asNames;
DWORD dwMode;
DWORD dwStatus;
CHString chServerName;
TCHAR tchServer[MAX_PATH] = {0};
bool bRet = 0;
HANDLE hServerName = SERVERNAME_CURRENT;
WINSTATIONLOADINDICATORDATA LIData;
ULONG CurrentLogonId = (ULONG) -1;
ULONG Length = 0;
chServerName.Format(L"%s", (LPCTSTR)GetLocalComputerName());
wcscpy (tchServer, chServerName);
hServerName = WinStationOpenServer (tchServer);
CurrentLogonId = GetCurrentLogonId();
if( hServerName != NULL )
{
bRet = WinStationQueryInformation(hServerName, CurrentLogonId,
WinStationLoadIndicator,
&LIData,
sizeof(LIData), &Length);
if( bRet )
{
// Method 2
Query.GetValuesForProp(m_szName, asNames);
BOOL bGetAllInstances = asNames.GetSize() == 0;
// Method 1
if (Query.IsPropertyRequired(m_szTotalSessions))
dwRequiredProperties |= BIT_TOTALSESSIONS;
if (Query.IsPropertyRequired(m_szDisconnectedSessions))
dwRequiredProperties |= BIT_DISCONNECTEDSESSIONS;
/*
if (Query.IsPropertyRequired(m_szEstimatedSessionCapacity))
dwRequiredProperties |= BIT_ESTIMATEDSESSIONCAPACITY;
if (Query.IsPropertyRequired(m_szResourceConstraint))
dwRequiredProperties |= BIT_RESOURCECONSTRAINT;
if (Query.IsPropertyRequired(m_szRawSessionCapacity))
dwRequiredProperties |= BIT_RAWSESSIONCAPACITY;
*/
CInstance* pInstance = CreateNewInstance(pMethodContext);
if( pInstance != NULL)
{
pInstance->SetCHString(m_szName, chServerName);
pInstance->SetCHString(m_szCaption, chServerName);
hr = LoadPropertyValues( pInstance, dwRequiredProperties, LIData );
if( SUCCEEDED( hr ) )
{
hr = pInstance->Commit();
}
pInstance->Release();
}
else
{
ERR((TB, "Win32_TerminalService@GetObject@ExecQuery: CreateNewInstance failed"));
hr = WBEM_E_OUT_OF_MEMORY;
}
}
}
else
{
TRC2((TB, "Win32_TerminalService@ExecQuery: WinStationQueryInformation GetLastError returned: 0x%x\n" , GetLastError()));
}
return hr;
}
//=---------------------
HRESULT CWin32_TerminalService::LoadPropertyValues( CInstance *pInstance, DWORD dwRequiredProperties, WINSTATIONLOADINDICATORDATA LIData)
{
if( pInstance != NULL )
{
if( dwRequiredProperties & BIT_TOTALSESSIONS )
{
pInstance->SetDWORD(m_szTotalSessions, LIData.TotalSessions);
}
if( dwRequiredProperties & BIT_DISCONNECTEDSESSIONS )
{
pInstance->SetDWORD(m_szDisconnectedSessions, LIData.DisconnectedSessions);
}
/*
if( dwRequiredProperties & BIT_ESTIMATEDSESSIONCAPACITY )
{
pInstance->SetDWORD(m_szEstimatedSessionCapacity, LIData.RemainingSessionCapacity);
}
if( dwRequiredProperties & BIT_RESOURCECONSTRAINT )
{
switch( LIData.LoadFactor )
{
case 0:
pInstance->SetCharSplat(m_szResourceConstraint, L"Error");
break;
case 1:
pInstance->SetCharSplat(m_szResourceConstraint, L"PagedPool");
break;
case 2:
pInstance->SetCharSplat(m_szResourceConstraint, L"NonPagedPool");
break;
case 3:
pInstance->SetCharSplat(m_szResourceConstraint, L"Available Memory");
break;
case 4:
pInstance->SetCharSplat(m_szResourceConstraint, L"System PTEs");
break;
case 5:
pInstance->SetCharSplat(m_szResourceConstraint, L"CPU");
break;
default:
pInstance->SetCharSplat(m_szResourceConstraint, L"Error");
break;
}
}
if( dwRequiredProperties & BIT_RAWSESSIONCAPACITY )
{
pInstance->SetDWORD(m_szRawSessionCapacity, LIData.RawSessionCapacity);
}
*/
}
return S_OK;
}
//=--------------
CWin32_TSSessionDirectory::CWin32_TSSessionDirectory (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider( lpwszName, lpwszNameSpace )
{
if ( g_hInstance != NULL)
{
TRC2((TB, "CWin32_TSSessionDirectory_ctor"));
_tcscpy(m_szMode, _T("TerminalServerMode"));
_tcscpy(m_szSessionDirectoryActive, _T("SessionDirectoryActive"));
_tcscpy(m_szSessionDirectoryLocation, _T("SessionDirectoryLocation"));
_tcscpy(m_szSessionDirectoryClusterName, _T("SessionDirectoryClusterName"));
// _tcscpy(m_szSessionDirectoryAdditionalParams, _T("SessionDirectoryAdditionalParams"));
_tcscpy(m_szSetSessionDirectoryProperty, _T("SetSessionDirectoryProperty"));
_tcscpy(m_szSetSessionDirectoryActive, _T("SetSessionDirectoryActive"));
_tcscpy(m_szPropertyName, _T("PropertyName"));
_tcscpy(m_szValue, _T("Value"));
_tcscpy(m_szSessionDirectoryExposeServerIP, _T("SessionDirectoryExposeServerIP"));
_tcscpy(m_szSetSessionDirectoryExposeServerIP, _T("SetSessionDirectoryExposeServerIP"));
_tcscpy(m_szSessionDirectoryIPAddress, _T("SessionDirectoryIPAddress"));
}
}
//=-------------
CWin32_TSSessionDirectory::~CWin32_TSSessionDirectory ()
{
}
HRESULT
GetNLBIP(LPWSTR * ppwszRetIP)
{
HRESULT hr = S_OK;
IWbemLocator * pWbemLocator = NULL;
IWbemServices * pWbemServices = NULL;
IWbemClassObject * pWbemObj = NULL;
IEnumWbemClassObject * pWbemEnum = NULL;
BSTR bstrServer = NULL;
BSTR bstrNode = NULL;
BSTR bstrNameProperty = NULL;
ULONG uReturned;
VARIANT vtNLBNodeName;
size_t dwIPLength;
// make sure an empty buffer is passed in
if (*ppwszRetIP != NULL)
{
hr = E_INVALIDARG;
goto Cleanup;
}
// create an instance of the WMI Locator, need this to query WMI
hr = CoCreateInstance(CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
reinterpret_cast<void**>(&pWbemLocator));
if (FAILED(hr))
{
goto Cleanup;
}
// create a connection to WMI Namespace "root\\MicrosoftNLB";
bstrServer = SysAllocString(L"root\\MicrosoftNLB");
if (bstrServer == NULL)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
hr = pWbemLocator->ConnectServer(bstrServer,
NULL,
NULL,
0,
NULL,
0,
0,
&pWbemServices);
if (FAILED(hr))
{
goto Cleanup;
}
hr = CoImpersonateClient();
if (FAILED(hr))
{
goto Cleanup;
}
// Set the proxy so that impersonation of the client occurs.
hr = CoSetProxyBlanket(pWbemServices,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_DYNAMIC_CLOAKING);
if (FAILED(hr))
{
goto Cleanup;
}
// get instance of MicrosoftNLB_NodeSetting, this is where we can get the
// IP Address for the Cluster IP through the "Name" property
bstrNode = SysAllocString(L"MicrosoftNLB_NodeSetting");
if (bstrNode == NULL)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
hr = pWbemServices->CreateInstanceEnum(bstrNode,
WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pWbemEnum);
if (FAILED(hr))
{
goto Cleanup;
}
// we only need to look at one instance to get the NLB IP Address
hr = pWbemEnum->Next(WBEM_INFINITE,
1,
&pWbemObj,
&uReturned);
if (FAILED(hr))
{
// if NLB provider doesn't exist provider will fail to load
// this is ok so we'll return S_OK in this case
if (hr == WBEM_E_PROVIDER_LOAD_FAILURE || hr == WBEM_E_ACCESS_DENIED)
{
hr = S_OK;
*ppwszRetIP = NULL;
}
goto Cleanup;
}
// query the "Name" property which holds the IP address we want
bstrNameProperty = SysAllocString(L"Name");
if (bstrNameProperty == NULL)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
hr = pWbemObj->Get(bstrNameProperty,
0,
&vtNLBNodeName,
NULL,
NULL);
if (FAILED(hr))
{
goto Cleanup;
}
// We should get a string back
if (vtNLBNodeName.vt != VT_BSTR)
{
hr = E_UNEXPECTED;
goto Cleanup;
}
// allocate memory for the return string, *** CALLER MUST FREE THIS ***
dwIPLength = wcslen(vtNLBNodeName.bstrVal) + 1;
*ppwszRetIP = (LPWSTR)GlobalAlloc(GPTR, dwIPLength * sizeof(WCHAR));
if (*ppwszRetIP == NULL)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
// Copy the string into our return buffer
wcscpy(*ppwszRetIP, vtNLBNodeName.bstrVal);
(*ppwszRetIP)[dwIPLength - 1] = L'\0';
Cleanup:
if (pWbemLocator)
pWbemLocator->Release();
if (pWbemServices)
pWbemServices->Release();
if (pWbemEnum)
pWbemEnum->Release();
if (pWbemObj)
pWbemObj->Release();
if (bstrServer)
SysFreeString(bstrServer);
if (bstrNode)
SysFreeString(bstrNode);
if (bstrNameProperty)
SysFreeString(bstrNameProperty);
VariantClear(&vtNLBNodeName);
return hr;
}
//=------------
HRESULT CWin32_TSSessionDirectory::DeleteInstance ( const CInstance &Instance, long lFlags )
{
return WBEM_E_PROVIDER_NOT_CAPABLE;
}
//=-------------------
/*****************************************************************************
*
* FUNCTION : CWin32_TSSessionDirectory::EnumerateInstances
*
* DESCRIPTION : Returns all the instances of this class.
*
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
* A long that contains the flags described in
* IWbemServices::CreateInstanceEnumAsync. Note that the following
* flags are handled by (and filtered out by) WinMgmt:
* WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY,
* WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
* RETURNS : WBEM_S_NO_ERROR if successful
*
* COMMENTS : All instances on the machine are returned here and
* all properties that this class knows how to populate must
* be filled in. If there are no instances, return
* WBEM_S_NO_ERROR.
*****************************************************************************/
HRESULT CWin32_TSSessionDirectory::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
HRESULT hr = WBEM_E_INVALID_CLASS;
OSVERSIONINFOEX OsVersionInfo;
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
ISettingsComp* pSettings = NULL;
DWORD dwStatus = 0;
DWORD dwMode = 0;
CStackClass StackObj;
if(StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
if( GetVersionEx((OSVERSIONINFO*)&OsVersionInfo) )
{
if( ( OsVersionInfo.dwMajorVersion < 5 ) || ( OsVersionInfo.dwMajorVersion == 5 && OsVersionInfo.dwMinorVersion < 1 ))
{
return WBEM_E_INVALID_CLASS;
}
if(!(OsVersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE) && !( OsVersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
{
return WBEM_E_INVALID_CLASS;
}
}
hr = StackObj.m_pCfgComp->QueryInterface( IID_ISettingsComp , ( PVOID * )&pSettings ) ;
if( SUCCEEDED( hr ) && pSettings != NULL )
{
pSettings->GetTermSrvMode(&dwMode , &dwStatus );
TRC2((TB, "Win32_TSSessionDirectory@EnumInst: GetTermSrvMode: dwMode ret 0x%x\n" , dwMode));
if( ERROR_SUCCESS == dwStatus && dwMode == 1)
{
CInstance* pInstance = CreateNewInstance(pMethodContext);
if( pInstance != NULL )
{
TRC2((TB, "Win32_TSSessionDirectory@EnumerateInstances: CreateNewInstance succeeded"));
hr = LoadPropertyValues(pInstance, BIT_ALL_PROPERTIES);
if( SUCCEEDED( hr ))
{
hr = pInstance->Commit();
}
pInstance->Release( );
}
}
}
if( pSettings != NULL)
{
pSettings->Release();
}
return hr ;
}
//=-------------
HRESULT CWin32_TSSessionDirectory::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
OSVERSIONINFOEX OsVersionInfo ;
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
HRESULT hr = WBEM_E_INVALID_CLASS;
ISettingsComp* pSettings = NULL;
DWORD dwStatus = 0;
DWORD dwMode = 0;
ICfgComp *pCfgComp = NULL;
if( GetVersionEx((OSVERSIONINFO*)&OsVersionInfo) )
{
if( ( OsVersionInfo.dwMajorVersion < 5 ) || ( OsVersionInfo.dwMajorVersion == 5 && OsVersionInfo.dwMinorVersion < 1 ) )
{
return WBEM_E_INVALID_CLASS;
}
if(!(OsVersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE) && !( OsVersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
{
return WBEM_E_INVALID_CLASS;
}
}
CStackClass StackObj;
if(StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
hr = StackObj.m_pCfgComp->QueryInterface( IID_ISettingsComp , ( PVOID * )&pSettings ) ;
if( SUCCEEDED( hr ) && pSettings != NULL )
{
pSettings->GetTermSrvMode(&dwMode , &dwStatus );
if( ERROR_SUCCESS == dwStatus && dwMode == 1)
{
ULONGLONG dwRequiredProperties = 0;
if (Query.IsPropertyRequired(m_szMode))
dwRequiredProperties |= BIT_MODE;
if (Query.IsPropertyRequired(m_szSessionDirectoryActive))
dwRequiredProperties |= BIT_SESSIONDIRECTORYACTIVE;
if (Query.IsPropertyRequired(m_szSessionDirectoryLocation))
dwRequiredProperties |= BIT_SESSIONDIRECTORY;
if (Query.IsPropertyRequired(m_szSessionDirectoryClusterName))
dwRequiredProperties |= BIT_CLUSTERNAME;
if (Query.IsPropertyRequired(m_szSessionDirectoryExposeServerIP))
dwRequiredProperties |= BIT_SESSIONDIRECTORYEXPOSESERVERIP;
if (Query.IsPropertyRequired(m_szSessionDirectoryIPAddress))
dwRequiredProperties |= BIT_SESSIONDIRECTORYIPADDRESS;
/*
if (Query.IsPropertyRequired(m_szSessionDirectoryAdditionalParams))
dwRequiredProperties |= BIT_ADDITIONALPARAMS;
*/
if( pInstance != NULL )
{
hr = LoadPropertyValues(pInstance, dwRequiredProperties);
TRC2((TB, "Win32_TSSessionDirectory@GetObject: LoadPropertyValues ret 0x%x\n" , hr));
}
}
}
if( pSettings != NULL)
{
pSettings->Release();
}
return hr;
}
//=-----------------
HRESULT CWin32_TSSessionDirectory::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
DWORD dwRequiredProperties = 0;
CHStringArray asNames;
CHString chSessionDirectory;
HRESULT hr = WBEM_E_INVALID_CLASS;
ISettingsComp* pSettings = NULL;
DWORD dwStatus = 0;
DWORD dwMode = 0;
ICfgComp *pCfgComp = NULL;
OSVERSIONINFOEX OsVersionInfo;
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( GetVersionEx((OSVERSIONINFO*)&OsVersionInfo) )
{
if( ( OsVersionInfo.dwMajorVersion < 5 ) || ( OsVersionInfo.dwMajorVersion == 5 && OsVersionInfo.dwMinorVersion < 1 ))
{
return WBEM_E_INVALID_CLASS;
}
if(!(OsVersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE) && !( OsVersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
{
return WBEM_E_INVALID_CLASS;
}
}
CStackClass StackObj;
if(StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
hr = StackObj.m_pCfgComp->QueryInterface( IID_ISettingsComp , ( PVOID * )&pSettings ) ;
if( SUCCEEDED( hr ) && pSettings != NULL )
{
pSettings->GetTermSrvMode(&dwMode , &dwStatus );
if( ERROR_SUCCESS == dwStatus && dwMode == 1)
{
// Method 2
// Query.GetValuesForProp(m_szSessionDirectoryLocation, asNames);
Query.GetValuesForProp(m_szMode, asNames);
BOOL bGetAllInstances = asNames.GetSize() == 0;
// Method 1
if (Query.IsPropertyRequired(m_szMode))
dwRequiredProperties |= BIT_MODE;
if (Query.IsPropertyRequired(m_szSessionDirectoryActive))
dwRequiredProperties |= BIT_SESSIONDIRECTORYACTIVE;
if (Query.IsPropertyRequired(m_szSessionDirectoryLocation))
dwRequiredProperties |= BIT_SESSIONDIRECTORY;
if (Query.IsPropertyRequired(m_szSessionDirectoryClusterName))
dwRequiredProperties |= BIT_CLUSTERNAME;
if (Query.IsPropertyRequired(m_szSessionDirectoryExposeServerIP))
dwRequiredProperties |= BIT_SESSIONDIRECTORYEXPOSESERVERIP;
if (Query.IsPropertyRequired(m_szSessionDirectoryIPAddress))
dwRequiredProperties |= BIT_SESSIONDIRECTORYIPADDRESS;
/*
if (Query.IsPropertyRequired(m_szSessionDirectoryAdditionalParams))
dwRequiredProperties |= BIT_ADDITIONALPARAMS;
*/
// Method 2
CInstance* pInstance = CreateNewInstance(pMethodContext);
if( pInstance != NULL)
{
pInstance->SetCHString(m_szSessionDirectoryLocation, chSessionDirectory );
hr = LoadPropertyValues(pInstance, dwRequiredProperties);
if( SUCCEEDED( hr ) )
{
hr = pInstance->Commit();
}
pInstance->Release();
}
else
{
ERR((TB, "Win32_TSSessionDirectory@ExecQuery: CreateNewInstance failed"));
hr = WBEM_E_OUT_OF_MEMORY;
}
}
}
if( pSettings != NULL )
{
pSettings->Release();
}
return hr;
}
//=--------------
BOOL CWin32_TSSessionDirectory::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
DWORD dwSize = asArray.GetSize();
for( DWORD x=0; x < dwSize; x++ )
{
if( asArray[x].CompareNoCase(pszString) == 0 )
{
return TRUE;
}
}
return FALSE;
}
//=-------------
HRESULT CWin32_TSSessionDirectory::ExecMethod ( const CInstance& Inst,
const BSTR bstrMethodName,
CInstance *pInParams,
CInstance *pOutParams,
long lFlags)
{
DWORD dwData = 0;
CHString chData;
HKEY hKey = NULL;
LONG lRet = 0;
bool bRet;
bool bUpdate = FALSE;
DWORD dwSize = sizeof (DWORD);
TCHAR szName[ SESSDIR_LENGTH ];
ISettingsComp* pSettings = NULL;
DWORD dwStatus = 0;
DWORD dwMode = 0;
HRESULT hr = WBEM_E_INVALID_CLASS;
ICfgComp *pCfgComp = NULL;
CHString chSessDirName;
DWORD cbName;
OSVERSIONINFOEX OsVersionInfo;
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
CStackClass StackObj;
if(StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
if( pInParams == NULL )
{
ERR((TB, "TSSessionDirectory@ExecQuery: invalid interface"));
return WBEM_E_INVALID_METHOD_PARAMETERS;
}
hr = StackObj.m_pCfgComp->QueryInterface( IID_ISettingsComp , ( PVOID * )&pSettings ) ;
if( SUCCEEDED( hr ) && pSettings != NULL )
{
pSettings->GetTermSrvMode(&dwMode , &dwStatus );
if( ERROR_SUCCESS == dwStatus && dwMode == 0)
{
return WBEM_E_INVALID_CLASS;
}
}
if( GetVersionEx((OSVERSIONINFO*) &OsVersionInfo) )
{
if( ( OsVersionInfo.dwMajorVersion < 5 ) || ( OsVersionInfo.dwMajorVersion == 5 && OsVersionInfo.dwMinorVersion < 1 ))
{
return WBEM_E_INVALID_CLASS;
}
if(!(OsVersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE) && !( OsVersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
{
return WBEM_E_INVALID_CLASS;
}
}
/*
Inst.GetCHString(m_szSessionDirectoryLocation, chSessDirName);
if( chSessDirName.GetLength() > WINSTATIONNAME_LENGTH )
{
return WBEM_E_VALUE_OUT_OF_RANGE;
}
if( chSessDirName.IsEmpty() != 0 )
{
return WBEM_E_ILLEGAL_NULL;
}
*/
do
{
// Sets one of the properties: SessionDirectoryLocation or SessionDirectoryClusterName
// uint32 SetSessionDirectoryProperty([In] string PropertyName, string Value);
if( _wcsicmp(bstrMethodName, m_szSetSessionDirectoryProperty) == 0 )
{
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
REG_TS_CLUSTERSETTINGS ,
0,
KEY_READ | KEY_WRITE,
&hKey );
if( ERROR_SUCCESS != lRet )
{
ERR((TB, "TSSessionDirectory@ExecQuery: RegOpenKeyEx failed"));
hr = WBEM_E_INITIALIZATION_FAILURE;
break;
}
pInParams->GetCHString (m_szPropertyName, chData);
if( chData.CompareNoCase (m_szSessionDirectoryLocation) == 0 )
{
RegGetMachinePolicy(&m_gpPolicy);
chData.Empty();
bRet = pInParams->GetCHString(m_szValue, chData );
if( ( m_gpPolicy.fPolicySessionDirectoryLocation == 0) && bRet )
{
if( chData.IsEmpty() )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
if( chData.GetLength() > SESSDIR_LENGTH )
{
hr = WBEM_E_VALUE_OUT_OF_RANGE;
break;
}
lstrcpy(szName, chData);
cbName = (lstrlen(szName)+ 1) * sizeof(TCHAR);
lRet = RegSetValueEx( hKey ,
REG_TS_CLUSTER_STORESERVERNAME,
NULL ,
REG_SZ,
( CONST LPBYTE )szName ,
cbName );
TRC2((TB, "Win32_TSSessionDirectory@ExecMethod: SessionDirectory returned 0x%x" , lRet));
if( lRet == ERROR_SUCCESS )
{
bUpdate = TRUE;
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
}
chData.Empty();
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else if( chData.CompareNoCase(m_szSessionDirectoryClusterName) == 0 )
{
RegGetMachinePolicy(&m_gpPolicy);
chData.Empty();
bRet = pInParams->GetCHString(m_szValue, chData );
if( ( m_gpPolicy.fPolicySessionDirectoryClusterName == 0) && bRet )
{
if( chData.GetLength() > SESSDIR_LENGTH )
{
hr = WBEM_E_VALUE_OUT_OF_RANGE;
break;
}
lstrcpy(szName, chData);
cbName = (lstrlen(szName)+ 1) * sizeof(TCHAR);
lRet = RegSetValueEx( hKey ,
REG_TS_CLUSTER_CLUSTERNAME,
NULL ,
REG_SZ,
( CONST LPBYTE )szName ,
cbName );
TRC2((TB, "Win32_TSSessionDirectory@ExecMethod: SessionDirectory returned 0x%x" , lRet));
if( lRet == ERROR_SUCCESS )
{
bUpdate = TRUE;
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
}
chData.Empty();
}
else
{
hr = WBEM_E_INVALID_OPERATION;
break;
}
}
else
{
hr = WBEM_E_INVALID_METHOD;
break;
}
}
// Enables / Disables participation of a server in Session Directory
// uint32 SetSessionDirectoryActive([In] uint32 Value);
else if( _wcsicmp(bstrMethodName, m_szSetSessionDirectoryActive) == 0 )
{
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
REG_CONTROL_TSERVER ,
0,
KEY_READ | KEY_WRITE,
&hKey );
if( ERROR_SUCCESS == lRet )
{
RegGetMachinePolicy(&m_gpPolicy);
bRet = pInParams->GetDWORD( m_szSessionDirectoryActive, dwData );
if( (m_gpPolicy.fPolicySessionDirectoryActive == 0) && bRet )
{
if( dwData != 0 && dwData != 1 )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
lRet = RegSetValueEx( hKey ,
REG_TS_SESSDIRACTIVE,
0 ,
REG_DWORD,
( LPBYTE )&dwData ,
dwSize );
TRC2((TB, "Win32_TSSessionDirectory@ExecMethod: SessionDirectoryActive returned 0x%x" , lRet));
if( ERROR_SUCCESS == lRet )
{
bUpdate = TRUE;
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
}
}
else
{
hr = WBEM_E_INVALID_METHOD;
}
}
}
// Enables / Disables exposing the IP Address of Session Directory Server
// uint32 SetSessionDirectoryExposeServerIP([In] uint32 Value);
else if( _wcsicmp(bstrMethodName, m_szSetSessionDirectoryExposeServerIP) == 0 )
{
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
REG_CONTROL_TSERVER ,
0,
KEY_READ | KEY_WRITE,
&hKey );
if( ERROR_SUCCESS == lRet )
{
RegGetMachinePolicy(&m_gpPolicy);
bRet = pInParams->GetDWORD( m_szSessionDirectoryExposeServerIP, dwData );
//todo: change the policy to IP
if( (m_gpPolicy.fPolicySessionDirectoryExposeServerIP == 0) && bRet )
{
if( dwData != 0 && dwData != 1 )
{
hr = WBEM_E_INVALID_PARAMETER;
break;
}
lRet = RegSetValueEx( hKey ,
REG_TS_SESSDIR_EXPOSE_SERVER_ADDR,
0 ,
REG_DWORD,
( LPBYTE )&dwData ,
dwSize );
TRC2((TB, "Win32_TSSessionDirectory@ExecMethod: SessionDirectoryExposeServerIP returned 0x%x" , lRet));
if( ERROR_SUCCESS == lRet )
{
bUpdate = TRUE;
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
}
}
else
{
hr = WBEM_E_INVALID_METHOD;
}
}
}
}while(0);
if( bUpdate )
{
StackObj.m_pCfgComp->UpdateSessionDirectory(&dwStatus);
}
if( hKey != NULL )
{
RegCloseKey( hKey );
}
if( pSettings != NULL )
{
pSettings->Release();
}
return hr;
}
//=-------------
HRESULT CWin32_TSSessionDirectory::LoadPropertyValues( CInstance *pInstance, DWORD dwRequiredProperties)
{
LONG lRet = 0;
DWORD dwData = 0;
DWORD dwSize = 0;
HKEY hKey = NULL;
WCHAR tchData[ OPAQUESETTINGS_LENGTH +1] ={0};
TCHAR tchData1[ OPAQUESETTINGS_LENGTH +1] = {0} ;
dwSize = sizeof( DWORD );
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
REG_CONTROL_TSERVER ,
0,
KEY_READ,
&hKey );
if( ERROR_SUCCESS == lRet && hKey != NULL)
{
if( dwRequiredProperties & BIT_SESSIONDIRECTORYACTIVE )
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicySessionDirectoryActive != 0 )
{
dwData = m_gpPolicy.SessionDirectoryActive;
}
else
{
lRet = RegQueryValueEx( hKey ,
REG_TS_SESSDIRACTIVE,
NULL ,
NULL ,
(LPBYTE)&dwData ,
&dwSize );
}
TRC2((TB, "Win32_TSSessionDirectory@LoadPropertyValues: SessionDirectoryActive returned 0x%x" , lRet));
if( ERROR_SUCCESS == lRet )
{
pInstance->SetDWORD(m_szSessionDirectoryActive, dwData);
}
}
if( dwRequiredProperties & BIT_SESSIONDIRECTORYEXPOSESERVERIP )
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicySessionDirectoryExposeServerIP != 0 )
{
dwData = m_gpPolicy.SessionDirectoryExposeServerIP;
}
else
{
lRet = RegQueryValueEx( hKey ,
REG_TS_SESSDIR_EXPOSE_SERVER_ADDR,
NULL ,
NULL ,
(LPBYTE)&dwData ,
&dwSize );
}
TRC2((TB, "Win32_TSSessionDirectory@LoadPropertyValues: SessionDirectoryExposeServerIP returned 0x%x" , lRet));
if( ERROR_SUCCESS == lRet )
{
pInstance->SetDWORD(m_szSessionDirectoryExposeServerIP, dwData);
}
}
RegCloseKey (hKey);
}
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
REG_TS_CLUSTERSETTINGS ,
0,
KEY_READ,
&hKey );
if( ERROR_SUCCESS == lRet && hKey != NULL)
{
if( dwRequiredProperties & BIT_SESSIONDIRECTORY )
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicySessionDirectoryLocation != 0 )
{
lstrcpy(tchData, m_gpPolicy.SessionDirectoryLocation);
}
else
{
dwSize = sizeof( tchData );
lRet = RegQueryValueEx( hKey ,
REG_TS_CLUSTER_STORESERVERNAME,
NULL ,
NULL ,
(LPBYTE)tchData ,
&dwSize );
}
TRC2((TB, "Win32_TSSessionDirectory@LoadPropertyValues: SessionDirectoryLocation returned 0x%x" , lRet));
if( ERROR_SUCCESS == lRet )
{
pInstance->SetCHString(m_szSessionDirectoryLocation, tchData);
}
}
if( dwRequiredProperties & BIT_CLUSTERNAME )
{
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicySessionDirectoryClusterName != 0 )
{
lstrcpy( tchData, m_gpPolicy.SessionDirectoryClusterName );
}
else
{
dwSize = sizeof( tchData );
lRet = RegQueryValueEx( hKey ,
REG_TS_CLUSTER_CLUSTERNAME,
NULL ,
NULL ,
(LPBYTE)tchData ,
&dwSize );
}
TRC2((TB, "Win32_TSSessionDirectory@LoadPropertyValues: ClusterName returned 0x%x" , lRet));
if( ERROR_SUCCESS == lRet )
{
pInstance->SetCHString(m_szSessionDirectoryClusterName, tchData);
}
}
if( dwRequiredProperties & BIT_SESSIONDIRECTORYIPADDRESS )
{
dwSize = sizeof( tchData1 );
lRet = RegQueryValueEx( hKey ,
REG_TS_CLUSTER_REDIRECTIONIP,
NULL ,
NULL ,
(LPBYTE)tchData1 ,
&dwSize );
TRC2((TB, "Win32_TSSessionDirectory@LoadPropertyValues:Session Directory IP Address returned 0x%x" , lRet));
if( ERROR_SUCCESS == lRet )
{
pInstance->SetCHString(m_szSessionDirectoryIPAddress, tchData1);
}
}
/*
if( dwRequiredProperties & BIT_ADDITIONALPARAMS )
{
dwSize = sizeof( tchData );
lRet = RegQueryValueEx( hKey ,
REG_TS_CLUSTER_OPAQUESETTINGS,
NULL ,
NULL ,
(LPBYTE)&tchData ,
&dwSize );
TRC2((TB, "Win32_TSSessionDirectory@LoadPropertyValues: AdditionalParams returned 0x%x" , lRet));
if( ERROR_SUCCESS == lRet )
{
pInstance->SetCHString(m_szSessionDirectoryAdditionalParams, (LPTSTR)(LPCTSTR)&tchData);
}
}
*/
RegCloseKey( hKey );
}
return S_OK;
}
//=-------------------
HRESULT CWin32_TSSessionDirectory::PutInstance ( const CInstance &Instance, long lFlags)
{
LONG hr = 0;
DWORD dwData;
CHString chData;
HKEY hKey = NULL;
LONG lRet;
DWORD dwSize = sizeof (DWORD);
TCHAR szName[ SESSDIR_LENGTH ];
DWORD cbName;
DWORD dwStatus;
ULONG ulTerminals = 0, ulAdapters = 0;
ULONG ulSize = 0, ulNum =0;
PWS pWS= NULL;
PWS pWSList= NULL;
PGUIDTBL pGuidtbl = NULL;
TCHAR tchGuid[ GUID_LENGTH ];
hr = WBEM_S_NO_ERROR;
CHString chAddress;
DWORD Err = 0;
TCHAR tchAdd[MAX_PATH]=L"";
TCHAR tchAdapterName[MAX_PATH]=L"";
DWORD AdapterInfoSize;
PIP_ADDR_STRING pAddrStr;
PIP_ADAPTER_INFO pAdapterInfo = NULL, pAdapt = NULL;
LPWSTR pwszNLBipAddress = NULL;
ICfgComp *pCfgComp = NULL;
CStackClass StackObj;
if(StackObj.m_pCfgComp == NULL)
{
return WBEM_E_ILLEGAL_NULL;
}
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
REG_CONTROL_TSERVER ,
0,
KEY_READ,
&hKey );
if( ERROR_SUCCESS != lRet || hKey == NULL)
{
return WBEM_E_INVALID_OPERATION;
}
RegGetMachinePolicy(&m_gpPolicy);
if( m_gpPolicy.fPolicySessionDirectoryActive != 0 )
{
dwData = m_gpPolicy.SessionDirectoryActive;
}
else
{
lRet = RegQueryValueEx( hKey ,
REG_TS_SESSDIRACTIVE,
NULL ,
NULL ,
(LPBYTE)&dwData ,
&dwSize );
}
TRC2((TB, "Win32_TSSessionDirectory@PutInstance: RegQuery for SessionDirectoryActive returned 0x%x" , lRet));
if(hKey)
{
RegCloseKey(hKey);
hKey = NULL;
}
if( dwData == 0 )
{
return WBEM_E_INVALID_OPERATION;
}
Instance.GetCHString(m_szSessionDirectoryIPAddress, chAddress);
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
REG_TS_CLUSTERSETTINGS ,
0,
KEY_READ | KEY_WRITE,
&hKey );
if( ERROR_SUCCESS != lRet )
{
ERR((TB, "TSSessionDirectory@PutInstance: RegOpenKeyEx failed"));
return WBEM_E_INVALID_OPERATION;
}
hr = GetNLBIP(&pwszNLBipAddress);
if (FAILED(hr))
{
goto Cleanup;
}
if( !_tcsicmp(chAddress, _TEXT("0.0.0.0")))
{
hr = WBEM_E_INVALID_PARAMETER;
goto Cleanup;
}
//
// Enumerate all of the adapter specific information using the IP_ADAPTER_INFO structure.
// Note: IP_ADAPTER_INFO contains a linked list of adapter entries.
//
AdapterInfoSize = 0;
GetAdaptersInfo(NULL, &AdapterInfoSize);
if(AdapterInfoSize == 0)
{
return WBEM_E_OUT_OF_MEMORY;
}
if( chAddress.GetLength() > GUID_LENGTH )
{
hr = WBEM_E_INVALID_PARAMETER;
goto Cleanup;
}
// Allocate memory from sizing information
if ((pAdapterInfo = (PIP_ADAPTER_INFO) GlobalAlloc(GPTR, AdapterInfoSize)) == NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
// Get actual adapter information
if ((Err = GetAdaptersInfo(pAdapterInfo, &AdapterInfoSize)) != 0)
{
hr = WBEM_E_OUT_OF_MEMORY;
goto Cleanup;
}
BOOL bAllAdapters = FALSE;
hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWSList);
if( SUCCEEDED( hr ) && pWSList != NULL )
{
for( ulNum = 0; ulNum < ulTerminals ; ulNum++ )
{
if( pWSList[ulNum].LanAdapter == 0 )
{
bAllAdapters = TRUE;
}
}
}
pAdapt = pAdapterInfo;
for (; pAdapt ; pAdapt = pAdapt->Next)
{
pAddrStr = &(pAdapt->IpAddressList);
while(pAddrStr)
{
MultiByteToWideChar(GetACP(), 0, pAddrStr->IpAddress.String, -1, tchAdd, MAX_PATH);
MultiByteToWideChar(GetACP(), 0, pAdapt->AdapterName, -1, tchAdapterName, MAX_PATH);
if( !_tcsicmp(chAddress, tchAdd))
{
if(pwszNLBipAddress && (_tcsstr(pwszNLBipAddress, tchAdd)!= NULL))
{
hr = WBEM_E_INVALID_PARAMETER;
goto Cleanup;
}
goto Label;
}
pAddrStr = pAddrStr->Next;
}
}
hr = WBEM_E_INVALID_PARAMETER;
goto Cleanup;
Label:
if(bAllAdapters == TRUE)
{
goto Found;
}
if( SUCCEEDED( hr ) && pWSList != NULL)
{
for( ulNum = 0; ulNum < ulTerminals ; ulNum++ )
{
if(_tcsicmp(pWSList[ulNum].pdName, L"Console"))
break;
}
hr = StackObj.m_pCfgComp->GetLanAdapterList2(pWSList[ulNum].pdName, &ulAdapters , &pGuidtbl );
if( SUCCEEDED( hr ) && pGuidtbl != NULL)
{
StringFromGUID2( ( pGuidtbl )[ pWSList[ulNum].LanAdapter ].guidNIC , tchGuid , ARRAYSIZE( tchGuid ) );
if( _tcsicmp( tchGuid, tchAdapterName ) == 0 )
{
goto Found;
}
}
}
hr = WBEM_E_INVALID_PARAMETER;
goto Cleanup;
Found:
lstrcpy(szName, chAddress);
cbName = (lstrlen(szName)+ 1) * sizeof(TCHAR);
lRet = RegSetValueEx( hKey ,
REG_TS_CLUSTER_REDIRECTIONIP,
NULL ,
REG_SZ,
( CONST LPBYTE )szName ,
cbName );
TRC2((TB, "Win32_TSSessionDirectory@ExecMethod: SessionDirectory returned 0x%x" , lRet));
if(lRet == ERROR_SUCCESS)
{
StackObj.m_pCfgComp->UpdateSessionDirectory(&dwStatus);
}
Cleanup:
if (pwszNLBipAddress)
GlobalFree(pwszNLBipAddress);
if(pAdapterInfo)
{
GlobalFree(pAdapterInfo);
}
return hr;
}