|
|
// Copyright (c) 1997-2001 Microsoft Corporation
//
// File: DNSInstallationUnit.cpp
//
// Synopsis: Defines a DNSInstallationUnit
// This object has the knowledge for installing the
// DNS service
//
// History: 02/05/2001 JeffJon Created
#include "pch.h"
#include "resource.h"
#include "DNSInstallationUnit.h"
DNSInstallationUnit::DNSInstallationUnit() : isExpressPathInstall(false), staticIPAddress(0), subnetMask(0), NetworkServiceInstallationBase( IDS_DNS_SERVER_TYPE, IDS_DNS_SERVER_DESCRIPTION, IDS_DNS_SERVER_DESCRIPTION_INSTALLED, DNS_INSTALL) { LOG_CTOR(DNSInstallationUnit); }
DNSInstallationUnit::~DNSInstallationUnit() { LOG_DTOR(DNSInstallationUnit); }
InstallationReturnType DNSInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd) { LOG_FUNCTION(DNSInstallationUnit::InstallService);
InstallationReturnType result = INSTALL_SUCCESS;
if (IsExpressPathInstall()) { result = ExpressPathInstall(logfileHandle, hwnd);
LOG_INSTALL_RETURN(result); return result; }
// Create the inf and unattend files that are used by the
// Optional Component Manager
String infFileText; String unattendFileText;
CreateInfFileText(infFileText, IDS_DNS_INF_WINDOW_TITLE); CreateUnattendFileText(unattendFileText, CYS_DNS_SERVICE_NAME);
// Install the service through the Optional Component Manager
bool ocmResult = InstallServiceWithOcManager(infFileText, unattendFileText); if (ocmResult && IsServiceInstalled()) { // Log the successful installation
LOG(L"DNS was installed successfully"); CYS_APPEND_LOG(String::load(IDS_LOG_INSTALL_START_DNS));
// Run the DNS Wizard
String resultText;
if (ExecuteWizard(CYS_DNS_SERVICE_NAME, resultText)) { // Check to be sure the wizard finished completely
String configWizardResults;
if (ReadConfigWizardRegkeys(configWizardResults)) { // The Configure DNS Server Wizard completed successfully
LOG(L"The Configure DNS Server Wizard completed successfully"); CYS_APPEND_LOG(String::load(IDS_LOG_DNS_COMPLETED_SUCCESSFULLY)); } else { // The Configure DNS Server Wizard did not finish successfully
if (!configWizardResults.empty()) { // An error was returned via the regkey
LOG(String::format( L"The Configure DNS Server Wizard returned the error: %1", configWizardResults.c_str()));
String formatString = String::load(IDS_LOG_DNS_WIZARD_ERROR); CYS_APPEND_LOG(String::format(formatString, configWizardResults.c_str()));
} else { // The Configure DNS Server Wizard was cancelled by the user
LOG(L"The Configure DNS Server Wizard was cancelled by the user");
CYS_APPEND_LOG(String::load(IDS_LOG_DNS_WIZARD_CANCELLED)); } } } else { // Show an error
LOG(L"DNS could not be installed.");
if (!resultText.empty()) { CYS_APPEND_LOG(resultText); } } } else { // Log the failure
LOG(L"DNS failed to install");
CYS_APPEND_LOG(String::load(IDS_LOG_DNS_INSTALL_FAILED));
result = INSTALL_FAILURE; }
LOG_INSTALL_RETURN(result);
return result; }
InstallationReturnType DNSInstallationUnit::ExpressPathInstall(HANDLE /*logfileHandle*/, HWND /*hwnd*/) { LOG_FUNCTION(DNSInstallationUnit::ExpressPathInstall);
InstallationReturnType result = INSTALL_SUCCESS;
// Set the static IP address and the subnet mask
// invoke netsh and wait for it to terminate
String friendlyName = GetTcpIpInterfaceFriendlyName();
do { // set static IP address and subnet mask
String commandLine = String::format( L"netsh interface ip set address " L"name=\"%1\" source=static addr=%2 mask=%3 gateway=none", friendlyName.c_str(), GetStaticIPAddressString().c_str(), GetSubnetMaskString().c_str());
DWORD exitCode1 = 0; HRESULT hr = ::CreateAndWaitForProcess(commandLine, exitCode1); if (FAILED(hr) || exitCode1) { LOG(String::format( L"Failed to set the static IP address and subnet mask: exitCode = %1!x!", exitCode1)); result = INSTALL_FAILURE; break; } ASSERT(SUCCEEDED(hr));
// set DNS server address to same address as local machine. netsh
// does not allow the dns server address to be the loopback address.
commandLine = String::format( L"netsh interface ip set dns name=\"%1\" source=static addr=%2", friendlyName.c_str(), GetStaticIPAddressString().c_str());
DWORD exitCode2 = 0; hr = ::CreateAndWaitForProcess(commandLine, exitCode2); if (FAILED(hr) || exitCode2) { LOG(String::format( L"Failed to set the preferred DNS server IP address: exitCode = %1!x!", exitCode2)); result = INSTALL_FAILURE; break; }
} while (false);
LOG_INSTALL_RETURN(result);
return result; }
// get guid name of the first tcp/ip interface we enum
HRESULT DNSInstallationUnit::GetTcpIpInterfaceGuidName(String& result) { LOG_FUNCTION(DNSInstallationUnit::GetTcpIpInterfaceGuidName);
result.erase();
DWORD dwError = 0; ULONG ulSize = 0; PIP_INTERFACE_INFO pInfo = NULL; HRESULT hr = S_OK;
while ( 1 ) { dwError = ::GetInterfaceInfo( pInfo, &ulSize ); if ( ERROR_INSUFFICIENT_BUFFER != dwError ) { break; }
if ( NULL != pInfo ) { Win::LocalFree(pInfo); } if ( 0 == ulSize ) { hr = E_FAIL; LOG_HRESULT(hr); return hr; }
pInfo = (PIP_INTERFACE_INFO) ::LocalAlloc(LPTR, ulSize); if ( NULL == pInfo ) { hr = E_OUTOFMEMORY; LOG_HRESULT(hr); return hr; } }
if ( ERROR_SUCCESS != dwError || 0 == pInfo->NumAdapters ) { if ( NULL != pInfo ) { Win::LocalFree(pInfo); } hr = E_FAIL; LOG_HRESULT(hr); return hr; }
// Skip the adapter prefix
result = pInfo->Adapter[0].Name + strlen("\\Device\\Tcpip_"),
// CODEWORK could do this with IIDFromString
// // // // check whether this is a valid GUID
// // //
// // // SHUnicodeToTChar(wszGuidName, szGuid, ARRAYSIZE(szGuid));
// // // if (!GUIDFromString(szGuid, &guid))
// // // {
// // // // we failed to get a valid tcp/ip interface
// // // *wszGuidName = 0;
// // // Win::LocalFree(pInfo);
// // // return E_FAIL;
// // // }
LocalFree(pInfo);
LOG(result);
return S_OK; }
// get friendly name of the first tcp/ip interface we enum
String DNSInstallationUnit::GetTcpIpInterfaceFriendlyName() { LOG_FUNCTION(DNSInstallationUnit::GetTcpIpInterfaceFriendlyName);
DWORD dwRet = 0; HANDLE hMprConfig = 0;
static const unsigned friendlyNameLength = 128; wchar_t wszFriendlyName[friendlyNameLength]; ZeroMemory(wszFriendlyName, sizeof(wchar_t) * friendlyNameLength);
String result;
String guidName; HRESULT hr = GetTcpIpInterfaceGuidName(guidName); if (SUCCEEDED(hr)) { dwRet = MprConfigServerConnect(0, &hMprConfig); if (NO_ERROR == dwRet) { dwRet = MprConfigGetFriendlyName( hMprConfig, const_cast<wchar_t*>(guidName.c_str()), wszFriendlyName, sizeof(wchar_t) * friendlyNameLength); if (NO_ERROR != dwRet) { LOG(String::format( L"MprConfigGetFriendlyName() failed: error = %1!x!", dwRet)); *wszFriendlyName = 0; } } else { LOG(String::format( L"MprConfigServerConnect() failed: error = %1!x!", dwRet)); }
MprConfigServerDisconnect(hMprConfig); }
if (!*wszFriendlyName) { // we failed to get a friendly name, so use the default one
// BUGBUG does this need to be localized?
result = L"Local Area Connection"; } else { result = wszFriendlyName; }
LOG(result);
return result; }
bool DNSInstallationUnit::ReadConfigWizardRegkeys(String& configWizardResults) const { LOG_FUNCTION(DNSInstallationUnit::ReadConfigWizardRegkeys);
bool result = true;
do { DWORD value = 0; result = GetRegKeyValue( DNS_WIZARD_CONFIG_REGKEY, DNS_WIZARD_CONFIG_VALUE, value);
if (result && value != 0) { // The Configure DNS Server Wizard succeeded
result = true; break; }
// Since there was a failure (or the wizard was cancelled)
// get the display string to log
result = GetRegKeyValue( DNS_WIZARD_RESULT_REGKEY, DNS_WIZARD_RESULT_VALUE, configWizardResults);
} while (false);
LOG_BOOL(result);
return result; }
bool DNSInstallationUnit::IsServiceInstalled() { LOG_FUNCTION(DNSInstallationUnit::IsServiceInstalled);
bool result = IsServiceInstalledHelper(CYS_DNS_SERVICE_NAME);
LOG_BOOL(result); return result; }
bool DNSInstallationUnit::GetFinishText(String& message) { LOG_FUNCTION(DNSInstallationUnit::GetFinishText);
message = String::load(IDS_DNS_FINISH_TEXT);
LOG_BOOL(true); return true; }
void DNSInstallationUnit::SetExpressPathInstall(bool isExpressPath) { LOG_FUNCTION2( DNSInstallationUnit::SetExpressPathInstall, (isExpressPath) ? L"true" : L"false");
isExpressPathInstall = isExpressPath; }
bool DNSInstallationUnit::IsExpressPathInstall() const { LOG_FUNCTION(DNSInstallationUnit::IsExpressPathInstall);
return isExpressPathInstall; }
void DNSInstallationUnit::SetStaticIPAddress(DWORD ipaddress) { LOG_FUNCTION2( DNSInstallationUnit::SetStaticIPAddress, String::format( L"%1!d!.%2!d!.%3!d!.%4!d!", FIRST_IPADDRESS(ipaddress), SECOND_IPADDRESS(ipaddress), THIRD_IPADDRESS(ipaddress), FOURTH_IPADDRESS(ipaddress)));
staticIPAddress = ipaddress; }
void DNSInstallationUnit::SetSubnetMask(DWORD mask) { LOG_FUNCTION2( DNSInstallationUnit::SetSubnetMask, String::format( L"%1!d!.%2!d!.%3!d!.%4!d!", FIRST_IPADDRESS(mask), SECOND_IPADDRESS(mask), THIRD_IPADDRESS(mask), FOURTH_IPADDRESS(mask)));
subnetMask = mask; }
String DNSInstallationUnit::GetStaticIPAddressString() const { LOG_FUNCTION(DNSInstallationUnit::GetStaticIPAddressString);
String result = String::format( L"%1!d!.%2!d!.%3!d!.%4!d!", FIRST_IPADDRESS(staticIPAddress), SECOND_IPADDRESS(staticIPAddress), THIRD_IPADDRESS(staticIPAddress), FOURTH_IPADDRESS(staticIPAddress));
LOG(result); return result; }
String DNSInstallationUnit::GetSubnetMaskString() const { LOG_FUNCTION(DNSInstallationUnit::GetSubnetMaskString);
String result = String::format( L"%1!d!.%2!d!.%3!d!.%4!d!", FIRST_IPADDRESS(subnetMask), SECOND_IPADDRESS(subnetMask), THIRD_IPADDRESS(subnetMask), FOURTH_IPADDRESS(subnetMask));
LOG(result); return result; }
|