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.

535 lines
14 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: TerminalServerInstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a TerminalServerInstallationUnit
  6. // This object has the knowledge for installing the
  7. // Application services portions of Terminal Server
  8. //
  9. // History: 02/06/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "TerminalServerInstallationUnit.h"
  13. // Finish page help
  14. static PCWSTR CYS_TS_FINISH_PAGE_HELP = L"cys.chm::/terminal_server_role.htm";
  15. static PCWSTR CYS_TS_MILESTONE_HELP = L"cys.chm::/terminal_server_role.htm#termsrvsummary";
  16. static PCWSTR CYS_TS_AFTER_FINISH_HELP = L"cys.chm::/terminal_server_role.htm#termsrvcompletion";
  17. static PCWSTR CYS_TS_LICENSING_HELP = L"cys.chm::/terminal_server_role.htm#termsrvlicensing";
  18. TerminalServerInstallationUnit::TerminalServerInstallationUnit() :
  19. applicationMode(static_cast<DWORD>(-1)),
  20. installTS(true),
  21. InstallationUnit(
  22. IDS_TERMINAL_SERVER_TYPE,
  23. IDS_TERMINAL_SERVER_DESCRIPTION,
  24. IDS_TS_FINISH_TITLE,
  25. IDS_TS_FINISH_UNINSTALL_TITLE,
  26. IDS_TS_FINISH_MESSAGE,
  27. IDS_TS_INSTALL_FAILED,
  28. IDS_TS_UNINSTALL_MESSAGE,
  29. IDS_TS_UNINSTALL_FAILED,
  30. IDS_TS_UNINSTALL_WARNING,
  31. IDS_TS_UNINSTALL_CHECKBOX,
  32. CYS_TS_FINISH_PAGE_HELP,
  33. CYS_TS_MILESTONE_HELP,
  34. CYS_TS_AFTER_FINISH_HELP,
  35. TERMINALSERVER_SERVER)
  36. {
  37. LOG_CTOR(TerminalServerInstallationUnit);
  38. }
  39. TerminalServerInstallationUnit::~TerminalServerInstallationUnit()
  40. {
  41. LOG_DTOR(TerminalServerInstallationUnit);
  42. }
  43. InstallationReturnType
  44. TerminalServerInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  45. {
  46. LOG_FUNCTION(TerminalServerInstallationUnit::InstallService);
  47. InstallationReturnType result = INSTALL_SUCCESS_REBOOT;
  48. CYS_APPEND_LOG(String::load(IDS_LOG_TERMINAL_SERVER_CONFIGURE));
  49. UpdateInstallationProgressText(hwnd, IDS_TS_PROGRESS);
  50. if (installTS)
  51. {
  52. // OCManager will reboot so prompt the user now
  53. if (IDOK == Win::MessageBox(
  54. hwnd,
  55. String::load(IDS_CONFIRM_REBOOT),
  56. String::load(IDS_WIZARD_TITLE),
  57. MB_OKCANCEL))
  58. {
  59. // Setup TS using an unattend file
  60. String unattendFileText;
  61. String infFileText;
  62. unattendFileText += L"[Components]\n";
  63. unattendFileText += L"TerminalServer=ON";
  64. // IMPORTANT!!! The OCManager will reboot the machine
  65. // The log file and registry keys must be written before we launch
  66. // the OCManager or all will be lost
  67. String homeKeyValue = CYS_HOME_REGKEY_TERMINAL_SERVER_VALUE;
  68. State::GetInstance().SetHomeRegkey(homeKeyValue);
  69. // set the key so CYS has to run again
  70. bool regkeyResult = SetRegKeyValue(
  71. CYS_HOME_REGKEY,
  72. CYS_HOME_REGKEY_MUST_RUN,
  73. CYS_HOME_RUN_KEY_RUN_AGAIN,
  74. HKEY_LOCAL_MACHINE,
  75. true);
  76. ASSERT(regkeyResult);
  77. // NTRAID#NTBUG9-478515-2001/10/09-jeffjon
  78. // Now set the state of the rerun to false so that the wizard
  79. // doesn't run again until after the reboot
  80. // State::GetInstance().SetRerunWizard(false);
  81. // The OCManager will reboot after installation so we don't want the finish
  82. // page to show the log or help
  83. result = INSTALL_SUCCESS_REBOOT;
  84. bool ocmResult = InstallServiceWithOcManager(infFileText, unattendFileText);
  85. if (!ocmResult)
  86. {
  87. CYS_APPEND_LOG(String::load(IDS_LOG_TERMINAL_SERVER_SERVER_FAILED));
  88. result = INSTALL_FAILURE;
  89. // Reset the regkeys since the OCM didn't reboot the machine
  90. homeKeyValue = CYS_HOME_REGKEY_DEFAULT_VALUE;
  91. State::GetInstance().SetHomeRegkey(homeKeyValue);
  92. // set the key so CYS doesn't have to run again
  93. homeKeyValue = CYS_HOME_REGKEY_DEFAULT_VALUE;
  94. State::GetInstance().SetHomeRegkey(homeKeyValue);
  95. regkeyResult =
  96. SetRegKeyValue(
  97. CYS_HOME_REGKEY,
  98. CYS_HOME_REGKEY_MUST_RUN,
  99. CYS_HOME_RUN_KEY_DONT_RUN,
  100. HKEY_LOCAL_MACHINE,
  101. true);
  102. ASSERT(regkeyResult);
  103. }
  104. }
  105. else
  106. {
  107. // user aborted the installation
  108. CYS_APPEND_LOG(String::load(IDS_LOG_TERMINAL_SERVER_ABORTED));
  109. LOG(L"The installation was cancelled by the user when prompted for reboot.");
  110. result = INSTALL_CANCELLED;
  111. // Reset the regkeys since the OCM didn't reboot the machine
  112. String homeKeyValue = CYS_HOME_REGKEY_DEFAULT_VALUE;
  113. State::GetInstance().SetHomeRegkey(homeKeyValue);
  114. // set the key so CYS doesn't have to run again
  115. bool regkeyResult =
  116. SetRegKeyValue(
  117. CYS_HOME_REGKEY,
  118. CYS_HOME_REGKEY_MUST_RUN,
  119. CYS_HOME_RUN_KEY_DONT_RUN,
  120. HKEY_LOCAL_MACHINE,
  121. true);
  122. ASSERT(regkeyResult);
  123. }
  124. }
  125. LOG_INSTALL_RETURN(result);
  126. return result;
  127. }
  128. UnInstallReturnType
  129. TerminalServerInstallationUnit::UnInstallService(HANDLE logfileHandle, HWND hwnd)
  130. {
  131. LOG_FUNCTION(TerminalServerInstallationUnit::UnInstallService);
  132. UnInstallReturnType result = UNINSTALL_SUCCESS;
  133. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_TERMINAL_SERVER_CONFIGURE));
  134. UpdateInstallationProgressText(hwnd, IDS_TS_UNINSTALL_PROGRESS);
  135. // OCManager will reboot so prompt the user now
  136. if (IDOK == Win::MessageBox(
  137. hwnd,
  138. String::load(IDS_CONFIRM_REBOOT),
  139. String::load(IDS_WIZARD_TITLE),
  140. MB_OKCANCEL))
  141. {
  142. // IMPORTANT!!! The OCManager will reboot the machine
  143. // The log file and registry keys must be written before we launch
  144. // the OCManager or all will be lost
  145. String homeKeyValue = CYS_HOME_REGKEY_UNINSTALL_TERMINAL_SERVER_VALUE;
  146. State::GetInstance().SetHomeRegkey(homeKeyValue);
  147. // set the key so CYS has to run again
  148. bool regkeyResult = SetRegKeyValue(
  149. CYS_HOME_REGKEY,
  150. CYS_HOME_REGKEY_MUST_RUN,
  151. CYS_HOME_RUN_KEY_RUN_AGAIN,
  152. HKEY_LOCAL_MACHINE,
  153. true);
  154. ASSERT(regkeyResult);
  155. String unattendFileText;
  156. String infFileText;
  157. unattendFileText += L"[Components]\n";
  158. unattendFileText += L"TerminalServer=OFF";
  159. bool ocmResult = InstallServiceWithOcManager(infFileText, unattendFileText);
  160. if (ocmResult &&
  161. !IsServiceInstalled())
  162. {
  163. LOG(L"The terminal server uninstall succeeded");
  164. }
  165. else
  166. {
  167. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_TERMINAL_SERVER_ABORTED));
  168. LOG(L"The terminal server uninstall failed");
  169. result = UNINSTALL_FAILURE;
  170. // set the key so CYS has to doesn't run again
  171. homeKeyValue = CYS_HOME_REGKEY_DEFAULT_VALUE;
  172. State::GetInstance().SetHomeRegkey(homeKeyValue);
  173. regkeyResult =
  174. SetRegKeyValue(
  175. CYS_HOME_REGKEY,
  176. CYS_HOME_REGKEY_MUST_RUN,
  177. CYS_HOME_RUN_KEY_DONT_RUN,
  178. HKEY_LOCAL_MACHINE,
  179. true);
  180. ASSERT(regkeyResult);
  181. }
  182. }
  183. else
  184. {
  185. LOG(L"User chose cancel from the reboot warning dialog");
  186. CYS_APPEND_LOG(String::load(IDS_LOG_TS_UNINSTALL_CANCEL_REBOOT));
  187. result = UNINSTALL_CANCELLED;
  188. }
  189. LOG_UNINSTALL_RETURN(result);
  190. return result;
  191. }
  192. bool
  193. TerminalServerInstallationUnit::GetMilestoneText(String& message)
  194. {
  195. LOG_FUNCTION(TerminalServerInstallationUnit::GetMilestoneText);
  196. if (installTS)
  197. {
  198. message += String::load(IDS_TERMINAL_SERVER_FINISH_SERVER_TS);
  199. }
  200. LOG_BOOL(installTS);
  201. return installTS;
  202. }
  203. bool
  204. TerminalServerInstallationUnit::GetUninstallMilestoneText(String& message)
  205. {
  206. LOG_FUNCTION(TerminalServerInstallationUnit::GetUninstallMilestoneText);
  207. message = String::load(IDS_TS_UNINSTALL_TEXT);
  208. LOG_BOOL(true);
  209. return true;
  210. }
  211. String
  212. TerminalServerInstallationUnit::GetServiceDescription()
  213. {
  214. LOG_FUNCTION(TerminalServerInstallationUnit::GetServiceDescription);
  215. unsigned int resourceID = static_cast<unsigned int>(-1);
  216. if (IsServiceInstalled())
  217. {
  218. resourceID = IDS_TERMINAL_SERVER_DESCRIPTION_INSTALLED;
  219. }
  220. else
  221. {
  222. resourceID = descriptionID;
  223. }
  224. ASSERT(resourceID != static_cast<unsigned int>(-1));
  225. return String::load(resourceID);
  226. }
  227. String
  228. TerminalServerInstallationUnit::GetFinishText()
  229. {
  230. LOG_FUNCTION(TerminalServerInstallationUnit::GetFinishText);
  231. unsigned int messageID = IDS_TS_FINISH_MESSAGE;
  232. if (installing)
  233. {
  234. InstallationReturnType result = GetInstallResult();
  235. if (result == INSTALL_CANCELLED)
  236. {
  237. messageID = IDS_TS_FINISH_CANCELLED;
  238. }
  239. else if (result != INSTALL_SUCCESS &&
  240. result != INSTALL_SUCCESS_REBOOT &&
  241. result != INSTALL_SUCCESS_PROMPT_REBOOT)
  242. {
  243. messageID = finishInstallFailedMessageID;
  244. }
  245. else
  246. {
  247. messageID = IDS_TS_FINISH_MESSAGE;
  248. }
  249. }
  250. else
  251. {
  252. messageID = finishUninstallMessageID;
  253. UnInstallReturnType result = GetUnInstallResult();
  254. if (result == UNINSTALL_CANCELLED)
  255. {
  256. messageID = IDS_TS_UNINSTALL_FINISH_CANCELLED;
  257. }
  258. else if (result != UNINSTALL_SUCCESS &&
  259. result != UNINSTALL_SUCCESS_REBOOT &&
  260. result != UNINSTALL_SUCCESS_PROMPT_REBOOT)
  261. {
  262. messageID = finishUninstallFailedMessageID;
  263. }
  264. }
  265. return String::load(messageID);
  266. }
  267. DWORD
  268. TerminalServerInstallationUnit::GetApplicationMode()
  269. {
  270. LOG_FUNCTION(TerminalServerInstallationUnit::GetApplicationMode);
  271. DWORD result = static_cast<DWORD>(-1);
  272. if (applicationMode == static_cast<DWORD>(-1))
  273. {
  274. // Read the application mode from the registry
  275. bool keyResult = GetRegKeyValue(
  276. CYS_APPLICATION_MODE_REGKEY,
  277. CYS_APPLICATION_MODE_VALUE,
  278. result);
  279. if (keyResult)
  280. {
  281. applicationMode = result;
  282. }
  283. }
  284. result = applicationMode;
  285. LOG(String::format(L"Application mode = %1!d!", result));
  286. return result;
  287. }
  288. bool
  289. TerminalServerInstallationUnit::SetApplicationMode(DWORD mode) const
  290. {
  291. LOG_FUNCTION2(
  292. TerminalServerInstallationUnit::SetApplicationMode,
  293. String::format(L"%1!d!", mode));
  294. bool result = SetRegKeyValue(
  295. CYS_APPLICATION_MODE_REGKEY,
  296. CYS_APPLICATION_MODE_VALUE,
  297. mode);
  298. ASSERT(result);
  299. return result;
  300. }
  301. void
  302. TerminalServerInstallationUnit::SetInstallTS(bool install)
  303. {
  304. LOG_FUNCTION2(
  305. TerminalServerInstallationUnit::SetInstallTS,
  306. install ? L"true" : L"false");
  307. installTS = install;
  308. }
  309. bool
  310. TerminalServerInstallationUnit::IsRemoteDesktopEnabled() const
  311. {
  312. LOG_FUNCTION(TerminalServerInstallationUnit::IsRemoteDesktopEnabled);
  313. bool result = false;
  314. do
  315. {
  316. SmartInterface<ILocalMachine> localMachine;
  317. HRESULT hr = localMachine.AcquireViaCreateInstance(
  318. CLSID_ShellLocalMachine,
  319. 0,
  320. CLSCTX_INPROC_SERVER,
  321. IID_ILocalMachine);
  322. if (FAILED(hr))
  323. {
  324. LOG(String::format(
  325. L"CoCreate on ILocalMachine failed: hr = %1!x!",
  326. hr));
  327. break;
  328. }
  329. VARIANT_BOOL isEnabled = FALSE;
  330. hr = localMachine->get_isRemoteConnectionsEnabled(&isEnabled);
  331. if (FAILED(hr))
  332. {
  333. LOG(String::format(
  334. L"Failed on call to get_isRemoteConnectionsEnabled: hr = %1!x!",
  335. hr));
  336. }
  337. result = isEnabled != 0;
  338. } while(false);
  339. LOG_BOOL(result);
  340. return result;
  341. }
  342. HRESULT
  343. TerminalServerInstallationUnit::EnableRemoteDesktop()
  344. {
  345. LOG_FUNCTION(TerminalServerInstallationUnit::EnableRemoteDesktop);
  346. HRESULT hr = S_OK;
  347. do
  348. {
  349. SmartInterface<ILocalMachine> localMachine;
  350. hr = localMachine.AcquireViaCreateInstance(
  351. CLSID_ShellLocalMachine,
  352. 0,
  353. CLSCTX_INPROC_SERVER,
  354. IID_ILocalMachine);
  355. if (FAILED(hr))
  356. {
  357. LOG(String::format(
  358. L"CoCreate on ILocalMachine failed: hr = %1!x!",
  359. hr));
  360. break;
  361. }
  362. VARIANT_BOOL enable = true;
  363. hr = localMachine->put_isRemoteConnectionsEnabled(enable);
  364. if (FAILED(hr))
  365. {
  366. LOG(String::format(
  367. L"Failed on call to put_isRemoteConnectionsEnabled: hr = %1!x!",
  368. hr));
  369. }
  370. } while(false);
  371. LOG_HRESULT(hr);
  372. return hr;
  373. }
  374. void
  375. TerminalServerInstallationUnit::ServerRoleLinkSelected(int linkIndex, HWND /*hwnd*/)
  376. {
  377. LOG_FUNCTION2(
  378. TerminalServerInstallationUnit::ServerRoleLinkSelected,
  379. String::format(
  380. L"linkIndex = %1!d!",
  381. linkIndex));
  382. if (IsServiceInstalled())
  383. {
  384. ASSERT(linkIndex == 0);
  385. LaunchMYS();
  386. }
  387. else
  388. {
  389. ASSERT(linkIndex == 0);
  390. LOG(L"Showing configuration help");
  391. ShowHelp(CYS_TS_FINISH_PAGE_HELP);
  392. }
  393. }
  394. void
  395. TerminalServerInstallationUnit::FinishLinkSelected(int linkIndex, HWND /*hwnd*/)
  396. {
  397. LOG_FUNCTION2(
  398. TerminalServerInstallationUnit::FinishLinkSelected,
  399. String::format(
  400. L"linkIndex = %1!d!",
  401. linkIndex));
  402. if (installing)
  403. {
  404. if (linkIndex == 0)
  405. {
  406. if (IsServiceInstalled())
  407. {
  408. LOG("Showing TS licensing help");
  409. ShowHelp(CYS_TS_LICENSING_HELP);
  410. }
  411. }
  412. }
  413. }