|
|
/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/ /**********************************************************************/
/*
Ports Interface node information FILE HISTORY: */
#include "stdafx.h"
#include "Ports.h"
#include "ifadmin.h"
#include "rtrstrm.h" // for RouterAdminConfigStream
#include "rtrlib.h" // ContainerColumnInfo
#include "coldlg.h" // ColumnDlg
#include "column.h" // ComponentConfigStream
#include "refresh.h" // IRouterRefresh
#include "iface.h" // for interfacenode data
#include "portdlg.h" // CConnDlg - connection dialog
#include "msgdlg.h" // CMessageDlg
#include "raserror.h"
#include "dmvcomp.h"
#include "remras.h"
#include "rrasutil.h" // Smart pointers
#include "rtrcomn.h" // CoCreateRouterConfig
#include "rtrutilp.h" // PortsDeviceTypeToCString
static BOOL RestartComputer(LPTSTR szMachineName);
//$PPTP
// This is the maximum number of ports that we allow for PPTP.
// Thus we can raise the maximum to this value only.
// --------------------------------------------------------------------
#define PPTP_MAX_PORTS 16384
//$L2TP
// This is the maximum number of ports that we allow for L2TP.
// Thus we can raise the maximum to this value only.
// --------------------------------------------------------------------
#define L2TP_MAX_PORTS 30000
/*---------------------------------------------------------------------------
Defaults ---------------------------------------------------------------------------*/
PortsNodeData::PortsNodeData() { #ifdef DEBUG
StrCpyA(m_szDebug, "PortsNodeData"); #endif
}
PortsNodeData::~PortsNodeData() { }
/*!--------------------------------------------------------------------------
PortsNodeData::InitAdminNodeData - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeData::InitAdminNodeData(ITFSNode *pNode, RouterAdminConfigStream *pConfigStream) { HRESULT hr = hrOK; PortsNodeData * pData = NULL; pData = new PortsNodeData;
SET_PORTSNODEDATA(pNode, pData);
// Need to connect to the router to get this data
return hr; }
/*!--------------------------------------------------------------------------
PortsNodeData::FreeAdminNodeData - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeData::FreeAdminNodeData(ITFSNode *pNode) { PortsNodeData * pData = GET_PORTSNODEDATA(pNode); delete pData; SET_PORTSNODEDATA(pNode, NULL); return hrOK; }
HRESULT PortsNodeData::LoadHandle(LPCTSTR pszMachineName) { m_stMachineName = pszMachineName; return HResultFromWin32(::MprAdminServerConnect((LPTSTR) pszMachineName, &m_sphDdmHandle)); }
HANDLE PortsNodeData::GetHandle() { if (!m_sphDdmHandle) { LoadHandle(m_stMachineName); } return m_sphDdmHandle; }
void PortsNodeData::ReleaseHandles() { m_sphDdmHandle.Release(); }
STDMETHODIMP PortsNodeHandler::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_rgPortsColumnInfo[];
const ContainerColumnInfo s_rgPortsColumnInfo[] = { { IDS_PORTS_COL_NAME, CON_SORT_BY_STRING, TRUE , COL_IF_NAME}, { IDS_PORTS_COL_DEVICE, CON_SORT_BY_STRING, TRUE , COL_STRING}, { IDS_PORTS_COL_USAGE, CON_SORT_BY_STRING, TRUE , COL_STRING}, { IDS_PORTS_COL_STATUS, CON_SORT_BY_STRING, TRUE , COL_STATUS}, { IDS_PORTS_COL_COMMENT, CON_SORT_BY_STRING, FALSE , COL_STRING}, }; #define NUM_FOLDERS 1
PortsNodeHandler::PortsNodeHandler(ITFSComponentData *pCompData) : BaseContainerHandler(pCompData, DM_COLUMNS_PORTS, s_rgPortsColumnInfo), m_bExpanded(FALSE), m_pConfigStream(NULL), m_ulConnId(0), m_ulRefreshConnId(0), m_dwActivePorts(0) {
m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED; m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
// Setup the verb states for this node
m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED; m_bState[MMC_VERB_REFRESH_INDEX] = TRUE; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::Init - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::Init(IRouterInfo *pRouterInfo, RouterAdminConfigStream *pConfigStream) { HRESULT hr = hrOK;
// 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);
m_pConfigStream = pConfigStream;
Error: return hrOK; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::DestroyHandler Implementation of ITFSNodeHandler::DestroyHandler Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsNodeHandler::DestroyHandler(ITFSNode *pNode) { PortsNodeData::FreeAdminNodeData(pNode);
m_spDataObject.Release(); 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; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::HasPropertyPages Implementation of ITFSNodeHandler::HasPropertyPages Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsNodeHandler::HasPropertyPages ( ITFSNode * pNode, LPDATAOBJECT pDataObject, DATA_OBJECT_TYPES type, DWORD dwType ) { // Yes, we do have property pages
return hrOK; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::CreatePropertyPages Implementation of ITFSNodeHandler::CreatePropertyPages Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsNodeHandler::CreatePropertyPages( ITFSNode * pNode, LPPROPERTYSHEETCALLBACK lpProvider, LPDATAOBJECT pDataObject, LONG_PTR handle, DWORD dwType ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = hrOK;
PortsProperties* pPropSheet = NULL; SPIComponentData spComponentData; CString stTitle;
CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
pPropSheet = new PortsProperties(pNode, spComponentData, m_spTFSCompData, stTitle, NULL, 0, TRUE );
if ( FHrFailed(pPropSheet->Init(m_spRouterInfo, this)) ) { AfxMessageBox(IDS_ERR_NO_ROUTERPROTOCOLS); delete pPropSheet; return hr; }
if (lpProvider) hr = pPropSheet->CreateModelessSheet(lpProvider, handle); else hr = pPropSheet->DoModelessSheet();
Error: return hr; }
/*---------------------------------------------------------------------------
Menu data structure for our menus ---------------------------------------------------------------------------*/
struct SPortsNodeMenu { ULONG m_sidMenu; // string/command id for this menu item
ULONG (PortsNodeHandler:: *m_pfnGetMenuFlags)(PortsNodeHandler::SMenuData *); ULONG m_ulPosition; };
//static const SPortsNodeMenu s_rgPortsNodeMenu[] =
//{
// // Add items that are primary go here
// // Add items that go on the "Create new" menu here
// // Add items that go on the "Task" menu here
//};
/*!--------------------------------------------------------------------------
PortsNodeHandler::OnAddMenuItems Implementation of ITFSNodeHandler::OnAddMenuItems Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsNodeHandler::OnAddMenuItems( ITFSNode *pNode, LPCONTEXTMENUCALLBACK pContextMenuCallback, LPDATAOBJECT lpDataObject, DATA_OBJECT_TYPES type, DWORD dwType, long *pInsertionAllowed) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = S_OK; COM_PROTECT_TRY { // Uncomment if you have items to add
// hr = AddArrayOfMenuItems(pNode, s_rgPortsNodeMenu,
// DimensionOf(s_rgPortsNodeMenu),
// pContextMenuCallback,
// *pInsertionAllowed);
} COM_PROTECT_CATCH; return hr; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::GetString Implementation of ITFSNodeHandler::GetString Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP_(LPCTSTR) PortsNodeHandler::GetString(ITFSNode *pNode, int nCol) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
COM_PROTECT_TRY { if (m_stTitle.IsEmpty()) m_stTitle.LoadString(IDS_PORTS); } COM_PROTECT_CATCH;
return m_stTitle; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::OnCreateDataObject Implementation of ITFSNodeHandler::OnCreateDataObject Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsNodeHandler::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; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::OnExpand - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::OnExpand(ITFSNode *pNode, LPDATAOBJECT pDataObject, DWORD dwType, LPARAM arg, LPARAM lParam) { HRESULT hr = hrOK;
// 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; if (m_bExpanded) return hrOK;
COM_PROTECT_TRY { SynchronizeNodeData(pNode);
m_bExpanded = TRUE;
} COM_PROTECT_CATCH;
return hr; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::OnResultShow - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::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; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::ConstructNode Initializes the Domain node (sets it up). Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::ConstructNode(ITFSNode *pNode) { HRESULT hr = hrOK; PortsNodeData * 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_RouterPortsNodeType); PortsNodeData::InitAdminNodeData(pNode, m_pConfigStream);
pNodeData = GET_PORTSNODEDATA(pNode); Assert(pNodeData); //if there is any handle open, release it first
pNodeData->ReleaseHandles(); // Ignore the error, we should be able to deal with the
// case of a stopped router.
pNodeData->LoadHandle(m_spRouterInfo->GetMachineName()); } COM_PROTECT_CATCH
return hr; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::SynchronizeNodeData - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::SynchronizeNodeData(ITFSNode *pThisNode) { Assert(pThisNode); SPITFSNodeEnum spEnum; int i; HRESULT hr = hrOK; InterfaceNodeData *pData; DWORD dwErr; PortsNodeData * pNodeData; PortsList portsList; PortsList newPortsList; PortsListEntry * pPorts; BOOL fFound; POSITION pos; SPITFSNode spChildNode; InterfaceNodeData * pChildData;
DWORD dwOldGdiBatchLimit;
dwOldGdiBatchLimit = GdiGetBatchLimit(); GdiSetBatchLimit(100);
COM_PROTECT_TRY {
// Get the status data from the running router
pNodeData = GET_PORTSNODEDATA(pThisNode); // Ignore the error, we should be able to deal with the
// case of a stopped router.
if(pNodeData) { pNodeData->ReleaseHandles(); pNodeData->LoadHandle(m_spRouterInfo->GetMachineName()); }
if (pNodeData == NULL || INVALID_HANDLE_VALUE == pNodeData->GetHandle()) { // Remove all of the nodes, we can't connect so we can't
// get any running data.
UnmarkAllNodes(pThisNode, spEnum); RemoveAllUnmarkedNodes(pThisNode, spEnum); return hrOK; } // Unmark all of the nodes
pThisNode->GetEnum(&spEnum); UnmarkAllNodes(pThisNode, spEnum); // Go out and grab the data, merge the the new data in with
// the old data.
if( S_OK == GenerateListOfPorts(pThisNode, &portsList) ) { pos = portsList.GetHeadPosition();
// clear active ports count -- for bug 165862
m_dwActivePorts = 0; while (pos) { pPorts = & portsList.GetNext(pos); // Look for this entry in our current list of nodes
spEnum->Reset(); spChildNode.Release(); fFound = FALSE; for (;spEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release()) { pChildData = GET_INTERFACENODEDATA(spChildNode); Assert(pChildData);
if (pChildData->m_rgData[PORTS_SI_PORT].m_ulData == (LONG_PTR) pPorts->m_rp0.hPort) { // Ok, this user already exists, update the metric
// and mark it
Assert(pChildData->dwMark == FALSE); pChildData->dwMark = TRUE; fFound = TRUE; SetUserData(spChildNode, *pPorts); // Force MMC to redraw the node
spChildNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA); break; } } if (!fFound) newPortsList.AddTail(*pPorts); } }
// Remove all nodes that were not marked
RemoveAllUnmarkedNodes(pThisNode, spEnum);
// Now iterate through the list of new users, adding them all in.
pos = newPortsList.GetHeadPosition(); while (pos) { pPorts = & newPortsList.GetNext(pos);
AddPortsUserNode(pThisNode, *pPorts); } } COM_PROTECT_CATCH;
GdiFlush(); GdiSetBatchLimit(dwOldGdiBatchLimit); return hr; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::SetUserData - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::SetUserData(ITFSNode *pNode, const PortsListEntry& entry) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = hrOK; InterfaceNodeData * pData; TCHAR szNumber[32]; CString st; int ids;
pData = GET_INTERFACENODEDATA(pNode); Assert(pData);
st.Format(IDS_PORTS_NAME_FORMAT, entry.m_rp0.wszDeviceName, entry.m_rp0.wszPortName); pData->m_rgData[PORTS_SI_NAME].m_stData = st; pData->m_rgData[PORTS_SI_DEVICE].m_stData = entry.m_rp0.wszDeviceType;
if (entry.m_fActiveDialOut) { ids = IDS_PORTS_DIALOUT_ACTIVE; } else if (entry.m_rp0.dwPortCondition == RAS_PORT_AUTHENTICATED) { ids = IDS_PORTS_ACTIVE; // to know how many active ports: BUG -- 165862
// to prepare total number of active ports -- Wei Jiang
m_dwActivePorts++; } else { ids = IDS_PORTS_INACTIVE; } pData->m_rgData[PORTS_SI_STATUS].m_stData.LoadString(ids); pData->m_rgData[PORTS_SI_STATUS].m_dwData = entry.m_rp0.dwPortCondition;
pData->m_rgData[PORTS_SI_PORT].m_ulData = (LONG_PTR) entry.m_rp0.hPort;
// fix b: 32887 -- show ras/routing enabled information
// Column 0...Usage
INT iType = (entry.m_dwEnableRas * 2) + entry.m_dwEnableRouting | entry.m_dwEnableOutboundRouting; pData->m_rgData[PORTS_SI_USAGE].m_stData = PortsDeviceTypeToCString(iType);
// Update the PortsListEntry
* (PortsListEntry *)pData->lParamPrivate = entry; // For status, need to check to see if there are any connections
// on this port.
return hr; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::GenerateListOfPorts - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::GenerateListOfPorts(ITFSNode *pNode, PortsList *pList) { HRESULT hr = hrOK; PortsListEntry entry; PortsNodeData * pPortsData; DWORD dwTotal; DWORD i; RAS_PORT_0 * rp0Table; DWORD rp0Count; SPMprAdminBuffer spMpr; HANDLE hRasHandle = INVALID_HANDLE_VALUE; DWORD dwSize, dwEntries; DWORD dwErr; LPBYTE pbPorts = NULL; POSITION pos; POSITION posPort; RasmanPortMap portMap; // fix b: 3288 --
PortsDeviceList portsDeviceList; PortsDataEntry portsDataEntry;
pPortsData = GET_PORTSNODEDATA(pNode); Assert(pPortsData);
// If we are connected, enumerate through the list of
// ports
CWRg( ::MprAdminPortEnum( pPortsData->GetHandle(), 0, INVALID_HANDLE_VALUE, (BYTE **) &rp0Table, (DWORD) -1, &rp0Count, &dwTotal, NULL) );
Assert(rp0Table); spMpr = (LPBYTE) rp0Table;
// Add a new PortsListEntry for each port
// fix b: 32887 -- show ras/routing enabled information
// use PortsDataEntry to load the device information to be use later for each ports
// to get if a port is enabled for ras / routing
hr = portsDataEntry.Initialize(m_spRouterInfo->GetMachineName());
if (hr == S_OK) { hr = portsDataEntry.LoadDevices(&portsDeviceList); } for (i=0; i<rp0Count; i++) { ::ZeroMemory(&entry, sizeof(entry)); entry.m_rp0 = rp0Table[i];
//Get the unicode name from the port handle
//RasGetUnicodeDeviceName(entry.m_rp0.hPort, entry.m_rp0.wszDeviceName);
entry.m_fActiveDialOut = FALSE;
// find out if ras / routing is enabled on the port
entry.m_dwEnableRas = 0; // = 1 if RAS is enabled on this device
entry.m_dwEnableRouting = 0; // = 1 if Routing is enabled on this device
entry.m_dwEnableOutboundRouting = 0; // = 1 if outbound
// routing is enabled
// on this device
POSITION pos; pos = portsDeviceList.GetHeadPosition();
while(pos != NULL) { PortsDeviceEntry * pPortEntry = portsDeviceList.GetNext(pos);
CString strPortName = entry.m_rp0.wszDeviceName;
if(strPortName == pPortEntry->m_stDisplayName) { entry.m_dwEnableRas = pPortEntry->m_dwEnableRas; entry.m_dwEnableRouting = pPortEntry->m_dwEnableRouting; entry.m_dwEnableOutboundRouting = pPortEntry->m_dwEnableOutboundRouting; break; } }
pList->AddTail(entry); }
spMpr.Free();
Error: delete [] pbPorts; if (hRasHandle != INVALID_HANDLE_VALUE) RasRpcDisconnectServer(hRasHandle); return hr; }
ImplementEmbeddedUnknown(PortsNodeHandler, IRtrAdviseSink)
STDMETHODIMP PortsNodeHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn, DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); InitPThis(PortsNodeHandler, IRtrAdviseSink); SPITFSNode spThisNode; HRESULT hr = hrOK;
COM_PROTECT_TRY {
pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spThisNode); if (dwChangeType == ROUTER_REFRESH) { // Ok, just call the synchronize on this node
pThis->SynchronizeNodeData(spThisNode); } else if (dwChangeType == ROUTER_DO_DISCONNECT) { PortsNodeData * pData = GET_PORTSNODEDATA(spThisNode); Assert(pData);
// Release the handle
pData->ReleaseHandles(); } } COM_PROTECT_CATCH; return hr; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::CompareItems Implementation of ITFSResultHandler::CompareItems Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP_(int) PortsNodeHandler::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); }
/*!--------------------------------------------------------------------------
PortsNodeHandler::AddPortsUserNode Adds a user to the UI. This will create a new result item node for each interface. Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::AddPortsUserNode(ITFSNode *pParent, const PortsListEntry& PortsEntry) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); PortsUserHandler * pHandler; SPITFSResultHandler spHandler; SPITFSNode spNode; HRESULT hr = hrOK;
pHandler = new PortsUserHandler(m_spTFSCompData); spHandler = pHandler; CORg( pHandler->Init(m_spRouterInfo, pParent) ); CORg( CreateLeafTFSNode(&spNode, NULL, static_cast<ITFSNodeHandler *>(pHandler), static_cast<ITFSResultHandler *>(pHandler), m_spNodeMgr) ); CORg( pHandler->ConstructNode(spNode, NULL, &PortsEntry) );
SetUserData(spNode, PortsEntry); // Make the node immediately visible
CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) ); CORg( pParent->AddChild(spNode) ); Error: return hr; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::UnmarkAllNodes - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::UnmarkAllNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum) { SPITFSNode spChildNode; InterfaceNodeData * pNodeData; pEnum->Reset(); for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release()) { pNodeData = GET_INTERFACENODEDATA(spChildNode); Assert(pNodeData); pNodeData->dwMark = FALSE; } return hrOK; }
/*!--------------------------------------------------------------------------
PortsNodeHandler::RemoveAllUnmarkedNodes - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsNodeHandler::RemoveAllUnmarkedNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum) { HRESULT hr = hrOK; SPITFSNode spChildNode; InterfaceNodeData * pNodeData; pEnum->Reset(); for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release()) { pNodeData = GET_INTERFACENODEDATA(spChildNode); Assert(pNodeData); if (pNodeData->dwMark == FALSE) { pNode->RemoveChild(spChildNode); spChildNode->Destroy(); } }
return hr; }
/*---------------------------------------------------------------------------
PortsUserHandler implementation ---------------------------------------------------------------------------*/
DEBUG_DECLARE_INSTANCE_COUNTER(PortsUserHandler)
IMPLEMENT_ADDREF_RELEASE(PortsUserHandler)
STDMETHODIMP PortsUserHandler::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 CBaseResultHandler::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 ---------------------------------------------------------------------------*/
PortsUserHandler::PortsUserHandler(ITFSComponentData *pCompData) : BaseRouterHandler(pCompData), m_ulConnId(0) { DEBUG_INCREMENT_INSTANCE_COUNTER(PortsUserHandler);
// Enable Refresh from the node itself
// ----------------------------------------------------------------
m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED; m_bState[MMC_VERB_REFRESH_INDEX] = TRUE; }
/*!--------------------------------------------------------------------------
PortsUserHandler::Init - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsUserHandler::Init(IRouterInfo *pInfo, ITFSNode *pParent) { m_spRouterInfo.Set(pInfo); return hrOK; }
/*!--------------------------------------------------------------------------
PortsUserHandler::DestroyResultHandler - Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsUserHandler::DestroyResultHandler(MMC_COOKIE cookie) { SPITFSNode spNode; m_spNodeMgr->FindNode(cookie, &spNode); InterfaceNodeData::Free(spNode); CHandler::DestroyResultHandler(cookie); return hrOK; }
static DWORD s_rgInterfaceImageMap[] = { ROUTER_IF_TYPE_HOME_ROUTER, IMAGE_IDX_WAN_CARD, ROUTER_IF_TYPE_FULL_ROUTER, IMAGE_IDX_WAN_CARD, ROUTER_IF_TYPE_CLIENT, IMAGE_IDX_WAN_CARD, ROUTER_IF_TYPE_DEDICATED, IMAGE_IDX_LAN_CARD, ROUTER_IF_TYPE_INTERNAL, IMAGE_IDX_LAN_CARD, ROUTER_IF_TYPE_LOOPBACK, IMAGE_IDX_LAN_CARD, -1, IMAGE_IDX_WAN_CARD, // sentinel value
};
/*!--------------------------------------------------------------------------
PortsUserHandler::ConstructNode Initializes the Domain node (sets it up). Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsUserHandler::ConstructNode(ITFSNode *pNode, IInterfaceInfo *pIfInfo, const PortsListEntry *pEntry) { HRESULT hr = hrOK; int i; InterfaceNodeData * pData;
Assert(pEntry); if (pNode == NULL) return hrOK;
COM_PROTECT_TRY { // Need to initialize the data for the Domain node
pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_WAN_CARD); pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_WAN_CARD); pNode->SetData(TFS_DATA_SCOPEID, 0);
pNode->SetData(TFS_DATA_COOKIE, reinterpret_cast<LONG_PTR>(pNode));
//$ Review: kennt, what are the different type of interfaces
// do we distinguish based on the same list as above? (i.e. the
// one for image indexes).
pNode->SetNodeType(&GUID_RouterPortsResultNodeType);
m_entry = *pEntry;
InterfaceNodeData::Init(pNode, pIfInfo);
// We need to save this pointer so that it can be modified
// (and updated) at a later time.
// ------------------------------------------------------------
pData = GET_INTERFACENODEDATA(pNode); pData->lParamPrivate = (LPARAM) &m_entry; } COM_PROTECT_CATCH return hr; }
/*!--------------------------------------------------------------------------
PortsUserHandler::GetString - Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP_(LPCTSTR) PortsUserHandler::GetString(ITFSComponent * pComponent, MMC_COOKIE cookie, int nCol) { Assert(m_spNodeMgr); SPITFSNode spNode; InterfaceNodeData * pData; ConfigStream * pConfig;
m_spNodeMgr->FindNode(cookie, &spNode); Assert(spNode);
pData = GET_INTERFACENODEDATA(spNode); Assert(pData);
pComponent->GetUserData((LONG_PTR *) &pConfig); Assert(pConfig);
return pData->m_rgData[pConfig->MapColumnToSubitem(DM_COLUMNS_PORTS, nCol)].m_stData; }
/*!--------------------------------------------------------------------------
PortsUserHandler::CompareItems - Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP_(int) PortsUserHandler::CompareItems(ITFSComponent * pComponent, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int nCol) { return StriCmpW(GetString(pComponent, cookieA, nCol), GetString(pComponent, cookieB, nCol)); }
static const SRouterNodeMenu s_rgIfNodeMenu[] = { { IDS_MENU_PORTS_STATUS, 0, CCM_INSERTIONPOINTID_PRIMARY_TOP}, { IDS_MENU_PORTS_DISCONNECT, PortsUserHandler::GetDisconnectMenuState, CCM_INSERTIONPOINTID_PRIMARY_TOP}, };
ULONG PortsUserHandler::GetDisconnectMenuState(const SRouterNodeMenu *pMenuData, INT_PTR pUserData) { InterfaceNodeData * pNodeData; SMenuData * pData = reinterpret_cast<SMenuData *>(pUserData); pNodeData = GET_INTERFACENODEDATA(pData->m_spNode); Assert(pNodeData);
if (pNodeData->m_rgData[PORTS_SI_STATUS].m_dwData == RAS_PORT_AUTHENTICATED) return 0; else return MF_GRAYED; }
/*!--------------------------------------------------------------------------
PortsUserHandler::AddMenuItems Implementation of ITFSResultHandler::OnAddMenuItems Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsUserHandler::AddMenuItems(ITFSComponent *pComponent, MMC_COOKIE cookie, LPDATAOBJECT lpDataObject, LPCONTEXTMENUCALLBACK pContextMenuCallback, long *pInsertionAllowed) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = S_OK; SPITFSNode spNode; PortsUserHandler::SMenuData menuData;
// We don't allow any actions on active dialout connections
// ------------------------------------------------------------
if (m_entry.m_fActiveDialOut) return hrOK; COM_PROTECT_TRY { m_spNodeMgr->FindNode(cookie, &spNode);
// Now go through and add our menu items
menuData.m_spNode.Set(spNode); hr = AddArrayOfMenuItems(spNode, s_rgIfNodeMenu, DimensionOf(s_rgIfNodeMenu), pContextMenuCallback, *pInsertionAllowed, reinterpret_cast<INT_PTR>(&menuData)); } COM_PROTECT_CATCH; return hr; }
/*!--------------------------------------------------------------------------
PortsUserHandler::Command - Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsUserHandler::Command(ITFSComponent *pComponent, MMC_COOKIE cookie, int nCommandId, LPDATAOBJECT pDataObject) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); SPITFSNode spNode; SPITFSNode spNodeParent; SPITFSNodeHandler spParentHandler; PortsNodeData * pData; HRESULT hr = S_OK;
COM_PROTECT_TRY { switch (nCommandId) { case IDS_MENU_PORTS_STATUS: { BOOL fRefresh = FALSE; DWORD dwInterval = 60; SPIRouterRefresh spRefresh; if (m_spRouterInfo) m_spRouterInfo->GetRefreshObject(&spRefresh); // Stop the auto refresh (if it is turned on)
// ------------------------------------------------
if (spRefresh && FHrOK(spRefresh->IsRefreshStarted())) { fRefresh = TRUE; spRefresh->GetRefreshInterval(&dwInterval); spRefresh->Stop(); } // NOTE: This function gets called from other places
// in the code (for which pDataObject==NULL)
// Get the hServer and hPort
m_spNodeMgr->FindNode(cookie, &spNode); spNode->GetParent(&spNodeParent);
pData = GET_PORTSNODEDATA(spNodeParent);
CPortDlg portdlg((LPCTSTR) pData->m_stMachineName, pData->GetHandle(), m_entry.m_rp0.hPort, spNodeParent );
portdlg.DoModal();
// if (portdlg.m_bChanged)
RefreshInterface(cookie);
// Restart the refresh mechanism
// ------------------------------------------------
if (fRefresh && spRefresh) { spRefresh->SetRefreshInterval(dwInterval); spRefresh->Start(dwInterval); } } break; case IDS_MENU_PORTS_DISCONNECT: { // Get the hServer and hPort
m_spNodeMgr->FindNode(cookie, &spNode); spNode->GetParent(&spNodeParent);
pData = GET_PORTSNODEDATA(spNodeParent); ::MprAdminPortDisconnect( pData->GetHandle(), m_entry.m_rp0.hPort);
RefreshInterface(cookie); } break; default: break; }; } COM_PROTECT_CATCH; return hr; }
ImplementEmbeddedUnknown(PortsUserHandler, IRtrAdviseSink)
STDMETHODIMP PortsUserHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn, DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam) { InitPThis(PortsUserHandler, IRtrAdviseSink); HRESULT hr = hrOK; return hr; }
/*!--------------------------------------------------------------------------
PortsUserHandler::OnCreateDataObject Implementation of ITFSResultHandler::OnCreateDataObject Author: KennT ---------------------------------------------------------------------------*/ STDMETHODIMP PortsUserHandler::OnCreateDataObject(ITFSComponent *pComp, MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject) { HRESULT hr = hrOK; COM_PROTECT_TRY { CORg( CreateDataObjectFromRouterInfo(m_spRouterInfo, m_spRouterInfo->GetMachineName(), type, cookie, m_spTFSCompData, ppDataObject, NULL, FALSE) ); COM_PROTECT_ERROR_LABEL; } COM_PROTECT_CATCH; return hr; }
STDMETHODIMP PortsUserHandler::HasPropertyPages ( ITFSComponent *pComp, MMC_COOKIE cookie, LPDATAOBJECT pDataObject) { return hrFalse; }
/*!--------------------------------------------------------------------------
PortsUserHandler::RefreshInterface - Author: KennT ---------------------------------------------------------------------------*/ void PortsUserHandler::RefreshInterface(MMC_COOKIE cookie) { ForceGlobalRefresh(m_spRouterInfo); }
/*!--------------------------------------------------------------------------
PortsUserHandler::OnResultItemClkOrDblClk - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsUserHandler::OnResultItemClkOrDblClk(ITFSComponent *pComponent, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam , BOOL bDoubleClick) { HRESULT hr = hrOK; // We don't allow any actions on active dialout connections
// ------------------------------------------------------------
if (m_entry.m_fActiveDialOut) return hrOK; if (bDoubleClick) { // Bring up the status dialog on this port
CORg( Command(pComponent, cookie, IDS_MENU_PORTS_STATUS, NULL) ); }
Error: return hr; }
/*---------------------------------------------------------------------------
PortsProperties implementation ---------------------------------------------------------------------------*/
PortsProperties::PortsProperties(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_PORTS_GLOBAL_GENERAL), m_pPortsNodeHandle(NULL), m_dwThreadId(0) { }
PortsProperties::~PortsProperties() { if (m_dwThreadId) DestroyTFSErrorInfoForThread(m_dwThreadId, 0); if(m_pPortsNodeHandle) { m_pPortsNodeHandle->Release(); m_pPortsNodeHandle = NULL; } }
/*!--------------------------------------------------------------------------
PortsProperties::Init Initialize the property sheets. The general action here will be to initialize/add the various pages. Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsProperties::Init(IRouterInfo *pRouter, PortsNodeHandler* pPortsNodeHandle) { Assert(pRouter); HRESULT hr = hrOK;
m_spRouter.Set(pRouter); m_pPortsNodeHandle = pPortsNodeHandle; if(m_pPortsNodeHandle) m_pPortsNodeHandle->AddRef();
// The pages are embedded members of the class
// do not delete them.
m_bAutoDeletePages = FALSE;
m_pageGeneral.Init(this, pRouter); AddPageToList((CPropertyPageBase*) &m_pageGeneral);
//Error:
return hr; }
/*!--------------------------------------------------------------------------
PortsProperties::SetThreadInfo - Author: KennT ---------------------------------------------------------------------------*/ void PortsProperties::SetThreadInfo(DWORD dwThreadId) { m_dwThreadId = dwThreadId; }
/*---------------------------------------------------------------------------
PortsPageGeneral ---------------------------------------------------------------------------*/
BEGIN_MESSAGE_MAP(PortsPageGeneral, RtrPropertyPage) //{{AFX_MSG_MAP(PortsPageGeneral)
ON_BN_CLICKED(IDC_PGG_BTN_CONFIGURE, OnConfigure) ON_NOTIFY(NM_DBLCLK, IDC_PGG_LIST, OnListDblClk) ON_NOTIFY(LVN_ITEMCHANGED, IDC_PGG_LIST, OnNotifyListItemChanged) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
PortsPageGeneral::~PortsPageGeneral() { while (!m_deviceList.IsEmpty()) delete m_deviceList.RemoveHead(); }
/*!--------------------------------------------------------------------------
PortsPageGeneral::Init - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsPageGeneral::Init(PortsProperties *pPropSheet, IRouterInfo *pRouter) { m_pPortsPropSheet = pPropSheet; m_spRouter.Set(pRouter); RouterVersionInfo routerVersion;
// Get the version info. Needed later on.
// ----------------------------------------------------------------
ASSERT(m_spRouter.p); m_spRouter->GetRouterVersionInfo(&routerVersion);
m_bShowContent = (routerVersion.dwRouterVersion >= 5);
return hrOK; }
/*!--------------------------------------------------------------------------
PortsPageGeneral::OnInitDialog - Author: KennT ---------------------------------------------------------------------------*/ BOOL PortsPageGeneral::OnInitDialog() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr= hrOK; int i; CString st; UINT cRows = 0; PortsDeviceEntry * pEntry = NULL; TCHAR szNumber[32]; HRESULT hrT; RECT rc; int nWidth, nUsageWidth; int nListWidth; POSITION pos; INT iPos; HKEY hkeyMachine = 0; INT iType, idsType; DWORD dwIn, dwOut;
// if focus on NT4 machine, not to display the content of the dialog, only display some text
// for the user that the snapin only shows property of NT5 server
if (!m_bShowContent) { CString st;
st.LoadString(IDS_ERR_NOPORTINFO_ON_NT4); EnableChildControls(GetSafeHwnd(), PROPPAGE_CHILD_HIDE | PROPPAGE_CHILD_DISABLE); GetDlgItem(IDC_PGG_TXT_NOINFO)->SetWindowText(st); GetDlgItem(IDC_PGG_TXT_NOINFO)->ShowWindow(SW_SHOW); GetDlgItem(IDC_PGG_TXT_NOINFO)->EnableWindow(TRUE); return TRUE; }
// hide the warning text if on NT5 servers
GetDlgItem(IDC_PGG_TXT_NOINFO)->ShowWindow(SW_HIDE); COM_PROTECT_TRY { // This assumes that this page will always come up.
// Create the error info for this thread!
// ------------------------------------------------------------
CreateTFSErrorInfo(0); m_pPortsPropSheet->SetThreadInfo(GetCurrentThreadId()); RtrPropertyPage::OnInitDialog();
ListView_SetExtendedListViewStyle(m_listCtrl.GetSafeHwnd(), LVS_EX_FULLROWSELECT);
// Initialize the list control (with the list of devices)
// Determine optimal width for the header control
GetDlgItem(IDC_PGG_LIST)->GetWindowRect(&rc); nListWidth = rc.right - rc.left;
// Figure out the size of Ras/Routing
st.LoadString(IDS_PORTSDLG_COL_RASROUTING); st += _T("WW"); // add extra padding to get a little wider
nUsageWidth = m_listCtrl.GetStringWidth(st);
// Remove the Ras/Routing column from the rest of the width
nListWidth -= nUsageWidth;
// Remove four pixels off the end (for the borders?)
nListWidth -= 4;
// Split the width into fifths
nWidth = nListWidth / 5;
// Create the column headers.
// Column 0...Usage
st.LoadString(IDS_PORTSDLG_COL_USAGE); m_listCtrl.InsertColumn(PORTS_COL_USAGE, st, LVCFMT_LEFT, nUsageWidth, 0);
// Column 1...Device
st.LoadString(IDS_PORTSDLG_COL_NAME); m_listCtrl.InsertColumn(PORTS_COL_DEVICE, st, LVCFMT_LEFT, 3*nWidth, 0);
// Column 2...Type
st.LoadString(IDS_PORTSDLG_COL_TYPE); m_listCtrl.InsertColumn(PORTS_COL_TYPE, st, LVCFMT_LEFT, nWidth, 0);
// Column 3...Number of Ports
st.LoadString(IDS_PORTSDLG_COL_NUM_PORTS); m_listCtrl.InsertColumn(PORTS_COL_NUMBER, st, LVCFMT_LEFT, nWidth, 0);
// Query for the ports' data.
m_deviceDataEntry.Initialize(m_spRouter->GetMachineName()); m_deviceDataEntry.LoadDevices(&m_deviceList);
// Walk the list of ports and construct the row entry for the table
// for the given port.
pos = m_deviceList.GetHeadPosition(); while (pos) { pEntry = m_deviceList.GetNext(pos); Assert(!::IsBadReadPtr(pEntry, sizeof(PortsDeviceEntry)));
// Column 1...Device
iPos = m_listCtrl.InsertItem(cRows, pEntry->m_stDisplayName); m_listCtrl.SetItemText(iPos, PORTS_COL_DEVICE, (LPCTSTR) pEntry->m_stDisplayName); // Column 2...Type
st = PortTypeToCString(RAS_DEVICE_TYPE(pEntry->m_eDeviceType)); m_listCtrl.SetItemText(iPos, PORTS_COL_TYPE, (LPCTSTR) st);
// Column 3...Number of Ports
FormatNumber(pEntry->m_dwPorts, szNumber, DimensionOf(szNumber), FALSE); m_listCtrl.SetItemText(iPos, PORTS_COL_NUMBER, (LPCTSTR) szNumber);
m_listCtrl.SetItemData(iPos, (LONG_PTR) pEntry);
// Column 0...Usage
iType = (pEntry->m_dwEnableRas * 2) + (pEntry->m_dwEnableRouting | pEntry->m_dwEnableOutboundRouting);
st = PortsDeviceTypeToCString(iType); m_listCtrl.SetItemText(iPos, PORTS_COL_USAGE, (LPCTSTR) st);
// How many rows now?
++cRows; // preincrement faster operation on Pentium chips...
}
// As a default, disable the maximum ports dialog
GetDlgItem(IDC_PGG_BTN_CONFIGURE)->EnableWindow(FALSE); if (cRows) { // Select the first entry in the list control
m_listCtrl.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED); }
} COM_PROTECT_CATCH; SetDirty(FALSE); if (!FHrSucceeded(hr)) { delete pEntry; Cancel(); } return FHrSucceeded(hr) ? TRUE : FALSE; }
/*!--------------------------------------------------------------------------
PortsPageGeneral::DoDataExchange - Author: KennT ---------------------------------------------------------------------------*/ void PortsPageGeneral::DoDataExchange(CDataExchange *pDX) { if (!m_bShowContent) return;
RtrPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(PortsPageGeneral)
DDX_Control(pDX, IDC_PGG_LIST, m_listCtrl); //}}AFX_DATA_MAP
}
/*!--------------------------------------------------------------------------
PortsPageGeneral::OnApply - Author: KennT ---------------------------------------------------------------------------*/ BOOL PortsPageGeneral::OnApply() { if (!m_bShowContent) return TRUE; if (m_pPortsPropSheet->IsCancel()) return TRUE;
if(!IsDirty()) return TRUE; BOOL fReturn; HRESULT hr = hrOK; HRESULT hrT = hrOK; DWORD dwErr, dwInValue, dwOutValue; HKEY hkeyMachine; RegKey regkeyMachine; POSITION pos; PortsDeviceEntry * pEntry;
// Create an error object (just in case)
CreateTFSErrorInfo(0); ClearTFSErrorInfo(0);
CWRg( ConnectRegistry(m_spRouter->GetMachineName(), &hkeyMachine) ); regkeyMachine.Attach(hkeyMachine);
// We ignore the error code from the SaveDevices(). The reason
// is that for most of the failures, it's only a partial failure
// (especially for the RasSetDeviceConfigInfo() call.
hrT = m_deviceDataEntry.SaveDevices(&m_deviceList); AddSystemErrorMessage(hrT); Error: if (!FHrSucceeded(hr) || !FHrSucceeded(hrT)) { AddHighLevelErrorStringId(IDS_ERR_CANNOT_SAVE_PORTINFO); DisplayTFSErrorMessage(NULL);
// Set focus back to the property sheet
BringWindowToTop();
// If the only thing that reports failure is hrT (or the
// SaveDevices() code), then we continue on.
if (FHrSucceeded(hr)) fReturn = RtrPropertyPage::OnApply(); else fReturn = FALSE; } else fReturn = RtrPropertyPage::OnApply();
// Windows NT Bug : 174916 - need to force a refresh through
ForceGlobalRefresh(m_spRouter); return fReturn; }
void PortsPageGeneral::OnListDblClk(NMHDR *pNMHdr, LRESULT *pResult) { OnConfigure();
*pResult = 0; }
/*!--------------------------------------------------------------------------
PortsPageGeneral::OnNotifyListItemChanged - Author: KennT ---------------------------------------------------------------------------*/ void PortsPageGeneral::OnNotifyListItemChanged(NMHDR *pNmHdr, LRESULT *pResult) { // NMLISTVIEW * pnmlv = reinterpret_cast<NMLISTVIEW *>(pNmHdr);
// BOOL fEnable = !!(pnmlv->uNewState & LVIS_SELECTED);
BOOL fEnable = (m_listCtrl.GetSelectedCount() != 0);
GetDlgItem(IDC_PGG_BTN_CONFIGURE)->EnableWindow(fEnable); *pResult = 0; }
/*!--------------------------------------------------------------------------
PortsPageGeneral::OnConfigure - Author: KennT ---------------------------------------------------------------------------*/ void PortsPageGeneral::OnConfigure() { // Windows NT Bug : 322955
// Always mark the page dirty. This is needed because the OnOK()
// will call OnApply() on the property sheet before the dialog is
// exited. This is called to force the changes to save back before
// the restart is called.
// ----------------------------------------------------------------
SetDirty(TRUE); SetModified(); OnConfigurePorts(m_spRouter->GetMachineName(), m_pPortsPropSheet->m_pPortsNodeHandle->GetActivePorts(), this, &m_listCtrl); }
/*---------------------------------------------------------------------------
PortsDataEntry implementation ---------------------------------------------------------------------------*/
PortsDataEntry::PortsDataEntry() { m_fReadFromRegistry = TRUE; }
PortsDataEntry::~PortsDataEntry() { }
/*!--------------------------------------------------------------------------
PortsDataEntry::Initialize - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDataEntry::Initialize(LPCTSTR pszMachineName) { DWORD dwErr; HRESULT hr = hrOK; HKEY hkeyMachine;
m_fRestrictDialin = TRUE; m_regkeyMachine.Close(); m_stMachine = pszMachineName; dwErr = ConnectRegistry( m_stMachine, &hkeyMachine); if( dwErr == NO_ERROR) { m_regkeyMachine.Attach(hkeyMachine); hr = CheckForDialinRestriction(); } else { hr = HRESULT_FROM_WIN32(dwErr); } return hr; }
/*!--------------------------------------------------------------------------
PortsDataEntry::LoadDevices - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDataEntry::LoadDevices(PortsDeviceList *pList) { HRESULT hr = hrOK; POSITION pos; PortsDeviceEntry * pEntry;
// Try to load the devices from the router (actually rasman),
// if that fails then try the registry
hr = LoadDevicesFromRouter(pList); if (!FHrSucceeded(hr)) hr = LoadDevicesFromRegistry(pList);
return hr; }
/*!--------------------------------------------------------------------------
PortsDataEntry::LoadDevicesFromRegistry - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDataEntry::LoadDevicesFromRegistry(PortsDeviceList *pList) { HRESULT hr = hrOK; RegKey regkey; RegKey regkeyDevice; RegKey regkeyEnable; RegKeyIterator regkeyIter; HRESULT hrIter; CString stKey; CString st; CString stFullText; CString stComponentId; DWORD dwEnableRas; DWORD dwEnableRouting; DWORD dwEnableOutboundRouting; DWORD dwT; DWORD dwErr; PortsDeviceEntry * pEntry; WCHAR devName[MAX_DEVICE_NAME + 1]; COM_PROTECT_TRY { // Connect to the machine
// ------------------------------------------------------------
if (m_regkeyMachine == NULL) { CORg(ERROR_CAN_NOT_COMPLETE); } // Get the list of devices
// ------------------------------------------------------------
// Open HKLM\System\CurrentControlSet\Control\Class\<Modem GUID>
// ------------------------------------------------------------
CWRg( regkey.Open(m_regkeyMachine, c_szModemKey, KEY_READ) );
// Enumerate through the list of modems
// ------------------------------------------------------------
CORg( regkeyIter.Init(®key) ); for (hrIter = regkeyIter.Next(&stKey); hrIter == hrOK; stKey.Empty(), hrIter = regkeyIter.Next(&stKey)) { // Cleanup from the previous loop
// --------------------------------------------------------
regkeyDevice.Close(); regkeyEnable.Close(); // Open the key
// --------------------------------------------------------
dwErr = regkeyDevice.Open(regkey, stKey, KEY_READ | KEY_WRITE); if (dwErr != ERROR_SUCCESS) continue; // Need to check for the EnableForRas subkey
// --------------------------------------------------------
dwErr = regkeyEnable.Open(regkeyDevice, c_szClientsRasKey, KEY_READ); if (dwErr == ERROR_SUCCESS) { dwErr = regkeyEnable.QueryValue(c_szEnableForRas, dwEnableRas); } // Default: assume that the modems are RAS-enabled
// --------------------------------------------------------
if (dwErr != ERROR_SUCCESS) dwEnableRas = 1; // Need to check for the EnableForRouting subkey
// --------------------------------------------------------
dwErr = regkeyEnable.QueryValue(c_szEnableForRouting, dwEnableRouting); // Default: assume that the modems are not routing-enabled
// --------------------------------------------------------
if (dwErr != ERROR_SUCCESS) dwEnableRouting = 0;
// Need to check for the EnableForOutboundRouting subkey
// --------------------------------------------------------
dwErr = regkeyEnable.QueryValue( c_szEnableForOutboundRouting, dwEnableOutboundRouting ); // Default: assume that the modems are not routing-enabled
// --------------------------------------------------------
if (dwErr != ERROR_SUCCESS) dwEnableOutboundRouting = 0;
CString stDisplay; // Do allocation before adding the text to the UI
// --------------------------------------------------------
pEntry = new PortsDeviceEntry; pEntry->m_fModified = FALSE; pEntry->m_dwPorts = 1; pEntry->m_fWriteable = FALSE; // # of ports can't be changed
pEntry->m_dwMinPorts = pEntry->m_dwPorts; pEntry->m_dwMaxPorts = pEntry->m_dwPorts; pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts; pEntry->m_dwEnableRas = dwEnableRas; pEntry->m_dwEnableRouting = dwEnableRouting; pEntry->m_dwEnableOutboundRouting = dwEnableOutboundRouting; pEntry->m_eDeviceType = RDT_Modem; // Save the old values
// --------------------------------------------------------
pEntry->m_dwOldPorts = pEntry->m_dwPorts;
// Add this modem to the list
// --------------------------------------------------------
regkeyDevice.QueryValue(c_szFriendlyName, stFullText); regkeyDevice.QueryValue(c_szAttachedTo, st); stDisplay.Format(IDS_PORTS_NAME_FORMAT, stFullText, st); swprintf(devName, L"%S",(LPCTSTR)stDisplay); pEntry->m_stDisplayName = devName;
// Read in all data from the registry key BEFORE here
// --------------------------------------------------------
pEntry->m_fRegistry = TRUE; pEntry->m_hKey = regkeyDevice; regkeyDevice.Detach();
pList->AddTail(pEntry); pEntry = NULL; } // Enumerate through the list of adapters that have the EnableForRas flag
// Open HKLM\System\CurrentControlSet\Control\Class\GUID_DEVCLASS_NET
// ------------------------------------------------------------
regkey.Close(); CWRg( regkey.Open(m_regkeyMachine, c_szRegKeyGUID_DEVCLASS_NET, KEY_READ | KEY_WRITE) ); // Enumerate through the list of adapters
// ------------------------------------------------------------
CORg( regkeyIter.Init(®key) ); stKey.Empty(); for (hrIter = regkeyIter.Next(&stKey); hrIter == hrOK; hrIter = regkeyIter.Next(&stKey)) { // Cleanup from the previous loop
// --------------------------------------------------------
regkeyDevice.Close(); // Open the key
// --------------------------------------------------------
dwErr = regkeyDevice.Open(regkey, stKey, KEY_READ | KEY_WRITE); if (dwErr == ERROR_SUCCESS) { CString stDisplay; DWORD dwEndpoints; // Need to get the ComponentId to check for PPTP/PTI
// ------------------------------------------------
dwErr = regkeyDevice.QueryValue(c_szRegValMatchingDeviceId, stComponentId); if (dwErr != ERROR_SUCCESS) { dwErr = regkeyDevice.QueryValue(c_szRegValComponentId, stComponentId); if (dwErr != ERROR_SUCCESS) stComponentId.Empty(); }
// Check to see if it has the EnableForRas flag
// ----------------------------------------------------
dwErr = regkeyDevice.QueryValue(c_szEnableForRas, dwEnableRas); // Default: assume that adapters are RAS-enabled
// ----------------------------------------------------
if (dwErr != ERROR_SUCCESS) { // Windows NT Bug : 292615
// If this is a parallel port, do not enable RAS
// by default.
// ------------------------------------------------
if (stComponentId.CompareNoCase(c_szPtiMiniPort) == 0) dwEnableRas = 0; else dwEnableRas = 1; }
// Check to see if it has the EnableForRouting flag
// ----------------------------------------------------
dwErr = regkeyDevice.QueryValue(c_szEnableForRouting, dwEnableRouting); // Default: assume that adapters are not routing-enabled
// ----------------------------------------------------
if (dwErr != ERROR_SUCCESS) dwEnableRouting = 0;
// Need to check for the EnableForOutboundRouting subkey
// --------------------------------------------------------
dwErr = regkeyEnable.QueryValue( c_szEnableForOutboundRouting, dwEnableOutboundRouting ); // Default: assume that the adapters are not routing-enabled
// --------------------------------------------------------
if (dwErr != ERROR_SUCCESS) dwEnableOutboundRouting = 0;
dwErr = regkeyDevice.QueryValue(c_szWanEndpoints, dwEndpoints);
// If there is no WanEndpoints key, then we assume
// that the device isn't RAS-capable
// ----------------------------------------------------
if (dwErr == ERROR_SUCCESS) { // Do allocation before adding the text to the UI
// ------------------------------------------------
pEntry = new PortsDeviceEntry; pEntry->m_fModified = FALSE; pEntry->m_dwEnableRas = dwEnableRas; pEntry->m_dwEnableRouting = dwEnableRouting; pEntry->m_dwEnableOutboundRouting = dwEnableOutboundRouting; pEntry->m_dwPorts = dwEndpoints; // If this is PPTP, then set the eDeviceType flag
// ------------------------------------------------
if (stComponentId.CompareNoCase(c_szPPTPMiniPort) == 0) pEntry->m_eDeviceType = RDT_Tunnel_Pptp; else if (stComponentId.CompareNoCase(c_szL2TPMiniPort) == 0) pEntry->m_eDeviceType = RDT_Tunnel_L2tp; else if (stComponentId.CompareNoCase(c_szPPPoEMiniPort) == 0) pEntry->m_eDeviceType = RDT_PPPoE; else if (stComponentId.CompareNoCase(c_szPtiMiniPort) == 0) pEntry->m_eDeviceType = RDT_Parallel; else pEntry->m_eDeviceType = (RASDEVICETYPE) RDT_Other;
// Save the old values
// ------------------------------------------------
pEntry->m_dwOldPorts = pEntry->m_dwPorts; // Look for min and max values
// If the MinWanEndpoints and MaxWanEndpoints keys
// exist then this is writeable.
// ------------------------------------------------
dwErr = regkeyDevice.QueryValue(c_szMinWanEndpoints, dwT); pEntry->m_dwMinPorts = dwT; if (dwErr == ERROR_SUCCESS) dwErr = regkeyDevice.QueryValue(c_szMaxWanEndpoints, dwT); if (dwErr != ERROR_SUCCESS) { pEntry->m_fWriteable = FALSE; pEntry->m_dwMinPorts = pEntry->m_dwPorts; pEntry->m_dwMaxPorts = pEntry->m_dwPorts; } else { pEntry->m_fWriteable = TRUE; pEntry->m_dwMaxPorts = dwT; } pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
//$PPTP
// For PPTP, we can change the m_dwMaxMaxPorts
// ------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) { pEntry->m_dwMaxMaxPorts = m_fRestrictDialin ? MAX_ALLOWED_DIALIN : PPTP_MAX_PORTS; }
//$L2TP
// For L2TP, change the dwMaxMaxPorts
// ------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp) { pEntry->m_dwMaxMaxPorts = m_fRestrictDialin ? MAX_ALLOWED_DIALIN : L2TP_MAX_PORTS; }
//$PPPoE
// For PPPoE, we cannot change the number of endpoints
// ------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_PPPoE) { pEntry->m_fWriteable = FALSE; }
// Verify current set of endpoints is within range
//-------------------------------------------------
if (pEntry->m_dwMaxPorts > pEntry->m_dwMaxMaxPorts) { pEntry->m_dwMaxPorts = pEntry->m_dwMaxMaxPorts; }
if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts) { pEntry->m_dwPorts = pEntry->m_dwMaxPorts; } // Add this device to the list
// ------------------------------------------------
regkeyDevice.QueryValue(c_szRegValDriverDesc, stDisplay); pEntry->m_stDisplayName = stDisplay; // Store the value so that we can use it to write
// ------------------------------------------------
pEntry->m_fRegistry = TRUE; pEntry->m_hKey = regkeyDevice; regkeyDevice.Detach(); pList->AddTail(pEntry); pEntry = NULL; } } stKey.Empty(); }
COM_PROTECT_ERROR_LABEL; } COM_PROTECT_CATCH;
if (FHrSucceeded(hr)) m_fReadFromRegistry = TRUE; return hr; }
/*!--------------------------------------------------------------------------
PortsDataEntry::LoadDevicesFromRouter - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDataEntry::LoadDevicesFromRouter(PortsDeviceList *pList) { HRESULT hr = hrOK; HANDLE hConnection = 0; DWORD cDevices = 0; DWORD cbData = 0; BYTE * pbData = NULL; RAS_DEVICE_INFO * pDevInfo = NULL; PortsDeviceEntry * pEntry = NULL; DWORD dwVersion; UINT i; DWORD dwErr; WCHAR devName[MAX_DEVICE_NAME + 1];
USES_CONVERSION;
COM_PROTECT_TRY {
// Connect to the server
CWRg( RasRpcConnectServer((LPTSTR) (LPCTSTR)m_stMachine, &hConnection) );
dwVersion = RasGetServerVersion(hConnection);
// Get the device information from the router
dwErr = RasGetDeviceConfigInfo(hConnection, &dwVersion, &cDevices, &cbData, NULL);
if (dwErr == ERROR_BUFFER_TOO_SMALL) dwErr = ERROR_SUCCESS; CWRg(dwErr); pbData = (BYTE *) new char[cbData]; // Go out and actually grab the data
CWRg( RasGetDeviceConfigInfo(hConnection, &dwVersion, &cDevices, &cbData, pbData));
pDevInfo = (RAS_DEVICE_INFO *) pbData;
// If we found something and we don't understand the dev version,
// just punt.
if (cDevices && pDevInfo->dwVersion != 0 && pDevInfo->dwVersion != VERSION_501) { // We don't understand the version information
hr = E_FAIL; goto Error; }
if(dwVersion == VERSION_501) { for (i=0; i<cDevices; i++, pDevInfo++) { pEntry = new PortsDeviceEntry; pEntry->m_fModified = FALSE; pEntry->m_dwEnableRas = pDevInfo->fRasEnabled; pEntry->m_dwEnableRouting = pDevInfo->fRouterEnabled; pEntry->m_dwEnableOutboundRouting = pDevInfo->fRouterOutboundEnabled; pEntry->m_stDisplayName = pDevInfo->wszDeviceName; pEntry->m_dwPorts = pDevInfo->dwNumEndPoints; pEntry->m_eDeviceType = pDevInfo->eDeviceType; // Save the old values
pEntry->m_dwOldPorts = pEntry->m_dwPorts;
pEntry->m_dwMinPorts = pDevInfo->dwMinWanEndPoints; pEntry->m_dwMaxPorts = pDevInfo->dwMaxWanEndPoints; pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
//$PPTP
// For PPTP, we can adjust the value of m_dwMaxPorts
// --------------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) { pEntry->m_dwMaxMaxPorts = m_fRestrictDialin ? MAX_ALLOWED_DIALIN : PPTP_MAX_PORTS; }
//$L2TP
// For L2TP, we can adjust the value of m_dwMaxPorts
// --------------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp) { pEntry->m_dwMaxMaxPorts = m_fRestrictDialin ? MAX_ALLOWED_DIALIN : L2TP_MAX_PORTS; }
// Verify current set of endpoints is within range
//-------------------------------------------------
if (pEntry->m_dwMaxPorts > pEntry->m_dwMaxMaxPorts) { pEntry->m_dwMaxPorts = pEntry->m_dwMaxMaxPorts; }
if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts) { pEntry->m_dwPorts = pEntry->m_dwMaxPorts; }
pEntry->m_fWriteable = (pEntry->m_dwMinPorts != pEntry->m_dwMaxPorts) && (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) != RDT_PPPoE); pEntry->m_fRegistry = FALSE; pEntry->m_hKey = NULL;
// Make a copy of the data
pEntry->m_RasDeviceInfo = *pDevInfo;
pList->AddTail(pEntry); pEntry = NULL; } } else { RAS_DEVICE_INFO_V500 * pDevInfo500 = (RAS_DEVICE_INFO_V500 *)pbData;
for (i=0; i<cDevices; i++, pDevInfo500++) { pEntry = new PortsDeviceEntry; pEntry->m_fModified = FALSE; pEntry->m_dwEnableRas = pDevInfo500->fRasEnabled; pEntry->m_dwEnableRouting = pDevInfo500->fRouterEnabled; swprintf(devName, L"%S", pDevInfo500->szDeviceName); pEntry->m_stDisplayName = devName; pEntry->m_dwPorts = pDevInfo500->dwNumEndPoints; pEntry->m_eDeviceType = pDevInfo500->eDeviceType; // Save the old values
pEntry->m_dwOldPorts = pEntry->m_dwPorts; pEntry->m_dwMinPorts = pDevInfo500->dwMinWanEndPoints; pEntry->m_dwMaxPorts = pDevInfo500->dwMaxWanEndPoints; pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
//$PPTP
// For PPTP, we can adjust the value of m_dwMaxPorts
// --------------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) { pEntry->m_dwMaxMaxPorts = PPTP_MAX_PORTS; } //$L2TP
// For L2TP, we can adjust the value of m_dwMaxPorts
// --------------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp) { pEntry->m_dwMaxMaxPorts = L2TP_MAX_PORTS; } pEntry->m_fWriteable = (pEntry->m_dwMinPorts != pEntry->m_dwMaxPorts) && (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) != RDT_PPPoE); pEntry->m_fRegistry = FALSE; pEntry->m_hKey = NULL;
// Make a copy of the data
// pEntry->m_RasDeviceInfo = *pDevInfo;
memcpy(&pEntry->m_RasDeviceInfo, pDevInfo500, FIELD_OFFSET(RAS_DEVICE_INFO, fRouterOutboundEnabled)); memcpy(&pEntry->m_RasDeviceInfo.dwTapiLineId, &pDevInfo500->dwTapiLineId, sizeof(RAS_DEVICE_INFO) - FIELD_OFFSET(RAS_DEVICE_INFO, dwTapiLineId)); pList->AddTail(pEntry); pEntry = NULL; } } COM_PROTECT_ERROR_LABEL; } COM_PROTECT_CATCH;
if (FHrSucceeded(hr)) m_fReadFromRegistry = FALSE; // If the function didn't succeed, clean out the list
if (!FHrSucceeded(hr)) { while (!pList->IsEmpty()) delete pList->RemoveHead(); }
delete [] pbData; delete pEntry; if (hConnection) RasRpcDisconnectServer(hConnection); return hr; }
/*!--------------------------------------------------------------------------
PortsDataEntry::SaveDevices - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDataEntry::SaveDevices(PortsDeviceList *pList) { HRESULT hr = hrOK; CWaitCursor wait;
if (m_fReadFromRegistry) hr = SaveDevicesToRegistry(pList); else hr = SaveDevicesToRouter(pList); return hr; }
/*!--------------------------------------------------------------------------
PortsDataEntry::SaveDevicesToRegistry - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDataEntry::SaveDevicesToRegistry(PortsDeviceList *pList) { HRESULT hr = hrOK; RegKey regkeyDevice; RegKey regkeyPptpProtocol; POSITION pos; PortsDeviceEntry * pEntry = NULL; DWORD dwErr;
Assert(pList);
// Write any changes made to the per-device configuration
// and write that back out to the registry
// ----------------------------------------------------------------
pos = pList->GetHeadPosition(); while (pos) { pEntry = pList->GetNext(pos);
if (pEntry->m_fModified) { Assert(pEntry->m_hKey);
regkeyDevice.Attach(pEntry->m_hKey); COM_PROTECT_TRY { RegKey regkeyModem; RegKey * pRegkeyDevice = NULL; if (pEntry->m_fWriteable) { if (m_fRestrictDialin && (pEntry->m_dwPorts > MAX_ALLOWED_DIALIN)) { pEntry->m_dwPorts = MAX_ALLOWED_DIALIN; } regkeyDevice.SetValue(c_szWanEndpoints, pEntry->m_dwPorts);
//$PPTP
// We need to adjust the upper limit for the
// number of PPTP ports.
// ------------------------------------------------
if ((RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) && (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)) { DWORD dwPorts;
//$PPTP
// Keep the value of the number of PPTP ports
// below the max.
// --------------------------------------------
if (m_fRestrictDialin) dwPorts = MAX_ALLOWED_DIALIN; else dwPorts = min(pEntry->m_dwPorts, PPTP_MAX_PORTS); regkeyDevice.SetValue(c_szMaxWanEndpoints, dwPorts); } //$L2TP
// We need to adjust the upper limit for the
// number of L2TP ports.
// ------------------------------------------------
if ((RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp) && (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)) { DWORD dwPorts;
//$L2TP
// Keep the value of the number of L2TP ports
// below the max.
// --------------------------------------------
if (m_fRestrictDialin) dwPorts = MAX_ALLOWED_DIALIN; else dwPorts = min(pEntry->m_dwPorts, L2TP_MAX_PORTS); regkeyDevice.SetValue(c_szMaxWanEndpoints, dwPorts); } }
// Get the clients subkey (if for a modem)
// else use the device key
// ----------------------------------------------------
if (pEntry->m_eDeviceType == RDT_Modem) { dwErr = regkeyModem.Create(regkeyDevice, c_szClientsRasKey); pRegkeyDevice = ®keyModem; } else { pRegkeyDevice = ®keyDevice; dwErr = ERROR_SUCCESS; }
if (dwErr == ERROR_SUCCESS) { pRegkeyDevice->SetValue(c_szEnableForRas, pEntry->m_dwEnableRas); pRegkeyDevice->SetValue(c_szEnableForRouting, pEntry->m_dwEnableRouting); pRegkeyDevice->SetValue(c_szEnableForOutboundRouting, pEntry->m_dwEnableOutboundRouting); } } COM_PROTECT_CATCH; regkeyDevice.Detach();
// The NumberLineDevices is no longer used in NT5.
// if this is for PPTP, then we need to special case the
// code to set the PPTP number of devices
// --------------------------------------------------------
if (pEntry->m_fWriteable && pEntry->m_fModified && RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) { // Open the PPTP registry key
// ----------------------------------------------------
dwErr = regkeyPptpProtocol.Open(m_regkeyMachine, c_szRegKeyPptpProtocolParam); // set the NumberLineDevices registry value
// ----------------------------------------------------
if (dwErr == ERROR_SUCCESS) regkeyPptpProtocol.SetValue(c_szRegValNumberLineDevices, pEntry->m_dwPorts); regkeyPptpProtocol.Close(); } }
// Windows NT Bug: 136858 (add called id support)
// Save called id info
// ------------------------------------------------------------
if (pEntry->m_fSaveCalledIdInfo) { Assert(pEntry->m_fCalledIdInfoLoaded);
regkeyDevice.Attach(pEntry->m_hKey);
regkeyDevice.SetValueExplicit(c_szRegValCalledIdInformation, REG_MULTI_SZ, pEntry->m_pCalledIdInfo->dwSize, (PBYTE) pEntry->m_pCalledIdInfo->bCalledId ); regkeyDevice.Detach();
} }
return hr; }
/*!--------------------------------------------------------------------------
PortsDataEntry::SaveDevicesToRouter - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDataEntry::SaveDevicesToRouter(PortsDeviceList *pList) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = hrOK, hrTemp; HANDLE hConnection = 0; DWORD cDevices = 0; BYTE * pbData = NULL; RAS_DEVICE_INFO * pDevInfo = NULL; PortsDeviceEntry * pEntry = NULL; POSITION pos; UINT i; RAS_CALLEDID_INFO calledIdInfo; DWORD dwErr = ERROR_SUCCESS; TCHAR szErr[512]; DWORD dwVersion;
Assert(pList);
COM_PROTECT_TRY {
// Connect to the server
// ------------------------------------------------------------
CWRg( RasRpcConnectServer((LPTSTR)(LPCTSTR)m_stMachine, &hConnection) );
dwVersion = RasGetServerVersion(hConnection);
// Allocate space for the data
// ------------------------------------------------------------
pbData = (BYTE *) new RAS_DEVICE_INFO[pList->GetCount()];
pDevInfo = (RAS_DEVICE_INFO *) pbData;
pos = pList->GetHeadPosition(); cDevices = pList->GetCount();
if(dwVersion == VERSION_501) { for (i=0; i<cDevices; i++, pDevInfo++) { Assert(pos);
pEntry = pList->GetNext(pos);
// Get the information needed to calculate the number
// of ports
// --------------------------------------------------------
*pDevInfo = pEntry->m_RasDeviceInfo;
pDevInfo->fWrite = TRUE; pDevInfo->fRasEnabled = pEntry->m_dwEnableRas; pDevInfo->fRouterEnabled = pEntry->m_dwEnableRouting; pDevInfo->fRouterOutboundEnabled = pEntry->m_dwEnableOutboundRouting; if ((m_fRestrictDialin) && (pEntry->m_dwPorts > MAX_ALLOWED_DIALIN)) { pEntry->m_dwPorts = MAX_ALLOWED_DIALIN; } pDevInfo->dwNumEndPoints = pEntry->m_dwPorts; pDevInfo->dwMaxWanEndPoints = pEntry->m_dwMaxPorts;
// Windows NT Bug : 168364
// From RaoS, I also need to set the maximum incoming/outging
// --------------------------------------------------------
// Windows NT Bug : ?
// Use the defaults for now,
// This will get removed later.
// --------------------------------------------------------
pDevInfo->dwMaxInCalls = (-1); pDevInfo->dwMaxOutCalls = 3;
// if this is for PPTP, then we need to special case the
// code to set the PPTP number of devices
// --------------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) { //$PPTP
// We need to adjust the upper limit for the
// number of PPTP ports.
// ------------------------------------------------
if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts) { DWORD dwPorts;
//$PPTP
// Keep the value of the number of PPTP ports
// below the max.
// --------------------------------------------
if (m_fRestrictDialin) dwPorts = MAX_ALLOWED_DIALIN; else dwPorts = min(pEntry->m_dwPorts, PPTP_MAX_PORTS); pDevInfo->dwMaxWanEndPoints = dwPorts; } RegKey regkeyMachine; RegKey regkeyPptpProtocol; HKEY hkeyMachine; // Connect to the machine
dwErr = ConnectRegistry(m_stMachine, &hkeyMachine); regkeyMachine.Attach(hkeyMachine);
// Open the PPTP registry key
dwErr = regkeyPptpProtocol.Open(regkeyMachine, c_szRegKeyPptpProtocolParam); // set the NumberLineDevices registry value
if (dwErr == ERROR_SUCCESS) regkeyPptpProtocol.SetValue(c_szRegValNumberLineDevices, pEntry->m_dwPorts); regkeyPptpProtocol.Close(); regkeyMachine.Close(); }
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp) { //$L2TP
// We need to adjust the upper limit for the
// number of L2TP ports.
// ------------------------------------------------
if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts) { DWORD dwPorts;
//$L2TP
// Keep the value of the number of L2TP ports
// below the max.
// --------------------------------------------
if (m_fRestrictDialin) dwPorts = MAX_ALLOWED_DIALIN; else dwPorts = min(pEntry->m_dwPorts, L2TP_MAX_PORTS); pDevInfo->dwMaxWanEndPoints = dwPorts; } }
// Windows NT Bug : 136858 (add called id support)
// Do we need to save the called id info?
// --------------------------------------------------------
if (pEntry->m_fSaveCalledIdInfo && pEntry->m_pCalledIdInfo) { Assert(pEntry->m_fCalledIdInfoLoaded); //: if the call fails, what should we do? -- save it later
hrTemp = RasSetCalledIdInfo(hConnection, pDevInfo, pEntry->m_pCalledIdInfo, TRUE);
// We've saved it, we don't need to save it again
// unless it changes.
// ----------------------------------------------------
if (FHrSucceeded(hrTemp)) pEntry->m_fSaveCalledIdInfo = FALSE; } }
dwErr = RasSetDeviceConfigInfo(hConnection, cDevices, sizeof(RAS_DEVICE_INFO)*cDevices, pbData); } else { RAS_DEVICE_INFO_V500 *pDevInfo500 = (RAS_DEVICE_INFO_V500 *) pbData; for (i=0; i<cDevices; i++, pDevInfo500++) { Assert(pos);
pEntry = pList->GetNext(pos);
// Get the information needed to calculate the number
// of ports
// --------------------------------------------------------
// *pDevInfo = pEntry->m_RasDeviceInfo;
memcpy(pDevInfo500, &pEntry->m_RasDeviceInfo, FIELD_OFFSET(RAS_DEVICE_INFO, fRouterOutboundEnabled)); memcpy(&pDevInfo500->dwTapiLineId, &pEntry->m_RasDeviceInfo.dwTapiLineId, sizeof(RAS_DEVICE_INFO) - FIELD_OFFSET(RAS_DEVICE_INFO, dwTapiLineId));
pDevInfo500->fWrite = TRUE; pDevInfo500->fRasEnabled = pEntry->m_dwEnableRas; pDevInfo500->fRouterEnabled = pEntry->m_dwEnableRouting; pDevInfo500->dwNumEndPoints = pEntry->m_dwPorts; pDevInfo500->dwMaxWanEndPoints = pEntry->m_dwMaxPorts;
// Windows NT Bug : 168364
// From RaoS, I also need to set the maximum incoming/outging
// --------------------------------------------------------
// Windows NT Bug : ?
// Use the defaults for now,
// This will get removed later.
// --------------------------------------------------------
pDevInfo500->dwMaxInCalls = (-1); pDevInfo500->dwMaxOutCalls = 3;
// if this is for PPTP, then we need to special case the
// code to set the PPTP number of devices
// --------------------------------------------------------
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) { //$PPTP
// We need to adjust the upper limit for the
// number of PPTP ports.
// ------------------------------------------------
if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts) { DWORD dwPorts;
//$PPTP
// Keep the value of the number of PPTP ports
// below the max.
// --------------------------------------------
dwPorts = min(pEntry->m_dwPorts, PPTP_MAX_PORTS); pDevInfo500->dwMaxWanEndPoints = dwPorts; } RegKey regkeyMachine; RegKey regkeyPptpProtocol; HKEY hkeyMachine; // Connect to the machine
dwErr = ConnectRegistry(m_stMachine, &hkeyMachine); regkeyMachine.Attach(hkeyMachine);
// Open the PPTP registry key
dwErr = regkeyPptpProtocol.Open(regkeyMachine, c_szRegKeyPptpProtocolParam); // set the NumberLineDevices registry value
if (dwErr == ERROR_SUCCESS) regkeyPptpProtocol.SetValue(c_szRegValNumberLineDevices, pEntry->m_dwPorts); regkeyPptpProtocol.Close(); regkeyMachine.Close(); }
if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp) { //$L2TP
// We need to adjust the upper limit for the
// number of L2TP ports.
// ------------------------------------------------
if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts) { DWORD dwPorts;
//$L2TP
// Keep the value of the number of L2TP ports
// below the max.
// --------------------------------------------
dwPorts = min(pEntry->m_dwPorts, L2TP_MAX_PORTS); pDevInfo500->dwMaxWanEndPoints = dwPorts; } }
// Windows NT Bug : 136858 (add called id support)
// Do we need to save the called id info?
// --------------------------------------------------------
if (pEntry->m_fSaveCalledIdInfo && pEntry->m_pCalledIdInfo) { Assert(pEntry->m_fCalledIdInfoLoaded); //: if the call fails, what should we do? -- save it later
hrTemp = RasSetCalledIdInfo(hConnection, (RAS_DEVICE_INFO *) pDevInfo500, pEntry->m_pCalledIdInfo, TRUE);
// We've saved it, we don't need to save it again
// unless it changes.
// ----------------------------------------------------
if (FHrSucceeded(hrTemp)) pEntry->m_fSaveCalledIdInfo = FALSE; } }
dwErr = RasSetDeviceConfigInfo(hConnection, cDevices, sizeof(RAS_DEVICE_INFO_V500)*cDevices, pbData); } if (dwErr != ERROR_SUCCESS) { CString stErr; CString stErrCode; BOOL fErr = FALSE; if(dwVersion == VERSION_501) { RAS_DEVICE_INFO * pDevice; // Need to grab the error information out of the
// info struct an set the error strings.
// Could not save the information for the following
// devices
pDevice = (RAS_DEVICE_INFO *) pbData;
stErr.LoadString(IDS_ERR_SETDEVICECONFIGINFO_GEEK); for (i=0; i<cDevices; i++, pDevice++) { if (pDevice->dwError) { CString stErrString;
FormatError(HRESULT_FROM_WIN32(pDevice->dwError), szErr, DimensionOf(szErr)); stErrCode.Format(_T("%s (%08lx)"), szErr, pDevice->dwError); stErr += _T(" "); stErr += pDevice->szDeviceName; stErr += _T(" "); stErr += stErrCode; stErr += _T("\n");
fErr = TRUE; } } } else { RAS_DEVICE_INFO_V500 * pDevice; // Need to grab the error information out of the
// info struct an set the error strings.
// Could not save the information for the following
// devices
pDevice = (RAS_DEVICE_INFO_V500 *) pbData;
stErr.LoadString(IDS_ERR_SETDEVICECONFIGINFO_GEEK); for (i=0; i<cDevices; i++, pDevice++) { if (pDevice->dwError) { CString stErrString;
FormatError(HRESULT_FROM_WIN32(pDevice->dwError), szErr, DimensionOf(szErr)); stErrCode.Format(_T("%s (%08lx)"), szErr, pDevice->dwError); stErr += _T(" "); stErr += pDevice->szDeviceName; stErr += _T(" "); stErr += stErrCode; stErr += _T("\n");
fErr = TRUE; } } }
if (fErr) AddGeekLevelErrorString(stErr); CWRg(dwErr); }
COM_PROTECT_ERROR_LABEL; } COM_PROTECT_CATCH;
delete [] pbData; if (hConnection) RasRpcDisconnectServer(hConnection); return hr; }
/*!--------------------------------------------------------------------------
IsMaxDialinPortsRestricted - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDataEntry::CheckForDialinRestriction() { DWORD dwMajor, dwMinor, dwErr; HRESULT hr = hrOK; RegKey regkeyProduct; CString stProductType, stSuite; CStringList stlProductSuite; COM_PROTECT_TRY { dwErr = GetNTVersion(m_regkeyMachine, &dwMajor, &dwMinor, NULL);
if ( (dwErr == NO_ERROR) && ( (dwMajor > 5) || ((dwMajor == 5) && (dwMinor > 1)) ) ) { CWRg( regkeyProduct.Open( m_regkeyMachine, c_szRegKeyProductOptions, KEY_READ ));
CWRg( regkeyProduct.QueryValue(c_szRegValProductType, stProductType) );
if (stProductType.Compare(c_szServerNT) == 0) { //
// ok, this is a server box
//
CWRg( regkeyProduct.QueryValue( c_szRegValProductSuite, stlProductSuite ) );
POSITION pos = stlProductSuite.GetHeadPosition();
while( pos != NULL ) { stSuite = stlProductSuite.GetNext(pos);
if(( stSuite.Compare(c_szEnterprise) == 0) || ( stSuite.Compare(c_szDataCenter) == 0) || ( stSuite.Compare(c_szSecurityAppliance) == 0 )) { //
// This is either a DataCenter or Enterprise version
//
m_fRestrictDialin = FALSE; } } } }
else { m_fRestrictDialin = FALSE; } COM_PROTECT_ERROR_LABEL; } COM_PROTECT_CATCH;
return hr; }
/*---------------------------------------------------------------------------
PortsDeviceConfigDlg implementation ---------------------------------------------------------------------------*/
BEGIN_MESSAGE_MAP(PortsDeviceConfigDlg, CBaseDialog) //{{AFX_MSG_MAP(PortsPageGeneral)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void PortsDeviceConfigDlg::DoDataExchange(CDataExchange *pDX) { CBaseDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_DEVCFG_SPIN_PORTS, m_spinPorts); }
void PortsDeviceConfigDlg::SetDevice(PortsDeviceEntry *pEntry, DWORD dwTotalActivePorts) { Assert(pEntry); m_pEntry = pEntry; m_dwTotalActivePorts = dwTotalActivePorts; }
BOOL PortsDeviceConfigDlg::OnInitDialog() { HRESULT hr; CString stCalledIdInfo; CString stDisplay; Assert(m_pEntry); CBaseDialog::OnInitDialog();
if (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE) { CheckDlgButton(IDC_DEVCFG_BTN_RAS, FALSE); GetDlgItem(IDC_DEVCFG_BTN_RAS)->EnableWindow(FALSE); CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, FALSE); GetDlgItem(IDC_DEVCFG_BTN_ROUTING)->EnableWindow(FALSE); CheckDlgButton( IDC_DEVCFG_BTN_OUTBOUND_ROUTING, m_pEntry->m_dwEnableOutboundRouting ); } else { CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_pEntry->m_dwEnableRas); CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_pEntry->m_dwEnableRouting); CheckDlgButton(IDC_DEVCFG_BTN_OUTBOUND_ROUTING, FALSE); GetDlgItem(IDC_DEVCFG_BTN_OUTBOUND_ROUTING)->EnableWindow(FALSE); }
m_spinPorts.SetBuddy(GetDlgItem(IDC_DEVCFG_EDIT_PORTS)); m_spinPorts.SetRange(m_pEntry->m_dwMinPorts, m_pEntry->m_dwMaxMaxPorts); m_spinPorts.SetPos(m_pEntry->m_dwPorts);
// If we can edit/change the number of ports, set it up here
// ----------------------------------------------------------------
if (!m_pEntry->m_fWriteable || (m_pEntry->m_dwMinPorts == m_pEntry->m_dwMaxPorts)) { GetDlgItem(IDC_DEVCFG_SPIN_PORTS)->EnableWindow(FALSE); GetDlgItem(IDC_DEVCFG_EDIT_PORTS)->EnableWindow(FALSE); GetDlgItem(IDC_DEVCFG_TEXT_PORTS)->EnableWindow(FALSE); GetDlgItem(IDC_DEVCFG_TEXT)->EnableWindow(FALSE); }
// Windows NT Bug : 136858 - Get the called id info
// ----------------------------------------------------------------
LoadCalledIdInfo();
// Get the called id info, format it into a string and add it to
// the display
// ----------------------------------------------------------------
CalledIdInfoToString(&stCalledIdInfo);
GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->SetWindowText(stCalledIdInfo); ((CEdit *)GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID))->SetModify(FALSE); if ((RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Parallel) || (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE)){ GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->EnableWindow(FALSE); GetDlgItem(IDC_DEVCFG_TEXT_CALLEDID)->EnableWindow(FALSE); }
// Set the window title to include the display name of the adapter
// ----------------------------------------------------------------
stDisplay.Format(IDS_TITLE_CONFIGURE_PORTS, (LPCTSTR) m_pEntry->m_stDisplayName); SetWindowText(stDisplay);
return TRUE; }
/*!--------------------------------------------------------------------------
PortsDeviceConfigDlg::OnOK - Author: KennT ---------------------------------------------------------------------------*/ void PortsDeviceConfigDlg::OnOK() { BOOL fChanged = FALSE; BOOL fReboot = FALSE; DWORD dwNewEnableRas, dwNewEnableRouting, dwNewEnableOutboundRouting, dwNewPorts; // Check to see if the values changed
dwNewEnableRas = (IsDlgButtonChecked(IDC_DEVCFG_BTN_RAS) != 0); dwNewEnableRouting = (IsDlgButtonChecked(IDC_DEVCFG_BTN_ROUTING) != 0); dwNewEnableOutboundRouting = (IsDlgButtonChecked(IDC_DEVCFG_BTN_OUTBOUND_ROUTING) != 0); dwNewPorts = m_spinPorts.GetPos();
// Make sure that we have a valid size
// ----------------------------------------------------------------
if ((dwNewPorts < m_pEntry->m_dwMinPorts) || (dwNewPorts > m_pEntry->m_dwMaxMaxPorts)) { CString st; st.Format(IDS_ERR_PORTS_BOGUS_SIZE, m_pEntry->m_dwMinPorts, m_pEntry->m_dwMaxMaxPorts); AfxMessageBox(st); return; }
// Windows NT Bug : 174803
// We do not allow the user to change the number of PPTP ports down
// to 0.
// ----------------------------------------------------------------
if ((RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) && (dwNewPorts == 0)) { AfxMessageBox(IDS_ERR_PPTP_PORTS_EQUAL_ZERO); return; }
// Windows NT Bugs : 165862
// If we are changing the number of ports for PPTP
// then we need to warn the user (since PPTP is not yet
// fully PnP (4/23/98).
//
//$PPTP
// For PPTP, if the value of m_dwPorts exceeds the value of
// m_dwMaxPorts, then we have to reboot (we also need to adjust
// the appropriate registry entries).
// ----------------------------------------------------------------
if ((dwNewPorts > m_pEntry->m_dwMaxPorts) && (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)) { // If we have a page, then we can do a reboot, otherwise we
// are in the wizard and can't do a reboot at this point.
// ------------------------------------------------------------
if (m_pageGeneral) { // The user chose Yes indicating that he wants to be prompted to
// reboot, so set this flag to trigger a reboot request.
// --------------------------------------------------------
if (AfxMessageBox(IDS_WRN_PPTP_NUMPORTS_CHANGING, MB_YESNO) == IDYES) { fReboot = TRUE; } } else AfxMessageBox(IDS_WRN_PPTP_NUMPORTS_CHANGING2, MB_OK); }
//$L2TP
// For L2TP, if the value of m_dwPorts exceeds the value of
// m_dwMaxPorts, then we have to reboot (we also need to adjust
// the appropriate registry entries).
// ----------------------------------------------------------------
if ((dwNewPorts > m_pEntry->m_dwMaxPorts) && (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)) { // If we have a page, then we can do a reboot, otherwise we
// are in the wizard and can't do a reboot at this point.
// ------------------------------------------------------------
if (m_pageGeneral) { // The user chose Yes indicating that he wants to be prompted to
// reboot, so set this flag to trigger a reboot request.
// --------------------------------------------------------
if (AfxMessageBox(IDS_WRN_L2TP_NUMPORTS_CHANGING, MB_YESNO) == IDYES) { fReboot = TRUE; } } else AfxMessageBox(IDS_WRN_L2TP_NUMPORTS_CHANGING2, MB_OK); }
if ((dwNewEnableRas != m_pEntry->m_dwEnableRas) || (dwNewEnableRouting != m_pEntry->m_dwEnableRouting) || (dwNewEnableOutboundRouting != m_pEntry->m_dwEnableOutboundRouting) || (dwNewPorts != m_pEntry->m_dwPorts)) { // warning user -- client could be disconnected -- BUG 165862
// when disable router / ras
// decreasing the number of ports
// ras
if(!dwNewEnableRas && m_pEntry->m_dwEnableRas && m_dwTotalActivePorts > 0 && AfxMessageBox(IDS_WRN_PORTS_DISABLERAS, MB_YESNO | MB_DEFBUTTON2) == IDNO) goto L_RESTORE; // routing
if (((!dwNewEnableRouting && m_pEntry->m_dwEnableRouting) || (!dwNewEnableOutboundRouting && m_pEntry->m_dwEnableOutboundRouting)) && m_dwTotalActivePorts > 0 && AfxMessageBox(IDS_WRN_PORTS_DISABLEROUTING, MB_YESNO | MB_DEFBUTTON2) == IDNO) goto L_RESTORE;
// Bug 263958
//ports -- We cannot count the number of outgoing connection remotely.
// Therefore if we reduce the number of port, give warning without counting total
// active connections.
if(dwNewPorts < m_pEntry->m_dwPorts && AfxMessageBox(IDS_WRN_PORTS_DECREASE, MB_YESNO | MB_DEFBUTTON2) == IDNO) goto L_RESTORE;
m_pEntry->m_dwEnableRas = dwNewEnableRas; m_pEntry->m_dwEnableRouting = dwNewEnableRouting; m_pEntry->m_dwEnableOutboundRouting = dwNewEnableOutboundRouting; m_pEntry->m_dwPorts = dwNewPorts; m_pEntry->m_fModified = TRUE; }
// Get the called id info string (if the field changed)
// ----------------------------------------------------------------
if (((CEdit *) GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID))->GetModify()) { CString st; GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->GetWindowText(st);
StringToCalledIdInfo((LPCTSTR) st);
// Now set the changed state on the structure
// We need to save this data back to the registry
// ------------------------------------------------------------
m_pEntry->m_fSaveCalledIdInfo = TRUE; } CBaseDialog::OnOK(); if(fReboot == TRUE) { Assert(m_pageGeneral); // force an OnApply to save data before shut down
// ------------------------------------------------------------
if (m_pageGeneral->OnApply()) { WCHAR szComputer[MAX_COMPUTERNAME_LENGTH + 1]; DWORD dwLength = MAX_COMPUTERNAME_LENGTH;
GetComputerName(szComputer, &dwLength ); if (lstrcmpi(szComputer, (LPTSTR)m_pageGeneral->m_spRouter->GetMachineName())) { ::RestartComputer((LPTSTR)m_pageGeneral->m_spRouter->GetMachineName()); } else ::RestartComputer((LPTSTR)NULL); } }
return; L_RESTORE: if (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE) { CheckDlgButton( IDC_DEVCFG_BTN_OUTBOUND_ROUTING, m_pEntry->m_dwEnableOutboundRouting ); }
else { CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_pEntry->m_dwEnableRas); CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_pEntry->m_dwEnableRouting); }
m_spinPorts.SetPos(m_pEntry->m_dwPorts);
return; }
/*!--------------------------------------------------------------------------
PortsDeviceConfigDlg::LoadCalledIdInfo - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDeviceConfigDlg::LoadCalledIdInfo() { HRESULT hr = hrOK; if (!m_pEntry->m_fCalledIdInfoLoaded) { // Read the data from the registry
// ------------------------------------------------------------
if (m_pEntry->m_fRegistry) { DWORD dwType; DWORD dwSize; LPBYTE pbData = NULL; DWORD dwErr; RegKey regkeyDevice; regkeyDevice.Attach(m_pEntry->m_hKey);
dwErr = regkeyDevice.QueryValueExplicit(c_szRegValCalledIdInformation, &dwType, &dwSize, &pbData);
hr = HRESULT_FROM_WIN32(dwErr);
if ((dwErr == ERROR_SUCCESS) && (dwType == REG_MULTI_SZ)) { // Allocate space for a new called id structure
// ----------------------------------------------------
delete (BYTE *) m_pEntry->m_pCalledIdInfo; hr = AllocateCalledId(dwSize, &(m_pEntry->m_pCalledIdInfo));
if (FHrSucceeded(hr)) { memcpy(m_pEntry->m_pCalledIdInfo->bCalledId, pbData, dwSize); }
} delete pbData; regkeyDevice.Detach(); } else { HANDLE hConnection = NULL; DWORD dwSize = 0; DWORD dwErr; // use Rao's API
// Connect to the server
// --------------------------------------------------------
dwErr = RasRpcConnectServer((LPTSTR) (LPCTSTR)m_stMachine, &hConnection);
// Call it once to get the size information
// --------------------------------------------------------
if (dwErr == ERROR_SUCCESS) dwErr = RasGetCalledIdInfo(hConnection, &m_pEntry->m_RasDeviceInfo, &dwSize, NULL); hr = HRESULT_FROM_WIN32(dwErr);
if ((dwErr == ERROR_BUFFER_TOO_SMALL) || (dwErr == ERROR_SUCCESS)) { // Allocate space for a new called id structure
// ----------------------------------------------------
delete (BYTE *) m_pEntry->m_pCalledIdInfo; AllocateCalledId(dwSize, &(m_pEntry->m_pCalledIdInfo));
dwErr = RasGetCalledIdInfo(hConnection, &m_pEntry->m_RasDeviceInfo, &dwSize, m_pEntry->m_pCalledIdInfo ); hr = HRESULT_FROM_WIN32(dwErr); }
if (hConnection) RasRpcDisconnectServer(hConnection); }
// Set the status flags, depending on whether the operation
// succeeded or not
// ------------------------------------------------------------
// We always set the save value to FALSE after we have read
// something in (or tried to read something in).
// ------------------------------------------------------------
m_pEntry->m_fSaveCalledIdInfo = FALSE;
// We always set the load value to TRUE (we have tried to load
// the information but it failed, for example the registry
// key may not exist).
// ------------------------------------------------------------
m_pEntry->m_fCalledIdInfoLoaded = TRUE; if (!FHrSucceeded(hr)) { delete m_pEntry->m_pCalledIdInfo; m_pEntry->m_pCalledIdInfo = NULL; } } //Error:
return hr; }
/*!--------------------------------------------------------------------------
PortsDeviceConfigDlg::AllocateCalledId - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDeviceConfigDlg::AllocateCalledId(DWORD dwSize, RAS_CALLEDID_INFO **ppCalledId) { HRESULT hr = hrOK;
*ppCalledId = NULL; COM_PROTECT_TRY { *ppCalledId = (RAS_CALLEDID_INFO *) new BYTE[sizeof(RAS_CALLEDID_INFO) + dwSize]; (*ppCalledId)->dwSize = dwSize; } COM_PROTECT_CATCH;
return hr; }
/*!--------------------------------------------------------------------------
PortsDeviceConfigDlg::CalledIdInfoToString Converts the data in the called id info structure into a semi-colon separated string. Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDeviceConfigDlg::CalledIdInfoToString(CString *pst) { WCHAR * pswz = NULL; HRESULT hr = hrOK; USES_CONVERSION;
Assert(pst); Assert(m_pEntry);
COM_PROTECT_TRY { pst->Empty();
if (m_pEntry->m_pCalledIdInfo) pswz = (WCHAR *) (m_pEntry->m_pCalledIdInfo->bCalledId);
if (pswz && *pswz) { *pst += W2T(pswz);
// Skip over the terminating NULL
// --------------------------------------------------------
pswz += StrLenW(pswz)+1; while (*pswz) { *pst += _T("; "); *pst += W2T(pswz); // Skip over the terminating NULL
// --------------------------------------------------------
pswz += StrLenW(pswz)+1; } } } COM_PROTECT_CATCH;
if (!FHrSucceeded(hr)) pst->Empty();
return hr; }
/*!--------------------------------------------------------------------------
PortsDeviceConfigDlg::StringToCalledIdInfo - Author: KennT ---------------------------------------------------------------------------*/ HRESULT PortsDeviceConfigDlg::StringToCalledIdInfo(LPCTSTR psz) { DWORD cchSize; WCHAR * pswzData = NULL; WCHAR * pswzCurrent; LPTSTR pszBufferStart = NULL; LPTSTR pszBuffer = NULL; RAS_CALLEDID_INFO * pCalledInfo = NULL; HRESULT hr = hrOK; CString stTemp;
// We need to parse the string (look for separators)
// ----------------------------------------------------------------
COM_PROTECT_TRY {
// Allocate some space for the called id info (it's just as long
// as the string, maybe even somewhat smaller).
// Allocate twice the space so that we are sure of getting
// all of the NULL terminating characters
// ------------------------------------------------------------
pswzData = new WCHAR[2*(StrLen(psz)+1) + 1]; pswzCurrent = pswzData; // Copy the string into a buffer
// ------------------------------------------------------------
pszBufferStart = StrDup(psz); pszBuffer = pszBufferStart; _tcstok(pszBuffer, _T(";")); while (pszBuffer && *pszBuffer) { // Trim the string (get rid of whitespace, before and after).
// --------------------------------------------------------
stTemp = pszBuffer; stTemp.TrimLeft(); stTemp.TrimRight(); if (!stTemp.IsEmpty()) { StrCpyWFromT(pswzCurrent, (LPCTSTR) stTemp); pswzCurrent += stTemp.GetLength()+1; } pszBuffer = _tcstok(NULL, _T(";")); } // Add extra terminating NULL character (so that it conforms
// to the REG_MULTI_SZ format).
// ------------------------------------------------------------
*pswzCurrent = 0; cchSize = pswzCurrent - pswzData + 1; // Allocate the real data structure
// Allocate and copy into a temporary so that in case
// of an exception, we don't lose the original data
// ------------------------------------------------------------
AllocateCalledId(cchSize*sizeof(WCHAR), &pCalledInfo); memcpy(pCalledInfo->bCalledId, pswzData, cchSize*sizeof(WCHAR));
delete (BYTE *) m_pEntry->m_pCalledIdInfo; m_pEntry->m_pCalledIdInfo = pCalledInfo;
// Set to NULL so that we don't delete our new pointer
// on exit.
// ------------------------------------------------------------
pCalledInfo = NULL; } COM_PROTECT_CATCH;
delete pszBufferStart; delete pswzData; delete pCalledInfo; return hr; }
/*---------------------------------------------------------------------------
PortsSimpleDeviceConfigDlg implementation ---------------------------------------------------------------------------*/
BEGIN_MESSAGE_MAP(PortsSimpleDeviceConfigDlg, CBaseDialog) //{{AFX_MSG_MAP(PortsPageGeneral)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void PortsSimpleDeviceConfigDlg::DoDataExchange(CDataExchange *pDX) { CBaseDialog::DoDataExchange(pDX); }
BOOL PortsSimpleDeviceConfigDlg::OnInitDialog() { HRESULT hr; CBaseDialog::OnInitDialog();
// If we are using the BIG dialog, then we need to disable
// the unapplicable controls.
if (GetDlgItem(IDC_DEVCFG_TEXT_CALLEDID)) { MultiEnableWindow(GetSafeHwnd(), FALSE, IDC_DEVCFG_TEXT_CALLEDID, IDC_DEVCFG_EDIT_CALLEDID, IDC_DEVCFG_TEXT_PORTS, IDC_DEVCFG_EDIT_PORTS, IDC_DEVCFG_SPIN_PORTS, IDC_DEVCFG_TEXT, 0); }
CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_dwEnableRas); CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_dwEnableRouting); GetDlgItem(IDC_DEVCFG_BTN_OUTBOUND_ROUTING)->EnableWindow(FALSE);
return TRUE; }
/*!--------------------------------------------------------------------------
PortsSimpleDeviceConfigDlg::OnOK - Author: KennT ---------------------------------------------------------------------------*/ void PortsSimpleDeviceConfigDlg::OnOK() { // Check to see if the values changed
m_dwEnableRas = (IsDlgButtonChecked(IDC_DEVCFG_BTN_RAS) != 0); m_dwEnableRouting = (IsDlgButtonChecked(IDC_DEVCFG_BTN_ROUTING) != 0);
CBaseDialog::OnOK(); return; }
/*---------------------------------------------------------------------------
PortsDeviceEntry implementation ---------------------------------------------------------------------------*/
PortsDeviceEntry::PortsDeviceEntry() : m_hKey(NULL), m_fRegistry(FALSE), m_fSaveCalledIdInfo(FALSE), m_fCalledIdInfoLoaded(FALSE), m_pCalledIdInfo(NULL) { }
PortsDeviceEntry::~PortsDeviceEntry() { delete (BYTE *) m_pCalledIdInfo; if (m_hKey) DisconnectRegistry(m_hKey); m_hKey = NULL; }
BOOL RestartComputer(LPTSTR szMachineName)
/* Called if user chooses to shut down the computer.
** ** Return false if failure, true otherwise */ { HANDLE hToken; /* handle to process token */ TOKEN_PRIVILEGES tkp; /* ptr. to token structure */ BOOL fResult; /* system shutdown flag */ CString str;
TRACE(L"RestartComputer");
/* Enable the shutdown privilege */
if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return FALSE;
/* Get the LUID for shutdown privilege. */
if (szMachineName) LookupPrivilegeValue(NULL, SE_REMOTE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); else LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1; /* one privilege to set */ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
/* Get shutdown privilege for this process. */
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
/* Cannot test the return value of AdjustTokenPrivileges. */
if (GetLastError() != ERROR_SUCCESS) return FALSE;
str.LoadString(IDS_SHUTDOWN_WARNING); fResult = InitiateSystemShutdownEx( szMachineName, // computer to shutdown
str.GetBuffer(10), // msg. to user
20, // time out period - shut down right away
FALSE, // forcibly close open apps
TRUE, // Reboot after shutdown
SHTDN_REASON_FLAG_PLANNED | SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG ); str.ReleaseBuffer();
if (!fResult) { return FALSE; } if( !ExitWindowsEx(EWX_REBOOT, 0)) return FALSE;
/* Disable shutdown privilege. */
tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
return TRUE; }
/*!--------------------------------------------------------------------------
OnConfigurePorts Returns TRUE if something has changed. FALSE otherwise. Author: KennT ---------------------------------------------------------------------------*/ BOOL OnConfigurePorts(LPCTSTR pszMachineName, DWORD dwTotalActivePorts, PortsPageGeneral *pPage, CListCtrlEx *pListCtrl) { BOOL fChanged = FALSE; // Need to determine if multiple items are selected or not
if (pListCtrl->GetSelectedCount() == 1) { PortsDeviceConfigDlg configdlg(pPage, pszMachineName); int iPos; PortsDeviceEntry * pEntry; CString st; int iType; TCHAR szNumber[32]; if ((iPos = pListCtrl->GetNextItem(-1, LVNI_SELECTED)) == -1) return FALSE; pEntry = (PortsDeviceEntry *) pListCtrl->GetItemData(iPos); // total number of active ports are passed over to dialog, so if user tries to reduce total number of port
// below this total number, give a warning message
configdlg.SetDevice(pEntry, dwTotalActivePorts); if (configdlg.DoModal() == IDOK) { // Get the values from pEntry and update the list control entry
iType = (pEntry->m_dwEnableRas * 2) + (pEntry->m_dwEnableRouting || pEntry->m_dwEnableOutboundRouting);
st = PortsDeviceTypeToCString(iType); pListCtrl->SetItemText(iPos, PORTS_COL_USAGE, (LPCTSTR) st); FormatNumber(pEntry->m_dwPorts, szNumber, DimensionOf(szNumber), FALSE); pListCtrl->SetItemText(iPos, PORTS_COL_NUMBER, (LPCTSTR) szNumber);
fChanged = TRUE; } } return fChanged; }
/*---------------------------------------------------------------------------
RasmanPortMap implementation ---------------------------------------------------------------------------*/
RasmanPortMap::~RasmanPortMap() { m_map.RemoveAll(); }
HRESULT RasmanPortMap::Init(HANDLE hRasHandle, RASMAN_PORT *pPort, DWORD dwPorts) { RASMAN_INFO rasmaninfo; DWORD i; DWORD dwErr = NO_ERROR; HRESULT hr = hrOK;
if (pPort == NULL) { m_map.RemoveAll(); return hr; } for (i=0; i<dwPorts; i++, pPort++) { // If the port is closed, there is no need
// to go any further. (No need to do an RPC for this).
// ----------------------------------------------------
if (pPort->P_Status == CLOSED) continue; dwErr = RasGetInfo(hRasHandle, pPort->P_Handle, &rasmaninfo); if (dwErr != ERROR_SUCCESS) continue; // If this is a dial-out port and in use
// mark it as active
// --------------------------------------------
if ((rasmaninfo.RI_ConnState == CONNECTED) && (pPort->P_ConfiguredUsage & (CALL_IN | CALL_ROUTER)) && (rasmaninfo.RI_CurrentUsage & CALL_OUT)) { // Ok, this is a candidate. Add it to the list
// ----------------------------------------
WCHAR swzPortName[MAX_PORT_NAME+1];
StrnCpyWFromA(swzPortName, pPort->P_PortName, MAX_PORT_NAME); m_map.SetAt(swzPortName, pPort); } }
return hr; }
BOOL RasmanPortMap::FIsDialoutActive(LPCWSTR pswzPortName) { LPVOID pv; return m_map.Lookup(pswzPortName, pv); }
|