////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000-2002 Microsoft Corporation // // Module Name: // CEnumClusCfgNetworks.cpp // // Description: // This file contains the definition of the CEnumClusCfgNetworks // class. // // The class CEnumClusCfgNetworks is the enumeration of cluster // networks. It implements the IEnumClusCfgNetworks interface. // // Maintained By: // Galen Barbee (GalenB) 23-FEB-2000 // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // Include Files ////////////////////////////////////////////////////////////////////////////// #include "Pch.h" #include #include "CEnumClusCfgNetworks.h" #include "CClusCfgNetworkInfo.h" ////////////////////////////////////////////////////////////////////////////// // Constant Definitions ////////////////////////////////////////////////////////////////////////////// DEFINE_THISCLASS( "CEnumClusCfgNetworks" ); //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumClusCfgNetworks class ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::S_HrCreateInstance // // Description: // Create a CEnumClusCfgNetworks instance. // // Arguments: // None. // // Return Values: // Pointer to CEnumClusCfgNetworks instance. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::S_HrCreateInstance( IUnknown ** ppunkOut ) { TraceFunc( "" ); HRESULT hr = S_OK; CEnumClusCfgNetworks * peccn = NULL; if ( ppunkOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // if: peccn = new CEnumClusCfgNetworks(); if ( peccn == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: error allocating object hr = THR( peccn->HrInit() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: HrInit() failed hr = THR( peccn->TypeSafeQI( IUnknown, ppunkOut ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: QI failed Cleanup: if ( FAILED( hr ) ) { LogMsg( L"[SRV] CEnumClusCfgNetworks::S_HrCreateInstance() failed. (hr = %#08x)", hr ); } // if: if ( peccn != NULL ) { peccn->Release(); } // if: HRETURN( hr ); } //*** CEnumClusCfgNetworks::S_HrCreateInstance ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::CEnumClusCfgNetworks // // Description: // Constructor of the CEnumClusCfgNetworks class. This initializes // the m_cRef variable to 1 instead of 0 to account of possible // QueryInterface failure in DllGetClassObject. // // Arguments: // None. // // Return Value: // None. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// CEnumClusCfgNetworks::CEnumClusCfgNetworks( void ) : m_cRef( 1 ) , m_lcid( LOCALE_NEUTRAL ) , m_fLoadedNetworks( false ) { TraceFunc( "" ); // Increment the count of components in memory so the DLL hosting this // object cannot be unloaded. InterlockedIncrement( &g_cObjects ); Assert( m_picccCallback == NULL ); Assert( m_pIWbemServices == NULL ); Assert( m_prgNetworks == NULL ); Assert( m_idxNext == 0 ); Assert( m_idxEnumNext == 0 ); Assert( m_bstrNodeName == NULL ); Assert( m_cNetworks == 0 ); TraceFuncExit(); } //*** CEnumClusCfgNetworks::CEnumClusCfgNetworks ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::~CEnumClusCfgNetworks // // Description: // Desstructor of the CEnumClusCfgNetworks class. // // Arguments: // None. // // Return Value: // None. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// CEnumClusCfgNetworks::~CEnumClusCfgNetworks( void ) { TraceFunc( "" ); ULONG idx; if ( m_pIWbemServices != NULL ) { m_pIWbemServices->Release(); } // if: if ( m_picccCallback != NULL ) { m_picccCallback->Release(); } // if: for ( idx = 0; idx < m_idxNext; idx++ ) { ((*m_prgNetworks)[ idx ])->Release(); } // for: TraceFree( m_prgNetworks ); TraceSysFreeString( m_bstrNodeName ); // There's going to be one less component in memory. Decrement component count. InterlockedDecrement( &g_cObjects ); TraceFuncExit(); } //*** CEnumClusCfgNetworks::~CEnumClusCfgNetworks //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumClusCfgNetworks -- IUknkown interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::AddRef // // Description: // Increment the reference count of this object by one. // // Arguments: // None. // // Return Value: // The new reference count. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CEnumClusCfgNetworks::AddRef( void ) { TraceFunc( "[IUnknown]" ); InterlockedIncrement( &m_cRef ); CRETURN( m_cRef ); } //*** CEnumClusCfgNetworks::AddRef ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::Release // // Description: // Decrement the reference count of this object by one. // // Arguments: // None. // // Return Value: // The new reference count. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CEnumClusCfgNetworks::Release( void ) { TraceFunc( "[IUnknown]" ); LONG cRef; cRef = InterlockedDecrement( &m_cRef ); if ( cRef == 0 ) { TraceDo( delete this ); } // if: reference count equal to zero CRETURN( cRef ); } //*** CEnumClusCfgNetworks::Release ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::QueryInterface // // Description: // Query this object for the passed in interface. // // Arguments: // riidIn // Id of interface requested. // // ppvOut // Pointer to the requested interface. // // Return Value: // S_OK // If the interface is available on this object. // // E_NOINTERFACE // If the interface is not available. // // E_POINTER // ppvOut was NULL. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumClusCfgNetworks::QueryInterface( REFIID riidIn , void ** ppvOut ) { TraceQIFunc( riidIn, ppvOut ); HRESULT hr = S_OK; // // Validate arguments. // Assert( ppvOut != NULL ); if ( ppvOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // // Handle known interfaces. // if ( IsEqualIID( riidIn, IID_IUnknown ) ) { *ppvOut = static_cast< IEnumClusCfgNetworks * >( this ); } // if: IUnknown else if ( IsEqualIID( riidIn, IID_IEnumClusCfgNetworks ) ) { *ppvOut = TraceInterface( __THISCLASS__, IEnumClusCfgNetworks, this, 0 ); } // else if: IEnumClusCfgNetworks else if ( IsEqualIID( riidIn, IID_IClusCfgWbemServices ) ) { *ppvOut = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 ); } // else if: IClusCfgWbemServices else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) ) { *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 ); } // else if: IClusCfgInitialize else { *ppvOut = NULL; hr = E_NOINTERFACE; } // // Add a reference to the interface if successful. // if ( SUCCEEDED( hr ) ) { ((IUnknown *) *ppvOut)->AddRef(); } // if: success Cleanup: QIRETURN_IGNORESTDMARSHALLING( hr, riidIn ); } //*** CEnumClusCfgNetworks::QueryInterface //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumClusCfgNetworks -- IClusCfgWbemServices interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::SetWbemServices // // Description: // Set the WBEM services provider. // // Arguments: // IN IWbemServices pIWbemServicesIn // // Return Value: // S_OK // Success // // E_POINTER // The pIWbemServicesIn param is NULL. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumClusCfgNetworks::SetWbemServices( IWbemServices * pIWbemServicesIn ) { TraceFunc( "[IClusCfgWbemServices]" ); HRESULT hr = S_OK; if ( pIWbemServicesIn == NULL ) { hr = THR( E_POINTER ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_SetWbemServices_Enum_Networks, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr ); goto Cleanup; } // if: m_pIWbemServices = pIWbemServicesIn; m_pIWbemServices->AddRef(); Cleanup: HRETURN( hr ); } //*** CEnumClusCfgNetworks::SetWbemServices //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumClusCfgNetworks -- IClusCfgInitialize interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::Initialize // // Description: // Initialize this component. // // Arguments: // punkCallbackIn // lcidIn // // Return Value: // S_OK - Success. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumClusCfgNetworks::Initialize( IUnknown * punkCallbackIn , LCID lcidIn ) { TraceFunc( "[IClusCfgInitialize]" ); Assert( m_picccCallback == NULL ); HRESULT hr = S_OK; m_lcid = lcidIn; if ( punkCallbackIn == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // if: hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrGetComputerName( ComputerNameDnsHostname , &m_bstrNodeName , TRUE // fBestEffortIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: Cleanup: HRETURN( hr ); } //*** CEnumClusCfgNetworks::Initialize //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumClusCfgNetworks -- IEnumClusCfgNetworks interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::Next // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumClusCfgNetworks::Next( ULONG cNumberRequestedIn, IClusCfgNetworkInfo ** rgpNetworkInfoOut, ULONG * pcNumberFetchedOut ) { TraceFunc( "[IEnumClusCfgNetworks]" ); HRESULT hr = S_FALSE; ULONG cFetched = 0; ULONG idx; IClusCfgNetworkInfo * pccni; if ( rgpNetworkInfoOut == NULL ) { hr = THR( E_POINTER ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Next_Enum_Networks, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr ); goto Cleanup; } // if: if ( m_fLoadedNetworks == FALSE ) { hr = THR( HrGetNetworks() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: Assert( m_prgNetworks != NULL ); Assert( m_idxNext > 0 ); cFetched = min( cNumberRequestedIn, ( m_idxNext - m_idxEnumNext ) ); // // Copy the interfaces to the caller's array. // for ( idx = 0; idx < cFetched; idx++, m_idxEnumNext++ ) { hr = THR( ((*m_prgNetworks)[ m_idxEnumNext ])->TypeSafeQI( IClusCfgNetworkInfo, &pccni ) ); if ( FAILED( hr ) ) { break; } // if: rgpNetworkInfoOut[ idx ] = pccni; } // for: // // If a failure occured, release all the interfaces copied to the caller's // array and log the error. // if ( FAILED( hr ) ) { ULONG idxStop = idx; ULONG idxError = m_idxEnumNext; m_idxEnumNext -= idx; for ( idx = 0; idx < idxStop; idx++ ) { (rgpNetworkInfoOut[ idx ])->Release(); } // for: cFetched = 0; LOG_STATUS_REPORT_STRING_MINOR( TASKID_Minor_Next_Failed , L"[SRV] Error QI'ing for IClusCfgNetworkInfo on network object at index %d when filling output array." , idxError , hr ); goto Cleanup; } // if: if ( cFetched < cNumberRequestedIn ) { hr = S_FALSE; } // if: Cleanup: if ( pcNumberFetchedOut != NULL ) { *pcNumberFetchedOut = cFetched; } // if: HRETURN( hr ); } //*** CEnumClusCfgNetworks::Next ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::Skip // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumClusCfgNetworks::Skip( ULONG cNumberToSkipIn ) { TraceFunc( "[IEnumClusCfgNetworks]" ); HRESULT hr = S_OK; m_idxEnumNext += cNumberToSkipIn; if ( m_idxEnumNext >= m_idxNext ) { m_idxEnumNext = m_idxNext; hr = STHR( S_FALSE ); } // if: HRETURN( hr ); } //*** CEnumClusCfgNetworks::Skip ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::Reset // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumClusCfgNetworks::Reset( void ) { TraceFunc( "[IEnumClusCfgNetworks]" ); HRESULT hr = S_OK; m_idxEnumNext = 0; HRETURN( hr ); } //*** CEnumClusCfgNetworks::Reset ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::Clone // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumClusCfgNetworks::Clone( IEnumClusCfgNetworks ** ppEnumNetworksOut ) { TraceFunc( "[IEnumClusCfgNetworks]" ); HRESULT hr = S_OK; if ( ppEnumNetworksOut == NULL ) { hr = THR( E_POINTER ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Clone_Enum_Networks, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr ); goto Cleanup; } // if: hr = THR( E_NOTIMPL ); Cleanup: HRETURN( hr ); } //*** CEnumClusCfgNetworks::Clone ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::Count // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumClusCfgNetworks::Count( DWORD * pnCountOut ) { TraceFunc( "[IEnumClusCfgNetworks]" ); HRESULT hr = S_OK; if ( pnCountOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // if: if ( !m_fLoadedNetworks ) { hr = THR( HrGetNetworks() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: *pnCountOut = m_cNetworks; Cleanup: HRETURN( hr ); } //*** CEnumClusCfgNetworks::Count //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumClusCfgNetworks class -- Private Methods. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::HrInit // // Description: // Initialize this component. // // Arguments: // None. // // Return Value: // // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrInit( void ) { TraceFunc( "" ); HRESULT hr = S_OK; // IUnknown Assert( m_cRef == 1 ); HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrInit ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::HrGetNetworks // // Description: // // Arguments: // // // Return Value: // // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrGetNetworks( void ) { TraceFunc( "" ); HRESULT hr = S_FALSE; BSTR bstrQuery = NULL; BSTR bstrAdapterQuery = NULL; IWbemClassObject * piwcoNetwork = NULL; IWbemClassObject * pAdapterInfo = NULL; IEnumWbemClassObject * piewcoNetworks = NULL; INetConnectionManager * pNetConManager = NULL; IEnumNetConnection * pEnumNetCon = NULL; INetConnection * pNetConnection = NULL; NETCON_PROPERTIES * pProps = NULL; ULONG cRecordsReturned; VARIANT varConnectionStatus; VARIANT varConnectionID; VARIANT varIndex; VARIANT varDHCPEnabled; DWORD sc; DWORD dwState; DWORD cNumConnectionsReturned; HRESULT hrTemp; CLSID clsidMajorId; CLSID clsidMinorId; BSTR bstrWQL = NULL; bstrWQL = TraceSysAllocString( L"WQL" ); if ( bstrWQL == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: sc = TW32( GetNodeClusterState( NULL, &dwState ) ); if ( sc != ERROR_SUCCESS ) { hr = HRESULT_FROM_WIN32( sc ); goto Cleanup; } // if: if ( dwState == ClusterStateRunning ) { hr = THR( HrLoadClusterNetworks() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: VariantInit( &varConnectionStatus ); VariantInit( &varConnectionID ); VariantInit( &varIndex ); VariantInit( &varDHCPEnabled ); // // Instantiate a connection manager object to enum the connections // hr = THR ( CoCreateInstance( CLSID_ConnectionManager , NULL , CLSCTX_ALL , IID_INetConnectionManager , reinterpret_cast< LPVOID * >( &pNetConManager ) ) ); if ( FAILED( hr ) || ( pNetConManager == NULL ) ) { STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_CoCreate_NetConnection_Manager_Failed , IDS_ERROR_ENUM_NETWORK_CONNECTIONS_FAILED , IDS_ERROR_ENUM_NETWORK_CONNECTIONS_FAILED_REF , hr ); goto Cleanup; } // // Enumerate the network connections // hr = THR( pNetConManager->EnumConnections( NCME_DEFAULT, &pEnumNetCon ) ); if ( ( FAILED( hr ) ) || ( pEnumNetCon == NULL ) ) { STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_Enumerate_Network_Connections_Failed , IDS_ERROR_ENUM_NETWORK_CONNECTIONS_FAILED , IDS_ERROR_ENUM_NETWORK_CONNECTIONS_FAILED_REF , hr ); goto Cleanup; } // if: hr = pEnumNetCon->Reset(); if ( FAILED( hr ) ) { STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_Reset_Network_Connections_Enum_Failed , IDS_ERROR_ENUM_NETWORK_CONNECTIONS_FAILED , IDS_ERROR_ENUM_NETWORK_CONNECTIONS_FAILED_REF , hr ); goto Cleanup; } // // Loop through the networks and skip inappropriate networks and form the network array // for ( ; ; ) { // // There are several "continue"s in this loop, so lets make sure we clean up before we start a new loop // if ( pNetConnection != NULL ) { pNetConnection->Release(); pNetConnection = NULL; } // if: if ( piewcoNetworks != NULL ) { piewcoNetworks->Release(); piewcoNetworks = NULL; } // if: if ( piwcoNetwork != NULL ) { piwcoNetwork->Release(); piwcoNetwork = NULL; } // if: if ( pAdapterInfo != NULL ) { pAdapterInfo->Release(); pAdapterInfo = NULL; } // if: // // Free network connection properties // NcFreeNetconProperties( pProps ); pProps = NULL; hr = STHR( pEnumNetCon->Next( 1, &pNetConnection, &cNumConnectionsReturned ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: else if ( ( hr == S_FALSE ) && ( cNumConnectionsReturned == 0 ) ) { hr = S_OK; break; } // else if: Assert( pNetConnection != NULL ); hr = THR( pNetConnection->GetProperties( &pProps ) ); if ( ( FAILED( hr ) ) || ( pProps == NULL ) ) { goto Cleanup; } // if: // // Create an ID for this particular network connection. We will use this ID later if there are issues with // this network connection. // hrTemp = THR( CoCreateGuid( &clsidMajorId ) ); if ( FAILED( hrTemp ) ) { LogMsg( L"[SRV] Could not create a guid for a network connection." ); clsidMajorId = IID_NULL; } // if: // // Get the NetworkAdapter WMI object with the specified NetConnectionID // hr = HrFormatStringIntoBSTR( L"Select * from Win32_NetworkAdapter where NetConnectionID='%1!ws!'", &bstrQuery, pProps->pszwName ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // We are executing a query which we assume will find 1 matching record since NetConnectionID is a unique value // hr = THR( m_pIWbemServices->ExecQuery( bstrWQL, bstrQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &piewcoNetworks ) ); if ( FAILED( hr ) ) { STATUS_REPORT_STRING( TASKID_Major_Find_Devices , clsidMajorId , IDS_INFO_NETWORK_CONNECTION_CONCERN , pProps->pszwName , hr ); STATUS_REPORT_STRING_REF( clsidMajorId , TASKID_Minor_WMI_NetworkAdapter_Qry_Failed , IDS_ERROR_WMI_NETWORKADAPTER_QRY_FAILED , pProps->pszwName , IDS_ERROR_WMI_NETWORKADAPTER_QRY_FAILED_REF , hr ); goto Cleanup; } // if: // // Get the network returned into piwcoNetwork // hr = THR( piewcoNetworks->Next( WBEM_INFINITE, 1, &piwcoNetwork, &cRecordsReturned ) ); if ( FAILED( hr ) ) { STATUS_REPORT_STRING( TASKID_Major_Find_Devices , clsidMajorId , IDS_INFO_NETWORK_CONNECTION_CONCERN , pProps->pszwName , hr ); STATUS_REPORT_STRING_REF( clsidMajorId , TASKID_Minor_WQL_Network_Qry_Next_Failed , IDS_ERROR_WQL_QRY_NEXT_FAILED , bstrQuery , IDS_ERROR_WQL_QRY_NEXT_FAILED_REF , hr ); goto Cleanup; } // if: else if ( hr == S_FALSE ) { TraceSysFreeString( bstrQuery ); bstrQuery = NULL; hr = S_OK; continue; } TraceSysFreeString( bstrQuery ); bstrQuery = NULL; // // Get the NetConnectionID. Only "real" hardware adapters will have this as a non-NULL property. // // TODO: 31-OCT-2001 Ozano & GalenB // // Do we really need this piece of code after we start looping using INetConnection // hr = HrGetWMIProperty( piwcoNetwork, L"NetConnectionID", VT_BSTR, &varConnectionID ); if ( ( hr == E_PROPTYPEMISMATCH ) && ( varConnectionID.vt == VT_NULL ) ) { hr = S_OK; // don't want a yellow bang in the UI STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_Not_Managed_Networks , IDS_INFO_NOT_MANAGED_NETWORKS , IDS_INFO_NOT_MANAGED_NETWORKS_REF , hr ); hrTemp = THR( CoCreateGuid( &clsidMinorId ) ); if ( FAILED( hrTemp ) ) { LogMsg( L"[SRV] Could not create a guid for a not connected network minor task ID" ); clsidMinorId = IID_NULL; } // if: STATUS_REPORT_STRING_REF( TASKID_Minor_Not_Managed_Networks , clsidMinorId , IDS_WARN_NETWORK_SKIPPED , pProps->pszwName , IDS_WARN_NETWORK_SKIPPED_REF , hr ); continue; // skip this adapter } // if: else if ( FAILED( hr ) ) { THR( hr ); goto Cleanup; } // else if: // // Check the connection status of this adapter and skip it if it is not connected. // hr = THR( HrGetWMIProperty( piwcoNetwork, L"NetConnectionStatus", VT_I4, &varConnectionStatus ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // If the network adapter is not connected then skip it. // if ( varConnectionStatus.iVal != STATUS_CONNECTED ) { hr = S_OK; // don't want a yellow bang in the UI STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_Not_Managed_Networks , IDS_INFO_NOT_MANAGED_NETWORKS , IDS_INFO_NOT_MANAGED_NETWORKS_REF , hr ); hrTemp = THR( CoCreateGuid( &clsidMinorId ) ); if ( FAILED( hrTemp ) ) { LogMsg( L"[SRV] Could not create a guid for a not connected network minor task ID" ); clsidMinorId = IID_NULL; } // if: STATUS_REPORT_STRING2_REF( TASKID_Minor_Not_Managed_Networks , clsidMinorId , IDS_WARN_NETWORK_NOT_CONNECTED , varConnectionID.bstrVal , varConnectionStatus.iVal , IDS_WARN_NETWORK_NOT_CONNECTED_REF , hr ); continue; } // if: // // If it is a bridged network connection, display a warning // if ( pProps->MediaType == NCM_BRIDGE ) { // This is the virtual bridged network connection STATUS_REPORT_STRING( TASKID_Major_Find_Devices , clsidMajorId , IDS_INFO_NETWORK_CONNECTION_CONCERN , pProps->pszwName , hr ); hrTemp = S_FALSE; STATUS_REPORT_STRING_REF( clsidMajorId , TASKID_Minor_Bridged_Network , IDS_WARN_NETWORK_BRIDGE_ENABLED , pProps->pszwName , IDS_WARN_NETWORK_BRIDGE_ENABLED_REF , hrTemp ); } // if: ( pProps->MediaType == NCM_BRIDGE ) else if ( ( pProps->dwCharacter & NCCF_BRIDGED ) == NCCF_BRIDGED ) { // This is one of the end points of a bridged network connection STATUS_REPORT_STRING( TASKID_Major_Find_Devices , clsidMajorId , IDS_INFO_NETWORK_CONNECTION_CONCERN , pProps->pszwName , hr ); hrTemp = S_FALSE; STATUS_REPORT_STRING_REF( clsidMajorId , TASKID_Minor_Bridged_Network , IDS_WARN_NETWORK_BRIDGE_ENDPOINT , pProps->pszwName , IDS_WARN_NETWORK_BRIDGE_ENDPOINT_REF , hrTemp ); continue; // skip end point connections since they do not have an IP address } // else if: ( ( pProps->dwCharacter & NCCF_BRIDGED ) == NCCF_BRIDGED ) // // If it is a firewall enabled network connection, display a warning // if ( ( pProps->dwCharacter & NCCF_FIREWALLED ) == NCCF_FIREWALLED ) { STATUS_REPORT_STRING( TASKID_Major_Find_Devices , clsidMajorId , IDS_INFO_NETWORK_CONNECTION_CONCERN , pProps->pszwName , hr ); hrTemp = S_FALSE; STATUS_REPORT_STRING_REF( clsidMajorId , TASKID_Minor_Network_Firewall_Enabled , IDS_WARN_NETWORK_FIREWALL_ENABLED , pProps->pszwName , IDS_WARN_NETWORK_FIREWALL_ENABLED_REF , hrTemp ); } // if: ( ( pProps->dwCharacter & NCCF_FIREWALLED ) == NCCF_FIREWALLED ) // // At this stage we should only have real LAN adapters. // Assert( pProps->MediaType == NCM_LAN ); // // Get the Index No. of this adapter // hr = THR( HrGetWMIProperty( piwcoNetwork, L"Index", VT_I4, &varIndex ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // Get the associated NetworkAdapterConfiguration WMI object. First, format the Query string // hr = HrFormatStringIntoBSTR( L"Win32_NetworkAdapterConfiguration.Index=%1!u!", &bstrAdapterQuery, varIndex.iVal ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // Then, get the Object // hr = THR( m_pIWbemServices->GetObject( bstrAdapterQuery , WBEM_FLAG_RETURN_WBEM_COMPLETE , NULL , &pAdapterInfo , NULL ) ); if ( FAILED ( hr ) ) { goto Cleanup; } // if: TraceSysFreeString( bstrAdapterQuery ); bstrAdapterQuery = NULL; // // Find out if this adapter is DHCP enabled. If it is, send out a warning. // hr = THR( HrGetWMIProperty( pAdapterInfo, L"DHCPEnabled", VT_BOOL, &varDHCPEnabled ) ); if ( FAILED ( hr ) ) { goto Cleanup; } // if: if ( ( varDHCPEnabled.vt == VT_BOOL ) && ( varDHCPEnabled.boolVal == VARIANT_TRUE ) ) { STATUS_REPORT_STRING( TASKID_Major_Find_Devices , clsidMajorId , IDS_INFO_NETWORK_CONNECTION_CONCERN , pProps->pszwName , hr ); hr = S_FALSE; STATUS_REPORT_STRING_REF( clsidMajorId , TASKID_Minor_HrGetNetworks_DHCP_Enabled , IDS_WARN_DHCP_ENABLED , varConnectionID.bstrVal , IDS_WARN_DHCP_ENABLED_REF , hr ); if ( FAILED ( hr ) ) { goto Cleanup; } } // if: hr = STHR( HrCreateAndAddNetworkToArray( piwcoNetwork, &clsidMajorId, pProps->pszwName ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // for: // // Check for any NLB network adapters and if there is one then send a warning status report. // hr = THR( HrCheckForNLBS() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: m_idxEnumNext = 0; m_fLoadedNetworks = TRUE; goto Cleanup; Cleanup: VariantClear( &varConnectionStatus ); VariantClear( &varConnectionID ); VariantClear( &varIndex ); VariantClear( &varDHCPEnabled ); TraceSysFreeString( bstrWQL ); TraceSysFreeString( bstrQuery ); TraceSysFreeString( bstrAdapterQuery ); NcFreeNetconProperties( pProps ); if ( piwcoNetwork != NULL ) { piwcoNetwork->Release(); } // if: if ( piewcoNetworks != NULL ) { piewcoNetworks->Release(); } // if: if ( pAdapterInfo != NULL ) { pAdapterInfo->Release(); } // if: if ( pNetConnection != NULL ) { pNetConnection->Release(); } // if: if ( pNetConManager != NULL ) { pNetConManager->Release(); } // if: if ( pEnumNetCon != NULL ) { pEnumNetCon->Release(); } // if: HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrGetNetworks ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks:HrAddNetworkToArray // // Description: // Add the passed in Network to the array of punks that holds the Networks. // // Arguments: // // // Return Value: // S_OK // Success // // E_OUTOFMEMORY // Couldn't allocate memeory. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrAddNetworkToArray( IUnknown * punkIn ) { TraceFunc( "" ); HRESULT hr = S_OK; IUnknown * ((*prgpunks)[]) = NULL; prgpunks = (IUnknown *((*)[])) TraceReAlloc( m_prgNetworks, sizeof( IUnknown * ) * ( m_idxNext + 1 ), HEAP_ZERO_MEMORY ); if ( prgpunks == NULL ) { hr = THR( E_OUTOFMEMORY ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrAddNetworkToArray, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr ); goto Cleanup; } // if: m_prgNetworks = prgpunks; (*m_prgNetworks)[ m_idxNext++ ] = punkIn; punkIn->AddRef(); m_cNetworks += 1; Cleanup: HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrAddNetworkToArray ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::HrCreateAndAddNetworkToArray // // Description: // Create a IClusCfgStorageDevice object and add the passed in Network to // the array of punks that holds the Networks. // // Arguments: // // // Return Value: // S_OK // Success // // E_OUTOFMEMORY // Couldn't allocate memory. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrCreateAndAddNetworkToArray( IWbemClassObject * pNetworkIn , const CLSID * pclsidMajorIdIn , LPCWSTR pwszNetworkNameIn ) { TraceFunc( "" ); Assert( pNetworkIn != NULL ); Assert( pclsidMajorIdIn != NULL ); Assert( pwszNetworkNameIn != NULL ); HRESULT hr = S_FALSE; IUnknown * punk = NULL; IClusCfgSetWbemObject * piccswo = NULL; bool fRetainObject = true; hr = THR( CClusCfgNetworkInfo::S_HrCreateInstance( &punk ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: punk = TraceInterface( L"CClusCfgNetworkInfo", IUnknown, punk, 1 ); hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) ); if ( FAILED( hr )) { goto Cleanup; } // if: hr = THR( HrSetWbemServices( punk, m_pIWbemServices ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( punk->TypeSafeQI( IClusCfgSetWbemObject, &piccswo ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( piccswo->SetWbemObject( pNetworkIn, &fRetainObject ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( ( hr == S_OK ) && ( fRetainObject ) ) { hr = STHR( HrIsThisNetworkUnique( punk, pNetworkIn, pclsidMajorIdIn, pwszNetworkNameIn ) ); if ( hr == S_OK ) { hr = THR( HrAddNetworkToArray( punk ) ); } // if: } // if: Cleanup: if ( piccswo != NULL ) { piccswo->Release(); } // if: if ( punk != NULL ) { punk->Release(); } // if: HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrCreateAndAddNetworkToArray ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks:HrIsThisNetworkUnique // // Description: // Does a network for this IP Address and subnet already exist? // // Arguments: // // // Return Value: // S_OK // Success // // S_FALSE // This network is a duplicate. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrIsThisNetworkUnique( IUnknown * punkIn , IWbemClassObject * pNetworkIn , const CLSID * pclsidMajorIdIn , LPCWSTR pwszNetworkNameIn ) { TraceFunc( "" ); Assert( punkIn != NULL ); Assert( pNetworkIn != NULL ); Assert( pclsidMajorIdIn != NULL ); Assert( pwszNetworkNameIn != NULL ); HRESULT hr = S_OK; ULONG idx; IClusCfgNetworkInfo * piccni = NULL; IClusCfgNetworkInfo * piccniSource = NULL; BSTR bstr = NULL; BSTR bstrSource = NULL; BSTR bstrAdapterName = NULL; BSTR bstrConnectionName = NULL; BSTR bstrMessage = NULL; VARIANT var; IClusCfgClusterNetworkInfo * picccni = NULL; IClusCfgClusterNetworkInfo * picccniSource = NULL; VariantInit( &var ); hr = THR( punkIn->TypeSafeQI( IClusCfgNetworkInfo, &piccniSource ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccniSource->TypeSafeQI( IClusCfgClusterNetworkInfo, &picccniSource ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( picccniSource->HrGetNetUID( &bstrSource, pclsidMajorIdIn, pwszNetworkNameIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( ( hr == S_FALSE ) && ( bstrSource == NULL ) ) { LOG_STATUS_REPORT_STRING( L"Unable to get a UID for '%1!ws!'.", pwszNetworkNameIn, hr ); goto Cleanup; } // if: TraceMemoryAddBSTR( bstrSource ); for ( idx = 0; idx < m_idxNext; idx++ ) { hr = THR( ((*m_prgNetworks)[ idx ])->TypeSafeQI( IClusCfgNetworkInfo, &piccni ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccni->GetUID( &bstr ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( ( hr == S_FALSE ) && ( bstr != NULL ) ) { BSTR bstrTemp = NULL; THR( piccni->GetName( &bstrTemp ) ); LOG_STATUS_REPORT_STRING( L" Unable to get a UID for '%1!ws!'.", ( bstrTemp != NULL ) ? bstrTemp : L"", hr ); SysFreeString( bstrTemp ); goto Cleanup; } // if: TraceMemoryAddBSTR( bstr ); if ( NBSTRCompareCase( bstr, bstrSource ) == 0 ) { hr = THR( piccni->TypeSafeQI( IClusCfgClusterNetworkInfo, &picccni ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( picccni->HrIsClusterNetwork() ); picccni->Release(); picccni = NULL; // // If the network in the enum was already a cluster network then we do not need // to warn the user. // if ( hr == S_OK ) { hr = S_FALSE; // tell the caller that this is a duplicate network } // if: else if ( hr == S_FALSE ) // warn the user { HRESULT hrTemp; CLSID clsidMinorId; hr = THR( HrGetWMIProperty( pNetworkIn, L"Name", VT_BSTR, &var ) ); if ( FAILED( hr ) ) { bstrAdapterName = NULL; } // if: else { bstrAdapterName = TraceSysAllocString( var.bstrVal ); } // else: VariantClear( &var ); hr = THR( HrGetWMIProperty( pNetworkIn, L"NetConnectionID", VT_BSTR, &var ) ); if ( FAILED( hr ) ) { bstrConnectionName = NULL; } // if: else { bstrConnectionName = TraceSysAllocString( var.bstrVal ); } // else: hr = S_OK; // don't want a yellow bang in the UI STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_Not_Managed_Networks , IDS_INFO_NOT_MANAGED_NETWORKS , IDS_INFO_NOT_MANAGED_NETWORKS_REF , hr ); hr = THR( HrFormatMessageIntoBSTR( g_hInstance , IDS_ERROR_WMI_NETWORKADAPTER_DUPE_FOUND , &bstrMessage , bstrAdapterName != NULL ? bstrAdapterName : L"Unknown" , bstrConnectionName != NULL ? bstrConnectionName : L"Unknown" ) ); if ( FAILED( hr ) ) { bstrMessage = NULL; hr = S_OK; } // if: hrTemp = THR( CoCreateGuid( &clsidMinorId ) ); if ( FAILED( hrTemp ) ) { LogMsg( L"[SRV] Could not create a guid for a duplicate network minor task ID" ); clsidMinorId = IID_NULL; } // if: hrTemp = THR( HrSendStatusReport( m_picccCallback , TASKID_Minor_Not_Managed_Networks , clsidMinorId , 0 , 1 , 1 , hr , bstrMessage != NULL ? bstrMessage : L"An adapter with a duplicate IP address and subnet was found." , IDS_ERROR_WMI_NETWORKADAPTER_DUPE_FOUND_REF ) ); if ( FAILED( hrTemp ) ) { hr = hrTemp; goto Cleanup; } // if: // Indicate to the caller that this network is not unique. hr = S_FALSE; } // else if: break; } // if: ( NBSTRCompareCase( bstr, bstrSource ) == 0 ) piccni->Release(); piccni = NULL; TraceSysFreeString( bstr ); bstr = NULL; } // for: Cleanup: if ( picccniSource != NULL ) { picccniSource->Release(); } // if: if ( piccniSource != NULL ) { piccniSource->Release(); } // if: if ( picccni != NULL ) { picccni->Release(); } // if: if ( piccni != NULL ) { piccni->Release(); } // if: VariantClear( &var ); TraceSysFreeString( bstrAdapterName ); TraceSysFreeString( bstrConnectionName ); TraceSysFreeString( bstrMessage ); TraceSysFreeString( bstrSource ); TraceSysFreeString( bstr ); HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrIsThisNetworkUnique ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks:HrCheckForNLBS // // Description: // Are there any soft NLBS adapters? If there is then send a warning status report. // // Arguments: // None. // // Return Value: // S_OK - The operation completed successfully. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrCheckForNLBS( void ) { TraceFunc( "" ); HRESULT hr = S_OK; IWbemClassObject * piwcoNetwork = NULL; IEnumWbemClassObject * piewcoNetworks = NULL; BSTR bstrAdapterName = NULL; BSTR bstrWQL = NULL; BSTR bstrQuery = NULL; ULONG cRecordsReturned; bstrWQL = TraceSysAllocString( L"WQL" ); if ( bstrWQL == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: // // Load the NLBS Soft adapter name. // hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_NLBS_SOFT_ADAPTER_NAME, &bstrAdapterName ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // Form the WMI query string. // hr = HrFormatStringIntoBSTR( L"Select * from Win32_NetworkAdapter where Name='%1!ws!'", &bstrQuery, bstrAdapterName ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // Execute this query and see if there are any NLB network adapters. // hr = THR( m_pIWbemServices->ExecQuery( bstrWQL, bstrQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &piewcoNetworks ) ); if ( FAILED( hr ) ) { STATUS_REPORT_STRING_REF( TASKID_Major_Find_Devices , TASKID_Minor_WMI_NetworkAdapter_Qry_Failed , IDS_ERROR_WMI_NETWORKADAPTER_QRY_FAILED , bstrQuery , IDS_ERROR_WMI_NETWORKADAPTER_QRY_FAILED_REF , hr ); goto Cleanup; } // if: // // Loop through the adapters returned. Actually we break out of the loop after the first pass. // The "for" loop is for future use in case we ever want to loop through every individual record returned. // for ( ; ; ) { hr = piewcoNetworks->Next( WBEM_INFINITE, 1, &piwcoNetwork, &cRecordsReturned ); if ( ( hr == S_OK ) && ( cRecordsReturned == 1 ) ) { // // NLB network adapter was found. // Send a warning status report and break out of the loop. // STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_Warning_NLBS_Detected , IDS_WARN_NLBS_DETECTED , IDS_WARN_NLBS_DETECTED_REF , S_FALSE // Display warning in UI ); break; } // if: NLB adapter found else if ( ( hr == S_FALSE ) && ( cRecordsReturned == 0 ) ) { // // There were no NLB adapters found. // hr = S_OK; break; } // else if: no NLB adapters found else { // // An error occurred. // STATUS_REPORT_STRING_REF( TASKID_Major_Find_Devices , TASKID_Minor_WQL_Network_Qry_Next_Failed , IDS_ERROR_WQL_QRY_NEXT_FAILED , bstrQuery , IDS_ERROR_WQL_QRY_NEXT_FAILED_REF , hr ); goto Cleanup; } // else: } // for ever Cleanup: TraceSysFreeString( bstrAdapterName ); TraceSysFreeString( bstrWQL ); TraceSysFreeString( bstrQuery ); if ( piwcoNetwork != NULL ) { piwcoNetwork->Release(); } // if: if ( piewcoNetworks != NULL ) { piewcoNetworks->Release(); } // if: HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrCheckForNLBS ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks:HrLoadClusterNetworks // // Description: // Load the cluster networks. // // Arguments: // // // Return Value: // S_OK // Success. // // Other HRESULT errors. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrLoadClusterNetworks( void ) { TraceFunc( "" ); HRESULT hr = S_OK; HCLUSTER hCluster = NULL; HCLUSENUM hEnum = NULL; DWORD sc; DWORD idx; DWORD cchNetworkName = 64; DWORD cchNetInterfaceName = 64; WCHAR * pszNetworkName = NULL; WCHAR * pszNetInterfaceName = NULL; BSTR bstrNetInterfaceName = NULL; DWORD dwType; HNETWORK hNetwork = NULL; HNETINTERFACE hNetInterface = NULL; BSTR bstrLocalNetBIOSName = NULL; // // Get netbios name for the GetClusterNetInterface clusapi call. // hr = THR( HrGetComputerName( ComputerNameNetBIOS, &bstrLocalNetBIOSName, TRUE ) ); if ( FAILED( hr ) ) { LOG_STATUS_REPORT( L"[SRV] Failed to get the local computer net bios name.", hr ); goto Cleanup; } // if: hCluster = OpenCluster( NULL ); if ( hCluster == NULL ) { sc = TW32( GetLastError() ); goto MakeHr; } // if: hEnum = ClusterOpenEnum( hCluster, CLUSTER_ENUM_NETWORK ); if ( hEnum == NULL ) { sc = TW32( GetLastError() ); goto MakeHr; } // if: pszNetworkName = new WCHAR [ cchNetworkName ]; if ( pszNetworkName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: pszNetInterfaceName = new WCHAR [ cchNetInterfaceName ]; if ( pszNetInterfaceName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: // // Enumerate all the network connections on this node. // for ( idx = 0; ; ) { // // Get the next network name. // sc = ClusterEnum( hEnum, idx, &dwType, pszNetworkName, &cchNetworkName ); if ( sc == ERROR_NO_MORE_ITEMS ) { break; } // if: if ( sc == ERROR_MORE_DATA ) { delete [] pszNetworkName; pszNetworkName = NULL; cchNetworkName++; pszNetworkName = new WCHAR [ cchNetworkName ]; if ( pszNetworkName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: sc = ClusterEnum( hEnum, idx, &dwType, pszNetworkName, &cchNetworkName ); } // if: if ( sc != ERROR_SUCCESS ) { TW32( sc ); goto MakeHr; } // if: ClusterEnum() failed. // // Get the network handle using the network name. // hNetwork = OpenClusterNetwork( hCluster, pszNetworkName ); if ( hNetwork == NULL ) { sc = TW32( GetLastError() ); hr = HRESULT_FROM_WIN32( sc ); LOG_STATUS_REPORT_STRING( L"[SRV] Cannot open cluster network \"%1!ws!\".", pszNetworkName, hr ); goto Cleanup; } // if: OpenClusterNetwork() failed. // // Get the network interface name on this node for the // current network name. // sc = GetClusterNetInterface( hCluster , bstrLocalNetBIOSName , pszNetworkName , pszNetInterfaceName , &cchNetInterfaceName ); if ( sc == ERROR_MORE_DATA ) { delete [] pszNetInterfaceName; pszNetInterfaceName = NULL; cchNetInterfaceName++; pszNetInterfaceName = new WCHAR [ cchNetInterfaceName ]; if ( pszNetInterfaceName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: sc = GetClusterNetInterface( hCluster , bstrLocalNetBIOSName , pszNetworkName , pszNetInterfaceName , &cchNetInterfaceName ); } // if: ( sc == ERROR_MORE_DATA ) if ( ( sc != ERROR_SUCCESS ) && ( sc != ERROR_CLUSTER_NETINTERFACE_NOT_FOUND ) ) { hr = HRESULT_FROM_WIN32( TW32( sc ) ); LOG_STATUS_REPORT_STRING( L"[SRV] Error locating a network interface for cluster network \"%1!ws!\".", pszNetworkName, hr ); goto Cleanup; } // if: GetClusterNetInterface() failed. if ( sc == ERROR_CLUSTER_NETINTERFACE_NOT_FOUND ) { // // If we get ERROR_CLUSTER_NETINTERFACE_NOT_FOUND for // any reason then display a warning regarding this network // interface on this node and find a valid (=enabled, working) // network interface on another node. // hr = S_FALSE; STATUS_REPORT_STRING2_REF( TASKID_Major_Find_Devices , TASKID_Minor_Network_Interface_Not_Found , IDS_WARN_NETWORK_INTERFACE_NOT_FOUND , pszNetworkName , bstrLocalNetBIOSName , IDS_WARN_NETWORK_INTERFACE_NOT_FOUND_REF , hr ); // // Find a valid network interface name of another node on this network. // hr = THR( HrFindNetInterface( hNetwork, &bstrNetInterfaceName ) ); if ( FAILED( hr ) ) { LOG_STATUS_REPORT_STRING( L"[SRV] Can not find a network interface for cluster network \"%1!ws!\".", pszNetworkName, hr ); goto Cleanup; } // if: HrFindNetInterface failed. } // if: sc == ERROR_CLUSTER_NETINTERFACE_NOT_FOUND else { // // We have a network interface name on this node // bstrNetInterfaceName = TraceSysAllocString ( pszNetInterfaceName ); if ( bstrNetInterfaceName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: } // else: sc == ERROR_SUCCESS Assert( bstrNetInterfaceName != NULL ); // // Open the network interface handle using the network interface // name. // hNetInterface = OpenClusterNetInterface( hCluster, bstrNetInterfaceName ); if ( hNetInterface == NULL ) { // // If we don't have network interface handle by now // we'll log an error and goto cleanup. // sc = TW32( GetLastError() ); hr = HRESULT_FROM_WIN32( sc ); LOG_STATUS_REPORT_STRING2( L"[SRV] Can not open the cluster network interface \"%1!ws!\" for cluster network \"%2!ws!\" on this node." , pszNetInterfaceName , pszNetworkName , hr ); goto Cleanup; } // if: Could not open the network interface. else { hr = THR( HrLoadClusterNetwork( hNetwork, hNetInterface ) ); if ( FAILED( hr ) ) { LOG_STATUS_REPORT_STRING( L"[SRV] Can not load information for cluster network \"%1!ws!\".", pszNetworkName, hr ); goto Cleanup; } // if: CloseClusterNetInterface( hNetInterface ); hNetInterface = NULL; } // else: Could open the network interface. CloseClusterNetwork( hNetwork ); hNetwork = NULL; idx++; } // for: Assert( hr == S_OK ); goto Cleanup; MakeHr: hr = HRESULT_FROM_WIN32( sc ); goto Cleanup; Cleanup: LOG_STATUS_REPORT( L"[SRV] Completed loading the cluster networks.", hr ); if ( hNetInterface != NULL ) { CloseClusterNetInterface( hNetInterface ); } // if: if ( hNetwork != NULL ) { CloseClusterNetwork( hNetwork ); } // if: if ( hEnum != NULL ) { ClusterCloseEnum( hEnum ); } // if: if ( hCluster != NULL ) { CloseCluster( hCluster ); } // if: delete [] pszNetworkName; delete [] pszNetInterfaceName; TraceSysFreeString( bstrNetInterfaceName ); TraceSysFreeString( bstrLocalNetBIOSName ); HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrLoadClusterNetworks ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks:HrLoadClusterNetwork // // Description: // Load the cluster network and put it into the array of networks. // // Arguments: // hNetworkIn // hNetInterfaceIn // // Return Value: // S_OK // Success. // // Other HRESULT errors. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrLoadClusterNetwork( HNETWORK hNetworkIn , HNETINTERFACE hNetInterfaceIn ) { TraceFunc( "" ); Assert( hNetworkIn != NULL ); Assert( hNetInterfaceIn != NULL ); HRESULT hr; IUnknown * punk = NULL; IUnknown * punkCallback = NULL; hr = THR( m_picccCallback->TypeSafeQI( IUnknown, &punkCallback ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // Have to pass the Initialize interface arguments since new objects will // be created when this call is made. // hr = THR( CClusCfgNetworkInfo::S_HrCreateInstance( hNetworkIn, hNetInterfaceIn, punkCallback, m_lcid, m_pIWbemServices, &punk ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // This is special -- do not initialize this again. // //hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) ); //if ( FAILED( hr )) //{ // goto Cleanup; //} // if: //hr = THR( HrSetWbemServices( punk, m_pIWbemServices ) ); //if ( FAILED( hr ) ) //{ // goto Cleanup; //} // if: hr = THR( HrAddNetworkToArray( punk ) ); goto Cleanup; Cleanup: if ( punkCallback != NULL ) { punkCallback->Release(); } // if: if ( punk != NULL ) { punk->Release(); } // if: HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrLoadClusterNetwork ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumClusCfgNetworks::HrFindNetInterface // // Description: // Finds the first network interface name for the passed in network. // // Arguments: // // // Return Value: // S_OK // Success. // // HRESULT version of error ERROR_CLUSTER_NETINTERFACE_NOT_FOUND // or other HRESULTS // Failure. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumClusCfgNetworks::HrFindNetInterface( HNETWORK hNetworkIn , BSTR * pbstrNetInterfaceNameOut ) { TraceFunc( "" ); Assert( hNetworkIn != NULL ); Assert( pbstrNetInterfaceNameOut != NULL ); HRESULT hr = S_OK; DWORD sc; HNETWORKENUM hEnum = NULL; WCHAR * pszNetInterfaceName = NULL; DWORD cchNetInterfaceName = 64; DWORD idx; DWORD dwType; *pbstrNetInterfaceNameOut = NULL; // // Create a netinterface enum for the passed in network. // hEnum = ClusterNetworkOpenEnum( hNetworkIn, CLUSTER_NETWORK_ENUM_NETINTERFACES ); if ( hEnum == NULL ) { sc = TW32( GetLastError() ); hr = HRESULT_FROM_WIN32( sc ); LOG_STATUS_REPORT( L"[SRV] Can not open Cluster Network enumeration.", hr ); goto Cleanup; } // if: pszNetInterfaceName = new WCHAR [ cchNetInterfaceName ]; if ( pszNetInterfaceName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: for ( idx = 0; ; ) { sc = ClusterNetworkEnum( hEnum, idx, &dwType, pszNetInterfaceName, &cchNetInterfaceName ); if ( sc == ERROR_NO_MORE_ITEMS ) { break; } // if: if ( sc == ERROR_MORE_DATA ) { delete [] pszNetInterfaceName; pszNetInterfaceName = NULL; cchNetInterfaceName++; pszNetInterfaceName = new WCHAR [ cchNetInterfaceName ]; if ( pszNetInterfaceName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: sc = ClusterNetworkEnum( hEnum, idx, &dwType, pszNetInterfaceName, &cchNetInterfaceName ); } // if: if ( sc != ERROR_SUCCESS ) { hr = HRESULT_FROM_WIN32( TW32( sc ) ); LOG_STATUS_REPORT_STRING( L"[SRV] Failed to enumerate Network Interface \"%1!ws!\".", pszNetInterfaceName != NULL ? pszNetInterfaceName : L"", hr ); goto Cleanup; } // if: ( sc != ERROR_SUCCESS ) // // Get the first enabled network interface for this network // and break out of the for loop. // *pbstrNetInterfaceNameOut = TraceSysAllocString( pszNetInterfaceName ); if ( *pbstrNetInterfaceNameOut == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: break; } // for: // // This function will either return S_OK or HRESULT version of error // ERROR_CLUSTER_NETINTERFACE_NOT_FOUND at this point. // if ( *pbstrNetInterfaceNameOut == NULL ) { hr = HRESULT_FROM_WIN32( TW32( ERROR_CLUSTER_NETINTERFACE_NOT_FOUND ) ); } // if: else { hr = S_OK; } // else: goto Cleanup; Cleanup: LOG_STATUS_REPORT_STRING( L"[SRV] Completed searching for NetInterface \"%1!ws!\".", pszNetInterfaceName != NULL ? pszNetInterfaceName : L"", hr ); if ( hEnum != NULL ) { ClusterNetworkCloseEnum( hEnum ); } // if: delete [] pszNetInterfaceName; HRETURN( hr ); } //*** CEnumClusCfgNetworks::HrFindNetInterface