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.

754 lines
18 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: WebInstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a WebInstallationUnit
  6. // This object has the knowledge for installing the
  7. // IIS service
  8. //
  9. // History: 02/06/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "WebInstallationUnit.h"
  13. #include "InstallationUnitProvider.h"
  14. // Finish page help
  15. static PCWSTR CYS_WEB_FINISH_PAGE_HELP = L"cys.chm::/web_server_role.htm";
  16. static PCWSTR CYS_WEB_MILESTONE_HELP = L"cys.chm::/web_server_role.htm#websrvsummary";
  17. static PCWSTR CYS_WEB_AFTER_FINISH_HELP = L"cys.chm::/web_server_role.htm#websrvcompletion";
  18. extern PCWSTR CYS_SAK_HOWTO = L"ntshowto.chm::/SAK_howto.htm";
  19. WebInstallationUnit::WebInstallationUnit() :
  20. optionalInstallComponents(0),
  21. webAppRoleResult(WEBAPP_SUCCESS),
  22. InstallationUnit(
  23. IDS_WEB_SERVER_TYPE,
  24. IDS_WEB_SERVER_DESCRIPTION,
  25. IDS_WEB_FINISH_TITLE,
  26. IDS_WEB_FINISH_UNINSTALL_TITLE,
  27. IDS_WEB_FINISH_MESSAGE,
  28. IDS_WEB_INSTALL_FAILED,
  29. IDS_WEB_UNINSTALL_MESSAGE,
  30. IDS_WEB_UNINSTALL_FAILED,
  31. IDS_WEB_UNINSTALL_WARNING,
  32. IDS_WEB_UNINSTALL_CHECKBOX,
  33. CYS_WEB_FINISH_PAGE_HELP,
  34. CYS_WEB_MILESTONE_HELP,
  35. CYS_WEB_AFTER_FINISH_HELP,
  36. WEBAPP_SERVER)
  37. {
  38. LOG_CTOR(WebInstallationUnit);
  39. }
  40. WebInstallationUnit::~WebInstallationUnit()
  41. {
  42. LOG_DTOR(WebInstallationUnit);
  43. }
  44. String
  45. WebInstallationUnit::GetServiceName()
  46. {
  47. LOG_FUNCTION(WebInstallationUnit::GetServiceName);
  48. if (name.empty())
  49. {
  50. if (State::GetInstance().Is64Bit())
  51. {
  52. name = String::load(IDS_WEB_SERVER_TYPE_64BIT);
  53. }
  54. else
  55. {
  56. name = String::load(IDS_WEB_SERVER_TYPE);
  57. }
  58. }
  59. return name;
  60. }
  61. InstallationReturnType
  62. WebInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  63. {
  64. LOG_FUNCTION(WebInstallationUnit::InstallService);
  65. InstallationReturnType result = INSTALL_SUCCESS;
  66. // Log heading
  67. // NTRAID#NTBUG9-487905-2001/11/05-JeffJon
  68. // Should only log the heading if this is the web server path
  69. // since this routine may be called for other paths
  70. InstallationUnit& currentInstallationUnit =
  71. InstallationUnitProvider::GetInstance().GetCurrentInstallationUnit();
  72. if (currentInstallationUnit.GetServerRole() == WEBAPP_SERVER)
  73. {
  74. CYS_APPEND_LOG(String::load(IDS_LOG_WEB_HEADING));
  75. }
  76. UpdateInstallationProgressText(hwnd, IDS_WEB_PROGRESS);
  77. // Only install IIS if it's not already installed.
  78. // NTRAID#NTBUG9-463509-2001/09/06-sburns
  79. if (!IsServiceInstalledHelper(CYS_WEB_SERVICE_NAME))
  80. {
  81. String unattendFileText;
  82. String infFileText;
  83. // NTRAID#NTBUG9-482422-2001/10/29-JeffJon
  84. // New unattend settings from IIS team (ShantT)
  85. unattendFileText += L"[Components]\n";
  86. unattendFileText += L"iis_common=ON\n";
  87. unattendFileText += L"iis_inetmgr=ON\n";
  88. unattendFileText += L"iis_www=ON\n";
  89. unattendFileText += L"appsrv_console=ON\n";
  90. unattendFileText += L"complusnetwork=ON\n";
  91. unattendFileText += L"dtcnetwork=ON\n";
  92. // Add the optional components for the Web application server
  93. DWORD optionalComponents = GetOptionalComponents();
  94. bool installingFrontPage = false;
  95. if (optionalComponents & FRONTPAGE_EXTENSIONS_COMPONENT)
  96. {
  97. LOG(L"Adding FrontPage Extensions to unattend");
  98. unattendFileText += CYS_WEBAPP_FPSE_COMPONENT L"=ON\n";
  99. installingFrontPage = true;
  100. }
  101. bool installingASPNET = false;
  102. if (optionalComponents & ASPNET_COMPONENT)
  103. {
  104. LOG(L"Adding ASP.NET to unattend");
  105. unattendFileText += CYS_WEBAPP_ASPNET_COMPONENT L"=ON\n";
  106. installingASPNET = true;
  107. }
  108. bool ocmResult = InstallServiceWithOcManager(infFileText, unattendFileText);
  109. if (ocmResult &&
  110. IsServiceInstalledHelper(CYS_WEB_SERVICE_NAME))
  111. {
  112. LOG(L"IIS was installed successfully");
  113. CYS_APPEND_LOG(String::load(IDS_LOG_SERVER_IIS_SUCCESS));
  114. if (installingFrontPage &&
  115. !AreFrontPageExtensionsInstalled())
  116. {
  117. webAppRoleResult |= WEBAPP_FRONTPAGE_FAILED;
  118. CYS_APPEND_LOG(String::load(IDS_LOG_WEBAPP_FRONTPAGE_FAILED));
  119. }
  120. if (installingASPNET &&
  121. !IsASPNETInstalled())
  122. {
  123. webAppRoleResult |= WEBAPP_ASPNET_FAILED;
  124. CYS_APPEND_LOG(String::load(IDS_LOG_WEBAPP_ASPNET_FAILED));
  125. }
  126. }
  127. else
  128. {
  129. LOG(L"IIS failed to install");
  130. CYS_APPEND_LOG(String::load(IDS_LOG_SERVER_IIS_FAILED));
  131. webAppRoleResult |= WEBAPP_IIS_FAILED;
  132. result = INSTALL_FAILURE;
  133. }
  134. }
  135. else
  136. {
  137. // IIS is already installed, the user must have gone thru the web path
  138. // and not checked the install web admin box.
  139. // NTRAID#NTBUG9-463508-2001/09/06-sburns
  140. LOG(L"IIS already installed");
  141. CYS_APPEND_LOG(String::load(IDS_LOG_IIS_ALREADY_SERVERED));
  142. }
  143. LOG_INSTALL_RETURN(result);
  144. return result;
  145. }
  146. UnInstallReturnType
  147. WebInstallationUnit::UnInstallService(HANDLE logfileHandle, HWND hwnd)
  148. {
  149. LOG_FUNCTION(WebInstallationUnit::UnInstallService);
  150. UnInstallReturnType result = UNINSTALL_SUCCESS;
  151. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_WEB_HEADING));
  152. if (State::GetInstance().Is64Bit())
  153. {
  154. UpdateInstallationProgressText(hwnd, IDS_WEB_UNINSTALL_PROGRESS_64BIT);
  155. }
  156. else
  157. {
  158. UpdateInstallationProgressText(hwnd, IDS_WEB_UNINSTALL_PROGRESS);
  159. }
  160. String unattendFileText;
  161. String infFileText;
  162. if (IsSMTPInstalled() ||
  163. IsFTPInstalled() ||
  164. IsNNTPInstalled())
  165. {
  166. // NTRAID#NTBUG9-528499-2002/02/04-JeffJon
  167. // Don't uninstall iis_common if POP3 is installed.
  168. // POP3 uses SMTP which is part of the iis_common
  169. // component
  170. unattendFileText += L"[Components]\n";
  171. unattendFileText += L"iis_www=OFF\n";
  172. }
  173. else
  174. {
  175. unattendFileText += L"[Components]\n";
  176. unattendFileText += L"iis_www=OFF\n";
  177. unattendFileText += L"iis_common=OFF\n";
  178. unattendFileText += L"iis_inetmgr=OFF\n";
  179. }
  180. // Always uninstall the console, COM+, DTC, and
  181. // the BITS ISAPI components
  182. unattendFileText += L"complusnetwork=OFF\n";
  183. unattendFileText += L"dtcnetwork=OFF\n";
  184. unattendFileText += L"appsrv_console=OFF\n";
  185. unattendFileText += L"BITSServerExtensionsISAPI=OFF\n";
  186. // Always uninstall FPSE, and ASP.NET
  187. unattendFileText += CYS_WEBAPP_FPSE_COMPONENT L"=OFF\n";
  188. unattendFileText += CYS_WEBAPP_ASPNET_COMPONENT L"=OFF\n";
  189. // NTRAID#NTBUG9-736557-2002/11/13-JeffJon
  190. // Pass the /w switch to sysocmgr when uninstalling
  191. // so that if a situation occurs in which a reboot
  192. // is required, the user will be prompted.
  193. String additionalArgs = L"/w";
  194. bool ocmResult =
  195. InstallServiceWithOcManager(
  196. infFileText,
  197. unattendFileText,
  198. additionalArgs);
  199. if (ocmResult &&
  200. !IsServiceInstalledHelper(CYS_WEB_SERVICE_NAME))
  201. {
  202. LOG(L"IIS was uninstalled successfully");
  203. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_IIS_SUCCESS));
  204. }
  205. else
  206. {
  207. LOG(L"IIS failed to uninstall");
  208. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_IIS_FAILED));
  209. result = UNINSTALL_FAILURE;
  210. }
  211. LOG_UNINSTALL_RETURN(result);
  212. return result;
  213. }
  214. InstallationReturnType
  215. WebInstallationUnit::CompletePath(
  216. HANDLE logfileHandle,
  217. HWND hwnd)
  218. {
  219. LOG_FUNCTION(WebInstallationUnit::CompletePath);
  220. InstallationReturnType result = InstallService(logfileHandle, hwnd);
  221. LOG_INSTALL_RETURN(result);
  222. return result;
  223. }
  224. bool
  225. WebInstallationUnit::GetMilestoneText(String& message)
  226. {
  227. LOG_FUNCTION(WebInstallationUnit::GetMilestoneText);
  228. if (!IsServiceInstalled())
  229. {
  230. message += String::load(IDS_WEB_FINISH_TEXT);
  231. // Add DTC if not already installed
  232. if (!IsDTCInstalled())
  233. {
  234. message += String::load(IDS_WEB_MILESTONE_DTC);
  235. }
  236. // Add the optional components for the Web application server
  237. DWORD optionalComponents = GetOptionalComponents();
  238. if (optionalComponents & FRONTPAGE_EXTENSIONS_COMPONENT)
  239. {
  240. message += String::load(IDS_WEB_MILESTONE_FRONTPAGE);
  241. }
  242. if (optionalComponents & ASPNET_COMPONENT)
  243. {
  244. message += String::load(IDS_WEB_MILESTONE_ASPNET);
  245. }
  246. }
  247. else
  248. {
  249. // NTRAID#NTBUG9-463508-2001/09/06-sburns
  250. message = String::load(IDS_CONFIGURE_WEB_SERVER);
  251. }
  252. LOG_BOOL(true);
  253. return true;
  254. }
  255. bool
  256. WebInstallationUnit::GetUninstallMilestoneText(String& message)
  257. {
  258. LOG_FUNCTION(WebInstallationUnit::GetUninstallMilestoneText);
  259. if (State::GetInstance().Is64Bit())
  260. {
  261. message = String::load(IDS_WEB_UNINSTALL_TEXT_64BIT);
  262. }
  263. else
  264. {
  265. message = String::load(IDS_WEB_UNINSTALL_TEXT);
  266. }
  267. LOG_BOOL(true);
  268. return true;
  269. }
  270. String
  271. WebInstallationUnit::GetServiceDescription()
  272. {
  273. LOG_FUNCTION(WebInstallationUnit::GetServiceDescription);
  274. unsigned int resourceID = static_cast<unsigned int>(-1);
  275. if (IsServiceInstalled())
  276. {
  277. resourceID = IDS_WEB_DESCRIPTION_INSTALLED;
  278. }
  279. else
  280. {
  281. if (State::GetInstance().Is64Bit())
  282. {
  283. resourceID = IDS_WEB_SERVER_DESCRIPTION_64BIT;
  284. }
  285. else
  286. {
  287. resourceID = IDS_WEB_SERVER_DESCRIPTION;
  288. }
  289. }
  290. ASSERT(resourceID != static_cast<unsigned int>(-1));
  291. String result = String::load(resourceID);
  292. LOG(result);
  293. return result;
  294. }
  295. int
  296. WebInstallationUnit::GetWizardStart()
  297. {
  298. LOG_FUNCTION(WebInstallationUnit::GetWizardStart);
  299. int result = IDD_WEBAPP_PAGE;
  300. bool installingRole = true;
  301. if (IsServiceInstalled())
  302. {
  303. installingRole = false;
  304. result = IDD_UNINSTALL_MILESTONE_PAGE;
  305. }
  306. else if (State::GetInstance().Is64Bit())
  307. {
  308. // ASP.NET is not available on
  309. // 64 bit so skip the optional components page
  310. result = IDD_MILESTONE_PAGE;
  311. }
  312. SetInstalling(installingRole);
  313. return result;
  314. }
  315. void
  316. WebInstallationUnit::ServerRoleLinkSelected(int linkIndex, HWND /*hwnd*/)
  317. {
  318. LOG_FUNCTION2(
  319. WebInstallationUnit::ServerRoleLinkSelected,
  320. String::format(
  321. L"linkIndex = %1!d!",
  322. linkIndex));
  323. if (IsServiceInstalled())
  324. {
  325. ASSERT(linkIndex == 0);
  326. LaunchMYS();
  327. }
  328. else
  329. {
  330. ASSERT(linkIndex == 0);
  331. LOG(L"Showing configuration help");
  332. ShowHelp(CYS_WEB_FINISH_PAGE_HELP);
  333. }
  334. }
  335. void
  336. WebInstallationUnit::FinishLinkSelected(int linkIndex, HWND /*hwnd*/)
  337. {
  338. LOG_FUNCTION2(
  339. WebInstallationUnit::FinishLinkSelected,
  340. String::format(
  341. L"linkIndex = %1!d!",
  342. linkIndex));
  343. if (installing)
  344. {
  345. if (IsServiceInstalled())
  346. {
  347. unsigned int roleResult = GetWebAppRoleResult();
  348. if (linkIndex == 0 &&
  349. (roleResult & WEBAPP_ASPNET_FAILED))
  350. {
  351. LOG(L"Launching Web Application Server console");
  352. String alternatePath =
  353. FS::AppendPath(
  354. Win::GetSystemDirectory(),
  355. L"inetsrv");
  356. LaunchMMCConsole(L"appsrv.msc", alternatePath);
  357. }
  358. else
  359. {
  360. LOG(L"Showing after checklist");
  361. ShowHelp(CYS_WEB_AFTER_FINISH_HELP);
  362. }
  363. }
  364. else
  365. {
  366. LOG(L"Showing configuration help");
  367. ShowHelp(CYS_WEB_FINISH_PAGE_HELP);
  368. }
  369. }
  370. }
  371. String
  372. WebInstallationUnit::GetFinishText()
  373. {
  374. LOG_FUNCTION(WebInstallationUnit::GetFinishText);
  375. String message = String::load(finishMessageID);
  376. if (installing)
  377. {
  378. InstallationReturnType result = GetInstallResult();
  379. if (result == INSTALL_SUCCESS ||
  380. result == INSTALL_SUCCESS_REBOOT ||
  381. result == INSTALL_SUCCESS_PROMPT_REBOOT)
  382. {
  383. unsigned int roleResult = GetWebAppRoleResult();
  384. if (roleResult == WEBAPP_IIS_FAILED)
  385. {
  386. // should never get here because
  387. // if IIS failed to install result should
  388. // be INSTALL_FAILURE
  389. ASSERT(false);
  390. message = String::load(finishMessageID);
  391. }
  392. else
  393. {
  394. // Load the initial text and then append all
  395. // optional component errors to it
  396. message = String::load(IDS_WEBAPP_FINISH_OPTIONAL_FAILURE_HEADER);
  397. if (roleResult & WEBAPP_FRONTPAGE_FAILED)
  398. {
  399. message += String::load(IDS_WEBAPP_FINISH_FRONTPAGE_FAILURE);
  400. }
  401. if (roleResult & WEBAPP_ASPNET_FAILED)
  402. {
  403. message += String::load(IDS_WEBAPP_FINISH_ASPNET_FAILURE);
  404. }
  405. // Now tack on the footer
  406. message += String::load(IDS_WEBAPP_FINISH_OPTIONAL_FAILURE_FOOTER);
  407. }
  408. }
  409. else
  410. {
  411. message = String::load(finishInstallFailedMessageID);
  412. }
  413. }
  414. else
  415. {
  416. message = String::load(finishUninstallMessageID);
  417. UnInstallReturnType result = GetUnInstallResult();
  418. if (result != UNINSTALL_SUCCESS &&
  419. result != UNINSTALL_SUCCESS_REBOOT &&
  420. result != UNINSTALL_SUCCESS_PROMPT_REBOOT)
  421. {
  422. message = String::load(finishUninstallFailedMessageID);
  423. }
  424. }
  425. return message;
  426. }
  427. String
  428. WebInstallationUnit::GetUninstallWarningText()
  429. {
  430. LOG_FUNCTION(WebInstallationUnit::GetUninstallWarningText);
  431. unsigned int messageID = uninstallMilestoneWarningID;
  432. bool webSAKInstalled = IsSAKUnitInstalled(WEB);
  433. bool nasSAKInstalled = IsSAKUnitInstalled(NAS);
  434. if (webSAKInstalled ||
  435. nasSAKInstalled)
  436. {
  437. messageID = IDS_WEB_UNINSTALL_WARNING_SAK;
  438. }
  439. else
  440. {
  441. messageID = IDS_WEB_UNINSTALL_WARNING;
  442. }
  443. return String::load(messageID);
  444. }
  445. void
  446. WebInstallationUnit::SetOptionalComponents(DWORD optionalComponents)
  447. {
  448. LOG_FUNCTION2(
  449. WebInstallationUnit::SetOptionalComponents,
  450. String::format(L"0x%1!x!", optionalComponents));
  451. optionalInstallComponents = optionalComponents;
  452. }
  453. DWORD
  454. WebInstallationUnit::GetOptionalComponents() const
  455. {
  456. LOG_FUNCTION(WebInstallationUnit::GetOptionalComponents);
  457. LOG(
  458. String::format(
  459. L"optionalInstallComponents = 0x%1!08X!",
  460. optionalInstallComponents));
  461. return optionalInstallComponents;
  462. }
  463. unsigned int
  464. WebInstallationUnit::GetWebAppRoleResult() const
  465. {
  466. LOG_FUNCTION(WebInstallationUnit::GetWebAppRoleResult);
  467. LOG(
  468. String::format(
  469. L"0x%1!x!",
  470. webAppRoleResult));
  471. return webAppRoleResult;
  472. }
  473. bool
  474. WebInstallationUnit::AreFrontPageExtensionsInstalled() const
  475. {
  476. LOG_FUNCTION(WebInstallationUnit::AreFrontPageExtensionsInstalled);
  477. bool result = false;
  478. DWORD value = 0;
  479. result =
  480. GetRegKeyValue(
  481. CYS_WEBAPP_OCM_COMPONENTS,
  482. CYS_WEBAPP_FPSE_COMPONENT,
  483. value);
  484. LOG(
  485. String::format(
  486. L"regkey value = 0x%1!x!",
  487. value));
  488. result = result && value;
  489. LOG_BOOL(result);
  490. return result;
  491. }
  492. bool
  493. WebInstallationUnit::IsASPNETInstalled() const
  494. {
  495. LOG_FUNCTION(WebInstallationUnit::IsASPNETInstalled);
  496. bool result = false;
  497. DWORD value = 0;
  498. result =
  499. GetRegKeyValue(
  500. CYS_WEBAPP_OCM_COMPONENTS,
  501. CYS_WEBAPP_ASPNET_COMPONENT,
  502. value);
  503. LOG(
  504. String::format(
  505. L"regkey value = 0x%1!x!",
  506. value));
  507. result = result && value;
  508. LOG_BOOL(result);
  509. return result;
  510. }
  511. bool
  512. WebInstallationUnit::IsDTCInstalled() const
  513. {
  514. LOG_FUNCTION(WebInstallationUnit::IsDTCInstalled);
  515. bool result = false;
  516. DWORD value = 0;
  517. result =
  518. GetRegKeyValue(
  519. CYS_WEBAPP_OCM_COMPONENTS,
  520. CYS_WEBAPP_DTC_COMPONENT,
  521. value);
  522. LOG(
  523. String::format(
  524. L"regkey value = 0x%1!x!",
  525. value));
  526. result = result && value;
  527. LOG_BOOL(result);
  528. return result;
  529. }
  530. bool
  531. WebInstallationUnit::IsFTPInstalled() const
  532. {
  533. LOG_FUNCTION(WebInstallationUnit::IsFTPInstalled);
  534. bool result = false;
  535. DWORD value = 0;
  536. result =
  537. GetRegKeyValue(
  538. CYS_WEBAPP_OCM_COMPONENTS,
  539. CYS_IIS_FTP_COMPONENT,
  540. value);
  541. LOG(
  542. String::format(
  543. L"regkey value = 0x%1!x!",
  544. value));
  545. result = result && value;
  546. LOG_BOOL(result);
  547. return result;
  548. }
  549. bool
  550. WebInstallationUnit::IsNNTPInstalled() const
  551. {
  552. LOG_FUNCTION(WebInstallationUnit::IsNNTPInstalled);
  553. bool result = false;
  554. DWORD value = 0;
  555. result =
  556. GetRegKeyValue(
  557. CYS_WEBAPP_OCM_COMPONENTS,
  558. CYS_IIS_NNTP_COMPONENT,
  559. value);
  560. LOG(
  561. String::format(
  562. L"regkey value = 0x%1!x!",
  563. value));
  564. result = result && value;
  565. LOG_BOOL(result);
  566. return result;
  567. }
  568. bool
  569. WebInstallationUnit::IsSMTPInstalled() const
  570. {
  571. LOG_FUNCTION(WebInstallationUnit::IsSMTPInstalled);
  572. bool result = false;
  573. DWORD value = 0;
  574. result =
  575. GetRegKeyValue(
  576. CYS_WEBAPP_OCM_COMPONENTS,
  577. CYS_IIS_SMTP_COMPONENT,
  578. value);
  579. LOG(
  580. String::format(
  581. L"regkey value = 0x%1!x!",
  582. value));
  583. result = result && value;
  584. LOG_BOOL(result);
  585. return result;
  586. }