1365 lines
38 KiB
C++
1365 lines
38 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
Servpp.h
|
|
Server properties implementation file
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "Servpp.h"
|
|
#include "server.h"
|
|
#include "service.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
const DWORD c_dwChangableFlagMask =
|
|
TAPISERVERCONFIGFLAGS_ENABLESERVER |
|
|
TAPISERVERCONFIGFLAGS_SETACCOUNT |
|
|
TAPISERVERCONFIGFLAGS_SETTAPIADMINISTRATORS;
|
|
|
|
const TCHAR szPasswordNull[] = _T(" "); // Empty password
|
|
|
|
BOOL
|
|
IsLocalSystemAccount(LPCTSTR pszAccount)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD dwSidSize = 128;
|
|
DWORD dwDomainNameSize = 128;
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
|
PSID pLocalSid = NULL;
|
|
PSID pLocalServiceSid = NULL;
|
|
PSID pNetworkServiceSid = NULL;
|
|
PSID accountSid = NULL;
|
|
SID_NAME_USE SidType;
|
|
LPWSTR pwszDomainName;
|
|
|
|
|
|
do
|
|
{
|
|
// Attempt to allocate a buffer for the SID. Note that apparently in the
|
|
// absence of any error theData->m_Sid is freed only when theData goes
|
|
// out of scope.
|
|
|
|
accountSid = LocalAlloc( LMEM_FIXED, dwSidSize );
|
|
pwszDomainName = (LPWSTR) LocalAlloc( LMEM_FIXED, dwDomainNameSize * sizeof(WCHAR) );
|
|
|
|
// Was space allocated for the SID and domain name successfully?
|
|
|
|
if ( accountSid == NULL || pwszDomainName == NULL )
|
|
{
|
|
if ( accountSid != NULL )
|
|
{
|
|
LocalFree( accountSid );
|
|
accountSid = NULL;
|
|
}
|
|
|
|
if ( pwszDomainName != NULL )
|
|
{
|
|
LocalFree( pwszDomainName );
|
|
}
|
|
|
|
goto ExitHere;
|
|
}
|
|
|
|
// Attempt to Retrieve the SID and domain name. If LookupAccountName failes
|
|
// because of insufficient buffer size(s) dwSidSize and dwDomainNameSize
|
|
// will be set correctly for the next attempt.
|
|
|
|
if (LookupAccountName (NULL,
|
|
pszAccount,
|
|
accountSid,
|
|
&dwSidSize,
|
|
pwszDomainName,
|
|
&dwDomainNameSize,
|
|
&SidType ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError ())
|
|
{
|
|
goto ExitHere;
|
|
}
|
|
|
|
// domain name isn't needed at any time
|
|
LocalFree (pwszDomainName);
|
|
LocalFree (accountSid);
|
|
|
|
} while ( TRUE );
|
|
|
|
if (!AllocateAndInitializeSid (
|
|
&NtAuthority,
|
|
1,
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&pLocalSid) ||
|
|
!AllocateAndInitializeSid (
|
|
&NtAuthority,
|
|
1,
|
|
SECURITY_LOCAL_SERVICE_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&pLocalServiceSid) ||
|
|
!AllocateAndInitializeSid (
|
|
&NtAuthority,
|
|
1,
|
|
SECURITY_NETWORK_SERVICE_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&pNetworkServiceSid)
|
|
)
|
|
{
|
|
goto ExitHere;
|
|
}
|
|
|
|
if (EqualSid(pLocalSid, accountSid) ||
|
|
EqualSid(pLocalServiceSid, accountSid) ||
|
|
EqualSid(pNetworkServiceSid, accountSid))
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
ExitHere:
|
|
|
|
if (NULL != pwszDomainName)
|
|
{
|
|
LocalFree (pwszDomainName);
|
|
}
|
|
|
|
if (NULL != accountSid)
|
|
{
|
|
LocalFree (accountSid);
|
|
}
|
|
|
|
if (NULL != pLocalSid)
|
|
{
|
|
FreeSid(pLocalSid);
|
|
}
|
|
if (NULL != pLocalServiceSid)
|
|
{
|
|
FreeSid (pLocalServiceSid);
|
|
}
|
|
if (NULL != pNetworkServiceSid)
|
|
{
|
|
FreeSid (pNetworkServiceSid);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CServerProperties holder
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CServerProperties::CServerProperties
|
|
(
|
|
ITFSNode * pNode,
|
|
IComponentData * pComponentData,
|
|
ITFSComponentData * pTFSCompData,
|
|
ITapiInfo * pTapiInfo,
|
|
LPCTSTR pszSheetName,
|
|
BOOL fTapiInfoLoaded
|
|
) : CPropertyPageHolderBase(pNode, pComponentData, pszSheetName),
|
|
m_fTapiInfoLoaded(fTapiInfoLoaded)
|
|
{
|
|
//ASSERT(pFolderNode == GetContainerNode());
|
|
|
|
m_bAutoDeletePages = FALSE; // we have the pages as embedded members
|
|
|
|
AddPageToList((CPropertyPageBase*) &m_pageSetup);
|
|
AddPageToList((CPropertyPageBase*) &m_pageRefresh);
|
|
|
|
Assert(pTFSCompData != NULL);
|
|
m_spTFSCompData.Set(pTFSCompData);
|
|
|
|
m_spTapiInfo.Set(pTapiInfo);
|
|
|
|
m_hScManager = NULL;
|
|
m_paQSC = NULL;
|
|
|
|
m_pszServiceName = TAPI_SERVICE_NAME;
|
|
|
|
}
|
|
|
|
CServerProperties::~CServerProperties()
|
|
{
|
|
// Close the service control manager database
|
|
if (m_hScManager != NULL)
|
|
{
|
|
(void)::CloseServiceHandle(m_hScManager);
|
|
}
|
|
|
|
// Free the allocated pointers
|
|
if (m_paQSC)
|
|
delete m_paQSC;
|
|
|
|
RemovePageFromList((CPropertyPageBase*) &m_pageSetup, FALSE);
|
|
RemovePageFromList((CPropertyPageBase*) &m_pageRefresh, FALSE);
|
|
}
|
|
|
|
BOOL
|
|
CServerProperties::FInit()
|
|
{
|
|
// get the service account information here
|
|
SC_HANDLE hService = NULL;
|
|
DWORD cbBytesNeeded = 0;
|
|
BOOL fSuccess = TRUE;
|
|
BOOL f;
|
|
DWORD dwErr;
|
|
|
|
m_uFlags = 0;
|
|
|
|
if (!FOpenScManager())
|
|
{
|
|
// Unable to open service control database
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
** Open service with querying access-control
|
|
*/
|
|
hService = ::OpenService(m_hScManager,
|
|
m_pszServiceName,
|
|
SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
|
|
if (hService == NULL)
|
|
{
|
|
TapiMessageBox(::GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
** Query the service status
|
|
*/
|
|
Trace1("# QueryServiceStatus(%s)...\n", m_pszServiceName);
|
|
f = ::QueryServiceStatus(hService, OUT &m_SS);
|
|
if (f)
|
|
{
|
|
//m_uFlags |= mskfValidSS;
|
|
}
|
|
else
|
|
{
|
|
::TapiMessageBox(::GetLastError());
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
/*
|
|
** Query the service config
|
|
*/
|
|
Trace1("# QueryServiceConfig(%s)...\n", m_pszServiceName);
|
|
f = ::QueryServiceConfig(hService,
|
|
NULL,
|
|
0,
|
|
OUT &cbBytesNeeded); // Compute how many bytes we need to allocate
|
|
|
|
cbBytesNeeded += 100; // Add extra bytes (just in case)
|
|
delete m_paQSC; // Free previously allocated memory (if any)
|
|
|
|
m_paQSC = (QUERY_SERVICE_CONFIG *) new BYTE[cbBytesNeeded];
|
|
f = ::QueryServiceConfig(hService,
|
|
OUT m_paQSC,
|
|
cbBytesNeeded,
|
|
OUT &cbBytesNeeded);
|
|
if (f)
|
|
{
|
|
m_strServiceDisplayName = m_paQSC->lpDisplayName;
|
|
m_strLogOnAccountName = m_paQSC->lpServiceStartName;
|
|
}
|
|
else
|
|
{
|
|
::TapiMessageBox(::GetLastError());
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
VERIFY(::CloseServiceHandle(hService));
|
|
return fSuccess;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// FOpenScManager()
|
|
//
|
|
// Open the service control manager database (if not already opened).
|
|
// The idea for such a function is to recover from a broken connection.
|
|
//
|
|
// Return TRUE if the service control database was opened successfully,
|
|
// othersise false.
|
|
//
|
|
BOOL
|
|
CServerProperties::FOpenScManager()
|
|
{
|
|
if (m_hScManager == NULL)
|
|
{
|
|
m_hScManager = ::OpenSCManager(m_strMachineName,
|
|
NULL,
|
|
SC_MANAGER_CONNECT);
|
|
}
|
|
|
|
if (m_hScManager == NULL)
|
|
{
|
|
TapiMessageBox(::GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
} // CServicePropertyData::FOpenScManager()
|
|
|
|
BOOL
|
|
CServerProperties::FUpdateServiceInfo(LPCTSTR pszName, LPCTSTR pszPassword, DWORD dwStartType)
|
|
{
|
|
SC_HANDLE hService = NULL;
|
|
BOOL fSuccess = TRUE;
|
|
BOOL f;
|
|
DWORD dwServiceType = 0;
|
|
|
|
Trace1("INFO: Updating data for service %s...\n", (LPCTSTR)m_pszServiceName);
|
|
// Re-open service control manager (in case it was closed)
|
|
if (!FOpenScManager())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
** Open service with write access
|
|
**
|
|
** CODEWORK Could provide a more specific error message
|
|
** if SERVICE_CHANGE_CONFIG is available but not SERVICE_START
|
|
*/
|
|
hService = ::OpenService(m_hScManager,
|
|
m_pszServiceName,
|
|
SERVICE_CHANGE_CONFIG);
|
|
if (hService == NULL)
|
|
{
|
|
TapiMessageBox(::GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
Trace1("# ChangeServiceConfig(%s)...\n", m_pszServiceName);
|
|
|
|
if (pszName)
|
|
{
|
|
if (IsLocalSystemAccount(pszName))
|
|
{
|
|
pszPassword = szPasswordNull;
|
|
}
|
|
dwServiceType = m_paQSC->dwServiceType & ~SERVICE_INTERACTIVE_PROCESS;
|
|
}
|
|
else
|
|
{
|
|
dwServiceType = SERVICE_NO_CHANGE;
|
|
}
|
|
|
|
f = ::ChangeServiceConfig(hService, // Handle to service
|
|
dwServiceType, // Type of service
|
|
dwStartType, // When/How to start service
|
|
SERVICE_NO_CHANGE, // dwErrorControl - severity if service fails to start
|
|
NULL, // Pointer to service binary file name
|
|
NULL, // lpLoadOrderGroup - pointer to load ordering group name
|
|
NULL, // lpdwTagId - pointer to variable to get tag identifier
|
|
NULL, // lpDependencies - pointer to array of dependency names
|
|
pszName, // Pointer to account name of service
|
|
pszPassword, // Pointer to password for service account
|
|
m_strServiceDisplayName);
|
|
|
|
if (!f)
|
|
{
|
|
DWORD dwErr = ::GetLastError();
|
|
Assert(dwErr != ERROR_SUCCESS);
|
|
Trace2("ERR: ChangeServiceConfig(%s) failed. err= %u.\n", m_pszServiceName, dwErr);
|
|
TapiMessageBox(dwErr);
|
|
fSuccess = FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_strLogOnAccountName = pszName;
|
|
|
|
// if pszName is null, we aren't changing the account info, so don't check
|
|
// the logon as service info
|
|
if (pszName && !IsLocalSystemAccount(pszName))
|
|
{
|
|
/*
|
|
** Make sure there is an LSA account with POLICY_MODE_SERVICE privilege
|
|
** This function reports its own errors, failure is only advisory
|
|
*/
|
|
FCheckLSAAccount();
|
|
}
|
|
}
|
|
|
|
VERIFY(::CloseServiceHandle(hService));
|
|
|
|
return fSuccess;
|
|
}
|
|
|
|
//Check if the user has the write access on service config info
|
|
BOOL
|
|
CServerProperties::FHasServiceControl()
|
|
{
|
|
BOOL fRet = FALSE;
|
|
|
|
if (FIsTapiInfoLoaded())
|
|
{
|
|
fRet = m_spTapiInfo->FHasServiceControl();
|
|
}
|
|
else
|
|
{
|
|
if (!FOpenScManager())
|
|
{
|
|
fRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
SC_HANDLE hService = NULL;
|
|
|
|
hService = ::OpenService(m_hScManager,
|
|
m_pszServiceName,
|
|
SERVICE_CHANGE_CONFIG);
|
|
|
|
fRet = (hService != NULL);
|
|
|
|
if (hService)
|
|
{
|
|
VERIFY(::CloseServiceHandle(hService));
|
|
}
|
|
}
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CServerPropRefresh property page
|
|
|
|
IMPLEMENT_DYNCREATE(CServerPropRefresh, CPropertyPageBase)
|
|
|
|
CServerPropRefresh::CServerPropRefresh() : CPropertyPageBase(CServerPropRefresh::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(CServerPropRefresh)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
CServerPropRefresh::~CServerPropRefresh()
|
|
{
|
|
}
|
|
|
|
void CServerPropRefresh::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CPropertyPageBase::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CServerPropRefresh)
|
|
DDX_Control(pDX, IDC_EDIT_MINUTES, m_editMinutes);
|
|
DDX_Control(pDX, IDC_EDIT_HOURS, m_editHours);
|
|
DDX_Control(pDX, IDC_SPIN_MINUTES, m_spinMinutes);
|
|
DDX_Control(pDX, IDC_SPIN_HOURS, m_spinHours);
|
|
DDX_Control(pDX, IDC_CHECK_ENABLE_STATS, m_checkEnableStats);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CServerPropRefresh, CPropertyPageBase)
|
|
//{{AFX_MSG_MAP(CServerPropRefresh)
|
|
ON_BN_CLICKED(IDC_CHECK_ENABLE_STATS, OnCheckEnableStats)
|
|
ON_EN_KILLFOCUS(IDC_EDIT_HOURS, OnKillfocusEditHours)
|
|
ON_EN_KILLFOCUS(IDC_EDIT_MINUTES, OnKillfocusEditMinutes)
|
|
ON_EN_CHANGE(IDC_EDIT_HOURS, OnChangeEditHours)
|
|
ON_EN_CHANGE(IDC_EDIT_MINUTES, OnChangeEditMinutes)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CServerPropRefresh message handlers
|
|
|
|
BOOL CServerPropRefresh::OnInitDialog()
|
|
{
|
|
CPropertyPageBase::OnInitDialog();
|
|
|
|
m_spinHours.SetRange(0, AUTO_REFRESH_HOURS_MAX);
|
|
m_spinMinutes.SetRange(0, AUTO_REFRESH_MINUTES_MAX);
|
|
|
|
m_checkEnableStats.SetCheck(m_bAutoRefresh);
|
|
|
|
// update the refresh interval
|
|
int nHours, nMinutes;
|
|
DWORD dwRefreshInterval = m_dwRefreshInterval;
|
|
|
|
nHours = dwRefreshInterval / MILLISEC_PER_HOUR;
|
|
dwRefreshInterval -= nHours * MILLISEC_PER_HOUR;
|
|
|
|
nMinutes = dwRefreshInterval / MILLISEC_PER_MINUTE;
|
|
dwRefreshInterval -= nMinutes * MILLISEC_PER_MINUTE;
|
|
|
|
m_spinHours.SetPos(nHours);
|
|
m_spinMinutes.SetPos(nMinutes);
|
|
|
|
m_editHours.LimitText(2);
|
|
m_editMinutes.LimitText(2);
|
|
|
|
// set the button states
|
|
UpdateButtons();
|
|
|
|
SetDirty(FALSE);
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
void CServerPropRefresh::UpdateButtons()
|
|
{
|
|
int nCheck = m_checkEnableStats.GetCheck();
|
|
|
|
GetDlgItem(IDC_EDIT_HOURS)->EnableWindow(nCheck != 0);
|
|
GetDlgItem(IDC_EDIT_MINUTES)->EnableWindow(nCheck != 0);
|
|
|
|
GetDlgItem(IDC_SPIN_HOURS)->EnableWindow(nCheck != 0);
|
|
GetDlgItem(IDC_SPIN_MINUTES)->EnableWindow(nCheck != 0);
|
|
}
|
|
|
|
void CServerPropRefresh::OnCheckEnableStats()
|
|
{
|
|
SetDirty(TRUE);
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
void CServerPropRefresh::OnKillfocusEditHours()
|
|
{
|
|
}
|
|
|
|
void CServerPropRefresh::OnKillfocusEditMinutes()
|
|
{
|
|
}
|
|
|
|
void CServerPropRefresh::OnChangeEditHours()
|
|
{
|
|
ValidateHours();
|
|
SetDirty(TRUE);
|
|
}
|
|
|
|
void CServerPropRefresh::OnChangeEditMinutes()
|
|
{
|
|
ValidateMinutes();
|
|
SetDirty(TRUE);
|
|
}
|
|
|
|
void CServerPropRefresh::ValidateHours()
|
|
{
|
|
CString strValue;
|
|
int nValue;
|
|
|
|
if (m_editHours.GetSafeHwnd() != NULL)
|
|
{
|
|
m_editHours.GetWindowText(strValue);
|
|
if (!strValue.IsEmpty())
|
|
{
|
|
nValue = _ttoi(strValue);
|
|
|
|
if ((nValue >= 0) &&
|
|
(nValue <= AUTO_REFRESH_HOURS_MAX))
|
|
{
|
|
// everything is good
|
|
return;
|
|
}
|
|
|
|
if (nValue > AUTO_REFRESH_HOURS_MAX)
|
|
nValue = AUTO_REFRESH_HOURS_MAX;
|
|
else
|
|
if (nValue < 0)
|
|
nValue = 0;
|
|
|
|
// set the new value and beep
|
|
CString strText;
|
|
LPTSTR pBuf = strText.GetBuffer(5);
|
|
|
|
_itot(nValue, pBuf, 10);
|
|
strText.ReleaseBuffer();
|
|
|
|
MessageBeep(MB_ICONEXCLAMATION);
|
|
|
|
m_editHours.SetWindowText(strText);
|
|
|
|
m_editHours.SetSel(0, -1);
|
|
m_editHours.SetFocus();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CServerPropRefresh::ValidateMinutes()
|
|
{
|
|
CString strValue;
|
|
int nValue;
|
|
|
|
if (m_editMinutes.GetSafeHwnd() != NULL)
|
|
{
|
|
m_editMinutes.GetWindowText(strValue);
|
|
if (!strValue.IsEmpty())
|
|
{
|
|
nValue = _ttoi(strValue);
|
|
|
|
if ((nValue >= 0) &&
|
|
(nValue <= AUTO_REFRESH_MINUTES_MAX))
|
|
{
|
|
// everything is good
|
|
return;
|
|
}
|
|
|
|
if (nValue > AUTO_REFRESH_MINUTES_MAX)
|
|
nValue = AUTO_REFRESH_MINUTES_MAX;
|
|
else
|
|
if (nValue < 0)
|
|
nValue = 0;
|
|
|
|
CString strText;
|
|
LPTSTR pBuf = strText.GetBuffer(5);
|
|
|
|
_itot(nValue, pBuf, 10);
|
|
strText.ReleaseBuffer();
|
|
|
|
MessageBeep(MB_ICONEXCLAMATION);
|
|
|
|
m_editMinutes.SetWindowText(strText);
|
|
|
|
m_editMinutes.SetSel(0, -1);
|
|
m_editMinutes.SetFocus();
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CServerPropRefresh::OnApply()
|
|
{
|
|
if (!IsDirty())
|
|
return TRUE;
|
|
|
|
UpdateData();
|
|
|
|
m_bAutoRefresh = (m_checkEnableStats.GetCheck() == 1) ? TRUE : FALSE;
|
|
|
|
int nHours = m_spinHours.GetPos();
|
|
int nMinutes = m_spinMinutes.GetPos();
|
|
|
|
m_dwRefreshInterval = nHours * MILLISEC_PER_HOUR;
|
|
m_dwRefreshInterval += nMinutes * MILLISEC_PER_MINUTE;
|
|
|
|
if (m_bAutoRefresh && m_dwRefreshInterval == 0)
|
|
{
|
|
CString strMessage;
|
|
|
|
AfxMessageBox(IDS_ERR_AUTO_REFRESH_ZERO);
|
|
m_editHours.SetSel(0, -1);
|
|
m_editHours.SetFocus();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL bRet = CPropertyPageBase::OnApply();
|
|
|
|
if (bRet == FALSE)
|
|
{
|
|
// Something bad happened... grab the error code
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
::TapiMessageBox(GetHolder()->GetError());
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CServerPropRefresh::OnPropertyChange(BOOL bScope, LONG_PTR *ChangeMask)
|
|
{
|
|
SPITFSNode spNode;
|
|
CTapiServer * pServer;
|
|
DWORD dwError;
|
|
|
|
// do stuff here.
|
|
BEGIN_WAIT_CURSOR;
|
|
|
|
spNode = GetHolder()->GetNode();
|
|
pServer = GETHANDLER(CTapiServer, spNode);
|
|
|
|
pServer->SetAutoRefresh(spNode, m_bAutoRefresh, m_dwRefreshInterval);
|
|
|
|
SPITFSNodeMgr spNodeMgr;
|
|
SPITFSNode spRootNode;
|
|
|
|
spNode->GetNodeMgr(&spNodeMgr);
|
|
spNodeMgr->GetRootNode(&spRootNode);
|
|
spRootNode->SetData(TFS_DATA_DIRTY, TRUE);
|
|
|
|
END_WAIT_CURSOR;
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CServerPropSetup property page
|
|
|
|
IMPLEMENT_DYNCREATE(CServerPropSetup, CPropertyPageBase)
|
|
|
|
CServerPropSetup::CServerPropSetup() : CPropertyPageBase(CServerPropSetup::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(CServerPropSetup)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_dwNewFlags = 0;
|
|
}
|
|
|
|
CServerPropSetup::~CServerPropSetup()
|
|
{
|
|
}
|
|
|
|
void CServerPropSetup::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CPropertyPage::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CServerPropSetup)
|
|
DDX_Control(pDX, IDC_LIST_ADMINS, m_listAdmins);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CServerPropSetup, CPropertyPageBase)
|
|
//{{AFX_MSG_MAP(CServerPropSetup)
|
|
ON_BN_CLICKED(IDC_BUTTON_ADD_ADMIN, OnButtonAdd)
|
|
ON_BN_CLICKED(IDC_BUTTON_CHOOSE_USER, OnButtonChooseUser)
|
|
ON_BN_CLICKED(IDC_BUTTON_REMOVE_ADMIN, OnButtonRemove)
|
|
ON_BN_CLICKED(IDC_CHECK_ENABLE_SERVER, OnCheckEnableServer)
|
|
ON_EN_CHANGE(IDC_EDIT_NAME, OnChangeEditName)
|
|
ON_EN_CHANGE(IDC_EDIT_PASSWORD, OnChangeEditPassword)
|
|
ON_LBN_SELCHANGE(IDC_LIST_ADMINS, OnSelchangeListAdmins)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CServerPropSetup message handlers
|
|
|
|
BOOL CServerPropSetup::OnInitDialog()
|
|
{
|
|
SPITapiInfo spTapiInfo;
|
|
CString strName;
|
|
HRESULT hr = hrOK;
|
|
|
|
CPropertyPageBase::OnInitDialog();
|
|
|
|
CServerProperties * pServerProp = (CServerProperties * ) GetHolder();
|
|
pServerProp->GetTapiInfo(&spTapiInfo);
|
|
Assert(spTapiInfo);
|
|
|
|
BOOL fIsNTS = TRUE;
|
|
|
|
if (pServerProp->FIsServiceRunning())
|
|
{
|
|
fIsNTS = spTapiInfo->IsServer();
|
|
|
|
hr = spTapiInfo->GetConfigInfo(&m_tapiConfigInfo);
|
|
if (FAILED(hr))
|
|
{
|
|
Panic1("ServerPropSetup - GetConfigInfo failed! %x", hr);
|
|
}
|
|
|
|
// update the checkbox
|
|
((CButton *) GetDlgItem(IDC_CHECK_ENABLE_SERVER))->SetCheck(spTapiInfo->IsTapiServer());
|
|
|
|
// now update any TAPI administrators
|
|
for (int i = 0; i < m_tapiConfigInfo.m_arrayAdministrators.GetSize(); i++)
|
|
{
|
|
((CListBox *) GetDlgItem(IDC_LIST_ADMINS))->AddString(m_tapiConfigInfo.m_arrayAdministrators[i].m_strName);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// check to see if the machine is NTS
|
|
TFSIsNTServer(pServerProp->m_strMachineName, &fIsNTS);
|
|
}
|
|
|
|
if (fIsNTS)
|
|
{
|
|
// fill in the username and password
|
|
strName = pServerProp->GetServiceAccountName();
|
|
GetDlgItem(IDC_EDIT_NAME)->SetWindowText(strName);
|
|
GetDlgItem(IDC_EDIT_PASSWORD)->SetWindowText(szPasswordNull);
|
|
|
|
m_dwNewFlags = TAPISERVERCONFIGFLAGS_ISSERVER;
|
|
}
|
|
else
|
|
{
|
|
m_dwNewFlags = 0;
|
|
}
|
|
EnableButtons(fIsNTS);
|
|
|
|
m_fRestartService = FALSE;
|
|
m_dwInitFlags = m_tapiConfigInfo.m_dwFlags;
|
|
|
|
SetDirty(FALSE);
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
void CServerPropSetup::OnButtonAdd()
|
|
{
|
|
CGetUsers getUsers(TRUE);
|
|
|
|
if (!getUsers.GetUsers(GetSafeHwnd()))
|
|
return;
|
|
|
|
for (int nCount = 0; nCount < getUsers.GetSize(); nCount++)
|
|
{
|
|
CUserInfo userTemp;
|
|
|
|
userTemp = getUsers[nCount];
|
|
|
|
BOOL fDuplicate = FALSE;
|
|
for (int i = 0; i < m_tapiConfigInfo.m_arrayAdministrators.GetSize(); i++)
|
|
{
|
|
if (m_tapiConfigInfo.m_arrayAdministrators[i].m_strName.CompareNoCase(userTemp.m_strName) == 0)
|
|
{
|
|
fDuplicate = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!fDuplicate)
|
|
{
|
|
// add to the array
|
|
int nIndex = (int)m_tapiConfigInfo.m_arrayAdministrators.Add(userTemp);
|
|
|
|
// now add to the listbox
|
|
m_listAdmins.AddString(m_tapiConfigInfo.m_arrayAdministrators[nIndex].m_strName);
|
|
}
|
|
else
|
|
{
|
|
// tell the user we're not adding this to the list
|
|
CString strMessage;
|
|
AfxFormatString1(strMessage, IDS_ADMIN_ALREADY_IN_LIST, userTemp.m_strName);
|
|
AfxMessageBox(strMessage);
|
|
}
|
|
|
|
SetDirty(TRUE);
|
|
}
|
|
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_SETTAPIADMINISTRATORS;
|
|
|
|
EnableButtons();
|
|
}
|
|
|
|
void CServerPropSetup::OnButtonRemove()
|
|
{
|
|
CString strSelectedName;
|
|
int nCurSel = m_listAdmins.GetCurSel();
|
|
|
|
m_listAdmins.GetText(nCurSel, strSelectedName);
|
|
|
|
// remove from the list
|
|
for (int i = 0; i < m_tapiConfigInfo.m_arrayAdministrators.GetSize(); i++)
|
|
{
|
|
if (strSelectedName.Compare(m_tapiConfigInfo.m_arrayAdministrators[i].m_strName) == 0)
|
|
{
|
|
// found it. remove from the list
|
|
m_tapiConfigInfo.m_arrayAdministrators.RemoveAt(i);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// now remove from the list box
|
|
m_listAdmins.DeleteString(nCurSel);
|
|
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_SETTAPIADMINISTRATORS;
|
|
|
|
SetDirty(TRUE);
|
|
|
|
EnableButtons();
|
|
}
|
|
|
|
void CServerPropSetup::OnButtonChooseUser()
|
|
{
|
|
CGetUsers getUsers;
|
|
|
|
if (!getUsers.GetUsers(GetSafeHwnd()))
|
|
return;
|
|
|
|
if (0 == getUsers.GetSize())
|
|
return;
|
|
|
|
CUserInfo userTemp;
|
|
|
|
userTemp = getUsers[0];
|
|
|
|
GetDlgItem(IDC_EDIT_NAME)->SetWindowText(userTemp.m_strName);
|
|
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_SETACCOUNT;
|
|
|
|
SetDirty(TRUE);
|
|
EnableButtons();
|
|
}
|
|
|
|
void CServerPropSetup::OnCheckEnableServer()
|
|
{
|
|
if (((CButton *) GetDlgItem(IDC_CHECK_ENABLE_SERVER))->GetCheck())
|
|
{
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_ENABLESERVER;
|
|
}
|
|
else
|
|
{
|
|
m_dwNewFlags &= ~TAPISERVERCONFIGFLAGS_ENABLESERVER;
|
|
}
|
|
|
|
EnableButtons ();
|
|
|
|
SetDirty(TRUE);
|
|
}
|
|
|
|
void CServerPropSetup::OnChangeEditName()
|
|
{
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_SETACCOUNT;
|
|
|
|
SetDirty(TRUE);
|
|
}
|
|
|
|
void CServerPropSetup::OnChangeEditPassword()
|
|
{
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_SETACCOUNT;
|
|
|
|
m_fRestartService = TRUE;
|
|
|
|
SetDirty(TRUE);
|
|
}
|
|
|
|
void CServerPropSetup::OnSelchangeListAdmins()
|
|
{
|
|
EnableButtons();
|
|
}
|
|
|
|
void CServerPropSetup::EnableButtons(BOOL fIsNtServer)
|
|
{
|
|
BOOL fServiceRunning = ((CServerProperties *) GetHolder())->FIsServiceRunning();
|
|
|
|
//if we are unable to get the write access to tapisrv service, we need to disable
|
|
// some controls
|
|
BOOL fHasServiceControl = ((CServerProperties *) GetHolder())->FHasServiceControl();
|
|
|
|
//We enable the admin controls only if we sucessfully loaded the tapi info
|
|
BOOL fTapiInfoLoaded = ((CServerProperties *) GetHolder())->FIsTapiInfoLoaded();
|
|
|
|
BOOL fIsAdmin = ((CServerProperties *) GetHolder())->FIsAdmin();
|
|
|
|
// if this isn't an NT server, disable all controls
|
|
if (!fIsNtServer)
|
|
fServiceRunning = FALSE;
|
|
|
|
//Enable the Admin controls only if
|
|
//(1) the service is running
|
|
//(2) successfully loaded the tapi config info
|
|
//(3) the user is a machine admin or tapi admin
|
|
BOOL fEnableAdminControls = fServiceRunning && fTapiInfoLoaded && fIsAdmin;
|
|
|
|
// enable the admin controls on
|
|
GetDlgItem(IDC_STATIC_ADMINS)->EnableWindow(fEnableAdminControls);
|
|
GetDlgItem(IDC_STATIC_NOTE)->EnableWindow(fEnableAdminControls);
|
|
GetDlgItem(IDC_STATIC_LISTBOX)->EnableWindow(fEnableAdminControls);
|
|
GetDlgItem(IDC_BUTTON_ADD_ADMIN)->EnableWindow(fEnableAdminControls);
|
|
GetDlgItem(IDC_BUTTON_REMOVE_ADMIN)->EnableWindow(fEnableAdminControls);
|
|
GetDlgItem(IDC_LIST_ADMINS)->EnableWindow(fEnableAdminControls);
|
|
|
|
//If the user is not admin, then they don't have ServiceControl write access
|
|
//So fHasServiceControl covers fIsAdmin
|
|
|
|
GetDlgItem(IDC_CHECK_ENABLE_SERVER)->EnableWindow(fServiceRunning
|
|
&& fHasServiceControl
|
|
&& fTapiInfoLoaded);
|
|
|
|
// these should always be available if we have service control access
|
|
// and we are running on server
|
|
GetDlgItem(IDC_STATIC_USERNAME)->EnableWindow(fIsNtServer && fHasServiceControl);
|
|
GetDlgItem(IDC_STATIC_PASSWORD)->EnableWindow(fIsNtServer && fHasServiceControl);
|
|
GetDlgItem(IDC_STATIC_ACCOUNT)->EnableWindow(fIsNtServer && fHasServiceControl);
|
|
GetDlgItem(IDC_BUTTON_CHOOSE_USER)->EnableWindow(fIsNtServer && fHasServiceControl);
|
|
GetDlgItem(IDC_EDIT_NAME)->EnableWindow(fIsNtServer && fHasServiceControl);
|
|
GetDlgItem(IDC_EDIT_PASSWORD)->EnableWindow(fIsNtServer && fHasServiceControl);
|
|
GetDlgItem(IDC_STATIC_ACCOUNT_INFO)->EnableWindow(fIsNtServer && fHasServiceControl);
|
|
|
|
if (fServiceRunning)
|
|
{
|
|
|
|
// enable the remove button if something is selected
|
|
BOOL fEnableRemove = m_listAdmins.GetCurSel() != LB_ERR;
|
|
|
|
//if we will disable the remove button and the remove button has the focus,
|
|
//we should change focus to the next control
|
|
CWnd * pwndRemove = GetDlgItem(IDC_BUTTON_REMOVE_ADMIN);
|
|
|
|
if (!fEnableRemove && GetFocus() == pwndRemove)
|
|
{
|
|
NextDlgCtrl();
|
|
}
|
|
|
|
pwndRemove->EnableWindow(fEnableRemove);
|
|
}
|
|
}
|
|
|
|
BOOL CServerPropSetup::OnApply()
|
|
{
|
|
CString strAccount, strPassword;
|
|
BOOL fUpdateAccount = FALSE;
|
|
BOOL fUpdateTapiServer = FALSE;
|
|
BOOL bRet = TRUE;
|
|
BOOL bWasServer, bToBeServer;
|
|
DWORD dwStartType = SERVICE_NO_CHANGE;
|
|
|
|
if (!IsDirty())
|
|
return bRet;
|
|
|
|
CServerProperties * pServerProp = (CServerProperties * ) GetHolder();
|
|
|
|
UpdateData();
|
|
|
|
// Check to see if there is any change on enabling server
|
|
// or user account name, that requires service restarting
|
|
if (!m_fRestartService)
|
|
{
|
|
bWasServer = m_dwInitFlags & TAPISERVERCONFIGFLAGS_ENABLESERVER;
|
|
bToBeServer = ((CButton *) GetDlgItem(IDC_CHECK_ENABLE_SERVER))->GetCheck();
|
|
if (bWasServer && !bToBeServer || !bWasServer && bToBeServer)
|
|
{
|
|
m_fRestartService = TRUE;
|
|
}
|
|
if (m_dwNewFlags & TAPISERVERCONFIGFLAGS_SETACCOUNT)
|
|
{
|
|
GetDlgItem(IDC_EDIT_NAME)->GetWindowText(strAccount);
|
|
if (strAccount.CompareNoCase(pServerProp->GetServiceAccountName()) != 0)
|
|
{
|
|
m_fRestartService = TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_dwNewFlags &= ~TAPISERVERCONFIGFLAGS_SETACCOUNT;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if the account information has changed, the update the info struct now
|
|
if (m_dwNewFlags & TAPISERVERCONFIGFLAGS_SETACCOUNT)
|
|
{
|
|
GetDlgItem(IDC_EDIT_NAME)->GetWindowText(strAccount);
|
|
GetDlgItem(IDC_EDIT_PASSWORD)->GetWindowText(strPassword);
|
|
|
|
// verify that the user is an admin on the machine
|
|
if (!IsLocalSystemAccount(strAccount))
|
|
{
|
|
DWORD dwErr;
|
|
BOOL fIsAdmin;
|
|
CString strMessage;
|
|
|
|
dwErr = ::IsAdmin(pServerProp->m_strMachineName, strAccount, strPassword, &fIsAdmin);
|
|
|
|
if (!fIsAdmin)
|
|
{
|
|
AfxFormatString1(strMessage, IDS_ERR_USER_NOT_ADMIN, pServerProp->m_strMachineName);
|
|
AfxMessageBox(strMessage);
|
|
|
|
GetDlgItem(IDC_EDIT_NAME)->SetFocus();
|
|
((CEdit *) GetDlgItem(IDC_EDIT_NAME))->SetSel(0, -1);
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// clear the flag so we don't use the TAPI MMC APIs to set this
|
|
m_dwNewFlags &= ~TAPISERVERCONFIGFLAGS_SETACCOUNT;
|
|
fUpdateAccount = TRUE;
|
|
}
|
|
|
|
// if we are changing the server state or admin stuff then
|
|
if (((CButton *) GetDlgItem(IDC_CHECK_ENABLE_SERVER))->GetCheck())
|
|
{
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_ENABLESERVER;
|
|
}
|
|
|
|
// only update config information if it has changed
|
|
if ((pServerProp->FIsServiceRunning()) &&
|
|
(m_tapiConfigInfo.m_dwFlags != m_dwNewFlags))
|
|
{
|
|
// if we modify the tapi server status then we need to change the
|
|
// service statrt type as well.
|
|
if ((m_dwNewFlags & TAPISERVERCONFIGFLAGS_ENABLESERVER) &&
|
|
!(m_tapiConfigInfo.m_dwFlags & TAPISERVERCONFIGFLAGS_ENABLESERVER))
|
|
{
|
|
fUpdateTapiServer = TRUE;
|
|
}
|
|
|
|
dwStartType = (m_dwNewFlags & TAPISERVERCONFIGFLAGS_ENABLESERVER) ? SERVICE_AUTO_START : SERVICE_DEMAND_START;
|
|
|
|
bRet = CPropertyPageBase::OnApply();
|
|
}
|
|
|
|
if (bRet == FALSE)
|
|
{
|
|
// Something bad happened... grab the error code
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
|
|
::TapiMessageBox(WIN32_FROM_HRESULT(GetHolder()->GetError()));
|
|
|
|
// restore the flag
|
|
if (fUpdateAccount)
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_SETACCOUNT;
|
|
}
|
|
else
|
|
{
|
|
m_dwNewFlags = TAPISERVERCONFIGFLAGS_ISSERVER;
|
|
|
|
if (fUpdateAccount || fUpdateTapiServer)
|
|
{
|
|
// do the account change
|
|
BEGIN_WAIT_CURSOR
|
|
|
|
LPCTSTR pszAccount = (fUpdateAccount) ? (LPCTSTR) strAccount : NULL;
|
|
LPCTSTR pszPassword = (fUpdateAccount) ? (LPCTSTR) strPassword : NULL;
|
|
|
|
bRet = pServerProp->FUpdateServiceInfo(pszAccount, pszPassword, dwStartType);
|
|
|
|
if (bRet)
|
|
{
|
|
/*$REVIEW
|
|
Tapisrv occupies a seperate house in NT server. It lives with the other
|
|
services on NT Professional Edition(workstation). We do not need to
|
|
sperate/merge services anymore. Users should not be allowed to change
|
|
account information from TAPI MMC on NT workstation(Disabled).
|
|
|
|
HRESULT hr;
|
|
|
|
// if the change was successful, update the svc host information
|
|
hr = UpdateSvcHostInfo(pServerProp->m_strMachineName, IsLocalSystemAccount(strAccount));
|
|
if (FAILED(hr))
|
|
{
|
|
// restore the flag
|
|
if (fUpdateAccount)
|
|
{
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_SETACCOUNT;
|
|
}
|
|
|
|
::TapiMessageBox(WIN32_FROM_HRESULT(hr));
|
|
return FALSE;
|
|
}
|
|
*/
|
|
}
|
|
else if (fUpdateAccount)
|
|
{
|
|
// set account failed, so set the flag again.
|
|
m_dwNewFlags |= TAPISERVERCONFIGFLAGS_SETACCOUNT;
|
|
}
|
|
|
|
END_WAIT_CURSOR
|
|
}
|
|
|
|
// if everything went OK and we changed something that requires a service restart then
|
|
// do ask the user if they want to do it now
|
|
if (bRet && m_fRestartService)
|
|
{
|
|
CString strText;
|
|
BOOL fServiceRunning = pServerProp->FIsServiceRunning();
|
|
|
|
::TFSIsServiceRunning(pServerProp->m_strMachineName,
|
|
TAPI_SERVICE_NAME,
|
|
&fServiceRunning);
|
|
|
|
if (fServiceRunning)
|
|
strText.LoadString(IDS_ACCOUNT_CHANGE_RESTART);
|
|
else
|
|
strText.LoadString(IDS_ACCOUNT_CHANGE_START);
|
|
|
|
// Tell the user the service needs to be restarted in order to make the changes
|
|
if (AfxMessageBox(strText, MB_YESNO) == IDYES)
|
|
{
|
|
if (RestartService() == ERROR_SUCCESS)
|
|
{
|
|
m_fRestartService = FALSE;
|
|
m_dwInitFlags = m_tapiConfigInfo.m_dwFlags;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bRet)
|
|
SetDirty(TRUE);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CServerPropSetup::OnPropertyChange(BOOL bScope, LONG_PTR *ChangeMask)
|
|
{
|
|
SPITapiInfo spTapiInfo;
|
|
HRESULT hr = hrOK;
|
|
BOOL fServiceRunning = TRUE;
|
|
DWORD dwOldFlags;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
CServerProperties * pServerProp = (CServerProperties * ) GetHolder();
|
|
|
|
pServerProp->GetTapiInfo(&spTapiInfo);
|
|
Assert(spTapiInfo);
|
|
|
|
// if the service isn't running, try to start it
|
|
//if (!pServerProp->FIsServiceRunning())
|
|
dwErr = ::TFSIsServiceRunning(pServerProp->m_strMachineName,
|
|
TAPI_SERVICE_NAME,
|
|
&fServiceRunning);
|
|
if (!fServiceRunning)
|
|
{
|
|
// service has stopped from under us. Return an error.
|
|
GetHolder()->SetError(HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE));
|
|
return FALSE;
|
|
}
|
|
|
|
// if everything is cool then make the changes
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
dwOldFlags = m_tapiConfigInfo.m_dwFlags;
|
|
|
|
//clear the changable bits in old flags
|
|
m_tapiConfigInfo.m_dwFlags &= ~c_dwChangableFlagMask;
|
|
|
|
//set the changable bits
|
|
m_tapiConfigInfo.m_dwFlags |= (m_dwNewFlags & c_dwChangableFlagMask);
|
|
|
|
hr = spTapiInfo->SetConfigInfo(&m_tapiConfigInfo);
|
|
|
|
//Bug 276787 We should clear the two write bits
|
|
m_tapiConfigInfo.m_dwFlags &= ~(TAPISERVERCONFIGFLAGS_SETACCOUNT |
|
|
TAPISERVERCONFIGFLAGS_SETTAPIADMINISTRATORS);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
GetHolder()->SetError(hr);
|
|
m_tapiConfigInfo.m_dwFlags = dwOldFlags;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
HRESULT CServerPropSetup::UpdateSvcHostInfo(LPCTSTR pszMachine, BOOL fLocalSystemAccount)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
MULTI_QI qi;
|
|
SPIRemoteNetworkConfig spRemote;
|
|
|
|
hr = CoInitialize(NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
if (IsLocalMachine(pszMachine))
|
|
{
|
|
hr = CoCreateInstance(CLSID_RemoteRouterConfig,
|
|
NULL,
|
|
CLSCTX_SERVER,
|
|
IID_IRemoteNetworkConfig,
|
|
(LPVOID *) &(qi.pItf));
|
|
}
|
|
else
|
|
{
|
|
COSERVERINFO csi;
|
|
|
|
qi.pIID = &IID_IRemoteNetworkConfig;
|
|
qi.pItf = NULL;
|
|
qi.hr = 0;
|
|
|
|
csi.dwReserved1 = 0;
|
|
csi.dwReserved2 = 0;
|
|
csi.pwszName = (LPWSTR) (LPCTSTR) pszMachine;
|
|
csi.pAuthInfo = NULL;
|
|
hr = CoCreateInstanceEx(CLSID_RemoteRouterConfig,
|
|
NULL,
|
|
CLSCTX_SERVER,
|
|
&csi,
|
|
1,
|
|
&qi);
|
|
}
|
|
|
|
Trace1("CServerPropSetup::UpdateSvcHostInfo - CoCreateInstance returned %lx\n", hr);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
CString strGroup;
|
|
|
|
strGroup = _T("Tapisrv");
|
|
|
|
spRemote = (IRemoteNetworkConfig *)qi.pItf;
|
|
hr = spRemote->SetUserConfig(TAPI_SERVICE_NAME, strGroup);
|
|
|
|
Trace1("CServerPropSetup::UpdateSvcHostInfo - SetUserConfig returned %lx\n", hr);
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
return hr;
|
|
}
|
|
|
|
DWORD CServerPropSetup::RestartService()
|
|
{
|
|
// restart the service if requested
|
|
CServerProperties * pServerProp = (CServerProperties * ) GetHolder();
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
BOOL fRestart = FALSE;
|
|
|
|
SPITapiInfo spTapiInfo;
|
|
pServerProp->GetTapiInfo(&spTapiInfo);
|
|
|
|
// gotta clean up before the service stops
|
|
spTapiInfo->Destroy();
|
|
|
|
// any time we stop/start the service we need to call this
|
|
::UnloadTapiDll();
|
|
|
|
// stop the service if it is running
|
|
BOOL fServiceRunning = pServerProp->FIsServiceRunning();
|
|
|
|
::TFSIsServiceRunning(pServerProp->m_strMachineName,
|
|
TAPI_SERVICE_NAME,
|
|
&fServiceRunning);
|
|
|
|
if (fServiceRunning)
|
|
{
|
|
dwErr = ::TFSStopService(pServerProp->m_strMachineName, TAPI_SERVICE_NAME, pServerProp->GetServiceDisplayName());
|
|
}
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
CString strText;
|
|
strText.LoadString(IDS_ERR_SERVICE_NOT_STOPPED);
|
|
TapiMessageBox(dwErr, MB_OK, strText);
|
|
}
|
|
|
|
// start the service
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
dwErr = ::TFSStartService(pServerProp->m_strMachineName, TAPI_SERVICE_NAME, pServerProp->GetServiceDisplayName());
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
CString strText;
|
|
strText.LoadString(IDS_ERR_SERVICE_NOT_STARTED);
|
|
TapiMessageBox(dwErr, MB_OK, strText);
|
|
}
|
|
}
|
|
|
|
StartRefresh();
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
void CServerPropSetup::StartRefresh()
|
|
{
|
|
// refresh the snapin to reflect the changes
|
|
SPITFSNode spNode;
|
|
CTapiServer * pServer;
|
|
|
|
spNode = GetHolder()->GetNode();
|
|
pServer = GETHANDLER(CTapiServer, spNode);
|
|
|
|
pServer->OnRefresh(spNode, NULL, 0, 0, 0);
|
|
}
|