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.

386 lines
9.5 KiB

  1. // Copyright (C) 1997 Microsoft Corporation
  2. //
  3. // new child page
  4. //
  5. // 12-22-97 sburns
  6. #include "headers.hxx"
  7. #include "page.hpp"
  8. #include "ChildPage.hpp"
  9. #include "resource.h"
  10. #include "dns.hpp"
  11. #include "common.hpp"
  12. #include "state.hpp"
  13. #include <ValidateDomainName.hpp>
  14. #include <ValidateDomainName.h>
  15. ChildPage::ChildPage()
  16. :
  17. DCPromoWizardPage(
  18. IDD_NEW_CHILD,
  19. IDS_CHILD_PAGE_TITLE,
  20. IDS_CHILD_PAGE_SUBTITLE),
  21. currentFocus(0)
  22. {
  23. LOG_CTOR(ChildPage);
  24. }
  25. ChildPage::~ChildPage()
  26. {
  27. LOG_DTOR(ChildPage);
  28. }
  29. void
  30. ChildPage::OnInit()
  31. {
  32. LOG_FUNCTION(ChildPage::OnInit);
  33. Win::Edit_LimitText(
  34. Win::GetDlgItem(hwnd, IDC_PARENT),
  35. DNS_DOMAIN_NAME_MAX_LIMIT_DUE_TO_POLICY);
  36. Win::Edit_LimitText(
  37. Win::GetDlgItem(hwnd, IDC_LEAF),
  38. Dns::MAX_LABEL_LENGTH);
  39. State& state = State::GetInstance();
  40. if (state.UsingAnswerFile())
  41. {
  42. Win::SetDlgItemText(
  43. hwnd,
  44. IDC_PARENT,
  45. state.GetAnswerFileOption(AnswerFile::OPTION_PARENT_DOMAIN_NAME));
  46. Win::SetDlgItemText(
  47. hwnd,
  48. IDC_LEAF,
  49. state.GetAnswerFileOption(AnswerFile::OPTION_CHILD_NAME));
  50. }
  51. else
  52. {
  53. // default domain is that to which the server is joined.
  54. Win::SetDlgItemText(
  55. hwnd,
  56. IDC_PARENT,
  57. state.GetComputer().GetDomainDnsName());
  58. // @@ if PDC_UPGRADE, set the pdc flat name as the leaf name here
  59. }
  60. }
  61. static
  62. void
  63. enable(HWND dialog)
  64. {
  65. ASSERT(Win::IsWindow(dialog));
  66. int next =
  67. ( !Win::GetTrimmedDlgItemText(dialog, IDC_PARENT).empty()
  68. && !Win::GetTrimmedDlgItemText(dialog, IDC_LEAF).empty() )
  69. ? PSWIZB_NEXT : 0;
  70. Win::PropSheet_SetWizButtons(
  71. Win::GetParent(dialog),
  72. PSWIZB_BACK | next);
  73. }
  74. bool
  75. ChildPage::OnCommand(
  76. HWND windowFrom,
  77. unsigned controlIDFrom,
  78. unsigned code)
  79. {
  80. // LOG_FUNCTION(ChildPage::OnCommand);
  81. switch (controlIDFrom)
  82. {
  83. case IDC_BROWSE:
  84. {
  85. if (code == BN_CLICKED)
  86. {
  87. String domain = BrowseForDomain(hwnd);
  88. if (!domain.empty())
  89. {
  90. Win::SetDlgItemText(hwnd, IDC_PARENT, domain);
  91. }
  92. // For some reason, the base dialog code (or perhaps the propsheet
  93. // code) will set the focus to the next button on the sheet (which
  94. // in this case is the Back button). That's s-tupid. The focus
  95. // should remain on whatever control had it previously.
  96. Win::PostMessage(
  97. Win::GetParent(hwnd),
  98. WM_NEXTDLGCTL,
  99. reinterpret_cast<WPARAM>(currentFocus),
  100. TRUE);
  101. return true;
  102. }
  103. else if (code == BN_SETFOCUS)
  104. {
  105. currentFocus = windowFrom;
  106. ASSERT(currentFocus == Win::GetDlgItem(hwnd, IDC_BROWSE));
  107. // sometimes the default style is stolem by the wizard navigation
  108. // buttons. Insist that if we're getting focus, we've also got the
  109. // default style. We have to use PostMessage here to that our
  110. // changes arrive after the message processing of the prop sheet
  111. // (essentially to steal the default style back again).
  112. Win::PostMessage(
  113. windowFrom,
  114. // we use this message instead of DM_SETDEFID, as this works
  115. // and DM_SETDEFID does not. See the sdk docs for a possible
  116. // reason why.
  117. BM_SETSTYLE,
  118. BS_DEFPUSHBUTTON,
  119. TRUE);
  120. // unfortunately, sometimes the prop sheet will set the default
  121. // style on one of the wizard navigation buttons. This brittle
  122. // hack will take care of that. I discovered the control IDs
  123. // by using spy++.
  124. // I'm not proud of this, but, hey, we've got a product to ship
  125. // and of course, every bug in comctl32 is by design.
  126. Win::PostMessage(
  127. Win::GetDlgItem(Win::GetParent(hwnd), Wizard::BACK_BTN_ID),
  128. BM_SETSTYLE,
  129. BS_PUSHBUTTON,
  130. TRUE);
  131. Win::PostMessage(
  132. Win::GetDlgItem(Win::GetParent(hwnd), Wizard::NEXT_BTN_ID),
  133. BM_SETSTYLE,
  134. BS_PUSHBUTTON,
  135. TRUE);
  136. }
  137. break;
  138. }
  139. case IDC_LEAF:
  140. case IDC_PARENT:
  141. {
  142. if (code == EN_CHANGE)
  143. {
  144. SetChanged(controlIDFrom);
  145. String parent = Win::GetTrimmedDlgItemText(hwnd, IDC_PARENT);
  146. String leaf = Win::GetTrimmedDlgItemText(hwnd, IDC_LEAF);
  147. String domain = leaf + L"." + parent;
  148. Win::SetDlgItemText(hwnd, IDC_DOMAIN, domain);
  149. enable(hwnd);
  150. return true;
  151. }
  152. else if (code == EN_SETFOCUS)
  153. {
  154. currentFocus = windowFrom;
  155. }
  156. break;
  157. }
  158. default:
  159. {
  160. // do nothing
  161. break;
  162. }
  163. }
  164. return false;
  165. }
  166. bool
  167. ChildPage::OnSetActive()
  168. {
  169. LOG_FUNCTION(ChildPage::OnSetActive);
  170. ASSERT(State::GetInstance().GetOperation() == State::CHILD);
  171. Win::PropSheet_SetWizButtons(
  172. Win::GetParent(hwnd),
  173. PSWIZB_BACK);
  174. State& state = State::GetInstance();
  175. if (state.RunHiddenUnattended())
  176. {
  177. int nextPage = ChildPage::Validate();
  178. if (nextPage != -1)
  179. {
  180. GetWizard().SetNextPageID(hwnd, nextPage);
  181. }
  182. else
  183. {
  184. state.ClearHiddenWhileUnattended();
  185. }
  186. }
  187. enable(hwnd);
  188. return true;
  189. }
  190. int
  191. ChildPage::Validate()
  192. {
  193. LOG_FUNCTION(ChildPage::Validate);
  194. String parent = Win::GetTrimmedDlgItemText(hwnd, IDC_PARENT);
  195. String leaf = Win::GetTrimmedDlgItemText(hwnd, IDC_LEAF);
  196. String domain = leaf + L"." + parent;
  197. State& state = State::GetInstance();
  198. int nextPage = -1;
  199. // SPB:251431 do validation even if this page is untouched, as upstream
  200. // pages may have been changed in such a fashion that re-validation is
  201. // required.
  202. // if (!WasChanged(IDC_PARENT) && !WasChanged(IDC_LEAF))
  203. // {
  204. // return nextPage;
  205. // }
  206. do
  207. {
  208. if (parent.empty())
  209. {
  210. popup.Gripe(hwnd, IDC_PARENT, IDS_MUST_ENTER_PARENT);
  211. break;
  212. }
  213. if (leaf.empty())
  214. {
  215. popup.Gripe(hwnd, IDC_LEAF, IDS_MUST_ENTER_LEAF);
  216. break;
  217. }
  218. bool parentIsNonRfc = false;
  219. if (
  220. !ValidateDomainDnsNameSyntax(
  221. hwnd,
  222. IDC_PARENT,
  223. popup,
  224. // only warn on non RFC names if running interactively
  225. !state.RunHiddenUnattended(),
  226. &parentIsNonRfc))
  227. {
  228. break;
  229. }
  230. if (
  231. !ValidateChildDomainLeafNameLabel(
  232. hwnd,
  233. IDC_LEAF,
  234. // only gripe if the parent is RFC and we're not hidden
  235. // NTRAID#NTBUG9-523532-2002/04/19-sburns
  236. !state.RunHiddenUnattended() && !parentIsNonRfc) )
  237. {
  238. break;
  239. }
  240. // now ensure that the parent domain exists
  241. String dnsName;
  242. if (!ValidateDomainExists(hwnd, IDC_PARENT, dnsName))
  243. {
  244. break;
  245. }
  246. if (!dnsName.empty())
  247. {
  248. // the user specified the netbios name of the domain, and
  249. // confirmed it, so use the dns domain name returned.
  250. parent = dnsName;
  251. domain = leaf + L"." + parent;
  252. Win::SetDlgItemText(hwnd, IDC_PARENT, dnsName);
  253. Win::SetDlgItemText(hwnd, IDC_DOMAIN, domain);
  254. }
  255. if (!state.IsDomainInForest(parent))
  256. {
  257. popup.Gripe(
  258. hwnd,
  259. IDC_DOMAIN,
  260. String::format(
  261. IDS_DOMAIN_NOT_IN_FOREST,
  262. parent.c_str(),
  263. state.GetUserForestName().c_str()));
  264. break;
  265. }
  266. if (domain.length() > DNS_DOMAIN_NAME_MAX_LIMIT_DUE_TO_POLICY)
  267. {
  268. String message =
  269. String::format(
  270. IDS_DNS_NAME_TOO_LONG,
  271. domain.c_str(),
  272. DNS_DOMAIN_NAME_MAX_LIMIT_DUE_TO_POLICY,
  273. DNS_DOMAIN_NAME_MAX_LIMIT_DUE_TO_POLICY_UTF8);
  274. popup.Gripe(hwnd, IDC_LEAF, message);
  275. break;
  276. }
  277. // validate the resulting child domain name, not warning on non-RFCness
  278. if (
  279. !ValidateDomainDnsNameSyntax(
  280. hwnd,
  281. domain,
  282. IDC_LEAF,
  283. popup,
  284. // only gripe if the parent is RFC and we're not hidden
  285. // NTRAID#NTBUG9-523532-2002/04/19-sburns
  286. !parentIsNonRfc && !state.RunHiddenUnattended()) )
  287. {
  288. break;
  289. }
  290. // now ensure that the child domain name does not exist
  291. if (!ValidateDomainDoesNotExist(hwnd, domain, IDC_LEAF))
  292. {
  293. break;
  294. }
  295. // valid
  296. ClearChanges();
  297. state.SetParentDomainDNSName(Win::GetTrimmedDlgItemText(hwnd, IDC_PARENT));
  298. state.SetNewDomainDNSName(domain);
  299. nextPage =
  300. state.GetRunContext() == State::PDC_UPGRADE
  301. ? IDD_PATHS
  302. : IDD_NETBIOS_NAME;
  303. }
  304. while (0);
  305. return nextPage;
  306. }