////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1999-2000 Microsoft Corporation // // Module Name: // Cluster.cpp // // Description: // Implementation of CCluster class // // Author: // Henry Wang (HenryWa) 24-AUG-1999 // ////////////////////////////////////////////////////////////////////////////// #include "Pch.h" #include "Cluster.h" //**************************************************************************** // // CCluster // //**************************************************************************** ////////////////////////////////////////////////////////////////////////////// //++ // // CCluster::CCluster( // LPCWSTR pwszNameIn, // CWbemServices * pNamespaceIn // ) // // Description: // Constructor. // // Arguments: // pwszNameIn -- Class name // pNamespaceIn -- Namespace // // Return Values: // None. // //-- ////////////////////////////////////////////////////////////////////////////// CCluster::CCluster( LPCWSTR pwszNameIn, CWbemServices * pNamespaceIn ) : CProvBase( pwszNameIn, pNamespaceIn ) { } //*** CCluster::CCluster() ////////////////////////////////////////////////////////////////////////////// //++ // // static // CProvBase * // CCluster::S_CreateThis( // LPCWSTR pwszNameIn, // CWbemServices * pNamespaceIn, // DWORD dwEnumTypeIn // ) // // Description: // Create a cluster object // // Arguments: // pwszNameIn -- Class name // pNamespaceIn -- Namespace // dwEnumTypeIn -- Type id // // Return Values: // pointer to the CProvBase // //-- ////////////////////////////////////////////////////////////////////////////// CProvBase * CCluster::S_CreateThis( LPCWSTR pwszNameIn, CWbemServices * pNamespaceIn, DWORD // dwEnumTypeIn ) { return new CCluster( pwszNameIn, pNamespaceIn ); } //*** CCluster::S_CreateThis() ////////////////////////////////////////////////////////////////////////////// //++ // // const SPropMapEntryArray * // CCluster::GetPropMap( void ) // // Description: // Retrieve the property maping table of the cluster. // // Arguments: // None. // // Return Values: // reference to the array of property maping table // //-- ////////////////////////////////////////////////////////////////////////////// const SPropMapEntryArray * CCluster::RgGetPropMap( void ) { static SPropMapEntry s_rgpm[] = { { PVD_PROP_CLUSTER_SECURITYDESCRIPTOR, CLUSREG_NAME_CLUS_SD, MULTI_SZ_TYPE, READWRITE }, { PVD_PROP_CLUSTER_GROUPADMIN, CLUS_CLUS_GROUPADMIN, MULTI_SZ_TYPE, READWRITE }, { PVD_PROP_CLUSTER_NETWORKADMIN, CLUS_CLUS_NETWORKADMIN, MULTI_SZ_TYPE, READWRITE }, { PVD_PROP_CLUSTER_NETINTFACEADMIN, CLUS_CLUS_NETINTERFACEADMIN, MULTI_SZ_TYPE, READWRITE }, { PVD_PROP_CLUSTER_NODEADMIN, CLUS_CLUS_NODEADMIN, MULTI_SZ_TYPE, READWRITE }, { PVD_PROP_CLUSTER_RESADMIN, CLUS_CLUS_RESADMIN, MULTI_SZ_TYPE, READWRITE }, { PVD_PROP_CLUSTER_RESTYPEADMIN, CLUS_CLUS_RESTYPEADMIN, MULTI_SZ_TYPE, READWRITE } }; static SPropMapEntryArray s_pmea ( sizeof( s_rgpm ) / sizeof( SPropMapEntry ), s_rgpm ); return &s_pmea; } //*** CCluster::GetPropMap() ////////////////////////////////////////////////////////////////////////////// //++ // // SCODE // CCluster::EnumInstance( // long lFlagsIn, // IWbemCOntext * pCtxIn, // IWbemObjectSing * pHandlerIn // ) // // Description: // Enum cluster instance. // // Arguments: // lFlagsIn -- WMI flag // pCtxIn -- WMI context // pHandlerIn -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // //-- ////////////////////////////////////////////////////////////////////////////// SCODE CCluster::EnumInstance( long lFlagsIn, IWbemContext * pCtxIn, IWbemObjectSink * pHandlerIn ) { SAFECLUSTER shCluster; shCluster = OpenCluster( NULL ); ClusterToWMI( shCluster, pHandlerIn ); return WBEM_S_NO_ERROR; } //*** CCluster::EnumInstance() ////////////////////////////////////////////////////////////////////////////// //++ // // void // CCluster::ClusterToWMI( // HCLUSTER hClusterIn, // IWbemObjectSink * pHandlerIn // ) // // Description: // Translate a cluster objects to WMI object. // // Arguments: // hClusterIn -- Handle to cluster // pHandlerIn -- Pointer to WMI sink // // Return Values: // WBEM_S_NO_ERROR // win32 error // //-- ////////////////////////////////////////////////////////////////////////////// void CCluster::ClusterToWMI( HCLUSTER hClusterIn, IWbemObjectSink * pHandlerIn ) { static SGetControl s_rgControl[] = { { CLUSCTL_CLUSTER_GET_RO_COMMON_PROPERTIES, FALSE }, { CLUSCTL_CLUSTER_GET_COMMON_PROPERTIES, FALSE }, { CLUSCTL_CLUSTER_GET_RO_PRIVATE_PROPERTIES, TRUE }, { CLUSCTL_CLUSTER_GET_PRIVATE_PROPERTIES, TRUE } }; static UINT s_cControl = sizeof( s_rgControl ) / sizeof( SGetControl ); DWORD dwError = ERROR_SUCCESS; CError er; UINT idx; CWbemClassObject wco; m_pClass->SpawnInstance( 0, &wco ); for ( idx = 0 ; idx < s_cControl ; idx++ ) { CClusPropList pl; er = pl.ScGetClusterProperties( hClusterIn, s_rgControl[ idx ].dwControl, NULL, 0 ); CClusterApi::GetObjectProperties( RgGetPropMap(), pl, wco, s_rgControl[ idx ].fPrivate ); } // for: each common property type // // cluster name // { DWORD cchClusterName = MAX_PATH; CWstrBuf wsbClusterName; wsbClusterName.SetSize( cchClusterName ); dwError = GetClusterInformation( hClusterIn, wsbClusterName, &cchClusterName, NULL ); if ( dwError == ERROR_MORE_DATA ) { wsbClusterName.SetSize( ++cchClusterName ); er = GetClusterInformation( hClusterIn, wsbClusterName, &cchClusterName, NULL ); } // if: buffer was too small wco.SetProperty( wsbClusterName, PVD_PROP_CLUSTER_NAME ); } // // network priority // { LPCWSTR pwszNetworks; BSTR pbstrNetworks[ MAX_PATH ]; UINT idx = 0; UINT cSize; CClusterEnum cluEnum( hClusterIn, CLUSTER_ENUM_INTERNAL_NETWORK ); // bugbug can you always clean up while ( ( pwszNetworks = cluEnum.GetNext() ) != NULL ) { pbstrNetworks[ idx ] = SysAllocString( pwszNetworks ); idx++; } wco.SetProperty( idx, pbstrNetworks, PVD_PROP_CLUSTER_NETWORK ); cSize = idx; for ( idx = 0 ; idx < cSize ; idx++ ) { SysFreeString( pbstrNetworks[ idx ] ); } } // // quorum resource // { CWstrBuf wsbName; DWORD cchName = MAX_PATH ; CWstrBuf wsbDeviceName; DWORD cchDeviceName = MAX_PATH; DWORD dwLogSize; wsbName.SetSize( cchName ); wsbDeviceName.SetSize( cchDeviceName ); dwError = GetClusterQuorumResource( hClusterIn, wsbName, &cchName, wsbDeviceName, &cchDeviceName, &dwLogSize ); if ( dwError == ERROR_MORE_DATA ) { wsbName.SetSize( ++cchName ); wsbDeviceName.SetSize( ++cchDeviceName ); er = GetClusterQuorumResource( hClusterIn, wsbName, &cchName, wsbDeviceName, &cchDeviceName, &dwLogSize ); } wco.SetProperty( wsbDeviceName, PVD_PROP_CLUSTER_FILE ); wco.SetProperty( dwLogSize, PVD_PROP_CLUSTER_LOGSIZE ); } pHandlerIn->Indicate( 1, &wco ); return; } //*** CCluster::ClusterToWMI() ////////////////////////////////////////////////////////////////////////////// //++ // // SCODE // CCluster::GetObject( // CObjPath & rObjPathIn, // long lFlagsIn, // IWbemContext * pCtxIn, // IWbemObjectSink * pHandlerIn // ) // // Description: // retrieve cluster object based given object path // // Arguments: // rObjPathIn -- Object path to cluster object // lFlagsIn -- WMI flag // pCtxIn -- WMI context // pHandlerIn -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // win32 error // //-- ////////////////////////////////////////////////////////////////////////////// SCODE CCluster::GetObject( CObjPath & rObjPathIn, long lFlagsIn, IWbemContext * pCtxIn, IWbemObjectSink * pHandlerIn ) { SAFECLUSTER shCluster; shCluster = OpenCluster( rObjPathIn.GetStringValueForProperty( PVD_PROP_NAME ) ); ClusterToWMI( shCluster, pHandlerIn ); return WBEM_S_NO_ERROR; } //*** CCluster::GetObject() ////////////////////////////////////////////////////////////////////////////// //++ // // SCODE // CCluster::ExecuteMethod( // CObjPath & rObjPathIn, // WCHAR * pwszMethodNameIn, // long lFlagIn, // IWbemClassObject * pParamsIn, // IWbemObjectSink * pHandlerIn // ) // // Description: // execute methods defined in the mof for cluster // // Arguments: // rObjPathIn -- Object path to cluster object // pwszMethodNameIn -- Name of the method to be invoked // lFlagIn -- WMI flag // pParamsIn -- Input parameters for the method // pHandlerIn -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // //-- ////////////////////////////////////////////////////////////////////////////// SCODE CCluster::ExecuteMethod( CObjPath & rObjPathIn, WCHAR * pwszMethodNameIn, long lFlagIn, IWbemClassObject * pParamsIn, IWbemObjectSink * pHandlerIn ) { SAFECLUSTER shCluster; CWbemClassObject InArgs( pParamsIn ); CError er; shCluster = OpenCluster( NULL ); if ( _wcsicmp( pwszMethodNameIn, PVD_MTH_CLUSTER_RENAME ) == 0 ) { _bstr_t bstrName; DWORD dwReturn; InArgs.GetProperty( bstrName, PVD_MTH_CLUSTER_PARM_NEWNAME ); dwReturn = SetClusterName( shCluster, bstrName ); if ( dwReturn != ERROR_RESOURCE_PROPERTIES_STORED ) { er = dwReturn; } } // if: create new group else if( _wcsicmp( pwszMethodNameIn, PVD_MTH_CLUSTER_SETQUORUM ) == 0 ) { _bstr_t bstrName; SAFERESOURCE hResource; CObjPath opPath; InArgs.GetProperty( bstrName, PVD_MTH_CLUSTER_PARM_RESOURCE ); opPath.Init( bstrName ); bstrName = opPath.GetStringValueForProperty( PVD_PROP_RES_NAME ); hResource = OpenClusterResource( shCluster, bstrName ); er = SetClusterQuorumResource( hResource, NULL, 64000 ); } // else if: set quorum resource return WBEM_S_NO_ERROR; } //*** CCluster::ExecuteMethod() ////////////////////////////////////////////////////////////////////////////// //++ // // SCODE // CCluster::PutInstance( // CWbemClassObject & rInstToPutIn, // long lFlagIn, // IWbemContext * pCtxIn, // IWbemObjectSink * pHandlerIn // ) // // Description: // save this instance // // Arguments: // rInstToPutIn -- WMI object to be saved // lFlagIn -- WMI flag // pCtxIn -- WMI context // pHandlerIn -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // //-- ////////////////////////////////////////////////////////////////////////////// SCODE CCluster::PutInstance( CWbemClassObject & rInstToPutIn, long lFlagIn, IWbemContext * pCtxIn, IWbemObjectSink * pHandlerIn ) { static SGetSetControl s_rgControl[] = { { CLUSCTL_CLUSTER_GET_COMMON_PROPERTIES, CLUSCTL_CLUSTER_SET_COMMON_PROPERTIES, FALSE }, { CLUSCTL_CLUSTER_GET_PRIVATE_PROPERTIES, CLUSCTL_CLUSTER_SET_PRIVATE_PROPERTIES, TRUE } }; static DWORD s_cControl = sizeof( s_rgControl ) / sizeof( SGetSetControl ); CError er; DWORD dwError; SAFECLUSTER shCluster; UINT idx; shCluster = OpenCluster( NULL ); for ( idx = 0 ; idx < s_cControl ; idx++ ) { CClusPropList plOld; CClusPropList plNew; er = plOld.ScGetClusterProperties( shCluster, s_rgControl[ idx ].dwGetControl, NULL, NULL, 0 ); CClusterApi::SetObjectProperties( RgGetPropMap(), plNew, plOld, rInstToPutIn, s_rgControl[ idx ].fPrivate ); if ( plNew.Cprops() > 0 ) { er = ClusterControl( shCluster, NULL, s_rgControl[ idx ].dwSetControl, plNew.PbPropList(), plNew.CbPropList(), NULL, 0, NULL ); } } // for: each control code // // network // { CClusPropList plNetwork; DWORD cNetworks = 0; _bstr_t * pbstrNetworks = NULL; UINT idx = 0; HNETWORK * phNetworks = NULL; rInstToPutIn.GetProperty( &cNetworks, &pbstrNetworks, PVD_PROP_CLUSTER_NETWORK ); try { phNetworks = new HNETWORK[ cNetworks ]; for( idx = 0 ; idx < cNetworks ; idx++ ) { *(phNetworks + idx) = NULL; } for ( idx = 0 ; idx < cNetworks ; idx++) { *( phNetworks + idx ) = OpenClusterNetwork( shCluster, *( pbstrNetworks + idx ) ); if ( phNetworks == NULL ) { throw CProvException( GetLastError() ); } } er = SetClusterNetworkPriorityOrder( shCluster, cNetworks, phNetworks ); } // try catch ( ... ) { for ( idx = 0 ; idx < cNetworks ; idx++) { if ( *( phNetworks + idx ) ) { CloseClusterNetwork( *( phNetworks + idx) ); } } delete [] phNetworks; delete [] pbstrNetworks; throw; } // catch: ... // // clean up // for ( idx = 0 ; idx < cNetworks ; idx++) { if ( *( phNetworks + idx ) ) { CloseClusterNetwork( *( phNetworks + idx) ); } } delete [] phNetworks; delete [] pbstrNetworks; } // // quorum resource // { CWstrBuf wsbName; DWORD cchName = MAX_PATH; CWstrBuf wsbDeviceName; DWORD cchDeviceName = MAX_PATH; DWORD dwLogSize; _bstr_t bstrNewDeviceName; DWORD dwNewLogSize; SAFERESOURCE shResource; wsbName.SetSize( cchName ); wsbDeviceName.SetSize( cchDeviceName ); dwError = GetClusterQuorumResource( shCluster, wsbName, &cchName, wsbDeviceName, &cchDeviceName, &dwLogSize ); if ( dwError == ERROR_MORE_DATA ) { wsbName.SetSize( ++cchName ); wsbDeviceName.SetSize( ++cchDeviceName ); er = GetClusterQuorumResource( shCluster, wsbName, &cchName, wsbDeviceName, &cchDeviceName, &dwLogSize ); } // if: buffer is too small rInstToPutIn.GetProperty( bstrNewDeviceName, PVD_PROP_CLUSTER_FILE ); rInstToPutIn.GetProperty( &dwNewLogSize, PVD_PROP_CLUSTER_LOGSIZE ); if ( _wcsicmp( wsbDeviceName, bstrNewDeviceName ) || dwLogSize != dwNewLogSize ) { shResource = OpenClusterResource( shCluster, wsbName ); er = SetClusterQuorumResource( shResource, bstrNewDeviceName, dwNewLogSize ); } // if: } return WBEM_S_NO_ERROR; } //*** CCluster::PutInstance() ////////////////////////////////////////////////////////////////////////////// //++ // // SCODE // CCluster::DeleteInstance( // CObjPath & rObjPathIn, // long lFlagIn, // IWbemContext * pCtxIn, // IWbemObjectSink * pHandlerIn // ) // // Description: // save this instance // // Arguments: // rObjPathIn -- ObjPath for the instance to be deleted // lFlagIn -- WMI flag // pCtxIn -- WMI context // pHandlerIn -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // //-- ////////////////////////////////////////////////////////////////////////////// SCODE CCluster::DeleteInstance( CObjPath & rObjPathIn, long lFlagIn, IWbemContext * pCtxIn, IWbemObjectSink * pHandlerIn ) { return WBEM_E_NOT_SUPPORTED; } //*** CCluster::DeleteInstance()