612 lines
18 KiB
C++
612 lines
18 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
//
|
|
// nbprop.cpp
|
|
// IPX summary node property sheet and property pages
|
|
//
|
|
// FILE HISTORY:
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "rtrutil.h" // smart MPR handle pointers
|
|
#include "format.h" // FormatNumber function
|
|
#include "IpxStaticSvc.h"
|
|
#include "summary.h"
|
|
#include "ipxrtdef.h"
|
|
#include "filter.h"
|
|
#include "ipxutil.h"
|
|
|
|
extern "C"
|
|
{
|
|
#include "routprot.h"
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// IpxStaticServicePropertySheet::IpxStaticServicePropertySheet
|
|
// Initialize the RtrPropertySheet and only Property Page.
|
|
// Author: Deonb
|
|
// ---------------------------------------------------------------------------
|
|
IpxStaticServicePropertySheet::IpxStaticServicePropertySheet(ITFSNode *pNode,
|
|
IComponentData *pComponentData,
|
|
ITFSComponentData *pTFSCompData,
|
|
LPCTSTR pszSheetName,
|
|
CWnd *pParent,
|
|
UINT iPage,
|
|
BOOL fScopePane)
|
|
: RtrPropertySheet(pNode, pComponentData, pTFSCompData,
|
|
pszSheetName, pParent, iPage, fScopePane),
|
|
m_pageGeneral(IDD_STATICSERVICESPROPERTIES_GENERAL)
|
|
{
|
|
m_spNode = pNode;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// IpxStaticServicePropertySheet::Init
|
|
// Initialize the property sheets. The general action here will be
|
|
// to initialize/add the various pages.
|
|
// Author: Deonb
|
|
// ---------------------------------------------------------------------------
|
|
HRESULT IpxStaticServicePropertySheet::Init(
|
|
BaseIPXResultNodeData *pNodeData,
|
|
IInterfaceInfo * spInterfaceInfo)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
BaseIPXResultNodeData * pData;
|
|
|
|
m_pNodeData = pNodeData;
|
|
m_spInterfaceInfo = spInterfaceInfo;
|
|
|
|
pData = GET_BASEIPXRESULT_NODEDATA(m_spNode);
|
|
ASSERT_BASEIPXRESULT_NODEDATA(pData);
|
|
|
|
// The pages are embedded members of the class
|
|
// do not delete them.
|
|
m_bAutoDeletePages = FALSE;
|
|
|
|
m_pageGeneral.Init(pNodeData, this);
|
|
AddPageToList((CPropertyPageBase*) &m_pageGeneral);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// IpxStaticServicePropertySheet::SaveSheetData
|
|
// Not sure what this does - this is never called. Kenn had this so I'll just
|
|
// copy this too.
|
|
// Author: Deonb
|
|
// ---------------------------------------------------------------------------
|
|
BOOL IpxStaticServicePropertySheet::SaveSheetData()
|
|
{
|
|
SPITFSNodeHandler spHandler;
|
|
SPITFSNode spParent;
|
|
|
|
// By this time each page should have written its information out
|
|
// to the infobase
|
|
|
|
// Force the node to do a resync
|
|
m_spNode->GetParent(&spParent);
|
|
spParent->GetHandler(&spHandler);
|
|
spHandler->OnCommand(spParent, IDS_MENU_SYNC, CCT_RESULT,
|
|
NULL, 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// IpxStaticServicePropertySheet::CancelSheetData
|
|
// -
|
|
// Author: Deonb
|
|
// ---------------------------------------------------------------------------
|
|
void IpxStaticServicePropertySheet::CancelSheetData()
|
|
{
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// ---------------------------------------------------------------------------
|
|
// IpxStaticServicePropertyPage
|
|
// ---------------------------------------------------------------------------
|
|
IpxStaticServicePropertyPage::~IpxStaticServicePropertyPage()
|
|
{
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(IpxStaticServicePropertyPage, RtrPropertyPage)
|
|
//{{AFX_MSG_MAP(IpxStaticServicePropertyPage)
|
|
ON_BN_CLICKED(IDC_NIG_BTN_ACCEPT, OnChangeButton)
|
|
ON_BN_CLICKED(IDC_NIG_BTN_DELIVER_ALWAYS, OnChangeButton)
|
|
ON_BN_CLICKED(IDC_NIG_BTN_DELIVER_NEVER, OnChangeButton)
|
|
ON_BN_CLICKED(IDC_NIG_BTN_DELIVER_STATIC, OnChangeButton)
|
|
ON_BN_CLICKED(IDC_NIG_BTN_DELIVER_WHEN_UP, OnChangeButton)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
void IpxStaticServicePropertyPage::OnChangeButton()
|
|
{
|
|
SetDirty(TRUE);
|
|
SetModified();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// IpxStaticServicePropertyPage::Init
|
|
// -
|
|
// Author: Deonb
|
|
//---------------------------------------------------------------------------
|
|
HRESULT IpxStaticServicePropertyPage::Init(BaseIPXResultNodeData *pNodeData,
|
|
IpxStaticServicePropertySheet * pIPXPropSheet)
|
|
|
|
{
|
|
ATLASSERT(pSREntry);
|
|
ATLASSERT(pIPXPropSheet);
|
|
|
|
m_pIPXPropSheet = pIPXPropSheet;
|
|
|
|
m_SREntry.LoadFrom(pNodeData);
|
|
m_InitSREntry = m_SREntry;
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// IpxStaticServicePropertyPage::OnInitDialog
|
|
// -
|
|
// Author: Deonb
|
|
// ---------------------------------------------------------------------------
|
|
BOOL IpxStaticServicePropertyPage::OnInitDialog()
|
|
{
|
|
HRESULT hr = hrOK;
|
|
PBYTE pData;
|
|
DWORD dwIfType;
|
|
UINT iButton;
|
|
|
|
RtrPropertyPage::OnInitDialog();
|
|
|
|
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);
|
|
|
|
USES_CONVERSION;
|
|
TCHAR szNumber[32];
|
|
wsprintf(szNumber, _T("%.4x"), m_SREntry.m_service.Type);
|
|
SetDlgItemText(IDC_SSD_EDIT_SERVICE_TYPE, szNumber);
|
|
|
|
SetDlgItemText(IDC_SSD_EDIT_SERVICE_NAME, A2CT((LPSTR) m_SREntry.m_service.Name));
|
|
|
|
FormatIpxNetworkNumber(szNumber,
|
|
DimensionOf(szNumber),
|
|
m_SREntry.m_service.Network,
|
|
sizeof(m_SREntry.m_service.Network));
|
|
SetDlgItemText(IDC_SSD_EDIT_NETWORK_ADDRESS, szNumber);
|
|
|
|
// Zero out the address beforehand
|
|
FormatBytes(szNumber, DimensionOf(szNumber),
|
|
(BYTE *) m_SREntry.m_service.Node,
|
|
sizeof(m_SREntry.m_service.Node));
|
|
SetDlgItemText(IDC_SSD_EDIT_NODE_ADDRESS, szNumber);
|
|
|
|
FormatBytes(szNumber, DimensionOf(szNumber),
|
|
(BYTE *) m_SREntry.m_service.Socket,
|
|
sizeof(m_SREntry.m_service.Socket));
|
|
SetDlgItemText(IDC_SSD_EDIT_SOCKET_ADDRESS, szNumber);
|
|
|
|
m_spinHopCount.SetPos(m_SREntry.m_service.HopCount);
|
|
|
|
// Disable the network number, next hop
|
|
GetDlgItem(IDC_SSD_EDIT_SERVICE_TYPE)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_SSD_EDIT_SERVICE_NAME)->EnableWindow(FALSE);
|
|
|
|
SetDirty(FALSE);
|
|
|
|
if (!FHrSucceeded(hr))
|
|
Cancel();
|
|
return FHrSucceeded(hr) ? TRUE : FALSE;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// IpxStaticServicePropertyPage::DoDataExchange
|
|
// -
|
|
// Author: Deonb
|
|
// ---------------------------------------------------------------------------
|
|
void IpxStaticServicePropertyPage::DoDataExchange(CDataExchange *pDX)
|
|
{
|
|
RtrPropertyPage::DoDataExchange(pDX);
|
|
|
|
//{{AFX_DATA_MAP(IpxStaticServicePropertyPage)
|
|
DDX_Control(pDX, IDC_SSD_SPIN_HOP_COUNT, m_spinHopCount);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// IpxStaticServicePropertyPage::OnApply
|
|
// -
|
|
// Author: Deonb
|
|
// ---------------------------------------------------------------------------
|
|
BOOL IpxStaticServicePropertyPage::OnApply()
|
|
{
|
|
|
|
BOOL fReturn;
|
|
HRESULT hr = hrOK;
|
|
|
|
if ( m_pIPXPropSheet->IsCancel() )
|
|
{
|
|
CancelApply();
|
|
return TRUE;
|
|
}
|
|
|
|
CString st;
|
|
GetDlgItemText(IDC_SSD_EDIT_SERVICE_TYPE, st);
|
|
m_SREntry.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);
|
|
return FALSE;
|
|
}
|
|
StrnCpyAFromW((LPSTR) m_SREntry.m_service.Name,
|
|
st,
|
|
sizeof(m_SREntry.m_service.Name));
|
|
|
|
GetDlgItemText(IDC_SSD_EDIT_NETWORK_ADDRESS, st);
|
|
ConvertToBytes(st,
|
|
m_SREntry.m_service.Network,
|
|
DimensionOf(m_SREntry.m_service.Network));
|
|
|
|
GetDlgItemText(IDC_SSD_EDIT_NODE_ADDRESS, st);
|
|
ConvertToBytes(st,
|
|
m_SREntry.m_service.Node,
|
|
DimensionOf(m_SREntry.m_service.Node));
|
|
|
|
GetDlgItemText(IDC_SSD_EDIT_SOCKET_ADDRESS, st);
|
|
ConvertToBytes(st,
|
|
m_SREntry.m_service.Socket,
|
|
DimensionOf(m_SREntry.m_service.Socket));
|
|
|
|
m_SREntry.m_service.HopCount = (USHORT) m_spinHopCount.GetPos();
|
|
|
|
// Updates the route info for this route
|
|
ModifyRouteInfo(m_pIPXPropSheet->m_spNode, &m_SREntry, &m_InitSREntry);
|
|
|
|
// Update the data in the UI
|
|
m_SREntry.SaveTo(m_pIPXPropSheet->m_pNodeData);
|
|
m_pIPXPropSheet->m_spInterfaceInfo = m_SREntry.m_spIf;
|
|
|
|
// Force a refresh
|
|
m_pIPXPropSheet->m_spNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
|
|
|
|
fReturn = RtrPropertyPage::OnApply();
|
|
return fReturn;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxStaticServicePropertyPage::RemoveStaticService
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxStaticServicePropertyPage::RemoveStaticService(SafeIPXSSListEntry *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;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IpxStaticServicePropertyPage::ModifyRouteInfo
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT IpxStaticServicePropertyPage::ModifyRouteInfo(ITFSNode *pNode,
|
|
SafeIPXSSListEntry *pSSEntryNew,
|
|
SafeIPXSSListEntry *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;
|
|
|
|
}
|
|
// --------------------------------------------------------------------------
|
|
// SafeIPXSSListEntry::LoadFrom
|
|
// -
|
|
// Author: DeonB
|
|
// --------------------------------------------------------------------------
|
|
void SafeIPXSSListEntry::LoadFrom(BaseIPXResultNodeData *pNodeData)
|
|
{
|
|
CString stFullAddress;
|
|
CString stNumber;
|
|
|
|
m_spIf = 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;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// SafeIPXSSListEntry::SaveTo
|
|
// -
|
|
// Author: DeonB
|
|
// --------------------------------------------------------------------------
|
|
void SafeIPXSSListEntry::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;
|
|
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
AddStaticService
|
|
This function ASSUMES that the route is NOT in the block.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT AddStaticService(SafeIPXSSListEntry *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;
|
|
}
|