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.

660 lines
18 KiB

  1. // Copyright (c) 1997-2001 Microsoft Corporation
  2. //
  3. // File: ApplicationInstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a ApplicationInstallationUnit
  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 "ApplicationInstallationUnit.h"
  13. #include "state.h"
  14. // Finish page help
  15. static PCWSTR CYS_TS_FINISH_PAGE_HELP = L"cys.chm::/cys_configuring_application_server.htm";
  16. ApplicationInstallationUnit::ApplicationInstallationUnit() :
  17. serverSize(static_cast<DWORD>(-1)),
  18. serverCache(static_cast<DWORD>(-1)),
  19. applicationMode(static_cast<DWORD>(-1)),
  20. installTS(false),
  21. InstallationUnit((State::GetInstance().GetProductSKU() & CYS_SERVER) ?
  22. IDS_APPLICATION_SERVER_TYPE_SRV : IDS_APPLICATION_SERVER_TYPE,
  23. IDS_APPLICATION_SERVER_DESCRIPTION,
  24. CYS_TS_FINISH_PAGE_HELP,
  25. APPLICATIONSERVER_INSTALL)
  26. {
  27. LOG_CTOR(ApplicationInstallationUnit);
  28. }
  29. ApplicationInstallationUnit::~ApplicationInstallationUnit()
  30. {
  31. LOG_DTOR(ApplicationInstallationUnit);
  32. }
  33. InstallationReturnType
  34. ApplicationInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  35. {
  36. LOG_FUNCTION(ApplicationInstallationUnit::InstallService);
  37. InstallationReturnType result = INSTALL_SUCCESS;
  38. bool optimize = false;
  39. bool install = false;
  40. CYS_APPEND_LOG(String::load(IDS_LOG_APP_CONFIGURE));
  41. if (State::GetInstance().GetProductSKU() & CYS_SERVER)
  42. {
  43. // Server SKU - service is installed if the optimizations for applications
  44. // have been turned on
  45. if (GetServerSize() == 3 &&
  46. GetServerCache() == 0)
  47. {
  48. // Server is already optimized - service is installed
  49. // do nothing
  50. optimize = false;
  51. install = false;
  52. }
  53. else
  54. {
  55. // Server has not been optimized - service is not considered installed
  56. optimize = true;
  57. install = false;
  58. }
  59. }
  60. else if (State::GetInstance().GetProductSKU() & (CYS_ADVANCED_SERVER | CYS_DATACENTER_SERVER))
  61. {
  62. // Datacenter or Advanced Server SKU - service is considered installed if the optimizations
  63. // have been turned on and the Terminal Server has been installed
  64. if (GetServerSize() == 3 &&
  65. GetServerCache() == 0 &&
  66. GetApplicationMode() == 1)
  67. {
  68. // Server is already optimized for applications - service is installed
  69. // do nothing
  70. optimize = false;
  71. install = false;
  72. }
  73. else if (GetServerSize() == 3 &&
  74. GetServerCache() == 0 &&
  75. GetApplicationMode() != 1)
  76. {
  77. // Server is already optimized for application but TS is not installed
  78. // - service not installed completely
  79. optimize = false;
  80. install = installTS;
  81. }
  82. else if ((GetServerSize() != 3 ||
  83. GetServerCache() != 0) &&
  84. GetApplicationMode() != 1)
  85. {
  86. // Server is not optimized for applications and TS is not installed
  87. // - service not installed
  88. optimize = true;
  89. install = installTS;
  90. }
  91. else if ((GetServerSize() != 3 ||
  92. GetServerCache() != 0) &&
  93. GetApplicationMode() == 1)
  94. {
  95. // Server is not optimized for applications but TS is installed
  96. // - service not installed completely
  97. optimize = true;
  98. install = false;
  99. }
  100. }
  101. else
  102. {
  103. // No other SKUs are supported
  104. optimize = false;
  105. install = false;
  106. }
  107. if (optimize)
  108. {
  109. // To optimize we set the server size and cache registry keys
  110. bool resultSize = true;
  111. bool resultCache = true;
  112. resultSize = SetServerSize(CYS_SERVER_SIZE_ON);
  113. resultCache = SetServerCache(CYS_SERVER_CACHE_ON);
  114. if (resultSize && resultCache)
  115. {
  116. CYS_APPEND_LOG(String::load(IDS_LOG_APP_OPTIMIZE_SUCCESS));
  117. LOG(L"The registry keys for TS optimizations were set successfully");
  118. if (install)
  119. {
  120. result = INSTALL_SUCCESS;
  121. }
  122. else
  123. {
  124. result = INSTALL_SUCCESS_PROMPT_REBOOT;
  125. // Set the regkeys for reboot
  126. bool regkeyResult =
  127. State::GetInstance().SetHomeRegkey(CYS_HOME_REGKEY_TERMINAL_SERVER_OPTIMIZED);
  128. ASSERT(regkeyResult);
  129. // set the key so CYS has to run again
  130. regkeyResult = SetRegKeyValue(
  131. CYS_HOME_REGKEY,
  132. CYS_HOME_REGKEY_MUST_RUN,
  133. CYS_HOME_RUN_KEY_RUN_AGAIN,
  134. HKEY_LOCAL_MACHINE,
  135. true);
  136. ASSERT(regkeyResult);
  137. }
  138. }
  139. else
  140. {
  141. CYS_APPEND_LOG(String::load(IDS_LOG_APP_OPTIMIZE_FAILED_WITH_ERROR));
  142. CYS_APPEND_LOG(String::load(IDS_LOG_APP_OPTIMIZE_FAILED));
  143. LOG(L"The registry keys for TS optimizations were not set");
  144. result = INSTALL_FAILURE;
  145. }
  146. }
  147. if (install)
  148. {
  149. // OCManager will reboot so prompt the user now
  150. if (IDOK == Win::MessageBox(
  151. hwnd,
  152. String::load(IDS_CONFIRM_REBOOT),
  153. String::load(IDS_WIZARD_TITLE),
  154. MB_OKCANCEL))
  155. {
  156. // Setup TS using an unattend file
  157. String unattendFileText;
  158. String infFileText;
  159. unattendFileText += L"[Components]\n";
  160. unattendFileText += L"TerminalServer=ON";
  161. // IMPORTANT!!! The OCManager will reboot the machine
  162. // The log file and registry keys must be written before we launch
  163. // the OCManager or all will be lost
  164. String homeKeyValue = CYS_HOME_REGKEY_TERMINAL_SERVER_VALUE;
  165. State::GetInstance().SetHomeRegkey(homeKeyValue);
  166. // set the key so CYS has to run again
  167. bool regkeyResult = SetRegKeyValue(
  168. CYS_HOME_REGKEY,
  169. CYS_HOME_REGKEY_MUST_RUN,
  170. CYS_HOME_RUN_KEY_RUN_AGAIN,
  171. HKEY_LOCAL_MACHINE,
  172. true);
  173. ASSERT(regkeyResult);
  174. // The OCManager will reboot after installation so we don't want the finish
  175. // page to show the log or help
  176. result = INSTALL_SUCCESS_REBOOT;
  177. bool ocmResult = InstallServiceWithOcManager(infFileText, unattendFileText);
  178. if (!ocmResult)
  179. {
  180. CYS_APPEND_LOG(String::load(IDS_LOG_APP_INSTALL_FAILED));
  181. result = INSTALL_FAILURE;
  182. }
  183. }
  184. else
  185. {
  186. // user aborted the installation
  187. CYS_APPEND_LOG(String::load(IDS_LOG_APP_ABORTED));
  188. LOG(L"The installation was cancelled by the user when prompted for reboot.");
  189. result = INSTALL_FAILURE;
  190. }
  191. }
  192. LOG_INSTALL_RETURN(result);
  193. return result;
  194. }
  195. bool
  196. ApplicationInstallationUnit::IsServiceInstalled()
  197. {
  198. LOG_FUNCTION(ApplicationInstallationUnit::IsServiceInstalled);
  199. bool result = false;
  200. if (State::GetInstance().GetProductSKU() & CYS_SERVER)
  201. {
  202. // Server SKU - service is installed if the optimizations for applications
  203. // have been turned on
  204. if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  205. GetServerCache() == CYS_SERVER_CACHE_ON)
  206. {
  207. // Server is already optimized - service is installed
  208. result = true;
  209. }
  210. else
  211. {
  212. // Server has not been optimized - service is not considered installed
  213. result = false;
  214. }
  215. }
  216. else if (State::GetInstance().GetProductSKU() & (CYS_ADVANCED_SERVER | CYS_DATACENTER_SERVER))
  217. {
  218. // Datacenter or Advanced Server SKU - service is considered installed if the optimizations
  219. // have been turned on and the Terminal Server has been installed
  220. if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  221. GetServerCache() == CYS_SERVER_CACHE_ON &&
  222. GetApplicationMode() == CYS_APPLICATION_MODE_ON)
  223. {
  224. // Server is already optimized for applications - service is installed
  225. result = true;
  226. }
  227. else if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  228. GetServerCache() == CYS_SERVER_CACHE_ON &&
  229. GetApplicationMode() != CYS_APPLICATION_MODE_ON)
  230. {
  231. // Server is already optimized for application but TS is not installed
  232. // - service not installed completely
  233. result = false;
  234. }
  235. else if ((GetServerSize() != CYS_SERVER_SIZE_ON ||
  236. GetServerCache() != CYS_SERVER_CACHE_ON) &&
  237. GetApplicationMode() != CYS_APPLICATION_MODE_ON)
  238. {
  239. // Server is not optimized for applications and TS is not installed
  240. // - service not installed
  241. result = false;
  242. }
  243. else if ((GetServerSize() != CYS_SERVER_SIZE_ON ||
  244. GetServerCache() != CYS_SERVER_CACHE_ON) &&
  245. GetApplicationMode() == CYS_APPLICATION_MODE_ON)
  246. {
  247. // Server is not optimized for applications but TS is installed
  248. // - service not installed completely
  249. result = false;
  250. }
  251. }
  252. else
  253. {
  254. // No other SKUs are supported
  255. result = false;
  256. }
  257. LOG_BOOL(result);
  258. return result;
  259. }
  260. bool
  261. ApplicationInstallationUnit::GetFinishText(String& message)
  262. {
  263. LOG_FUNCTION(ApplicationInstallationUnit::GetFinishText);
  264. bool optimize = false;
  265. bool install = false;
  266. if (State::GetInstance().GetProductSKU() & CYS_SERVER)
  267. {
  268. // Server SKU - service is installed if the optimizations for applications
  269. // have been turned on
  270. if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  271. GetServerCache() == CYS_SERVER_CACHE_ON)
  272. {
  273. // Server is already optimized - service is installed
  274. // do nothing
  275. optimize = false;
  276. install = false;
  277. }
  278. else
  279. {
  280. // Server has not been optimized - service is not considered installed
  281. optimize = true;
  282. install = false;
  283. }
  284. }
  285. else if (State::GetInstance().GetProductSKU() & (CYS_ADVANCED_SERVER | CYS_DATACENTER_SERVER))
  286. {
  287. // Datacenter or Advanced Server SKU - service is considered installed if the optimizations
  288. // have been turned on and the Terminal Server has been installed
  289. if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  290. GetServerCache() == CYS_SERVER_CACHE_ON &&
  291. GetApplicationMode() == CYS_APPLICATION_MODE_ON)
  292. {
  293. // Server is already optimized for applications - service is installed
  294. // do nothing
  295. optimize = false;
  296. install = false;
  297. }
  298. else if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  299. GetServerCache() == CYS_SERVER_CACHE_ON &&
  300. GetApplicationMode() != CYS_APPLICATION_MODE_ON)
  301. {
  302. // Server is already optimized for application but TS is not installed
  303. // - service not installed completely
  304. optimize = false;
  305. install = GetInstallTS();
  306. }
  307. else if ((GetServerSize() != CYS_SERVER_SIZE_ON ||
  308. GetServerCache() != CYS_SERVER_CACHE_ON) &&
  309. GetApplicationMode() != CYS_APPLICATION_MODE_ON)
  310. {
  311. // Server is not optimized for applications and TS is not installed
  312. // - service not installed
  313. optimize = true;
  314. install = GetInstallTS();
  315. }
  316. else if ((GetServerSize() != CYS_SERVER_SIZE_ON ||
  317. GetServerCache() != CYS_SERVER_CACHE_ON) &&
  318. GetApplicationMode() == CYS_APPLICATION_MODE_ON)
  319. {
  320. // Server is not optimized for applications but TS is installed
  321. // - service not installed completely
  322. optimize = true;
  323. install = false;
  324. }
  325. }
  326. else
  327. {
  328. // No other SKUs are supported
  329. optimize = false;
  330. install = false;
  331. }
  332. if (optimize)
  333. {
  334. message = String::load(IDS_APPLICATION_FINISH_TEXT);
  335. }
  336. if (install)
  337. {
  338. message += String::load(IDS_APPLICATION_FINISH_INSTALL_TS);
  339. }
  340. if (!optimize && !install)
  341. {
  342. message = String::load(IDS_FINISH_NO_CHANGES);
  343. }
  344. LOG_BOOL(optimize || install);
  345. return optimize || install;
  346. }
  347. String
  348. ApplicationInstallationUnit::GetServiceDescription()
  349. {
  350. LOG_FUNCTION(ApplicationInstallationUnit::GetServiceDescription);
  351. unsigned int resourceID = static_cast<unsigned int>(-1);
  352. if (State::GetInstance().GetProductSKU() & CYS_SERVER)
  353. {
  354. // Server SKU - service is installed if the optimizations for applications
  355. // have been turned on
  356. if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  357. GetServerCache() == CYS_SERVER_CACHE_ON)
  358. {
  359. // Server is already optimized - service is installed
  360. resourceID = IDS_APP_SERVER_DESCRIPTION_OPTIMIZED;
  361. }
  362. else
  363. {
  364. // Server has not been optimized - service is not considered installed
  365. resourceID = IDS_APP_SERVER_DESCRIPTION_NOT_OPTIMIZED;
  366. }
  367. }
  368. else if (State::GetInstance().GetProductSKU() & (CYS_ADVANCED_SERVER | CYS_DATACENTER_SERVER))
  369. {
  370. // Datacenter or Advanced Server SKU - service is considered installed if the optimizations
  371. // have been turned on and the Terminal Server has been installed
  372. if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  373. GetServerCache() == CYS_SERVER_CACHE_ON &&
  374. GetApplicationMode() == CYS_APPLICATION_MODE_ON)
  375. {
  376. // Server is already optimized for applications - service is installed
  377. resourceID = IDS_APP_ADVSERVER_DESCRIPTION_OPTIMIZED_INSTALLED;
  378. }
  379. else if (GetServerSize() == CYS_SERVER_SIZE_ON &&
  380. GetServerCache() == CYS_SERVER_CACHE_ON &&
  381. GetApplicationMode() != CYS_APPLICATION_MODE_ON)
  382. {
  383. // Server is already optimized for application but TS is not installed
  384. // - service not installed completely
  385. resourceID = IDS_APP_ADVSERVER_DESCRIPTION_OPTIMIZED_NOT_INSTALLED;
  386. }
  387. else if ((GetServerSize() != CYS_SERVER_SIZE_ON ||
  388. GetServerCache() != CYS_SERVER_CACHE_ON) &&
  389. GetApplicationMode() != CYS_APPLICATION_MODE_ON)
  390. {
  391. // Server is not optimized for applications and TS is not installed
  392. // - service not installed
  393. resourceID = IDS_APP_ADVSERVER_DESCRIPTION_NOT_OPTIMIZED_NOT_INSTALLED;
  394. }
  395. else if ((GetServerSize() != CYS_SERVER_SIZE_ON ||
  396. GetServerCache() != CYS_SERVER_CACHE_ON) &&
  397. GetApplicationMode() == CYS_APPLICATION_MODE_ON)
  398. {
  399. // Server is not optimized for applications but TS is installed
  400. // - service not installed completely
  401. resourceID = IDS_APP_ADVSERVER_DESCRIPTION_NOT_OPTIMIZED_INSTALLED;
  402. }
  403. }
  404. else
  405. {
  406. // No other SKUs are supported
  407. resourceID = descriptionID;
  408. }
  409. ASSERT(resourceID != static_cast<unsigned int>(-1));
  410. return String::load(resourceID);
  411. }
  412. DWORD
  413. ApplicationInstallationUnit::GetServerSize()
  414. {
  415. LOG_FUNCTION(ApplicationInstallationUnit::GetServerSize);
  416. DWORD result = static_cast<DWORD>(-1);
  417. if (serverSize == static_cast<DWORD>(-1))
  418. {
  419. // Read the server size from the registry
  420. bool keyResult = GetRegKeyValue(
  421. CYS_SERVER_SIZE_REGKEY,
  422. CYS_SERVER_SIZE_VALUE,
  423. result);
  424. ASSERT(keyResult);
  425. serverSize = result;
  426. }
  427. result = serverSize;
  428. LOG(String::format(L"Server size = %1!d!", result));
  429. return result;
  430. }
  431. DWORD
  432. ApplicationInstallationUnit::GetServerCache()
  433. {
  434. LOG_FUNCTION(ApplicationInstallationUnit::GetServerCache);
  435. DWORD result = static_cast<DWORD>(-1);
  436. if (serverCache == static_cast<DWORD>(-1))
  437. {
  438. // Read the server cache from the registry
  439. bool keyResult = GetRegKeyValue(
  440. CYS_SERVER_CACHE_REGKEY,
  441. CYS_SERVER_CACHE_VALUE,
  442. result);
  443. ASSERT(keyResult);
  444. if (keyResult)
  445. {
  446. serverCache = result;
  447. }
  448. }
  449. result = serverCache;
  450. LOG(String::format(L"Server cache = %1!d!", result));
  451. return result;
  452. }
  453. DWORD
  454. ApplicationInstallationUnit::GetApplicationMode()
  455. {
  456. LOG_FUNCTION(ApplicationInstallationUnit::GetApplicationMode);
  457. DWORD result = static_cast<DWORD>(-1);
  458. if (applicationMode == static_cast<DWORD>(-1))
  459. {
  460. // Read the application mode from the registry
  461. bool keyResult = GetRegKeyValue(
  462. CYS_APPLICATION_MODE_REGKEY,
  463. CYS_APPLICATION_MODE_VALUE,
  464. result);
  465. ASSERT(keyResult);
  466. if (keyResult)
  467. {
  468. applicationMode = result;
  469. }
  470. }
  471. result = applicationMode;
  472. LOG(String::format(L"Application mode = %1!d!", result));
  473. return result;
  474. }
  475. bool
  476. ApplicationInstallationUnit::SetServerSize(DWORD size) const
  477. {
  478. LOG_FUNCTION2(
  479. ApplicationInstallationUnit::SetServerSize,
  480. String::format(L"%1!d!", size));
  481. // Write the server size from the registry
  482. bool result = SetRegKeyValue(
  483. CYS_SERVER_SIZE_REGKEY,
  484. CYS_SERVER_SIZE_VALUE,
  485. size);
  486. ASSERT(result);
  487. return result;
  488. }
  489. bool
  490. ApplicationInstallationUnit::SetServerCache(DWORD cache) const
  491. {
  492. LOG_FUNCTION2(
  493. ApplicationInstallationUnit::SetServerCache,
  494. String::format(L"%1!d!", cache));
  495. // Write the server cache to the registry
  496. bool result = SetRegKeyValue(
  497. CYS_SERVER_CACHE_REGKEY,
  498. CYS_SERVER_CACHE_VALUE,
  499. cache);
  500. ASSERT(result);
  501. return result;
  502. }
  503. bool
  504. ApplicationInstallationUnit::SetApplicationMode(DWORD mode) const
  505. {
  506. LOG_FUNCTION2(
  507. ApplicationInstallationUnit::SetApplicationMode,
  508. String::format(L"%1!d!", mode));
  509. bool result = SetRegKeyValue(
  510. CYS_APPLICATION_MODE_REGKEY,
  511. CYS_APPLICATION_MODE_VALUE,
  512. mode);
  513. ASSERT(result);
  514. return result;
  515. }
  516. void
  517. ApplicationInstallationUnit::SetInstallTS(bool install)
  518. {
  519. LOG_FUNCTION2(
  520. ApplicationInstallationUnit::SetInstallTS,
  521. install ? L"true" : L"false");
  522. installTS = install;
  523. }