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
595 lines
15 KiB
// Copyright (c) 2001 Microsoft Corporation
|
|
//
|
|
// File: AdminPackInstallationUnit.cpp
|
|
//
|
|
// Synopsis: Defines a AdminPackInstallationUnit
|
|
// This object has the knowledge for installing
|
|
// the Administration Tools Pack
|
|
//
|
|
// History: 06/01/2001 JeffJon Created
|
|
|
|
#include "pch.h"
|
|
#include "resource.h"
|
|
|
|
#include "InstallationUnitProvider.h"
|
|
#include "state.h"
|
|
|
|
// Define the GUIDs used by the Server Appliance Kit COM object
|
|
|
|
#include <initguid.h>
|
|
DEFINE_GUID(CLSID_SaInstall,0x142B8185,0x53AE,0x45B3,0x88,0x8F,0xC9,0x83,0x5B,0x15,0x6C,0xA9);
|
|
DEFINE_GUID(IID_ISaInstall,0xF4DEDEF3,0x4D83,0x4516,0xBC,0x1E,0x10,0x3A,0x63,0xF5,0xF0,0x14);
|
|
|
|
|
|
AdminPackInstallationUnit::AdminPackInstallationUnit() :
|
|
installAdminPack(false),
|
|
installWebAdmin(false),
|
|
installNASAdmin(false),
|
|
InstallationUnit(
|
|
IDS_ADMIN_PACK_TYPE,
|
|
IDS_ADMIN_PACK_DESCRIPTION,
|
|
IDS_PROGRESS_SUBTITLE,
|
|
IDS_FINISH_TITLE,
|
|
IDS_FINISH_MESSAGE,
|
|
L"",
|
|
L"",
|
|
ADMINPACK_SERVER)
|
|
{
|
|
LOG_CTOR(AdminPackInstallationUnit);
|
|
}
|
|
|
|
|
|
AdminPackInstallationUnit::~AdminPackInstallationUnit()
|
|
{
|
|
LOG_DTOR(AdminPackInstallationUnit);
|
|
}
|
|
|
|
|
|
InstallationReturnType
|
|
AdminPackInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::InstallService);
|
|
|
|
InstallationReturnType result = INSTALL_SUCCESS;
|
|
|
|
do
|
|
{
|
|
String computerName = State::GetInstance().GetComputerName();
|
|
|
|
if (GetInstallNASAdmin())
|
|
{
|
|
// First check to see if IIS is installed and
|
|
// install it if not
|
|
|
|
WebInstallationUnit& webInstallationUnit =
|
|
InstallationUnitProvider::GetInstance().GetWebInstallationUnit();
|
|
|
|
if (!webInstallationUnit.IsServiceInstalled())
|
|
{
|
|
webInstallationUnit.InstallService(logfileHandle, hwnd);
|
|
|
|
// Ignore the return value because the SAK installation
|
|
// portion will actually provide the best error message
|
|
}
|
|
|
|
String logText;
|
|
String errorMessage;
|
|
|
|
result = InstallNASAdmin(errorMessage);
|
|
if (result == INSTALL_FAILURE)
|
|
{
|
|
logText = String::format(
|
|
IDS_NAS_ADMIN_LOG_FAILED,
|
|
errorMessage.c_str());
|
|
}
|
|
else
|
|
{
|
|
if (errorMessage.empty())
|
|
{
|
|
logText = String::format(
|
|
IDS_NAS_ADMIN_LOG_SUCCESS,
|
|
computerName.c_str());
|
|
}
|
|
else
|
|
{
|
|
logText = String::format(
|
|
IDS_NAS_ADMIN_LOG_SUCCESS_WITH_MESSAGE,
|
|
errorMessage.c_str());
|
|
}
|
|
}
|
|
CYS_APPEND_LOG(logText);
|
|
|
|
}
|
|
|
|
if (GetInstallWebAdmin())
|
|
{
|
|
|
|
// First check to see if IIS is installed and
|
|
// install it if not
|
|
|
|
WebInstallationUnit& webInstallationUnit =
|
|
InstallationUnitProvider::GetInstance().GetWebInstallationUnit();
|
|
|
|
if (!webInstallationUnit.IsServiceInstalled())
|
|
{
|
|
webInstallationUnit.InstallService(logfileHandle, hwnd);
|
|
|
|
// Ignore the return value because the SAK installation
|
|
// portion will actually provide the best error message
|
|
}
|
|
|
|
String logText;
|
|
String errorMessage;
|
|
|
|
result = InstallWebAdmin(errorMessage);
|
|
if (result == INSTALL_FAILURE)
|
|
{
|
|
logText = String::format(
|
|
IDS_WEB_ADMIN_LOG_FAILED,
|
|
errorMessage.c_str());
|
|
}
|
|
else
|
|
{
|
|
logText = String::format(
|
|
IDS_WEB_ADMIN_LOG_SUCCESS,
|
|
computerName.c_str());
|
|
}
|
|
CYS_APPEND_LOG(logText);
|
|
}
|
|
|
|
if (GetInstallAdminPack())
|
|
{
|
|
InstallationReturnType adminPackResult = InstallAdminPack();
|
|
if (adminPackResult == INSTALL_FAILURE)
|
|
{
|
|
CYS_APPEND_LOG(String::load(IDS_ADMIN_PACK_LOG_FAILED));
|
|
result = adminPackResult;
|
|
}
|
|
else
|
|
{
|
|
CYS_APPEND_LOG(String::load(IDS_ADMIN_PACK_LOG_SUCCESS));
|
|
}
|
|
}
|
|
|
|
} while (false);
|
|
|
|
|
|
LOG_INSTALL_RETURN(result);
|
|
|
|
return result;
|
|
}
|
|
|
|
InstallationReturnType
|
|
AdminPackInstallationUnit::InstallSAKUnit(SA_TYPE unitType, String& errorMessage)
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::InstallSAKUnit);
|
|
|
|
InstallationReturnType result = INSTALL_SUCCESS;
|
|
|
|
errorMessage.erase();
|
|
|
|
do
|
|
{
|
|
Win::WaitCursor wait;
|
|
|
|
// Check to make sure we are not on 64bit
|
|
|
|
if (State::GetInstance().Is64Bit())
|
|
{
|
|
ASSERT(!State::GetInstance().Is64Bit());
|
|
|
|
result = INSTALL_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Get the name of the source location of the install files
|
|
|
|
String installLocation;
|
|
DWORD productSKU = State::GetInstance().GetProductSKU();
|
|
|
|
if (productSKU & CYS_SERVER)
|
|
{
|
|
installLocation = String::load(IDS_SERVER_CD);
|
|
}
|
|
else if (productSKU & CYS_ADVANCED_SERVER)
|
|
{
|
|
installLocation = String::load(IDS_ADVANCED_SERVER_CD);
|
|
}
|
|
else if (productSKU & CYS_DATACENTER_SERVER)
|
|
{
|
|
installLocation = String::load(IDS_DATACENTER_SERVER_CD);
|
|
}
|
|
else
|
|
{
|
|
installLocation = String::load(IDS_WINDOWS_CD);
|
|
}
|
|
|
|
// Get the Server Appliance COM object
|
|
|
|
SmartInterface<ISaInstall> sakInstall;
|
|
|
|
HRESULT hr = GetSAKObject(sakInstall);
|
|
if (FAILED(hr))
|
|
{
|
|
// We failed the CoCreate on the SAK (Server Appliance Kit) COM object
|
|
// Can't do anything without that!
|
|
|
|
LOG(String::format(
|
|
L"Failed to create the SAK (Server Appliance Kit) COM object: hr = 0x%1!x!",
|
|
hr));
|
|
|
|
result = INSTALL_FAILURE;
|
|
break;
|
|
}
|
|
|
|
VARIANT_BOOL displayError = false;
|
|
VARIANT_BOOL unattended = false;
|
|
BSTR tempMessage = 0;
|
|
hr = sakInstall->SAInstall(
|
|
unitType,
|
|
const_cast<WCHAR*>(installLocation.c_str()),
|
|
displayError,
|
|
unattended,
|
|
&tempMessage);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
LOG(String::format(
|
|
L"Failed to install the SAK unit: hr = 0x%1!x!",
|
|
hr));
|
|
|
|
if (tempMessage)
|
|
{
|
|
errorMessage = tempMessage;
|
|
::SysFreeString(tempMessage);
|
|
}
|
|
|
|
result = INSTALL_FAILURE;
|
|
break;
|
|
}
|
|
|
|
} while (false);
|
|
|
|
LOG_INSTALL_RETURN(result);
|
|
return result;
|
|
}
|
|
|
|
InstallationReturnType
|
|
AdminPackInstallationUnit::InstallNASAdmin(String& errorMessage)
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::InstallNASAdmin);
|
|
|
|
InstallationReturnType result = InstallSAKUnit(NAS, errorMessage);
|
|
|
|
LOG_INSTALL_RETURN(result);
|
|
return result;
|
|
}
|
|
|
|
InstallationReturnType
|
|
AdminPackInstallationUnit::InstallWebAdmin(String& errorMessage)
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::InstallWebAdmin);
|
|
|
|
InstallationReturnType result = InstallSAKUnit(WEB, errorMessage );
|
|
|
|
LOG_INSTALL_RETURN(result);
|
|
return result;
|
|
}
|
|
|
|
InstallationReturnType
|
|
AdminPackInstallationUnit::InstallAdminPack()
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::InstallAdminPack);
|
|
|
|
InstallationReturnType result = INSTALL_SUCCESS;
|
|
|
|
do
|
|
{
|
|
Win::WaitCursor wait;
|
|
|
|
// The Admin Tools Pack msi file is located in the %windir%\system32
|
|
// directory on all x86 Server SKUs
|
|
// The "/i" parameter means install, the "/qn" means quite mode/no UI
|
|
|
|
String sysFolder = Win::GetSystemDirectory();
|
|
String adminpakPath = sysFolder + L"\\msiexec.exe /i " + sysFolder + L"\\adminpak.msi /qn";
|
|
|
|
DWORD exitCode = 0;
|
|
HRESULT hr = CreateAndWaitForProcess(adminpakPath, exitCode, true);
|
|
if (FAILED(hr))
|
|
{
|
|
LOG(String::format(
|
|
L"Failed to launch Admin Pack install: hr = 0x%1!x!",
|
|
hr));
|
|
|
|
result = INSTALL_FAILURE;
|
|
break;
|
|
}
|
|
|
|
if (exitCode != 0)
|
|
{
|
|
LOG(String::format(
|
|
L"Failed to install Admin Tools Pack: exitCode = 0x%1!x!",
|
|
exitCode));
|
|
|
|
result = INSTALL_FAILURE;
|
|
break;
|
|
}
|
|
|
|
LOG(String::format(
|
|
L"Admin Pack returned with exitCode = 0x%1!x!",
|
|
exitCode));
|
|
|
|
} while (false);
|
|
|
|
LOG_INSTALL_RETURN(result);
|
|
return result;
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::IsServiceInstalled()
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::IsServiceInstalled);
|
|
|
|
bool result = false;
|
|
|
|
// This should never be called...
|
|
// The caller should be checking each individual
|
|
// tools package instead. For instance, GetAdminPackInstall(),
|
|
// GetNASAdminInstall(), or GetWebAdminInstall()
|
|
|
|
ASSERT(false);
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
String
|
|
AdminPackInstallationUnit::GetServiceDescription()
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::GetServiceDescription);
|
|
|
|
// this should never be called. AdminPack isn't a
|
|
// server role
|
|
|
|
ASSERT(false);
|
|
return L"";
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::GetMilestoneText(String& message)
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::GetMilestoneText);
|
|
|
|
bool result = false;
|
|
|
|
if (GetInstallWebAdmin())
|
|
{
|
|
|
|
message += String::load(IDS_WEB_ADMIN_FINISH_TEXT);
|
|
result = true;
|
|
}
|
|
|
|
if (GetInstallNASAdmin())
|
|
{
|
|
message += String::load(IDS_NAS_ADMIN_FINISH_TEXT);
|
|
|
|
// If IIS isn't installed, add the text from the WebInstallationUnit
|
|
|
|
WebInstallationUnit& webInstallationUnit =
|
|
InstallationUnitProvider::GetInstance().GetWebInstallationUnit();
|
|
|
|
if (!webInstallationUnit.IsServiceInstalled())
|
|
{
|
|
webInstallationUnit.GetMilestoneText(message);
|
|
}
|
|
result = true;
|
|
}
|
|
|
|
if (GetInstallAdminPack())
|
|
{
|
|
message += String::load(IDS_ADMIN_PACK_FINISH_TEXT);
|
|
result = true;
|
|
}
|
|
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::IsAdminPackInstalled()
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::IsAdminPackInstalled);
|
|
|
|
// Admin Tools Pack is no longer allowing itself to be installed
|
|
// on server builds. By returning true here the UI will always
|
|
// think its already install and never give the option.
|
|
// NTRAID#NTBUG9-448167-2001/07/31-jeffjon
|
|
|
|
bool result = true;
|
|
/*
|
|
bool result = false;
|
|
|
|
// Admin Tools Pack is installed if the registry key for
|
|
// uninstalling is present
|
|
|
|
RegistryKey key;
|
|
HRESULT hr = key.Open(
|
|
HKEY_LOCAL_MACHINE,
|
|
CYS_ADMINPAK_SERVERED_REGKEY,
|
|
KEY_READ);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
LOG(L"The Admin Pack uninstall key exists");
|
|
result = true;
|
|
}
|
|
else
|
|
{
|
|
LOG(String::format(
|
|
L"Failed to open Admin Pack uninstall key: hr = 0x%1!x!",
|
|
hr));
|
|
}
|
|
*/
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
void
|
|
AdminPackInstallationUnit::SetInstallAdminPack(bool install)
|
|
{
|
|
LOG_FUNCTION2(
|
|
AdminPackInstallationUnit::SetInstallAdminPack,
|
|
install ? L"true" : L"false");
|
|
|
|
installAdminPack = install;
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::GetInstallAdminPack() const
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::GetInstallAdminPack);
|
|
|
|
bool result = installAdminPack;
|
|
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::IsWebAdminInstalled()
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::IsWebAdminInstalled);
|
|
|
|
bool result = IsSAKUnitInstalled(WEB);
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
void
|
|
AdminPackInstallationUnit::SetInstallWebAdmin(bool install)
|
|
{
|
|
LOG_FUNCTION2(
|
|
AdminPackInstallationUnit::SetInstallWebAdmin,
|
|
install ? L"true" : L"false");
|
|
|
|
installWebAdmin = install;
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::GetInstallWebAdmin() const
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::GetInstallWebAdmin);
|
|
|
|
bool result = installWebAdmin;
|
|
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::IsNASAdminInstalled()
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::IsNASAdminInstalled);
|
|
|
|
bool result = IsSAKUnitInstalled(NAS);
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::IsSAKUnitInstalled(SA_TYPE unitType)
|
|
{
|
|
LOG_FUNCTION2(
|
|
AdminPackInstallationUnit::IsSAKUnitInstalled,
|
|
String::format(L"type = %1!d!", (int) unitType));
|
|
|
|
bool result = true;
|
|
|
|
do
|
|
{
|
|
// Check to make sure we are not on 64bit
|
|
|
|
if (State::GetInstance().Is64Bit())
|
|
{
|
|
result = false;
|
|
break;
|
|
}
|
|
|
|
// Get the Server Appliance Kit COM object
|
|
|
|
SmartInterface<ISaInstall> sakInstall;
|
|
HRESULT hr = GetSAKObject(sakInstall);
|
|
if (FAILED(hr))
|
|
{
|
|
LOG(String::format(
|
|
L"Failed to get the SAK COM object: hr = 0x%1!x!",
|
|
hr));
|
|
|
|
break;
|
|
}
|
|
|
|
// Check to see if NAS is already installed
|
|
|
|
VARIANT_BOOL saInstalled;
|
|
hr = sakInstall->SAAlreadyInstalled(unitType, &saInstalled);
|
|
if (FAILED(hr))
|
|
{
|
|
LOG(String::format(
|
|
L"Failed call to SAAlreadyInstalled: hr = 0x%1!x!",
|
|
hr));
|
|
break;
|
|
}
|
|
|
|
if (!saInstalled)
|
|
{
|
|
result = false;
|
|
}
|
|
|
|
} while (false);
|
|
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
void
|
|
AdminPackInstallationUnit::SetInstallNASAdmin(bool install)
|
|
{
|
|
LOG_FUNCTION2(
|
|
AdminPackInstallationUnit::SetInstallNASAdmin,
|
|
install ? L"true" : L"false");
|
|
|
|
installNASAdmin = install;
|
|
}
|
|
|
|
bool
|
|
AdminPackInstallationUnit::GetInstallNASAdmin() const
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::GetInstallNASAdmin);
|
|
|
|
bool result = installNASAdmin;
|
|
|
|
LOG_BOOL(result);
|
|
return result;
|
|
}
|
|
|
|
HRESULT
|
|
AdminPackInstallationUnit::GetSAKObject(SmartInterface<ISaInstall>& sakInstall)
|
|
{
|
|
LOG_FUNCTION(AdminPackInstallationUnit::GetSAKObject);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!sakInstallObject)
|
|
{
|
|
hr = sakInstallObject.AcquireViaCreateInstance(
|
|
CLSID_SaInstall,
|
|
0,
|
|
CLSCTX_INPROC_SERVER);
|
|
}
|
|
|
|
ASSERT(sakInstallObject);
|
|
sakInstall = sakInstallObject;
|
|
|
|
LOG_HRESULT(hr);
|
|
return hr;
|
|
}
|