|
|
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2002 Microsoft Corporation
//
// Module Name:
// CTaskUpgradeNT4.cpp
//
// Description:
// Implementation file for the CTaskUpgradeNT4 class.
//
// Header File:
// CTaskUpgradeNT4.h
//
// Maintained By:
// David Potter (DavidP) 25-MAR-2002
// Vij Vasu (Vvasu) 18-APR-2000
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Include Files
//////////////////////////////////////////////////////////////////////////////
// Precompiled header for this DLL.
#include "Pch.h"
// The header file for this module.
#include "CTaskUpgradeNT4.h"
//////////////////////////////////////////////////////////////////////////////
// Macro Definitions
//////////////////////////////////////////////////////////////////////////////
// Needed for tracing.
DEFINE_THISCLASS( "CTaskUpgradeNT4" )
// Name of the cluster service executable
#define CLUSSVC_EXECUTABLE_NAME L"ClusSvc.exe"
// Multi-sz string of cluster service dependencies
#define CLUSSVC_DEPENDENCY_MULTISZ L"ClusNet\0RpcSs\0W32Time\0NetMan"
/////////////////////////////////////////////////////////////////////////////
//++
//
// CTaskUpgradeNT4::CTaskUpgradeNT4
//
// Description:
// Constructor of the CTaskUpgradeNT4 class.
//
// Arguments:
// const CClusOCMApp & rAppIn
// Reference to the CClusOCMApp object that is hosting this task.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CTaskUpgradeNT4::CTaskUpgradeNT4( const CClusOCMApp & rAppIn ) : BaseClass( rAppIn ) { TraceFunc( "" ); TraceFuncExit();
} //*** CTaskUpgradeNT4::CTaskUpgradeNT4()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CTaskUpgradeNT4::~CTaskUpgradeNT4
//
// Description:
// Destructor of the CTaskUpgradeNT4 class.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CTaskUpgradeNT4::~CTaskUpgradeNT4( void ) { TraceFunc( "" ); TraceFuncExit();
} //*** CTaskUpgradeNT4::~CTaskUpgradeNT4()
/////////////////////////////////////////////////////////////////////////////
//++
//
// DWORD
// CTaskUpgradeNT4::DwOcQueueFileOps
//
// Description:
// This function handles the OC_QUEUE_FILE_OPS messages from the Optional
// Components Manager. It installs the files needed for an upgrade from
// Windows 2000.
//
// Arguments:
// HSPFILEQ hSetupFileQueueIn
// Handle to the file queue to operate upon.
//
// Return Value:
// NO_ERROR if all went well.
// Other Win32 error codes on failure.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CTaskUpgradeNT4::DwOcQueueFileOps( HSPFILEQ hSetupFileQueueIn ) { TraceFunc( "" ); LogMsg( "Entering " __FUNCTION__ "()" );
DWORD dwReturnValue = NO_ERROR;
// The base class helper function does everything that we need to do here.
// So, just call it.
dwReturnValue = TW32( BaseClass::DwOcQueueFileOps( hSetupFileQueueIn, INF_SECTION_NT4_UPGRADE ) );
LogMsg( "Return Value is %#x.", dwReturnValue );
RETURN( dwReturnValue );
} //*** CTaskUpgradeNT4::DwOcQueueFileOps()
/////////////////////////////////////////////////////////////////////////////
//++
//
// DWORD
// CTaskUpgradeNT4::DwOcCompleteInstallation
//
// Description:
// This function handles the OC_COMPLETE_INSTALLATION messages from the
// Optional Components Manager during an upgrade from Windows 2000.
//
// Registry operations, COM component registrations, creation of servies
// etc. are performed in this function.
//
// Arguments:
// None.
//
// Return Value:
// NO_ERROR if all went well.
// Other Win32 error codes on failure.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CTaskUpgradeNT4::DwOcCompleteInstallation( void ) { TraceFunc( "" ); LogMsg( "Entering " __FUNCTION__ "()" );
DWORD dwReturnValue = NO_ERROR;
// Call the base class helper function to perform some registry and service
// related configuration from the INF file.
dwReturnValue = TW32( BaseClass::DwOcCompleteInstallation( INF_SECTION_NT4_UPGRADE ) );
//
// Change the cluster service display name, description, dependencies, failure actions
// and executable name.
//
while( dwReturnValue == NO_ERROR ) { // Pointer the the cluster service directory.
const WCHAR * pcszInstallDir = NULL;
// Smart pointer to the cluster service display name string.
SmartSz sszClusSvcDispName;
// Smart pointer to the cluster service description string.
SmartSz sszClusSvcDesc;
// Smart pointer to the cluster service binary path string.
SmartSz sszClusSvcBinPath;
// Smart pointer to the cluster service.
SmartServiceHandle shClusSvc;
// Connect to the Service Control Manager
SmartServiceHandle shServiceMgr( OpenSCManager( NULL, NULL, GENERIC_READ | GENERIC_WRITE ) ); if ( shServiceMgr.HHandle() == NULL ) { dwReturnValue = TW32( GetLastError() ); LogMsg( "Error %#x occurred trying to open a connection to the local service control manager.", dwReturnValue ); break; } // if: opening the SCM was unsuccessful
// Open a handle to the Cluster Service.
shClusSvc.Assign( OpenService( shServiceMgr, L"ClusSvc", SERVICE_ALL_ACCESS ) ); if ( shClusSvc.HHandle() == NULL ) { dwReturnValue = TW32( GetLastError() ); LogMsg( "Error %#x occurred trying to open a handle to the cluster service.", dwReturnValue ); break; } // if: the handle could not be opened
// Load the cluster service name string.
dwReturnValue = DwLoadString( IDS_CLUSSVC_DISPLAY_NAME, sszClusSvcDispName ); if ( dwReturnValue != ERROR_SUCCESS ) { LogMsg( "Error %#x occurred trying load the display name of the cluster service.", dwReturnValue ); break; } // if: we could not load the cluster service display name string
LogMsg( "The new cluster service display name is '%ws'.", sszClusSvcDispName.PMem() );
// Load the cluster service description string.
dwReturnValue = DwLoadString( IDS_CLUSSVC_SERVICE_DESC, sszClusSvcDesc ); if ( dwReturnValue != ERROR_SUCCESS ) { LogMsg( "Error %#x occurred trying load the description of the cluster service.", dwReturnValue ); break; } // if: we could not load the cluster service description string
LogMsg( "The new cluster service description is '%ws'.", sszClusSvcDesc.PMem() );
//
// Form the service binary path by appending the name of the cluster service executable to
// the cluster service directory.
//
// Do not free the pointer returned by this call.
dwReturnValue = TW32( DwGetClusterServiceDirectory( pcszInstallDir ) ); if ( dwReturnValue != NO_ERROR ) { LogMsg( "Error %#x occurred trying to determine the directory in which the cluster binaries are installed.", dwReturnValue ); break; } // if: we could not get the cluster service installation directory
LogMsg( "The cluster service directory is '%ws'.", pcszInstallDir );
{ WCHAR * pszTempPtr;
// Length of the the install directory string, not including the terminating L'\0'
size_t cchInstallDirLen = wcslen( pcszInstallDir ); // Length of the cluster service executable name, including the terminating L'\0'
size_t cchClusSvcExeLen = RTL_NUMBER_OF( CLUSSVC_EXECUTABLE_NAME );
size_t cchRemaining = cchInstallDirLen + 1 + cchClusSvcExeLen;
// Allocate memory for the cluster service binary path (the extra character is for the intervening L'\\'.
sszClusSvcBinPath.Assign( new WCHAR[ cchInstallDirLen + 1 + cchClusSvcExeLen ] ); if ( sszClusSvcBinPath.FIsEmpty() ) { dwReturnValue = TW32( ERROR_NOT_ENOUGH_MEMORY ); LogMsg( "An error occurred trying to allocate memory for the cluster service binary path." ); break; } // if: an error occurred trying to allocate memory for the cluster service binary path
pszTempPtr = sszClusSvcBinPath.PMem();
// Copy the install directory string to the newly allocated buffer.
THR( StringCchCopyNExW( pszTempPtr, cchRemaining, pcszInstallDir, cchInstallDirLen, &pszTempPtr, &cchRemaining, 0 ) );
// Copy the trailing L'\\' character
*(pszTempPtr++) = L'\\'; cchRemaining--;
// Copy the cluster service executable name.
THR( StringCchCopyNW( pszTempPtr, cchRemaining, CLUSSVC_EXECUTABLE_NAME, cchClusSvcExeLen ) );
LogMsg( "The new cluster service binary path is '%ws'.", sszClusSvcBinPath.PMem() ); }
// Change the binary path, dependency list and display name.
if ( ChangeServiceConfig( shClusSvc.HHandle() // handle to service
, SERVICE_NO_CHANGE // type of service
, SERVICE_NO_CHANGE // when to start service
, SERVICE_NO_CHANGE // severity of start failure
, sszClusSvcBinPath.PMem() // service binary file name
, NULL // load ordering group name
, NULL // tag identifier
, CLUSSVC_DEPENDENCY_MULTISZ // array of dependency names
, NULL // account name
, NULL // account password
, sszClusSvcDispName.PMem() // display name
) == FALSE ) { dwReturnValue = TW32( GetLastError() ); LogMsg( "Error %#x occurred trying to change the cluster service configuration.", dwReturnValue ); break; } // if: ChangeServiceConfig() failed
LogMsg( "The cluster service binary path, dependency list and display name have been changed." );
// Change the service description
{ SERVICE_DESCRIPTION sdServiceDescription;
sdServiceDescription.lpDescription = sszClusSvcDesc.PMem(); if ( ChangeServiceConfig2( shClusSvc.HHandle() // handle to service
, SERVICE_CONFIG_DESCRIPTION // information level
, &sdServiceDescription // new data
) == FALSE ) { dwReturnValue = TW32( GetLastError() ); LogMsg( "Error %#x occurred trying to change the cluster service description.", dwReturnValue ); break; } // if: ChangeServiceConfig2() failed
}
LogMsg( "The cluster service description has been changed." );
// Change the cluster service failure actions.
dwReturnValue = TW32( ClRtlSetSCMFailureActions( NULL ) ); if ( dwReturnValue != ERROR_SUCCESS ) { LogMsg( "Error %#x occurred trying to set the cluster service failure actions.", dwReturnValue ); break; } // if: ClRtlSetSCMFailureActions() failed
LogMsg( "The cluster service failure actions have been changed." );
LogMsg( "The cluster service configuration has been changed." ); break; } // while: the call to the base class function has succeeded
LogMsg( "Return Value is %#x.", dwReturnValue );
RETURN( dwReturnValue );
} //*** CTaskUpgradeNT4::DwOcCompleteInstallation()
/////////////////////////////////////////////////////////////////////////////
//++
//
// DWORD
// CTaskUpgradeNT4::DwOcCleanup
//
// Description:
// This function handles the OC_CLEANUP messages from the
// Optional Components Manager during an upgrade from Windows 2000.
//
// If an error has previously occurred during this task, cleanup operations
// are performed. Otherwise nothing is done by this function.
//
// Arguments:
// None.
//
// Return Value:
// NO_ERROR if all went well.
// Other Win32 error codes on failure.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CTaskUpgradeNT4::DwOcCleanup( void ) { TraceFunc( "" ); LogMsg( "Entering " __FUNCTION__ "()" );
DWORD dwReturnValue = NO_ERROR;
// The base class helper function does everything that we need to do here.
// So, just call it.
dwReturnValue = TW32( BaseClass::DwOcCleanup( INF_SECTION_NT4_UPGRADE_CLEANUP ) );
LogMsg( "Return Value is %#x.", dwReturnValue );
RETURN( dwReturnValue );
} //*** CTaskUpgradeNT4::DwOcCleanup()
/////////////////////////////////////////////////////////////////////////////
//++
//
// DWORD
// CTaskUpgradeNT4::DwSetDirectoryIds
//
// Description:
// This function maps ids specified in the INF file to directories.
// The cluster installation directory is got from the service control
// manager, since it is possible the the cluster binaries are installed
// in a non-default location.
//
// Arguments:
// None.
//
// Return Value:
// NO_ERROR if all went well.
// Other Win32 error codes on failure.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CTaskUpgradeNT4::DwSetDirectoryIds() { TraceFunc( "" ); LogMsg( "Entering " __FUNCTION__ "()" );
DWORD dwReturnValue = NO_ERROR;
do { const WCHAR * pcszInstallDir = NULL;
// If we are here, the this node is already a part of a cluster. So, get the
// installation directory from SCM.
LogMsg( "This node is part of a cluster. Trying to determine the installation directory." );
// Do not free the pointer returned by this call.
dwReturnValue = TW32( DwGetClusterServiceDirectory( pcszInstallDir ) ); if ( dwReturnValue != NO_ERROR ) { LogMsg( "Error %#x occurred trying to determine the directory in which the cluster binaries are installed.", dwReturnValue ); break; } // if: we could not get the cluster service installation directory
LogMsg( "The cluster binaries are installed in the directory '%ws'.", pcszInstallDir );
// Create the mapping between the directory id and the path
if ( SetupSetDirectoryId( RGetApp().RsicGetSetupInitComponent().ComponentInfHandle , CLUSTER_DEFAULT_INSTALL_DIRID , pcszInstallDir ) == FALSE ) { dwReturnValue = TW32( GetLastError() ); LogMsg( "Error %#x occurred trying set the cluster install directory id.", dwReturnValue ); break; } // if: SetupSetDirectoryId() failed
LogMsg( "The id %d maps to '%ws'.", CLUSTER_DEFAULT_INSTALL_DIRID, pcszInstallDir );
} while ( false ); // dummy do-while loop to avoid gotos
LogMsg( "Return Value is %#x.", dwReturnValue );
RETURN( dwReturnValue );
} //*** CTaskUpgradeNT4::DwSetDirectoryIds()
|