Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1592 lines
50 KiB

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
IFadmin
Interface node information
FILE HISTORY:
*/
#include "stdafx.h"
#include "ifadmin.h"
#include "iface.h" // to get InterfaceNodeHandler class
#include "rtrstrm.h" // for RouterAdminConfigStream
#include "rtrlib.h" // ContainerColumnInfo
#include "coldlg.h" // ColumnDlg
#include "column.h" // ComponentConfigStream
#include "refresh.h" // IRouterRefresh
#include "refrate.h" // CRefRate dialog
#include "machine.h"
#include "dmvcomp.h"
#include "rtrerr.h" // FormatRasError
#include "ports.h" // for PortsDataEntry
extern "C" {
#define _NOUIUTIL_H_
#include "dtl.h"
#include "pbuser.h"
};
#ifdef UNICODE
#define SZROUTERENTRYDLG "RouterEntryDlgW"
#else
#define SZROUTERENTRYDLG "RouterEntryDlgA"
#endif
IfAdminNodeData::IfAdminNodeData()
{
#ifdef DEBUG
StrCpyA(m_szDebug, "IfAdminNodeData");
#endif
}
IfAdminNodeData::~IfAdminNodeData()
{
}
/*!--------------------------------------------------------------------------
IfAdminNodeData::InitAdminNodeData
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeData::InitAdminNodeData(ITFSNode *pNode, RouterAdminConfigStream *pConfigStream)
{
HRESULT hr = hrOK;
IfAdminNodeData * pData = NULL;
pData = new IfAdminNodeData;
SET_IFADMINNODEDATA(pNode, pData);
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeData::FreeAdminNodeData
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeData::FreeAdminNodeData(ITFSNode *pNode)
{
IfAdminNodeData * pData = GET_IFADMINNODEDATA(pNode);
delete pData;
SET_IFADMINNODEDATA(pNode, NULL);
return hrOK;
}
STDMETHODIMP IfAdminNodeHandler::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 CHandler::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;
}
/*---------------------------------------------------------------------------
NodeHandler implementation
---------------------------------------------------------------------------*/
extern const ContainerColumnInfo s_rgIfAdminColumnInfo[];
const ContainerColumnInfo s_rgIfAdminColumnInfo[] =
{
{ IDS_COL_INTERFACES, CON_SORT_BY_STRING, TRUE, COL_IF_NAME },
{ IDS_COL_TYPE, CON_SORT_BY_STRING, TRUE, COL_STRING },
{ IDS_COL_STATUS, CON_SORT_BY_STRING, TRUE, COL_STATUS },
{ IDS_COL_CONNECTION_STATE, CON_SORT_BY_STRING, TRUE, COL_STRING},
{ IDS_COL_DEVICE_NAME, CON_SORT_BY_STRING, TRUE, COL_IF_DEVICE},
};
IfAdminNodeHandler::IfAdminNodeHandler(ITFSComponentData *pCompData)
: BaseContainerHandler(pCompData, DM_COLUMNS_IFADMIN, s_rgIfAdminColumnInfo),
m_bExpanded(FALSE),
m_hInstRasDlg(NULL),
m_pfnRouterEntryDlg(NULL),
m_pConfigStream(NULL),
m_ulConnId(0),
m_ulRefreshConnId(0)
{
// Setup the verb states for this node
m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::Init
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::Init(IRouterInfo *pRouterInfo, RouterAdminConfigStream *pConfigStream)
{
HRESULT hr = hrOK;
HKEY hkeyMachine;
// If we don't have a router info then we probably failed to load
// or failed to connect. Bail out of this.
if (!pRouterInfo)
CORg( E_FAIL );
m_spRouterInfo.Set(pRouterInfo);
// Also need to register for change notifications
m_spRouterInfo->RtrAdvise(&m_IRtrAdviseSink, &m_ulConnId, 0);
if (m_hInstRasDlg == NULL)
m_hInstRasDlg = AfxLoadLibrary(_T("rasdlg.dll"));
if (m_hInstRasDlg)
{
m_pfnRouterEntryDlg= (PROUTERENTRYDLG)::GetProcAddress(m_hInstRasDlg,
SZROUTERENTRYDLG);
if (m_pfnRouterEntryDlg == NULL)
{
Trace0("MPRSNAP - Could not find function: RouterEntryDlg\n");
}
}
else
Trace0("MPRSNAP - failed to load rasdlg.dll\n");
m_pConfigStream = pConfigStream;
Error:
return hrOK;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::DestroyHandler
Implementation of ITFSNodeHandler::DestroyHandler
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP IfAdminNodeHandler::DestroyHandler(ITFSNode *pNode)
{
IfAdminNodeData::FreeAdminNodeData(pNode);
m_spDataObject.Release();
if (m_hInstRasDlg)
{
FreeLibrary(m_hInstRasDlg);
m_hInstRasDlg = NULL;
}
if (m_ulRefreshConnId)
{
SPIRouterRefresh spRefresh;
if (m_spRouterInfo)
m_spRouterInfo->GetRefreshObject(&spRefresh);
if (spRefresh)
spRefresh->UnadviseRefresh(m_ulRefreshConnId);
}
m_ulRefreshConnId = 0;
if (m_spRouterInfo)
{
m_spRouterInfo->RtrUnadvise(m_ulConnId);
m_spRouterInfo.Release();
}
return hrOK;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::HasPropertyPages
Implementation of ITFSNodeHandler::HasPropertyPages
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
IfAdminNodeHandler::HasPropertyPages
(
ITFSNode * pNode,
LPDATAOBJECT pDataObject,
DATA_OBJECT_TYPES type,
DWORD dwType
)
{
return hrOK;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::OnAddMenuItems
Implementation of ITFSNodeHandler::OnAddMenuItems
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP IfAdminNodeHandler::OnAddMenuItems(
ITFSNode *pNode,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
LPDATAOBJECT lpDataObject,
DATA_OBJECT_TYPES type,
DWORD dwType,
long *pInsertionAllowed)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
CString stMenuItem;
DWORD dwWiz;
ULONG ulFlags;
SPIRouterRefresh spRefresh;
RouterVersionInfo routerVer;
BOOL fNt4;
COM_PROTECT_TRY
{
m_spRouterInfo->GetRouterVersionInfo(&routerVer);
fNt4 = (routerVer.dwRouterVersion == 4);
if ((type == CCT_SCOPE) || (dwType == TFS_COMPDATA_CHILD_CONTEXTMENU))
{
long lMenuText;
//
// If any more menus are added to this section, then the
// code for the InterfaceNodeHandler needs to be updated also.
//
// Add these menus at the top of the context menu
if (!fNt4)
{
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
{
lMenuText = IDS_MENU_NEW_DEMAND_DIAL_INTERFACE;
stMenuItem.LoadString( lMenuText );
hr = LoadAndAddMenuItem( pContextMenuCallback,
stMenuItem,
lMenuText,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
EnableAddInterface() ? 0 : MF_GRAYED);
#if 0
lMenuText = IDS_MENU_ADD_TUNNEL;
stMenuItem.LoadString( lMenuText );
hr = LoadAndAddMenuItem( pContextMenuCallback,
stMenuItem,
lMenuText,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
EnableAddInterface() ? 0 : MF_GRAYED);
#endif
}
}
// For NT4, we add the option to disable the wizard
// interface.
// --------------------------------------------------------
if (fNt4)
{
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
{
lMenuText = IDS_MENU_ADD_INTERFACE;
stMenuItem.LoadString(lMenuText);
hr = LoadAndAddMenuItem( pContextMenuCallback,
stMenuItem,
lMenuText,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
EnableAddInterface() ? 0 : MF_GRAYED);
}
hr = GetDemandDialWizardRegKey(OLE2CT(m_spRouterInfo->GetMachineName()),
&dwWiz);
if (!FHrSucceeded(hr))
dwWiz = TRUE;
ulFlags = dwWiz ? MF_CHECKED : MF_UNCHECKED;
if (!FHrSucceeded(hr))
ulFlags |= MF_GRAYED;
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
{
lMenuText = IDS_MENU_USE_DEMANDDIALWIZARD;
stMenuItem.LoadString(lMenuText);
hr = LoadAndAddMenuItem( pContextMenuCallback,
stMenuItem,
lMenuText,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
ulFlags );
ASSERT( SUCCEEDED(hr) );
}
}
}
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::OnCommand
Implementation of ITFSNodeHandler::OnCommand
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP IfAdminNodeHandler::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_NEW_DEMAND_DIAL_INTERFACE:
case IDS_MENU_ADD_INTERFACE:
OnAddInterface();
break;
#if 0
case IDS_MENU_ADD_TUNNEL:
OnNewTunnel();
break;
#endif
case IDS_MENU_USE_DEMANDDIALWIZARD:
OnUseDemandDialWizard();
break;
case IDS_MENU_REFRESH:
SynchronizeNodeData(pNode);
break;
default:
break;
}
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::GetString
Implementation of ITFSNodeHandler::GetString
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR) IfAdminNodeHandler::GetString(ITFSNode *pNode, int nCol)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
if (m_stTitle.IsEmpty())
m_stTitle.LoadString(IDS_ROUTING_INTERFACES);
}
COM_PROTECT_CATCH;
return m_stTitle;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::OnCreateDataObject
Implementation of ITFSNodeHandler::OnCreateDataObject
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP IfAdminNodeHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
{
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
if (!m_spDataObject)
{
CORg( CreateDataObjectFromRouterInfo(m_spRouterInfo,
m_spRouterInfo->GetMachineName(),
type, cookie, m_spTFSCompData,
&m_spDataObject, NULL, FALSE) );
Assert(m_spDataObject);
}
*ppDataObject = m_spDataObject;
(*ppDataObject)->AddRef();
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::OnExpand
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::OnExpand(ITFSNode *pNode,
LPDATAOBJECT pDataObject,
DWORD dwType,
LPARAM arg,
LPARAM lParam)
{
HRESULT hr = hrOK;
SPIEnumInterfaceInfo spEnumIf;
SPIInterfaceInfo spIf;
// If we don't have a router object, then we don't have any info, don't
// try to expand.
if (!m_spRouterInfo)
return hrOK;
// Windows NT Bug: 288427
// This flag may also get set inside of the OnChange() call.
// The OnChange() will enumerate and all interfaces.
// They may have been added as the result of an OnChange()
// because they were added before the OnExpand() was called.
//
// WARNING! Be careful about adding anything to this function,
// since the m_bExpanded can be set in another function.
// ----------------------------------------------------------------
if (m_bExpanded)
{
return hrOK;
}
COM_PROTECT_TRY
{
CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
while (spEnumIf->Next(1, &spIf, NULL) == hrOK)
{
AddInterfaceNode(pNode, spIf);
spIf.Release();
}
m_bExpanded = TRUE;
// Now that we have all of the nodes, update the data for
// all of the nodes
SynchronizeNodeData(pNode);
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::OnResultShow
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::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;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::ConstructNode
Initializes the Domain node (sets it up).
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::ConstructNode(ITFSNode *pNode)
{
HRESULT hr = hrOK;
IfAdminNodeData * pNodeData;
if (pNode == NULL)
return hrOK;
COM_PROTECT_TRY
{
// Need to initialize the data for the Domain node
pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_INTERFACES);
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_INTERFACES);
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<LONG_PTR>(pNode);
pNode->SetData(TFS_DATA_COOKIE, m_cookie);
pNode->SetNodeType(&GUID_RouterIfAdminNodeType);
IfAdminNodeData::InitAdminNodeData(pNode, m_pConfigStream);
pNodeData = GET_IFADMINNODEDATA(pNode);
Assert(pNodeData);
// Copy over this data so that the Interface node can access
// this and use this to configure its interface.
pNodeData->m_hInstRasDlg = m_hInstRasDlg;
pNodeData->m_pfnRouterEntryDlg = m_pfnRouterEntryDlg;
}
COM_PROTECT_CATCH
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::OnAddInterface
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::OnAddInterface()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
CString stPhoneBook;
CString stRouter;
DWORD dwErr = NO_ERROR;
SPIConsole spConsole;
SPIInterfaceInfo spIfInfo;
BOOL bStatus;
MachineNodeData *pData;
SPITFSNode spNode, spParent;
DWORD dwRouterType;
CString stServiceDesc;
RouterVersionInfo routerVersion;
if (!EnableAddInterface())
{
AddHighLevelErrorStringId(IDS_ERR_TEMPNOADD);
CORg( E_FAIL );
}
m_spNodeMgr->FindNode(m_cookie, &spNode);
spNode->GetParent(&spParent);
pData = GET_MACHINENODEDATA(spParent);
// Get the router type, if WAN routing is not-enabled
// then we don't need to create demand-dial interfaces.
// ----------------------------------------------------------------
Assert(m_spRouterInfo);
dwRouterType = m_spRouterInfo->GetRouterType();
Trace1("Routertype is %d\n", dwRouterType);
if ((dwRouterType & ROUTER_TYPE_WAN) == 0)
{
AddHighLevelErrorStringId(IDS_ERR_NEEDS_WAN);
CORg( E_FAIL );
}
// Get the version info. Needed later on.
// ----------------------------------------------------------------
m_spRouterInfo->GetRouterVersionInfo(&routerVersion);
// Check to see if the router service is running, before
// continuing on.
// ----------------------------------------------------------------
hr = IsRouterServiceRunning(m_spRouterInfo->GetMachineName(), NULL);
if (hr == hrFalse)
{
// Ask the user if they want to start the service
// ------------------------------------------------------------
if (AfxMessageBox(IDS_PROMPT_SERVICESTART, MB_YESNO) != IDYES)
CWRg( ERROR_CANCELLED );
// Else start the service
// ------------------------------------------------------------
stServiceDesc.LoadString(IDS_RRAS_SERVICE_DESC);
dwErr = TFSStartService(m_spRouterInfo->GetMachineName(), c_szRemoteAccess, stServiceDesc);
if (dwErr != NO_ERROR)
{
AddHighLevelErrorStringId(IDS_ERR_IFASERVICESTOPPED);
CWRg( dwErr );
}
//$todo: what to do about forcing a refresh through?
// ForceGlobalRefresh();
}
// Now we need to check to see if there are any routing-enabled ports
// (Here we can assume that rasman is running). We can make this
// check only for >= NT5, since this is when we got Rao's API.
// ----------------------------------------------------------------
if ((routerVersion.dwRouterVersion >= 5) &&
!FLookForRoutingEnabledPorts(m_spRouterInfo->GetMachineName()))
{
AfxMessageBox(IDS_ERR_NO_ROUTING_ENABLED_PORTS);
CWRg( ERROR_CANCELLED );
}
m_spTFSCompData->GetConsole(&spConsole);
// First create the phone book entry.
RASENTRYDLG info;
HWND hwnd;
ZeroMemory( &info, sizeof(info) );
info.dwSize = sizeof(info);
hwnd = NULL;
spConsole->GetMainWindow(&hwnd);
info.hwndOwner = hwnd;
//info.hwndOwner = IFGetApp()->m_hWndHost;
info.dwFlags |= RASEDFLAG_NewEntry;
TRACE0("RouterEntryDlg\n");
ASSERT(m_pfnRouterEntryDlg);
stRouter = m_spRouterInfo->GetMachineName();
GetPhoneBookPath(stRouter, &stPhoneBook);
if (stRouter.GetLength() == 0)
{
stRouter = CString(_T("\\\\")) + GetLocalMachineName();
}
bStatus = m_pfnRouterEntryDlg(
(LPTSTR)(LPCTSTR)stRouter, (LPTSTR)(LPCTSTR)stPhoneBook, NULL, &info);
Trace2("RouterEntryDlg=%f,e=%d\n", bStatus, info.dwError);
if (!bStatus)
{
if (info.dwError != NO_ERROR)
{
AddHighLevelErrorStringId(IDS_ERR_UNABLETOCONFIGPBK);
CWRg( info.dwError );
}
CWRg( ERROR_CANCELLED );
}
CORg( CreateInterfaceInfo(&spIfInfo,
info.szEntry,
ROUTER_IF_TYPE_FULL_ROUTER) );
CORg( spIfInfo->SetTitle(spIfInfo->GetId()) );
CORg( spIfInfo->SetMachineName(m_spRouterInfo->GetMachineName()) );
CORg( m_spRouterInfo->AddInterface(spIfInfo) );
// Ok, we've added the interfaces, we now need to add in
// the appropriate defaults for the router managers
if (info.reserved2 & RASNP_Ip)
{
CORg( AddRouterManagerToInterface(spIfInfo,
m_spRouterInfo,
PID_IP) );
}
if (info.reserved2 & RASNP_Ipx)
{
CORg( AddRouterManagerToInterface(spIfInfo,
m_spRouterInfo,
PID_IPX) );
}
Error:
if (!FHrSucceeded(hr) && (hr != HRESULT_FROM_WIN32(ERROR_CANCELLED)))
{
TCHAR szErr[2048] = _T(" ");
if (hr != E_FAIL) // E_FAIL doesn't give user any information
{
FormatRasError(hr, szErr, DimensionOf(szErr));
}
AddLowLevelErrorString(szErr);
// If there is no high level error string, add a
// generic error string. This will be used if no other
// high level error string is set.
SetDefaultHighLevelErrorStringId(IDS_ERR_GENERIC_ERROR);
DisplayTFSErrorMessage(NULL);
}
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::OnNewTunnel
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::OnNewTunnel()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
SPIConsole spConsole;
SPIInterfaceInfo spIfInfo;
int idsErr = 0;
RouterVersionInfo routerVersion;
TunnelDialog tunnel;
GUID guidNew;
TCHAR szGuid[128];
if (!EnableAddInterface())
{
idsErr = IDS_ERR_TEMPNOADD;
CORg( E_FAIL );
}
// Get the version info. Needed later on.
// ----------------------------------------------------------------
m_spRouterInfo->GetRouterVersionInfo(&routerVersion);
m_spTFSCompData->GetConsole(&spConsole);
// For now, popup a dialog asking for the tunnel information
// ----------------------------------------------------------------
if (tunnel.DoModal() == IDOK)
{
// We need to create a GUID for this tunnel.
// ------------------------------------------------------------
CORg( CoCreateGuid(&guidNew) );
// Convert the GUID into a string
// ------------------------------------------------------------
Verify( StringFromGUID2(guidNew, szGuid, DimensionOf(szGuid)) );
CORg( CreateInterfaceInfo(&spIfInfo,
szGuid,
ROUTER_IF_TYPE_TUNNEL1) );
CORg( spIfInfo->SetTitle(tunnel.m_stName) );
CORg( spIfInfo->SetMachineName(m_spRouterInfo->GetMachineName()) );
CORg( m_spRouterInfo->AddInterface(spIfInfo) );
// Need to add the IP Specific data
ForceGlobalRefresh(m_spRouterInfo);
}
Error:
if (!FHrSucceeded(hr) && (hr != HRESULT_FROM_WIN32(ERROR_CANCELLED)))
{
TCHAR szErr[2048];
if (idsErr)
AddHighLevelErrorStringId(idsErr);
FormatRasError(hr, szErr, DimensionOf(szErr));
AddLowLevelErrorString(szErr);
DisplayTFSErrorMessage(NULL);
}
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::AddRouterManagerToInterface
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::AddRouterManagerToInterface(IInterfaceInfo *pIf,
IRouterInfo *pRouter,
DWORD dwTransportId)
{
HRESULT hr = hrOK;
SPIRtrMgrInfo spRm;
SPIRtrMgrInterfaceInfo spRmIf;
SPIInfoBase spInfoBase;
// Get the router manager
hr = pRouter->FindRtrMgr(dwTransportId, &spRm);
// If this cannot find the RtrMgr, then just exit out.
if (!FHrOK(hr))
goto Error;
// Construct a new CRmInterfaceInfo object
CORg( CreateRtrMgrInterfaceInfo(&spRmIf,
spRm->GetId(),
spRm->GetTransportId(),
pIf->GetId(),
pIf->GetInterfaceType()) );
CORg( spRmIf->SetTitle(pIf->GetTitle()) );
CORg( spRmIf->SetMachineName(pRouter->GetMachineName()) );
// Add this interface to the router-manager
CORg( pIf->AddRtrMgrInterface(spRmIf, NULL) );
// get/create the infobase for this interface
CORg( spRmIf->Load(pIf->GetMachineName(), NULL, NULL, NULL) );
CORg( spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase) );
if (!spInfoBase)
CORg( CreateInfoBase(&spInfoBase) );
if (dwTransportId == PID_IP)
CORg( AddIpPerInterfaceBlocks(pIf, spInfoBase) );
else
{
Assert(dwTransportId == PID_IPX);
CORg( AddIpxPerInterfaceBlocks(pIf, spInfoBase) );
}
// Save the infobase
CORg( spRmIf->Save(pIf->GetMachineName(),
NULL, NULL, NULL, spInfoBase, 0) );
// Mark this interface (it can now be synced with the router)
spRmIf->SetFlags( spRmIf->GetFlags() | RouterSnapin_InSyncWithRouter );
// Notify RM of a new interface
spRm->RtrNotify(ROUTER_CHILD_ADD, ROUTER_OBJ_RmIf, 0);
Error:
if (!FHrSucceeded(hr))
{
// Cleanup
pIf->DeleteRtrMgrInterface(dwTransportId, TRUE);
}
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::OnUseDemandDialWizard
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::OnUseDemandDialWizard()
{
HRESULT hr = hrOK;
DWORD dwWiz;
hr = GetDemandDialWizardRegKey(OLE2CT(m_spRouterInfo->GetMachineName()),
&dwWiz);
if (FHrSucceeded(hr))
{
// Ok, now toggle the switch
SetDemandDialWizardRegKey(OLE2CT(m_spRouterInfo->GetMachineName()),
!dwWiz);
}
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::SynchronizeNodeData
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::SynchronizeNodeData(ITFSNode *pThisNode)
{
Assert(pThisNode);
SPITFSNodeEnum spEnum;
SPITFSNode spNode;
DWORD dwStatus;
DWORD dwConnState;
DWORD dwUnReachabilityReason;
int i;
HRESULT hr = hrOK;
InterfaceNodeData *pData;
SPMprAdminBuffer spIf0Table;
SPMprServerHandle sphMprServer;
MPR_INTERFACE_0 * if0Table = NULL;
DWORD if0Count = 0;
DWORD dwTotal;
DWORD dwErr;
// Get the status data from the running router
dwErr = ConnectRouter(m_spRouterInfo->GetMachineName(), &sphMprServer);
if (dwErr == NO_ERROR)
{
::MprAdminInterfaceEnum(sphMprServer,
0,
(BYTE **) &spIf0Table,
(DWORD) -1,
&if0Count,
&dwTotal,
NULL);
if0Table = (MPR_INTERFACE_0 *) (BYTE *) spIf0Table;
}
pThisNode->GetEnum(&spEnum);
spEnum->Reset();
while (spEnum->Next(1, &spNode, NULL) == hrOK)
{
pData = GET_INTERFACENODEDATA(spNode);
Assert(pData);
// default status/connection states
dwConnState = ROUTER_IF_STATE_UNREACHABLE;
dwUnReachabilityReason = MPR_INTERFACE_NOT_LOADED;
pData->dwLastError = 0;
// Match the status we find to the actual status
for (i=0; i<(int) if0Count; i++)
{
// There could be a client interface with the same name
// as a router interface, so filter the client interfaces
if ((if0Table[i].dwIfType != ROUTER_IF_TYPE_CLIENT) &&
!StriCmpW(pData->spIf->GetId(), if0Table[i].wszInterfaceName))
{
break;
}
}
// If we found an entry in the table, pull the data out
if (i < (int) if0Count)
{
dwConnState = if0Table[i].dwConnectionState;
dwUnReachabilityReason = if0Table[i].fUnReachabilityReasons;
if (dwUnReachabilityReason & MPR_INTERFACE_CONNECTION_FAILURE)
pData->dwLastError = if0Table[i].dwLastError;
}
dwStatus = pData->spIf->IsInterfaceEnabled();
// Place the data into the per-node data area
pData->m_rgData[IFADMIN_SUBITEM_TITLE].m_stData = pData->spIf->GetTitle();
pData->m_rgData[IFADMIN_SUBITEM_DEVICE_NAME].m_stData =
pData->spIf->GetDeviceName();
pData->m_rgData[IFADMIN_SUBITEM_TYPE].m_stData =
InterfaceTypeToCString(pData->spIf->GetInterfaceType());
pData->m_rgData[IFADMIN_SUBITEM_STATUS].m_stData = StatusToCString(dwStatus);
pData->m_rgData[IFADMIN_SUBITEM_CONNECTION_STATE].m_stData =
ConnectionStateToCString(dwConnState);
pData->dwUnReachabilityReason = dwUnReachabilityReason;
pData->dwConnectionState = dwConnState;
pData->fIsRunning = ::MprAdminIsServiceRunning((LPWSTR) pData->spIf->GetMachineName());
// Force MMC to redraw the nodes
spNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
// Cleanup
spNode.Release();
}
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::EnableAddInterface
-
Author: KennT
---------------------------------------------------------------------------*/
BOOL IfAdminNodeHandler::EnableAddInterface()
{
return m_hInstRasDlg != 0;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::GetPhoneBookPath
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::GetPhoneBookPath(LPCTSTR pszMachine, CString *pstPath)
{
CString str = _T(""), stPath;
CString stRouter = pszMachine;
if (pszMachine && StrLen(pszMachine))
{
// add on the two slashes to the beginning of the machine name
if (stRouter.Left(2) != _T("\\\\"))
{
stRouter = _T("\\\\");
stRouter += pszMachine;
}
// If this is not the local machine, use this string
if (stRouter.GetLength() &&
StriCmp(stRouter, CString(_T("\\\\")) + GetLocalMachineName()))
str = stRouter;
}
Verify( FHrSucceeded(::GetRouterPhonebookPath(str, &stPath)) );
*pstPath = stPath;
return hrOK;
}
ImplementEmbeddedUnknown(IfAdminNodeHandler, IRtrAdviseSink)
STDMETHODIMP IfAdminNodeHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
{
InitPThis(IfAdminNodeHandler, IRtrAdviseSink);
SPIEnumInterfaceInfo spEnumIf;
SPIInterfaceInfo spIf;
SPITFSNode spThisNode;
SPITFSNode spNode;
SPITFSNodeEnum spEnumNode;
InterfaceNodeData * pNodeData;
BOOL fFound, fAdded;
HRESULT hr = hrOK;
pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spThisNode);
if (dwObjectType == ROUTER_OBJ_If)
{
// Force a data refresh of the current result pane
if (dwChangeType == ROUTER_CHILD_DELETE)
{
// Go through the list of nodes, if we cannot find this
// node in the list of interfaces, delete the node
spThisNode->GetEnum(&spEnumNode);
spEnumNode->Reset();
while (spEnumNode->Next(1, &spNode, NULL) == hrOK)
{
// Get the node data, look for the interface
pNodeData = GET_INTERFACENODEDATA(spNode);
pThis->m_spRouterInfo->FindInterface(pNodeData->spIf->GetId(),
&spIf);
if (spIf == NULL)
{
// cannot find the interface, release this node!
spThisNode->RemoveChild(spNode);
spNode->Destroy();
}
spNode.Release();
spIf.Release();
}
}
else if (dwChangeType == ROUTER_CHILD_ADD)
{
// Enumerate through the list of interfaces
// if we cannot find this interface in our current
// set of nodes, then add it.
spThisNode->GetEnum(&spEnumNode);
CORg( pThis->m_spRouterInfo->EnumInterface(&spEnumIf) );
fAdded = FALSE;
spEnumIf->Reset();
while (spEnumIf->Next(1, &spIf, NULL) == hrOK)
{
// Look for this interface in our list of nodes
fFound = FALSE;
spEnumNode->Reset();
while (spEnumNode->Next(1, &spNode, NULL) == hrOK)
{
pNodeData = GET_INTERFACENODEDATA(spNode);
Assert(pNodeData);
if (StriCmpW(pNodeData->spIf->GetId(),spIf->GetId()) == 0)
{
fFound = TRUE;
break;
}
spNode.Release();
}
//
// If the interface was not found in the list of nodes,
// then we should add the interface to the UI.
//
if (!fFound)
{
pThis->AddInterfaceNode(spThisNode, spIf);
fAdded = TRUE;
}
spNode.Release();
spIf.Release();
}
// Now that we have all of the nodes, update the data for
// all of the nodes
if (fAdded)
pThis->SynchronizeNodeData(spThisNode);
// Windows NT Bug : 288247
// Set this here, so that we can avoid the nodes being
// added in the OnExpand().
pThis->m_bExpanded = TRUE;
}
// Determine what nodes were deleted, changed, or added
// and do the appropriate action
}
else if (dwChangeType == ROUTER_REFRESH)
{
// Ok, just call the synchronize on this node
pThis->SynchronizeNodeData(spThisNode);
}
Error:
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::CompareItems
Implementation of ITFSResultHandler::CompareItems
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP_(int) IfAdminNodeHandler::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);
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::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 IfAdminNodeHandler::AddMenuItems(ITFSComponent *pComponent,
MMC_COOKIE cookie,
LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK pCallback,
long *pInsertionAllowed)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SPITFSNode spNode;
CString stMenu;
LONG lMenuText;
HRESULT hr = hrOK;
m_spNodeMgr->FindNode(cookie, &spNode);
hr = OnAddMenuItems(spNode,
pCallback,
pDataObject,
CCT_RESULT,
TFS_COMPDATA_CHILD_CONTEXTMENU,
pInsertionAllowed);
CORg( hr );
Error:
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::Command
-
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP IfAdminNodeHandler::Command(ITFSComponent *pComponent,
MMC_COOKIE cookie,
int nCommandID,
LPDATAOBJECT pDataObject)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SPITFSNode spNode;
HRESULT hr = hrOK;
m_spNodeMgr->FindNode(cookie, &spNode);
hr = OnCommand(spNode,
nCommandID,
CCT_RESULT,
pDataObject,
TFS_COMPDATA_CHILD_CONTEXTMENU);
return hr;
}
typedef DWORD (APIENTRY* PRASRPCCONNECTSERVER)(LPTSTR, HANDLE *);
typedef DWORD (APIENTRY* PRASRPCDISCONNECTSERVER)(HANDLE);
typedef DWORD (APIENTRY* PRASRPCREMOTEGETUSERPREFERENCES)(HANDLE, PBUSER *, DWORD);
typedef DWORD (APIENTRY* PRASRPCREMOTESETUSERPREFERENCES)(HANDLE, PBUSER *, DWORD);
/*!--------------------------------------------------------------------------
GetDemandDialWizardRegKey
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT GetDemandDialWizardRegKey(LPCTSTR szMachine, DWORD *pfWizard)
{
ASSERT(pfWizard);
BOOL fUnload = FALSE;
DWORD dwErr;
PBUSER pbUser;
PRASRPCCONNECTSERVER pRasRpcConnectServer;
PRASRPCDISCONNECTSERVER pRasRpcDisconnectServer;
PRASRPCREMOTEGETUSERPREFERENCES pRasRpcRemoteGetUserPreferences;
PRASRPCREMOTESETUSERPREFERENCES pRasRpcRemoteSetUserPreferences;
HINSTANCE hrpcdll = NULL;
HANDLE hConnection = NULL;
if (!(hrpcdll = LoadLibrary(TEXT("rasman.dll"))) ||
!(pRasRpcConnectServer =
(PRASRPCCONNECTSERVER)GetProcAddress(
hrpcdll, "RasRpcConnectServer"
)) ||
!(pRasRpcDisconnectServer =
(PRASRPCDISCONNECTSERVER)GetProcAddress(
hrpcdll, "RasRpcDisconnectServer"
)) ||
!(pRasRpcRemoteGetUserPreferences =
(PRASRPCREMOTEGETUSERPREFERENCES)GetProcAddress(
hrpcdll, "RasRpcRemoteGetUserPreferences"
)) ||
!(pRasRpcRemoteSetUserPreferences =
(PRASRPCREMOTESETUSERPREFERENCES)GetProcAddress(
hrpcdll, "RasRpcRemoteSetUserPreferences"
)))
{
if (hrpcdll) { FreeLibrary(hrpcdll); }
return HRESULT_FROM_WIN32(GetLastError());
}
dwErr = pRasRpcConnectServer((LPTSTR) szMachine, &hConnection);
if (dwErr)
goto Error;
fUnload = TRUE;
dwErr = pRasRpcRemoteGetUserPreferences(hConnection, &pbUser, UPM_Router);
if (dwErr)
goto Error;
*pfWizard = pbUser.fNewEntryWizard;
// Ignore error codes for these calls, we can't do
// anything about them if they fail.
pRasRpcRemoteSetUserPreferences(hConnection, &pbUser, UPM_Router);
DestroyUserPreferences((PBUSER *) &pbUser);
Error:
if (fUnload)
pRasRpcDisconnectServer(hConnection);
if (hrpcdll)
FreeLibrary(hrpcdll);
return HRESULT_FROM_WIN32(dwErr);
}
/*!--------------------------------------------------------------------------
SetDemandDialWizardRegistyKey
This is a function that was added for Beta1 of Steelhead. We want
to allow the user to use the wizard even though it was turned off.
So we have added this hack for the beta where we set the registry
key for the user/
Author: KennT
---------------------------------------------------------------------------*/
HRESULT SetDemandDialWizardRegKey(LPCTSTR szMachine, DWORD fEnableWizard)
{
DWORD dwErr;
PBUSER pbUser;
BOOL fUnload = FALSE;
PRASRPCCONNECTSERVER pRasRpcConnectServer;
PRASRPCDISCONNECTSERVER pRasRpcDisconnectServer;
PRASRPCREMOTEGETUSERPREFERENCES pRasRpcRemoteGetUserPreferences;
PRASRPCREMOTESETUSERPREFERENCES pRasRpcRemoteSetUserPreferences;
HINSTANCE hrpcdll = NULL;
HANDLE hConnection = NULL;
if (!(hrpcdll = LoadLibrary(TEXT("rasman.dll"))) ||
!(pRasRpcConnectServer =
(PRASRPCCONNECTSERVER)GetProcAddress(
hrpcdll, "RasRpcConnectServer"
)) ||
!(pRasRpcDisconnectServer =
(PRASRPCDISCONNECTSERVER)GetProcAddress(
hrpcdll, "RasRpcDisconnectServer"
)) ||
!(pRasRpcRemoteGetUserPreferences =
(PRASRPCREMOTEGETUSERPREFERENCES)GetProcAddress(
hrpcdll, "RasRpcRemoteGetUserPreferences"
)) ||
!(pRasRpcRemoteSetUserPreferences =
(PRASRPCREMOTESETUSERPREFERENCES)GetProcAddress(
hrpcdll, "RasRpcRemoteSetUserPreferences"
)))
{
if (hrpcdll) { FreeLibrary(hrpcdll); }
return HRESULT_FROM_WIN32(GetLastError());
}
dwErr = pRasRpcConnectServer((LPTSTR) szMachine, &hConnection);
if (dwErr)
goto Error;
fUnload = TRUE;
dwErr = pRasRpcRemoteGetUserPreferences(hConnection, &pbUser, UPM_Router);
if (dwErr)
goto Error;
pbUser.fNewEntryWizard = fEnableWizard;
pbUser.fDirty = TRUE;
// Ignore error codes for these calls, we can't do
// anything about them if they fail.
pRasRpcRemoteSetUserPreferences(hConnection, &pbUser, UPM_Router);
DestroyUserPreferences((PBUSER *) &pbUser);
Error:
if (fUnload)
pRasRpcDisconnectServer(hConnection);
if (hrpcdll)
FreeLibrary(hrpcdll);
return HRESULT_FROM_WIN32(dwErr);
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::AddInterfaceNode
Adds an interface to the UI. This will create a new result item
node for each interface.
Author: KennT
---------------------------------------------------------------------------*/
HRESULT IfAdminNodeHandler::AddInterfaceNode(ITFSNode *pParent, IInterfaceInfo *pIf)
{
InterfaceNodeHandler * pHandler;
SPITFSResultHandler spHandler;
SPITFSNode spNode;
HRESULT hr = hrOK;
pHandler = new InterfaceNodeHandler(m_spTFSCompData);
spHandler = pHandler;
CORg( pHandler->Init(pIf, pParent) );
CORg( CreateLeafTFSNode(&spNode,
NULL,
static_cast<ITFSNodeHandler *>(pHandler),
static_cast<ITFSResultHandler *>(pHandler),
m_spNodeMgr) );
CORg( pHandler->ConstructNode(spNode, pIf) );
// Make the node immediately visible
CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
CORg( pParent->AddChild(spNode) );
Error:
return hr;
}
/*!--------------------------------------------------------------------------
IfAdminNodeHandler::FLookForRoutingEnabledPorts
Returns TRUE if we find at least on routing-enabled port.
Author: KennT
---------------------------------------------------------------------------*/
BOOL IfAdminNodeHandler::FLookForRoutingEnabledPorts(LPCTSTR pszMachineName)
{
PortsDataEntry portsData;
PortsDeviceList portsList;
PortsDeviceEntry * pPorts = NULL;
BOOL fReturn = FALSE;
HRESULT hr = hrOK;
POSITION pos;
COM_PROTECT_TRY
{
CORg( portsData.Initialize(pszMachineName) );
CORg( portsData.LoadDevices(&portsList) );
// Now go through the list, looking for a routing-enabled port
pos = portsList.GetHeadPosition();
while (pos)
{
pPorts = portsList.GetNext(pos);
if ((pPorts->m_dwEnableRouting) ||
(pPorts->m_dwEnableOutboundRouting))
{
fReturn = TRUE;
break;
}
}
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
while (!portsList.IsEmpty())
delete portsList.RemoveHead();
return fReturn;
}
/*---------------------------------------------------------------------------
TunnelDialog implementation
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
TunnelDialog::TunnelDialog
-
Author: KennT
---------------------------------------------------------------------------*/
TunnelDialog::TunnelDialog()
: CBaseDialog(TunnelDialog::IDD)
{
}
/*!--------------------------------------------------------------------------
TunnelDialog::~TunnelDialog
-
Author: KennT
---------------------------------------------------------------------------*/
TunnelDialog::~TunnelDialog()
{
}
BEGIN_MESSAGE_MAP(TunnelDialog, CBaseDialog)
//{{AFX_MSG_MAP(TunnelDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*!--------------------------------------------------------------------------
RadiusServerDialog::DoDataExchange
-
Author: KennT
---------------------------------------------------------------------------*/
void TunnelDialog::DoDataExchange(CDataExchange* pDX)
{
CBaseDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(TunnelDialog)
//}}AFX_DATA_MAP
}
/*!--------------------------------------------------------------------------
TunnelDialog::OnInitDialog
-
Author: KennT
---------------------------------------------------------------------------*/
BOOL TunnelDialog::OnInitDialog()
{
CBaseDialog::OnInitDialog();
return TRUE;
}
/*!--------------------------------------------------------------------------
TunnelDialog::OnOK
-
Author: KennT
---------------------------------------------------------------------------*/
void TunnelDialog::OnOK()
{
CString stLocal, stRemote;
GetDlgItemText(IDC_TUNNEL_EDIT_NAME, m_stName);
m_stName.TrimLeft();
m_stName.TrimRight();
if (m_stName.IsEmpty())
{
AfxMessageBox(IDS_ERR_TUNNEL_NEEDS_A_NAME);
GetDlgItem(IDC_TUNNEL_EDIT_NAME)->SetFocus();
goto Error;
}
// Truncate the interface ID to MAX_INTERFACE_NAME_LEN characters
if (m_stName.GetLength() > MAX_INTERFACE_NAME_LEN)
{
m_stName.GetBufferSetLength(MAX_INTERFACE_NAME_LEN+1);
m_stName.ReleaseBuffer(MAX_INTERFACE_NAME_LEN);
}
CBaseDialog::OnOK();
Error:
return;
}