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.
1910 lines
52 KiB
1910 lines
52 KiB
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
ssview.cpp
|
|
IPX Static Services node implementation.
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "util.h"
|
|
#include "ssview.h"
|
|
#include "reg.h"
|
|
#include "ipxadmin.h"
|
|
#include "rtrutil.h" // smart MPR handle pointers
|
|
#include "ipxstrm.h" // IPXAdminConfigStream
|
|
#include "strmap.h" // XXXtoCString functions
|
|
#include "service.h" // TFS service APIs
|
|
#include "format.h" // FormatNumber function
|
|
#include "coldlg.h" // columndlg
|
|
#include "ipxutil.h"
|
|
#include "column.h" // ComponentConfigStream
|
|
#include "rtrui.h"
|
|
#include "routprot.h" // IP_LOCAL
|
|
#include "rtrres.h"
|
|
#include "dumbprop.h"
|
|
#include "ipxstaticsvc.h"
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Keep this in sync with the column ids in ssview.h
|
|
---------------------------------------------------------------------------*/
|
|
extern const ContainerColumnInfo s_rgSSViewColumnInfo[];
|
|
|
|
const ContainerColumnInfo s_rgSSViewColumnInfo[] =
|
|
{
|
|
{ IDS_IPX_SS_COL_NAME, CON_SORT_BY_STRING, TRUE, COL_IF_NAME },
|
|
{ IDS_IPX_SS_COL_SERVICE_TYPE, CON_SORT_BY_STRING, TRUE, COL_STRING },
|
|
{ IDS_IPX_SS_COL_SERVICE_NAME, CON_SORT_BY_STRING, TRUE, COL_STRING },
|
|
{ IDS_IPX_SS_COL_SERVICE_ADDRESS,CON_SORT_BY_STRING, TRUE, COL_STRING },
|
|
{ IDS_IPX_SS_COL_HOP_COUNT, CON_SORT_BY_DWORD, TRUE, COL_SMALL_NUM},
|
|
};
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
IpxSSHandler implementation
|
|
---------------------------------------------------------------------------*/
|
|
|
|
DEBUG_DECLARE_INSTANCE_COUNTER(IpxSSHandler)
|
|
|
|
|
|
IpxSSHandler::IpxSSHandler(ITFSComponentData *pCompData)
|
|
: BaseContainerHandler(pCompData, COLUMNS_STATICSERVICES,
|
|
s_rgSSViewColumnInfo),
|
|
m_ulConnId(0),
|
|
m_ulRefreshConnId(0)
|
|
{
|
|
// Setup the verb states
|
|
m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
|
|
m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
|
|
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(IpxSSHandler)
|
|
}
|
|
|
|
IpxSSHandler::~IpxSSHandler()
|
|
{
|
|
DEBUG_DECREMENT_INSTANCE_COUNTER(IpxSSHandler)
|
|
}
|
|
|
|
|
|
STDMETHODIMP IpxSSHandler::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;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::DestroyHandler
|
|
Implementation of ITFSNodeHandler::DestroyHandler
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxSSHandler::DestroyHandler(ITFSNode *pNode)
|
|
{
|
|
IPXConnection * pIPXConn;
|
|
|
|
pIPXConn = GET_IPX_SS_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_ulConnId)
|
|
m_spRtrMgrInfo->RtrUnadvise(m_ulConnId);
|
|
m_ulConnId = 0;
|
|
m_spRtrMgrInfo.Release();
|
|
|
|
m_spRouterInfo.Release();
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::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
|
|
IpxSSHandler::HasPropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
return hrFalse;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Menu data structure for our menus
|
|
---------------------------------------------------------------------------*/
|
|
|
|
static const SRouterNodeMenu s_rgIfNodeMenu[] =
|
|
{
|
|
{ IDS_MENU_IPX_SS_NEW_SERVICE, 0,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP },
|
|
|
|
{ IDS_MENU_SEPARATOR, 0,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP },
|
|
|
|
{ IDS_MENU_IPX_SS_TASK_SERVICE, 0,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP },
|
|
};
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::OnAddMenuItems
|
|
Implementation of ITFSNodeHandler::OnAddMenuItems
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxSSHandler::OnAddMenuItems(
|
|
ITFSNode *pNode,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
LPDATAOBJECT lpDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType,
|
|
long *pInsertionAllowed)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = S_OK;
|
|
IpxSSHandler::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;
|
|
}
|
|
|
|
|
|
HRESULT IpxSSHandler::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spNode, spParent;
|
|
SPITFSResultHandler spParentRH;
|
|
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
|
|
// forward this command to the parent to handle
|
|
CORg (spNode->GetParent(&spParent));
|
|
CORg (spParent->GetResultHandler(&spParentRH));
|
|
|
|
CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
|
|
|
|
Error:
|
|
return hrOK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::OnCommand
|
|
Implementation of ITFSNodeHandler::OnCommand
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxSSHandler::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_IPX_SS_NEW_SERVICE:
|
|
hr = OnNewService(pNode);
|
|
if (!FHrSucceeded(hr))
|
|
DisplayErrorMessage(NULL, hr);
|
|
break;
|
|
case IDS_MENU_IPX_SS_TASK_SERVICE:
|
|
hr = ForwardCommandToParent(pNode,
|
|
IDS_MENU_IPXSUM_TASK_SERVICE_TABLE,
|
|
type, pDataObject, dwType);
|
|
break;
|
|
case IDS_MENU_SYNC:
|
|
SynchronizeNodeData(pNode);
|
|
break;
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::GenerateListOfServices
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::GenerateListOfServices(ITFSNode *pNode, IpxSSList *pSSList)
|
|
{
|
|
Assert(pSSList);
|
|
HRESULT hr = hrOK;
|
|
SPIEnumInterfaceInfo spEnumIf;
|
|
SPIInterfaceInfo spIf;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
SPIInfoBase spInfoBase;
|
|
PIPX_STATIC_SERVICE_INFO pService;
|
|
InfoBlock * pBlock;
|
|
int i;
|
|
IpxSSListEntry * pSSEntry;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
// Ok go through and find all of the static Services
|
|
|
|
CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
|
|
|
|
for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
|
|
{
|
|
// Get the next interface
|
|
spRmIf.Release();
|
|
if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) != hrOK)
|
|
continue;
|
|
|
|
// Load IP information for this interface
|
|
spInfoBase.Release();
|
|
if (spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase) != hrOK)
|
|
continue;
|
|
|
|
// Retrieve the data for the IPX_STATIC_SERVICE_INFO block
|
|
if (spInfoBase->GetBlock(IPX_STATIC_SERVICE_INFO_TYPE, &pBlock, 0) != hrOK)
|
|
continue;
|
|
|
|
pService = (PIPX_STATIC_SERVICE_INFO) pBlock->pData;
|
|
|
|
// Update our list of Services with the Services read from this
|
|
// interface
|
|
|
|
for (i=0; i<(int) pBlock->dwCount; i++, pService++)
|
|
{
|
|
pSSEntry = new IpxSSListEntry;
|
|
pSSEntry->m_spIf.Set(spIf);
|
|
pSSEntry->m_service = *pService;
|
|
|
|
pSSList->AddTail(pSSEntry);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
if (!FHrSucceeded(hr))
|
|
{
|
|
// Should make sure that we get the SSList cleaned up
|
|
while (!pSSList->IsEmpty())
|
|
delete pSSList->RemoveHead();
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::OnExpand
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::OnExpand(ITFSNode *pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DWORD dwType,
|
|
LPARAM arg,
|
|
LPARAM lParam)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
IpxSSList SSList;
|
|
IpxSSListEntry * pSSEntry;
|
|
|
|
if (m_bExpanded)
|
|
return hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
// Ok go through and find all of the static Services
|
|
CORg( GenerateListOfServices(pNode, &SSList) );
|
|
|
|
// Now iterate through the list of static Services adding them
|
|
// all in. Ideally we could merge this into the Refresh code,
|
|
// but the refresh code can't assume a blank slate.
|
|
while (!SSList.IsEmpty())
|
|
{
|
|
pSSEntry = SSList.RemoveHead();
|
|
AddStaticServiceNode(pNode, pSSEntry);
|
|
delete pSSEntry;
|
|
}
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
// Should make sure that we get the SSList cleaned up
|
|
while (!SSList.IsEmpty())
|
|
delete SSList.RemoveHead();
|
|
|
|
|
|
m_bExpanded = TRUE;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::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) IpxSSHandler::GetString(ITFSNode *pNode, int nCol)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (m_stTitle.IsEmpty())
|
|
m_stTitle.LoadString(IDS_IPX_SS_TITLE);
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return m_stTitle;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::OnCreateDataObject
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxSSHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
|
|
Assert(m_spRtrMgrInfo);
|
|
|
|
CORg( CreateDataObjectFromRtrMgrInfo(m_spRtrMgrInfo,
|
|
type, cookie, m_spTFSCompData,
|
|
ppDataObject) );
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::Init
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::Init(IRtrMgrInfo *pRmInfo, IPXAdminConfigStream *pConfigStream)
|
|
{
|
|
m_spRtrMgrInfo.Set(pRmInfo);
|
|
if (pRmInfo)
|
|
pRmInfo->GetParentRouterInfo(&m_spRouterInfo);
|
|
m_pConfigStream = pConfigStream;
|
|
|
|
// Also need to register for change notifications
|
|
Assert(m_ulConnId == 0);
|
|
m_spRtrMgrInfo->RtrAdvise(&m_IRtrAdviseSink, &m_ulConnId, 0);
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::ConstructNode
|
|
Initializes the root node (sets it up).
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::ConstructNode(ITFSNode *pNode, LPCTSTR pszName,
|
|
IPXConnection *pIPXConn)
|
|
{
|
|
Assert(pIPXConn);
|
|
HRESULT hr = hrOK;
|
|
|
|
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_IPXStaticServicesNodeType);
|
|
|
|
// Setup the node data
|
|
pIPXConn->AddRef();
|
|
SET_IPX_SS_NODEDATA(pNode, pIPXConn);
|
|
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
if (!FHrSucceeded(hr))
|
|
{
|
|
SET_IPX_SS_NODEDATA(pNode, NULL);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::AddStaticServiceNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::AddStaticServiceNode(ITFSNode *pParent, IpxSSListEntry *pService)
|
|
{
|
|
IpxServiceHandler * pHandler;
|
|
SPITFSResultHandler spHandler;
|
|
SPITFSNode spNode;
|
|
HRESULT hr = hrOK;
|
|
BaseIPXResultNodeData * pData;
|
|
IPXConnection * pIPXConn;
|
|
|
|
// Create the handler for this node
|
|
pHandler = new IpxServiceHandler(m_spTFSCompData);
|
|
spHandler = pHandler;
|
|
CORg( pHandler->Init(pService->m_spIf, pParent) );
|
|
|
|
pIPXConn = GET_IPX_SS_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, pService->m_spIf, pIPXConn) );
|
|
|
|
pData = GET_BASEIPXRESULT_NODEDATA(spNode);
|
|
Assert(pData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pData);
|
|
|
|
// Set the data for this node
|
|
SetServiceData(pData, pService);
|
|
|
|
|
|
// Make the node immediately visible
|
|
CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
|
|
CORg( pParent->AddChild(spNode) );
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::SynchronizeNodeData
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::SynchronizeNodeData(ITFSNode *pNode)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
BaseIPXResultNodeData * pNodeData;
|
|
SPITFSNodeEnum spNodeEnum;
|
|
SPITFSNode spChildNode;
|
|
BOOL fFound;
|
|
IpxSSList SSList;
|
|
IpxSSList newSSList;
|
|
IpxSSListEntry * pSSEntry;
|
|
USES_CONVERSION;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
|
|
// Mark all of the nodes
|
|
CORg( pNode->GetEnum(&spNodeEnum) );
|
|
MarkAllNodes(pNode, spNodeEnum);
|
|
|
|
// Go out and grab the data, merge the new data in with the old data
|
|
// This is the data-gathering code and this is what should go
|
|
// on the background thread for the refresh code.
|
|
CORg( GenerateListOfServices(pNode, &SSList) );
|
|
|
|
while (!SSList.IsEmpty())
|
|
{
|
|
pSSEntry = SSList.RemoveHead();
|
|
|
|
// Look for this entry in our current list of nodes
|
|
spNodeEnum->Reset();
|
|
spChildNode.Release();
|
|
|
|
fFound = FALSE;
|
|
|
|
for (;spNodeEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
|
|
{
|
|
TCHAR szNumber[32];
|
|
|
|
pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
|
|
Assert(pNodeData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
|
|
|
|
|
|
if ((pNodeData->m_rgData[IPX_SS_SI_SERVICE_TYPE].m_dwData ==
|
|
pSSEntry->m_service.Type) &&
|
|
(StriCmp(pNodeData->m_rgData[IPX_SS_SI_SERVICE_NAME].m_stData,
|
|
A2CT((LPSTR) pSSEntry->m_service.Name)) == 0) &&
|
|
(StriCmp(pNodeData->m_spIf->GetId(), pSSEntry->m_spIf->GetId()) == 0))
|
|
{
|
|
// Ok, this route already exists, update the metric
|
|
// and mark it
|
|
Assert(pNodeData->m_dwMark == FALSE);
|
|
pNodeData->m_dwMark = TRUE;
|
|
|
|
fFound = TRUE;
|
|
|
|
SetServiceData(pNodeData, pSSEntry);
|
|
|
|
// Force MMC to redraw the node
|
|
spChildNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if (fFound)
|
|
delete pSSEntry;
|
|
else
|
|
newSSList.AddTail(pSSEntry);
|
|
}
|
|
|
|
// Now remove all nodes that were not marked
|
|
RemoveAllUnmarkedNodes(pNode, spNodeEnum);
|
|
|
|
|
|
// Now iterate through the list of static Services adding them
|
|
// all in. Ideally we could merge this into the Refresh code,
|
|
// but the refresh code can't assume a blank slate.
|
|
POSITION pos;
|
|
|
|
while (!newSSList.IsEmpty())
|
|
{
|
|
pSSEntry = newSSList.RemoveHead();
|
|
AddStaticServiceNode(pNode, pSSEntry);
|
|
delete pSSEntry;
|
|
}
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
while (!SSList.IsEmpty())
|
|
delete SSList.RemoveHead();
|
|
|
|
while (!newSSList.IsEmpty())
|
|
delete newSSList.RemoveHead();
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::MarkAllNodes
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::MarkAllNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
|
|
{
|
|
SPITFSNode spChildNode;
|
|
BaseIPXResultNodeData * pNodeData;
|
|
|
|
pEnum->Reset();
|
|
for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
|
|
{
|
|
pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
|
|
Assert(pNodeData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
|
|
|
|
pNodeData->m_dwMark = FALSE;
|
|
}
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::RemoveAllUnmarkedNodes
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::RemoveAllUnmarkedNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spChildNode;
|
|
BaseIPXResultNodeData * pNodeData;
|
|
|
|
pEnum->Reset();
|
|
for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
|
|
{
|
|
pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
|
|
Assert(pNodeData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
|
|
|
|
if (pNodeData->m_dwMark == FALSE)
|
|
{
|
|
pNode->RemoveChild(spChildNode);
|
|
spChildNode->Destroy();
|
|
}
|
|
}
|
|
|
|
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_rgIfResultNodeMenu[] =
|
|
{
|
|
{ IDS_MENU_IPX_SS_NEW_SERVICE, 0,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP },
|
|
|
|
{ IDS_MENU_SEPARATOR, 0,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP },
|
|
|
|
{ IDS_MENU_IPX_SS_TASK_SERVICE, 0,
|
|
CCM_INSERTIONPOINTID_PRIMARY_TOP },
|
|
};
|
|
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::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 IpxSSHandler::AddMenuItems(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT pDataObject,
|
|
LPCONTEXTMENUCALLBACK pCallback,
|
|
long *pInsertionAllowed)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
SPITFSNode spNode;
|
|
IpxSSHandler::SMenuData menuData;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
menuData.m_spNode.Set(spNode);
|
|
|
|
hr = AddArrayOfMenuItems(spNode,
|
|
s_rgIfResultNodeMenu,
|
|
DimensionOf(s_rgIfResultNodeMenu),
|
|
pCallback,
|
|
*pInsertionAllowed,
|
|
reinterpret_cast<INT_PTR>(&menuData));
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::Command
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxSSHandler::Command(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
int nCommandID,
|
|
LPDATAOBJECT pDataObject)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
SPITFSNode spNode;
|
|
HRESULT hr = hrOK;
|
|
|
|
switch (nCommandID)
|
|
{
|
|
case IDS_MENU_IPX_SS_NEW_SERVICE:
|
|
{
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
hr = OnNewService(spNode);
|
|
if (!FHrSucceeded(hr))
|
|
DisplayErrorMessage(NULL, hr);
|
|
}
|
|
break;
|
|
case IDS_MENU_IPX_SS_TASK_SERVICE:
|
|
{
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
hr = ForwardCommandToParent(spNode,
|
|
IDS_MENU_IPXSUM_TASK_SERVICE_TABLE,
|
|
CCT_RESULT, NULL, 0
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::CompareItems
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(int) IpxSSHandler::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);
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::OnNewService
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::OnNewService(ITFSNode *pNode)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
IpxSSListEntry SREntry;
|
|
CStaticServiceDlg srdlg(&SREntry, 0, m_spRouterInfo);
|
|
SPIInfoBase spInfoBase;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
IPXConnection * pIPXConn;
|
|
InfoBlock * pBlock;
|
|
|
|
pIPXConn = GET_IPX_SS_NODEDATA(pNode);
|
|
Assert(pIPXConn);
|
|
|
|
::ZeroMemory(&(SREntry.m_service), sizeof(SREntry.m_service));
|
|
|
|
if (srdlg.DoModal() == IDOK)
|
|
{
|
|
CORg( SREntry.m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
|
|
CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
|
|
NULL,
|
|
NULL,
|
|
&spInfoBase));
|
|
|
|
// Ok, go ahead and add the route
|
|
|
|
// Get the IPX_STATIC_SERVICE_INFO block from the interface
|
|
spInfoBase->GetBlock(IPX_STATIC_SERVICE_INFO_TYPE, &pBlock, 0);
|
|
|
|
CORg( AddStaticService(&SREntry, spInfoBase, pBlock) );
|
|
|
|
// Update the interface information
|
|
CORg( spRmIf->Save(SREntry.m_spIf->GetMachineName(),
|
|
pIPXConn->GetConfigHandle(),
|
|
NULL,
|
|
NULL,
|
|
spInfoBase,
|
|
0));
|
|
|
|
// Refresh the node
|
|
SynchronizeNodeData(pNode);
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
ImplementEmbeddedUnknown(IpxSSHandler, IRtrAdviseSink)
|
|
|
|
STDMETHODIMP IpxSSHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
|
|
DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
|
|
{
|
|
InitPThis(IpxSSHandler, IRtrAdviseSink);
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (dwChangeType == ROUTER_REFRESH)
|
|
{
|
|
SPITFSNode spNode;
|
|
|
|
Assert(ulConn == pThis->m_ulRefreshConnId);
|
|
|
|
pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spNode);
|
|
pThis->SynchronizeNodeData(spNode);
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSHandler::OnResultShow
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxSSHandler::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);
|
|
}
|
|
else
|
|
{
|
|
if (m_ulRefreshConnId)
|
|
spRefresh->UnadviseRefresh(m_ulRefreshConnId);
|
|
m_ulRefreshConnId = 0;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Class: IpxServiceHandler
|
|
---------------------------------------------------------------------------*/
|
|
|
|
IpxServiceHandler::IpxServiceHandler(ITFSComponentData *pCompData)
|
|
: BaseIPXResultHandler(pCompData, COLUMNS_STATICSERVICES),
|
|
m_ulConnId(0)
|
|
{
|
|
m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
|
|
m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
|
|
|
|
m_rgButtonState[MMC_VERB_DELETE_INDEX] = ENABLED;
|
|
m_bState[MMC_VERB_DELETE_INDEX] = TRUE;
|
|
|
|
m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
|
|
m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
|
|
|
|
m_verbDefault = MMC_VERB_PROPERTIES;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::ConstructNode
|
|
Initializes the Domain node (sets it up).
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxServiceHandler::ConstructNode(ITFSNode *pNode, IInterfaceInfo *pIfInfo, IPXConnection *pIPXConn)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
int i;
|
|
|
|
if (pNode == NULL)
|
|
return hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
// Need to initialize the data for the Domain node
|
|
|
|
pNode->SetData(TFS_DATA_SCOPEID, 0);
|
|
|
|
// We don't want icons for these nodes.
|
|
pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
|
|
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
|
|
|
|
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_IPXStaticServicesResultNodeType);
|
|
|
|
BaseIPXResultNodeData::Init(pNode, pIfInfo, pIPXConn);
|
|
}
|
|
COM_PROTECT_CATCH
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::OnCreateDataObject
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxServiceHandler::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;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::OnCreateDataObject
|
|
Implementation of ITFSResultHandler::OnCreateDataObject
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxServiceHandler::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;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::Init
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxServiceHandler::Init(IInterfaceInfo *pIfInfo, ITFSNode *pParent)
|
|
{
|
|
Assert(pIfInfo);
|
|
|
|
m_spInterfaceInfo.Set(pIfInfo);
|
|
|
|
pIfInfo->GetParentRouterInfo(&m_spRouterInfo);
|
|
|
|
|
|
BaseIPXResultHandler::Init(pIfInfo, pParent);
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::DestroyResultHandler
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxServiceHandler::DestroyResultHandler(MMC_COOKIE cookie)
|
|
{
|
|
m_spInterfaceInfo.Release();
|
|
BaseIPXResultHandler::DestroyResultHandler(cookie);
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::AddMenuItems
|
|
Implementation of ITFSResultHandler::AddMenuItems
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxServiceHandler::AddMenuItems(
|
|
ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT lpDataObject,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
long *pInsertionAllowed)
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::Command
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxServiceHandler::Command(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
int nCommandID,
|
|
LPDATAOBJECT pDataObject)
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::HasPropertyPages
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxServiceHandler::HasPropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPDATAOBJECT pDataObject,
|
|
DATA_OBJECT_TYPES type,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
return S_OK;
|
|
|
|
/* AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
// Need to fill in a IpxSSListEntry
|
|
IpxSSListEntry SREntry;
|
|
IpxSSListEntry SREntryOld;
|
|
SPIRouterInfo spRouterInfo;
|
|
HRESULT hr = hrOK;
|
|
|
|
CORg( m_spInterfaceInfo->GetParentRouterInfo(&spRouterInfo) );
|
|
|
|
BaseIPXResultNodeData * pNodeData;
|
|
|
|
pNodeData = GET_BASEIPXRESULT_NODEDATA(pNode);
|
|
Assert(pNodeData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
|
|
|
|
// Fill in our SREntry
|
|
SREntry.LoadFrom(pNodeData);
|
|
SREntryOld.LoadFrom(pNodeData);
|
|
|
|
{
|
|
CStaticServiceDlg srdlg(&SREntry, SR_DLG_MODIFY, spRouterInfo);
|
|
if (srdlg.DoModal() == IDOK)
|
|
{
|
|
// Updates the route info for this route
|
|
ModifyRouteInfo(pNode, &SREntry, &SREntryOld);
|
|
|
|
// Update the data in the UI
|
|
SetServiceData(pNodeData, &SREntry);
|
|
m_spInterfaceInfo.Set(SREntry.m_spIf);
|
|
|
|
// Force a refresh
|
|
pNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
|
|
}
|
|
}
|
|
Error:
|
|
return hrOK;*/
|
|
}
|
|
|
|
STDMETHODIMP IpxServiceHandler::HasPropertyPages(ITFSComponent *pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPDATAOBJECT pDataObject)
|
|
{
|
|
SPITFSNode spNode;
|
|
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
return HasPropertyPages(spNode, pDataObject, CCT_RESULT, 0);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::CreatePropertyPages
|
|
Implementation of ResultHandler::CreatePropertyPages
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxServiceHandler::CreatePropertyPages
|
|
(
|
|
ITFSComponent * pComponent,
|
|
MMC_COOKIE cookie,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle
|
|
)
|
|
{
|
|
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;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::CreatePropertyPages
|
|
Implementation of NodeHandler::CreatePropertyPages
|
|
Author: Deonb
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP IpxServiceHandler::CreatePropertyPages
|
|
(
|
|
ITFSNode * pNode,
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LPDATAOBJECT pDataObject,
|
|
LONG_PTR handle,
|
|
DWORD dwType
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
HRESULT hr = hrOK;
|
|
IpxStaticServicePropertySheet *pProperties = NULL;
|
|
SPIComponentData spComponentData;
|
|
CString stTitle;
|
|
|
|
CComPtr<IInterfaceInfo> spInterfaceInfo;
|
|
BaseIPXResultNodeData * pNodeData;
|
|
|
|
CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
|
|
if (m_spInterfaceInfo)
|
|
stTitle.Format(IDS_IPXSUMMARY_IF_PAGE_TITLE, m_spInterfaceInfo->GetTitle());
|
|
else
|
|
stTitle.LoadString(IDS_IPXSUMMARY_CLIENT_IF_PAGE_TITLE);
|
|
|
|
pProperties = new IpxStaticServicePropertySheet(pNode, spComponentData, m_spTFSCompData, stTitle);
|
|
|
|
pNodeData = GET_BASEIPXRESULT_NODEDATA(pNode);
|
|
Assert(pNodeData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
|
|
|
|
CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
|
|
|
|
spInterfaceInfo = m_spInterfaceInfo;
|
|
CORg( pProperties->Init(pNodeData, spInterfaceInfo) );
|
|
|
|
if (lpProvider)
|
|
hr = pProperties->CreateModelessSheet(lpProvider, handle);
|
|
else
|
|
hr = pProperties->DoModelessSheet();
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::OnResultDelete
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxServiceHandler::OnResultDelete(ITFSComponent *pComponent,
|
|
LPDATAOBJECT pDataObject,
|
|
MMC_COOKIE cookie,
|
|
LPARAM arg,
|
|
LPARAM param)
|
|
{
|
|
SPITFSNode spNode;
|
|
|
|
m_spNodeMgr->FindNode(cookie, &spNode);
|
|
return OnRemoveStaticService(spNode);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::OnRemoveStaticService
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxServiceHandler::OnRemoveStaticService(ITFSNode *pNode)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPIInfoBase spInfoBase;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
IPXConnection *pIPXConn;
|
|
SPITFSNode spNodeParent;
|
|
BaseIPXResultNodeData * pData;
|
|
IpxSSListEntry SREntry;
|
|
CWaitCursor wait;
|
|
|
|
pNode->GetParent(&spNodeParent);
|
|
|
|
pIPXConn = GET_IPX_SS_NODEDATA(spNodeParent);
|
|
Assert(pIPXConn);
|
|
|
|
pData = GET_BASEIPXRESULT_NODEDATA(pNode);
|
|
Assert(pData);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pData);
|
|
|
|
//
|
|
// Load the old interface's information
|
|
//
|
|
Assert(lstrcmpi(m_spInterfaceInfo->GetId(), pData->m_spIf->GetId()) == 0);
|
|
CORg( m_spInterfaceInfo->FindRtrMgrInterface(PID_IPX, &spRmIf) );
|
|
|
|
CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
|
|
NULL,
|
|
NULL,
|
|
&spInfoBase));
|
|
|
|
SREntry.LoadFrom(pData);
|
|
|
|
CORg( RemoveStaticService(&SREntry, spInfoBase) );
|
|
|
|
// Update the interface information
|
|
CORg( spRmIf->Save(m_spInterfaceInfo->GetMachineName(),
|
|
pIPXConn->GetConfigHandle(),
|
|
NULL,
|
|
NULL,
|
|
spInfoBase,
|
|
0));
|
|
|
|
// Refresh the node
|
|
ParentRefresh(pNode);
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::RemoveStaticService
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxServiceHandler::RemoveStaticService(IpxSSListEntry *pSSEntry,
|
|
IInfoBase *pInfoBase)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
InfoBlock * pBlock;
|
|
PIPX_STATIC_SERVICE_INFO pRow;
|
|
INT i;
|
|
|
|
// Get the IPX_STATIC_SERVICE_INFO block from the interface
|
|
CORg( pInfoBase->GetBlock(IPX_STATIC_SERVICE_INFO_TYPE, &pBlock, 0) );
|
|
|
|
// Look for the removed route in the IPX_STATIC_SERVICE_INFO
|
|
pRow = (IPX_STATIC_SERVICE_INFO*) pBlock->pData;
|
|
|
|
for (i = 0; i < (INT)pBlock->dwCount; i++, pRow++)
|
|
{
|
|
// Compare this route to the removed one
|
|
if (FAreTwoServicesEqual(pRow, &(pSSEntry->m_service)))
|
|
{
|
|
// This is the removed route, so modify this block
|
|
// to exclude the route:
|
|
|
|
// Decrement the number of Services
|
|
--pBlock->dwCount;
|
|
|
|
if (pBlock->dwCount && (i < (INT)pBlock->dwCount))
|
|
{
|
|
// Overwrite this route with the ones which follow it
|
|
::memmove(pRow,
|
|
pRow + 1,
|
|
(pBlock->dwCount - i) * sizeof(*pRow));
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::ModifyRouteInfo
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxServiceHandler::ModifyRouteInfo(ITFSNode *pNode,
|
|
IpxSSListEntry *pSSEntryNew,
|
|
IpxSSListEntry *pSSEntryOld)
|
|
{
|
|
Assert(pSSEntryNew);
|
|
Assert(pSSEntryOld);
|
|
|
|
INT i;
|
|
HRESULT hr = hrOK;
|
|
InfoBlock* pBlock;
|
|
SPIInfoBase spInfoBase;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
SPITFSNode spNodeParent;
|
|
IPXConnection * pIPXConn;
|
|
IPX_STATIC_SERVICE_INFO *psr, *psrOld;
|
|
IPX_STATIC_SERVICE_INFO IpxRow;
|
|
|
|
CWaitCursor wait;
|
|
|
|
pNode->GetParent(&spNodeParent);
|
|
pIPXConn = GET_IPX_SS_NODEDATA(spNodeParent);
|
|
Assert(pIPXConn);
|
|
|
|
// Remove the old route if it is on another interface
|
|
if (lstrcmpi(pSSEntryOld->m_spIf->GetId(), pSSEntryNew->m_spIf->GetId()) != 0)
|
|
{
|
|
// the outgoing interface for a route is to be changed.
|
|
|
|
CORg( pSSEntryOld->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
|
|
CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
|
|
NULL,
|
|
NULL,
|
|
&spInfoBase));
|
|
|
|
// Remove the old interface
|
|
CORg( RemoveStaticService(pSSEntryOld, spInfoBase) );
|
|
|
|
// Update the interface information
|
|
CORg( spRmIf->Save(pSSEntryOld->m_spIf->GetMachineName(),
|
|
pIPXConn->GetConfigHandle(),
|
|
NULL,
|
|
NULL,
|
|
spInfoBase,
|
|
0));
|
|
}
|
|
|
|
spRmIf.Release();
|
|
spInfoBase.Release();
|
|
|
|
|
|
// Either
|
|
// (a) a route is being modified (on the same interface)
|
|
// (b) a route is being moved from one interface to another.
|
|
|
|
// Retrieve the configuration for the interface to which the route
|
|
// is now attached;
|
|
|
|
|
|
CORg( pSSEntryNew->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
|
|
CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
|
|
NULL,
|
|
NULL,
|
|
&spInfoBase));
|
|
|
|
|
|
// Get the IPX_STATIC_SERVICE_INFO block from the interface
|
|
hr = spInfoBase->GetBlock(IPX_STATIC_SERVICE_INFO_TYPE, &pBlock, 0);
|
|
if (!FHrOK(hr))
|
|
{
|
|
//
|
|
// No IPX_STATIC_SERVICE_INFO block was found; we create a new block
|
|
// with the new route, and add that block to the interface-info
|
|
//
|
|
|
|
CORg( AddStaticService(pSSEntryNew, spInfoBase, NULL) );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// An IPX_STATIC_SERVICE_INFO block was found.
|
|
//
|
|
// We are modifying an existing route.
|
|
// If the route's interface was not changed when it was modified,
|
|
// look for the existing route in the IPX_STATIC_SERVICE_INFO, and then
|
|
// update its parameters.
|
|
// Otherwise, write a completely new route in the IPX_STATIC_SERVICE_INFO;
|
|
//
|
|
|
|
if (lstrcmpi(pSSEntryOld->m_spIf->GetId(), pSSEntryNew->m_spIf->GetId()) == 0)
|
|
{
|
|
//
|
|
// The route's interface was not changed when it was modified;
|
|
// We now look for it amongst the existing Services
|
|
// for this interface.
|
|
// The route's original parameters are in 'preOld',
|
|
// so those are the parameters with which we search
|
|
// for a route to modify
|
|
//
|
|
|
|
psr = (IPX_STATIC_SERVICE_INFO*)pBlock->pData;
|
|
|
|
for (i = 0; i < (INT)pBlock->dwCount; i++, psr++)
|
|
{
|
|
// Compare this route to the re-configured one
|
|
if (!FAreTwoServicesEqual(&(pSSEntryOld->m_service), psr))
|
|
continue;
|
|
|
|
// This is the route which was modified;
|
|
// We can now modify the parameters for the route in-place.
|
|
*psr = pSSEntryNew->m_service;
|
|
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CORg( AddStaticService(pSSEntryNew, spInfoBase, pBlock) );
|
|
}
|
|
|
|
// Save the updated information
|
|
CORg( spRmIf->Save(pSSEntryNew->m_spIf->GetMachineName(),
|
|
pIPXConn->GetConfigHandle(),
|
|
NULL,
|
|
NULL,
|
|
spInfoBase,
|
|
0));
|
|
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxServiceHandler::ParentRefresh
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxServiceHandler::ParentRefresh(ITFSNode *pNode)
|
|
{
|
|
return ForwardCommandToParent(pNode, IDS_MENU_SYNC,
|
|
CCT_RESULT, NULL, 0);
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Class: CStaticServiceDlg
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: CStaticServiceDlg::CStaticServiceDlg
|
|
//
|
|
// Constructor: initialize the base-class and the dialog's data.
|
|
//----------------------------------------------------------------------------
|
|
|
|
CStaticServiceDlg::CStaticServiceDlg(IpxSSListEntry * pSSEntry,
|
|
DWORD dwFlags,
|
|
IRouterInfo *pRouter,
|
|
CWnd *pParent)
|
|
: CBaseDialog(IDD_STATIC_SERVICE, pParent),
|
|
m_pSSEntry(pSSEntry),
|
|
m_dwFlags(dwFlags)
|
|
{
|
|
|
|
//{{AFX_DATA_INIT(CStaticServiceDlg)
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_spRouterInfo.Set(pRouter);
|
|
|
|
// SetHelpMap(m_dwHelpMap);
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: CStaticServiceDlg::DoDataExchange
|
|
//----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
CStaticServiceDlg::DoDataExchange(
|
|
CDataExchange* pDX
|
|
) {
|
|
|
|
CBaseDialog::DoDataExchange(pDX);
|
|
|
|
//{{AFX_DATA_MAP(CStaticServiceDlg)
|
|
DDX_Control(pDX, IDC_SSD_COMBO_INTERFACE, m_cbInterfaces);
|
|
DDX_Control(pDX, IDC_SSD_SPIN_HOP_COUNT, m_spinHopCount);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CStaticServiceDlg, CBaseDialog)
|
|
//{{AFX_MSG_MAP(CStaticServiceDlg)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
DWORD CStaticServiceDlg::m_dwHelpMap[] =
|
|
{
|
|
// IDC_SRD_DESTINATION, HIDC_SRD_DESTINATION,
|
|
// IDC_SRD_NETMASK, HIDC_SRD_NETMASK,
|
|
// IDC_SRD_GATEWAY, HIDC_SRD_GATEWAY,
|
|
// IDC_SRD_METRIC, HIDC_SRD_METRIC,
|
|
// IDC_SRD_SPINMETRIC, HIDC_SRD_SPINMETRIC,
|
|
// IDC_SRD_INTERFACES, HIDC_SRD_INTERFACES,
|
|
0,0
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: CStaticServiceDlg::OnInitDialog
|
|
//
|
|
// Handles the 'WM_INITDIALOG' message for the dialog.
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
CStaticServiceDlg::OnInitDialog(
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
SPIEnumInterfaceInfo spEnumIf;
|
|
SPIInterfaceInfo spIf;
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
TCHAR szNumber[32];
|
|
USES_CONVERSION;
|
|
|
|
CBaseDialog::OnInitDialog();
|
|
|
|
// initialize the controls
|
|
m_spinHopCount.SetRange(0, 15);
|
|
m_spinHopCount.SetBuddy(GetDlgItem(IDC_SSD_EDIT_HOP_COUNT));
|
|
|
|
((CEdit *) GetDlgItem(IDC_SSD_EDIT_SERVICE_TYPE))->LimitText(4);
|
|
((CEdit *) GetDlgItem(IDC_SSD_EDIT_SERVICE_NAME))->LimitText(48);
|
|
((CEdit *) GetDlgItem(IDC_SSD_EDIT_NETWORK_ADDRESS))->LimitText(8);
|
|
((CEdit *) GetDlgItem(IDC_SSD_EDIT_NODE_ADDRESS))->LimitText(12);
|
|
((CEdit *) GetDlgItem(IDC_SSD_EDIT_SOCKET_ADDRESS))->LimitText(4);
|
|
|
|
|
|
// Get a list of the interfaces enabled for IPX routing.
|
|
m_spRouterInfo->EnumInterface(&spEnumIf);
|
|
|
|
for( ; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
|
|
{
|
|
spRmIf.Release();
|
|
|
|
if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) != hrOK)
|
|
continue;
|
|
|
|
// Add the interface to the combobox
|
|
INT i = m_cbInterfaces.AddString(spIf->GetTitle());
|
|
|
|
m_cbInterfaces.SetItemData(i, (DWORD_PTR)m_ifidList.AddTail(spIf->GetId()));
|
|
}
|
|
|
|
if (!m_cbInterfaces.GetCount())
|
|
{
|
|
AfxMessageBox(IDS_ERR_NO_IPX_INTERFACES);
|
|
EndDialog(IDCANCEL);
|
|
return FALSE;
|
|
}
|
|
|
|
m_cbInterfaces.SetCurSel(0);
|
|
|
|
//
|
|
// If we were given a route to modify, set the dialog up
|
|
// with the parameters in the route
|
|
//
|
|
if ((m_dwFlags & SR_DLG_MODIFY) == 0)
|
|
{
|
|
// No route was given, so leave the controls blank
|
|
}
|
|
else
|
|
{
|
|
// A route to be edited was given, so initialize the controls
|
|
wsprintf(szNumber, _T("%.4x"), m_pSSEntry->m_service.Type);
|
|
SetDlgItemText(IDC_SSD_EDIT_SERVICE_TYPE, szNumber);
|
|
|
|
SetDlgItemText(IDC_SSD_EDIT_SERVICE_NAME, A2CT((LPSTR) m_pSSEntry->m_service.Name));
|
|
|
|
FormatIpxNetworkNumber(szNumber,
|
|
DimensionOf(szNumber),
|
|
m_pSSEntry->m_service.Network,
|
|
sizeof(m_pSSEntry->m_service.Network));
|
|
SetDlgItemText(IDC_SSD_EDIT_NETWORK_ADDRESS, szNumber);
|
|
|
|
// Zero out the address beforehand
|
|
FormatBytes(szNumber, DimensionOf(szNumber),
|
|
(BYTE *) m_pSSEntry->m_service.Node,
|
|
sizeof(m_pSSEntry->m_service.Node));
|
|
SetDlgItemText(IDC_SSD_EDIT_NODE_ADDRESS, szNumber);
|
|
|
|
FormatBytes(szNumber, DimensionOf(szNumber),
|
|
(BYTE *) m_pSSEntry->m_service.Socket,
|
|
sizeof(m_pSSEntry->m_service.Socket));
|
|
SetDlgItemText(IDC_SSD_EDIT_SOCKET_ADDRESS, szNumber);
|
|
|
|
|
|
m_cbInterfaces.SelectString(-1, m_pSSEntry->m_spIf->GetTitle());
|
|
|
|
m_spinHopCount.SetPos(m_pSSEntry->m_service.HopCount);
|
|
|
|
// Disable the network number, next hop, and interface
|
|
GetDlgItem(IDC_SSD_EDIT_SERVICE_TYPE)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_SSD_EDIT_SERVICE_NAME)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_SSD_COMBO_INTERFACE)->EnableWindow(FALSE);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: CStaticServiceDlg::OnOK
|
|
//
|
|
// Handles 'BN_CLICKED' notification from the 'OK' button.
|
|
//----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
CStaticServiceDlg::OnOK(
|
|
) {
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
CString st;
|
|
SPIInterfaceInfo spIf;
|
|
CString stIf;
|
|
POSITION pos;
|
|
|
|
do
|
|
{
|
|
// Get the route's outgoing interface
|
|
INT item = m_cbInterfaces.GetCurSel();
|
|
if (item == CB_ERR)
|
|
break;
|
|
|
|
pos = (POSITION)m_cbInterfaces.GetItemData(item);
|
|
|
|
stIf = (LPCTSTR)m_ifidList.GetAt(pos);
|
|
|
|
m_spRouterInfo->FindInterface(stIf, &spIf);
|
|
|
|
m_pSSEntry->m_spIf.Set(spIf);
|
|
|
|
// Get the rest of the data
|
|
GetDlgItemText(IDC_SSD_EDIT_SERVICE_TYPE, st);
|
|
m_pSSEntry->m_service.Type = (USHORT) _tcstoul(st, NULL, 16);
|
|
|
|
GetDlgItemText(IDC_SSD_EDIT_SERVICE_NAME, st);
|
|
st.TrimLeft();
|
|
st.TrimRight();
|
|
if (st.IsEmpty())
|
|
{
|
|
GetDlgItem(IDC_SSD_EDIT_SERVICE_NAME)->SetFocus();
|
|
AfxMessageBox(IDS_ERR_INVALID_SERVICE_NAME);
|
|
break;
|
|
}
|
|
StrnCpyAFromW((LPSTR) m_pSSEntry->m_service.Name,
|
|
st,
|
|
sizeof(m_pSSEntry->m_service.Name));
|
|
|
|
GetDlgItemText(IDC_SSD_EDIT_NETWORK_ADDRESS, st);
|
|
ConvertToBytes(st,
|
|
m_pSSEntry->m_service.Network,
|
|
DimensionOf(m_pSSEntry->m_service.Network));
|
|
|
|
GetDlgItemText(IDC_SSD_EDIT_NODE_ADDRESS, st);
|
|
ConvertToBytes(st,
|
|
m_pSSEntry->m_service.Node,
|
|
DimensionOf(m_pSSEntry->m_service.Node));
|
|
|
|
GetDlgItemText(IDC_SSD_EDIT_SOCKET_ADDRESS, st);
|
|
ConvertToBytes(st,
|
|
m_pSSEntry->m_service.Socket,
|
|
DimensionOf(m_pSSEntry->m_service.Socket));
|
|
|
|
m_pSSEntry->m_service.HopCount = (USHORT) m_spinHopCount.GetPos();
|
|
|
|
CBaseDialog::OnOK();
|
|
|
|
} while(FALSE);
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSListEntry::LoadFrom
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
void IpxSSListEntry::LoadFrom(BaseIPXResultNodeData *pNodeData)
|
|
{
|
|
CString stFullAddress;
|
|
CString stNumber;
|
|
|
|
m_spIf.Set(pNodeData->m_spIf);
|
|
|
|
m_service.Type = (USHORT) _tcstoul(
|
|
pNodeData->m_rgData[IPX_SS_SI_SERVICE_TYPE].m_stData,
|
|
NULL, 16);
|
|
|
|
StrnCpyAFromW((LPSTR) m_service.Name,
|
|
pNodeData->m_rgData[IPX_SS_SI_SERVICE_NAME].m_stData,
|
|
DimensionOf(m_service.Name));
|
|
|
|
// Need to break the address up into Network.Node.Socket
|
|
stFullAddress = pNodeData->m_rgData[IPX_SS_SI_SERVICE_ADDRESS].m_stData;
|
|
Assert(StrLen(stFullAddress) == (8 + 1 + 12 + 1 + 4));
|
|
|
|
stNumber = stFullAddress.Left(8);
|
|
ConvertToBytes(stNumber,
|
|
m_service.Network, sizeof(m_service.Network));
|
|
|
|
stNumber = stFullAddress.Mid(9, 12);
|
|
ConvertToBytes(stNumber,
|
|
m_service.Node, sizeof(m_service.Node));
|
|
|
|
stNumber = stFullAddress.Mid(22, 4);
|
|
ConvertToBytes(stNumber,
|
|
m_service.Socket, sizeof(m_service.Socket));
|
|
|
|
m_service.HopCount = (USHORT) pNodeData->m_rgData[IPX_SS_SI_HOP_COUNT].m_dwData;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxSSListEntry::SaveTo
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
void IpxSSListEntry::SaveTo(BaseIPXResultNodeData *pNodeData)
|
|
{
|
|
TCHAR szNumber[32];
|
|
CString st;
|
|
USES_CONVERSION;
|
|
|
|
pNodeData->m_spIf.Set(m_spIf);
|
|
|
|
pNodeData->m_rgData[IPX_SS_SI_NAME].m_stData = m_spIf->GetTitle();
|
|
|
|
wsprintf(szNumber, _T("%.4x"), m_service.Type);
|
|
pNodeData->m_rgData[IPX_SS_SI_SERVICE_TYPE].m_stData = szNumber;
|
|
pNodeData->m_rgData[IPX_SS_SI_SERVICE_TYPE].m_dwData = (DWORD) m_service.Type;
|
|
|
|
pNodeData->m_rgData[IPX_SS_SI_SERVICE_NAME].m_stData =
|
|
A2CT((LPSTR) m_service.Name);
|
|
|
|
FormatBytes(szNumber, DimensionOf(szNumber),
|
|
m_service.Network, sizeof(m_service.Network));
|
|
st = szNumber;
|
|
st += _T(".");
|
|
FormatBytes(szNumber, DimensionOf(szNumber),
|
|
m_service.Node, sizeof(m_service.Node));
|
|
st += szNumber;
|
|
st += _T(".");
|
|
FormatBytes(szNumber, DimensionOf(szNumber),
|
|
m_service.Socket, sizeof(m_service.Socket));
|
|
st += szNumber;
|
|
|
|
Assert(st.GetLength() == (8+1+12+1+4));
|
|
|
|
pNodeData->m_rgData[IPX_SS_SI_SERVICE_ADDRESS].m_stData = st;
|
|
|
|
FormatNumber(m_service.HopCount,
|
|
szNumber,
|
|
DimensionOf(szNumber),
|
|
FALSE);
|
|
pNodeData->m_rgData[IPX_SS_SI_HOP_COUNT].m_stData = szNumber;
|
|
pNodeData->m_rgData[IPX_SS_SI_HOP_COUNT].m_dwData = m_service.HopCount;
|
|
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
SetServiceData
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT SetServiceData(BaseIPXResultNodeData *pData,
|
|
IpxSSListEntry *pService)
|
|
{
|
|
|
|
pService->SaveTo(pData);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
AddStaticService
|
|
This function ASSUMES that the route is NOT in the block.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT AddStaticService(IpxSSListEntry *pSSEntryNew,
|
|
IInfoBase *pInfoBase,
|
|
InfoBlock *pBlock)
|
|
{
|
|
IPX_STATIC_SERVICE_INFO srRow;
|
|
HRESULT hr = hrOK;
|
|
|
|
if (pBlock == NULL)
|
|
{
|
|
//
|
|
// No IPX_STATIC_SERVICE_INFO block was found; we create a new block
|
|
// with the new route, and add that block to the interface-info
|
|
//
|
|
|
|
CORg( pInfoBase->AddBlock(IPX_STATIC_SERVICE_INFO_TYPE,
|
|
sizeof(IPX_STATIC_SERVICE_INFO),
|
|
(LPBYTE) &(pSSEntryNew->m_service), 1, 0) );
|
|
}
|
|
else
|
|
{
|
|
// Either the route is completely new, or it is a route
|
|
// which was moved from one interface to another.
|
|
// Set a new block as the IPX_STATIC_SERVICE_INFO,
|
|
// and include the re-configured route in the new block.
|
|
PIPX_STATIC_SERVICE_INFO psrTable;
|
|
|
|
psrTable = new IPX_STATIC_SERVICE_INFO[pBlock->dwCount + 1];
|
|
Assert(psrTable);
|
|
|
|
// Copy the original table of Services
|
|
::memcpy(psrTable, pBlock->pData,
|
|
pBlock->dwCount * sizeof(IPX_STATIC_SERVICE_INFO));
|
|
|
|
// Append the new route
|
|
psrTable[pBlock->dwCount] = pSSEntryNew->m_service;
|
|
|
|
// Replace the old route-table with the new one
|
|
CORg( pInfoBase->SetData(IPX_STATIC_SERVICE_INFO_TYPE,
|
|
sizeof(IPX_STATIC_SERVICE_INFO),
|
|
(LPBYTE) psrTable, pBlock->dwCount + 1, 0) );
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL FAreTwoServicesEqual(IPX_STATIC_SERVICE_INFO *pService1,
|
|
IPX_STATIC_SERVICE_INFO *pService2)
|
|
{
|
|
return (pService1->Type == pService2->Type) &&
|
|
(StrnCmpA((LPCSTR) pService1->Name, (LPCSTR) pService2->Name, DimensionOf(pService1->Name)) == 0);
|
|
}
|