/**********************************************************************/ /** 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(&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(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(pHandler), static_cast(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(&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(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 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); }