Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
6.0 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. //
  3. // demote page
  4. //
  5. // 1-20-98 sburns
  6. #include "headers.hxx"
  7. #include "page.hpp"
  8. #include "DemotePage.hpp"
  9. #include "resource.h"
  10. #include "state.hpp"
  11. #include "ds.hpp"
  12. #include "common.hpp"
  13. DemotePage::DemotePage()
  14. :
  15. DCPromoWizardPage(
  16. IDD_DEMOTE,
  17. IDS_DEMOTE_PAGE_TITLE,
  18. IDS_DEMOTE_PAGE_SUBTITLE),
  19. bulletFont(0),
  20. warnIcon(0)
  21. {
  22. LOG_CTOR(DemotePage);
  23. }
  24. DemotePage::~DemotePage()
  25. {
  26. LOG_DTOR(DemotePage);
  27. HRESULT hr = S_OK;
  28. if (warnIcon)
  29. {
  30. hr = Win::DestroyIcon(warnIcon);
  31. ASSERT(SUCCEEDED(hr));
  32. }
  33. if (bulletFont)
  34. {
  35. hr = Win::DeleteObject(bulletFont);
  36. ASSERT(SUCCEEDED(hr));
  37. }
  38. }
  39. void
  40. DemotePage::SetBulletFont()
  41. {
  42. LOG_FUNCTION(DemotePage::SetBulletFont);
  43. HRESULT hr = S_OK;
  44. do
  45. {
  46. NONCLIENTMETRICS ncm;
  47. memset(&ncm, 0, sizeof(ncm));
  48. ncm.cbSize = sizeof(ncm);
  49. hr = Win::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  50. BREAK_ON_FAILED_HRESULT(hr);
  51. LOGFONT logFont = ncm.lfMessageFont;
  52. logFont.lfWeight = FW_BOLD;
  53. String fontName = String::load(IDS_BULLET_FONT_NAME);
  54. // ensure null termination
  55. memset(logFont.lfFaceName, 0, LF_FACESIZE * sizeof(TCHAR));
  56. size_t fnLen = fontName.length();
  57. fontName.copy(
  58. logFont.lfFaceName,
  59. // don't copy over the last null
  60. min(LF_FACESIZE - 1, fnLen));
  61. hr = Win::CreateFontIndirect(logFont, bulletFont);
  62. BREAK_ON_FAILED_HRESULT(hr);
  63. SetControlFont(hwnd, IDC_BULLET1, bulletFont);
  64. SetControlFont(hwnd, IDC_BULLET2, bulletFont);
  65. }
  66. while (0);
  67. }
  68. void
  69. DemotePage::OnInit()
  70. {
  71. LOG_FUNCTION(DemotePage::OnInit);
  72. // 361172
  73. //
  74. // CODEWORK: the bullets aren't very impressive. I'm told an icon is
  75. // a better way to do this
  76. SetBulletFont();
  77. HRESULT hr = Win::LoadImage(IDI_WARN, warnIcon);
  78. ASSERT(SUCCEEDED(hr));
  79. if (SUCCEEDED(hr))
  80. {
  81. Win::SendMessage(
  82. Win::GetDlgItem(hwnd, IDC_WARNING_ICON),
  83. STM_SETICON,
  84. reinterpret_cast<WPARAM>(warnIcon),
  85. 0);
  86. }
  87. State& state = State::GetInstance();
  88. if (state.UsingAnswerFile())
  89. {
  90. String option =
  91. state.GetAnswerFileOption(State::OPTION_IS_LAST_DC);
  92. if (option.icompare(State::VALUE_YES) == 0)
  93. {
  94. Win::CheckDlgButton(hwnd, IDC_LAST, BST_CHECKED);
  95. return;
  96. }
  97. }
  98. else
  99. {
  100. // determine if this machine is a GC, if so pop up a warning message
  101. if (state.IsGlobalCatalog())
  102. {
  103. popup.Info(GetHWND(), IDS_DEMOTE_GC_WARNING);
  104. }
  105. }
  106. // you may ask yourself: "Why not set the state of the checkbox based
  107. // on the result of IsReallyLastDcInDomain?" Because demoting the
  108. // last DC deletes the domain, too. We want the user to be very
  109. // deliberate when checking that checkbox.
  110. }
  111. bool
  112. DemotePage::OnSetActive()
  113. {
  114. LOG_FUNCTION(DemotePage::OnSetActive);
  115. State& state = State::GetInstance();
  116. if (state.RunHiddenUnattended())
  117. {
  118. int nextPage = DemotePage::Validate();
  119. if (nextPage != -1)
  120. {
  121. GetWizard().SetNextPageID(hwnd, nextPage);
  122. }
  123. else
  124. {
  125. state.ClearHiddenWhileUnattended();
  126. }
  127. }
  128. Win::PropSheet_SetWizButtons(
  129. Win::GetParent(hwnd),
  130. PSWIZB_BACK | PSWIZB_NEXT);
  131. return true;
  132. }
  133. bool
  134. OtherDcFound(const String& domainName)
  135. {
  136. LOG_FUNCTION2(OtherDcFound, domainName);
  137. ASSERT(!domainName.empty());
  138. bool result = false;
  139. HRESULT hr = S_OK;
  140. do
  141. {
  142. DOMAIN_CONTROLLER_INFO* info = 0;
  143. hr =
  144. MyDsGetDcName(
  145. 0,
  146. domainName,
  147. DS_FORCE_REDISCOVERY
  148. | DS_AVOID_SELF
  149. | DS_DIRECTORY_SERVICE_REQUIRED,
  150. info);
  151. BREAK_ON_FAILED_HRESULT(hr);
  152. ASSERT(info->DomainControllerName);
  153. ::NetApiBufferFree(info);
  154. result = true;
  155. }
  156. while (0);
  157. LOG_HRESULT(hr);
  158. LOG(result ? L"true" : L"false");
  159. return result;
  160. }
  161. int
  162. DemotePage::Validate()
  163. {
  164. LOG_FUNCTION(DemotePage::Validate);
  165. State& state = State::GetInstance();
  166. ASSERT(state.GetOperation() == State::DEMOTE);
  167. bool isLast = Win::IsDlgButtonChecked(hwnd, IDC_LAST);
  168. if (isLast)
  169. {
  170. if (!state.IsReallyLastDcInDomain())
  171. {
  172. // user checked the box, but we found other dc objects in the DS.
  173. // verify that the user really meant to check the checkbox.
  174. if (
  175. popup.MessageBox(
  176. hwnd,
  177. String::format(
  178. IDS_VERIFY_LAST_DC,
  179. state.GetComputer().GetDomainDnsName().c_str()),
  180. MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) != IDYES)
  181. {
  182. state.SetIsLastDCInDomain(false);
  183. return -1;
  184. }
  185. }
  186. }
  187. else
  188. {
  189. // the user unchecked the box, check for other DCs for that domain
  190. Win::WaitCursor cursor;
  191. if (!OtherDcFound(state.GetComputer().GetDomainDnsName()))
  192. {
  193. if (
  194. popup.MessageBox(
  195. hwnd,
  196. String::format(
  197. IDS_VERIFY_NOT_LAST_DC,
  198. state.GetComputer().GetDomainDnsName().c_str()),
  199. MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) != IDYES)
  200. {
  201. // user clicked no or cancel
  202. state.SetIsLastDCInDomain(false);
  203. return -1;
  204. }
  205. // The user clicked "yes, proceed even if I lose changes"
  206. // CODEWORK: set flag to allow demote and abandon local changes
  207. // here...
  208. }
  209. }
  210. state.SetIsLastDCInDomain(isLast);
  211. // jump to credentials page if the user checked the "last dc in domain"
  212. // checkbox, unless this is last dc in forest root domain. 318736, 391440
  213. const Computer& computer = state.GetComputer();
  214. bool isForestRootDomain =
  215. (computer.GetDomainDnsName().icompare(computer.GetForestDnsName()) == 0);
  216. return
  217. isLast and !isForestRootDomain
  218. ? IDD_GET_CREDENTIALS
  219. : IDD_ADMIN_PASSWORD;
  220. }