Leaked source code of windows server 2003
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.

297 lines
6.2 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. {
  21. LOG_CTOR(DemotePage);
  22. }
  23. DemotePage::~DemotePage()
  24. {
  25. LOG_DTOR(DemotePage);
  26. HRESULT hr = S_OK;
  27. if (bulletFont)
  28. {
  29. hr = Win::DeleteObject(bulletFont);
  30. ASSERT(SUCCEEDED(hr));
  31. }
  32. }
  33. void
  34. DemotePage::SetBulletFont()
  35. {
  36. LOG_FUNCTION(DemotePage::SetBulletFont);
  37. HRESULT hr = S_OK;
  38. do
  39. {
  40. NONCLIENTMETRICS ncm;
  41. // REVIEWED-2002/02/25-sburns byte count correctly passed.
  42. ::ZeroMemory(&ncm, sizeof ncm);
  43. ncm.cbSize = sizeof ncm;
  44. // ISSUE-2002/02/27-sburns Seems to me that the second param here needs
  45. // to be sizeof ncm
  46. hr = Win::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  47. BREAK_ON_FAILED_HRESULT(hr);
  48. LOGFONT logFont = ncm.lfMessageFont;
  49. logFont.lfWeight = FW_BOLD;
  50. String fontName = String::load(IDS_BULLET_FONT_NAME);
  51. // ensure null termination
  52. // according to the docs for LOGFONT, the face size is limited to
  53. // 32 characters.
  54. ASSERT(LF_FACESIZE <= 32);
  55. // REVIEWED-2002/02/25-sburns byte count correctly passed.
  56. ::ZeroMemory(logFont.lfFaceName, LF_FACESIZE * sizeof WCHAR);
  57. size_t fnLen = fontName.length();
  58. // REVIEWED-2002/02/25-sburns character count correctly passed.
  59. fontName.copy(
  60. logFont.lfFaceName,
  61. // don't copy over the last null
  62. min(LF_FACESIZE - 1, fnLen));
  63. hr = Win::CreateFontIndirect(logFont, bulletFont);
  64. BREAK_ON_FAILED_HRESULT(hr);
  65. SetControlFont(hwnd, IDC_BULLET1, bulletFont);
  66. SetControlFont(hwnd, IDC_BULLET2, bulletFont);
  67. }
  68. while (0);
  69. }
  70. void
  71. DemotePage::OnInit()
  72. {
  73. LOG_FUNCTION(DemotePage::OnInit);
  74. // 361172
  75. //
  76. // CODEWORK: the bullets aren't very impressive. I'm told an icon is
  77. // a better way to do this
  78. SetBulletFont();
  79. State& state = State::GetInstance();
  80. if (state.UsingAnswerFile())
  81. {
  82. String option =
  83. state.GetAnswerFileOption(AnswerFile::OPTION_IS_LAST_DC);
  84. if (option.icompare(AnswerFile::VALUE_YES) == 0)
  85. {
  86. Win::CheckDlgButton(hwnd, IDC_LAST, BST_CHECKED);
  87. return;
  88. }
  89. }
  90. else
  91. {
  92. // determine if this machine is a GC, if so pop up a warning message
  93. if (state.IsGlobalCatalog())
  94. {
  95. popup.Info(GetHWND(), IDS_DEMOTE_GC_WARNING);
  96. }
  97. }
  98. // you may ask yourself: "Why not set the state of the checkbox based
  99. // on the result of IsReallyLastDcInDomain?" Because demoting the
  100. // last DC deletes the domain, too. We want the user to be very
  101. // deliberate when checking that checkbox.
  102. }
  103. bool
  104. DemotePage::OnSetActive()
  105. {
  106. LOG_FUNCTION(DemotePage::OnSetActive);
  107. State& state = State::GetInstance();
  108. if (state.RunHiddenUnattended())
  109. {
  110. int nextPage = DemotePage::Validate();
  111. if (nextPage != -1)
  112. {
  113. GetWizard().SetNextPageID(hwnd, nextPage);
  114. }
  115. else
  116. {
  117. state.ClearHiddenWhileUnattended();
  118. }
  119. }
  120. Win::PropSheet_SetWizButtons(
  121. Win::GetParent(hwnd),
  122. PSWIZB_BACK | PSWIZB_NEXT);
  123. return true;
  124. }
  125. bool
  126. OtherDcFound(const String& domainName)
  127. {
  128. LOG_FUNCTION2(OtherDcFound, domainName);
  129. ASSERT(!domainName.empty());
  130. bool result = false;
  131. HRESULT hr = S_OK;
  132. do
  133. {
  134. DOMAIN_CONTROLLER_INFO* info = 0;
  135. hr =
  136. MyDsGetDcName(
  137. 0,
  138. domainName,
  139. DS_FORCE_REDISCOVERY
  140. | DS_AVOID_SELF
  141. | DS_DIRECTORY_SERVICE_REQUIRED,
  142. info);
  143. BREAK_ON_FAILED_HRESULT(hr);
  144. ASSERT(info->DomainControllerName);
  145. ::NetApiBufferFree(info);
  146. result = true;
  147. }
  148. while (0);
  149. LOG_HRESULT(hr);
  150. LOG(result ? L"true" : L"false");
  151. return result;
  152. }
  153. int
  154. DemotePage::Validate()
  155. {
  156. LOG_FUNCTION(DemotePage::Validate);
  157. State& state = State::GetInstance();
  158. ASSERT(state.GetOperation() == State::DEMOTE);
  159. bool isLast = Win::IsDlgButtonChecked(hwnd, IDC_LAST);
  160. if (isLast)
  161. {
  162. if (!state.IsReallyLastDcInDomain())
  163. {
  164. // user checked the box, but we found other dc objects in the DS.
  165. // verify that the user really meant to check the checkbox.
  166. if (
  167. popup.MessageBox(
  168. hwnd,
  169. String::format(
  170. IDS_VERIFY_LAST_DC,
  171. state.GetComputer().GetDomainDnsName().c_str()),
  172. MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) != IDYES)
  173. {
  174. state.SetIsLastDCInDomain(false);
  175. return -1;
  176. }
  177. }
  178. }
  179. else
  180. {
  181. // the user unchecked the box, check for other DCs for that domain
  182. Win::WaitCursor cursor;
  183. if (!OtherDcFound(state.GetComputer().GetDomainDnsName()))
  184. {
  185. if (
  186. popup.MessageBox(
  187. hwnd,
  188. String::format(
  189. IDS_VERIFY_NOT_LAST_DC,
  190. state.GetComputer().GetDomainDnsName().c_str()),
  191. MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) != IDYES)
  192. {
  193. // user clicked no or cancel
  194. state.SetIsLastDCInDomain(false);
  195. return -1;
  196. }
  197. // The user clicked "yes, proceed even if I lose changes"
  198. // CODEWORK: set flag to allow demote and abandon local changes
  199. // here... (currently that's provided as the /forceremoval option,
  200. // which we're not currently thinking should be broadly advertised
  201. // yet.
  202. }
  203. }
  204. state.SetIsLastDCInDomain(isLast);
  205. return IDD_APP_PARTITION;
  206. }