windows-nt/Source/XPSP1/NT/base/cluster/mgmt/cluscfg/basecluster/cclusdb.cpp
2020-09-26 16:20:57 +08:00

397 lines
12 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999-2000 Microsoft Corporation
//
// Module Name:
// CClusDB.cpp
//
// Description:
// Contains the definition of the CClusDB class.
//
// Maintained By:
// Vij Vasu (Vvasu) 08-MAR-2000
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Include Files
//////////////////////////////////////////////////////////////////////////////
// The precompiled header.
#include "pch.h"
// For setupapi functions
#include <setupapi.h>
// The header for this file
#include "CClusDB.h"
// For the CBaseClusterAction class
#include "CBaseClusterAction.h"
// For g_GenericSetupQueueCallback and other global functions
#include "GlobalFuncs.h"
// For CEnableThreadPrivilege
#include "CEnableThreadPrivilege.h"
// For ClRtlSetObjSecurityInfo() and other functions.
#include "clusrtl.h"
//////////////////////////////////////////////////////////////////////////
// Macros definitions
//////////////////////////////////////////////////////////////////////////
// Section in the INF file that deals with cleaning up the cluster database
#define CLUSDB_CLEANUP_INF_SECTION_NAME L"ClusDB_Cleanup"
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDB::CClusDB()
//
// Description:
// Constructor of the CClusDB class
//
// Arguments:
// pbcaParentActionIn
// Pointer to the base cluster action of which this action is a part.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CAssert
// If the parameters are incorrect.
//
// Any exceptions thrown by underlying functions
//
//--
//////////////////////////////////////////////////////////////////////////////
CClusDB::CClusDB(
CBaseClusterAction * pbcaParentActionIn
)
: m_pbcaParentAction( pbcaParentActionIn )
{
BCATraceScope( "" );
if ( m_pbcaParentAction == NULL)
{
BCATraceMsg( "Pointers to the parent action is NULL. Throwing exception." );
THROW_ASSERT(
E_INVALIDARG
, "CClusDB::CClusDB() => Required input pointer in NULL"
);
} // if: the parent action pointer is NULL
} //*** CClusDB::CClusDB()
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDB::~CClusDB()
//
// Description:
// Destructor of the CClusDB class.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any exceptions thrown by underlying functions
//
//--
//////////////////////////////////////////////////////////////////////////////
CClusDB::~CClusDB( void )
{
BCATraceScope( "" );
} //*** CClusDB::~CClusDB()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CClusDB::CreateHive()
//
// Description:
// Creates the cluster cluster hive in the registry.
//
// Arguments:
// pbcaClusterActionIn
// Pointer to the CBaseClusterAction object which contains this object.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CRuntimeError
// If any of the APIs fail.
//
// Any that are thrown by the called functions.
//
//--
//////////////////////////////////////////////////////////////////////////////
void
CClusDB::CreateHive( CBaseClusterAction * pbcaClusterActionIn )
{
BCATraceScope( "" );
LogMsg( "Attempting to create the cluster hive in the registry." );
OBJECT_ATTRIBUTES oaClusterHiveKey;
OBJECT_ATTRIBUTES oaClusterHiveFile;
HRESULT hrStatus = STATUS_SUCCESS;
do
{
CStr strClusterHiveFileName( pbcaClusterActionIn->RStrGetClusterInstallDirectory() );
UNICODE_STRING ustrClusterHiveFileName;
UNICODE_STRING ustrClusterHiveKeyName;
strClusterHiveFileName += L"\\" CLUSTER_DATABASE_NAME;
BCATraceMsg1( "The cluster hive backing file is '%s'.", strClusterHiveFileName.PszData() );
//
// Enable the SE_RESTORE_PRIVILEGE.
//
// What we are doing here is that we are creating an object of
// type CEnableThreadPrivilege. This object enables the privilege
// in the constructor and restores it to its original state in the destructor.
//
CEnableThreadPrivilege etpAcquireRestorePrivilege( SE_RESTORE_NAME );
//
// Convert the DOS file name to NT file name.
// WARNING: This function call allocates memory in the RTL heap and it is not being
// assigned to a smart pointer. Make sure that we do not call any functions that
// could throw an exception till this memory is freed.
//
if ( RtlDosPathNameToNtPathName_U(
strClusterHiveFileName.PszData()
, &ustrClusterHiveFileName
, NULL
, NULL
)
== FALSE
)
{
BCATraceMsg1( "RtlDosPathNameToNtPathName failed. Making up error code %#08x.", STATUS_OBJECT_PATH_INVALID );
// Use the most appropriate error code.
hrStatus = STATUS_OBJECT_PATH_INVALID;
break;
} // if: we could not convert from the dos file name to the nt file name
InitializeObjectAttributes(
&oaClusterHiveFile
, &ustrClusterHiveFileName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
RtlInitUnicodeString( &ustrClusterHiveKeyName, L"\\Registry\\Machine\\" CLUSREG_KEYNAME_CLUSTER );
InitializeObjectAttributes(
&oaClusterHiveKey
, &ustrClusterHiveKeyName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
//
// This function creates an empty hive and the backing file and log. The calling thread must
// have the SE_RESTORE_PRIVILEGE privilege enabled.
//
hrStatus = THR( NtLoadKey2( &oaClusterHiveKey, &oaClusterHiveFile, REG_NO_LAZY_FLUSH ) );
// Free allocated memory before throwing exception.
RtlFreeHeap( RtlProcessHeap(), 0, ustrClusterHiveFileName.Buffer );
if ( NT_ERROR( hrStatus ) )
{
BCATraceMsg1( "NtLoadKey2 returned error code %#08x.", hrStatus );
break;
} // if: something went wrong with NtLoadKey2
BCATraceMsg( "NtLoadKey2 was successful." );
// Set the security descriptor on the hive.
{
DWORD dwError;
// Open the cluster hive key.
CRegistryKey rkClusterHive( HKEY_LOCAL_MACHINE, CLUSREG_KEYNAME_CLUSTER, KEY_ALL_ACCESS );
dwError = TW32( ClRtlSetObjSecurityInfo(
rkClusterHive.HGetKey()
, SE_REGISTRY_KEY
, KEY_ALL_ACCESS
, KEY_ALL_ACCESS
, KEY_READ
) );
if ( dwError != ERROR_SUCCESS )
{
hrStatus = HRESULT_FROM_WIN32( dwError );
BCATraceMsg1( "Error %#08x occurred trying set the cluster hive security.", hrStatus );
break;
} // if: ClRtlSetObjSecurityInfo failed
// Flush the changes to the registry.
RegFlushKey( rkClusterHive.HGetKey() );
}
// At this point, the cluster hive has been created.
LogMsg( "The cluster hive has been created." );
}
while( false ); // dummy do-while loop to avoid gotos.
if ( NT_ERROR( hrStatus ) )
{
LogMsg( "Error %#08x occurred trying to create the cluster hive.", hrStatus );
BCATraceMsg1( "Error %#08x occurred trying to create the cluster hive. Throwing exception.", hrStatus );
THROW_RUNTIME_ERROR(
hrStatus
, IDS_ERROR_CLUSDB_CREATE_HIVE
);
} // if: something went wrong.
} //*** CClusDB::CreateHive()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CClusDB::CleanupHive()
//
// Description:
// Unload the cluster hive and delete the cluster database.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CRuntimeError
// If any of the APIs fail.
//
//--
//////////////////////////////////////////////////////////////////////////////
void
CClusDB::CleanupHive( void )
{
BCATraceScope( "" );
DWORD dwError = ERROR_SUCCESS;
do
{
HKEY hTempKey;
// Check if the cluster hive is loaded before attempting to unload it.
if ( RegOpenKeyEx(
HKEY_LOCAL_MACHINE
, CLUSREG_KEYNAME_CLUSTER
, 0
, KEY_READ
, &hTempKey
)
== ERROR_SUCCESS
)
{
RegCloseKey( hTempKey );
//
// Enable the SE_RESTORE_PRIVILEGE.
//
// What we are doing here is that we are creating an object of
// type CEnableThreadPrivilege. This object enables the privilege
// in the constructor and restores it to its original state in the destructor.
//
CEnableThreadPrivilege etpAcquireRestorePrivilege( SE_RESTORE_NAME );
//
// Unload the cluster hive, so that it can be deleted. Note, thread must
// have SE_RESTORE_PRIVILEGE enabled.
//
dwError = RegUnLoadKey(
HKEY_LOCAL_MACHINE
, CLUSREG_KEYNAME_CLUSTER
);
// MUSTDO: Check if ERROR_FILE_NOT_FOUND is an acceptable return value.
if ( dwError != ERROR_SUCCESS )
{
LogMsg( "Error %#08x occurred while trying to unload the cluster hive.", dwError );
BCATraceMsg( "RegUnLoadKey returned an error while trying to unload the cluster hive." );
break;
} // if: the hive could not be unloaded.
BCATraceMsg( "The cluster hive has been unloaded." );
LogMsg( "The cluster hive has been unloaded." );
} // if: the cluster hive is loaded
else
{
LogMsg( "The cluster hive was not loaded." );
BCATraceMsg( "The cluster hive was not loaded." );
} // else: the cluster hive is not loaded
//
// Process ClusDB cleanup section in the INF file.
// This will delete the cluster database file and the log file.
//
if ( SetupInstallFromInfSection(
NULL // optional, handle of a parent window
, m_pbcaParentAction->HGetMainInfFileHandle() // handle to the INF file
, CLUSDB_CLEANUP_INF_SECTION_NAME // name of the Install section
, SPINST_FILES // which lines to install from section
, NULL // optional, key for registry installs
, NULL // optional, path for source files
, 0 // optional, specifies copy behavior
, g_GenericSetupQueueCallback // optional, specifies callback routine
, NULL // optional, callback routine context
, NULL // optional, device information set
, NULL // optional, device info structure
) == FALSE
)
{
dwError = GetLastError();
LogMsg( "Error %#08x occurred while trying to clean up the cluster database files.", dwError );
BCATraceMsg( "Setup API returned an error while trying to cleanup the cluster database." );
break;
} // if: SetupInstallServicesFromInfSection failed
LogMsg( "The cluster database files have been cleaned up." );
}
while( false ); // dummy do-while loop to avoid gotos
if ( dwError != ERROR_SUCCESS )
{
LogMsg( "Error %#08x occurred while trying to cleanup the cluster database.", dwError );
BCATraceMsg1( "Error %#08x occurred while trying to cleanup the cluster database. Throwing exception.", dwError );
THROW_RUNTIME_ERROR( HRESULT_FROM_WIN32( dwError ), IDS_ERROR_CLUSDB_CLEANUP );
}
} //*** CClusDB::CleanupHive()