Windows-Server-2003/admin/netid/idpage.cpp

504 lines
12 KiB
C++

// Copyright (c) 1997-1999 Microsoft Corporation
//
// netid prop page
//
// 3-10-98 sburns
#include "headers.hxx"
#include "idpage.hpp"
#include "resource.h"
#include "helpids.h"
#include "iddlg.hpp"
#include "state.hpp"
static const DWORD HELP_MAP[] =
{
IDC_IDENTIFICATION_TEXT, NO_HELP,
IDC_DESCRIPTION_EDIT, IDH_COMPUTER_DESCRIPTION,
IDC_FULL_NAME, IDH_IDENT_FULL_NAME,
IDC_FULL_NAME_STATIC, IDH_IDENT_FULL_NAME,
IDC_DOMAIN, IDH_IDENT_MEMBER_OF,
IDC_ACCOUNT_WIZARD_BUTTON, IDH_IDENT_CHANGE_BUTTON,
IDC_CHANGE, IDH_IDENT_CHANGE_ADVANCED_BUTTON,
IDC_MEMBER_OF, IDH_IDENT_MEMBER_OF,
IDC_COMPUTER_ICON, NO_HELP,
IDC_MESSAGE, NO_HELP,
IDC_WARNING_ICON, NO_HELP,
IDC_CLICK_MESSAGE1, NO_HELP,
IDC_CLICK_MESSAGE2, NO_HELP,
IDC_REBOOT_MESSAGE, NO_HELP,
IDC_STATIC_HELPLESS, NO_HELP,
0, 0
};
NetIDPage::NetIDPage(bool isWorkstation, bool isPersonal)
:
PropertyPage(isWorkstation ? (isPersonal ? IDD_NETID_PER : IDD_NETID)
: IDD_NETID_SRV,
HELP_MAP),
certsvc(L"CertSvc"),
warnIcon(0),
fIsPersonal(isPersonal)
{
LOG_CTOR(NetIDPage);
}
NetIDPage::~NetIDPage()
{
LOG_DTOR(NetIDPage);
State::Delete();
if (warnIcon)
{
Win::DestroyIcon(warnIcon);
}
}
void
appendMessage(String& message, const String& additionalText)
{
LOG_FUNCTION2(appendMessage, message + L" " + additionalText);
ASSERT(!additionalText.empty());
if (message.empty())
{
// add intro first
message = String::load(IDS_CANT_TWEAK_ID);
}
// then bullet items next
message.append(L"\r\n" + additionalText);
}
// return false if the machine is undergoing a role change, or needs to
// be rebooted from a role change (i.e. dcpromo), true otherwise.
// If false, appends which condition to the provided string.
bool
EvaluateRoleChangeState(String& message)
{
LOG_FUNCTION(EvaluateRoleChangeState);
bool result = true;
switch (GetDsRoleChangeState())
{
case ::DsRoleOperationIdle:
{
// do nothing
break;
}
case ::DsRoleOperationActive:
{
// a role change operation is underway
result = false;
appendMessage(message, String::load(IDS_ROLE_CHANGE_IN_PROGRESS));
break;
}
case ::DsRoleOperationNeedReboot:
{
// a role change has already taken place, need to reboot before
// attempting another.
result = false;
appendMessage(message, String::load(IDS_ROLE_CHANGE_NEEDS_REBOOT));
break;
}
default:
{
ASSERT(false);
break;
}
}
return result;
}
// Returns true if the change and advanced buttons should be enabled, false if
// not. As an added bonus, also composes the text to appear on the page
// indicating why the buttons are not enabled, and whether the values reflect
// current machine names or a reboot is required. 289623
bool
NetIDPage::evaluateButtonEnablingAndComposeMessageText(String& message)
{
LOG_FUNCTION(NetIDPage::evaluateButtonEnablingAndComposeMessageText);
State& state = State::GetInstance();
bool result = true;
do
{
if (!IsCurrentUserAdministrator())
{
// must be an administrator
result = false;
message = String::load(IDS_MUST_BE_ADMIN);
// go no further -- more messages would reveal too much about this
// machine to a non-admin.
break;
}
// 236596: allow rename on DC's, now.
// // if (state.IsMachineDc())
// // {
// // // sorry- DCs can't be renamed
// // result = false;
// // appendMessage(message, String::load(IDS_CANT_RENAME_DC));
// // }
if (IsDcpromoRunning())
{
result = false;
appendMessage(message, String::load(IDS_MUST_EXIT_DCPROMO));
}
else
{
// this test is redundant if dcpromo is running, so only perform
// it when dcpromo is not running.
if (IsUpgradingDc())
{
// must complete dcpromo, first.
result = false;
appendMessage(message, String::load(IDS_MUST_COMPLETE_DCPROMO));
}
}
if (certsvc.IsInstalled())
{
// sorry- renaming cert issuers invalidates their certs.
result = false;
appendMessage(message, String::load(IDS_CANT_RENAME_CERT_SVC));
}
if (!state.IsNetworkingInstalled() && !state.IsMemberOfWorkgroup())
{
// domain members need to be able to reach a dc
result = false;
appendMessage(message, String::load(IDS_NETWORKING_NEEDED));
}
// 362770
if (!EvaluateRoleChangeState(message))
{
// dcpromo is running or was just run
result = false;
// the message has been updated for us by EvaluateRoleChangeState
}
}
while (0);
// show the message whether changes requiring a reboot have been made
// during this session or any other session (or even if the computer
// name has been changed by some other entity than ourselves)
bool show = (state.NeedsReboot() || state.ChangesMadeThisSession());
Win::ShowWindow(
Win::GetDlgItem(hwnd, IDC_REBOOT_MESSAGE),
show ? SW_SHOW : SW_HIDE);
Win::ShowWindow(
Win::GetDlgItem(hwnd, IDC_WARNING_ICON),
show ? SW_SHOW : SW_HIDE);
return result;
}
void
NetIDPage::refresh()
{
LOG_FUNCTION(NetIDPage::refresh);
State& state = State::GetInstance();
Win::SetDlgItemText(hwnd, IDC_FULL_NAME, state.GetFullComputerName());
Win::SetDlgItemText(hwnd, IDC_DOMAIN, state.GetDomainName());
Win::SetDlgItemText(
hwnd,
IDC_MEMBER_OF,
String::load(
state.IsMemberOfWorkgroup()
? IDS_MEMBER_OF_WORKGROUP
: IDS_MEMBER_OF_DOMAIN));
String message;
bool enableButtons =
evaluateButtonEnablingAndComposeMessageText(message);
bool networkingInstalled = state.IsNetworkingInstalled();
Win::EnableWindow(Win::GetDlgItem(hwnd, IDC_CHANGE), enableButtons);
Win::EnableWindow(
Win::GetDlgItem(hwnd, IDC_ACCOUNT_WIZARD_BUTTON),
enableButtons && networkingInstalled && !fIsPersonal );
Win::EnableWindow(
Win::GetDlgItem(hwnd, IDC_CLICK_MESSAGE1),
enableButtons && networkingInstalled && !fIsPersonal );
Win::EnableWindow(
Win::GetDlgItem(hwnd, IDC_CLICK_MESSAGE2),
enableButtons);
Win::SetDlgItemText(hwnd, IDC_MESSAGE, message);
if (!networkingInstalled)
{
// if networking is not installed, then domain join is not an option,
// so replace the button text to only mention rename. 371999
Win::SetWindowText(
Win::GetDlgItem(hwnd, IDC_CLICK_MESSAGE2),
String::load(IDS_RENAME_PROMPT));
}
}
void
NetIDPage::OnInit()
{
LOG_FUNCTION(NetIDPage::OnInit);
State::Init();
// JonN 10/24/00 Computer Description
// CODEWORK It would probably be cleaner to roll the
// computer description into ComputerState
SERVER_INFO_101* psi101 = NULL;
DWORD dwErr = ::NetServerGetInfo( NULL, 101, (LPBYTE*)&psi101 );
if (0 == dwErr && NULL != psi101)
{
if (NULL != psi101->sv101_comment)
{
Win::SetDlgItemText(hwnd,
IDC_DESCRIPTION_EDIT,
psi101->sv101_comment);
Win::PropSheet_Unchanged(Win::GetParent(hwnd), hwnd);
ClearChanges(); // clear IDC_DESCRIPTION_EDIT flag
}
(void) ::NetApiBufferFree( psi101 );
}
else
{
// If we failed to read the comment, disable this field
Win::EnableWindow(Win::GetDlgItem(hwnd, IDC_DESCRIPTION_EDIT), false);
}
// JonN 2/20/01 322286
Win::Edit_LimitText(
Win::GetDlgItem(hwnd, IDC_DESCRIPTION_EDIT),
MAXCOMMENTSZ);
refresh();
// destroyed in the dtor
HRESULT hr = Win::LoadImage(IDI_WARN, warnIcon);
if (SUCCEEDED(hr))
{
Win::SendMessage(
Win::GetDlgItem(hwnd, IDC_WARNING_ICON),
STM_SETICON,
reinterpret_cast<WPARAM>(warnIcon),
0);
}
}
bool
NetIDPage::OnSetActive()
{
LOG_FUNCTION(NetIDPage::OnSetActive);
refresh();
return true;
}
bool
NetIDPage::OnCommand(
HWND windowFrom,
unsigned controlIDFrom,
unsigned code)
{
switch (controlIDFrom)
{
case IDC_CHANGE:
{
if (code == BN_CLICKED)
{
// JonN 4/20/01
// Computer Name: warn users to "prepare" computer rename
// prior to DC computer rename
if (State::GetInstance().IsMachineDc())
{
if (
popup.MessageBox(
hwnd,
IDS_RENAME_DC_WARNING,
MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2) != IDOK)
{
break;
}
}
IDChangesDialog dlg(fIsPersonal);
dlg.ModalExecute(hwnd);
if (State::GetInstance().ChangesMadeThisSession())
{
Win::PropSheet_RebootSystem(Win::GetParent(hwnd));
}
State::Refresh();
refresh();
// JonN 4/24/01 280197
// wrong button has focus after joining or changing the Domain name
Win::SetFocus(Win::GetDlgItem(hwnd, IDC_CHANGE));
}
break;
}
case IDC_ACCOUNT_WIZARD_BUTTON:
{
if (code == BN_CLICKED)
{
HINSTANCE hNetWiz = LoadLibrary(c_szWizardFilename);
HRESULT (*pfnNetConnectWizard)(HWND, ULONG, BOOL *);
BOOL fReboot = FALSE;
if (hNetWiz) {
pfnNetConnectWizard = (HRESULT (*)(HWND, ULONG, BOOL *)) GetProcAddress(
hNetWiz,
"NetAccessWizard"
);
if (pfnNetConnectWizard) {
pfnNetConnectWizard(windowFrom, 0, &fReboot);
if (fReboot) {
popup.Info(hwnd, IDS_MUST_REBOOT);
State::GetInstance().SetChangesMadeThisSession(true);
Win::PropSheet_RebootSystem(Win::GetParent(hwnd));
} // if (fReboot)
State::Refresh();
refresh();
} // if (pfnNetConnectWizard)
FreeLibrary(hNetWiz);
} // if (hNetWiz)
}
break;
}
case IDC_DESCRIPTION_EDIT:
{
if (code == EN_CHANGE)
{
SetChanged(IDC_DESCRIPTION_EDIT);
Win::PropSheet_Changed(Win::GetParent(hwnd), hwnd);
}
break;
}
default:
{
break;
}
}
return true;
}
bool
NetIDPage::OnMessage(
UINT message,
WPARAM /* wparam */ ,
LPARAM /* lparam */ )
{
bool result = false;
switch (message)
{
case WM_ACTIVATE:
{
refresh();
result = true;
break;
}
default:
{
// do nothing
break;
}
}
return result;
}
bool
NetIDPage::OnApply(bool isClosing )
{
LOG_FUNCTION2(
NetIDPage::OnApply,
isClosing ? L"closing" : L"not closing");
// JonN 10/24/00 Computer Description
// CODEWORK It would probably be cleaner to roll the
// computer description into ComputerState
if (!WasChanged(IDC_DESCRIPTION_EDIT))
return true;
// If we got here, Win::PropSheet_Changed() must have been called
// in OnCommand().
String strDescription = Win::GetTrimmedDlgItemText(
hwnd, IDC_DESCRIPTION_EDIT);
SERVER_INFO_101 si101;
::ZeroMemory( &si101, sizeof(si101) );
si101.sv101_comment = (LMSTR)strDescription.c_str();
DWORD parmerror = 0;
DWORD dwErr = ::NetServerSetInfo(
NULL, 101, (LPBYTE)&si101, &parmerror );
if (0 != dwErr)
{
popup.Gripe(
hwnd,
IDC_DESCRIPTION_EDIT,
Win32ToHresult(dwErr),
String::format(IDS_CHANGE_DESCRIPTION_FAILED));
// don't dismiss the property page
Win::SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID);
return true;
}
else
{
Win::PropSheet_Unchanged(Win::GetParent(hwnd), hwnd);
ClearChanges(); // clear IDC_DESCRIPTION_EDIT flag
}
return true;
}