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

888 lines
21 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000 Microsoft Corporation
//
// Module Name:
// IPSubnetPage.cpp
//
// Maintained By:
// Geoffrey Pease (GPease) 12-MAY-2000
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.h"
#include "IPSubnetPage.h"
DEFINE_THISCLASS("CIPSubnetPage");
#define CONVERT_ADDRESS( _addrOut, _addrIn ) \
_addrOut = ( FIRST_IPADDRESS( _addrIn ) ) | ( SECOND_IPADDRESS( _addrIn ) << 8 ) | ( THIRD_IPADDRESS( _addrIn ) << 16 ) | ( FOURTH_IPADDRESS( _addrIn ) << 24 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// CIPSubnetPage::CIPSubnetPage(
// IServiceProvider * pspIn,
// ECreateAddMode ecamCreateAddModeIn
// LONG * pulIPSubnetInout,
// BSTR * pbstrNetworkNameInout,
// ULONG * pulIPAddressIn,
// BSTR * pbstrClusterNameIn
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
CIPSubnetPage::CIPSubnetPage(
IServiceProvider * pspIn,
ECreateAddMode ecamCreateAddModeIn,
ULONG * pulIPSubnetInout,
BSTR * pbstrNetworkNameInout,
ULONG * pulIPAddressIn,
BSTR * pbstrClusterNameIn
)
{
TraceFunc( "" );
Assert( pspIn != NULL );
Assert( pulIPSubnetInout != NULL );
Assert( pbstrNetworkNameInout != NULL );
Assert( pulIPAddressIn != NULL );
Assert( pbstrClusterNameIn != NULL );
// m_hwnd = NULL;
THR( pspIn->TypeSafeQI( IServiceProvider, &m_psp ) );
m_pulIPSubnet = pulIPSubnetInout;
m_pbstrNetworkName = pbstrNetworkNameInout;
m_pulIPAddress = pulIPAddressIn;
m_pbstrClusterName = pbstrClusterNameIn;
TraceFuncExit( );
} //*** CIPSubnetPage::CIPSubnetPage( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// CIPSubnetPage::~CIPSubnetPage( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
CIPSubnetPage::~CIPSubnetPage( void )
{
TraceFunc( "" );
if ( m_psp != NULL )
{
m_psp->Release( );
}
TraceFuncExit( );
} //*** CIPSubnetPage::~CIPSubnetPage( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// LRESULT
// CIPSubnetPage::OnInitDialog( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CIPSubnetPage::OnInitDialog( void )
{
TraceFunc( "" );
BOOL bRet;
LRESULT lr = FALSE; // Didn't set focus
if ( *m_pulIPSubnet != 0 )
{
ULONG ulIPSubnet;
CONVERT_ADDRESS( ulIPSubnet, *m_pulIPSubnet );
SendDlgItemMessage( m_hwnd, IDC_IP_SUBNETMASK, IPM_SETADDRESS, 0, ulIPSubnet );
}
RETURN( lr );
} //*** CIPSubnetPage::OnInitDialog( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// LRESULT
// CIPSubnetPage::OnCommand(
// UINT idNotificationIn,
// UINT idControlIn,
// HWND hwndSenderIn
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CIPSubnetPage::OnCommand(
UINT idNotificationIn,
UINT idControlIn,
HWND hwndSenderIn
)
{
TraceFunc( "" );
LRESULT lr = FALSE;
switch ( idControlIn )
{
case IDC_IP_SUBNETMASK:
if ( idNotificationIn == IPN_FIELDCHANGED
|| idNotificationIn == EN_CHANGE
)
{
THR( HrUpdateWizardButtons( ) );
lr = TRUE;
}
break;
case IDC_CB_NETWORKS:
if ( idNotificationIn == CBN_SELCHANGE )
{
THR( HrUpdateWizardButtons( ) );
lr = TRUE;
}
break;
}
RETURN( lr );
} //*** CIPSubnetPage::OnCommand( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CIPSubnetPage::HrUpdateWizardButtons( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
CIPSubnetPage::HrUpdateWizardButtons( void )
{
TraceFunc( "" );
LRESULT lr;
ULONG ulIPSubnet;
HRESULT hr = S_OK;
DWORD dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
lr = SendDlgItemMessage( m_hwnd, IDC_IP_SUBNETMASK, IPM_ISBLANK, 0, 0 );
if ( lr != 0 )
{
dwFlags &= ~PSWIZB_NEXT;
}
lr = ComboBox_GetCurSel( GetDlgItem( m_hwnd, IDC_CB_NETWORKS ) );
if ( lr == CB_ERR )
{
dwFlags &= ~PSWIZB_NEXT;
}
PropSheet_SetWizButtons( GetParent( m_hwnd ), dwFlags );
HRETURN( hr );
} //*** CIPSubnetPage::HrUpdateWizardButtons( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// LRESULT
// CIPSubnetPage::OnNotify(
// WPARAM idCtrlIn,
// LPNMHDR pnmhdrIn
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CIPSubnetPage::OnNotify(
WPARAM idCtrlIn,
LPNMHDR pnmhdrIn
)
{
TraceFunc( "" );
LRESULT lr = TRUE;
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, 0 );
switch( pnmhdrIn->code )
{
case PSN_SETACTIVE:
lr = OnNotifySetActive( );
break;
case PSN_KILLACTIVE:
lr = OnNotifyKillActive( );
break;
case PSN_WIZNEXT:
lr = OnNotifyWizNext( );
break;
case PSN_QUERYCANCEL:
lr = OnNotifyQueryCancel( );
break;
}
RETURN( lr );
} //*** CIPSubnetPage::OnNotify( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// LRESULT
// CIPSubnetPage::OnNotifyQueryCancel( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CIPSubnetPage::OnNotifyQueryCancel( void )
{
TraceFunc( "" );
LRESULT lr = TRUE;
int iRet;
iRet = MessageBoxFromStrings( m_hwnd,
IDS_QUERY_CANCEL_TITLE,
IDS_QUERY_CANCEL_TEXT,
MB_YESNO
);
if ( iRet == IDNO )
{
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
}
RETURN( lr );
} //*** CIPSubnetPage::OnNotifyQueryCancel( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// LRESULT
// CIPSubnetPage::OnNotifySetActive( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CIPSubnetPage::OnNotifySetActive( void )
{
TraceFunc( "" );
LRESULT lr = TRUE;
HWND hwndIP = GetDlgItem( m_hwnd, IDC_IP_SUBNETMASK );
HWND hwndCB = GetDlgItem( m_hwnd, IDC_CB_NETWORKS );
WCHAR szIPAddress[ ARRAYSIZE( "255 . 255 . 255 . 255" ) ];
LRESULT lrCB;
HRESULT hr;
THR( HrUpdateWizardButtons( ) );
//
// Set the IP address string.
//
wnsprintf( szIPAddress,
ARRAYSIZE( szIPAddress ),
L"%u . %u . %u . %u",
FOURTH_IPADDRESS( *m_pulIPAddress ),
THIRD_IPADDRESS( *m_pulIPAddress ),
SECOND_IPADDRESS( *m_pulIPAddress ),
FIRST_IPADDRESS( *m_pulIPAddress )
);
SetDlgItemText( m_hwnd, IDC_E_IPADDRESS, szIPAddress );
//
// Add networks to the combobox.
//
hr = STHR( HrAddNetworksToComboBox( hwndCB ) );
//
// Set the subnet mask based on what was found from
// the networks added to the combobox.
//
if ( *m_pulIPSubnet != 0 )
{
ULONG ulIPSubnet;
CONVERT_ADDRESS( ulIPSubnet, *m_pulIPSubnet );
SendMessage( hwndIP, IPM_SETADDRESS, 0, ulIPSubnet );
}
//
// If there isn't a selected network, select the first one.
//
lrCB = ComboBox_GetCurSel( hwndCB );
if ( lrCB == CB_ERR )
{
ComboBox_SetCurSel( hwndCB, 0 );
}
//
// Determine if we need to show this page.
//
if ( hr == S_OK )
{
OnNotifyWizNext();
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
}
RETURN( lr );
} //*** CIPSubnetPage::OnNotifySetActive( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// LRESULT
// CIPSubnetPage::OnNotifyKillActive( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CIPSubnetPage::OnNotifyKillActive( void )
{
TraceFunc( "" );
LRESULT lr = TRUE;
HWND hwndCB = GetDlgItem( m_hwnd, IDC_CB_NETWORKS );
LRESULT citems;
//
// Release all the network info interfaces stored in the combobox.
//
citems = ComboBox_GetCount( hwndCB );
Assert( citems != CB_ERR );
if ( ( citems != CB_ERR )
&& ( citems > 0 ) )
{
LRESULT idx;
LRESULT lrItemData;
IClusCfgNetworkInfo * pccni;
for ( idx = 0 ; idx < citems ; idx++ )
{
lrItemData = ComboBox_GetItemData( hwndCB, idx );
Assert( lrItemData != CB_ERR );
pccni = reinterpret_cast< IClusCfgNetworkInfo * >( lrItemData );
pccni->Release();
} // for: each item in the combobox
} // if: retrieved combobox count and combobox not empty
ComboBox_ResetContent( hwndCB );
RETURN( lr );
} //*** CIPSubnetPage::OnNotifyKillActive( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// LRESULT
// CIPSubnetPage::OnNotifyWizNext( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CIPSubnetPage::OnNotifyWizNext( void )
{
TraceFunc( "" );
OBJECTCOOKIE cookieDummy;
LRESULT lr = TRUE;
LRESULT lrCB;
HRESULT hr;
ULONG ulIPSubnet;
HWND hwndCB = GetDlgItem( m_hwnd, IDC_CB_NETWORKS );
IUnknown * punk = NULL;
IObjectManager * pom = NULL;
IClusCfgClusterInfo * pccci = NULL;
IClusCfgNetworkInfo * pccni = NULL;
SendDlgItemMessage( m_hwnd, IDC_IP_SUBNETMASK, IPM_GETADDRESS, 0, (LPARAM) &ulIPSubnet );
CONVERT_ADDRESS( *m_pulIPSubnet, ulIPSubnet );
//
// Grab the object manager.
//
hr = THR( m_psp->TypeSafeQS( CLSID_ObjectManager,
IObjectManager,
&pom
) );
if ( FAILED( hr ) )
goto Error;
//
// Get the cluster configuration info.
//
hr = THR( pom->FindObject( CLSID_ClusterConfigurationType,
NULL,
*m_pbstrClusterName,
DFGUID_ClusterConfigurationInfo,
&cookieDummy,
&punk
) );
if ( FAILED( hr ) )
goto Error;
hr = THR( punk->TypeSafeQI( IClusCfgClusterInfo, &pccci ) );
if ( FAILED( hr ) )
goto Cleanup;
//
// Set the IP subnet mask.
//
hr = THR( pccci->SetSubnetMask( *m_pulIPSubnet ) );
if ( FAILED( hr ) )
goto Error;
//
// Get the selected network.
//
//
// Set the network.
//
lrCB = ComboBox_GetCurSel( hwndCB );
Assert( lrCB != CB_ERR );
lrCB = ComboBox_GetItemData( hwndCB, lrCB );
Assert( lrCB != CB_ERR );
pccni = reinterpret_cast< IClusCfgNetworkInfo * >( lrCB );
hr = THR( pccci->SetNetworkInfo( pccni ) );
if ( FAILED( hr ) )
goto Error;
Cleanup:
if ( punk != NULL )
{
punk->Release( );
}
if ( pccci != NULL )
{
pccci->Release( );
}
if ( pom != NULL )
{
pom->Release( );
}
RETURN( lr );
Error:
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
goto Cleanup;
} //*** CIPSubnetPage::OnNotifyWizNext( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CIPSubnetPage::HrAddNetworksToComboBox( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
CIPSubnetPage::HrAddNetworksToComboBox(
HWND hwndCBIn
)
{
TraceFunc( "" );
HRESULT hr = S_OK;
IUnknown * punk = NULL;
IObjectManager * pom = NULL;
IEnumCookies * pec = NULL;
IEnumClusCfgNetworks * peccn = NULL;
IClusCfgNetworkInfo * pccni = NULL;
BSTR bstrNetName = NULL;
OBJECTCOOKIE cookieCluster;
OBJECTCOOKIE cookieNode;
OBJECTCOOKIE cookieDummy;
ULONG celtDummy;
bool fFoundNetwork = false;
LRESULT lr;
LRESULT lrIndex;
Assert( hwndCBIn != NULL );
ComboBox_ResetContent( hwndCBIn );
//
// Grab the object manager.
//
hr = THR( m_psp->TypeSafeQS(
CLSID_ObjectManager,
IObjectManager,
&pom
) );
if ( FAILED( hr ) )
goto Cleanup;
//
// Get the cluster configuration info cookie.
//
hr = THR( pom->FindObject(
CLSID_ClusterConfigurationType,
NULL,
*m_pbstrClusterName,
IID_NULL,
&cookieCluster,
&punk
) );
Assert( punk == NULL );
if ( FAILED( hr ) )
goto Cleanup;
//
// Get the enumeration of nodes whose parent is this cluster.
// We want the enumeration of cookies (indicated by using
// DFGUID_EnumCookies) because we want to use the cookie of the
// node to search for all networks on that node.
//
hr = THR( pom->FindObject(
CLSID_NodeType,
cookieCluster,
NULL,
DFGUID_EnumCookies,
&cookieDummy,
&punk
) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( punk->TypeSafeQI( IEnumCookies, &pec ) );
if ( FAILED( hr ) )
goto Cleanup;
pec = TraceInterface( L"CIPSubnetPage!IEnumCookies", IEnumCookies, pec, 1 );
punk->Release( );
punk = NULL;
//
// Get the cookie for the first node in the node enumeration.
//
hr = THR( pec->Next( 1, &cookieNode, &celtDummy ) );
if ( FAILED( hr ) )
goto Cleanup;
//
// Get the network enumerator.
//
hr = THR( pom->FindObject(
CLSID_NetworkType,
cookieNode,
NULL,
DFGUID_EnumManageableNetworks,
&cookieDummy,
&punk
) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( punk->TypeSafeQI( IEnumClusCfgNetworks, &peccn ) );
if ( FAILED( hr ) )
goto Cleanup;
punk->Release( );
punk = NULL;
//
// Add each network to the combobox.
//
for ( ;; )
{
// Get the next network.
hr = STHR( peccn->Next( 1, &pccni, &celtDummy ) );
if ( hr == S_FALSE )
break;
if ( FAILED( hr ) )
goto Cleanup;
// Skip this network if it isn't public.
hr = STHR( pccni->IsPublic() );
if ( hr == S_OK )
{
// Get the name of the network.
hr = THR( pccni->GetName( &bstrNetName ) );
if ( SUCCEEDED( hr ) )
{
TraceMemoryAddBSTR( bstrNetName );
// Add the network to the combobox.
lrIndex = ComboBox_AddString( hwndCBIn, bstrNetName );
Assert( ( lrIndex != CB_ERR )
&& ( lrIndex != CB_ERRSPACE )
);
// Add the netinfo interface to the combobox as well.
if ( ( lrIndex != CB_ERR )
&& ( lrIndex != CB_ERRSPACE ) )
{
pccni->AddRef();
lr = ComboBox_SetItemData( hwndCBIn, lrIndex, pccni );
Assert( lr != CB_ERR );
}
// Determine if this network matches the user's IP address.
// If it is, select it in the combobox.
if ( ! fFoundNetwork )
{
hr = STHR( HrMatchNetwork( pccni, bstrNetName ) );
if ( hr == S_OK )
{
fFoundNetwork = true;
lr = ComboBox_SetCurSel( hwndCBIn, lrIndex );
Assert( lr != CB_ERR );
}
}
// Cleanup.
TraceSysFreeString( bstrNetName );
bstrNetName = NULL;
} // if: name retrieved successfully
} // if: network is public
pccni->Release();
pccni = NULL;
} // forever
if ( fFoundNetwork )
{
hr = S_OK;
}
else
{
hr = S_FALSE;
}
Cleanup:
if ( punk != NULL )
{
punk->Release( );
}
if ( bstrNetName != NULL )
{
SysFreeString( bstrNetName );
}
if ( pccni != NULL )
{
pccni->Release();
}
if ( peccn != NULL )
{
peccn->Release();
}
if ( pec != NULL )
{
pec->Release();
}
if ( pom != NULL )
{
pom->Release();
}
HRETURN( hr );
} //*** CIPSubnetPage::HrAddNetworksToComboBox( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CIPSubnetPage::HrMatchNetwork(
// IClusCfgNetworkInfo * pccniIn,
// BSTR bstrNetworkNameIn
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
CIPSubnetPage::HrMatchNetwork(
IClusCfgNetworkInfo * pccniIn,
BSTR bstrNetworkNameIn
)
{
TraceFunc( "" );
HRESULT hr = S_OK;
IClusCfgIPAddressInfo * pccipai = NULL;
ULONG ulIPAddress;
ULONG ulIPSubnet;
Assert( pccniIn != NULL );
Assert( bstrNetworkNameIn != NULL );
//
// Get the IP Address Info for the network.
//
hr = THR( pccniIn->GetPrimaryNetworkAddress( &pccipai ) );
if ( FAILED( hr ) )
goto Cleanup;
//
// Get the address and subnet of the network.
//
hr = THR( pccipai->GetIPAddress( &ulIPAddress ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( pccipai->GetSubnetMask( &ulIPSubnet ) );
if ( FAILED( hr ) )
goto Cleanup;
//
// Determine if these match.
//
if ( ClRtlAreTcpipAddressesOnSameSubnet( *m_pulIPAddress, ulIPAddress, ulIPSubnet) )
{
// Save the subnet mask.
*m_pulIPSubnet = ulIPSubnet;
// Save the name of the network.
if ( *m_pbstrNetworkName == NULL )
{
*m_pbstrNetworkName = TraceSysAllocString( bstrNetworkNameIn );
if ( *m_pbstrNetworkName == NULL )
goto OutOfMemory;
}
else
{
INT iRet = TraceSysReAllocString( m_pbstrNetworkName, bstrNetworkNameIn );
if ( ! iRet )
goto OutOfMemory;
}
} // if: match found
else
{
hr = S_FALSE;
}
Cleanup:
if ( pccipai != NULL )
{
pccipai->Release();
}
HRETURN( hr );
OutOfMemory:
hr = E_OUTOFMEMORY;
goto Cleanup;
} //*** CIPSubnetPage::HrMatchNetwork( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// [static]
// INT_PTR
// CALLBACK
// CIPSubnetPage::S_DlgProc(
// HWND hDlgIn,
// UINT MsgIn,
// WPARAM wParam,
// LPARAM lParam
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
INT_PTR
CALLBACK
CIPSubnetPage::S_DlgProc(
HWND hDlgIn,
UINT MsgIn,
WPARAM wParam,
LPARAM lParam
)
{
// Don't do TraceFunc because every mouse movement
// will cause this function to be called.
WndMsg( hDlgIn, MsgIn, wParam, lParam );
LRESULT lr = FALSE;
CIPSubnetPage * pPage = reinterpret_cast< CIPSubnetPage *> ( GetWindowLongPtr( hDlgIn, GWLP_USERDATA ) );
if ( MsgIn == WM_INITDIALOG )
{
PROPSHEETPAGE * ppage = reinterpret_cast< PROPSHEETPAGE * >( lParam );
SetWindowLongPtr( hDlgIn, GWLP_USERDATA, (LPARAM) ppage->lParam );
pPage = reinterpret_cast< CIPSubnetPage * >( ppage->lParam );
pPage->m_hwnd = hDlgIn;
}
if ( pPage != NULL )
{
Assert( hDlgIn == pPage->m_hwnd );
switch( MsgIn )
{
case WM_INITDIALOG:
lr = pPage->OnInitDialog( );
break;
case WM_NOTIFY:
lr = pPage->OnNotify( wParam, reinterpret_cast< LPNMHDR >( lParam ) );
break;
case WM_COMMAND:
lr= pPage->OnCommand( HIWORD( wParam ), LOWORD( wParam ), (HWND) lParam );
break;
// no default clause needed
}
}
return lr;
} //*** CIPSubnetPage::S_DlgProc( )