397 lines
12 KiB
C++
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()
|