// Copyright (c) 1997-2001 Microsoft Corporation // // File: DHCPInstallationUnit.cpp // // Synopsis: Defines a DHCPInstallationUnit // This object has the knowledge for installing the // DHCP service // // History: 02/05/2001 JeffJon Created #include "pch.h" #include "resource.h" #include "DHCPInstallationUnit.h" #include "InstallationUnitProvider.h" DHCPInstallationUnit::DHCPInstallationUnit() : isExpressPathInstall(false), startIPAddress(0), endIPAddress(0), NetworkServiceInstallationBase( IDS_DHCP_SERVER_TYPE, IDS_DHCP_SERVER_DESCRIPTION, IDS_DHCP_SERVER_DESCRIPTION_INSTALLED, DHCP_INSTALL) { LOG_CTOR(DHCPInstallationUnit); } DHCPInstallationUnit::~DHCPInstallationUnit() { LOG_DTOR(DHCPInstallationUnit); } InstallationReturnType DHCPInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd) { LOG_FUNCTION(DHCPInstallationUnit::InstallService); InstallationReturnType result = INSTALL_SUCCESS; if (IsExpressPathInstall()) { // This is an express path install. It must be done special result = ExpressPathInstall(logfileHandle, hwnd); LOG_INSTALL_RETURN(result); return result; } String infFileText; String unattendFileText; CreateInfFileText(infFileText, IDS_DHCP_INF_WINDOW_TITLE); CreateUnattendFileText(unattendFileText, CYS_DHCP_SERVICE_NAME); bool ocmResult = InstallServiceWithOcManager(infFileText, unattendFileText); if (ocmResult && IsServiceInstalled()) { // Log the successful installation LOG(L"DHCP was installed successfully"); CYS_APPEND_LOG(String::load(IDS_LOG_INSTALL_START_DHCP)); // Run the DHCP Wizard String resultText; if (ExecuteWizard(CYS_DHCP_SERVICE_NAME, resultText)) { // Check to be sure the wizard finished completely String configWizardResults; if (IsDhcpConfigured()) { // The New Scope Wizard completed successfully LOG(L"DHCP installed and the New Scope Wizard completed successfully"); CYS_APPEND_LOG(String::load(IDS_LOG_DHCP_COMPLETED_SUCCESSFULLY)); } else { // The New Scope Wizard did not finish successfully LOG(L"DHCP installed successfully, but a problem occurred during the New Scope Wizard"); CYS_APPEND_LOG(String::load(IDS_LOG_DHCP_WIZARD_ERROR)); } } else { // Log an error LOG(L"DHCP could not be installed."); if (!resultText.empty()) { CYS_APPEND_LOG(resultText); } } } else { // Log the failure LOG(L"DHCP failed to install"); CYS_APPEND_LOG(String::load(IDS_LOG_DHCP_INSTALL_FAILED)); result = INSTALL_FAILURE; } LOG_INSTALL_RETURN(result); return result; } InstallationReturnType DHCPInstallationUnit::ExpressPathInstall(HANDLE /*logfileHandle*/, HWND /*hwnd*/) { LOG_FUNCTION(DHCPInstallationUnit::ExpressPathInstall); InstallationReturnType result = INSTALL_SUCCESS; String infFileText; String unattendFileText; String commandline; CreateInfFileText(infFileText, IDS_DHCP_INF_WINDOW_TITLE); CreateUnattendFileTextForExpressPath(unattendFileText); do { bool ocmResult = InstallServiceWithOcManager(infFileText, unattendFileText); if (ocmResult && !IsServiceInstalled()) { result = INSTALL_FAILURE; LOG(L"DHCP installation failed"); break; } else { HRESULT hr = S_OK; DWORD exitCode = 0; String ipaddressString = InstallationUnitProvider::GetInstance().GetDNSInstallationUnit().GetStaticIPAddressString(); String subnetMaskString = InstallationUnitProvider::GetInstance().GetDNSInstallationUnit().GetSubnetMaskString(); do { commandline = L"netsh dhcp server add optiondef 6 \"DNS Servers\" IPADDRESS 1"; hr = CreateAndWaitForProcess(commandline, exitCode); if (FAILED(hr)) { LOG(String::format( L"Failed to run DHCP options: hr = %1!x!", hr)); break; } if (exitCode != 1) { LOG(String::format( L"Failed to run DHCP options: exitCode = %1!x!", exitCode)); break; } commandline.format( L"netsh dhcp server set optionvalue 6 IPADDRESS %1", ipaddressString); exitCode = 0; hr = CreateAndWaitForProcess(commandline, exitCode); if (FAILED(hr)) { LOG(String::format( L"Failed to run DHCP server IP address: hr = %1!x!", hr)); break; } if (exitCode != 1) { LOG(String::format( L"Failed to run DHCP server IP address: exitCode = %1!x!", exitCode)); break; } } while (false); // Set the subnet mask DWORD staticipaddress = InstallationUnitProvider::GetInstance().GetDNSInstallationUnit().GetStaticIPAddress(); DWORD subnetMask = InstallationUnitProvider::GetInstance().GetDNSInstallationUnit().GetSubnetMask(); DWORD subnet = staticipaddress & subnetMask; String subnetString = String::format( L"%1!d!.%2!d!.%3!d!.%4!d!", FIRST_IPADDRESS(subnet), SECOND_IPADDRESS(subnet), THIRD_IPADDRESS(subnet), FOURTH_IPADDRESS(subnet)); commandline.format( L"netsh dhcp server 127.0.0.1 add scope %1 %2 Scope1", subnetString.c_str(), subnetMaskString.c_str()); exitCode = 0; hr = CreateAndWaitForProcess(commandline, exitCode); if (FAILED(hr)) { LOG(String::format( L"Failed to set DHCP address and subnet: hr = %1!x!", hr)); break; } if (exitCode != 1) { LOG(String::format( L"Failed to set DHCP address and subnet: exitCode = %1!x!", exitCode)); break; } // Set the DHCP scopes commandline.format( L"netsh dhcp server 127.0.0.1 add scope %1 add iprange %2 %3 both", subnetString.c_str(), GetStartIPAddressString().c_str(), GetEndIPAddressString().c_str()); exitCode = 0; hr = CreateAndWaitForProcess(commandline, exitCode); if (FAILED(hr)) { LOG(String::format( L"Failed to set DHCP scopes: hr = %1!x!", hr)); break; } if (exitCode != 1) { LOG(String::format( L"Failed to set DHCP scopes: exitCode = %1!x!", exitCode)); break; } // Set the DHCP scope lease time commandline = L"netsh dhcp server 127.0.0.1 add optiondef 51 LeaseTime DWORD"; exitCode = 0; hr = CreateAndWaitForProcess(commandline, exitCode); if (FAILED(hr)) { LOG(String::format( L"Failed to set DHCP scope lease time: hr = %1!x!", hr)); break; } if (exitCode != 1) { LOG(String::format( L"Failed to set DHCP scope lease time: exitCode = %1!x!", exitCode)); break; } // Set the DHCP scope lease time value commandline.format( L"netsh dhcp server 127.0.0.1 scope %1 set optionvalue 51 dword 874800", subnetString.c_str()); exitCode = 0; hr = CreateAndWaitForProcess(commandline, exitCode); if (FAILED(hr)) { LOG(String::format( L"Failed to set DHCP scope lease time value: hr = %1!x!", hr)); break; } if (exitCode != 1) { LOG(String::format( L"Failed to set DHCP scope lease time value: exitCode = %1!x!", exitCode)); break; } } } while (false); LOG_INSTALL_RETURN(result); return result; } void DHCPInstallationUnit::CreateUnattendFileTextForExpressPath( String& unattendFileText) { LOG_FUNCTION(DHCPInstallationUnit::CreateUnattendFileText); unattendFileText = L"[NetOptionalComponents]\n"; unattendFileText += L"DHCPServer=1\n"; unattendFileText += L"[dhcpserver]\n"; unattendFileText += L"Subnets=192.168.16.2\n"; // Add the DHCP scope unattendFileText += L"StartIP="; unattendFileText += GetStartIPAddressString(); unattendFileText += L"EndIp="; unattendFileText += GetEndIPAddressString(); // Add subnet mask unattendFileText += L"SubnetMask=255.255.255.0\n"; unattendFileText += L"LeaseDuration=874800\n"; // The DNS server IP String dnsIPString = InstallationUnitProvider::GetInstance().GetDNSInstallationUnit().GetStaticIPAddressString(); unattendFileText += String::format( L"DnsServer=%1", dnsIPString.c_str()); // The domain name unattendFileText += String::format( L"DomainName=%1\n", InstallationUnitProvider::GetInstance().GetADInstallationUnit().GetNewDomainDNSName()); } bool DHCPInstallationUnit::IsServiceInstalled() { LOG_FUNCTION(DHCPInstallationUnit::IsServiceInstalled); bool result = IsServiceInstalledHelper(CYS_DHCP_SERVICE_NAME); LOG_BOOL(result); return result; } bool DHCPInstallationUnit::IsConfigured() { LOG_FUNCTION(DHCPInstallationUnit::IsConfigured); return IsDhcpConfigured(); } bool DHCPInstallationUnit::GetFinishText(String& message) { LOG_FUNCTION(DHCPInstallationUnit::GetFinishText); if (IsExpressPathInstall()) { } else { message = String::load(IDS_DHCP_FINISH_TEXT); } LOG_BOOL(true); return true; } bool DHCPInstallationUnit::AuthorizeDHCPScope(const String& dnsName) const { LOG_FUNCTION(DHCPInstallationUnit::AuthorizeDHCPScope); bool result = true; do { String domainDNSIP; result = GetRegKeyValue( CYS_DHCP_DOMAIN_IP_REGKEY, CYS_DHCP_DOMAIN_IP_VALUE, domainDNSIP); if (!result) { LOG(L"Failed to read domain DNS IP from registry"); break; } // Authorize the DHCP scope String commandline; commandline = L"netsh dhcp add server "; commandline += dnsName; commandline += L" "; commandline += domainDNSIP; DWORD exitCode = 0; HRESULT hr = CreateAndWaitForProcess(commandline, exitCode); if (FAILED(hr)) { LOG(String::format( L"Failed to run DHCP authorization: hr = %1!x!", hr)); result = false; break; } if (exitCode != 1) { result = false; break; } } while (false); LOG_BOOL(result); return result; } void DHCPInstallationUnit::SetExpressPathInstall(bool isExpressPath) { LOG_FUNCTION2( DHCPInstallationUnit::SetExpressPathInstall, (isExpressPath) ? L"true" : L"false"); isExpressPathInstall = isExpressPath; } bool DHCPInstallationUnit::IsExpressPathInstall() const { LOG_FUNCTION(DHCPInstallationUnit::IsExpressPathInstall); return isExpressPathInstall; } void DHCPInstallationUnit::SetStartIPAddress(DWORD ipaddress) { LOG_FUNCTION2( DHCPInstallationUnit::SetStartIPAddress, String::format(L"0x%1!x!", ipaddress)); startIPAddress = ipaddress; } void DHCPInstallationUnit::SetEndIPAddress(DWORD ipaddress) { LOG_FUNCTION2( DHCPInstallationUnit::SetEndIPAddress, String::format(L"0x%1!x!", ipaddress)); endIPAddress = ipaddress; } String DHCPInstallationUnit::GetStartIPAddressString() const { LOG_FUNCTION(DHCPInstallationUnit::GetStartIPAddressString); String result = String::format( L"%1!d!.%2!d!.%3!d!.%4!d!", FIRST_IPADDRESS(startIPAddress), SECOND_IPADDRESS(startIPAddress), THIRD_IPADDRESS(startIPAddress), FOURTH_IPADDRESS(startIPAddress)); LOG(result); return result; } String DHCPInstallationUnit::GetEndIPAddressString() const { LOG_FUNCTION(DHCPInstallationUnit::GetEndIPAddressString); String result = String::format( L"%1!d!.%2!d!.%3!d!.%4!d!", FIRST_IPADDRESS(endIPAddress), SECOND_IPADDRESS(endIPAddress), THIRD_IPADDRESS(endIPAddress), FOURTH_IPADDRESS(endIPAddress)); LOG(result); return result; }