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.

966 lines
25 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: DNSInstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a DNSInstallationUnit
  6. // This object has the knowledge for installing the
  7. // DNS service
  8. //
  9. // History: 02/05/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "DNSInstallationUnit.h"
  13. #include "InstallationUnitProvider.h"
  14. #include "NetworkInterface.h"
  15. // Finish page help
  16. static PCWSTR CYS_DNS_FINISH_PAGE_HELP = L"cys.chm::/dns_server_role.htm";
  17. static PCWSTR CYS_DNS_MILESTONE_HELP = L"cys.chm::/dns_server_role.htm#dnssrvsummary";
  18. static PCWSTR CYS_DNS_AFTER_FINISH_HELP = L"cys.chm::/dns_server_role.htm#dnssrvcompletion";
  19. DNSInstallationUnit::DNSInstallationUnit() :
  20. staticIPAddress(CYS_DEFAULT_IPADDRESS),
  21. subnetMask(CYS_DEFAULT_SUBNETMASK),
  22. forwarderIPAddress(0),
  23. manualForwarder(false),
  24. dnsRoleResult(DNS_SUCCESS),
  25. installedDescriptionID(IDS_DNS_SERVER_DESCRIPTION_INSTALLED),
  26. ExpressPathInstallationUnitBase(
  27. IDS_DNS_SERVER_TYPE,
  28. IDS_DNS_SERVER_DESCRIPTION,
  29. IDS_DNS_FINISH_TITLE,
  30. IDS_DNS_FINISH_UNINSTALL_TITLE,
  31. IDS_DNS_FINISH_MESSAGE,
  32. IDS_DNS_INSTALL_FAILED,
  33. IDS_DNS_UNINSTALL_MESSAGE,
  34. IDS_DNS_UNINSTALL_FAILED,
  35. IDS_DNS_UNINSTALL_WARNING,
  36. IDS_DNS_UNINSTALL_CHECKBOX,
  37. CYS_DNS_FINISH_PAGE_HELP,
  38. CYS_DNS_MILESTONE_HELP,
  39. CYS_DNS_AFTER_FINISH_HELP,
  40. DNS_SERVER)
  41. {
  42. LOG_CTOR(DNSInstallationUnit);
  43. }
  44. DNSInstallationUnit::~DNSInstallationUnit()
  45. {
  46. LOG_DTOR(DNSInstallationUnit);
  47. }
  48. InstallationReturnType
  49. DNSInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  50. {
  51. LOG_FUNCTION(DNSInstallationUnit::InstallService);
  52. InstallationReturnType result = INSTALL_SUCCESS;
  53. if (IsExpressPathInstall())
  54. {
  55. result = ExpressPathInstall(logfileHandle, hwnd);
  56. LOG_INSTALL_RETURN(result);
  57. return result;
  58. }
  59. dnsRoleResult = DNS_SUCCESS;
  60. // Log the DNS header
  61. CYS_APPEND_LOG(String::load(IDS_LOG_DNS_HEADER));
  62. UpdateInstallationProgressText(hwnd, IDS_DNS_INSTALL_PROGRESS);
  63. // Create the inf and unattend files that are used by the
  64. // Optional Component Manager
  65. String infFileText;
  66. String unattendFileText;
  67. CreateInfFileText(infFileText, IDS_DNS_INF_WINDOW_TITLE);
  68. CreateUnattendFileText(unattendFileText, CYS_DNS_SERVICE_NAME);
  69. // Install the service through the Optional Component Manager
  70. String additionalArgs = L"/z:netoc_show_unattended_messages";
  71. // We are ignoring the ocmresult because it doesn't matter
  72. // with respect to whether the role is installed or not
  73. InstallServiceWithOcManager(
  74. infFileText,
  75. unattendFileText,
  76. additionalArgs);
  77. if (IsServiceInstalled())
  78. {
  79. // Log the successful installation
  80. LOG(L"DNS was installed successfully");
  81. CYS_APPEND_LOG(String::load(IDS_LOG_SERVER_START_DNS));
  82. // Wait for the service to enter the running state
  83. NTService serviceObject(CYS_DNS_SERVICE_NAME);
  84. HRESULT hr = serviceObject.WaitForServiceState(SERVICE_RUNNING);
  85. if (FAILED(hr))
  86. {
  87. // This is a config failure because as far as we are concerned the
  88. // service was installed properly.
  89. dnsRoleResult = DNS_SERVICE_START_FAILURE;
  90. LOG(String::format(
  91. L"The DNS service failed to start in a timely fashion: %1!x!",
  92. hr));
  93. CYS_APPEND_LOG(String::load(IDS_LOG_DNS_SERVICE_TIMEOUT));
  94. result = INSTALL_FAILURE;
  95. }
  96. else
  97. {
  98. // Run the DNS Wizard
  99. UpdateInstallationProgressText(hwnd, IDS_DNS_CONFIG_PROGRESS);
  100. String resultText;
  101. HRESULT unused = S_OK;
  102. if (ExecuteWizard(hwnd, CYS_DNS_SERVICE_NAME, resultText, unused))
  103. {
  104. // Check to be sure the wizard finished completely
  105. String configWizardResults;
  106. if (ReadConfigWizardRegkeys(configWizardResults))
  107. {
  108. // The Configure DNS Server Wizard completed successfully
  109. LOG(L"The Configure DNS Server Wizard completed successfully");
  110. CYS_APPEND_LOG(String::load(IDS_LOG_DNS_COMPLETED_SUCCESSFULLY));
  111. }
  112. else
  113. {
  114. // The Configure DNS Server Wizard did not finish successfully
  115. dnsRoleResult = DNS_CONFIG_FAILURE;
  116. result = INSTALL_FAILURE;
  117. if (!configWizardResults.empty())
  118. {
  119. // An error was returned via the regkey
  120. LOG(String::format(
  121. L"The Configure DNS Server Wizard returned the error: %1",
  122. configWizardResults.c_str()));
  123. String formatString = String::load(IDS_LOG_DNS_WIZARD_ERROR);
  124. CYS_APPEND_LOG(String::format(formatString, configWizardResults.c_str()));
  125. }
  126. else
  127. {
  128. // The Configure DNS Server Wizard was cancelled by the user
  129. LOG(L"The Configure DNS Server Wizard was cancelled by the user");
  130. CYS_APPEND_LOG(String::load(IDS_LOG_DNS_WIZARD_CANCELLED));
  131. }
  132. }
  133. }
  134. else
  135. {
  136. dnsRoleResult = DNS_INSTALL_FAILURE;
  137. // Show an error
  138. LOG(L"DNS could not be installed.");
  139. if (!resultText.empty())
  140. {
  141. CYS_APPEND_LOG(resultText);
  142. }
  143. }
  144. }
  145. }
  146. else
  147. {
  148. dnsRoleResult = DNS_INSTALL_FAILURE;
  149. // Log the failure
  150. LOG(L"DNS failed to install");
  151. CYS_APPEND_LOG(String::load(IDS_LOG_DNS_SERVER_FAILED));
  152. result = INSTALL_FAILURE;
  153. }
  154. LOG_INSTALL_RETURN(result);
  155. return result;
  156. }
  157. UnInstallReturnType
  158. DNSInstallationUnit::UnInstallService(HANDLE logfileHandle, HWND hwnd)
  159. {
  160. LOG_FUNCTION(DNSInstallationUnit::UnInstallService);
  161. UnInstallReturnType result = UNINSTALL_SUCCESS;
  162. // Log the DNS header
  163. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_DNS_HEADER));
  164. UpdateInstallationProgressText(hwnd, IDS_DNS_UNINSTALL_PROGRESS);
  165. String infFileText;
  166. String unattendFileText;
  167. CreateInfFileText(infFileText, IDS_DNS_INF_WINDOW_TITLE);
  168. CreateUnattendFileText(unattendFileText, CYS_DNS_SERVICE_NAME, false);
  169. // NTRAID#NTBUG9-736557-2002/11/13-JeffJon
  170. // Pass the /w switch to sysocmgr when uninstalling
  171. // so that if a situation occurs in which a reboot
  172. // is required, the user will be prompted.
  173. String additionalArgs = L"/w";
  174. // We are ignoring the ocmresult because it doesn't matter
  175. // with respect to whether the role is installed or not
  176. InstallServiceWithOcManager(
  177. infFileText,
  178. unattendFileText,
  179. additionalArgs);
  180. if (IsServiceInstalled())
  181. {
  182. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_DNS_FAILED));
  183. result = UNINSTALL_FAILURE;
  184. }
  185. else
  186. {
  187. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_DNS_SUCCESS));
  188. }
  189. LOG_UNINSTALL_RETURN(result);
  190. return result;
  191. }
  192. void
  193. DNSInstallationUnit::SetForwardersForExpressPath()
  194. {
  195. LOG_FUNCTION(DNSInstallationUnit::SetForwardersForExpressPath);
  196. // If the forwarders were set manually write them
  197. // to the registry so that we can set
  198. // a forwarder after the reboot
  199. // Note: this will write a zero entry if the user
  200. // chose not to forward. The code run after reboot
  201. // needs to handle this properly
  202. if (IsManualForwarder())
  203. {
  204. if (!SetRegKeyValue(
  205. CYS_FIRST_DC_REGKEY,
  206. CYS_FIRST_DC_FORWARDER,
  207. forwarderIPAddress,
  208. HKEY_LOCAL_MACHINE,
  209. true))
  210. {
  211. LOG(L"Failed to set forwarder regkey");
  212. }
  213. }
  214. else
  215. {
  216. // Write the current DNS servers as forwarders to the registry
  217. // so that we don't have problems after the reboot
  218. IPAddressList forwarders;
  219. GetForwarders(forwarders);
  220. if (forwarders.empty())
  221. {
  222. LOG(L"No DNS servers set on any NIC");
  223. }
  224. else
  225. {
  226. // Format the IP addresses into a string for storage
  227. // in the registry
  228. String ipList;
  229. for (IPAddressList::iterator itr = forwarders.begin();
  230. itr != forwarders.end();
  231. ++itr)
  232. {
  233. if (!ipList.empty())
  234. {
  235. ipList += L" ";
  236. }
  237. ipList += String::format(
  238. L"%1",
  239. IPAddressToString(*itr).c_str());
  240. }
  241. if (!SetRegKeyValue(
  242. CYS_FIRST_DC_REGKEY,
  243. CYS_FIRST_DC_AUTOFORWARDER,
  244. ipList,
  245. HKEY_LOCAL_MACHINE,
  246. true))
  247. {
  248. LOG(L"We failed to set the forwarders regkey.");
  249. }
  250. }
  251. }
  252. }
  253. InstallationReturnType
  254. DNSInstallationUnit::ExpressPathInstall(HANDLE logfileHandle, HWND hwnd)
  255. {
  256. LOG_FUNCTION(DNSInstallationUnit::ExpressPathInstall);
  257. InstallationReturnType result = INSTALL_SUCCESS;
  258. do
  259. {
  260. String netshPath = GetNetshPath();
  261. String commandLine;
  262. HRESULT hr = S_OK;
  263. UpdateInstallationProgressText(hwnd, IDS_DNS_CLIENT_CONFIG_PROGRESS);
  264. // We ignore if the NIC is found or not because the function will return
  265. // the first NIC if the correct NIC is not found. We can then use this
  266. // to setup the network
  267. NetworkInterface* nic = State::GetInstance().GetLocalNIC();
  268. if (!nic)
  269. {
  270. LOG(L"Couldn't find the NIC so fail");
  271. result = INSTALL_FAILURE;
  272. CYS_APPEND_LOG(
  273. String::load(IDS_EXPRESS_DNS_LOG_STATIC_IP_FAILED));
  274. InstallationUnitProvider::GetInstance().
  275. GetExpressInstallationUnit().SetExpressRoleResult(
  276. ExpressInstallationUnit::EXPRESS_DNS_FAILURE);
  277. break;
  278. }
  279. // set static IP address and subnet mask
  280. String friendlyName =
  281. nic->GetFriendlyName(
  282. String::load(IDS_LOCAL_AREA_CONNECTION));
  283. if (nic->IsDHCPEnabled() ||
  284. nic->GetIPAddress(0) == 0)
  285. {
  286. // invoke netsh and wait for it to terminate
  287. String availableIPAddress = IPAddressToString(
  288. nic->GetNextAvailableIPAddress(
  289. CYS_DEFAULT_IPADDRESS,
  290. CYS_DEFAULT_SUBNETMASK));
  291. commandLine =
  292. String::format(
  293. L"interface ip set address "
  294. L"name=\"%1\" source=static addr=%2 mask=%3 gateway=none",
  295. friendlyName.c_str(),
  296. availableIPAddress.c_str(),
  297. CYS_DEFAULT_SUBNETMASK_STRING);
  298. DWORD exitCode1 = 0;
  299. hr = ::CreateAndWaitForProcess(
  300. netshPath,
  301. commandLine,
  302. exitCode1,
  303. true);
  304. if (FAILED(hr) || exitCode1)
  305. {
  306. LOG(String::format(
  307. L"Failed to set the static IP address and subnet mask: exitCode = %1!x!",
  308. exitCode1));
  309. result = INSTALL_FAILURE;
  310. CYS_APPEND_LOG(
  311. String::load(IDS_EXPRESS_DNS_LOG_STATIC_IP_FAILED));
  312. InstallationUnitProvider::GetInstance().
  313. GetExpressInstallationUnit().SetExpressRoleResult(
  314. ExpressInstallationUnit::EXPRESS_DNS_FAILURE);
  315. break;
  316. }
  317. ASSERT(SUCCEEDED(hr));
  318. // NTRAID#NTBUG9-638337-2002/06/13-JeffJon
  319. // Now that the IP address was set, write it to a regkey so
  320. // that we can compare it to the IP address on reboot and
  321. // give a failure if they are different.
  322. if (!SetRegKeyValue(
  323. CYS_FIRST_DC_REGKEY,
  324. CYS_FIRST_DC_STATIC_IP,
  325. availableIPAddress,
  326. HKEY_LOCAL_MACHINE,
  327. true))
  328. {
  329. LOG(L"Failed to set the static IP regkey");
  330. }
  331. CYS_APPEND_LOG(
  332. String::format(
  333. IDS_EXPRESS_IPADDRESS_SUCCESS,
  334. availableIPAddress.c_str()));
  335. CYS_APPEND_LOG(
  336. String::format(
  337. IDS_EXPRESS_SUBNETMASK_SUCCESS,
  338. CYS_DEFAULT_SUBNETMASK_STRING));
  339. // Set the IP address and subnet mask on the NetworkInterface object
  340. nic->SetIPAddress(
  341. StringToIPAddress(availableIPAddress),
  342. availableIPAddress);
  343. nic->SetSubnetMask(
  344. CYS_DEFAULT_SUBNETMASK,
  345. CYS_DEFAULT_SUBNETMASK_STRING);
  346. }
  347. // NTRAID#NTBUG9-664171-2002/07/15-JeffJon
  348. // The forwarders must be read and set after setting the static
  349. // IP address or else we may be adding multiple entries for
  350. // the new static IP address in the forwarders list
  351. SetForwardersForExpressPath();
  352. // set DNS server address to same address as the private NIC of
  353. // local machine for all NICs. In most cases this will be 192.168.0.1
  354. // netsh does not allow the dns server address to be the loopback address.
  355. for (unsigned int nicIndex = 0;
  356. nicIndex < State::GetInstance().GetNICCount();
  357. ++nicIndex)
  358. {
  359. NetworkInterface* currentNIC = State::GetInstance().GetNIC(nicIndex);
  360. if (!currentNIC)
  361. {
  362. continue;
  363. }
  364. // First check to be sure the IP address isn't already in the list
  365. bool okToAddDNSServer = true;
  366. IPAddressList dnsServers;
  367. currentNIC->GetDNSServers(dnsServers);
  368. for (IPAddressList::iterator itr = dnsServers.begin();
  369. itr != dnsServers.end();
  370. ++itr)
  371. {
  372. if (itr &&
  373. *itr == nic->GetIPAddress(0))
  374. {
  375. okToAddDNSServer = false;
  376. break;
  377. }
  378. }
  379. // Add the IP address to the DNS servers since it
  380. // isn't already in the list
  381. if (okToAddDNSServer)
  382. {
  383. String currentFriendlyName =
  384. currentNIC->GetFriendlyName(
  385. String::load(IDS_LOCAL_AREA_CONNECTION));
  386. commandLine =
  387. String::format(
  388. L"interface ip set dns name=\"%1\" source=static addr=%2",
  389. currentFriendlyName.c_str(),
  390. nic->GetStringIPAddress(0).c_str());
  391. DWORD exitCode2 = 0;
  392. hr = ::CreateAndWaitForProcess(
  393. netshPath,
  394. commandLine,
  395. exitCode2,
  396. true);
  397. if (FAILED(hr) || exitCode2)
  398. {
  399. LOG(String::format(
  400. L"Failed to set the preferred DNS server IP address: exitCode = %1!x!",
  401. exitCode2));
  402. // This should really only be considered a failure for the "local" NIC
  403. if (currentFriendlyName.icompare(friendlyName) == 0)
  404. {
  405. result = INSTALL_FAILURE;
  406. InstallationUnitProvider::GetInstance().
  407. GetExpressInstallationUnit().SetExpressRoleResult(
  408. ExpressInstallationUnit::EXPRESS_DNS_FAILURE);
  409. break;
  410. }
  411. }
  412. }
  413. }
  414. if (result != INSTALL_FAILURE)
  415. {
  416. CYS_APPEND_LOG(
  417. String::format(
  418. IDS_EXPRESS_DNSSERVER_SUCCESS,
  419. nic->GetStringIPAddress(0).c_str()));
  420. }
  421. } while (false);
  422. LOG_INSTALL_RETURN(result);
  423. return result;
  424. }
  425. bool
  426. DNSInstallationUnit::ReadConfigWizardRegkeys(String& configWizardResults) const
  427. {
  428. LOG_FUNCTION(DNSInstallationUnit::ReadConfigWizardRegkeys);
  429. bool result = false;
  430. do
  431. {
  432. DWORD value = 0;
  433. result = GetRegKeyValue(
  434. DNS_WIZARD_CONFIG_REGKEY,
  435. DNS_WIZARD_CONFIG_VALUE,
  436. value);
  437. if (result &&
  438. value != 0)
  439. {
  440. // The Configure DNS Server Wizard succeeded
  441. result = true;
  442. break;
  443. }
  444. // Since there was a failure (or the wizard was cancelled)
  445. // get the display string to log
  446. GetRegKeyValue(
  447. DNS_WIZARD_RESULT_REGKEY,
  448. DNS_WIZARD_RESULT_VALUE,
  449. configWizardResults);
  450. } while (false);
  451. LOG_BOOL(result);
  452. return result;
  453. }
  454. bool
  455. DNSInstallationUnit::GetMilestoneText(String& message)
  456. {
  457. LOG_FUNCTION(DNSInstallationUnit::GetMilestoneText);
  458. message = String::load(IDS_DNS_FINISH_TEXT);
  459. LOG_BOOL(true);
  460. return true;
  461. }
  462. bool
  463. DNSInstallationUnit::GetUninstallMilestoneText(String& message)
  464. {
  465. LOG_FUNCTION(DNSInstallationUnit::GetUninstallMilestoneText);
  466. message = String::load(IDS_DNS_UNINSTALL_TEXT);
  467. LOG_BOOL(true);
  468. return true;
  469. }
  470. String
  471. DNSInstallationUnit::GetUninstallWarningText()
  472. {
  473. LOG_FUNCTION(DNSInstallationUnit::GetUninstallWarningText);
  474. unsigned int messageID = uninstallMilestoneWarningID;
  475. if (State::GetInstance().IsDC())
  476. {
  477. messageID = IDS_DNS_UNINSTALL_WARNING_ISDC;
  478. }
  479. return String::load(messageID);
  480. }
  481. void
  482. DNSInstallationUnit::SetStaticIPAddress(DWORD ipaddress)
  483. {
  484. LOG_FUNCTION2(
  485. DNSInstallationUnit::SetStaticIPAddress,
  486. IPAddressToString(ipaddress).c_str());
  487. staticIPAddress = ipaddress;
  488. }
  489. void
  490. DNSInstallationUnit::SetSubnetMask(DWORD mask)
  491. {
  492. LOG_FUNCTION2(
  493. DNSInstallationUnit::SetSubnetMask,
  494. IPAddressToString(mask).c_str());
  495. subnetMask = mask;
  496. }
  497. String
  498. DNSInstallationUnit::GetStaticIPAddressString()
  499. {
  500. LOG_FUNCTION(DNSInstallationUnit::GetStaticIPAddressString);
  501. String result = IPAddressToString(GetStaticIPAddress());
  502. LOG(result);
  503. return result;
  504. }
  505. String
  506. DNSInstallationUnit::GetSubnetMaskString()
  507. {
  508. LOG_FUNCTION(DNSInstallationUnit::GetSubnetMaskString);
  509. String result = IPAddressToString(GetSubnetMask());
  510. LOG(result);
  511. return result;
  512. }
  513. DWORD
  514. DNSInstallationUnit::GetStaticIPAddress()
  515. {
  516. LOG_FUNCTION(DNSInstallationUnit::GetStaticIPAddress);
  517. // Get the IP address from the NIC only if it
  518. // is a static IP address else use the default
  519. NetworkInterface* nic = State::GetInstance().GetNIC(0);
  520. if (nic &&
  521. !nic->IsDHCPEnabled())
  522. {
  523. staticIPAddress = nic->GetIPAddress(0);
  524. }
  525. return staticIPAddress;
  526. }
  527. DWORD
  528. DNSInstallationUnit::GetSubnetMask()
  529. {
  530. LOG_FUNCTION(DNSInstallationUnit::GetSubnetMask);
  531. // Get the subnet mask from the NIC only if it
  532. // is a static IP address else use the default
  533. NetworkInterface* nic = State::GetInstance().GetNIC(0);
  534. if (nic &&
  535. !nic->IsDHCPEnabled())
  536. {
  537. subnetMask = nic->GetSubnetMask(0);
  538. }
  539. return subnetMask;
  540. }
  541. void
  542. DNSInstallationUnit::SetForwarder(DWORD forwarderAddress)
  543. {
  544. LOG_FUNCTION2(
  545. DNSInstallationUnit::SetForwarder,
  546. String::format(L"%1!x!", forwarderAddress));
  547. forwarderIPAddress = forwarderAddress;
  548. manualForwarder = true;
  549. }
  550. void
  551. DNSInstallationUnit::GetForwarders(IPAddressList& forwarders) const
  552. {
  553. LOG_FUNCTION(DNSInstallationUnit::GetForwarders);
  554. // clear out the list to start
  555. forwarders.clear();
  556. if (IsManualForwarder() &&
  557. forwarderIPAddress != 0)
  558. {
  559. DWORD forwarderInDisplayOrder = ConvertIPAddressOrder(forwarderIPAddress);
  560. LOG(
  561. String::format(
  562. L"Adding manual forwarder to list: %1",
  563. IPAddressToString(forwarderInDisplayOrder).c_str()));
  564. // Forwarder was assigned through the UI
  565. forwarders.push_back(forwarderIPAddress);
  566. }
  567. else if (IsManualForwarder() &&
  568. forwarderIPAddress == 0)
  569. {
  570. // The user chose not to forward
  571. LOG(L"User chose not to foward");
  572. // Do nothing. Need to check the list returned
  573. // to make sure there is a valid address
  574. }
  575. else
  576. {
  577. LOG(L"No user defined forwarder. Trying to detect through NICs");
  578. // No forwarder assigned through the UI so
  579. // search the NICs
  580. for (unsigned int idx = 0; idx < State::GetInstance().GetNICCount(); ++idx)
  581. {
  582. NetworkInterface* nic = State::GetInstance().GetNIC(idx);
  583. // Add the DNS servers from this NIC
  584. if (nic)
  585. {
  586. nic->GetDNSServers(forwarders);
  587. }
  588. }
  589. // Make sure there are no forwarders that are the same as
  590. // the IP addresses of any of the NICs
  591. for (unsigned int idx = 0; idx < State::GetInstance().GetNICCount(); ++idx)
  592. {
  593. NetworkInterface* nic = State::GetInstance().GetNIC(idx);
  594. if (!nic)
  595. {
  596. continue;
  597. }
  598. for (DWORD ipidx = 0; ipidx < nic->GetIPAddressCount(); ++ipidx)
  599. {
  600. DWORD ipaddress = nic->GetIPAddress(ipidx);
  601. for (IPAddressList::iterator itr = forwarders.begin();
  602. itr != forwarders.end();
  603. ++itr)
  604. {
  605. if (ipaddress == *itr)
  606. {
  607. // The forwarder matches a local IP address
  608. // so remove it
  609. LOG(String::format(
  610. L"Can't put the local IP address in the forwarders list: %1",
  611. IPAddressToString(*itr).c_str()));
  612. forwarders.erase(itr);
  613. break;
  614. }
  615. }
  616. if (forwarders.empty())
  617. {
  618. // It's possible that we removed the last forwarder
  619. // so break out if we did
  620. break;
  621. }
  622. }
  623. if (forwarders.empty())
  624. {
  625. // It's possible that we removed the last forwarder
  626. // so break out if we did
  627. break;
  628. }
  629. }
  630. }
  631. }
  632. bool
  633. DNSInstallationUnit::IsManualForwarder() const
  634. {
  635. LOG_FUNCTION(DNSInstallationUnit::IsManualForwarder);
  636. LOG_BOOL(manualForwarder);
  637. return manualForwarder;
  638. }
  639. String
  640. DNSInstallationUnit::GetServiceDescription()
  641. {
  642. LOG_FUNCTION(DNSInstallationUnit::GetServiceDescription);
  643. String result;
  644. unsigned int resultID = descriptionID;
  645. if (GetStatus() == STATUS_COMPLETED)
  646. {
  647. resultID = installedDescriptionID;
  648. }
  649. result = String::load(resultID);
  650. ASSERT(!result.empty());
  651. return result;
  652. }
  653. void
  654. DNSInstallationUnit::ServerRoleLinkSelected(int linkIndex, HWND /*hwnd*/)
  655. {
  656. LOG_FUNCTION2(
  657. DNSInstallationUnit::ServerRoleLinkSelected,
  658. String::format(
  659. L"linkIndex = %1!d!",
  660. linkIndex));
  661. if (IsServiceInstalled())
  662. {
  663. ASSERT(linkIndex == 0);
  664. LaunchMYS();
  665. }
  666. else
  667. {
  668. ASSERT(linkIndex == 0);
  669. LOG(L"Showing configuration help");
  670. ShowHelp(CYS_DNS_FINISH_PAGE_HELP);
  671. }
  672. }
  673. void
  674. DNSInstallationUnit::FinishLinkSelected(int linkIndex, HWND /*hwnd*/)
  675. {
  676. LOG_FUNCTION2(
  677. DNSInstallationUnit::FinishLinkSelected,
  678. String::format(
  679. L"linkIndex = %1!d!",
  680. linkIndex));
  681. if (installing)
  682. {
  683. if (linkIndex == 0 &&
  684. IsServiceInstalled())
  685. {
  686. if (dnsRoleResult == DNS_SUCCESS)
  687. {
  688. LOG("Showing after checklist");
  689. ShowHelp(CYS_DNS_AFTER_FINISH_HELP);
  690. }
  691. else if (dnsRoleResult == DNS_SERVICE_START_FAILURE)
  692. {
  693. LOG(L"Launching Services console");
  694. LaunchMMCConsole(L"services.msc");
  695. }
  696. else
  697. {
  698. LOG(L"Launching DNS snapin");
  699. LaunchMMCConsole(L"dnsmgmt.msc");
  700. }
  701. }
  702. else
  703. {
  704. LOG(L"Showing configuration help");
  705. ShowHelp(CYS_DNS_FINISH_PAGE_HELP);
  706. }
  707. }
  708. }
  709. String
  710. DNSInstallationUnit::GetFinishText()
  711. {
  712. LOG_FUNCTION(DNSInstallationUnit::GetFinishText);
  713. unsigned int messageID = finishMessageID;
  714. if (installing)
  715. {
  716. InstallationReturnType result = GetInstallResult();
  717. if (result != INSTALL_SUCCESS &&
  718. result != INSTALL_SUCCESS_REBOOT &&
  719. result != INSTALL_SUCCESS_PROMPT_REBOOT)
  720. {
  721. if (dnsRoleResult == DNS_INSTALL_FAILURE)
  722. {
  723. messageID = finishInstallFailedMessageID;
  724. }
  725. else if (dnsRoleResult == DNS_SERVICE_START_FAILURE)
  726. {
  727. messageID = IDS_DNS_SERVICE_START_FAILED;
  728. }
  729. else
  730. {
  731. messageID = IDS_DNS_CONFIG_FAILED;
  732. }
  733. }
  734. }
  735. else
  736. {
  737. messageID = finishUninstallMessageID;
  738. UnInstallReturnType result = GetUnInstallResult();
  739. if (result != UNINSTALL_SUCCESS &&
  740. result != UNINSTALL_SUCCESS_REBOOT &&
  741. result != UNINSTALL_SUCCESS_PROMPT_REBOOT)
  742. {
  743. messageID = finishUninstallFailedMessageID;
  744. }
  745. }
  746. return String::load(messageID);
  747. }