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.

633 lines
14 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: POP3InstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a POP3InstallationUnit
  6. // This object has the knowledge for installing the
  7. // POP3 mail service
  8. //
  9. // History: 12/14/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "POP3InstallationUnit.h"
  13. #include <initguid.h>
  14. DEFINE_GUID(CLSID_P3Config,0x27AAC95F,0xCCC1,0x46F8,0xB4,0xBC,0xE5,0x92,0x25,0x27,0x55,0xA9);
  15. // Finish page help
  16. static PCWSTR CYS_POP3_FINISH_PAGE_HELP = L"cys.chm::/mail_server_role.htm";
  17. static PCWSTR CYS_POP3_MILESTONE_HELP = L"cys.chm::/mail_server_role.htm#mailsrvsummary";
  18. static PCWSTR CYS_POP3_AFTER_FINISH_HELP = L"cys.chm::/mail_server_role.htm#mailsrvcompletion";
  19. POP3InstallationUnit::POP3InstallationUnit() :
  20. authMethodIndex(0),
  21. pop3RoleResult(POP3_SUCCESS),
  22. InstallationUnit(
  23. IDS_POP3_SERVER_TYPE,
  24. IDS_POP3_SERVER_DESCRIPTION,
  25. IDS_POP3_FINISH_TITLE,
  26. IDS_POP3_FINISH_UNINSTALL_TITLE,
  27. IDS_POP3_FINISH_MESSAGE,
  28. IDS_POP3_INSTALL_FAILED,
  29. IDS_POP3_UNINSTALL_MESSAGE,
  30. IDS_POP3_UNINSTALL_FAILED,
  31. IDS_POP3_UNINSTALL_WARNING,
  32. IDS_POP3_UNINSTALL_CHECKBOX,
  33. CYS_POP3_FINISH_PAGE_HELP,
  34. CYS_POP3_MILESTONE_HELP,
  35. CYS_POP3_AFTER_FINISH_HELP,
  36. POP3_SERVER)
  37. {
  38. LOG_CTOR(POP3InstallationUnit);
  39. }
  40. POP3InstallationUnit::~POP3InstallationUnit()
  41. {
  42. LOG_DTOR(POP3InstallationUnit);
  43. }
  44. InstallationReturnType
  45. POP3InstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  46. {
  47. LOG_FUNCTION(POP3InstallationUnit::InstallService);
  48. // Log heading
  49. CYS_APPEND_LOG(String::load(IDS_LOG_POP3_HEADING));
  50. UpdateInstallationProgressText(hwnd, IDS_POP3_PROGRESS);
  51. InstallationReturnType result = INSTALL_SUCCESS;
  52. String unattendFileText;
  53. String infFileText;
  54. unattendFileText += L"[Components]\n";
  55. unattendFileText += L"Pop3Srv=ON\n";
  56. unattendFileText += L"Pop3Service=ON\n";
  57. bool ocmResult = InstallServiceWithOcManager(infFileText, unattendFileText);
  58. if (ocmResult &&
  59. IsServiceInstalled())
  60. {
  61. LOG(L"POP3 was installed successfully");
  62. CYS_APPEND_LOG(String::load(IDS_LOG_POP3_SERVER_SUCCESS));
  63. }
  64. else
  65. {
  66. LOG(L"POP3 failed to install");
  67. CYS_APPEND_LOG(String::load(IDS_LOG_POP3_SERVER_FAILURE));
  68. result = INSTALL_FAILURE;
  69. pop3RoleResult = POP3_INSTALL_FAILED;
  70. }
  71. if (result == INSTALL_SUCCESS)
  72. {
  73. // Now configure the service
  74. // This will set the role result if
  75. // there are any errors
  76. UpdateInstallationProgressText(hwnd, IDS_POP3_CONFIG_PROGRESS);
  77. ConfigurePOP3Service(logfileHandle);
  78. }
  79. LOG_INSTALL_RETURN(result);
  80. return result;
  81. }
  82. HRESULT
  83. POP3InstallationUnit::ConfigAuthMethod(
  84. SmartInterface<IP3Config>& p3Config,
  85. HANDLE logfileHandle)
  86. {
  87. LOG_FUNCTION(POP3InstallationUnit::ConfigAuthMethod);
  88. HRESULT hr = S_OK;
  89. do
  90. {
  91. // Get the authentication methods that are available
  92. IAuthMethods* dumbPointer = 0;
  93. hr =
  94. p3Config->get_Authentication(
  95. (IAuthMethods**)&dumbPointer);
  96. if (FAILED(hr) ||
  97. !dumbPointer)
  98. {
  99. LOG(
  100. String::format(
  101. L"Failed to get the authentication methods: hr = 0x%1!x!",
  102. hr));
  103. break;
  104. }
  105. SmartInterface<IAuthMethods> authMethods;
  106. authMethods.Acquire(dumbPointer);
  107. // Set the current authentication method
  108. VARIANT var;
  109. ::VariantInit(&var);
  110. V_VT(&var) = VT_I4;
  111. V_I4(&var) = GetAuthMethodIndex();
  112. hr = authMethods->put_CurrentAuthMethod(var);
  113. ::VariantClear(&var);
  114. if (FAILED(hr))
  115. {
  116. LOG(
  117. String::format(
  118. L"Failed to put the authentication method: hr = 0x%1!x!",
  119. hr));
  120. break;
  121. }
  122. // Now call save to commit the change
  123. hr = authMethods->Save();
  124. if (FAILED(hr))
  125. {
  126. LOG(
  127. String::format(
  128. L"Failed to save the auth method: hr = 0x%1!x!",
  129. hr));
  130. break;
  131. }
  132. } while (false);
  133. if (FAILED(hr) &&
  134. logfileHandle)
  135. {
  136. CYS_APPEND_LOG(
  137. String::format(
  138. IDS_LOG_POP3_AUTH_FAILURE,
  139. GetErrorMessage(hr).c_str()));
  140. }
  141. LOG_HRESULT(hr);
  142. return hr;
  143. }
  144. HRESULT
  145. POP3InstallationUnit::AddDomainName(
  146. SmartInterface<IP3Config>& p3Config,
  147. HANDLE logfileHandle)
  148. {
  149. LOG_FUNCTION(POP3InstallationUnit::AddDomainName);
  150. HRESULT hr = S_OK;
  151. do
  152. {
  153. IP3Domains* dumbPointer = 0;
  154. hr =
  155. p3Config->get_Domains(
  156. (IP3Domains**)&dumbPointer);
  157. if (FAILED(hr) ||
  158. !dumbPointer)
  159. {
  160. LOG(
  161. String::format(
  162. L"Failed to get the domains: hr = 0x%1!x!",
  163. hr));
  164. break;
  165. }
  166. SmartInterface<IP3Domains> p3Domains;
  167. p3Domains.Acquire(dumbPointer);
  168. // Now add the new domain name
  169. hr = p3Domains->Add(AutoBstr(GetDomainName().c_str()));
  170. if (FAILED(hr))
  171. {
  172. LOG(
  173. String::format(
  174. L"Failed to set the new domain name: hr = 0x%1!x!",
  175. hr));
  176. break;
  177. }
  178. } while (false);
  179. if (FAILED(hr) &&
  180. logfileHandle)
  181. {
  182. CYS_APPEND_LOG(
  183. String::format(
  184. IDS_LOG_POP3_DOMAIN_FAILURE,
  185. GetErrorMessage(hr).c_str(),
  186. GetDomainName().c_str()));
  187. }
  188. LOG_HRESULT(hr);
  189. return hr;
  190. }
  191. void
  192. POP3InstallationUnit::ConfigurePOP3Service(HANDLE logfileHandle)
  193. {
  194. LOG_FUNCTION(POP3InstallationUnit::ConfigurePOP3Service);
  195. do
  196. {
  197. // First create the IP3Config COM object which will be used
  198. // by the other config functions
  199. SmartInterface<IP3Config> p3Config;
  200. HRESULT hr = GetP3Config(p3Config);
  201. if (FAILED(hr))
  202. {
  203. LOG(
  204. String::format(
  205. L"Failed to instantiate the IP3Config COM object: hr = 0x%1!x!",
  206. hr));
  207. pop3RoleResult = POP3_AUTH_METHOD_FAILED;
  208. CYS_APPEND_LOG(
  209. String::format(
  210. IDS_LOG_POP3_AUTH_FAILURE,
  211. GetErrorMessage(hr).c_str()));
  212. break;
  213. }
  214. // The authentication method must be set before adding
  215. // a domain name
  216. hr = ConfigAuthMethod(p3Config, logfileHandle);
  217. if (FAILED(hr))
  218. {
  219. LOG(
  220. String::format(
  221. L"Failed to config auth method: hr = 0x%1!x!",
  222. hr));
  223. pop3RoleResult = POP3_AUTH_METHOD_FAILED;
  224. break;
  225. }
  226. // Now that the authentication method was set successfully
  227. // add the domain name
  228. hr = AddDomainName(p3Config, logfileHandle);
  229. if (FAILED(hr))
  230. {
  231. LOG(
  232. String::format(
  233. L"Failed to add the domain name: hr = 0x%1!x!",
  234. hr));
  235. pop3RoleResult = POP3_DOMAIN_NAME_FAILED;
  236. break;
  237. }
  238. } while (false);
  239. }
  240. UnInstallReturnType
  241. POP3InstallationUnit::UnInstallService(HANDLE logfileHandle, HWND hwnd)
  242. {
  243. LOG_FUNCTION(POP3InstallationUnit::UnInstallService);
  244. UnInstallReturnType result = UNINSTALL_SUCCESS;
  245. // Log heading
  246. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_POP3_HEADING));
  247. UpdateInstallationProgressText(hwnd, IDS_UNINSTALL_POP3_PROGRESS);
  248. String unattendFileText;
  249. String infFileText;
  250. unattendFileText += L"[Components]\n";
  251. unattendFileText += L"iis_smtp=OFF\n";
  252. unattendFileText += L"Pop3Srv=OFF\n";
  253. unattendFileText += L"Pop3Service=OFF\n";
  254. // NTRAID#NTBUG9-736557-2002/11/13-JeffJon
  255. // Pass the /w switch to sysocmgr when uninstalling
  256. // so that if a situation occurs in which a reboot
  257. // is required, the user will be prompted.
  258. String additionalArgs = L"/w";
  259. bool ocmResult =
  260. InstallServiceWithOcManager(
  261. infFileText,
  262. unattendFileText,
  263. additionalArgs);
  264. if (ocmResult &&
  265. !IsServiceInstalled())
  266. {
  267. LOG(L"POP3 was uninstalled successfully");
  268. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_POP3_SERVER_SUCCESS));
  269. }
  270. else
  271. {
  272. LOG(L"POP3 failed to uninstall");
  273. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_POP3_SERVER_FAILURE));
  274. result = UNINSTALL_FAILURE;
  275. }
  276. LOG_UNINSTALL_RETURN(result);
  277. return result;
  278. }
  279. bool
  280. POP3InstallationUnit::GetMilestoneText(String& message)
  281. {
  282. LOG_FUNCTION(POP3InstallationUnit::GetMilestoneText);
  283. message = String::load(IDS_POP3_FINISH_TEXT);
  284. LOG_BOOL(true);
  285. return true;
  286. }
  287. bool
  288. POP3InstallationUnit::GetUninstallMilestoneText(String& message)
  289. {
  290. LOG_FUNCTION(POP3InstallationUnit::GetUninstallMilestoneText);
  291. message = String::load(IDS_POP3_UNINSTALL_TEXT);
  292. LOG_BOOL(true);
  293. return true;
  294. }
  295. String
  296. POP3InstallationUnit::GetServiceDescription()
  297. {
  298. LOG_FUNCTION(POP3InstallationUnit::GetServiceDescription);
  299. unsigned int resourceID = static_cast<unsigned int>(-1);
  300. if (IsServiceInstalled())
  301. {
  302. resourceID = IDS_POP3_SERVER_DESCRIPTION_INSTALLED;
  303. }
  304. else
  305. {
  306. resourceID = descriptionID;
  307. }
  308. ASSERT(resourceID != static_cast<unsigned int>(-1));
  309. return String::load(resourceID);
  310. }
  311. void
  312. POP3InstallationUnit::ServerRoleLinkSelected(int linkIndex, HWND /*hwnd*/)
  313. {
  314. LOG_FUNCTION2(
  315. POP3InstallationUnit::ServerRoleLinkSelected,
  316. String::format(
  317. L"linkIndex = %1!d!",
  318. linkIndex));
  319. if (IsServiceInstalled())
  320. {
  321. ASSERT(linkIndex == 0);
  322. LaunchMYS();
  323. }
  324. else
  325. {
  326. ASSERT(linkIndex == 0);
  327. LOG(L"Showing configuration help");
  328. ShowHelp(CYS_POP3_FINISH_PAGE_HELP);
  329. }
  330. }
  331. void
  332. POP3InstallationUnit::FinishLinkSelected(int linkIndex, HWND /*hwnd*/)
  333. {
  334. LOG_FUNCTION2(
  335. POP3InstallationUnit::FinishLinkSelected,
  336. String::format(
  337. L"linkIndex = %1!d!",
  338. linkIndex));
  339. if (linkIndex != 0)
  340. {
  341. LOG("Unexpected link index");
  342. ASSERT(linkIndex == 0);
  343. return;
  344. }
  345. if (installing)
  346. {
  347. if (GetPOP3RoleResult() == POP3_SUCCESS)
  348. {
  349. LOG("Showing after checklist");
  350. ShowHelp(CYS_POP3_AFTER_FINISH_HELP);
  351. }
  352. // NTRAID#NTBUG9-703593-2002/09/16-artm
  353. else if (GetPOP3RoleResult() == POP3_INSTALL_FAILED)
  354. {
  355. LOG("Showing configuration help");
  356. ShowHelp(CYS_POP3_FINISH_PAGE_HELP);
  357. }
  358. else
  359. {
  360. LOG("Opening the console");
  361. // First read the console file path from the registry
  362. String consolePath;
  363. if (GetRegKeyValue(
  364. CYS_POP3_REGKEY,
  365. CYS_POP3_CONSOLE,
  366. consolePath))
  367. {
  368. LaunchMMCConsole(L"p3server.msc", consolePath);
  369. }
  370. else
  371. {
  372. // if we couldn't read the console file path from
  373. // the registry just go ahead and assume its in
  374. // the system32 directory
  375. LaunchMMCConsole(L"p3server.msc");
  376. }
  377. }
  378. }
  379. }
  380. void
  381. POP3InstallationUnit::SetDomainName(const String& domain)
  382. {
  383. LOG_FUNCTION2(
  384. POP3InstallationUnit::SetDomainName,
  385. domain);
  386. domainName = domain;
  387. }
  388. String
  389. POP3InstallationUnit::GetDomainName() const
  390. {
  391. LOG_FUNCTION(POP3InstallationUnit::GetDomainName);
  392. String result = domainName;
  393. LOG(result);
  394. return result;
  395. }
  396. void
  397. POP3InstallationUnit::SetAuthMethodIndex(int method)
  398. {
  399. LOG_FUNCTION2(
  400. POP3InstallationUnit::SetAuthMethodIndex,
  401. String::format(
  402. L"%1!d!",
  403. method));
  404. authMethodIndex = method;
  405. }
  406. int
  407. POP3InstallationUnit::GetAuthMethodIndex() const
  408. {
  409. LOG_FUNCTION(POP3InstallationUnit::GetAuthMethodIndex);
  410. LOG(
  411. String::format(
  412. L"authMethodIndex = %1!d!",
  413. authMethodIndex));
  414. return authMethodIndex;
  415. }
  416. int
  417. POP3InstallationUnit::GetWizardStart()
  418. {
  419. LOG_FUNCTION(POP3InstallationUnit::GetWizardStart);
  420. int result = IDD_POP3_PAGE;
  421. bool installingRole = true;
  422. if (IsServiceInstalled())
  423. {
  424. installingRole = false;
  425. result = IDD_UNINSTALL_MILESTONE_PAGE;
  426. }
  427. SetInstalling(installingRole);
  428. LOG(String::format(
  429. L"wizard start = %1!d!",
  430. result));
  431. return result;
  432. }
  433. HRESULT
  434. POP3InstallationUnit::GetP3Config(SmartInterface<IP3Config>& p3Config) const
  435. {
  436. LOG_FUNCTION(POP3InstallationUnit::GetP3Config);
  437. HRESULT hr =
  438. p3Config.AcquireViaCreateInstance(
  439. CLSID_P3Config,
  440. 0,
  441. CLSCTX_INPROC_SERVER);
  442. LOG_HRESULT(hr);
  443. return hr;
  444. }
  445. unsigned int
  446. POP3InstallationUnit::GetPOP3RoleResult() const
  447. {
  448. LOG_FUNCTION(POP3InstallationUnit::GetPOP3RoleResult);
  449. LOG(
  450. String::format(
  451. L"pop3RoleResult = %1!d!",
  452. pop3RoleResult));
  453. return pop3RoleResult;
  454. }
  455. String
  456. POP3InstallationUnit::GetFinishText()
  457. {
  458. LOG_FUNCTION(POP3InstallationUnit::GetFinishText);
  459. unsigned int messageID = finishMessageID;
  460. if (installing)
  461. {
  462. unsigned int pop3RoleResult = GetPOP3RoleResult();
  463. if (pop3RoleResult == POP3_AUTH_METHOD_FAILED)
  464. {
  465. messageID = IDS_POP3_AUTH_METHOD_FAILED;
  466. }
  467. else if (pop3RoleResult == POP3_DOMAIN_NAME_FAILED)
  468. {
  469. messageID = IDS_POP3_DOMAIN_NAME_FAILED;
  470. }
  471. else if (pop3RoleResult == POP3_INSTALL_FAILED)
  472. {
  473. messageID = IDS_POP3_INSTALL_FAILED;
  474. }
  475. else
  476. {
  477. messageID = finishMessageID;
  478. }
  479. }
  480. else
  481. {
  482. messageID = finishUninstallMessageID;
  483. UnInstallReturnType result = GetUnInstallResult();
  484. if (result != UNINSTALL_SUCCESS &&
  485. result != UNINSTALL_SUCCESS_REBOOT &&
  486. result != UNINSTALL_SUCCESS_PROMPT_REBOOT)
  487. {
  488. messageID = finishUninstallFailedMessageID;
  489. }
  490. }
  491. return String::load(messageID);
  492. }