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.

503 lines
12 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. //
  3. // netid prop page
  4. //
  5. // 3-10-98 sburns
  6. #include "headers.hxx"
  7. #include "idpage.hpp"
  8. #include "resource.h"
  9. #include "helpids.h"
  10. #include "iddlg.hpp"
  11. #include "state.hpp"
  12. static const DWORD HELP_MAP[] =
  13. {
  14. IDC_IDENTIFICATION_TEXT, NO_HELP,
  15. IDC_DESCRIPTION_EDIT, IDH_COMPUTER_DESCRIPTION,
  16. IDC_FULL_NAME, IDH_IDENT_FULL_NAME,
  17. IDC_FULL_NAME_STATIC, IDH_IDENT_FULL_NAME,
  18. IDC_DOMAIN, IDH_IDENT_MEMBER_OF,
  19. IDC_ACCOUNT_WIZARD_BUTTON, IDH_IDENT_CHANGE_BUTTON,
  20. IDC_CHANGE, IDH_IDENT_CHANGE_ADVANCED_BUTTON,
  21. IDC_MEMBER_OF, IDH_IDENT_MEMBER_OF,
  22. IDC_COMPUTER_ICON, NO_HELP,
  23. IDC_MESSAGE, NO_HELP,
  24. IDC_WARNING_ICON, NO_HELP,
  25. IDC_CLICK_MESSAGE1, NO_HELP,
  26. IDC_CLICK_MESSAGE2, NO_HELP,
  27. IDC_REBOOT_MESSAGE, NO_HELP,
  28. IDC_STATIC_HELPLESS, NO_HELP,
  29. 0, 0
  30. };
  31. NetIDPage::NetIDPage(bool isWorkstation, bool isPersonal)
  32. :
  33. PropertyPage(isWorkstation ? (isPersonal ? IDD_NETID_PER : IDD_NETID)
  34. : IDD_NETID_SRV,
  35. HELP_MAP),
  36. certsvc(L"CertSvc"),
  37. warnIcon(0),
  38. fIsPersonal(isPersonal)
  39. {
  40. LOG_CTOR(NetIDPage);
  41. }
  42. NetIDPage::~NetIDPage()
  43. {
  44. LOG_DTOR(NetIDPage);
  45. State::Delete();
  46. if (warnIcon)
  47. {
  48. Win::DestroyIcon(warnIcon);
  49. }
  50. }
  51. void
  52. appendMessage(String& message, const String& additionalText)
  53. {
  54. LOG_FUNCTION2(appendMessage, message + L" " + additionalText);
  55. ASSERT(!additionalText.empty());
  56. if (message.empty())
  57. {
  58. // add intro first
  59. message = String::load(IDS_CANT_TWEAK_ID);
  60. }
  61. // then bullet items next
  62. message.append(L"\r\n" + additionalText);
  63. }
  64. // return false if the machine is undergoing a role change, or needs to
  65. // be rebooted from a role change (i.e. dcpromo), true otherwise.
  66. // If false, appends which condition to the provided string.
  67. bool
  68. EvaluateRoleChangeState(String& message)
  69. {
  70. LOG_FUNCTION(EvaluateRoleChangeState);
  71. bool result = true;
  72. switch (GetDsRoleChangeState())
  73. {
  74. case ::DsRoleOperationIdle:
  75. {
  76. // do nothing
  77. break;
  78. }
  79. case ::DsRoleOperationActive:
  80. {
  81. // a role change operation is underway
  82. result = false;
  83. appendMessage(message, String::load(IDS_ROLE_CHANGE_IN_PROGRESS));
  84. break;
  85. }
  86. case ::DsRoleOperationNeedReboot:
  87. {
  88. // a role change has already taken place, need to reboot before
  89. // attempting another.
  90. result = false;
  91. appendMessage(message, String::load(IDS_ROLE_CHANGE_NEEDS_REBOOT));
  92. break;
  93. }
  94. default:
  95. {
  96. ASSERT(false);
  97. break;
  98. }
  99. }
  100. return result;
  101. }
  102. // Returns true if the change and advanced buttons should be enabled, false if
  103. // not. As an added bonus, also composes the text to appear on the page
  104. // indicating why the buttons are not enabled, and whether the values reflect
  105. // current machine names or a reboot is required. 289623
  106. bool
  107. NetIDPage::evaluateButtonEnablingAndComposeMessageText(String& message)
  108. {
  109. LOG_FUNCTION(NetIDPage::evaluateButtonEnablingAndComposeMessageText);
  110. State& state = State::GetInstance();
  111. bool result = true;
  112. do
  113. {
  114. if (!IsCurrentUserAdministrator())
  115. {
  116. // must be an administrator
  117. result = false;
  118. message = String::load(IDS_MUST_BE_ADMIN);
  119. // go no further -- more messages would reveal too much about this
  120. // machine to a non-admin.
  121. break;
  122. }
  123. // 236596: allow rename on DC's, now.
  124. // // if (state.IsMachineDc())
  125. // // {
  126. // // // sorry- DCs can't be renamed
  127. // // result = false;
  128. // // appendMessage(message, String::load(IDS_CANT_RENAME_DC));
  129. // // }
  130. if (IsDcpromoRunning())
  131. {
  132. result = false;
  133. appendMessage(message, String::load(IDS_MUST_EXIT_DCPROMO));
  134. }
  135. else
  136. {
  137. // this test is redundant if dcpromo is running, so only perform
  138. // it when dcpromo is not running.
  139. if (IsUpgradingDc())
  140. {
  141. // must complete dcpromo, first.
  142. result = false;
  143. appendMessage(message, String::load(IDS_MUST_COMPLETE_DCPROMO));
  144. }
  145. }
  146. if (certsvc.IsInstalled())
  147. {
  148. // sorry- renaming cert issuers invalidates their certs.
  149. result = false;
  150. appendMessage(message, String::load(IDS_CANT_RENAME_CERT_SVC));
  151. }
  152. if (!state.IsNetworkingInstalled() && !state.IsMemberOfWorkgroup())
  153. {
  154. // domain members need to be able to reach a dc
  155. result = false;
  156. appendMessage(message, String::load(IDS_NETWORKING_NEEDED));
  157. }
  158. // 362770
  159. if (!EvaluateRoleChangeState(message))
  160. {
  161. // dcpromo is running or was just run
  162. result = false;
  163. // the message has been updated for us by EvaluateRoleChangeState
  164. }
  165. }
  166. while (0);
  167. // show the message whether changes requiring a reboot have been made
  168. // during this session or any other session (or even if the computer
  169. // name has been changed by some other entity than ourselves)
  170. bool show = (state.NeedsReboot() || state.ChangesMadeThisSession());
  171. Win::ShowWindow(
  172. Win::GetDlgItem(hwnd, IDC_REBOOT_MESSAGE),
  173. show ? SW_SHOW : SW_HIDE);
  174. Win::ShowWindow(
  175. Win::GetDlgItem(hwnd, IDC_WARNING_ICON),
  176. show ? SW_SHOW : SW_HIDE);
  177. return result;
  178. }
  179. void
  180. NetIDPage::refresh()
  181. {
  182. LOG_FUNCTION(NetIDPage::refresh);
  183. State& state = State::GetInstance();
  184. Win::SetDlgItemText(hwnd, IDC_FULL_NAME, state.GetFullComputerName());
  185. Win::SetDlgItemText(hwnd, IDC_DOMAIN, state.GetDomainName());
  186. Win::SetDlgItemText(
  187. hwnd,
  188. IDC_MEMBER_OF,
  189. String::load(
  190. state.IsMemberOfWorkgroup()
  191. ? IDS_MEMBER_OF_WORKGROUP
  192. : IDS_MEMBER_OF_DOMAIN));
  193. String message;
  194. bool enableButtons =
  195. evaluateButtonEnablingAndComposeMessageText(message);
  196. bool networkingInstalled = state.IsNetworkingInstalled();
  197. Win::EnableWindow(Win::GetDlgItem(hwnd, IDC_CHANGE), enableButtons);
  198. Win::EnableWindow(
  199. Win::GetDlgItem(hwnd, IDC_ACCOUNT_WIZARD_BUTTON),
  200. enableButtons && networkingInstalled && !fIsPersonal );
  201. Win::EnableWindow(
  202. Win::GetDlgItem(hwnd, IDC_CLICK_MESSAGE1),
  203. enableButtons && networkingInstalled && !fIsPersonal );
  204. Win::EnableWindow(
  205. Win::GetDlgItem(hwnd, IDC_CLICK_MESSAGE2),
  206. enableButtons);
  207. Win::SetDlgItemText(hwnd, IDC_MESSAGE, message);
  208. if (!networkingInstalled)
  209. {
  210. // if networking is not installed, then domain join is not an option,
  211. // so replace the button text to only mention rename. 371999
  212. Win::SetWindowText(
  213. Win::GetDlgItem(hwnd, IDC_CLICK_MESSAGE2),
  214. String::load(IDS_RENAME_PROMPT));
  215. }
  216. }
  217. void
  218. NetIDPage::OnInit()
  219. {
  220. LOG_FUNCTION(NetIDPage::OnInit);
  221. State::Init();
  222. // JonN 10/24/00 Computer Description
  223. // CODEWORK It would probably be cleaner to roll the
  224. // computer description into ComputerState
  225. SERVER_INFO_101* psi101 = NULL;
  226. DWORD dwErr = ::NetServerGetInfo( NULL, 101, (LPBYTE*)&psi101 );
  227. if (0 == dwErr && NULL != psi101)
  228. {
  229. if (NULL != psi101->sv101_comment)
  230. {
  231. Win::SetDlgItemText(hwnd,
  232. IDC_DESCRIPTION_EDIT,
  233. psi101->sv101_comment);
  234. Win::PropSheet_Unchanged(Win::GetParent(hwnd), hwnd);
  235. ClearChanges(); // clear IDC_DESCRIPTION_EDIT flag
  236. }
  237. (void) ::NetApiBufferFree( psi101 );
  238. }
  239. else
  240. {
  241. // If we failed to read the comment, disable this field
  242. Win::EnableWindow(Win::GetDlgItem(hwnd, IDC_DESCRIPTION_EDIT), false);
  243. }
  244. // JonN 2/20/01 322286
  245. Win::Edit_LimitText(
  246. Win::GetDlgItem(hwnd, IDC_DESCRIPTION_EDIT),
  247. MAXCOMMENTSZ);
  248. refresh();
  249. // destroyed in the dtor
  250. HRESULT hr = Win::LoadImage(IDI_WARN, warnIcon);
  251. if (SUCCEEDED(hr))
  252. {
  253. Win::SendMessage(
  254. Win::GetDlgItem(hwnd, IDC_WARNING_ICON),
  255. STM_SETICON,
  256. reinterpret_cast<WPARAM>(warnIcon),
  257. 0);
  258. }
  259. }
  260. bool
  261. NetIDPage::OnSetActive()
  262. {
  263. LOG_FUNCTION(NetIDPage::OnSetActive);
  264. refresh();
  265. return true;
  266. }
  267. bool
  268. NetIDPage::OnCommand(
  269. HWND windowFrom,
  270. unsigned controlIDFrom,
  271. unsigned code)
  272. {
  273. switch (controlIDFrom)
  274. {
  275. case IDC_CHANGE:
  276. {
  277. if (code == BN_CLICKED)
  278. {
  279. // JonN 4/20/01
  280. // Computer Name: warn users to "prepare" computer rename
  281. // prior to DC computer rename
  282. if (State::GetInstance().IsMachineDc())
  283. {
  284. if (
  285. popup.MessageBox(
  286. hwnd,
  287. IDS_RENAME_DC_WARNING,
  288. MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2) != IDOK)
  289. {
  290. break;
  291. }
  292. }
  293. IDChangesDialog dlg(fIsPersonal);
  294. dlg.ModalExecute(hwnd);
  295. if (State::GetInstance().ChangesMadeThisSession())
  296. {
  297. Win::PropSheet_RebootSystem(Win::GetParent(hwnd));
  298. }
  299. State::Refresh();
  300. refresh();
  301. // JonN 4/24/01 280197
  302. // wrong button has focus after joining or changing the Domain name
  303. Win::SetFocus(Win::GetDlgItem(hwnd, IDC_CHANGE));
  304. }
  305. break;
  306. }
  307. case IDC_ACCOUNT_WIZARD_BUTTON:
  308. {
  309. if (code == BN_CLICKED)
  310. {
  311. HINSTANCE hNetWiz = LoadLibrary(c_szWizardFilename);
  312. HRESULT (*pfnNetConnectWizard)(HWND, ULONG, BOOL *);
  313. BOOL fReboot = FALSE;
  314. if (hNetWiz) {
  315. pfnNetConnectWizard = (HRESULT (*)(HWND, ULONG, BOOL *)) GetProcAddress(
  316. hNetWiz,
  317. "NetAccessWizard"
  318. );
  319. if (pfnNetConnectWizard) {
  320. pfnNetConnectWizard(windowFrom, 0, &fReboot);
  321. if (fReboot) {
  322. popup.Info(hwnd, IDS_MUST_REBOOT);
  323. State::GetInstance().SetChangesMadeThisSession(true);
  324. Win::PropSheet_RebootSystem(Win::GetParent(hwnd));
  325. } // if (fReboot)
  326. State::Refresh();
  327. refresh();
  328. } // if (pfnNetConnectWizard)
  329. FreeLibrary(hNetWiz);
  330. } // if (hNetWiz)
  331. }
  332. break;
  333. }
  334. case IDC_DESCRIPTION_EDIT:
  335. {
  336. if (code == EN_CHANGE)
  337. {
  338. SetChanged(IDC_DESCRIPTION_EDIT);
  339. Win::PropSheet_Changed(Win::GetParent(hwnd), hwnd);
  340. }
  341. break;
  342. }
  343. default:
  344. {
  345. break;
  346. }
  347. }
  348. return true;
  349. }
  350. bool
  351. NetIDPage::OnMessage(
  352. UINT message,
  353. WPARAM /* wparam */ ,
  354. LPARAM /* lparam */ )
  355. {
  356. bool result = false;
  357. switch (message)
  358. {
  359. case WM_ACTIVATE:
  360. {
  361. refresh();
  362. result = true;
  363. break;
  364. }
  365. default:
  366. {
  367. // do nothing
  368. break;
  369. }
  370. }
  371. return result;
  372. }
  373. bool
  374. NetIDPage::OnApply(bool isClosing )
  375. {
  376. LOG_FUNCTION2(
  377. NetIDPage::OnApply,
  378. isClosing ? L"closing" : L"not closing");
  379. // JonN 10/24/00 Computer Description
  380. // CODEWORK It would probably be cleaner to roll the
  381. // computer description into ComputerState
  382. if (!WasChanged(IDC_DESCRIPTION_EDIT))
  383. return true;
  384. // If we got here, Win::PropSheet_Changed() must have been called
  385. // in OnCommand().
  386. String strDescription = Win::GetTrimmedDlgItemText(
  387. hwnd, IDC_DESCRIPTION_EDIT);
  388. SERVER_INFO_101 si101;
  389. ::ZeroMemory( &si101, sizeof(si101) );
  390. si101.sv101_comment = (LMSTR)strDescription.c_str();
  391. DWORD parmerror = 0;
  392. DWORD dwErr = ::NetServerSetInfo(
  393. NULL, 101, (LPBYTE)&si101, &parmerror );
  394. if (0 != dwErr)
  395. {
  396. popup.Gripe(
  397. hwnd,
  398. IDC_DESCRIPTION_EDIT,
  399. Win32ToHresult(dwErr),
  400. String::format(IDS_CHANGE_DESCRIPTION_FAILED));
  401. // don't dismiss the property page
  402. Win::SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID);
  403. return true;
  404. }
  405. else
  406. {
  407. Win::PropSheet_Unchanged(Win::GetParent(hwnd), hwnd);
  408. ClearChanges(); // clear IDC_DESCRIPTION_EDIT flag
  409. }
  410. return true;
  411. }