You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1695 lines
48 KiB
1695 lines
48 KiB
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
ripview.cpp
|
|
IPX RIP node implementation.
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "util.h"
|
|
#include "ripview.h"
|
|
#include "reg.h"
|
|
#include "rtrutil.h" // smart MPR handle pointers
|
|
#include "ripstrm.h" // IPAdminConfigStream
|
|
#include "strmap.h" // XXXtoCString functions
|
|
#include "service.h" // TFS service APIs
|
|
#include "format.h" // FormatNumber function
|
|
#include "coldlg.h" // columndlg
|
|
#include "column.h" // ComponentConfigStream
|
|
#include "rtrui.h"
|
|
#include "ripprop.h" // RIP property pages
|
|
#include "routprot.h" // IP_LOCAL
|
|
#include "ipxstrm.h"
|
|
#include "ipxutil.h" // String conversions
|
|
#include "globals.h" // IPX defaults
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Keep this in sync with the column ids in ripview.h
|
|
---------------------------------------------------------------------------*/
|
|
extern const ContainerColumnInfo s_rgRipViewColumnInfo[];
|
|
|
|
const ContainerColumnInfo s_rgRipViewColumnInfo[] =
|
|
{
|
|
{ IDS_RIP_COL_INTERFACE, CON_SORT_BY_STRING, TRUE, COL_IF_NAME },
|
|
{ IDS_RIP_COL_TYPE, CON_SORT_BY_STRING, TRUE, COL_IF_DEVICE },
|
|
{ IDS_RIP_COL_ACCEPT_ROUTES, CON_SORT_BY_STRING, FALSE, COL_STRING },
|
|
{ IDS_RIP_COL_SUPPLY_ROUTES, CON_SORT_BY_STRING, FALSE, COL_STRING },
|
|
{ IDS_RIP_COL_UPDATE_MODE, CON_SORT_BY_STRING, TRUE, COL_STRING },
|
|
{ IDS_RIP_COL_UPDATE_PERIOD, CON_SORT_BY_DWORD, FALSE, COL_DURATION },
|
|
{ IDS_RIP_COL_AGE_MULTIPLIER, CON_SORT_BY_DWORD, FALSE, COL_SMALL_NUM },
|
|
{ IDS_RIP_COL_ADMIN_STATE, CON_SORT_BY_STRING, TRUE, COL_STATUS },
|
|
{ IDS_RIP_COL_OPER_STATE, CON_SORT_BY_STRING, TRUE, COL_STATUS },
|
|
{ IDS_RIP_COL_PACKETS_SENT, CON_SORT_BY_DWORD, TRUE, COL_LARGE_NUM },
|
|
{ IDS_RIP_COL_PACKETS_RECEIVED, CON_SORT_BY_DWORD, TRUE, COL_LARGE_NUM },
|
|
};
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
RipNodeHandler implementation
|
|
---------------------------------------------------------------------------*/
|
|
|
|
RipNodeHandler::RipNodeHandler(ITFSComponentData *pCompData)
|
|
: BaseContainerHandler(pCompData, RIP_COLUMNS,
|
|
s_rgRipViewColumnInfo),
|
|
m_ulConnId(0),
|
|
m_ulRmConnId(0),
|
|
m_ulRefreshConnId(0),
|
|
m_ulStatsConnId(0)
|
|
{
|
|
// Setup the verb states
|
|
m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
|
|
m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
|
|
|
|
m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
|
|
m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
|
|
|
|
}
|
|
|
|
|
|
STDMETHODIMP RipNodeHandler::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
// Is the pointer bad?
|
|
if (ppv == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
// Place NULL in *ppv in case of failure
|
|
*ppv = NULL;
|
|
|
|
// This is the non-delegating IUnknown implementation
|
|
if (riid == IID_IUnknown)
|
|
*ppv = (LPVOID) this;
|
|
else if (riid == IID_IRtrAdviseSink)
|
|
*ppv = &m_IRtrAdviseSink;
|
|
else
|
|
return BaseContainerHandler::QueryInterface(riid, ppv);
|
|
|
|
// If we're going to return an interface, AddRef it first
|
|
if (*ppv)
|
|
{
|
|
((LPUNKNOWN) *ppv)->AddRef();
|
|
return hrOK;
|
|
}
|
|
else
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::DestroyHandler
|
|
Implementation of ITFSNodeHandler::DestroyHandler
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipNodeHandler::DestroyHandler(ITFSNode *pNode)
|
|
{
|
|
IPXConnection * pIPXConn;
|
|
|
|
pIPXConn = GET_RIP_NODEDATA(pNode);
|
|
pIPXConn->Release();
|
|
|
|
if (m_ulRefreshConnId)
|
|
{
|
|
SPIRouterRefresh spRefresh;
|
|
if (m_spRouterInfo)
|
|
m_spRouterInfo->GetRefreshObject(&spRefresh);
|
|
if (spRefresh)
|
|
spRefresh->UnadviseRefresh(m_ulRefreshConnId);
|
|
}
|
|
m_ulRefreshConnId = 0;
|
|
|
|
if (m_ulStatsConnId)
|
|
{
|
|
SPIRouterRefresh spRefresh;
|
|
if (m_spRouterInfo)
|
|
m_spRouterInfo->GetRefreshObject(&spRefresh);
|
|
if (spRefresh)
|
|
spRefresh->UnadviseRefresh(m_ulStatsConnId);
|
|
}
|
|
m_ulStatsConnId = 0;
|
|
|
|
|
|
if (m_ulConnId)
|
|
m_spRmProt->RtrUnadvise(m_ulConnId);
|
|
m_ulConnId = 0;
|
|
m_spRmProt.Release();
|
|
|
|
if (m_ulRmConnId)
|
|
m_spRm->RtrUnadvise(m_ulRmConnId);
|
|
m_ulRmConnId = 0;
|
|
m_spRm.Release();
|
|
|
|
WaitForStatisticsWindow(&m_RIPParamsStats);
|
|
|
|
m_spRouterInfo.Release();
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::HasPropertyPages
|
|
Implementation of ITFSNodeHandler::HasPropertyPages
|
|
NOTE: the root node handler has to over-ride this function to
|
|
handle the snapin manager property page (wizard) case!!!
|
|
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
RipNodeHandler::HasPropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::CreatePropertyPages
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
RipNodeHandler::CreatePropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
HRESULT hr = hrOK;
|
|
RipProperties * pProperties = NULL;
|
|
SPIComponentData spComponentData;
|
|
CString stTitle;
|
|
|
|
CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
|
|
|
|
pProperties = new RipProperties(pNode, spComponentData,
|
|
m_spTFSCompData, stTitle);
|
|
|
|
CORg( pProperties->Init(m_spRm) );
|
|
|
|
if (lpProvider)
|
|
hr = pProperties->CreateModelessSheet(lpProvider, handle);
|
|
else
|
|
hr = pProperties->DoModelessSheet();
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Menu data structure for our menus
|
|
---------------------------------------------------------------------------*/
|
|
|
|
static const SRouterNodeMenu s_rgIfNodeMenu[] =
|
|
{
|
|
{ IDS_MENU_RIP_SHOW_PARAMS, 0,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP },
|
|
};
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::OnAddMenuItems
|
|
Implementation of ITFSNodeHandler::OnAddMenuItems
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipNodeHandler::OnAddMenuItems(
|
|
ITFSNode *pNode,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
LPDATAOBJECT lpDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType,
|
|
long *pInsertionAllowed)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = S_OK;
|
|
RipNodeHandler::SMenuData menuData;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
menuData.m_spNode.Set(pNode);
|
|
|
|
hr = AddArrayOfMenuItems(pNode, s_rgIfNodeMenu,
|
|
DimensionOf(s_rgIfNodeMenu),
|
|
pContextMenuCallback,
|
|
*pInsertionAllowed,
|
|
reinterpret_cast<INT_PTR>(&menuData));
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::OnCommand
|
|
Implementation of ITFSNodeHandler::OnCommand
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipNodeHandler::OnCommand(ITFSNode *pNode, long nCommandId,
|
|
DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
HRESULT hr = S_OK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
switch (nCommandId)
|
|
{
|
|
case IDS_MENU_RIP_SHOW_PARAMS:
|
|
CreateNewStatisticsWindow(&m_RIPParamsStats,
|
|
::FindMMCMainWindow(),
|
|
IDD_STATS_NARROW);
|
|
break;
|
|
case IDS_MENU_SYNC:
|
|
SynchronizeNodeData(pNode);
|
|
break;
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::OnExpand
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::OnExpand(ITFSNode *pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType,
|
|
LPARAM arg,
|
|
LPARAM lParam)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPIEnumInterfaceInfo spEnumIf;
|
|
SPIInterfaceInfo spIf;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
SPIInfoBase spInfoBase;
|
|
|
|
if (m_bExpanded)
|
|
return hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
|
|
|
|
while (spEnumIf->Next(1, &spIf, NULL) == hrOK)
|
|
{
|
|
if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) == hrOK)
|
|
{
|
|
if (spRmIf->FindRtrMgrProtocolInterface(IPX_PROTOCOL_RIP, NULL) == hrOK)
|
|
{
|
|
// Now we create an interface node for this interface
|
|
AddInterfaceNode(pNode, spIf, FALSE);
|
|
}
|
|
|
|
}
|
|
spRmIf.Release();
|
|
spIf.Release();
|
|
}
|
|
|
|
//$CLIENT: Add the client interface (setup default data)
|
|
// the only thing that we can do in synchronize is to
|
|
// get the Administrative status
|
|
AddInterfaceNode(pNode, NULL, TRUE);
|
|
|
|
m_bExpanded = TRUE;
|
|
|
|
// Now that we have all of the nodes, update the data for
|
|
// all of the nodes
|
|
SynchronizeNodeData(pNode);
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
m_bExpanded = TRUE;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::GetString
|
|
Implementation of ITFSNodeHandler::GetString
|
|
We don't need to do anything, since our root node is an extension
|
|
only and thus can't do anything to the node text.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(LPCTSTR) RipNodeHandler::GetString(ITFSNode *pNode, int nCol)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_stTitle.IsEmpty())
|
|
m_stTitle.LoadString(IDS_IPX_RIP_TITLE);
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return m_stTitle;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::OnCreateDataObject
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipNodeHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
|
|
Assert(m_spRmProt);
|
|
|
|
CORg( CreateDataObjectFromRtrMgrProtocolInfo(m_spRmProt,
|
|
type, cookie, m_spTFSCompData,
|
|
ppDataObject) );
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::Init
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::Init(IRouterInfo *pRouter, RipConfigStream *pConfigStream)
|
|
{
|
|
m_spRouterInfo.Set(pRouter);
|
|
|
|
m_spRm.Release();
|
|
pRouter->FindRtrMgr(PID_IPX, &m_spRm);
|
|
|
|
m_spRmProt.Release();
|
|
m_spRm->FindRtrMgrProtocol(IPX_PROTOCOL_RIP, &m_spRmProt);
|
|
|
|
m_pConfigStream = pConfigStream;
|
|
|
|
// Also need to register for change notifications from IPX_PROTOCOL_RIP
|
|
Assert(m_ulConnId == 0);
|
|
m_spRmProt->RtrAdvise(&m_IRtrAdviseSink, &m_ulConnId, 0);
|
|
|
|
// Need to register for change notifications on the Router manager
|
|
// This way we can add the necessary protocols when an interface
|
|
// gets added.
|
|
Assert(m_ulRmConnId == 0);
|
|
m_spRm->RtrAdvise(&m_IRtrAdviseSink, &m_ulRmConnId, 0);
|
|
|
|
m_RIPParamsStats.SetConfigInfo(pConfigStream, RIPSTRM_STATS_RIPPARAMS);
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::ConstructNode
|
|
Initializes the root node (sets it up).
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::ConstructNode(ITFSNode *pNode)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
IPXConnection * pIPXConn = NULL;
|
|
|
|
if (pNode == NULL)
|
|
return hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
// Need to initialize the data for the root node
|
|
pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
|
|
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
|
|
pNode->SetData(TFS_DATA_SCOPEID, 0);
|
|
|
|
// This is a leaf node in the scope pane
|
|
pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
|
|
|
|
m_cookie = reinterpret_cast<DWORD_PTR>(pNode);
|
|
pNode->SetData(TFS_DATA_COOKIE, m_cookie);
|
|
|
|
pNode->SetNodeType(&GUID_IPXRipNodeType);
|
|
|
|
|
|
pIPXConn = new IPXConnection;
|
|
pIPXConn->SetMachineName(m_spRouterInfo->GetMachineName());
|
|
|
|
SET_RIP_NODEDATA(pNode, pIPXConn);
|
|
|
|
m_RIPParamsStats.SetConnectionData(pIPXConn);
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
if (!FHrSucceeded(hr))
|
|
{
|
|
SET_RIP_NODEDATA(pNode, NULL);
|
|
if (pIPXConn)
|
|
pIPXConn->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::AddInterfaceNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::AddInterfaceNode(ITFSNode *pParent,
|
|
IInterfaceInfo *pIf,
|
|
BOOL fClient)
|
|
{
|
|
Assert(pParent);
|
|
|
|
RipInterfaceHandler * pHandler;
|
|
SPITFSResultHandler spHandler;
|
|
SPITFSNode spNode;
|
|
HRESULT hr = hrOK;
|
|
BaseIPXResultNodeData * pData;
|
|
IPXConnection * pIPXConn;
|
|
SPIInfoBase spInfoBase;
|
|
PRIP_IF_CONFIG pric = NULL;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
|
|
// Create the handler for this node
|
|
pHandler = new RipInterfaceHandler(m_spTFSCompData);
|
|
spHandler = pHandler;
|
|
CORg( pHandler->Init(pIf, m_spRouterInfo, pParent) );
|
|
|
|
pIPXConn = GET_RIP_NODEDATA(pParent);
|
|
|
|
// Create a result item node (or a leaf node)
|
|
CORg( CreateLeafTFSNode(&spNode,
|
|
NULL,
|
|
static_cast<ITFSNodeHandler *>(pHandler),
|
|
static_cast<ITFSResultHandler *>(pHandler),
|
|
m_spNodeMgr) );
|
|
CORg( pHandler->ConstructNode(spNode, pIf, pIPXConn) );
|
|
|
|
pData = GET_BASEIPXRESULT_NODEDATA(spNode);
|
|
Assert(pData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pData);
|
|
|
|
pData->m_fClient = fClient;
|
|
|
|
// If we don't have an interface, then this is a client node
|
|
if (pIf)
|
|
{
|
|
pIf->FindRtrMgrInterface(PID_IPX, &spRmIf);
|
|
|
|
if (spRmIf)
|
|
spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
|
|
|
|
if (spInfoBase)
|
|
spInfoBase->GetData(IPX_PROTOCOL_RIP, 0, (LPBYTE *) &pric);
|
|
|
|
Trace1("Adding RIP node : %s\n", pIf->GetTitle());
|
|
}
|
|
else
|
|
{
|
|
// This is a client, make it visible
|
|
pric = (PRIP_IF_CONFIG) ULongToPtr(0xFFFFFFFF);
|
|
|
|
Trace0("Adding client interface\n");
|
|
}
|
|
|
|
// if pric == NULL, then we are adding this protocol to the
|
|
// interface and we need to hide the node.
|
|
if (pric)
|
|
{
|
|
CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
|
|
CORg( spNode->Show() );
|
|
}
|
|
else
|
|
CORg( spNode->SetVisibilityState(TFS_VIS_HIDE) );
|
|
CORg( pParent->AddChild(spNode) );
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
This is the set of menus that will appear when a right-click is
|
|
done on the blank area of the result pane.
|
|
---------------------------------------------------------------------------*/
|
|
static const SRouterNodeMenu s_rgRipResultNodeMenu[] =
|
|
{
|
|
{ IDS_MENU_RIP_SHOW_PARAMS, 0,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP },
|
|
};
|
|
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::AddMenuItems
|
|
Implementation of ITFSResultHandler::AddMenuItems
|
|
Use this to add commands to the context menu of the blank areas
|
|
of the result pane.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipNodeHandler::AddMenuItems(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT pDataObject,
|
|
LPCONTEXTMENUCALLBACK pCallback,
|
|
long *pInsertionAllowed)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spNode;
|
|
RipNodeHandler::SMenuData menuData;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
menuData.m_spNode.Set(spNode);
|
|
|
|
hr = AddArrayOfMenuItems(spNode,
|
|
s_rgRipResultNodeMenu,
|
|
DimensionOf(s_rgRipResultNodeMenu),
|
|
pCallback,
|
|
*pInsertionAllowed,
|
|
reinterpret_cast<INT_PTR>(&menuData));
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::Command
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipNodeHandler::Command(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
int nCommandID,
|
|
LPDATAOBJECT pDataObject)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
SPITFSNode spNode;
|
|
HRESULT hr = hrOK;
|
|
|
|
switch (nCommandID)
|
|
{
|
|
case IDS_MENU_RIP_SHOW_PARAMS:
|
|
CreateNewStatisticsWindow(&m_RIPParamsStats,
|
|
::FindMMCMainWindow(),
|
|
IDD_STATS_NARROW);
|
|
break;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
ImplementEmbeddedUnknown(RipNodeHandler, IRtrAdviseSink)
|
|
|
|
STDMETHODIMP RipNodeHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
|
|
DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
|
|
{
|
|
InitPThis(RipNodeHandler, IRtrAdviseSink);
|
|
SPITFSNode spThisNode;
|
|
SPITFSNode spNode;
|
|
SPITFSNodeEnum spEnumNode;
|
|
SPIEnumInterfaceInfo spEnumIf;
|
|
SPIInterfaceInfo spIf;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
SPIInfoBase spInfoBase;
|
|
BOOL fPleaseAdd;
|
|
BOOL fFound;
|
|
BaseIPXResultNodeData * pData;
|
|
HRESULT hr = hrOK;
|
|
|
|
pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spThisNode);
|
|
|
|
if (dwObjectType == ROUTER_OBJ_RmIf)
|
|
{
|
|
if (dwChangeType == ROUTER_CHILD_PREADD)
|
|
{
|
|
// Add RIP to the infobase
|
|
pThis->AddProtocolToInfoBase(spThisNode);
|
|
}
|
|
else if (dwChangeType == ROUTER_CHILD_ADD)
|
|
{
|
|
// Add the protocol to the router mgr
|
|
// We need to add the protocol to the interface (use
|
|
// default values).
|
|
pThis->AddProtocolToInterface(spThisNode);
|
|
}
|
|
}
|
|
|
|
if (dwObjectType == ROUTER_OBJ_RmProtIf)
|
|
{
|
|
if (dwChangeType == ROUTER_CHILD_ADD)
|
|
{
|
|
// If the node hasn't been expanded yet, then we don't
|
|
// need to do anything yet.
|
|
if (pThis->m_bExpanded)
|
|
{
|
|
// Enumerate through the list of interfaces looking for
|
|
// the interfaces that have this protocol. If we find
|
|
// one, look for this interface in our list of nodes.
|
|
spThisNode->GetEnum(&spEnumNode);
|
|
|
|
CORg( pThis->m_spRouterInfo->EnumInterface(&spEnumIf) );
|
|
|
|
spEnumIf->Reset();
|
|
|
|
fPleaseAdd = FALSE;
|
|
|
|
for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
|
|
{
|
|
// Look for this interface in our list of nodes
|
|
// If it's there than continue on
|
|
fFound = FALSE;
|
|
spEnumNode->Reset();
|
|
spNode.Release();
|
|
|
|
for (; spEnumNode->Next(1, &spNode, NULL) == hrOK; spNode.Release())
|
|
{
|
|
pData = GET_BASEIPXRESULT_NODEDATA(spNode);
|
|
Assert(pData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pData);
|
|
|
|
if (!pData->m_fClient && StriCmpW(pData->m_spIf->GetId(), spIf->GetId()) == 0)
|
|
{
|
|
fFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If the interface was not found in the list of nodes,
|
|
// then it is a candidate. Now we have to see if the
|
|
// interface supports this transport.
|
|
if (!fFound && (LookupRtrMgrProtocolInterface(spIf, PID_IPX, IPX_PROTOCOL_RIP, NULL) == hrOK))
|
|
{
|
|
// If this interface has this transport, and is NOT in
|
|
// the current list of nodes then add this interface
|
|
// to the UI
|
|
|
|
// Grab the infobase
|
|
// Load the infobase for this interface
|
|
spRmIf.Release();
|
|
spInfoBase.Release();
|
|
hr = spIf->FindRtrMgrInterface(PID_IPX, &spRmIf);
|
|
|
|
if (FHrOK(hr))
|
|
{
|
|
spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
|
|
hr = pThis->AddInterfaceNode(spThisNode, spIf, FALSE);
|
|
}
|
|
fPleaseAdd = TRUE;
|
|
}
|
|
}
|
|
|
|
// Now that we have all of the nodes, update the data for
|
|
// all of the nodes
|
|
if (fPleaseAdd)
|
|
pThis->SynchronizeNodeData(spThisNode);
|
|
}
|
|
}
|
|
else if (dwChangeType == ROUTER_CHILD_DELETE)
|
|
{
|
|
// Go through the list of nodes, if we cannot find the
|
|
// node in the list of interfaces, delete the node
|
|
|
|
spThisNode->GetEnum(&spEnumNode);
|
|
spEnumNode->Reset();
|
|
while (spEnumNode->Next(1, &spNode, NULL) == hrOK)
|
|
{
|
|
// Get the node data, look for the interface
|
|
pData = GET_BASEIPXRESULT_NODEDATA(spNode);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pData);
|
|
|
|
if (pData->m_spIf &&
|
|
LookupRtrMgrProtocolInterface(pData->m_spIf,
|
|
PID_IPX, IPX_PROTOCOL_RIP, NULL) != hrOK)
|
|
{
|
|
// If this flag is set, then we are in the new
|
|
// interface case, and we do not want to delete
|
|
// this here since it will then deadlock.
|
|
if ((spNode->GetVisibilityState() & TFS_VIS_DELETE) == 0)
|
|
{
|
|
// cannot find the interface, release this node!
|
|
spThisNode->RemoveChild(spNode);
|
|
spNode->Destroy();
|
|
}
|
|
}
|
|
spNode.Release();
|
|
spIf.Release();
|
|
}
|
|
|
|
}
|
|
}
|
|
else if (dwChangeType == ROUTER_REFRESH)
|
|
{
|
|
if (ulConn == pThis->m_ulStatsConnId)
|
|
{
|
|
pThis->m_RIPParamsStats.PostRefresh();
|
|
}
|
|
else
|
|
pThis->SynchronizeNodeData(spThisNode);
|
|
}
|
|
else if (dwChangeType == ROUTER_DO_DISCONNECT)
|
|
{
|
|
IPXConnection * pIPXConn = NULL;
|
|
|
|
pIPXConn = GET_RIP_NODEDATA(spThisNode);
|
|
pIPXConn->DisconnectAll();
|
|
}
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT RipNodeHandler::AddProtocolToInfoBase(ITFSNode *pThisNode)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPITFSNodeEnum spEnumNode;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
SPIEnumInterfaceInfo spEnumIf;
|
|
SPIInterfaceInfo spIf;
|
|
SPITFSNode spNode;
|
|
BaseIPXResultNodeData * pData;
|
|
|
|
// Enumerate through the list of interfaces looking for
|
|
// the interfaces that have this protocol. If we find
|
|
// one, look for this interface in our list of nodes.
|
|
pThisNode->GetEnum(&spEnumNode);
|
|
|
|
CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
|
|
|
|
spEnumIf->Reset();
|
|
|
|
for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
|
|
{
|
|
// Look for this interface in our list of nodes
|
|
// If it's there than continue on
|
|
spEnumNode->Reset();
|
|
spNode.Release();
|
|
spRmIf.Release();
|
|
|
|
// If this interface has IPX but not RIP, add it
|
|
if ((spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) == hrOK) &&
|
|
(LookupRtrMgrProtocolInterface(spIf, PID_IPX,
|
|
IPX_PROTOCOL_RIP, NULL) != hrOK))
|
|
{
|
|
// Add RIP to this node
|
|
SPIInfoBase spInfoBase;
|
|
|
|
// We need to get the infobase for this and create
|
|
// the RIP blocks (but do NOT save, let the property
|
|
// sheet take care of that).
|
|
spInfoBase.Release();
|
|
if (!FHrOK(spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase)))
|
|
{
|
|
spRmIf->Load(spRmIf->GetMachineName(), NULL, NULL, NULL);
|
|
spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
|
|
}
|
|
if (!spInfoBase)
|
|
CreateInfoBase(&spInfoBase);
|
|
|
|
if (!FHrOK(spInfoBase->ProtocolExists(IPX_PROTOCOL_RIP)))
|
|
{
|
|
// Add a RIP_IF_CONFIG block
|
|
BYTE * pDefault;
|
|
|
|
if (spIf->GetInterfaceType() == ROUTER_IF_TYPE_DEDICATED)
|
|
pDefault = g_pIpxRipLanInterfaceDefault;
|
|
else
|
|
pDefault = g_pIpxRipInterfaceDefault;
|
|
spInfoBase->AddBlock(IPX_PROTOCOL_RIP,
|
|
sizeof(RIP_IF_CONFIG),
|
|
pDefault,
|
|
1,
|
|
0);
|
|
|
|
spRmIf->SetInfoBase(NULL, NULL, NULL, spInfoBase);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// Now that we have all of the nodes, update the data for
|
|
// all of the nodes
|
|
// if (fPleaseAdd)
|
|
// pThis->SynchronizeNodeData(spThisNode);
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT RipNodeHandler::AddProtocolToInterface(ITFSNode *pThisNode)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPITFSNodeEnum spEnumNode;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
SPIRtrMgrProtocolInterfaceInfo spRmProtIf;
|
|
SPIEnumInterfaceInfo spEnumIf;
|
|
SPIInterfaceInfo spIf;
|
|
SPITFSNode spNode;
|
|
BaseIPXResultNodeData * pData;
|
|
|
|
// Enumerate through the list of interfaces looking for
|
|
// the interfaces that have this protocol. If we find
|
|
// one, look for this interface in our list of nodes.
|
|
pThisNode->GetEnum(&spEnumNode);
|
|
|
|
CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
|
|
|
|
spEnumIf->Reset();
|
|
|
|
for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
|
|
{
|
|
// Look for this interface in our list of nodes
|
|
// If it's there than continue on
|
|
spEnumNode->Reset();
|
|
spNode.Release();
|
|
|
|
// If this interface has IPX but not RIP, add it
|
|
if ((spIf->FindRtrMgrInterface(PID_IPX, NULL) == hrOK) &&
|
|
(LookupRtrMgrProtocolInterface(spIf, PID_IPX,
|
|
IPX_PROTOCOL_RIP, NULL) != hrOK))
|
|
{
|
|
// Add RIP to this node
|
|
RtrMgrProtocolCB RmProtCB;
|
|
RtrMgrProtocolInterfaceCB RmProtIfCB;
|
|
SPIInfoBase spInfoBase;
|
|
|
|
// Need to create an RmProtIf
|
|
m_spRmProt->CopyCB(&RmProtCB);
|
|
|
|
spRmProtIf.Release();
|
|
|
|
RmProtIfCB.dwProtocolId = RmProtCB.dwProtocolId;
|
|
StrnCpyW(RmProtIfCB.szId, RmProtCB.szId, RTR_ID_MAX);
|
|
RmProtIfCB.dwTransportId = RmProtCB.dwTransportId;
|
|
StrnCpyW(RmProtIfCB.szRtrMgrId, RmProtCB.szRtrMgrId, RTR_ID_MAX);
|
|
|
|
StrnCpyW(RmProtIfCB.szInterfaceId, spIf->GetId(), RTR_ID_MAX);
|
|
RmProtIfCB.dwIfType = spIf->GetInterfaceType();
|
|
RmProtIfCB.szTitle[0] = 0;
|
|
|
|
CORg( CreateRtrMgrProtocolInterfaceInfo(&spRmProtIf,
|
|
&RmProtIfCB) );
|
|
|
|
spRmProtIf->SetTitle(spIf->GetTitle());
|
|
|
|
// Add this to the spRmIf
|
|
spRmIf.Release();
|
|
CORg( spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
|
|
Assert(spRmIf);
|
|
|
|
// We need to get the infobase for this and create
|
|
// the RIP blocks (but do NOT save, let the property
|
|
// sheet take care of that).
|
|
spInfoBase.Release();
|
|
// spRmIf->Load(spRmIf->GetMachineName(), NULL, NULL, NULL);
|
|
spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase);
|
|
if (!spInfoBase)
|
|
CreateInfoBase(&spInfoBase);
|
|
|
|
if (!FHrOK(spInfoBase->ProtocolExists(IPX_PROTOCOL_RIP)))
|
|
{
|
|
// Add a RIP_IF_CONFIG block
|
|
BYTE * pDefault;
|
|
|
|
if (spIf->GetInterfaceType() == ROUTER_IF_TYPE_DEDICATED)
|
|
pDefault = g_pIpxRipLanInterfaceDefault;
|
|
else
|
|
pDefault = g_pIpxRipInterfaceDefault;
|
|
|
|
spInfoBase->AddBlock(IPX_PROTOCOL_RIP,
|
|
sizeof(RIP_IF_CONFIG),
|
|
pDefault,
|
|
1,
|
|
0);
|
|
}
|
|
|
|
|
|
CORg(spRmIf->AddRtrMgrProtocolInterface(spRmProtIf,
|
|
spInfoBase /* pInfoBase */));
|
|
}
|
|
}
|
|
|
|
// Now that we have all of the nodes, update the data for
|
|
// all of the nodes
|
|
// if (fPleaseAdd)
|
|
// pThis->SynchronizeNodeData(spThisNode);
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::SynchronizeNodeData
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::SynchronizeNodeData(ITFSNode *pThisNode)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
HRESULT hr = hrOK;
|
|
SPITFSNodeEnum spNodeEnum;
|
|
SPITFSNode spNode;
|
|
CStringList ifidList;
|
|
BaseIPXResultNodeData * pNodeData;
|
|
RipList ripList;
|
|
RipListEntry * pRipEntry = NULL;
|
|
RipListEntry * pRipCurrent = NULL;
|
|
int i;
|
|
CString stNotAvailable;
|
|
POSITION pos;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
// Do the data gathering work (separate this from the rest of the
|
|
// code so that we can move this part to a background thread later).
|
|
|
|
stNotAvailable.LoadString(IDS_IPX_NOT_AVAILABLE);
|
|
|
|
// We need to build up a list of interface ids
|
|
pThisNode->GetEnum(&spNodeEnum);
|
|
for (; spNodeEnum->Next(1, &spNode, NULL) == hrOK; spNode.Release() )
|
|
{
|
|
pNodeData = GET_BASEIPXRESULT_NODEDATA(spNode);
|
|
Assert(pNodeData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
|
|
|
|
pRipEntry = new RipListEntry;
|
|
|
|
pRipEntry->m_spIf.Set(pNodeData->m_spIf);
|
|
pRipEntry->m_spNode.Set(spNode);
|
|
|
|
::ZeroMemory(&(pRipEntry->m_info), sizeof(pRipEntry->m_info));
|
|
::ZeroMemory(&(pRipEntry->m_stats), sizeof(pRipEntry->m_stats));
|
|
|
|
pRipEntry->m_fClient = pNodeData->m_fClient;
|
|
pRipEntry->m_fFoundIfIndex = FALSE;
|
|
pRipEntry->m_dwIfIndex = 0;
|
|
|
|
// The data in the m_info struct is not up to date
|
|
pRipEntry->m_fInfoUpdated = FALSE;
|
|
|
|
ripList.AddTail(pRipEntry);
|
|
pRipEntry = NULL;
|
|
|
|
// Fill in the result data with '-'
|
|
// This is a little bogus, but it's the easiest way, we
|
|
// don't want to touch interface and relay_mode.
|
|
for (i=RIP_SI_INTERFACE; i<RIP_SI_MAX_COLUMNS; i++)
|
|
{
|
|
pNodeData->m_rgData[i].m_stData = stNotAvailable;
|
|
pNodeData->m_rgData[i].m_dwData = 0xFFFFFFFF;
|
|
}
|
|
|
|
// Fill in as much data as we can at this point
|
|
if (pNodeData->m_fClient)
|
|
{
|
|
pNodeData->m_rgData[RIP_SI_INTERFACE].m_stData.LoadString(
|
|
IDS_IPX_DIAL_IN_CLIENTS);
|
|
pNodeData->m_rgData[RIP_SI_TYPE].m_stData =
|
|
IpxTypeToCString(ROUTER_IF_TYPE_CLIENT);
|
|
}
|
|
else
|
|
{
|
|
pNodeData->m_rgData[RIP_SI_INTERFACE].m_stData =
|
|
pNodeData->m_spIf->GetTitle();
|
|
|
|
pNodeData->m_rgData[RIP_SI_TYPE].m_stData =
|
|
IpxTypeToCString(pNodeData->m_spIf->GetInterfaceType());
|
|
}
|
|
|
|
}
|
|
spNode.Release();
|
|
|
|
|
|
// We can now use this list of ids, to get the data for each item
|
|
hr = GetRipData(pThisNode, &ripList);
|
|
|
|
// Now for each data item, fill in the appropriate data in
|
|
// the node
|
|
pos = ripList.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
pRipCurrent = ripList.GetNext(pos);
|
|
|
|
pNodeData = GET_BASEIPXRESULT_NODEDATA(pRipCurrent->m_spNode);
|
|
Assert(pNodeData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
|
|
|
|
if (pRipCurrent->m_fInfoUpdated)
|
|
{
|
|
pNodeData->m_rgData[RIP_SI_ACCEPT_ROUTES].m_stData =
|
|
IpxAdminStateToCString(pRipCurrent->m_info.Listen);
|
|
|
|
pNodeData->m_rgData[RIP_SI_SUPPLY_ROUTES].m_stData =
|
|
IpxAdminStateToCString(pRipCurrent->m_info.Supply);
|
|
|
|
pNodeData->m_rgData[RIP_SI_UPDATE_MODE].m_stData =
|
|
RipSapUpdateModeToCString(pRipCurrent->m_info.UpdateMode);
|
|
|
|
FillInNumberData(pNodeData, RIP_SI_UPDATE_PERIOD,
|
|
pRipCurrent->m_info.PeriodicUpdateInterval);
|
|
|
|
FillInNumberData(pNodeData, RIP_SI_AGE_MULTIPLIER,
|
|
pRipCurrent->m_info.AgeIntervalMultiplier);
|
|
|
|
pNodeData->m_rgData[RIP_SI_ADMIN_STATE].m_stData =
|
|
IpxAdminStateToCString(pRipCurrent->m_info.AdminState);
|
|
}
|
|
|
|
if (FHrSucceeded(hr) && !pRipCurrent->m_fClient)
|
|
{
|
|
pNodeData->m_rgData[RIP_SI_OPER_STATE].m_stData =
|
|
IpxOperStateToCString(pRipCurrent->m_stats.RipIfOperState);
|
|
|
|
FillInNumberData(pNodeData, RIP_SI_PACKETS_SENT,
|
|
pRipCurrent->m_stats.RipIfOutputPackets);
|
|
|
|
FillInNumberData(pNodeData, RIP_SI_PACKETS_RECEIVED,
|
|
pRipCurrent->m_stats.RipIfInputPackets);
|
|
}
|
|
|
|
pRipCurrent->m_spNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
|
|
}
|
|
|
|
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
delete pRipEntry;
|
|
while (!ripList.IsEmpty())
|
|
delete ripList.RemoveTail();
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::GetRipData
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::GetRipData(ITFSNode *pThisNode, RipList *pRipList)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
BOOL fIsServiceRunning;
|
|
IPXConnection * pIPXConn;
|
|
RIP_MIB_GET_INPUT_DATA MibGetInputData;
|
|
SPIInfoBase spInfoBase;
|
|
POSITION pos;
|
|
RipListEntry * pRipEntry;
|
|
int i;
|
|
PRIP_INTERFACE pRipIf = NULL;
|
|
DWORD cbRipIf;
|
|
SPMprMibBuffer spMib;
|
|
DWORD dwErr;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
PRIP_IF_CONFIG pric;
|
|
HRESULT hrIndex = hrOK;
|
|
|
|
|
|
// Retrieve the IP interface table; we will need this in order to
|
|
// map interface-names to interface-indices, and we will need the
|
|
// interface-indices in order to query for RIP MIB information.
|
|
//
|
|
CORg( IsRouterServiceRunning(m_spRouterInfo->GetMachineName(), NULL) );
|
|
fIsServiceRunning = (hr == hrOK);
|
|
|
|
// Get the connection data
|
|
pIPXConn = GET_RIP_NODEDATA(pThisNode);
|
|
|
|
// Iterate through the list filling in the interface indexes
|
|
hrIndex = FillInInterfaceIndex(pIPXConn, pRipList);
|
|
|
|
// Iterate throught the list of entries, gathering data for each
|
|
// interface
|
|
pos = pRipList->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
pRipEntry = pRipList->GetNext(pos);
|
|
|
|
// if (!fIsServiceRunning)
|
|
// continue;
|
|
|
|
if (pRipEntry->m_fClient)
|
|
{
|
|
// Fill in the client data
|
|
FillClientData(pRipEntry);
|
|
continue;
|
|
}
|
|
|
|
// Load the infobase and get the data for this entry
|
|
spRmIf.Release();
|
|
spInfoBase.Release();
|
|
CORg( pRipEntry->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
|
|
if (!spRmIf)
|
|
continue;
|
|
|
|
CORg( spRmIf->Load(spRmIf->GetMachineName(), NULL, NULL, NULL) );
|
|
CORg( spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase) );
|
|
CORg( spInfoBase->GetData(IPX_PROTOCOL_RIP, 0, (LPBYTE *) &pric) );
|
|
|
|
pRipEntry->m_info = pric->RipIfInfo;
|
|
pRipEntry->m_fInfoUpdated = TRUE;
|
|
|
|
if (!pRipEntry->m_fFoundIfIndex)
|
|
continue;
|
|
|
|
if (!fIsServiceRunning)
|
|
continue;
|
|
|
|
if (!FHrSucceeded(hrIndex))
|
|
continue;
|
|
|
|
// Now get the dynamic data from the MIBs
|
|
|
|
spMib.Free();
|
|
MibGetInputData.InterfaceIndex = pRipEntry->m_dwIfIndex;
|
|
MibGetInputData.TableId = RIP_INTERFACE_TABLE;
|
|
|
|
dwErr = ::MprAdminMIBEntryGet(pIPXConn->GetMibHandle(),
|
|
PID_IPX,
|
|
IPX_PROTOCOL_RIP,
|
|
&MibGetInputData,
|
|
sizeof(MibGetInputData),
|
|
(LPVOID *) &pRipIf,
|
|
&cbRipIf);
|
|
spMib = (PBYTE) pRipIf;
|
|
CWRg(dwErr);
|
|
|
|
Assert(pRipIf);
|
|
|
|
pRipEntry->m_stats = pRipIf->RipIfStats;
|
|
}
|
|
|
|
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::FillInInterfaceIndex
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::FillInInterfaceIndex(IPXConnection *pIPXConn, RipList *pRipList)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
POSITION pos;
|
|
RipListEntry * pRipEntry;
|
|
IPX_MIB_GET_INPUT_DATA MibGetInputData;
|
|
DWORD IfSize = sizeof(IPX_INTERFACE);
|
|
PIPX_INTERFACE pIpxIf;
|
|
DWORD dwErr;
|
|
SPMprMibBuffer spMib;
|
|
USES_CONVERSION;
|
|
|
|
MibGetInputData.TableId = IPX_INTERFACE_TABLE;
|
|
dwErr = ::MprAdminMIBEntryGetFirst(pIPXConn->GetMibHandle(),
|
|
PID_IPX,
|
|
IPX_PROTOCOL_BASE,
|
|
&MibGetInputData,
|
|
sizeof(IPX_MIB_GET_INPUT_DATA),
|
|
(LPVOID *) &pIpxIf,
|
|
&IfSize);
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
spMib = (LPBYTE) pIpxIf;
|
|
|
|
while (FHrSucceeded(hr))
|
|
{
|
|
// go through the list of interfaces looking for a match
|
|
pos = pRipList->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
pRipEntry = pRipList->GetNext(pos);
|
|
|
|
// If this is the client interface, we don't need to
|
|
// look for an interface that matches
|
|
if (pRipEntry->m_fClient)
|
|
continue;
|
|
|
|
if (StriCmp(pRipEntry->m_spIf->GetId(),
|
|
A2CT((LPCSTR) pIpxIf->InterfaceName)) == 0)
|
|
{
|
|
Assert(pRipEntry->m_fFoundIfIndex == FALSE);
|
|
|
|
pRipEntry->m_dwIfIndex = pIpxIf->InterfaceIndex;
|
|
pRipEntry->m_fFoundIfIndex = TRUE;
|
|
break;
|
|
}
|
|
pRipEntry = NULL;
|
|
}
|
|
|
|
// Go onto the next interface
|
|
|
|
MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex =
|
|
pIpxIf->InterfaceIndex;
|
|
spMib.Free();
|
|
pIpxIf = NULL;
|
|
|
|
dwErr = ::MprAdminMIBEntryGetNext(pIPXConn->GetMibHandle(),
|
|
PID_IPX,
|
|
IPX_PROTOCOL_BASE,
|
|
&MibGetInputData,
|
|
sizeof(IPX_MIB_GET_INPUT_DATA),
|
|
(LPVOID *) &pIpxIf,
|
|
&IfSize);
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
spMib = (LPBYTE) pIpxIf;
|
|
}
|
|
|
|
|
|
//Error:
|
|
return hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) ? hrOK : hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::FillClientData
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::FillClientData(RipListEntry *pRipEntry)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPIInfoBase spInfoBase;
|
|
PRIP_IF_CONFIG pric = NULL;
|
|
|
|
Assert(pRipEntry->m_fClient == TRUE);
|
|
Assert(pRipEntry->m_fFoundIfIndex == FALSE);
|
|
|
|
CORg( m_spRm->GetInfoBase(NULL, NULL, NULL, &spInfoBase) );
|
|
|
|
CORg( spInfoBase->GetData(IPX_PROTOCOL_RIP, 0, (LPBYTE *) &pric) );
|
|
|
|
pRipEntry->m_info = pric->RipIfInfo;
|
|
pRipEntry->m_fInfoUpdated = TRUE;
|
|
|
|
memset(&(pRipEntry->m_stats), 0xFF, sizeof(pRipEntry->m_stats));
|
|
pRipEntry->m_dwIfIndex = 0xFFFFFFFF;
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::OnResultShow
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipNodeHandler::OnResultShow(ITFSComponent *pTFSComponent, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
|
|
{
|
|
BOOL bSelect = (BOOL) arg;
|
|
HRESULT hr = hrOK;
|
|
SPIRouterRefresh spRefresh;
|
|
SPITFSNode spNode;
|
|
|
|
BaseContainerHandler::OnResultShow(pTFSComponent, cookie, arg, lParam);
|
|
|
|
if (bSelect)
|
|
{
|
|
// Call synchronize on this node
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
if (spNode)
|
|
SynchronizeNodeData(spNode);
|
|
}
|
|
|
|
// Un/Register for refresh advises
|
|
if (m_spRouterInfo)
|
|
m_spRouterInfo->GetRefreshObject(&spRefresh);
|
|
|
|
if (spRefresh)
|
|
{
|
|
if (bSelect)
|
|
{
|
|
if (m_ulRefreshConnId == 0)
|
|
spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulRefreshConnId, 0);
|
|
if (m_ulStatsConnId == 0)
|
|
spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulStatsConnId, 0);
|
|
}
|
|
else
|
|
{
|
|
if (m_ulRefreshConnId)
|
|
spRefresh->UnadviseRefresh(m_ulRefreshConnId);
|
|
m_ulRefreshConnId = 0;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipNodeHandler::CompareItems
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(int) RipNodeHandler::CompareItems(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookieA,
|
|
MMC_COOKIE cookieB,
|
|
int nCol)
|
|
{
|
|
// Get the strings from the nodes and use that as a basis for
|
|
// comparison.
|
|
SPITFSNode spNode;
|
|
SPITFSResultHandler spResult;
|
|
|
|
m_spNodeMgr->FindNode(cookieA, &spNode);
|
|
spNode->GetResultHandler(&spResult);
|
|
return spResult->CompareItems(pComponent, cookieA, cookieB, nCol);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Class: RipInterfaceHandler
|
|
---------------------------------------------------------------------------*/
|
|
|
|
RipInterfaceHandler::RipInterfaceHandler(ITFSComponentData *pCompData)
|
|
: BaseIPXResultHandler(pCompData, RIP_COLUMNS),
|
|
m_ulConnId(0)
|
|
{
|
|
m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
|
|
m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
|
|
|
|
m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
|
|
m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
|
|
|
|
m_verbDefault = MMC_VERB_PROPERTIES;
|
|
}
|
|
|
|
static const DWORD s_rgInterfaceImageMap[] =
|
|
{
|
|
ROUTER_IF_TYPE_HOME_ROUTER, IMAGE_IDX_WAN_CARD,
|
|
ROUTER_IF_TYPE_FULL_ROUTER, IMAGE_IDX_WAN_CARD,
|
|
ROUTER_IF_TYPE_CLIENT, IMAGE_IDX_WAN_CARD,
|
|
ROUTER_IF_TYPE_DEDICATED, IMAGE_IDX_LAN_CARD,
|
|
ROUTER_IF_TYPE_INTERNAL, IMAGE_IDX_LAN_CARD,
|
|
ROUTER_IF_TYPE_LOOPBACK, IMAGE_IDX_LAN_CARD,
|
|
-1, IMAGE_IDX_WAN_CARD, // sentinel value
|
|
};
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::ConstructNode
|
|
Initializes the Domain node (sets it up).
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipInterfaceHandler::ConstructNode(ITFSNode *pNode, IInterfaceInfo *pIfInfo, IPXConnection *pIPXConn)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
int i;
|
|
DWORD dwIfType;
|
|
|
|
if (pNode == NULL)
|
|
return hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
// Need to initialize the data for the Domain node
|
|
|
|
// Find the right image index for this type of node
|
|
if (pIfInfo)
|
|
dwIfType = pIfInfo->GetInterfaceType();
|
|
else
|
|
dwIfType = ROUTER_IF_TYPE_CLIENT;
|
|
|
|
for (i=0; i<DimensionOf(s_rgInterfaceImageMap); i+=2)
|
|
{
|
|
if ((dwIfType == s_rgInterfaceImageMap[i]) ||
|
|
(-1 == s_rgInterfaceImageMap[i]))
|
|
break;
|
|
}
|
|
pNode->SetData(TFS_DATA_IMAGEINDEX, s_rgInterfaceImageMap[i+1]);
|
|
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, s_rgInterfaceImageMap[i+1]);
|
|
|
|
pNode->SetData(TFS_DATA_SCOPEID, 0);
|
|
|
|
pNode->SetData(TFS_DATA_COOKIE, reinterpret_cast<DWORD_PTR>(pNode));
|
|
|
|
//$ Review: kennt, what are the different type of interfaces
|
|
// do we distinguish based on the same list as above? (i.e. the
|
|
// one for image indexes).
|
|
pNode->SetNodeType(&GUID_IPXRipInterfaceNodeType);
|
|
|
|
BaseIPXResultNodeData::Init(pNode, pIfInfo, pIPXConn);
|
|
}
|
|
COM_PROTECT_CATCH
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::OnCreateDataObject
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipInterfaceHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
|
|
type, cookie, m_spTFSCompData,
|
|
ppDataObject) );
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::OnCreateDataObject
|
|
Implementation of ITFSResultHandler::OnCreateDataObject
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipInterfaceHandler::OnCreateDataObject(ITFSComponent *pComp, MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
|
|
type, cookie, m_spTFSCompData,
|
|
ppDataObject) );
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::RefreshInterface
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
void RipInterfaceHandler::RefreshInterface(MMC_COOKIE cookie)
|
|
{
|
|
SPITFSNode spNode;
|
|
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
|
|
ForwardCommandToParent(spNode, IDS_MENU_SYNC,
|
|
CCT_RESULT, NULL, 0);
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::Init
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT RipInterfaceHandler::Init(IInterfaceInfo *pIfInfo,
|
|
IRouterInfo *pRouterInfo,
|
|
ITFSNode *pParent)
|
|
{
|
|
m_spInterfaceInfo.Set(pIfInfo);
|
|
|
|
BaseIPXResultHandler::Init(pIfInfo, pParent);
|
|
|
|
m_spRouterInfo.Set(pRouterInfo);
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::DestroyResultHandler
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipInterfaceHandler::DestroyResultHandler(MMC_COOKIE cookie)
|
|
{
|
|
m_spInterfaceInfo.Release();
|
|
BaseIPXResultHandler::DestroyResultHandler(cookie);
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
This is the list of commands that will show up for the result pane
|
|
nodes.
|
|
---------------------------------------------------------------------------*/
|
|
struct SIPInterfaceNodeMenu
|
|
{
|
|
ULONG m_sidMenu; // string/command id for this menu item
|
|
ULONG (RipInterfaceHandler:: *m_pfnGetMenuFlags)(RipInterfaceHandler::SMenuData *);
|
|
ULONG m_ulPosition;
|
|
};
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::AddMenuItems
|
|
Implementation of ITFSResultHandler::AddMenuItems
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipInterfaceHandler::AddMenuItems(
|
|
ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT lpDataObject,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
long *pInsertionAllowed)
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::Command
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipInterfaceHandler::Command(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
int nCommandID,
|
|
LPDATAOBJECT pDataObject)
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::HasPropertyPages
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipInterfaceHandler::HasPropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
return hrTrue;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::CreatePropertyPages
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipInterfaceHandler::CreatePropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
HRESULT hr = hrOK;
|
|
RipInterfaceProperties * pProperties = NULL;
|
|
SPIComponentData spComponentData;
|
|
CString stTitle;
|
|
SPIRouterInfo spRouter;
|
|
SPIRtrMgrInfo spRm;
|
|
|
|
CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
|
|
|
|
// stTitle.Format(IDS_RIP_GENERAL_PAGE_TITLE,
|
|
// m_spInterfaceInfo->GetTitle());
|
|
|
|
pProperties = new RipInterfaceProperties(pNode, spComponentData,
|
|
m_spTFSCompData, stTitle);
|
|
|
|
CORg( m_spRouterInfo->FindRtrMgr(PID_IPX, &spRm) );
|
|
CORg( pProperties->Init(m_spInterfaceInfo, spRm) );
|
|
|
|
if (lpProvider)
|
|
hr = pProperties->CreateModelessSheet(lpProvider, handle);
|
|
else
|
|
hr = pProperties->DoModelessSheet();
|
|
|
|
Error:
|
|
// Is this the right way to destroy the sheet?
|
|
if (!FHrSucceeded(hr))
|
|
delete pProperties;
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RipInterfaceHandler::CreatePropertyPages
|
|
Implementation of ResultHandler::CreatePropertyPages
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RipInterfaceHandler::CreatePropertyPages
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle
|
|
)
|
|
{
|
|
// Forward this call onto the NodeHandler::CreatePropertyPages
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spNode;
|
|
|
|
Assert( m_spNodeMgr );
|
|
|
|
CORg( m_spNodeMgr->FindNode(cookie, &spNode) );
|
|
|
|
// Call the ITFSNodeHandler::CreatePropertyPages
|
|
hr = CreatePropertyPages(spNode, lpProvider, pDataObject, handle, 0);
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|