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.
391 lines
12 KiB
391 lines
12 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2001 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// SaInstall.cpp : Implementation of SaInstall
|
|
//
|
|
// Description:
|
|
// Implements the 3 methods in ISaInstall to provide
|
|
// installation and uninstallation of the SAK 2.0.
|
|
// SASetup.msi is located and run from the system32 directory.
|
|
//
|
|
// Documentation:
|
|
// SaInstall2.2.doc
|
|
//
|
|
// Header File:
|
|
// SaInstall.h
|
|
//
|
|
// History:
|
|
// travisn 23-JUL-2001 Created
|
|
// travisn 2-AUG-2001 Modified to better follow coding standards
|
|
// travisn 22-AUG-2001 Added file tracing calls
|
|
// travisn 5-OCT-2001 Added UsersAndGroups to Blade
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include <initguid.h>
|
|
#include <assert.h>
|
|
|
|
#include "sainstallcom.h"
|
|
#include "SaInstall.h"
|
|
#include "MetabaseObject.h"
|
|
#include "helper.h"
|
|
#include "satrace.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Define constants
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Command line options for a silent install, prepended to other options
|
|
//
|
|
const LPCWSTR MSIEXEC_INSTALL = L"msiexec.exe /qb /i ";
|
|
|
|
//
|
|
// Command line options for a silent install without a progress dialog
|
|
//
|
|
const LPCWSTR MSIEXEC_NO_PROGRESS_INSTALL = L"msiexec.exe /qn /i ";
|
|
|
|
//
|
|
// Install 16 components for WEB
|
|
// What WEB has that NAS doesn't: WebBlade
|
|
//
|
|
const LPCWSTR WEB_INSTALL_OPTIONS =
|
|
L" ADDLOCAL=BackEndFramework,WebUI,WebCore,SetDateAndTime,Set_Language,\
|
|
NetworkSetup,Logs,AlertEmail,Shutdown,\
|
|
UsersAndGroups,RemoteDesktop,SysInfo,WebBlade";
|
|
|
|
//
|
|
// Other command line options
|
|
//
|
|
const LPCWSTR REMOVE_ALL = L"msiexec /qn /X";
|
|
|
|
//Path to IIS in the metabase
|
|
const LPCWSTR METABASE_IIS_PATH = L"LM/w3svc";
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SaInstall::SAAlreadyInstalled
|
|
//
|
|
// Description:
|
|
// Detects if a type of Server Appliance is installed.
|
|
//
|
|
// Arguments:
|
|
// [in] SA_TYPE: The type of SA to query (NAS or WEB)
|
|
// [OUT] VARIANT_BOOL: Whether this type of SA is installed
|
|
//
|
|
// Returns:
|
|
// HRESULT
|
|
//
|
|
// history:
|
|
// travisn Created 23-JUL-2001
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP SaInstall::SAAlreadyInstalled(
|
|
const SA_TYPE installedType, //[in] Is a NAS or WEB solution is installed?
|
|
VARIANT_BOOL *pbInstalled)//[out] tells if the SAK is already installed
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SATraceString ("Entering SaInstall::SAAlreadyInstalled");
|
|
|
|
try
|
|
{
|
|
//Check to see if a valid SAK type was passed in
|
|
if (installedType != NAS && installedType != WEB)
|
|
{
|
|
hr = E_ABORT;
|
|
SATraceString (" Invalid installedType");
|
|
}
|
|
else
|
|
{ //Check to see if the NAS or WEB is installed
|
|
*pbInstalled = bSAIsInstalled(installedType) ? VARIANT_TRUE : VARIANT_FALSE;
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
//Single point of return
|
|
SATraceString ("Exiting SaInstall::SAAlreadyInstalled");
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SaInstall::SAUninstall
|
|
//
|
|
// Description:
|
|
// Uninstalls a Server Appliance solution, if the type requested
|
|
// is installed.
|
|
//
|
|
// Arguments:
|
|
// [in] SA_TYPE: The type to uninstall (WEB)
|
|
// [OUT] BSTR*: Currently there are no reported errors
|
|
// Returns:
|
|
// HRESULT
|
|
//
|
|
// history:
|
|
// travisn Created 23-JUL-2001
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP SaInstall::SAUninstall(
|
|
const SA_TYPE uninstallType, //[in]Type of SAK to uninstall
|
|
BSTR* pbstrErrorString)//[out]
|
|
{
|
|
SATraceString ("Entering SaInstall::SAUninstall");
|
|
//Clear out the error string
|
|
*pbstrErrorString = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
try
|
|
{
|
|
//
|
|
// Create this do...while(false) loop to create a single point
|
|
// of return
|
|
//
|
|
do
|
|
{
|
|
if (uninstallType != WEB)
|
|
{
|
|
//Unidentified or unsupported type to uninstall
|
|
hr = E_ABORT;
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_INVALID_TYPE);
|
|
break;
|
|
}
|
|
|
|
//Detect if it's installed
|
|
if (bSAIsInstalled(WEB))
|
|
{
|
|
//
|
|
// uninstall the whole thing.
|
|
// Generate the command line to call MSI to uninstall the package
|
|
//
|
|
wstring wsCommand(REMOVE_ALL);
|
|
wsCommand += SAK_PRODUCT_CODE;
|
|
hr = CreateHiddenConsoleProcess(wsCommand.data());
|
|
if (FAILED(hr))
|
|
{
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_UNINSTALL_SA_FAILED);
|
|
}
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Neither of these types are installed, so report an error
|
|
// since they shouldn't have requested to uninstall.
|
|
//
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_NOT_INSTALLED);
|
|
|
|
//
|
|
// Since trying to uninstall something that is not present
|
|
// isn't fatal, return S_FALSE
|
|
//
|
|
hr = S_FALSE;
|
|
}
|
|
while (false);
|
|
}
|
|
catch (...)
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
//Single point of return
|
|
SATraceString ("Exiting SaInstall::SAUninstall");
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SaInstall::SAInstall
|
|
//
|
|
// Description:
|
|
// Installs a Server Appliance solution, depending on the arguments.
|
|
// Does some simple error checking to make sure that SaSetup.msi
|
|
// is present, and displays error messages if any errors occur.
|
|
//
|
|
// Arguments:
|
|
// [in] SA_TYPE: The type to install (NAS or WEB)
|
|
// [in] BSTR: The name of the CD that will be prompted for if
|
|
// SaSetup.msi is not found. Not used anymore
|
|
// [in] VARIANT_BOOL: Whether error dialog prompts will appear
|
|
// [in] VARIANT_BOOL: Whether the install is unattended
|
|
// [OUT] BSTR*: If an error occurs during installation, the error
|
|
// string is returned here
|
|
// Returns:
|
|
// HRESULT
|
|
//
|
|
// history:
|
|
// travisn Created 23-JUL-2001
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP SaInstall::SAInstall(
|
|
const SA_TYPE installType, //[in]
|
|
const BSTR bstrDiskName, //[in]
|
|
const VARIANT_BOOL bDispError, //[in]
|
|
const VARIANT_BOOL bUnattended, //[in]
|
|
BSTR* pbstrErrorString) //[out]
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
SATraceString("Entering SaInstall::SAInstall");
|
|
|
|
try
|
|
{
|
|
//Clear out the error string
|
|
*pbstrErrorString = NULL;
|
|
|
|
//
|
|
// Create this do...while(false) loop to create a single point
|
|
// of return
|
|
//
|
|
do
|
|
{ //
|
|
//Check the parameters
|
|
//
|
|
|
|
//Check to see if a valid SAK type was passed in
|
|
if (installType != WEB)
|
|
{
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_INVALID_TYPE);
|
|
break;
|
|
}
|
|
|
|
//Check to see if this SAK type is already installed
|
|
if (bSAIsInstalled(installType))
|
|
{
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_ALREADY_INSTALLED);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Make sure that IIS is installed and functioning
|
|
//
|
|
{ // CMetabaseObject must go out of scope to avoid keeping a read-lock
|
|
// on the metabase during our install
|
|
CMetabaseObject metabase;
|
|
hr = metabase.openObject(METABASE_IIS_PATH);
|
|
if (FAILED(hr))
|
|
{
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_IIS_NOT_INSTALLED);
|
|
break; // Something wrong with IIS installation
|
|
}
|
|
}
|
|
|
|
//
|
|
// Make sure we're installing on an NTFS partition
|
|
//
|
|
if (!InstallingOnNTFS())
|
|
{
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_NTFS_REQUIRED);
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Find the path to SaSetup.msi in system32
|
|
//
|
|
wstring wsLocationOfSaSetup;
|
|
hr = GetInstallLocation(wsLocationOfSaSetup);
|
|
if (FAILED(hr))
|
|
{
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_SASETUP_NOT_FOUND);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Create the complete command line for the SaSetup, whether for NAS or
|
|
// WebBlade. We already have the complete path to SaSetup.msi in
|
|
// wsLocationOfSaSetup, so we need to append the command-line parameters.
|
|
//
|
|
|
|
//Create the command-line options applicable to all installations
|
|
wstring wsCommand;
|
|
|
|
//
|
|
// There are 3 sources that call this installation: CYS, IIS, and SaInstall.exe.
|
|
// We want to display a progress dialog for CYS and IIS, but not SaInstall.
|
|
// SaInstall is the only source that calls this function with bDispError == true.
|
|
//
|
|
if (bDispError)
|
|
wsCommand = MSIEXEC_NO_PROGRESS_INSTALL;
|
|
else
|
|
wsCommand = MSIEXEC_INSTALL;
|
|
|
|
wsCommand += wsLocationOfSaSetup;
|
|
|
|
//Install a Web solution
|
|
wsCommand += WEB_INSTALL_OPTIONS;
|
|
|
|
//
|
|
//Take the command line and create a hidden window to execute it
|
|
//
|
|
hr = CreateHiddenConsoleProcess(wsCommand.data());
|
|
if (FAILED(hr))
|
|
{
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_SASETUP_FAILED);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Check to make sure that the installation completed successfully
|
|
// in case the user aborted by clicking Cancel
|
|
// If they did cancel, return E_FAIL
|
|
// If it is a valid installation, return S_OK
|
|
// This is necessary since the return value from the MSI process
|
|
// always returns SUCCESS, even if the user aborted
|
|
//
|
|
|
|
if (!bSAIsInstalled(installType))
|
|
{
|
|
ReportError(pbstrErrorString, VARIANT_FALSE, IDS_INSTALL_FAILED);
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Test to make sure the Admin site started
|
|
//
|
|
TestWebSites(bDispError, pbstrErrorString);
|
|
|
|
hr = S_OK;
|
|
}
|
|
while (false);
|
|
|
|
}
|
|
catch (...)
|
|
{
|
|
SATraceString ("Unexpected exception in SAInstall::SAInstall");
|
|
//Unexpected exception!!
|
|
}
|
|
|
|
SATraceString("Exiting SAInstall::SAInstall");
|
|
//Single point of return
|
|
return hr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// SaInstall::InterfaceSupportsErrorInfo
|
|
//
|
|
// Description:
|
|
// From Interface ISupportErrorInfo
|
|
//
|
|
// history
|
|
// travisn 2-AUG-2001 Some comments added
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP SaInstall::InterfaceSupportsErrorInfo(REFIID riid)//[in]
|
|
{
|
|
if (InlineIsEqualGUID(IID_ISaInstall, riid))
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|