windows-nt/Source/XPSP1/NT/net/mmc/ipxsnap/riproot.cpp
2020-09-26 16:20:57 +08:00

355 lines
9.7 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
root.cpp
Root node information (the root node is not displayed
in the MMC framework but contains information such as
all of the subnodes in this snapin).
FILE HISTORY:
*/
#include "stdafx.h"
#include "util.h"
#include "riproot.h"
#include "reg.h"
#include "ripview.h" // RIP handlers
#include "ripstats.h"
#include "routprot.h" // IP_BOOTP
/*---------------------------------------------------------------------------
RipRootHandler implementation
---------------------------------------------------------------------------*/
DEBUG_DECLARE_INSTANCE_COUNTER(RipRootHandler)
extern const ContainerColumnInfo s_rgRIPParamsStatsColumnInfo[];
struct _ViewInfoColumnEntry
{
UINT m_ulId;
UINT m_cColumns;
const ContainerColumnInfo *m_prgColumn;
};
static const struct _ViewInfoColumnEntry s_rgViewColumnInfo[] =
{
{ RIPSTRM_STATS_RIPPARAMS, MVR_RIPPARAMS_COUNT, s_rgRIPParamsStatsColumnInfo },
};
RipRootHandler::RipRootHandler(ITFSComponentData *pCompData)
: RootHandler(pCompData)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(RipRootHandler)
m_ConfigStream.Init(DimensionOf(s_rgViewColumnInfo));
// This will initialize the view information for the statistics
// dialogs. (which is why the fConfigurableColumns is set to TRUE).
for (int i=0; i<DimensionOf(s_rgViewColumnInfo); i++)
{
m_ConfigStream.InitViewInfo(s_rgViewColumnInfo[i].m_ulId,
TRUE /*fConfigurableColumns*/,
s_rgViewColumnInfo[i].m_cColumns,
TRUE,
s_rgViewColumnInfo[i].m_prgColumn);
}
}
STDMETHODIMP RipRootHandler::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 RootHandler::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;
}
///////////////////////////////////////////////////////////////////////////////
//// IPersistStream interface members
STDMETHODIMP RipRootHandler::GetClassID
(
CLSID *pClassID
)
{
ASSERT(pClassID != NULL);
// Copy the CLSID for this snapin
*pClassID = CLSID_IPXRipExtension;
return hrOK;
}
/*!--------------------------------------------------------------------------
RipRootHandler::OnExpand
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT RipRootHandler::OnExpand(ITFSNode *pNode,
LPDATAOBJECT pDataObject,
DWORD dwType,
LPARAM arg,
LPARAM lParam)
{
HRESULT hr = hrOK;
SPITFSNode spNode;
SPIRtrMgrProtocolInfo spRmProt;
SPIRtrMgrInfo spRm;
SPIRouterInfo spRouterInfo;
LONG_PTR ulConnId;
// Grab the router info from the dataobject
spRm.Query(pDataObject);
Assert(spRm);
spRm->GetParentRouterInfo(&spRouterInfo);
// Setup the advise on the RtrMgr (to see when BootP is added/removed)
spRm->RtrAdvise(&m_IRtrAdviseSink, &ulConnId, 0);
// add things to our map for later
AddRtrObj(ulConnId, IID_IRtrMgrInfo, spRm);
AddScopeItem(spRm->GetMachineName(), (HSCOPEITEM) lParam);
hr = spRm->FindRtrMgrProtocol(IPX_PROTOCOL_RIP, &spRmProt);
if (!FHrOK(hr))
{
// Treat this as an already expanded node, we depend on
// the notification mechanism to let us know if something
// changes
goto Error;
}
CORg( AddProtocolNode(pNode, spRouterInfo) );
SetProtocolAdded(ulConnId, TRUE);
Error:
return hr;
}
/*!--------------------------------------------------------------------------
RipRootHandler::OnCreateDataObject
Implementation of ITFSNodeHandler::OnCreateDataObject
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP RipRootHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
{
HRESULT hr = hrOK;
SPIRouterInfo spRouterInfo;
COM_PROTECT_TRY
{
// this will always be NULL
if (spRouterInfo == NULL)
{
// If we haven't created the sub nodes yet, we still have to
// create a dataobject.
CDataObject * pObject = NULL;
SPIDataObject spDataObject;
SPITFSNode spNode;
SPITFSNodeHandler spHandler;
pObject = new CDataObject;
spDataObject = pObject; // do this so that it gets released correctly
Assert(pObject != NULL);
// Save cookie and type for delayed rendering
pObject->SetType(type);
pObject->SetCookie(cookie);
// Store the coclass with the data object
pObject->SetClsid(*(m_spTFSCompData->GetCoClassID()));
pObject->SetTFSComponentData(m_spTFSCompData);
hr = pObject->QueryInterface(IID_IDataObject,
reinterpret_cast<void**>(ppDataObject));
}
else
hr = CreateDataObjectFromRouterInfo(spRouterInfo,
type, cookie, m_spTFSCompData,
ppDataObject);
}
COM_PROTECT_CATCH;
return hr;
}
ImplementEmbeddedUnknown(RipRootHandler, IRtrAdviseSink)
STDMETHODIMP RipRootHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
{
InitPThis(RipRootHandler, IRtrAdviseSink);
HRESULT hr = hrOK;
SPITFSNode spNode;
SPIRtrMgrInfo spRm;
SPIRouterInfo spRouterInfo;
if (dwObjectType != ROUTER_OBJ_RmProt)
return hr;
COM_PROTECT_TRY
{
CORg (pThis->GetRtrObj(ulConn, (IUnknown **) &spRm));
if (dwChangeType == ROUTER_CHILD_ADD)
{
// check to see if BootP is in the current list
if (spRm->FindRtrMgrProtocol(IPX_PROTOCOL_RIP, NULL) == hrOK)
{
// We found Bootp, add our child node if we
// don't have a child node
if (!pThis->IsProtocolAdded(ulConn))
{
spRm->GetParentRouterInfo(&spRouterInfo);
pThis->m_spNodeMgr->GetRootNode(&spNode);
pThis->AddProtocolNode(spNode, spRouterInfo);
pThis->SetProtocolAdded(ulConn, TRUE);
}
}
}
else if (dwChangeType == ROUTER_CHILD_DELETE)
{
if (spRm->FindRtrMgrProtocol(IPX_PROTOCOL_RIP, NULL) == hrFalse)
{
// couldn't find Bootp, delete all of our child nodes
pThis->m_spNodeMgr->GetRootNode(&spNode);
pThis->RemoveNode(spNode, spRm->GetMachineName());
pThis->SetProtocolAdded(ulConn, FALSE);
}
}
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
RipRootHandler::DestroyHandler
-
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP RipRootHandler::DestroyHandler(ITFSNode *pNode)
{
RemoveAllNodes(pNode);
RemoveAllRtrObj();
return hrOK;
}
/*!--------------------------------------------------------------------------
RipRootHandler::AddProtocolNode
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT RipRootHandler::AddProtocolNode(ITFSNode *pNode, IRouterInfo * pRouterInfo)
{
SPITFSNodeHandler spHandler;
RipNodeHandler * pHandler = NULL;
HRESULT hr = hrOK;
SPITFSNode spNode;
HSCOPEITEM hScopeItem, hOldScopeItem;
// Windows NT Bug : 246822
// Due to the server list programming model, we need to setup
// the proper scopeitem (so that MMC adds this to the proper
// node).
// Get the proper scope item for this node.
// ----------------------------------------------------------------
Verify( GetScopeItem(pRouterInfo->GetMachineName(), &hScopeItem) == hrOK);
// Get the old one and save it. place the new one in the node.
// ----------------------------------------------------------------
hOldScopeItem = pNode->GetData(TFS_DATA_SCOPEID);
pNode->SetData(TFS_DATA_SCOPEID, hScopeItem);
pHandler = new RipNodeHandler(m_spTFSCompData);
spHandler = pHandler;
CORg( pHandler->Init(pRouterInfo, &m_ConfigStream) );
CreateContainerTFSNode(&spNode,
&GUID_IPXRipNodeType,
static_cast<ITFSNodeHandler *>(pHandler),
static_cast<ITFSResultHandler *>(pHandler),
m_spNodeMgr);
// Call to the node handler to init the node data
pHandler->ConstructNode(spNode);
// Make the node immediately visible
spNode->SetVisibilityState(TFS_VIS_SHOW);
pNode->AddChild(spNode);
Error:
// Restore the scope item
pNode->SetData(TFS_DATA_SCOPEID, hOldScopeItem);
return hr;
}
/*!--------------------------------------------------------------------------
RipRootHandler::CompareNodeToMachineName
This function is used by the RemoveNode() function.
Returns hrOK if this node is a DHCP relay node and corresponds
to the pszMachineName.
Returns hrFalse if this is not the indicated node.
Returns errors otherwise.
Author: KennT
---------------------------------------------------------------------------*/
HRESULT RipRootHandler::CompareNodeToMachineName(ITFSNode *pNode,
LPCTSTR pszMachineName)
{
HRESULT hr = hrFalse;
// Should check that this is a RIP node
if (*(pNode->GetNodeType()) != GUID_IPXRipNodeType)
hr = hrFalse;
else
{
IPXConnection * pIPXConn;
pIPXConn = GET_RIP_NODEDATA(pNode);
if (StriCmp(pszMachineName, pIPXConn->GetMachineName()) == 0)
hr = hrOK;
}
return hr;
}