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.

531 lines
15 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: ExpressInstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a ExpressInstallationUnit
  6. // This object has the knowledge for installing the
  7. // services for the express path. AD, DNS, and DHCP
  8. //
  9. // History: 02/08/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "ExpressInstallationUnit.h"
  13. #include "InstallationUnitProvider.h"
  14. #include "smcyscom.h"
  15. // Define the GUIDs used by the Server Management Console COM object
  16. #include <initguid.h>
  17. DEFINE_GUID(CLSID_SMCys,0x9436DA1F,0x7F32,0x43ac,0xA4,0x8C,0xF6,0xF8,0x13,0x88,0x2B,0xE8);
  18. // Finish page help
  19. static PCWSTR CYS_EXPRESS_FINISH_PAGE_HELP = L"cys.chm::/typical_setup.htm";
  20. static PCWSTR CYS_EXPRESS_AFTER_FINISH_HELP = L"cys.chm::/typical_setup.htm#typicalcompletion";
  21. static PCWSTR CYS_TAPI_HELP = L"TAPIconcepts.chm::/sag_TAPIconcepts_150.htm";
  22. const String ExpressInstallationUnit::expressRoleResultStrings[] =
  23. {
  24. String(L"EXPRESS_SUCCESS"),
  25. String(L"EXPRESS_CANCELLED"),
  26. String(L"EXPRESS_RRAS_FAILURE"),
  27. String(L"EXPRESS_RRAS_CANCELLED"),
  28. String(L"EXPRESS_DNS_FAILURE"),
  29. String(L"EXPRESS_DHCP_INSTALL_FAILURE"),
  30. String(L"EXPRESS_DHCP_CONFIG_FAILURE"),
  31. String(L"EXPRESS_AD_FAILURE"),
  32. String(L"EXPRESS_DNS_SERVER_FAILURE"),
  33. String(L"EXPRESS_DNS_FORWARDER_FAILURE"),
  34. String(L"EXPRESS_DHCP_SCOPE_FAILURE"),
  35. String(L"EXPRESS_DHCP_ACTIVATION_FAILURE"),
  36. String(L"EXPRESS_TAPI_FAILURE")
  37. };
  38. ExpressInstallationUnit::ExpressInstallationUnit() :
  39. expressRoleResult(EXPRESS_SUCCESS),
  40. InstallationUnit(
  41. IDS_EXPRESS_PATH_TYPE,
  42. IDS_EXPRESS_PATH_DESCRIPTION,
  43. IDS_EXPRESS_FINISH_TITLE,
  44. 0,
  45. IDS_EXPRESS_FINISH_MESSAGE,
  46. 0,
  47. 0,
  48. 0,
  49. 0,
  50. 0,
  51. CYS_EXPRESS_FINISH_PAGE_HELP,
  52. CYS_EXPRESS_FINISH_PAGE_HELP,
  53. CYS_EXPRESS_AFTER_FINISH_HELP,
  54. EXPRESS_SERVER)
  55. {
  56. LOG_CTOR(ExpressInstallationUnit);
  57. }
  58. ExpressInstallationUnit::~ExpressInstallationUnit()
  59. {
  60. LOG_DTOR(ExpressInstallationUnit);
  61. }
  62. InstallationReturnType
  63. ExpressInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  64. {
  65. LOG_FUNCTION(ExpressInstallationUnit::InstallService);
  66. InstallationReturnType result = INSTALL_SUCCESS;
  67. do
  68. {
  69. // Log the First Server header
  70. CYS_APPEND_LOG(String::load(IDS_LOG_EXPRESS_HEADER));
  71. // Warn the user of a reboot during installation
  72. if (IDOK != Win::MessageBox(
  73. hwnd,
  74. String::load(IDS_CONFIRM_REBOOT),
  75. String::load(IDS_WIZARD_TITLE),
  76. MB_OKCANCEL))
  77. {
  78. CYS_APPEND_LOG(String::load(IDS_LOG_EXPRESS_CANCELLED));
  79. result = INSTALL_CANCELLED;
  80. SetExpressRoleResult(EXPRESS_CANCELLED);
  81. break;
  82. }
  83. // The order of the installation is extremely important.
  84. //
  85. // RRAS - must be installed first because they return the local NIC to us
  86. // which is used in the other installation units
  87. // DNS - must be second because it sets the static IP address on the local
  88. // NIC
  89. // DHCP - must be third because it has to be installed prior to running
  90. // DCPromo which reboots the machine
  91. // AD - must be last because it reboots the machine
  92. // Install RRAS
  93. result =
  94. InstallationUnitProvider::GetInstance().
  95. GetRRASInstallationUnit().InstallService(
  96. logfileHandle,
  97. hwnd);
  98. if (result != INSTALL_SUCCESS)
  99. {
  100. LOG(L"Failed to install routing and/or firewall");
  101. break;
  102. }
  103. // Install the server management console
  104. // REVIEW_JEFFJON : ignore the results for now
  105. InstallServerManagementConsole();
  106. // Call the DNS installation unit to set the static IP address and subnet mask
  107. result = InstallationUnitProvider::GetInstance().GetDNSInstallationUnit().InstallService(
  108. logfileHandle,
  109. hwnd);
  110. if (result != INSTALL_SUCCESS)
  111. {
  112. LOG(L"Failed to install static IP address and subnet mask");
  113. break;
  114. }
  115. // Install DHCP
  116. result = InstallationUnitProvider::GetInstance().GetDHCPInstallationUnit().InstallService(logfileHandle, hwnd);
  117. if (result != INSTALL_SUCCESS)
  118. {
  119. LOG(L"Failed to install DCHP");
  120. break;
  121. }
  122. result = InstallationUnitProvider::GetInstance().GetADInstallationUnit().InstallService(logfileHandle, hwnd);
  123. } while (false);
  124. LOG_INSTALL_RETURN(result);
  125. return result;
  126. }
  127. UnInstallReturnType
  128. ExpressInstallationUnit::UnInstallService(HANDLE /*logfileHandle*/, HWND /*hwnd*/)
  129. {
  130. LOG_FUNCTION(ExpressInstallationUnit::UnInstallService);
  131. UnInstallReturnType result = UNINSTALL_NO_CHANGES;
  132. // Shouldn't get here!
  133. ASSERT(false);
  134. LOG_UNINSTALL_RETURN(result);
  135. return result;
  136. }
  137. bool
  138. ExpressInstallationUnit::IsServiceInstalled()
  139. {
  140. LOG_FUNCTION(ExpressInstallationUnit:IsServiceInstalled);
  141. bool result = false;
  142. if (InstallationUnitProvider::GetInstance().
  143. GetDHCPInstallationUnit().IsServiceInstalled() ||
  144. InstallationUnitProvider::GetInstance().
  145. GetDNSInstallationUnit().IsServiceInstalled() ||
  146. InstallationUnitProvider::GetInstance().
  147. GetADInstallationUnit().IsServiceInstalled())
  148. {
  149. result = true;
  150. }
  151. LOG_BOOL(result);
  152. return result;
  153. }
  154. bool
  155. ExpressInstallationUnit::GetMilestoneText(String& message)
  156. {
  157. LOG_FUNCTION(ExpressInstallationUnit::GetMilestoneText);
  158. // ADInstallationUnit& adInstallationUnit =
  159. // InstallationUnitProvider::GetInstance().GetADInstallationUnit();
  160. DNSInstallationUnit& dnsInstallationUnit =
  161. InstallationUnitProvider::GetInstance().GetDNSInstallationUnit();
  162. // DHCPInstallationUnit& dhcpInstallationUnit =
  163. // InstallationUnitProvider::GetInstance().GetDHCPInstallationUnit();
  164. // Add the RRAS message if required
  165. if (InstallationUnitProvider::GetInstance().GetRRASInstallationUnit().ShouldRunRRASWizard())
  166. {
  167. message += String::load(IDS_EXPRESS_RRAS_FINISH_TEXT);
  168. }
  169. // Add "Install DHCP if required"
  170. message += String::load(IDS_EXPRESS_DHCP_TEXT);
  171. // Add "Install Active Directory and DNS"
  172. message += String::load(IDS_EXPRESS_FINISH_TEXT);
  173. // Add the create domain message
  174. message += String::format(
  175. String::load(IDS_EXPRESS_FINISH_DOMAIN_NAME),
  176. InstallationUnitProvider::GetInstance().GetADInstallationUnit().GetNewDomainDNSName().c_str());
  177. if (dnsInstallationUnit.IsManualForwarder())
  178. {
  179. IPAddressList forwardersList;
  180. dnsInstallationUnit.GetForwarders(forwardersList);
  181. if (!forwardersList.empty())
  182. {
  183. // There should only be one entry for manual forwarding
  184. DWORD forwarderInDisplayByteOrder = ConvertIPAddressOrder(forwardersList[0]);
  185. message += String::format(
  186. String::load(IDS_EXPRESS_FINISH_DNS_FORWARDERS),
  187. IPAddressToString(forwarderInDisplayByteOrder).c_str());
  188. }
  189. }
  190. LOG_BOOL(true);
  191. return true;
  192. }
  193. HRESULT
  194. ExpressInstallationUnit::DoTapiConfig(const String& dnsName)
  195. {
  196. LOG_FUNCTION2(
  197. ExpressInstallationUnit::DoTapiConfig,
  198. dnsName);
  199. // Comments below taken from old HTA CYS
  200. /*
  201. // The TAPICFG is a straight command line utility where all the required parameters can be at once supplied
  202. // in the command line arguments and there are no sub-menus to traverse. The /Directory switch takes the DNS
  203. // name of the NC to be created and the optional /Server switch takes the name of the domain controller on
  204. // which the NC is to be created. If the /server switch is not specified, then the command assumes it is
  205. // running on a DC and tries to create the NC locally.
  206. // NDNC (non-domain naming context) is a partition that is created on Active Directory and serves as a dynamic
  207. // directory, where its used for temporary storage (depending on TTL) of objects pre-defined in the AD schema.
  208. // Here in TAPI we use NDNC to store user and conference information dynamically on the server.
  209. */
  210. HRESULT hr = S_OK;
  211. String fullPath =
  212. FS::AppendPath(
  213. Win::GetSystemDirectory(),
  214. String::load(IDS_TAPI_CONFIG_EXE));
  215. String commandLine = String::format(IDS_TAPI_CONFIG_COMMAND_FORMAT, dnsName.c_str());
  216. DWORD exitCode = 0;
  217. hr = CreateAndWaitForProcess(
  218. fullPath,
  219. commandLine,
  220. exitCode,
  221. true);
  222. if (SUCCEEDED(hr) &&
  223. exitCode != 0)
  224. {
  225. LOG(String::format(L"Exit code = %1!x!", exitCode));
  226. hr = E_FAIL;
  227. }
  228. LOG(String::format(L"hr = %1!x!", hr));
  229. return hr;
  230. }
  231. void
  232. ExpressInstallationUnit::InstallServerManagementConsole()
  233. {
  234. LOG_FUNCTION(ExpressInstallationUnit::InstallServerManagementConsole);
  235. do
  236. {
  237. SmartInterface<ISMCys> smCYS;
  238. HRESULT hr = smCYS.AcquireViaCreateInstance(
  239. CLSID_SMCys,
  240. 0,
  241. CLSCTX_INPROC_SERVER);
  242. if (FAILED(hr))
  243. {
  244. LOG(String::format(
  245. L"Failed to create ISMCys COM object: hr = 0x%1!x!",
  246. hr));
  247. break;
  248. }
  249. String installLocation;
  250. DWORD productSKU = State::GetInstance().GetProductSKU();
  251. if (productSKU & CYS_SERVER)
  252. {
  253. installLocation = String::load(IDS_SERVER_CD);
  254. }
  255. else if (productSKU & CYS_ADVANCED_SERVER)
  256. {
  257. installLocation = String::load(IDS_ADVANCED_SERVER_CD);
  258. }
  259. else if (productSKU & CYS_DATACENTER_SERVER)
  260. {
  261. installLocation = String::load(IDS_DATACENTER_SERVER_CD);
  262. }
  263. else
  264. {
  265. installLocation = String::load(IDS_WINDOWS_CD);
  266. }
  267. hr = smCYS->Install( AutoBstr(installLocation.c_str()) );
  268. if (FAILED(hr))
  269. {
  270. LOG(String::format(
  271. L"Failed to install the Server Management Console: hr = 0x%1!x!",
  272. hr));
  273. break;
  274. }
  275. // Add the shortcut to the Start Menu
  276. String target =
  277. Win::GetSystemDirectory() + L"\\administration\\servmgmt.msc";
  278. hr =
  279. AddShortcutToAdminTools(
  280. target,
  281. IDS_SERVERMGMT_SHORTCUT_DESCRIPTION,
  282. IDS_SERVERMGMT_ADMIN_TOOLS_LINK);
  283. } while(false);
  284. }
  285. ExpressInstallationUnit::ExpressRoleResult
  286. ExpressInstallationUnit::GetExpressRoleResult()
  287. {
  288. LOG_FUNCTION(ExpressInstallationUnit::GetExpressRoleResult);
  289. LOG(expressRoleResultStrings[expressRoleResult]);
  290. return expressRoleResult;
  291. }
  292. String
  293. ExpressInstallationUnit::GetFinishText()
  294. {
  295. LOG_FUNCTION(ExpressInstallationUnit::GetFinishText);
  296. unsigned int messageID = IDS_EXPRESS_FINISH_MESSAGE;
  297. if (installing)
  298. {
  299. InstallationReturnType result = GetInstallResult();
  300. if (result != INSTALL_SUCCESS)
  301. {
  302. ExpressRoleResult roleResult = GetExpressRoleResult();
  303. if (roleResult == EXPRESS_RRAS_CANCELLED)
  304. {
  305. messageID = IDS_EXPRESS_FINISH_RRAS_CANCELLED;
  306. }
  307. else if (roleResult == EXPRESS_RRAS_FAILURE)
  308. {
  309. messageID = IDS_EXPRESS_FINISH_RRAS_FAILURE;
  310. }
  311. else if (roleResult == EXPRESS_DNS_FAILURE)
  312. {
  313. messageID = IDS_EXPRESS_FINISH_DNS_FAILURE;
  314. }
  315. else if (roleResult == EXPRESS_DHCP_INSTALL_FAILURE)
  316. {
  317. messageID = IDS_EXPRESS_FINISH_DHCP_INSTALL_FAILURE;
  318. }
  319. else if (roleResult == EXPRESS_DHCP_CONFIG_FAILURE)
  320. {
  321. messageID = IDS_EXPRESS_FINISH_DHCP_CONFIG_FAILURE;
  322. }
  323. else if (roleResult == EXPRESS_AD_FAILURE)
  324. {
  325. messageID = IDS_EXPRESS_FINISH_AD_FAILURE;
  326. }
  327. else if (roleResult == EXPRESS_DNS_SERVER_FAILURE)
  328. {
  329. messageID = IDS_EXPRESS_DNS_SERVER_FAILURE;
  330. }
  331. else if (roleResult == EXPRESS_DNS_FORWARDER_FAILURE)
  332. {
  333. messageID = IDS_EXPRESS_DNS_FORWARDER_FAILURE;
  334. }
  335. else if (roleResult == EXPRESS_DHCP_SCOPE_FAILURE)
  336. {
  337. messageID = IDS_EXPRESS_DHCP_SCOPE_FAILURE;
  338. }
  339. else if (roleResult == EXPRESS_DHCP_ACTIVATION_FAILURE)
  340. {
  341. messageID = IDS_EXPRESS_DHCP_ACTIVATION_FAILURE;
  342. }
  343. else if (roleResult == EXPRESS_TAPI_FAILURE)
  344. {
  345. messageID = IDS_EXPRESS_TAPI_FAILURE;
  346. }
  347. else if (roleResult == EXPRESS_CANCELLED)
  348. {
  349. messageID = IDS_EXPRESS_CANCELLED;
  350. }
  351. }
  352. }
  353. return String::load(messageID);
  354. }
  355. void
  356. ExpressInstallationUnit::FinishLinkSelected(int linkIndex, HWND /*hwnd*/)
  357. {
  358. LOG_FUNCTION2(
  359. ExpressInstallationUnit::FinishLinkSelected,
  360. String::format(
  361. L"linkIndex = %1!d!",
  362. linkIndex));
  363. // Currently we have only one link
  364. ASSERT(linkIndex == 0);
  365. ExpressRoleResult result = GetExpressRoleResult();
  366. if (result == EXPRESS_SUCCESS)
  367. {
  368. LOG("Showing after checklist");
  369. ShowHelp(CYS_EXPRESS_AFTER_FINISH_HELP);
  370. }
  371. else if (result == EXPRESS_CANCELLED)
  372. {
  373. // Nothing???
  374. }
  375. else if (result == EXPRESS_RRAS_FAILURE ||
  376. result == EXPRESS_RRAS_CANCELLED)
  377. {
  378. LOG("Launch the RRAS snapin");
  379. LaunchMMCConsole(L"rrasmgmt.msc");
  380. }
  381. else if (result == EXPRESS_DNS_FAILURE ||
  382. result == EXPRESS_DHCP_CONFIG_FAILURE ||
  383. result == EXPRESS_DHCP_SCOPE_FAILURE ||
  384. result == EXPRESS_DHCP_ACTIVATION_FAILURE)
  385. {
  386. LOG("Launch the DHCP snapin");
  387. LaunchMMCConsole(L"dhcpmgmt.msc");
  388. }
  389. else if (result == EXPRESS_DHCP_INSTALL_FAILURE)
  390. {
  391. LOG(L"Show DHCP configuration help");
  392. ShowHelp(CYS_DHCP_FINISH_PAGE_HELP);
  393. }
  394. else if (result == EXPRESS_AD_FAILURE)
  395. {
  396. LOG(L"Launch DCPROMO");
  397. HRESULT hr =
  398. MyCreateProcess(
  399. InstallationUnitProvider::GetInstance().
  400. GetADInstallationUnit().GetDCPromoPath(),
  401. String());
  402. ASSERT(SUCCEEDED(hr));
  403. }
  404. else if (result == EXPRESS_DNS_FORWARDER_FAILURE)
  405. {
  406. LOG(L"Launch DNS Manager");
  407. LaunchMMCConsole(L"dnsmgmt.msc");
  408. }
  409. else if (result == EXPRESS_TAPI_FAILURE)
  410. {
  411. LOG(L"Show TAPI help");
  412. ShowHelp(CYS_TAPI_HELP);
  413. }
  414. else
  415. {
  416. LOG("Showing after checklist");
  417. ShowHelp(CYS_EXPRESS_AFTER_FINISH_HELP);
  418. }
  419. }
  420. void
  421. ExpressInstallationUnit::SetExpressRoleResult(
  422. ExpressRoleResult roleResult)
  423. {
  424. LOG_FUNCTION(ExpressInstallationUnit::SetExpressRoleResult);
  425. expressRoleResult = roleResult;
  426. }