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.

595 lines
15 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: AdminPackInstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a AdminPackInstallationUnit
  6. // This object has the knowledge for installing
  7. // the Administration Tools Pack
  8. //
  9. // History: 06/01/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "InstallationUnitProvider.h"
  13. #include "state.h"
  14. // Define the GUIDs used by the Server Appliance Kit COM object
  15. #include <initguid.h>
  16. DEFINE_GUID(CLSID_SaInstall,0x142B8185,0x53AE,0x45B3,0x88,0x8F,0xC9,0x83,0x5B,0x15,0x6C,0xA9);
  17. DEFINE_GUID(IID_ISaInstall,0xF4DEDEF3,0x4D83,0x4516,0xBC,0x1E,0x10,0x3A,0x63,0xF5,0xF0,0x14);
  18. AdminPackInstallationUnit::AdminPackInstallationUnit() :
  19. installAdminPack(false),
  20. installWebAdmin(false),
  21. installNASAdmin(false),
  22. InstallationUnit(
  23. IDS_ADMIN_PACK_TYPE,
  24. IDS_ADMIN_PACK_DESCRIPTION,
  25. IDS_PROGRESS_SUBTITLE,
  26. IDS_FINISH_TITLE,
  27. IDS_FINISH_MESSAGE,
  28. L"",
  29. L"",
  30. ADMINPACK_SERVER)
  31. {
  32. LOG_CTOR(AdminPackInstallationUnit);
  33. }
  34. AdminPackInstallationUnit::~AdminPackInstallationUnit()
  35. {
  36. LOG_DTOR(AdminPackInstallationUnit);
  37. }
  38. InstallationReturnType
  39. AdminPackInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  40. {
  41. LOG_FUNCTION(AdminPackInstallationUnit::InstallService);
  42. InstallationReturnType result = INSTALL_SUCCESS;
  43. do
  44. {
  45. String computerName = State::GetInstance().GetComputerName();
  46. if (GetInstallNASAdmin())
  47. {
  48. // First check to see if IIS is installed and
  49. // install it if not
  50. WebInstallationUnit& webInstallationUnit =
  51. InstallationUnitProvider::GetInstance().GetWebInstallationUnit();
  52. if (!webInstallationUnit.IsServiceInstalled())
  53. {
  54. webInstallationUnit.InstallService(logfileHandle, hwnd);
  55. // Ignore the return value because the SAK installation
  56. // portion will actually provide the best error message
  57. }
  58. String logText;
  59. String errorMessage;
  60. result = InstallNASAdmin(errorMessage);
  61. if (result == INSTALL_FAILURE)
  62. {
  63. logText = String::format(
  64. IDS_NAS_ADMIN_LOG_FAILED,
  65. errorMessage.c_str());
  66. }
  67. else
  68. {
  69. if (errorMessage.empty())
  70. {
  71. logText = String::format(
  72. IDS_NAS_ADMIN_LOG_SUCCESS,
  73. computerName.c_str());
  74. }
  75. else
  76. {
  77. logText = String::format(
  78. IDS_NAS_ADMIN_LOG_SUCCESS_WITH_MESSAGE,
  79. errorMessage.c_str());
  80. }
  81. }
  82. CYS_APPEND_LOG(logText);
  83. }
  84. if (GetInstallWebAdmin())
  85. {
  86. // First check to see if IIS is installed and
  87. // install it if not
  88. WebInstallationUnit& webInstallationUnit =
  89. InstallationUnitProvider::GetInstance().GetWebInstallationUnit();
  90. if (!webInstallationUnit.IsServiceInstalled())
  91. {
  92. webInstallationUnit.InstallService(logfileHandle, hwnd);
  93. // Ignore the return value because the SAK installation
  94. // portion will actually provide the best error message
  95. }
  96. String logText;
  97. String errorMessage;
  98. result = InstallWebAdmin(errorMessage);
  99. if (result == INSTALL_FAILURE)
  100. {
  101. logText = String::format(
  102. IDS_WEB_ADMIN_LOG_FAILED,
  103. errorMessage.c_str());
  104. }
  105. else
  106. {
  107. logText = String::format(
  108. IDS_WEB_ADMIN_LOG_SUCCESS,
  109. computerName.c_str());
  110. }
  111. CYS_APPEND_LOG(logText);
  112. }
  113. if (GetInstallAdminPack())
  114. {
  115. InstallationReturnType adminPackResult = InstallAdminPack();
  116. if (adminPackResult == INSTALL_FAILURE)
  117. {
  118. CYS_APPEND_LOG(String::load(IDS_ADMIN_PACK_LOG_FAILED));
  119. result = adminPackResult;
  120. }
  121. else
  122. {
  123. CYS_APPEND_LOG(String::load(IDS_ADMIN_PACK_LOG_SUCCESS));
  124. }
  125. }
  126. } while (false);
  127. LOG_INSTALL_RETURN(result);
  128. return result;
  129. }
  130. InstallationReturnType
  131. AdminPackInstallationUnit::InstallSAKUnit(SA_TYPE unitType, String& errorMessage)
  132. {
  133. LOG_FUNCTION(AdminPackInstallationUnit::InstallSAKUnit);
  134. InstallationReturnType result = INSTALL_SUCCESS;
  135. errorMessage.erase();
  136. do
  137. {
  138. Win::WaitCursor wait;
  139. // Check to make sure we are not on 64bit
  140. if (State::GetInstance().Is64Bit())
  141. {
  142. ASSERT(!State::GetInstance().Is64Bit());
  143. result = INSTALL_FAILURE;
  144. break;
  145. }
  146. // Get the name of the source location of the install files
  147. String installLocation;
  148. DWORD productSKU = State::GetInstance().GetProductSKU();
  149. if (productSKU & CYS_SERVER)
  150. {
  151. installLocation = String::load(IDS_SERVER_CD);
  152. }
  153. else if (productSKU & CYS_ADVANCED_SERVER)
  154. {
  155. installLocation = String::load(IDS_ADVANCED_SERVER_CD);
  156. }
  157. else if (productSKU & CYS_DATACENTER_SERVER)
  158. {
  159. installLocation = String::load(IDS_DATACENTER_SERVER_CD);
  160. }
  161. else
  162. {
  163. installLocation = String::load(IDS_WINDOWS_CD);
  164. }
  165. // Get the Server Appliance COM object
  166. SmartInterface<ISaInstall> sakInstall;
  167. HRESULT hr = GetSAKObject(sakInstall);
  168. if (FAILED(hr))
  169. {
  170. // We failed the CoCreate on the SAK (Server Appliance Kit) COM object
  171. // Can't do anything without that!
  172. LOG(String::format(
  173. L"Failed to create the SAK (Server Appliance Kit) COM object: hr = 0x%1!x!",
  174. hr));
  175. result = INSTALL_FAILURE;
  176. break;
  177. }
  178. VARIANT_BOOL displayError = false;
  179. VARIANT_BOOL unattended = false;
  180. BSTR tempMessage = 0;
  181. hr = sakInstall->SAInstall(
  182. unitType,
  183. const_cast<WCHAR*>(installLocation.c_str()),
  184. displayError,
  185. unattended,
  186. &tempMessage);
  187. if (FAILED(hr))
  188. {
  189. LOG(String::format(
  190. L"Failed to install the SAK unit: hr = 0x%1!x!",
  191. hr));
  192. if (tempMessage)
  193. {
  194. errorMessage = tempMessage;
  195. ::SysFreeString(tempMessage);
  196. }
  197. result = INSTALL_FAILURE;
  198. break;
  199. }
  200. } while (false);
  201. LOG_INSTALL_RETURN(result);
  202. return result;
  203. }
  204. InstallationReturnType
  205. AdminPackInstallationUnit::InstallNASAdmin(String& errorMessage)
  206. {
  207. LOG_FUNCTION(AdminPackInstallationUnit::InstallNASAdmin);
  208. InstallationReturnType result = InstallSAKUnit(NAS, errorMessage);
  209. LOG_INSTALL_RETURN(result);
  210. return result;
  211. }
  212. InstallationReturnType
  213. AdminPackInstallationUnit::InstallWebAdmin(String& errorMessage)
  214. {
  215. LOG_FUNCTION(AdminPackInstallationUnit::InstallWebAdmin);
  216. InstallationReturnType result = InstallSAKUnit(WEB, errorMessage );
  217. LOG_INSTALL_RETURN(result);
  218. return result;
  219. }
  220. InstallationReturnType
  221. AdminPackInstallationUnit::InstallAdminPack()
  222. {
  223. LOG_FUNCTION(AdminPackInstallationUnit::InstallAdminPack);
  224. InstallationReturnType result = INSTALL_SUCCESS;
  225. do
  226. {
  227. Win::WaitCursor wait;
  228. // The Admin Tools Pack msi file is located in the %windir%\system32
  229. // directory on all x86 Server SKUs
  230. // The "/i" parameter means install, the "/qn" means quite mode/no UI
  231. String sysFolder = Win::GetSystemDirectory();
  232. String adminpakPath = sysFolder + L"\\msiexec.exe /i " + sysFolder + L"\\adminpak.msi /qn";
  233. DWORD exitCode = 0;
  234. HRESULT hr = CreateAndWaitForProcess(adminpakPath, exitCode, true);
  235. if (FAILED(hr))
  236. {
  237. LOG(String::format(
  238. L"Failed to launch Admin Pack install: hr = 0x%1!x!",
  239. hr));
  240. result = INSTALL_FAILURE;
  241. break;
  242. }
  243. if (exitCode != 0)
  244. {
  245. LOG(String::format(
  246. L"Failed to install Admin Tools Pack: exitCode = 0x%1!x!",
  247. exitCode));
  248. result = INSTALL_FAILURE;
  249. break;
  250. }
  251. LOG(String::format(
  252. L"Admin Pack returned with exitCode = 0x%1!x!",
  253. exitCode));
  254. } while (false);
  255. LOG_INSTALL_RETURN(result);
  256. return result;
  257. }
  258. bool
  259. AdminPackInstallationUnit::IsServiceInstalled()
  260. {
  261. LOG_FUNCTION(AdminPackInstallationUnit::IsServiceInstalled);
  262. bool result = false;
  263. // This should never be called...
  264. // The caller should be checking each individual
  265. // tools package instead. For instance, GetAdminPackInstall(),
  266. // GetNASAdminInstall(), or GetWebAdminInstall()
  267. ASSERT(false);
  268. LOG_BOOL(result);
  269. return result;
  270. }
  271. String
  272. AdminPackInstallationUnit::GetServiceDescription()
  273. {
  274. LOG_FUNCTION(AdminPackInstallationUnit::GetServiceDescription);
  275. // this should never be called. AdminPack isn't a
  276. // server role
  277. ASSERT(false);
  278. return L"";
  279. }
  280. bool
  281. AdminPackInstallationUnit::GetMilestoneText(String& message)
  282. {
  283. LOG_FUNCTION(AdminPackInstallationUnit::GetMilestoneText);
  284. bool result = false;
  285. if (GetInstallWebAdmin())
  286. {
  287. message += String::load(IDS_WEB_ADMIN_FINISH_TEXT);
  288. result = true;
  289. }
  290. if (GetInstallNASAdmin())
  291. {
  292. message += String::load(IDS_NAS_ADMIN_FINISH_TEXT);
  293. // If IIS isn't installed, add the text from the WebInstallationUnit
  294. WebInstallationUnit& webInstallationUnit =
  295. InstallationUnitProvider::GetInstance().GetWebInstallationUnit();
  296. if (!webInstallationUnit.IsServiceInstalled())
  297. {
  298. webInstallationUnit.GetMilestoneText(message);
  299. }
  300. result = true;
  301. }
  302. if (GetInstallAdminPack())
  303. {
  304. message += String::load(IDS_ADMIN_PACK_FINISH_TEXT);
  305. result = true;
  306. }
  307. LOG_BOOL(result);
  308. return result;
  309. }
  310. bool
  311. AdminPackInstallationUnit::IsAdminPackInstalled()
  312. {
  313. LOG_FUNCTION(AdminPackInstallationUnit::IsAdminPackInstalled);
  314. // Admin Tools Pack is no longer allowing itself to be installed
  315. // on server builds. By returning true here the UI will always
  316. // think its already install and never give the option.
  317. // NTRAID#NTBUG9-448167-2001/07/31-jeffjon
  318. bool result = true;
  319. /*
  320. bool result = false;
  321. // Admin Tools Pack is installed if the registry key for
  322. // uninstalling is present
  323. RegistryKey key;
  324. HRESULT hr = key.Open(
  325. HKEY_LOCAL_MACHINE,
  326. CYS_ADMINPAK_SERVERED_REGKEY,
  327. KEY_READ);
  328. if (SUCCEEDED(hr))
  329. {
  330. LOG(L"The Admin Pack uninstall key exists");
  331. result = true;
  332. }
  333. else
  334. {
  335. LOG(String::format(
  336. L"Failed to open Admin Pack uninstall key: hr = 0x%1!x!",
  337. hr));
  338. }
  339. */
  340. LOG_BOOL(result);
  341. return result;
  342. }
  343. void
  344. AdminPackInstallationUnit::SetInstallAdminPack(bool install)
  345. {
  346. LOG_FUNCTION2(
  347. AdminPackInstallationUnit::SetInstallAdminPack,
  348. install ? L"true" : L"false");
  349. installAdminPack = install;
  350. }
  351. bool
  352. AdminPackInstallationUnit::GetInstallAdminPack() const
  353. {
  354. LOG_FUNCTION(AdminPackInstallationUnit::GetInstallAdminPack);
  355. bool result = installAdminPack;
  356. LOG_BOOL(result);
  357. return result;
  358. }
  359. bool
  360. AdminPackInstallationUnit::IsWebAdminInstalled()
  361. {
  362. LOG_FUNCTION(AdminPackInstallationUnit::IsWebAdminInstalled);
  363. bool result = IsSAKUnitInstalled(WEB);
  364. LOG_BOOL(result);
  365. return result;
  366. }
  367. void
  368. AdminPackInstallationUnit::SetInstallWebAdmin(bool install)
  369. {
  370. LOG_FUNCTION2(
  371. AdminPackInstallationUnit::SetInstallWebAdmin,
  372. install ? L"true" : L"false");
  373. installWebAdmin = install;
  374. }
  375. bool
  376. AdminPackInstallationUnit::GetInstallWebAdmin() const
  377. {
  378. LOG_FUNCTION(AdminPackInstallationUnit::GetInstallWebAdmin);
  379. bool result = installWebAdmin;
  380. LOG_BOOL(result);
  381. return result;
  382. }
  383. bool
  384. AdminPackInstallationUnit::IsNASAdminInstalled()
  385. {
  386. LOG_FUNCTION(AdminPackInstallationUnit::IsNASAdminInstalled);
  387. bool result = IsSAKUnitInstalled(NAS);
  388. LOG_BOOL(result);
  389. return result;
  390. }
  391. bool
  392. AdminPackInstallationUnit::IsSAKUnitInstalled(SA_TYPE unitType)
  393. {
  394. LOG_FUNCTION2(
  395. AdminPackInstallationUnit::IsSAKUnitInstalled,
  396. String::format(L"type = %1!d!", (int) unitType));
  397. bool result = true;
  398. do
  399. {
  400. // Check to make sure we are not on 64bit
  401. if (State::GetInstance().Is64Bit())
  402. {
  403. result = false;
  404. break;
  405. }
  406. // Get the Server Appliance Kit COM object
  407. SmartInterface<ISaInstall> sakInstall;
  408. HRESULT hr = GetSAKObject(sakInstall);
  409. if (FAILED(hr))
  410. {
  411. LOG(String::format(
  412. L"Failed to get the SAK COM object: hr = 0x%1!x!",
  413. hr));
  414. break;
  415. }
  416. // Check to see if NAS is already installed
  417. VARIANT_BOOL saInstalled;
  418. hr = sakInstall->SAAlreadyInstalled(unitType, &saInstalled);
  419. if (FAILED(hr))
  420. {
  421. LOG(String::format(
  422. L"Failed call to SAAlreadyInstalled: hr = 0x%1!x!",
  423. hr));
  424. break;
  425. }
  426. if (!saInstalled)
  427. {
  428. result = false;
  429. }
  430. } while (false);
  431. LOG_BOOL(result);
  432. return result;
  433. }
  434. void
  435. AdminPackInstallationUnit::SetInstallNASAdmin(bool install)
  436. {
  437. LOG_FUNCTION2(
  438. AdminPackInstallationUnit::SetInstallNASAdmin,
  439. install ? L"true" : L"false");
  440. installNASAdmin = install;
  441. }
  442. bool
  443. AdminPackInstallationUnit::GetInstallNASAdmin() const
  444. {
  445. LOG_FUNCTION(AdminPackInstallationUnit::GetInstallNASAdmin);
  446. bool result = installNASAdmin;
  447. LOG_BOOL(result);
  448. return result;
  449. }
  450. HRESULT
  451. AdminPackInstallationUnit::GetSAKObject(SmartInterface<ISaInstall>& sakInstall)
  452. {
  453. LOG_FUNCTION(AdminPackInstallationUnit::GetSAKObject);
  454. HRESULT hr = S_OK;
  455. if (!sakInstallObject)
  456. {
  457. hr = sakInstallObject.AcquireViaCreateInstance(
  458. CLSID_SaInstall,
  459. 0,
  460. CLSCTX_INPROC_SERVER);
  461. }
  462. ASSERT(sakInstallObject);
  463. sakInstall = sakInstallObject;
  464. LOG_HRESULT(hr);
  465. return hr;
  466. }