windows-nt/Source/XPSP1/NT/admin/snapin/filemgmt/svcprop2.cpp
2020-09-26 16:20:57 +08:00

547 lines
17 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// svcprop2.cpp : implementation file
//
// This file is used to display the 'log on information' and the
// 'hardware profiles' of a given service.
//
// HISTORY
// 10-Oct-96 t-danmo Creation.
//
#include "stdafx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// These strings are not localized
// JonN 4/11/00 17756: Changed behavior so that empty string is displayed in
// account name field when last logon name was LocalSystem
const TCHAR szLocalSystemAccount[] = _T("LocalSystem");
const TCHAR szPasswordNull[] = _T(" "); // Empty password
// Array of control Ids to prevent user to change account selection
const UINT rgzidDisableAccountSelection[] =
{
IDC_RADIO_LOGONAS_SYSTEMACCOUNT,
IDC_RADIO_LOGONAS_THIS_ACCOUNT,
IDC_EDIT_ACCOUNTNAME,
IDC_BUTTON_CHOOSE_USER,
IDC_STATIC_PASSWORD,
IDC_EDIT_PASSWORD,
IDC_STATIC_PASSWORD_CONFIRM,
IDC_EDIT_PASSWORD_CONFIRM,
0
};
// Array of control Ids to indicate user to not type a password
const UINT rgzidDisablePassword[] =
{
IDC_EDIT_ACCOUNTNAME,
IDC_BUTTON_CHOOSE_USER,
IDC_STATIC_PASSWORD,
IDC_EDIT_PASSWORD,
IDC_STATIC_PASSWORD_CONFIRM,
IDC_EDIT_PASSWORD_CONFIRM,
0
};
// Array of control Ids to hide hardware profile listbox and releated buttons
const UINT rgzidHwProfileHide[] =
{
IDC_LIST_HARDWARE_PROFILES,
IDC_BUTTON_ENABLE,
IDC_BUTTON_DISABLE,
0
};
// Column headers for the hardware profiles
const TColumnHeaderItem rgzHardwareProfileHeader[] =
{
{ IDS_SVC_HARDWARE_PROFILE, 75 },
{ IDS_SVC_STATUS, 24 },
{ 0, 0 },
};
const TColumnHeaderItem rgzHardwareProfileHeaderInst[] =
{
{ IDS_SVC_HARDWARE_PROFILE, 55 },
{ IDS_SVC_INSTANCE, 22 },
{ IDS_SVC_STATUS, 22 },
{ 0, 0 },
};
/////////////////////////////////////////////////////////////////////////////
// CServicePageHwProfile property page
IMPLEMENT_DYNCREATE(CServicePageHwProfile, CPropertyPage)
CServicePageHwProfile::CServicePageHwProfile() : CPropertyPage(CServicePageHwProfile::IDD)
{
//{{AFX_DATA_INIT(CServicePageHwProfile)
m_fAllowServiceToInteractWithDesktop = FALSE;
//}}AFX_DATA_INIT
m_idRadioButton = 0;
m_fPasswordDirty = FALSE;
}
CServicePageHwProfile::~CServicePageHwProfile()
{
}
void CServicePageHwProfile::DoDataExchange(CDataExchange* pDX)
{
Assert(m_pData != NULL);
Assert(m_pData->m_paQSC != NULL);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!pDX->m_bSaveAndValidate)
{
// Determine if service is running under 'local system'
m_fIsSystemAccount = (m_pData->m_paQSC->lpServiceStartName == NULL) ||
(lstrcmpi(m_pData->m_strLogOnAccountName, szLocalSystemAccount) == 0);
m_fAllowServiceToInteractWithDesktop = m_fIsSystemAccount &&
(m_pData->m_paQSC->dwServiceType & SERVICE_INTERACTIVE_PROCESS);
// JonN 4/11/00: 17756
if (m_fIsSystemAccount)
m_strAccountName.Empty();
else
m_strAccountName = m_pData->m_strLogOnAccountName;
m_strPassword =
(m_fIsSystemAccount) ? szPasswordNull : m_pData->m_strPassword;
m_strPasswordConfirm = m_strPassword;
//
// JonN 4/10/00
// 89823: RPC Service:Cannot restart the service when you disable it
//
// Do not allow the RpcSs service to change from Local System
//
if ( !lstrcmpi(m_pData->m_strServiceName,L"RpcSs")
&& m_fIsSystemAccount )
{
EnableDlgItem(m_hWnd, IDC_RADIO_LOGONAS_SYSTEMACCOUNT, FALSE);
EnableDlgItem(m_hWnd, IDC_RADIO_LOGONAS_THIS_ACCOUNT, FALSE);
}
} // if
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CServicePageHwProfile)
DDX_Check(pDX, IDC_CHECK_SERVICE_INTERACT_WITH_DESKTOP, m_fAllowServiceToInteractWithDesktop);
DDX_Text(pDX, IDC_EDIT_ACCOUNTNAME, m_strAccountName);
DDV_MaxChars(pDX, m_strPassword, DNLEN+UNLEN+1);
DDX_Text(pDX, IDC_EDIT_PASSWORD, m_strPassword);
DDV_MaxChars(pDX, m_strPassword, PWLEN);
DDX_Text(pDX, IDC_EDIT_PASSWORD_CONFIRM, m_strPasswordConfirm);
DDV_MaxChars(pDX, m_strPasswordConfirm, PWLEN);
//}}AFX_DATA_MAP
if (pDX->m_bSaveAndValidate)
{
if (!m_fIsSystemAccount)
{
TrimString(m_strAccountName);
if (m_strAccountName.IsEmpty()) // JonN 4/11/00: 17756
{
m_fIsSystemAccount = TRUE;
}
}
if (!m_fIsSystemAccount)
{
//
// Log On As "This Account"
//
// If not system account, can't interact with desktop
m_pData->m_paQSC->dwServiceType &= ~SERVICE_INTERACTIVE_PROCESS;
// Search if the string contains a server name
// JonN 3/16/99: and if name is not a UPN (bug 280254)
if (m_strAccountName.FindOneOf(_T("@\\")) < 0)
{
// Add ".\" at the beginning
m_strAccountName = _T(".\\") + m_strAccountName;
}
if (m_strPassword != m_strPasswordConfirm)
{
DoServicesErrMsgBox(m_hWnd, MB_OK | MB_ICONEXCLAMATION, 0, IDS_MSG_PASSWORD_MISMATCH);
pDX->Fail();
Assert(FALSE && "Unreachable code");
}
} // if (!m_fIsSystemAccount)
if (m_fIsSystemAccount)
{
//
// Log On As "System Account"
//
if (m_fAllowServiceToInteractWithDesktop)
m_pData->m_paQSC->dwServiceType |= SERVICE_INTERACTIVE_PROCESS;
else
m_pData->m_paQSC->dwServiceType &= ~SERVICE_INTERACTIVE_PROCESS;
m_strAccountName.Empty(); // JonN 4/11/00: 17756
m_strPassword.Empty(); // Clear the password (system account don't require password)
m_fPasswordDirty = FALSE;
}
// JonN 4/11/00: 17756
BOOL fWasSystemAccount = !lstrcmpi(
m_pData->m_strLogOnAccountName, szLocalSystemAccount);
BOOL fAccountNameModified = (m_fIsSystemAccount)
? !fWasSystemAccount
: (fWasSystemAccount || lstrcmpi(m_strAccountName, m_pData->m_strLogOnAccountName));
// Check if either the Account Name or password was modified
// CODEWORK Note that fAccountNameModified will be TRUE if the last write
// attempt failed.
if (fAccountNameModified || m_fPasswordDirty)
{
if (fAccountNameModified && (m_strPassword == szPasswordNull))
{
// Account name modified, but password not changed
DoServicesErrMsgBox(m_hWnd, MB_OK | MB_ICONEXCLAMATION, 0, IDS_MSG_PASSWORD_EMPTY);
pDX->PrepareEditCtrl(IDC_EDIT_PASSWORD);
pDX->Fail();
Assert(FALSE && "Unreacheable code");
}
TRACE0("Service log on account name or password modified...\n");
m_pData->m_strLogOnAccountName = // JonN 4/11/00: 17756
(m_fIsSystemAccount) ? szLocalSystemAccount : m_strAccountName;
m_pData->m_strPassword = m_strPassword;
// If the account name is changed or the password is changed,
// then all the following parameters must be re-written
// to the registry. Otherwise ChangeServiceConfig() will fail.
// This is not documented; it is the reality.
m_pData->SetDirty( (enum CServicePropertyData::_DIRTYFLAGS)
(CServicePropertyData::mskfDirtyAccountName |
CServicePropertyData::mskfDirtyPassword |
CServicePropertyData::mskfDirtySvcType) );
}
} // if
} // CServicePageHwProfile::DoDataExchange()
BEGIN_MESSAGE_MAP(CServicePageHwProfile, CPropertyPage)
//{{AFX_MSG_MAP(CServicePageHwProfile)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_HARDWARE_PROFILES, OnItemChangedListHwProfiles)
ON_NOTIFY(NM_DBLCLK, IDC_LIST_HARDWARE_PROFILES, OnDblclkListHwProfiles)
ON_MESSAGE(WM_HELP, OnHelp)
ON_MESSAGE(WM_CONTEXTMENU, OnContextHelp)
ON_BN_CLICKED(IDC_BUTTON_DISABLE, OnButtonDisableHwProfile)
ON_BN_CLICKED(IDC_BUTTON_ENABLE, OnButtonEnableHwProfile)
ON_BN_CLICKED(IDC_BUTTON_CHOOSE_USER, OnButtonChooseUser)
ON_BN_CLICKED(IDC_RADIO_LOGONAS_SYSTEMACCOUNT, OnRadioLogonasSystemAccount)
ON_BN_CLICKED(IDC_RADIO_LOGONAS_THIS_ACCOUNT, OnRadioLogonasThisAccount)
ON_BN_CLICKED(IDC_CHECK_SERVICE_INTERACT_WITH_DESKTOP, OnCheckServiceInteractWithDesktop)
ON_EN_CHANGE(IDC_EDIT_ACCOUNTNAME, OnChangeEditAccountName)
ON_EN_CHANGE(IDC_EDIT_PASSWORD, OnChangeEditPassword)
ON_EN_CHANGE(IDC_EDIT_PASSWORD_CONFIRM, OnChangeEditPasswordConfirm)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServicePageHwProfile message handlers
BOOL CServicePageHwProfile::OnInitDialog()
{
Assert(m_pData != NULL);
Assert(m_pData->m_paQSC != NULL);
if (m_pData->m_paQSC == NULL)
EndDialog(FALSE); // Just in case
m_pData->m_strPassword = szPasswordNull;
::LoadString(g_hInstanceSave, IDS_SVC_ENABLED,
OUT m_szHwProfileEnabled, LENGTH(m_szHwProfileEnabled));
::LoadString(g_hInstanceSave, IDS_SVC_DISABLED,
OUT m_szHwProfileDisabled, LENGTH(m_szHwProfileDisabled));
m_hwndListViewHwProfiles = ::GetDlgItem(m_hWnd, IDC_LIST_HARDWARE_PROFILES);
if (m_pData->m_paHardwareProfileEntryList != NULL)
{
ListView_AddColumnHeaders(m_hwndListViewHwProfiles, m_pData->m_fShowHwProfileInstances
? rgzHardwareProfileHeaderInst : rgzHardwareProfileHeader);
BuildHwProfileList();
}
else
{
// There are no hardware profile(s) in the list, so hide
// all the controls that have something to do with hardware profiles
ShowDlgItemGroup(m_hWnd, rgzidHwProfileHide, FALSE);
}
CPropertyPage::OnInitDialog();
return TRUE;
} // OnInitDialog()
/////////////////////////////////////////////////////////////////////
// Select a given radio button and enable/disable
// controls depending on which radio button is selected
void CServicePageHwProfile::SelectRadioButton(UINT idRadioButtonNew)
{
Assert(HGetDlgItem(m_hWnd, idRadioButtonNew));
if (idRadioButtonNew == m_idRadioButton)
return;
m_fAllowSetModified = FALSE;
CheckRadioButton(IDC_RADIO_LOGONAS_SYSTEMACCOUNT, IDC_RADIO_LOGONAS_THIS_ACCOUNT, idRadioButtonNew);
if (idRadioButtonNew == IDC_RADIO_LOGONAS_SYSTEMACCOUNT)
{
m_fIsSystemAccount = TRUE;
::EnableDlgItemGroup(m_hWnd, rgzidDisablePassword, FALSE);
if (m_idRadioButton != 0)
{
GetDlgItemText(IDC_EDIT_ACCOUNTNAME, m_strAccountName);
GetDlgItemText(IDC_EDIT_PASSWORD, m_strPassword);
GetDlgItemText(IDC_EDIT_PASSWORD_CONFIRM, m_strPasswordConfirm);
}
SetDlgItemText(IDC_EDIT_ACCOUNTNAME, L"");
SetDlgItemText(IDC_EDIT_PASSWORD, L"");
SetDlgItemText(IDC_EDIT_PASSWORD_CONFIRM, L"");
}
else
{
m_fIsSystemAccount = FALSE;
::EnableDlgItemGroup(m_hWnd, rgzidDisablePassword, TRUE);
SetDlgItemText(IDC_EDIT_ACCOUNTNAME, m_strAccountName);
SetDlgItemText(IDC_EDIT_PASSWORD, m_strPassword);
SetDlgItemText(IDC_EDIT_PASSWORD_CONFIRM, m_strPasswordConfirm);
}
GetDlgItem(IDC_CHECK_SERVICE_INTERACT_WITH_DESKTOP)->EnableWindow(m_fIsSystemAccount);
m_idRadioButton = idRadioButtonNew;
m_fAllowSetModified = TRUE;
} // CServicePageHwProfile::SelectRadioButton()
/////////////////////////////////////////////////////////////////////
void CServicePageHwProfile::BuildHwProfileList()
{
LV_ITEM lvItem;
INT iItem;
CHardwareProfileEntry * pHPE;
Assert(IsWindow(m_hwndListViewHwProfiles));
ListView_DeleteAllItems(m_hwndListViewHwProfiles);
m_iItemHwProfileEntry = -1; // No profile selected
GarbageInit(OUT &lvItem, sizeof(lvItem));
lvItem.iItem = 0;
pHPE = m_pData->m_paHardwareProfileEntryList;
while (pHPE != NULL)
{
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.lParam = (LPARAM)pHPE;
lvItem.iSubItem = 0;
lvItem.pszText = pHPE->m_hpi.HWPI_szFriendlyName;
iItem = ListView_InsertItem(m_hwndListViewHwProfiles, IN &lvItem);
Report(iItem >= 0);
lvItem.iItem = iItem;
lvItem.mask = LVIF_TEXT;
if (m_pData->m_fShowHwProfileInstances)
{
lvItem.iSubItem = 1;
lvItem.pszText = const_cast<LPTSTR>((LPCTSTR)pHPE->m_strDeviceNameFriendly);
VERIFY(ListView_SetItem(m_hwndListViewHwProfiles, IN &lvItem));
Report(iItem >= 0);
}
lvItem.iSubItem = m_pData->m_iSubItemHwProfileStatus;
lvItem.pszText = pHPE->m_fEnabled ? m_szHwProfileEnabled : m_szHwProfileDisabled;
VERIFY(ListView_SetItem(m_hwndListViewHwProfiles, IN &lvItem));
pHPE = pHPE->m_pNext;
} // while
// Select the first item
ListView_SetItemState(m_hwndListViewHwProfiles, 0, LVIS_SELECTED, LVIS_SELECTED);
} // BuildHwProfileList()
/////////////////////////////////////////////////////////////////////
// Toggle the current hardware profile item.
void CServicePageHwProfile::ToggleCurrentHwProfileItem()
{
if (m_iItemHwProfileEntry < 0)
return;
LV_ITEM lvItem;
GarbageInit(OUT &lvItem, sizeof(lvItem));
lvItem.mask = LVIF_PARAM;
lvItem.iItem = m_iItemHwProfileEntry;
lvItem.iSubItem = 0;
VERIFY(ListView_GetItem(m_hwndListViewHwProfiles, OUT &lvItem));
Assert(lvItem.lParam != NULL);
CHardwareProfileEntry * pHPE = (CHardwareProfileEntry *)lvItem.lParam;
if (pHPE != NULL && !pHPE->m_fReadOnly) // Just in case
{
pHPE->m_fEnabled = !pHPE->m_fEnabled;
lvItem.mask = LVIF_TEXT;
lvItem.iSubItem = m_pData->m_iSubItemHwProfileStatus;
lvItem.pszText = pHPE->m_fEnabled ? m_szHwProfileEnabled : m_szHwProfileDisabled;
VERIFY(ListView_SetItem(m_hwndListViewHwProfiles, IN &lvItem));
}
EnableHwProfileButtons();
} // ToggleCurrentHwProfileItem()
/////////////////////////////////////////////////////////////////////
// Enable/disable buttons according to current hardware profile item.
void CServicePageHwProfile::EnableHwProfileButtons()
{
BOOL fButtonEnable = FALSE;
BOOL fButtonDisable = FALSE;
if (m_iItemHwProfileEntry >= 0)
{
LV_ITEM lvItem;
GarbageInit(OUT &lvItem, sizeof(lvItem));
lvItem.mask = LVIF_PARAM;
lvItem.iItem = m_iItemHwProfileEntry;
lvItem.iSubItem = 0;
VERIFY(ListView_GetItem(m_hwndListViewHwProfiles, OUT &lvItem));
Assert(lvItem.lParam != NULL);
CHardwareProfileEntry * pHPE = (CHardwareProfileEntry *)lvItem.lParam;
if (pHPE != NULL && !pHPE->m_fReadOnly)
{
Assert(pHPE->m_fEnabled == TRUE || pHPE->m_fEnabled == FALSE);
fButtonEnable = !pHPE->m_fEnabled;
fButtonDisable = pHPE->m_fEnabled;
}
} // if
EnableDlgItem(m_hWnd, IDC_BUTTON_ENABLE, fButtonEnable);
EnableDlgItem(m_hWnd, IDC_BUTTON_DISABLE, fButtonDisable);
} // EnableHwProfileButtons()
void CServicePageHwProfile::OnItemChangedListHwProfiles(NMHDR* pNMHDR, LRESULT* pResult)
{
m_iItemHwProfileEntry = ((NM_LISTVIEW *)pNMHDR)->iItem;
EnableHwProfileButtons();
*pResult = 0;
}
void CServicePageHwProfile::OnDblclkListHwProfiles(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
ToggleCurrentHwProfileItem();
SetModified();
*pResult = 0;
}
void CServicePageHwProfile::OnButtonEnableHwProfile()
{
ToggleCurrentHwProfileItem();
SetModified();
::SetDlgItemFocus(m_hWnd, IDC_BUTTON_DISABLE);
}
void CServicePageHwProfile::OnButtonDisableHwProfile()
{
ToggleCurrentHwProfileItem();
SetModified();
::SetDlgItemFocus(m_hWnd, IDC_BUTTON_ENABLE);
}
void CServicePageHwProfile::OnButtonChooseUser()
{
Assert(m_pData != NULL);
PUSERDETAILS paUserDetails = NULL; // Pointer to allocated USERDETAILS buffer
LPCTSTR pszServerName = NULL;
BOOL fSuccess;
if (!m_pData->m_strMachineName.IsEmpty())
pszServerName = m_pData->m_strMachineName;
// Invoke the user picker dialog
CString str;
fSuccess = UiGetUser(m_hWnd, FALSE, pszServerName, IN OUT str);
if (fSuccess)
{
SetDlgItemText(IDC_EDIT_ACCOUNTNAME, str);
SetModified();
}
} // OnButtonChooseUser()
void CServicePageHwProfile::OnRadioLogonasSystemAccount()
{
CString strAccountName;
GetDlgItemText(IDC_EDIT_ACCOUNTNAME, OUT strAccountName);
TrimString(strAccountName);
if (!strAccountName.IsEmpty()) // JonN 4/11/00: 17756
SetModified();
SelectRadioButton(IDC_RADIO_LOGONAS_SYSTEMACCOUNT);
}
void CServicePageHwProfile::OnCheckServiceInteractWithDesktop()
{
m_pData->SetDirty(CServicePropertyData::mskfDirtySvcType);
SetModified();
}
void CServicePageHwProfile::OnRadioLogonasThisAccount()
{
SelectRadioButton(IDC_RADIO_LOGONAS_THIS_ACCOUNT);
}
void CServicePageHwProfile::OnChangeEditAccountName()
{
if (m_fAllowSetModified)
SetModified();
}
void CServicePageHwProfile::OnChangeEditPassword()
{
if (m_fAllowSetModified)
{
m_fPasswordDirty = TRUE;
SetModified();
}
}
void CServicePageHwProfile::OnChangeEditPasswordConfirm()
{
if (m_fAllowSetModified)
{
m_fPasswordDirty = TRUE;
SetModified();
}
}
BOOL CServicePageHwProfile::OnApply()
{
// Write the data into the service control database
if (!m_pData->FOnApply())
{
// Unable to write the information
return FALSE;
}
BOOL f = CPropertyPage::OnApply();
m_fAllowSetModified = FALSE;
UpdateData(FALSE);
BuildHwProfileList();
m_fAllowSetModified = TRUE;
return f;
}
BOOL CServicePageHwProfile::OnSetActive()
{
Assert(m_pData != NULL);
m_fAllowSetModified = FALSE;
BOOL f = CPropertyPage::OnSetActive();
m_idRadioButton = 0;
SelectRadioButton(m_fIsSystemAccount ? IDC_RADIO_LOGONAS_SYSTEMACCOUNT : IDC_RADIO_LOGONAS_THIS_ACCOUNT);
m_fAllowSetModified = TRUE;
m_fPasswordDirty = FALSE;
return f;
}
BOOL CServicePageHwProfile::OnHelp(WPARAM /*wParam*/, LPARAM lParam)
{
return DoHelp(lParam, HELP_DIALOG_TOPIC(IDD_PROPPAGE_SERVICE_HWPROFILE));
}
BOOL CServicePageHwProfile::OnContextHelp(WPARAM wParam, LPARAM /*lParam*/)
{
return DoContextHelp(wParam, HELP_DIALOG_TOPIC(IDD_PROPPAGE_SERVICE_HWPROFILE));
}