//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation 1996-2001. // // File: cservice.cpp // // Contents: implementation of CConfigService // //---------------------------------------------------------------------------- #include "stdafx.h" #include "wsecmgr.h" #include "resource.h" #include "snapmgr.h" #include "attr.h" #include "Cservice.h" #include "util.h" #include "servperm.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CConfigService dialog CConfigService::CConfigService(UINT nTemplateID) : CAttribute(nTemplateID ? nTemplateID : IDD), m_hwndSecurity(NULL), m_pNewSD(NULL), m_NewSeInfo(0) { //{{AFX_DATA_INIT(CConfigService) m_nStartupRadio = -1; //}}AFX_DATA_INIT m_pHelpIDs = (DWORD_PTR) a195HelpIDs; m_uTemplateResID = IDD; } void CConfigService::DoDataExchange(CDataExchange* pDX) { CAttribute::DoDataExchange(pDX); //{{AFX_DATA_MAP(CConfigService) DDX_Radio(pDX, IDC_ENABLED, m_nStartupRadio); DDX_Control(pDX, IDC_BASESD, m_bPermission); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CConfigService, CAttribute) //{{AFX_MSG_MAP(CConfigService) ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure) ON_BN_CLICKED(IDC_BASESD, OnChangeSecurity) ON_BN_CLICKED(IDC_DISABLED, OnDisabled) ON_BN_CLICKED(IDC_IGNORE, OnIgnore) ON_BN_CLICKED(IDC_ENABLED, OnEnabled) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CConfigService message handlers BOOL CConfigService::OnApply() { if ( !m_bReadOnly ) { DWORD dw = 0; int status = 0; UpdateData(TRUE); PEDITTEMPLATE pTemp = m_pData->GetBaseProfile(); if (!m_bConfigure ) { if ( m_pData->GetBase() != 0 ) { if ( pTemp != NULL && pTemp->pTemplate != NULL ) { // // look for the address stored in m_pData->GetBase() // if found it, delete it. // PSCE_SERVICES pServParent, pService; for ( pService=pTemp->pTemplate->pServices, pServParent=NULL; pService != NULL; pServParent=pService, pService=pService->Next ) { if (pService == (PSCE_SERVICES)m_pData->GetBase() ) { // // a configured service becomes not configured // if ( pServParent == NULL ) { // the first service pTemp->pTemplate->pServices = pService->Next; } else pServParent->Next = pService->Next; pService->Next = NULL; break; } } m_pData->SetBase(NULL); //Raid #378271, 4/27/2001 } else { // should never happen // // free the service node // SceFreeMemory((PVOID)(m_pData->GetBase()), SCE_STRUCT_SERVICES); m_pData->SetBase(0); } } if ( m_pNewSD ) { LocalFree(m_pNewSD); m_pNewSD = NULL; } } else { switch(m_nStartupRadio) { case 0: // Automatic dw = SCE_STARTUP_AUTOMATIC; break; case 1: // Manual dw = SCE_STARTUP_MANUAL; break; case 2: // DISABLED dw = SCE_STARTUP_DISABLED; break; default: //Raid #470209, Yang Gao. //When it is configured it must have one of above values CString msg; msg.LoadString(IDS_ERROR_NO_START_MODE); AfxMessageBox(msg, MB_OK|MB_ICONEXCLAMATION); //Raid #495010, yanggao return FALSE; } PSCE_SERVICES pNode=(PSCE_SERVICES)(m_pData->GetBase()); if ( NULL == pNode ) { // // a node is changed from not configured to configured // pNode = CreateServiceNode(m_pData->GetUnits(), m_pData->GetAttr(), dw, m_pNewSD, m_NewSeInfo); if ( pNode != NULL ) { // // add to the service list // pNode->Next = pTemp->pTemplate->pServices; pTemp->pTemplate->pServices = pNode; m_pData->SetBase((LONG_PTR)pNode); m_pNewSD = NULL; } else { // // no memory, error out // if ( m_pNewSD ) { LocalFree(m_pNewSD); m_pNewSD = NULL; } } } else { // // an existing service // pNode->Startup = (BYTE)dw; if ( m_pNewSD != NULL ) { if ( pNode->General.pSecurityDescriptor != m_pNewSD && pNode->General.pSecurityDescriptor != NULL ) { LocalFree(pNode->General.pSecurityDescriptor); } pNode->General.pSecurityDescriptor = m_pNewSD; m_pNewSD = NULL; pNode->SeInfo = m_NewSeInfo; } } } m_pData->Update(m_pSnapin); m_NewSeInfo = 0; m_hwndParent = NULL; } return CAttribute::OnApply(); } void CConfigService::OnCancel() { if ( m_pNewSD ) { LocalFree(m_pNewSD); m_pNewSD = NULL; } m_NewSeInfo = 0; m_hwndParent = NULL; m_bConfigure = m_bOriginalConfigure; CAttribute::OnCancel(); } BOOL CConfigService::OnInitDialog() { CAttribute::OnInitDialog(); m_bOriginalConfigure = m_bConfigure; AddUserControl(IDC_ENABLED); AddUserControl(IDC_DISABLED); AddUserControl(IDC_IGNORE); AddUserControl(IDC_BASESD); if (QueryReadOnly()) { CString str; str.LoadString(IDS_VIEW_SECURITY); if ( GetDlgItem(IDC_SECURITY) ) SetDlgItemText(IDC_SECURITY,str); else if ( GetDlgItem(IDC_BASESD) ) SetDlgItemText(IDC_BASESD,str); } OnConfigure(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CConfigService::Initialize(CResult * pResult) { CAttribute::Initialize(pResult); PSCE_SERVICES pService; pService = (PSCE_SERVICES)(pResult->GetBase()); if ( NULL == pService ) { m_bConfigure = FALSE; pService = (PSCE_SERVICES)(pResult->GetSetting()); } m_pNewSD = NULL; m_NewSeInfo = 0; if ( pService != NULL ) { switch ( pService->Startup ) { case SCE_STARTUP_AUTOMATIC: m_nStartupRadio = 0; break; case SCE_STARTUP_MANUAL: m_nStartupRadio = 1; break; case SCE_STARTUP_DISABLED: // disabled m_nStartupRadio = 2; break; default: // not defined //Raid #470209, Yang Gao m_nStartupRadio = -1; break; } // // initialize SD and SeInfo // if ( pService->General.pSecurityDescriptor ) { MyMakeSelfRelativeSD(pService->General.pSecurityDescriptor, &m_pNewSD); } m_NewSeInfo = pService->SeInfo; } } PSCE_SERVICES CreateServiceNode(LPTSTR ServiceName, LPTSTR DisplayName, DWORD Startup, PSECURITY_DESCRIPTOR pSD, SECURITY_INFORMATION SeInfo) { if ( NULL == ServiceName ) { return NULL; } PSCE_SERVICES pTemp; pTemp = (PSCE_SERVICES)LocalAlloc(0,sizeof(SCE_SERVICES)); if ( pTemp != NULL ) { pTemp->ServiceName = (LPTSTR)LocalAlloc(0, (wcslen(ServiceName)+1)*sizeof(TCHAR)); if ( pTemp->ServiceName != NULL ) { if ( DisplayName != NULL ) { pTemp->DisplayName = (LPTSTR)LocalAlloc(0, (wcslen(DisplayName)+1)*sizeof(TCHAR)); if ( pTemp->DisplayName != NULL ) { //This may not be a safe usage. pTemp->DisplayName is PWSTR, Consider fix. wcscpy(pTemp->DisplayName, DisplayName); } else { // no memory to allocate LocalFree(pTemp->ServiceName); LocalFree(pTemp); return NULL; } } else pTemp->DisplayName = NULL; //This may not be a safe usage. pTemp->ServiceName is PWSTR, Consider fix. wcscpy(pTemp->ServiceName, ServiceName); pTemp->Status = 0; pTemp->Startup = (BYTE)Startup; pTemp->General.pSecurityDescriptor = pSD; pTemp->SeInfo = SeInfo; pTemp->Next = NULL; return pTemp; } else { // no memory to allocate LocalFree(pTemp); return NULL; } } return NULL; } void CConfigService::OnConfigure() { CAttribute::OnConfigure(); if( -1 == m_nStartupRadio && m_bConfigure ) //Raid #485374, Yanggao, 11/2/2001 { PSCE_SERVICES pService = (PSCE_SERVICES)m_pData->GetProfileDefault(); if( SCE_NO_VALUE != (DWORD)PtrToUlong((PVOID)pService) ) { switch ( pService->Startup ) { case SCE_STARTUP_AUTOMATIC: m_nStartupRadio = 0; break; case SCE_STARTUP_MANUAL: m_nStartupRadio = 1; break; case SCE_STARTUP_DISABLED: m_nStartupRadio = 2; break; default: m_nStartupRadio = -1; break; } UpdateData(FALSE); } } } void CConfigService::OnChangeSecurity() { if (IsWindow(m_hwndSecurity)) { ::BringWindowToTop(m_hwndSecurity); return; } PSECURITY_DESCRIPTOR m_pOldSD = m_pNewSD; //Raid #358244, 4/5/2001 SECURITY_INFORMATION m_OldSeInfo = m_NewSeInfo; if (!m_pNewSD) { GetDefaultServiceSecurity(&m_pNewSD,&m_NewSeInfo); } INT_PTR nRet = MyCreateSecurityPage2(FALSE, &m_pNewSD, &m_NewSeInfo, (LPCTSTR)(m_pData->GetAttr()), SE_SERVICE, QueryReadOnly() ? SECURITY_PAGE_RO_NP : SECURITY_PAGE_NO_PROTECT, GetSafeHwnd(), FALSE); // not modeless if ( -1 == nRet ) { CString str; str.LoadString(IDS_CANT_ASSIGN_SECURITY); AfxMessageBox(str); if( m_pNewSD != m_pOldSD && m_pNewSD ) //Raid #358244, 4/5/2001 { LocalFree(m_pNewSD); } m_pNewSD = m_pOldSD; m_NewSeInfo = m_OldSeInfo; } if( 0 == nRet ) //Raid #358244, 4/5/2001 { if( m_pNewSD != m_pOldSD && m_pNewSD ) { LocalFree(m_pNewSD); } m_pNewSD = m_pOldSD; m_NewSeInfo = m_OldSeInfo; } SetModified(TRUE); } void CConfigService::OnDisabled() { int prevValue = m_nStartupRadio; //Raid #490995, Yanggao UpdateData(); if(m_nStartupRadio != prevValue) { SetModified(TRUE); } } void CConfigService::OnIgnore() { int prevValue = m_nStartupRadio; //Raid #490995, Yanggao UpdateData(); if(m_nStartupRadio != prevValue) { SetModified(TRUE); } } void CConfigService::OnEnabled() { int prevValue = m_nStartupRadio; //Raid #490995, Yanggao UpdateData(); if(m_nStartupRadio != prevValue) { SetModified(TRUE); } } void CConfigService::EnableUserControls( BOOL bEnable ) { CAttribute::EnableUserControls(bEnable); // // IDC_SECURITY needs to be available even in read only // mode so that the security page can be viewed. // // The page itself will be read only if necessary // if (QueryReadOnly() && bEnable) { CWnd* pWnd = GetDlgItem(IDC_SECURITY); if (pWnd) { pWnd->EnableWindow(TRUE); } else { pWnd = GetDlgItem(IDC_BASESD); if (pWnd) { pWnd->EnableWindow(TRUE); } } } }