Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3905 lines
135 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. Ports
  7. Interface node information
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "Ports.h"
  12. #include "ifadmin.h"
  13. #include "rtrstrm.h" // for RouterAdminConfigStream
  14. #include "rtrlib.h" // ContainerColumnInfo
  15. #include "coldlg.h" // ColumnDlg
  16. #include "column.h" // ComponentConfigStream
  17. #include "refresh.h" // IRouterRefresh
  18. #include "iface.h" // for interfacenode data
  19. #include "portdlg.h" // CConnDlg - connection dialog
  20. #include "msgdlg.h" // CMessageDlg
  21. #include "raserror.h"
  22. #include "dmvcomp.h"
  23. #include "remras.h"
  24. #include "rrasutil.h" // Smart pointers
  25. #include "rtrcomn.h" // CoCreateRouterConfig
  26. #include "rtrutilp.h" // PortsDeviceTypeToCString
  27. static BOOL RestartComputer(LPTSTR szMachineName);
  28. //$PPTP
  29. // This is the maximum number of ports that we allow for PPTP.
  30. // Thus we can raise the maximum to this value only.
  31. // --------------------------------------------------------------------
  32. #define PPTP_MAX_PORTS 16384
  33. //$L2TP
  34. // This is the maximum number of ports that we allow for L2TP.
  35. // Thus we can raise the maximum to this value only.
  36. // --------------------------------------------------------------------
  37. #define L2TP_MAX_PORTS 30000
  38. /*---------------------------------------------------------------------------
  39. Defaults
  40. ---------------------------------------------------------------------------*/
  41. PortsNodeData::PortsNodeData()
  42. {
  43. #ifdef DEBUG
  44. StrCpyA(m_szDebug, "PortsNodeData");
  45. #endif
  46. }
  47. PortsNodeData::~PortsNodeData()
  48. {
  49. }
  50. /*!--------------------------------------------------------------------------
  51. PortsNodeData::InitAdminNodeData
  52. -
  53. Author: KennT
  54. ---------------------------------------------------------------------------*/
  55. HRESULT PortsNodeData::InitAdminNodeData(ITFSNode *pNode,
  56. RouterAdminConfigStream *pConfigStream)
  57. {
  58. HRESULT hr = hrOK;
  59. PortsNodeData * pData = NULL;
  60. pData = new PortsNodeData;
  61. SET_PORTSNODEDATA(pNode, pData);
  62. // Need to connect to the router to get this data
  63. return hr;
  64. }
  65. /*!--------------------------------------------------------------------------
  66. PortsNodeData::FreeAdminNodeData
  67. -
  68. Author: KennT
  69. ---------------------------------------------------------------------------*/
  70. HRESULT PortsNodeData::FreeAdminNodeData(ITFSNode *pNode)
  71. {
  72. PortsNodeData * pData = GET_PORTSNODEDATA(pNode);
  73. delete pData;
  74. SET_PORTSNODEDATA(pNode, NULL);
  75. return hrOK;
  76. }
  77. HRESULT PortsNodeData::LoadHandle(LPCTSTR pszMachineName)
  78. {
  79. m_stMachineName = pszMachineName;
  80. return HResultFromWin32(::MprAdminServerConnect((LPTSTR) pszMachineName,
  81. &m_sphDdmHandle));
  82. }
  83. HANDLE PortsNodeData::GetHandle()
  84. {
  85. if (!m_sphDdmHandle)
  86. {
  87. LoadHandle(m_stMachineName);
  88. }
  89. return m_sphDdmHandle;
  90. }
  91. void PortsNodeData::ReleaseHandles()
  92. {
  93. m_sphDdmHandle.Release();
  94. }
  95. STDMETHODIMP PortsNodeHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  96. {
  97. // Is the pointer bad?
  98. if (ppv == NULL)
  99. return E_INVALIDARG;
  100. // Place NULL in *ppv in case of failure
  101. *ppv = NULL;
  102. // This is the non-delegating IUnknown implementation
  103. if (riid == IID_IUnknown)
  104. *ppv = (LPVOID) this;
  105. else if (riid == IID_IRtrAdviseSink)
  106. *ppv = &m_IRtrAdviseSink;
  107. else
  108. return CHandler::QueryInterface(riid, ppv);
  109. // If we're going to return an interface, AddRef it first
  110. if (*ppv)
  111. {
  112. ((LPUNKNOWN) *ppv)->AddRef();
  113. return hrOK;
  114. }
  115. else
  116. return E_NOINTERFACE;
  117. }
  118. /*---------------------------------------------------------------------------
  119. NodeHandler implementation
  120. ---------------------------------------------------------------------------*/
  121. extern const ContainerColumnInfo s_rgPortsColumnInfo[];
  122. const ContainerColumnInfo s_rgPortsColumnInfo[] =
  123. {
  124. { IDS_PORTS_COL_NAME, CON_SORT_BY_STRING, TRUE , COL_IF_NAME},
  125. { IDS_PORTS_COL_DEVICE, CON_SORT_BY_STRING, TRUE , COL_STRING},
  126. { IDS_PORTS_COL_USAGE, CON_SORT_BY_STRING, TRUE , COL_STRING},
  127. { IDS_PORTS_COL_STATUS, CON_SORT_BY_STRING, TRUE , COL_STATUS},
  128. { IDS_PORTS_COL_COMMENT, CON_SORT_BY_STRING, FALSE , COL_STRING},
  129. };
  130. #define NUM_FOLDERS 1
  131. PortsNodeHandler::PortsNodeHandler(ITFSComponentData *pCompData)
  132. : BaseContainerHandler(pCompData, DM_COLUMNS_PORTS, s_rgPortsColumnInfo),
  133. m_bExpanded(FALSE),
  134. m_pConfigStream(NULL),
  135. m_ulConnId(0),
  136. m_ulRefreshConnId(0),
  137. m_dwActivePorts(0)
  138. {
  139. m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
  140. m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
  141. // Setup the verb states for this node
  142. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  143. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  144. }
  145. /*!--------------------------------------------------------------------------
  146. PortsNodeHandler::Init
  147. -
  148. Author: KennT
  149. ---------------------------------------------------------------------------*/
  150. HRESULT PortsNodeHandler::Init(IRouterInfo *pRouterInfo,
  151. RouterAdminConfigStream *pConfigStream)
  152. {
  153. HRESULT hr = hrOK;
  154. // If we don't have a router info then we probably failed to load
  155. // or failed to connect. Bail out of this.
  156. if (!pRouterInfo)
  157. CORg( E_FAIL );
  158. m_spRouterInfo.Set(pRouterInfo);
  159. // Also need to register for change notifications
  160. m_spRouterInfo->RtrAdvise(&m_IRtrAdviseSink, &m_ulConnId, 0);
  161. m_pConfigStream = pConfigStream;
  162. Error:
  163. return hrOK;
  164. }
  165. /*!--------------------------------------------------------------------------
  166. PortsNodeHandler::DestroyHandler
  167. Implementation of ITFSNodeHandler::DestroyHandler
  168. Author: KennT
  169. ---------------------------------------------------------------------------*/
  170. STDMETHODIMP PortsNodeHandler::DestroyHandler(ITFSNode *pNode)
  171. {
  172. PortsNodeData::FreeAdminNodeData(pNode);
  173. m_spDataObject.Release();
  174. if (m_ulRefreshConnId)
  175. {
  176. SPIRouterRefresh spRefresh;
  177. if (m_spRouterInfo)
  178. m_spRouterInfo->GetRefreshObject(&spRefresh);
  179. if (spRefresh)
  180. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  181. }
  182. m_ulRefreshConnId = 0;
  183. if (m_spRouterInfo)
  184. {
  185. m_spRouterInfo->RtrUnadvise(m_ulConnId);
  186. m_spRouterInfo.Release();
  187. }
  188. return hrOK;
  189. }
  190. /*!--------------------------------------------------------------------------
  191. PortsNodeHandler::HasPropertyPages
  192. Implementation of ITFSNodeHandler::HasPropertyPages
  193. Author: KennT
  194. ---------------------------------------------------------------------------*/
  195. STDMETHODIMP
  196. PortsNodeHandler::HasPropertyPages
  197. (
  198. ITFSNode * pNode,
  199. LPDATAOBJECT pDataObject,
  200. DATA_OBJECT_TYPES type,
  201. DWORD dwType
  202. )
  203. {
  204. // Yes, we do have property pages
  205. return hrOK;
  206. }
  207. /*!--------------------------------------------------------------------------
  208. PortsNodeHandler::CreatePropertyPages
  209. Implementation of ITFSNodeHandler::CreatePropertyPages
  210. Author: KennT
  211. ---------------------------------------------------------------------------*/
  212. STDMETHODIMP PortsNodeHandler::CreatePropertyPages(
  213. ITFSNode * pNode,
  214. LPPROPERTYSHEETCALLBACK lpProvider,
  215. LPDATAOBJECT pDataObject,
  216. LONG_PTR handle,
  217. DWORD dwType
  218. )
  219. {
  220. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  221. HRESULT hr = hrOK;
  222. PortsProperties* pPropSheet = NULL;
  223. SPIComponentData spComponentData;
  224. CString stTitle;
  225. CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
  226. pPropSheet = new PortsProperties(pNode, spComponentData,
  227. m_spTFSCompData, stTitle,
  228. NULL, 0, TRUE
  229. );
  230. if ( FHrFailed(pPropSheet->Init(m_spRouterInfo, this)) )
  231. {
  232. AfxMessageBox(IDS_ERR_NO_ROUTERPROTOCOLS);
  233. delete pPropSheet;
  234. return hr;
  235. }
  236. if (lpProvider)
  237. hr = pPropSheet->CreateModelessSheet(lpProvider, handle);
  238. else
  239. hr = pPropSheet->DoModelessSheet();
  240. Error:
  241. return hr;
  242. }
  243. /*---------------------------------------------------------------------------
  244. Menu data structure for our menus
  245. ---------------------------------------------------------------------------*/
  246. struct SPortsNodeMenu
  247. {
  248. ULONG m_sidMenu; // string/command id for this menu item
  249. ULONG (PortsNodeHandler:: *m_pfnGetMenuFlags)(PortsNodeHandler::SMenuData *);
  250. ULONG m_ulPosition;
  251. };
  252. //static const SPortsNodeMenu s_rgPortsNodeMenu[] =
  253. //{
  254. // // Add items that are primary go here
  255. // // Add items that go on the "Create new" menu here
  256. // // Add items that go on the "Task" menu here
  257. //};
  258. /*!--------------------------------------------------------------------------
  259. PortsNodeHandler::OnAddMenuItems
  260. Implementation of ITFSNodeHandler::OnAddMenuItems
  261. Author: KennT
  262. ---------------------------------------------------------------------------*/
  263. STDMETHODIMP PortsNodeHandler::OnAddMenuItems(
  264. ITFSNode *pNode,
  265. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  266. LPDATAOBJECT lpDataObject,
  267. DATA_OBJECT_TYPES type,
  268. DWORD dwType,
  269. long *pInsertionAllowed)
  270. {
  271. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  272. HRESULT hr = S_OK;
  273. COM_PROTECT_TRY
  274. {
  275. // Uncomment if you have items to add
  276. // hr = AddArrayOfMenuItems(pNode, s_rgPortsNodeMenu,
  277. // DimensionOf(s_rgPortsNodeMenu),
  278. // pContextMenuCallback,
  279. // *pInsertionAllowed);
  280. }
  281. COM_PROTECT_CATCH;
  282. return hr;
  283. }
  284. /*!--------------------------------------------------------------------------
  285. PortsNodeHandler::GetString
  286. Implementation of ITFSNodeHandler::GetString
  287. Author: KennT
  288. ---------------------------------------------------------------------------*/
  289. STDMETHODIMP_(LPCTSTR) PortsNodeHandler::GetString(ITFSNode *pNode, int nCol)
  290. {
  291. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  292. HRESULT hr = hrOK;
  293. COM_PROTECT_TRY
  294. {
  295. if (m_stTitle.IsEmpty())
  296. m_stTitle.LoadString(IDS_PORTS);
  297. }
  298. COM_PROTECT_CATCH;
  299. return m_stTitle;
  300. }
  301. /*!--------------------------------------------------------------------------
  302. PortsNodeHandler::OnCreateDataObject
  303. Implementation of ITFSNodeHandler::OnCreateDataObject
  304. Author: KennT
  305. ---------------------------------------------------------------------------*/
  306. STDMETHODIMP PortsNodeHandler::OnCreateDataObject(MMC_COOKIE cookie,
  307. DATA_OBJECT_TYPES type,
  308. IDataObject **ppDataObject)
  309. {
  310. HRESULT hr = hrOK;
  311. COM_PROTECT_TRY
  312. {
  313. if (!m_spDataObject)
  314. {
  315. CORg( CreateDataObjectFromRouterInfo(m_spRouterInfo,
  316. m_spRouterInfo->GetMachineName(),
  317. type, cookie, m_spTFSCompData,
  318. &m_spDataObject, NULL, FALSE) );
  319. Assert(m_spDataObject);
  320. }
  321. *ppDataObject = m_spDataObject;
  322. (*ppDataObject)->AddRef();
  323. COM_PROTECT_ERROR_LABEL;
  324. }
  325. COM_PROTECT_CATCH;
  326. return hr;
  327. }
  328. /*!--------------------------------------------------------------------------
  329. PortsNodeHandler::OnExpand
  330. -
  331. Author: KennT
  332. ---------------------------------------------------------------------------*/
  333. HRESULT PortsNodeHandler::OnExpand(ITFSNode *pNode,
  334. LPDATAOBJECT pDataObject,
  335. DWORD dwType,
  336. LPARAM arg,
  337. LPARAM lParam)
  338. {
  339. HRESULT hr = hrOK;
  340. // If we don't have a router object, then we don't have any info, don't
  341. // try to expand.
  342. if (!m_spRouterInfo)
  343. return hrOK;
  344. if (m_bExpanded)
  345. return hrOK;
  346. COM_PROTECT_TRY
  347. {
  348. SynchronizeNodeData(pNode);
  349. m_bExpanded = TRUE;
  350. }
  351. COM_PROTECT_CATCH;
  352. return hr;
  353. }
  354. /*!--------------------------------------------------------------------------
  355. PortsNodeHandler::OnResultShow
  356. -
  357. Author: KennT
  358. ---------------------------------------------------------------------------*/
  359. HRESULT PortsNodeHandler::OnResultShow(ITFSComponent *pTFSComponent,
  360. MMC_COOKIE cookie,
  361. LPARAM arg,
  362. LPARAM lParam)
  363. {
  364. BOOL bSelect = (BOOL) arg;
  365. HRESULT hr = hrOK;
  366. SPIRouterRefresh spRefresh;
  367. SPITFSNode spNode;
  368. BaseContainerHandler::OnResultShow(pTFSComponent, cookie, arg, lParam);
  369. if (bSelect)
  370. {
  371. // Call synchronize on this node
  372. m_spNodeMgr->FindNode(cookie, &spNode);
  373. if (spNode)
  374. SynchronizeNodeData(spNode);
  375. }
  376. // Un/Register for refresh advises
  377. if (m_spRouterInfo)
  378. m_spRouterInfo->GetRefreshObject(&spRefresh);
  379. if (spRefresh)
  380. {
  381. if (bSelect)
  382. {
  383. if (m_ulRefreshConnId == 0)
  384. spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulRefreshConnId, 0);
  385. }
  386. else
  387. {
  388. if (m_ulRefreshConnId)
  389. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  390. m_ulRefreshConnId = 0;
  391. }
  392. }
  393. return hr;
  394. }
  395. /*!--------------------------------------------------------------------------
  396. PortsNodeHandler::ConstructNode
  397. Initializes the Domain node (sets it up).
  398. Author: KennT
  399. ---------------------------------------------------------------------------*/
  400. HRESULT PortsNodeHandler::ConstructNode(ITFSNode *pNode)
  401. {
  402. HRESULT hr = hrOK;
  403. PortsNodeData * pNodeData;
  404. if (pNode == NULL)
  405. return hrOK;
  406. COM_PROTECT_TRY
  407. {
  408. // Need to initialize the data for the Domain node
  409. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_INTERFACES);
  410. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_INTERFACES);
  411. pNode->SetData(TFS_DATA_SCOPEID, 0);
  412. // This is a leaf node in the scope pane
  413. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  414. m_cookie = reinterpret_cast<LONG_PTR>(pNode);
  415. pNode->SetData(TFS_DATA_COOKIE, m_cookie);
  416. pNode->SetNodeType(&GUID_RouterPortsNodeType);
  417. PortsNodeData::InitAdminNodeData(pNode, m_pConfigStream);
  418. pNodeData = GET_PORTSNODEDATA(pNode);
  419. Assert(pNodeData);
  420. //if there is any handle open, release it first
  421. pNodeData->ReleaseHandles();
  422. // Ignore the error, we should be able to deal with the
  423. // case of a stopped router.
  424. pNodeData->LoadHandle(m_spRouterInfo->GetMachineName());
  425. }
  426. COM_PROTECT_CATCH
  427. return hr;
  428. }
  429. /*!--------------------------------------------------------------------------
  430. PortsNodeHandler::SynchronizeNodeData
  431. -
  432. Author: KennT
  433. ---------------------------------------------------------------------------*/
  434. HRESULT PortsNodeHandler::SynchronizeNodeData(ITFSNode *pThisNode)
  435. {
  436. Assert(pThisNode);
  437. SPITFSNodeEnum spEnum;
  438. int i;
  439. HRESULT hr = hrOK;
  440. InterfaceNodeData *pData;
  441. DWORD dwErr;
  442. PortsNodeData * pNodeData;
  443. PortsList portsList;
  444. PortsList newPortsList;
  445. PortsListEntry * pPorts;
  446. BOOL fFound;
  447. POSITION pos;
  448. SPITFSNode spChildNode;
  449. InterfaceNodeData * pChildData;
  450. DWORD dwOldGdiBatchLimit;
  451. dwOldGdiBatchLimit = GdiGetBatchLimit();
  452. GdiSetBatchLimit(100);
  453. COM_PROTECT_TRY
  454. {
  455. // Get the status data from the running router
  456. pNodeData = GET_PORTSNODEDATA(pThisNode);
  457. // Ignore the error, we should be able to deal with the
  458. // case of a stopped router.
  459. if(pNodeData)
  460. {
  461. pNodeData->ReleaseHandles();
  462. pNodeData->LoadHandle(m_spRouterInfo->GetMachineName());
  463. }
  464. if (pNodeData == NULL || INVALID_HANDLE_VALUE == pNodeData->GetHandle())
  465. {
  466. // Remove all of the nodes, we can't connect so we can't
  467. // get any running data.
  468. UnmarkAllNodes(pThisNode, spEnum);
  469. RemoveAllUnmarkedNodes(pThisNode, spEnum);
  470. return hrOK;
  471. }
  472. // Unmark all of the nodes
  473. pThisNode->GetEnum(&spEnum);
  474. UnmarkAllNodes(pThisNode, spEnum);
  475. // Go out and grab the data, merge the the new data in with
  476. // the old data.
  477. if( S_OK == GenerateListOfPorts(pThisNode, &portsList) )
  478. {
  479. pos = portsList.GetHeadPosition();
  480. // clear active ports count -- for bug 165862
  481. m_dwActivePorts = 0;
  482. while (pos)
  483. {
  484. pPorts = & portsList.GetNext(pos);
  485. // Look for this entry in our current list of nodes
  486. spEnum->Reset();
  487. spChildNode.Release();
  488. fFound = FALSE;
  489. for (;spEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  490. {
  491. pChildData = GET_INTERFACENODEDATA(spChildNode);
  492. Assert(pChildData);
  493. if (pChildData->m_rgData[PORTS_SI_PORT].m_ulData ==
  494. (LONG_PTR) pPorts->m_rp0.hPort)
  495. {
  496. // Ok, this user already exists, update the metric
  497. // and mark it
  498. Assert(pChildData->dwMark == FALSE);
  499. pChildData->dwMark = TRUE;
  500. fFound = TRUE;
  501. SetUserData(spChildNode, *pPorts);
  502. // Force MMC to redraw the node
  503. spChildNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  504. break;
  505. }
  506. }
  507. if (!fFound)
  508. newPortsList.AddTail(*pPorts);
  509. }
  510. }
  511. // Remove all nodes that were not marked
  512. RemoveAllUnmarkedNodes(pThisNode, spEnum);
  513. // Now iterate through the list of new users, adding them all in.
  514. pos = newPortsList.GetHeadPosition();
  515. while (pos)
  516. {
  517. pPorts = & newPortsList.GetNext(pos);
  518. AddPortsUserNode(pThisNode, *pPorts);
  519. }
  520. }
  521. COM_PROTECT_CATCH;
  522. GdiFlush();
  523. GdiSetBatchLimit(dwOldGdiBatchLimit);
  524. return hr;
  525. }
  526. /*!--------------------------------------------------------------------------
  527. PortsNodeHandler::SetUserData
  528. -
  529. Author: KennT
  530. ---------------------------------------------------------------------------*/
  531. HRESULT PortsNodeHandler::SetUserData(ITFSNode *pNode,
  532. const PortsListEntry& entry)
  533. {
  534. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  535. HRESULT hr = hrOK;
  536. InterfaceNodeData * pData;
  537. TCHAR szNumber[32];
  538. CString st;
  539. int ids;
  540. pData = GET_INTERFACENODEDATA(pNode);
  541. Assert(pData);
  542. st.Format(IDS_PORTS_NAME_FORMAT, entry.m_rp0.wszDeviceName,
  543. entry.m_rp0.wszPortName);
  544. pData->m_rgData[PORTS_SI_NAME].m_stData = st;
  545. pData->m_rgData[PORTS_SI_DEVICE].m_stData = entry.m_rp0.wszDeviceType;
  546. if (entry.m_fActiveDialOut)
  547. {
  548. ids = IDS_PORTS_DIALOUT_ACTIVE;
  549. }
  550. else if (entry.m_rp0.dwPortCondition == RAS_PORT_AUTHENTICATED)
  551. {
  552. ids = IDS_PORTS_ACTIVE;
  553. // to know how many active ports: BUG -- 165862
  554. // to prepare total number of active ports -- Wei Jiang
  555. m_dwActivePorts++;
  556. }
  557. else
  558. {
  559. ids = IDS_PORTS_INACTIVE;
  560. }
  561. pData->m_rgData[PORTS_SI_STATUS].m_stData.LoadString(ids);
  562. pData->m_rgData[PORTS_SI_STATUS].m_dwData = entry.m_rp0.dwPortCondition;
  563. pData->m_rgData[PORTS_SI_PORT].m_ulData = (LONG_PTR) entry.m_rp0.hPort;
  564. // fix b: 32887 -- show ras/routing enabled information
  565. // Column 0...Usage
  566. INT iType = (entry.m_dwEnableRas * 2) +
  567. entry.m_dwEnableRouting |
  568. entry.m_dwEnableOutboundRouting;
  569. pData->m_rgData[PORTS_SI_USAGE].m_stData = PortsDeviceTypeToCString(iType);
  570. // Update the PortsListEntry
  571. * (PortsListEntry *)pData->lParamPrivate = entry;
  572. // For status, need to check to see if there are any connections
  573. // on this port.
  574. return hr;
  575. }
  576. /*!--------------------------------------------------------------------------
  577. PortsNodeHandler::GenerateListOfPorts
  578. -
  579. Author: KennT
  580. ---------------------------------------------------------------------------*/
  581. HRESULT PortsNodeHandler::GenerateListOfPorts(ITFSNode *pNode, PortsList *pList)
  582. {
  583. HRESULT hr = hrOK;
  584. PortsListEntry entry;
  585. PortsNodeData * pPortsData;
  586. DWORD dwTotal;
  587. DWORD i;
  588. RAS_PORT_0 * rp0Table;
  589. DWORD rp0Count;
  590. SPMprAdminBuffer spMpr;
  591. HANDLE hRasHandle = INVALID_HANDLE_VALUE;
  592. DWORD dwSize, dwEntries;
  593. DWORD dwErr;
  594. LPBYTE pbPorts = NULL;
  595. POSITION pos;
  596. POSITION posPort;
  597. RasmanPortMap portMap;
  598. // fix b: 3288 --
  599. PortsDeviceList portsDeviceList;
  600. PortsDataEntry portsDataEntry;
  601. pPortsData = GET_PORTSNODEDATA(pNode);
  602. Assert(pPortsData);
  603. // If we are connected, enumerate through the list of
  604. // ports
  605. CWRg( ::MprAdminPortEnum( pPortsData->GetHandle(),
  606. 0,
  607. INVALID_HANDLE_VALUE,
  608. (BYTE **) &rp0Table,
  609. (DWORD) -1,
  610. &rp0Count,
  611. &dwTotal,
  612. NULL) );
  613. Assert(rp0Table);
  614. spMpr = (LPBYTE) rp0Table;
  615. // Add a new PortsListEntry for each port
  616. // fix b: 32887 -- show ras/routing enabled information
  617. // use PortsDataEntry to load the device information to be use later for each ports
  618. // to get if a port is enabled for ras / routing
  619. hr = portsDataEntry.Initialize(m_spRouterInfo->GetMachineName());
  620. if (hr == S_OK)
  621. {
  622. hr = portsDataEntry.LoadDevices(&portsDeviceList);
  623. }
  624. for (i=0; i<rp0Count; i++)
  625. {
  626. ::ZeroMemory(&entry, sizeof(entry));
  627. entry.m_rp0 = rp0Table[i];
  628. //Get the unicode name from the port handle
  629. //RasGetUnicodeDeviceName(entry.m_rp0.hPort, entry.m_rp0.wszDeviceName);
  630. entry.m_fActiveDialOut = FALSE;
  631. // find out if ras / routing is enabled on the port
  632. entry.m_dwEnableRas = 0; // = 1 if RAS is enabled on this device
  633. entry.m_dwEnableRouting = 0; // = 1 if Routing is enabled on this device
  634. entry.m_dwEnableOutboundRouting = 0; // = 1 if outbound
  635. // routing is enabled
  636. // on this device
  637. POSITION pos;
  638. pos = portsDeviceList.GetHeadPosition();
  639. while(pos != NULL)
  640. {
  641. PortsDeviceEntry * pPortEntry = portsDeviceList.GetNext(pos);
  642. CString strPortName = entry.m_rp0.wszDeviceName;
  643. if(strPortName == pPortEntry->m_stDisplayName)
  644. {
  645. entry.m_dwEnableRas = pPortEntry->m_dwEnableRas;
  646. entry.m_dwEnableRouting = pPortEntry->m_dwEnableRouting;
  647. entry.m_dwEnableOutboundRouting =
  648. pPortEntry->m_dwEnableOutboundRouting;
  649. break;
  650. }
  651. }
  652. pList->AddTail(entry);
  653. }
  654. spMpr.Free();
  655. Error:
  656. delete [] pbPorts;
  657. if (hRasHandle != INVALID_HANDLE_VALUE)
  658. RasRpcDisconnectServer(hRasHandle);
  659. return hr;
  660. }
  661. ImplementEmbeddedUnknown(PortsNodeHandler, IRtrAdviseSink)
  662. STDMETHODIMP PortsNodeHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  663. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  664. {
  665. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  666. InitPThis(PortsNodeHandler, IRtrAdviseSink);
  667. SPITFSNode spThisNode;
  668. HRESULT hr = hrOK;
  669. COM_PROTECT_TRY
  670. {
  671. pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spThisNode);
  672. if (dwChangeType == ROUTER_REFRESH)
  673. {
  674. // Ok, just call the synchronize on this node
  675. pThis->SynchronizeNodeData(spThisNode);
  676. }
  677. else if (dwChangeType == ROUTER_DO_DISCONNECT)
  678. {
  679. PortsNodeData * pData = GET_PORTSNODEDATA(spThisNode);
  680. Assert(pData);
  681. // Release the handle
  682. pData->ReleaseHandles();
  683. }
  684. }
  685. COM_PROTECT_CATCH;
  686. return hr;
  687. }
  688. /*!--------------------------------------------------------------------------
  689. PortsNodeHandler::CompareItems
  690. Implementation of ITFSResultHandler::CompareItems
  691. Author: KennT
  692. ---------------------------------------------------------------------------*/
  693. STDMETHODIMP_(int) PortsNodeHandler::CompareItems(
  694. ITFSComponent * pComponent,
  695. MMC_COOKIE cookieA,
  696. MMC_COOKIE cookieB,
  697. int nCol)
  698. {
  699. // Get the strings from the nodes and use that as a basis for
  700. // comparison.
  701. SPITFSNode spNode;
  702. SPITFSResultHandler spResult;
  703. m_spNodeMgr->FindNode(cookieA, &spNode);
  704. spNode->GetResultHandler(&spResult);
  705. return spResult->CompareItems(pComponent, cookieA, cookieB, nCol);
  706. }
  707. /*!--------------------------------------------------------------------------
  708. PortsNodeHandler::AddPortsUserNode
  709. Adds a user to the UI. This will create a new result item
  710. node for each interface.
  711. Author: KennT
  712. ---------------------------------------------------------------------------*/
  713. HRESULT PortsNodeHandler::AddPortsUserNode(ITFSNode *pParent, const PortsListEntry& PortsEntry)
  714. {
  715. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  716. PortsUserHandler * pHandler;
  717. SPITFSResultHandler spHandler;
  718. SPITFSNode spNode;
  719. HRESULT hr = hrOK;
  720. pHandler = new PortsUserHandler(m_spTFSCompData);
  721. spHandler = pHandler;
  722. CORg( pHandler->Init(m_spRouterInfo, pParent) );
  723. CORg( CreateLeafTFSNode(&spNode,
  724. NULL,
  725. static_cast<ITFSNodeHandler *>(pHandler),
  726. static_cast<ITFSResultHandler *>(pHandler),
  727. m_spNodeMgr) );
  728. CORg( pHandler->ConstructNode(spNode, NULL, &PortsEntry) );
  729. SetUserData(spNode, PortsEntry);
  730. // Make the node immediately visible
  731. CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
  732. CORg( pParent->AddChild(spNode) );
  733. Error:
  734. return hr;
  735. }
  736. /*!--------------------------------------------------------------------------
  737. PortsNodeHandler::UnmarkAllNodes
  738. -
  739. Author: KennT
  740. ---------------------------------------------------------------------------*/
  741. HRESULT PortsNodeHandler::UnmarkAllNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
  742. {
  743. SPITFSNode spChildNode;
  744. InterfaceNodeData * pNodeData;
  745. pEnum->Reset();
  746. for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  747. {
  748. pNodeData = GET_INTERFACENODEDATA(spChildNode);
  749. Assert(pNodeData);
  750. pNodeData->dwMark = FALSE;
  751. }
  752. return hrOK;
  753. }
  754. /*!--------------------------------------------------------------------------
  755. PortsNodeHandler::RemoveAllUnmarkedNodes
  756. -
  757. Author: KennT
  758. ---------------------------------------------------------------------------*/
  759. HRESULT PortsNodeHandler::RemoveAllUnmarkedNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
  760. {
  761. HRESULT hr = hrOK;
  762. SPITFSNode spChildNode;
  763. InterfaceNodeData * pNodeData;
  764. pEnum->Reset();
  765. for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  766. {
  767. pNodeData = GET_INTERFACENODEDATA(spChildNode);
  768. Assert(pNodeData);
  769. if (pNodeData->dwMark == FALSE)
  770. {
  771. pNode->RemoveChild(spChildNode);
  772. spChildNode->Destroy();
  773. }
  774. }
  775. return hr;
  776. }
  777. /*---------------------------------------------------------------------------
  778. PortsUserHandler implementation
  779. ---------------------------------------------------------------------------*/
  780. DEBUG_DECLARE_INSTANCE_COUNTER(PortsUserHandler)
  781. IMPLEMENT_ADDREF_RELEASE(PortsUserHandler)
  782. STDMETHODIMP PortsUserHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  783. {
  784. // Is the pointer bad?
  785. if (ppv == NULL)
  786. return E_INVALIDARG;
  787. // Place NULL in *ppv in case of failure
  788. *ppv = NULL;
  789. // This is the non-delegating IUnknown implementation
  790. if (riid == IID_IUnknown)
  791. *ppv = (LPVOID) this;
  792. else if (riid == IID_IRtrAdviseSink)
  793. *ppv = &m_IRtrAdviseSink;
  794. else
  795. return CBaseResultHandler::QueryInterface(riid, ppv);
  796. // If we're going to return an interface, AddRef it first
  797. if (*ppv)
  798. {
  799. ((LPUNKNOWN) *ppv)->AddRef();
  800. return hrOK;
  801. }
  802. else
  803. return E_NOINTERFACE;
  804. }
  805. /*---------------------------------------------------------------------------
  806. NodeHandler implementation
  807. ---------------------------------------------------------------------------*/
  808. PortsUserHandler::PortsUserHandler(ITFSComponentData *pCompData)
  809. : BaseRouterHandler(pCompData),
  810. m_ulConnId(0)
  811. {
  812. DEBUG_INCREMENT_INSTANCE_COUNTER(PortsUserHandler);
  813. // Enable Refresh from the node itself
  814. // ----------------------------------------------------------------
  815. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  816. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  817. }
  818. /*!--------------------------------------------------------------------------
  819. PortsUserHandler::Init
  820. -
  821. Author: KennT
  822. ---------------------------------------------------------------------------*/
  823. HRESULT PortsUserHandler::Init(IRouterInfo *pInfo, ITFSNode *pParent)
  824. {
  825. m_spRouterInfo.Set(pInfo);
  826. return hrOK;
  827. }
  828. /*!--------------------------------------------------------------------------
  829. PortsUserHandler::DestroyResultHandler
  830. -
  831. Author: KennT
  832. ---------------------------------------------------------------------------*/
  833. STDMETHODIMP PortsUserHandler::DestroyResultHandler(MMC_COOKIE cookie)
  834. {
  835. SPITFSNode spNode;
  836. m_spNodeMgr->FindNode(cookie, &spNode);
  837. InterfaceNodeData::Free(spNode);
  838. CHandler::DestroyResultHandler(cookie);
  839. return hrOK;
  840. }
  841. static DWORD s_rgInterfaceImageMap[] =
  842. {
  843. ROUTER_IF_TYPE_HOME_ROUTER, IMAGE_IDX_WAN_CARD,
  844. ROUTER_IF_TYPE_FULL_ROUTER, IMAGE_IDX_WAN_CARD,
  845. ROUTER_IF_TYPE_CLIENT, IMAGE_IDX_WAN_CARD,
  846. ROUTER_IF_TYPE_DEDICATED, IMAGE_IDX_LAN_CARD,
  847. ROUTER_IF_TYPE_INTERNAL, IMAGE_IDX_LAN_CARD,
  848. ROUTER_IF_TYPE_LOOPBACK, IMAGE_IDX_LAN_CARD,
  849. -1, IMAGE_IDX_WAN_CARD, // sentinel value
  850. };
  851. /*!--------------------------------------------------------------------------
  852. PortsUserHandler::ConstructNode
  853. Initializes the Domain node (sets it up).
  854. Author: KennT
  855. ---------------------------------------------------------------------------*/
  856. HRESULT PortsUserHandler::ConstructNode(ITFSNode *pNode,
  857. IInterfaceInfo *pIfInfo,
  858. const PortsListEntry *pEntry)
  859. {
  860. HRESULT hr = hrOK;
  861. int i;
  862. InterfaceNodeData * pData;
  863. Assert(pEntry);
  864. if (pNode == NULL)
  865. return hrOK;
  866. COM_PROTECT_TRY
  867. {
  868. // Need to initialize the data for the Domain node
  869. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_WAN_CARD);
  870. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_WAN_CARD);
  871. pNode->SetData(TFS_DATA_SCOPEID, 0);
  872. pNode->SetData(TFS_DATA_COOKIE, reinterpret_cast<LONG_PTR>(pNode));
  873. //$ Review: kennt, what are the different type of interfaces
  874. // do we distinguish based on the same list as above? (i.e. the
  875. // one for image indexes).
  876. pNode->SetNodeType(&GUID_RouterPortsResultNodeType);
  877. m_entry = *pEntry;
  878. InterfaceNodeData::Init(pNode, pIfInfo);
  879. // We need to save this pointer so that it can be modified
  880. // (and updated) at a later time.
  881. // ------------------------------------------------------------
  882. pData = GET_INTERFACENODEDATA(pNode);
  883. pData->lParamPrivate = (LPARAM) &m_entry;
  884. }
  885. COM_PROTECT_CATCH
  886. return hr;
  887. }
  888. /*!--------------------------------------------------------------------------
  889. PortsUserHandler::GetString
  890. -
  891. Author: KennT
  892. ---------------------------------------------------------------------------*/
  893. STDMETHODIMP_(LPCTSTR) PortsUserHandler::GetString(ITFSComponent * pComponent,
  894. MMC_COOKIE cookie,
  895. int nCol)
  896. {
  897. Assert(m_spNodeMgr);
  898. SPITFSNode spNode;
  899. InterfaceNodeData * pData;
  900. ConfigStream * pConfig;
  901. m_spNodeMgr->FindNode(cookie, &spNode);
  902. Assert(spNode);
  903. pData = GET_INTERFACENODEDATA(spNode);
  904. Assert(pData);
  905. pComponent->GetUserData((LONG_PTR *) &pConfig);
  906. Assert(pConfig);
  907. return pData->m_rgData[pConfig->MapColumnToSubitem(DM_COLUMNS_PORTS, nCol)].m_stData;
  908. }
  909. /*!--------------------------------------------------------------------------
  910. PortsUserHandler::CompareItems
  911. -
  912. Author: KennT
  913. ---------------------------------------------------------------------------*/
  914. STDMETHODIMP_(int) PortsUserHandler::CompareItems(ITFSComponent * pComponent,
  915. MMC_COOKIE cookieA,
  916. MMC_COOKIE cookieB,
  917. int nCol)
  918. {
  919. return StriCmpW(GetString(pComponent, cookieA, nCol),
  920. GetString(pComponent, cookieB, nCol));
  921. }
  922. static const SRouterNodeMenu s_rgIfNodeMenu[] =
  923. {
  924. { IDS_MENU_PORTS_STATUS, 0,
  925. CCM_INSERTIONPOINTID_PRIMARY_TOP},
  926. { IDS_MENU_PORTS_DISCONNECT, PortsUserHandler::GetDisconnectMenuState,
  927. CCM_INSERTIONPOINTID_PRIMARY_TOP},
  928. };
  929. ULONG PortsUserHandler::GetDisconnectMenuState(const SRouterNodeMenu *pMenuData,
  930. INT_PTR pUserData)
  931. {
  932. InterfaceNodeData * pNodeData;
  933. SMenuData * pData = reinterpret_cast<SMenuData *>(pUserData);
  934. pNodeData = GET_INTERFACENODEDATA(pData->m_spNode);
  935. Assert(pNodeData);
  936. if (pNodeData->m_rgData[PORTS_SI_STATUS].m_dwData == RAS_PORT_AUTHENTICATED)
  937. return 0;
  938. else
  939. return MF_GRAYED;
  940. }
  941. /*!--------------------------------------------------------------------------
  942. PortsUserHandler::AddMenuItems
  943. Implementation of ITFSResultHandler::OnAddMenuItems
  944. Author: KennT
  945. ---------------------------------------------------------------------------*/
  946. STDMETHODIMP PortsUserHandler::AddMenuItems(ITFSComponent *pComponent,
  947. MMC_COOKIE cookie,
  948. LPDATAOBJECT lpDataObject,
  949. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  950. long *pInsertionAllowed)
  951. {
  952. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  953. HRESULT hr = S_OK;
  954. SPITFSNode spNode;
  955. PortsUserHandler::SMenuData menuData;
  956. // We don't allow any actions on active dialout connections
  957. // ------------------------------------------------------------
  958. if (m_entry.m_fActiveDialOut)
  959. return hrOK;
  960. COM_PROTECT_TRY
  961. {
  962. m_spNodeMgr->FindNode(cookie, &spNode);
  963. // Now go through and add our menu items
  964. menuData.m_spNode.Set(spNode);
  965. hr = AddArrayOfMenuItems(spNode, s_rgIfNodeMenu,
  966. DimensionOf(s_rgIfNodeMenu),
  967. pContextMenuCallback,
  968. *pInsertionAllowed,
  969. reinterpret_cast<INT_PTR>(&menuData));
  970. }
  971. COM_PROTECT_CATCH;
  972. return hr;
  973. }
  974. /*!--------------------------------------------------------------------------
  975. PortsUserHandler::Command
  976. -
  977. Author: KennT
  978. ---------------------------------------------------------------------------*/
  979. STDMETHODIMP PortsUserHandler::Command(ITFSComponent *pComponent,
  980. MMC_COOKIE cookie,
  981. int nCommandId,
  982. LPDATAOBJECT pDataObject)
  983. {
  984. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  985. SPITFSNode spNode;
  986. SPITFSNode spNodeParent;
  987. SPITFSNodeHandler spParentHandler;
  988. PortsNodeData * pData;
  989. HRESULT hr = S_OK;
  990. COM_PROTECT_TRY
  991. {
  992. switch (nCommandId)
  993. {
  994. case IDS_MENU_PORTS_STATUS:
  995. {
  996. BOOL fRefresh = FALSE;
  997. DWORD dwInterval = 60;
  998. SPIRouterRefresh spRefresh;
  999. if (m_spRouterInfo)
  1000. m_spRouterInfo->GetRefreshObject(&spRefresh);
  1001. // Stop the auto refresh (if it is turned on)
  1002. // ------------------------------------------------
  1003. if (spRefresh && FHrOK(spRefresh->IsRefreshStarted()))
  1004. {
  1005. fRefresh = TRUE;
  1006. spRefresh->GetRefreshInterval(&dwInterval);
  1007. spRefresh->Stop();
  1008. }
  1009. // NOTE: This function gets called from other places
  1010. // in the code (for which pDataObject==NULL)
  1011. // Get the hServer and hPort
  1012. m_spNodeMgr->FindNode(cookie, &spNode);
  1013. spNode->GetParent(&spNodeParent);
  1014. pData = GET_PORTSNODEDATA(spNodeParent);
  1015. CPortDlg portdlg((LPCTSTR) pData->m_stMachineName,
  1016. pData->GetHandle(),
  1017. m_entry.m_rp0.hPort,
  1018. spNodeParent
  1019. );
  1020. portdlg.DoModal();
  1021. // if (portdlg.m_bChanged)
  1022. RefreshInterface(cookie);
  1023. // Restart the refresh mechanism
  1024. // ------------------------------------------------
  1025. if (fRefresh && spRefresh)
  1026. {
  1027. spRefresh->SetRefreshInterval(dwInterval);
  1028. spRefresh->Start(dwInterval);
  1029. }
  1030. }
  1031. break;
  1032. case IDS_MENU_PORTS_DISCONNECT:
  1033. {
  1034. // Get the hServer and hPort
  1035. m_spNodeMgr->FindNode(cookie, &spNode);
  1036. spNode->GetParent(&spNodeParent);
  1037. pData = GET_PORTSNODEDATA(spNodeParent);
  1038. ::MprAdminPortDisconnect(
  1039. pData->GetHandle(),
  1040. m_entry.m_rp0.hPort);
  1041. RefreshInterface(cookie);
  1042. }
  1043. break;
  1044. default:
  1045. break;
  1046. };
  1047. }
  1048. COM_PROTECT_CATCH;
  1049. return hr;
  1050. }
  1051. ImplementEmbeddedUnknown(PortsUserHandler, IRtrAdviseSink)
  1052. STDMETHODIMP PortsUserHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  1053. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  1054. {
  1055. InitPThis(PortsUserHandler, IRtrAdviseSink);
  1056. HRESULT hr = hrOK;
  1057. return hr;
  1058. }
  1059. /*!--------------------------------------------------------------------------
  1060. PortsUserHandler::OnCreateDataObject
  1061. Implementation of ITFSResultHandler::OnCreateDataObject
  1062. Author: KennT
  1063. ---------------------------------------------------------------------------*/
  1064. STDMETHODIMP PortsUserHandler::OnCreateDataObject(ITFSComponent *pComp,
  1065. MMC_COOKIE cookie,
  1066. DATA_OBJECT_TYPES type,
  1067. IDataObject **ppDataObject)
  1068. {
  1069. HRESULT hr = hrOK;
  1070. COM_PROTECT_TRY
  1071. {
  1072. CORg( CreateDataObjectFromRouterInfo(m_spRouterInfo,
  1073. m_spRouterInfo->GetMachineName(),
  1074. type, cookie, m_spTFSCompData,
  1075. ppDataObject, NULL, FALSE) );
  1076. COM_PROTECT_ERROR_LABEL;
  1077. }
  1078. COM_PROTECT_CATCH;
  1079. return hr;
  1080. }
  1081. STDMETHODIMP PortsUserHandler::HasPropertyPages (
  1082. ITFSComponent *pComp,
  1083. MMC_COOKIE cookie,
  1084. LPDATAOBJECT pDataObject)
  1085. {
  1086. return hrFalse;
  1087. }
  1088. /*!--------------------------------------------------------------------------
  1089. PortsUserHandler::RefreshInterface
  1090. -
  1091. Author: KennT
  1092. ---------------------------------------------------------------------------*/
  1093. void PortsUserHandler::RefreshInterface(MMC_COOKIE cookie)
  1094. {
  1095. ForceGlobalRefresh(m_spRouterInfo);
  1096. }
  1097. /*!--------------------------------------------------------------------------
  1098. PortsUserHandler::OnResultItemClkOrDblClk
  1099. -
  1100. Author: KennT
  1101. ---------------------------------------------------------------------------*/
  1102. HRESULT PortsUserHandler::OnResultItemClkOrDblClk(ITFSComponent *pComponent,
  1103. MMC_COOKIE cookie,
  1104. LPARAM arg,
  1105. LPARAM lParam ,
  1106. BOOL bDoubleClick)
  1107. {
  1108. HRESULT hr = hrOK;
  1109. // We don't allow any actions on active dialout connections
  1110. // ------------------------------------------------------------
  1111. if (m_entry.m_fActiveDialOut)
  1112. return hrOK;
  1113. if (bDoubleClick)
  1114. {
  1115. // Bring up the status dialog on this port
  1116. CORg( Command(pComponent, cookie, IDS_MENU_PORTS_STATUS,
  1117. NULL) );
  1118. }
  1119. Error:
  1120. return hr;
  1121. }
  1122. /*---------------------------------------------------------------------------
  1123. PortsProperties implementation
  1124. ---------------------------------------------------------------------------*/
  1125. PortsProperties::PortsProperties(ITFSNode *pNode,
  1126. IComponentData *pComponentData,
  1127. ITFSComponentData *pTFSCompData,
  1128. LPCTSTR pszSheetName,
  1129. CWnd *pParent,
  1130. UINT iPage,
  1131. BOOL fScopePane)
  1132. : RtrPropertySheet(pNode, pComponentData, pTFSCompData,
  1133. pszSheetName, pParent, iPage, fScopePane),
  1134. m_pageGeneral(IDD_PORTS_GLOBAL_GENERAL),
  1135. m_pPortsNodeHandle(NULL),
  1136. m_dwThreadId(0)
  1137. {
  1138. }
  1139. PortsProperties::~PortsProperties()
  1140. {
  1141. if (m_dwThreadId)
  1142. DestroyTFSErrorInfoForThread(m_dwThreadId, 0);
  1143. if(m_pPortsNodeHandle)
  1144. {
  1145. m_pPortsNodeHandle->Release();
  1146. m_pPortsNodeHandle = NULL;
  1147. }
  1148. }
  1149. /*!--------------------------------------------------------------------------
  1150. PortsProperties::Init
  1151. Initialize the property sheets. The general action here will be
  1152. to initialize/add the various pages.
  1153. Author: KennT
  1154. ---------------------------------------------------------------------------*/
  1155. HRESULT PortsProperties::Init(IRouterInfo *pRouter, PortsNodeHandler* pPortsNodeHandle)
  1156. {
  1157. Assert(pRouter);
  1158. HRESULT hr = hrOK;
  1159. m_spRouter.Set(pRouter);
  1160. m_pPortsNodeHandle = pPortsNodeHandle;
  1161. if(m_pPortsNodeHandle) m_pPortsNodeHandle->AddRef();
  1162. // The pages are embedded members of the class
  1163. // do not delete them.
  1164. m_bAutoDeletePages = FALSE;
  1165. m_pageGeneral.Init(this, pRouter);
  1166. AddPageToList((CPropertyPageBase*) &m_pageGeneral);
  1167. //Error:
  1168. return hr;
  1169. }
  1170. /*!--------------------------------------------------------------------------
  1171. PortsProperties::SetThreadInfo
  1172. -
  1173. Author: KennT
  1174. ---------------------------------------------------------------------------*/
  1175. void PortsProperties::SetThreadInfo(DWORD dwThreadId)
  1176. {
  1177. m_dwThreadId = dwThreadId;
  1178. }
  1179. /*---------------------------------------------------------------------------
  1180. PortsPageGeneral
  1181. ---------------------------------------------------------------------------*/
  1182. BEGIN_MESSAGE_MAP(PortsPageGeneral, RtrPropertyPage)
  1183. //{{AFX_MSG_MAP(PortsPageGeneral)
  1184. ON_BN_CLICKED(IDC_PGG_BTN_CONFIGURE, OnConfigure)
  1185. ON_NOTIFY(NM_DBLCLK, IDC_PGG_LIST, OnListDblClk)
  1186. ON_NOTIFY(LVN_ITEMCHANGED, IDC_PGG_LIST, OnNotifyListItemChanged)
  1187. //}}AFX_MSG_MAP
  1188. END_MESSAGE_MAP()
  1189. PortsPageGeneral::~PortsPageGeneral()
  1190. {
  1191. while (!m_deviceList.IsEmpty())
  1192. delete m_deviceList.RemoveHead();
  1193. }
  1194. /*!--------------------------------------------------------------------------
  1195. PortsPageGeneral::Init
  1196. -
  1197. Author: KennT
  1198. ---------------------------------------------------------------------------*/
  1199. HRESULT PortsPageGeneral::Init(PortsProperties *pPropSheet, IRouterInfo *pRouter)
  1200. {
  1201. m_pPortsPropSheet = pPropSheet;
  1202. m_spRouter.Set(pRouter);
  1203. RouterVersionInfo routerVersion;
  1204. // Get the version info. Needed later on.
  1205. // ----------------------------------------------------------------
  1206. ASSERT(m_spRouter.p);
  1207. m_spRouter->GetRouterVersionInfo(&routerVersion);
  1208. m_bShowContent = (routerVersion.dwRouterVersion >= 5);
  1209. return hrOK;
  1210. }
  1211. /*!--------------------------------------------------------------------------
  1212. PortsPageGeneral::OnInitDialog
  1213. -
  1214. Author: KennT
  1215. ---------------------------------------------------------------------------*/
  1216. BOOL PortsPageGeneral::OnInitDialog()
  1217. {
  1218. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1219. HRESULT hr= hrOK;
  1220. int i;
  1221. CString st;
  1222. UINT cRows = 0;
  1223. PortsDeviceEntry * pEntry = NULL;
  1224. TCHAR szNumber[32];
  1225. HRESULT hrT;
  1226. RECT rc;
  1227. int nWidth, nUsageWidth;
  1228. int nListWidth;
  1229. POSITION pos;
  1230. INT iPos;
  1231. HKEY hkeyMachine = 0;
  1232. INT iType, idsType;
  1233. DWORD dwIn, dwOut;
  1234. // if focus on NT4 machine, not to display the content of the dialog, only display some text
  1235. // for the user that the snapin only shows property of NT5 server
  1236. if (!m_bShowContent)
  1237. {
  1238. CString st;
  1239. st.LoadString(IDS_ERR_NOPORTINFO_ON_NT4);
  1240. EnableChildControls(GetSafeHwnd(), PROPPAGE_CHILD_HIDE | PROPPAGE_CHILD_DISABLE);
  1241. GetDlgItem(IDC_PGG_TXT_NOINFO)->SetWindowText(st);
  1242. GetDlgItem(IDC_PGG_TXT_NOINFO)->ShowWindow(SW_SHOW);
  1243. GetDlgItem(IDC_PGG_TXT_NOINFO)->EnableWindow(TRUE);
  1244. return TRUE;
  1245. }
  1246. // hide the warning text if on NT5 servers
  1247. GetDlgItem(IDC_PGG_TXT_NOINFO)->ShowWindow(SW_HIDE);
  1248. COM_PROTECT_TRY
  1249. {
  1250. // This assumes that this page will always come up.
  1251. // Create the error info for this thread!
  1252. // ------------------------------------------------------------
  1253. CreateTFSErrorInfo(0);
  1254. m_pPortsPropSheet->SetThreadInfo(GetCurrentThreadId());
  1255. RtrPropertyPage::OnInitDialog();
  1256. ListView_SetExtendedListViewStyle(m_listCtrl.GetSafeHwnd(),
  1257. LVS_EX_FULLROWSELECT);
  1258. // Initialize the list control (with the list of devices)
  1259. // Determine optimal width for the header control
  1260. GetDlgItem(IDC_PGG_LIST)->GetWindowRect(&rc);
  1261. nListWidth = rc.right - rc.left;
  1262. // Figure out the size of Ras/Routing
  1263. st.LoadString(IDS_PORTSDLG_COL_RASROUTING);
  1264. st += _T("WW"); // add extra padding to get a little wider
  1265. nUsageWidth = m_listCtrl.GetStringWidth(st);
  1266. // Remove the Ras/Routing column from the rest of the width
  1267. nListWidth -= nUsageWidth;
  1268. // Remove four pixels off the end (for the borders?)
  1269. nListWidth -= 4;
  1270. // Split the width into fifths
  1271. nWidth = nListWidth / 5;
  1272. // Create the column headers.
  1273. // Column 0...Usage
  1274. st.LoadString(IDS_PORTSDLG_COL_USAGE);
  1275. m_listCtrl.InsertColumn(PORTS_COL_USAGE, st, LVCFMT_LEFT, nUsageWidth, 0);
  1276. // Column 1...Device
  1277. st.LoadString(IDS_PORTSDLG_COL_NAME);
  1278. m_listCtrl.InsertColumn(PORTS_COL_DEVICE, st, LVCFMT_LEFT, 3*nWidth, 0);
  1279. // Column 2...Type
  1280. st.LoadString(IDS_PORTSDLG_COL_TYPE);
  1281. m_listCtrl.InsertColumn(PORTS_COL_TYPE, st, LVCFMT_LEFT, nWidth, 0);
  1282. // Column 3...Number of Ports
  1283. st.LoadString(IDS_PORTSDLG_COL_NUM_PORTS);
  1284. m_listCtrl.InsertColumn(PORTS_COL_NUMBER, st, LVCFMT_LEFT, nWidth, 0);
  1285. // Query for the ports' data.
  1286. m_deviceDataEntry.Initialize(m_spRouter->GetMachineName());
  1287. m_deviceDataEntry.LoadDevices(&m_deviceList);
  1288. // Walk the list of ports and construct the row entry for the table
  1289. // for the given port.
  1290. pos = m_deviceList.GetHeadPosition();
  1291. while (pos)
  1292. {
  1293. pEntry = m_deviceList.GetNext(pos);
  1294. Assert(!::IsBadReadPtr(pEntry, sizeof(PortsDeviceEntry)));
  1295. // Column 1...Device
  1296. iPos = m_listCtrl.InsertItem(cRows, pEntry->m_stDisplayName);
  1297. m_listCtrl.SetItemText(iPos, PORTS_COL_DEVICE,
  1298. (LPCTSTR) pEntry->m_stDisplayName);
  1299. // Column 2...Type
  1300. st = PortTypeToCString(RAS_DEVICE_TYPE(pEntry->m_eDeviceType));
  1301. m_listCtrl.SetItemText(iPos, PORTS_COL_TYPE, (LPCTSTR) st);
  1302. // Column 3...Number of Ports
  1303. FormatNumber(pEntry->m_dwPorts, szNumber,
  1304. DimensionOf(szNumber), FALSE);
  1305. m_listCtrl.SetItemText(iPos, PORTS_COL_NUMBER, (LPCTSTR) szNumber);
  1306. m_listCtrl.SetItemData(iPos, (LONG_PTR) pEntry);
  1307. // Column 0...Usage
  1308. iType = (pEntry->m_dwEnableRas * 2) +
  1309. (pEntry->m_dwEnableRouting |
  1310. pEntry->m_dwEnableOutboundRouting);
  1311. st = PortsDeviceTypeToCString(iType);
  1312. m_listCtrl.SetItemText(iPos, PORTS_COL_USAGE, (LPCTSTR) st);
  1313. // How many rows now?
  1314. ++cRows; // preincrement faster operation on Pentium chips...
  1315. }
  1316. // As a default, disable the maximum ports dialog
  1317. GetDlgItem(IDC_PGG_BTN_CONFIGURE)->EnableWindow(FALSE);
  1318. if (cRows)
  1319. {
  1320. // Select the first entry in the list control
  1321. m_listCtrl.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
  1322. }
  1323. }
  1324. COM_PROTECT_CATCH;
  1325. SetDirty(FALSE);
  1326. if (!FHrSucceeded(hr))
  1327. {
  1328. delete pEntry;
  1329. Cancel();
  1330. }
  1331. return FHrSucceeded(hr) ? TRUE : FALSE;
  1332. }
  1333. /*!--------------------------------------------------------------------------
  1334. PortsPageGeneral::DoDataExchange
  1335. -
  1336. Author: KennT
  1337. ---------------------------------------------------------------------------*/
  1338. void PortsPageGeneral::DoDataExchange(CDataExchange *pDX)
  1339. {
  1340. if (!m_bShowContent) return;
  1341. RtrPropertyPage::DoDataExchange(pDX);
  1342. //{{AFX_DATA_MAP(PortsPageGeneral)
  1343. DDX_Control(pDX, IDC_PGG_LIST, m_listCtrl);
  1344. //}}AFX_DATA_MAP
  1345. }
  1346. /*!--------------------------------------------------------------------------
  1347. PortsPageGeneral::OnApply
  1348. -
  1349. Author: KennT
  1350. ---------------------------------------------------------------------------*/
  1351. BOOL PortsPageGeneral::OnApply()
  1352. {
  1353. if (!m_bShowContent) return TRUE;
  1354. if (m_pPortsPropSheet->IsCancel())
  1355. return TRUE;
  1356. if(!IsDirty())
  1357. return TRUE;
  1358. BOOL fReturn;
  1359. HRESULT hr = hrOK;
  1360. HRESULT hrT = hrOK;
  1361. DWORD dwErr, dwInValue, dwOutValue;
  1362. HKEY hkeyMachine;
  1363. RegKey regkeyMachine;
  1364. POSITION pos;
  1365. PortsDeviceEntry * pEntry;
  1366. // Create an error object (just in case)
  1367. CreateTFSErrorInfo(0);
  1368. ClearTFSErrorInfo(0);
  1369. CWRg( ConnectRegistry(m_spRouter->GetMachineName(), &hkeyMachine) );
  1370. regkeyMachine.Attach(hkeyMachine);
  1371. // We ignore the error code from the SaveDevices(). The reason
  1372. // is that for most of the failures, it's only a partial failure
  1373. // (especially for the RasSetDeviceConfigInfo() call.
  1374. hrT = m_deviceDataEntry.SaveDevices(&m_deviceList);
  1375. AddSystemErrorMessage(hrT);
  1376. Error:
  1377. if (!FHrSucceeded(hr) || !FHrSucceeded(hrT))
  1378. {
  1379. AddHighLevelErrorStringId(IDS_ERR_CANNOT_SAVE_PORTINFO);
  1380. DisplayTFSErrorMessage(NULL);
  1381. // Set focus back to the property sheet
  1382. BringWindowToTop();
  1383. // If the only thing that reports failure is hrT (or the
  1384. // SaveDevices() code), then we continue on.
  1385. if (FHrSucceeded(hr))
  1386. fReturn = RtrPropertyPage::OnApply();
  1387. else
  1388. fReturn = FALSE;
  1389. }
  1390. else
  1391. fReturn = RtrPropertyPage::OnApply();
  1392. // Windows NT Bug : 174916 - need to force a refresh through
  1393. ForceGlobalRefresh(m_spRouter);
  1394. return fReturn;
  1395. }
  1396. void PortsPageGeneral::OnListDblClk(NMHDR *pNMHdr, LRESULT *pResult)
  1397. {
  1398. OnConfigure();
  1399. *pResult = 0;
  1400. }
  1401. /*!--------------------------------------------------------------------------
  1402. PortsPageGeneral::OnNotifyListItemChanged
  1403. -
  1404. Author: KennT
  1405. ---------------------------------------------------------------------------*/
  1406. void PortsPageGeneral::OnNotifyListItemChanged(NMHDR *pNmHdr, LRESULT *pResult)
  1407. {
  1408. // NMLISTVIEW * pnmlv = reinterpret_cast<NMLISTVIEW *>(pNmHdr);
  1409. // BOOL fEnable = !!(pnmlv->uNewState & LVIS_SELECTED);
  1410. BOOL fEnable = (m_listCtrl.GetSelectedCount() != 0);
  1411. GetDlgItem(IDC_PGG_BTN_CONFIGURE)->EnableWindow(fEnable);
  1412. *pResult = 0;
  1413. }
  1414. /*!--------------------------------------------------------------------------
  1415. PortsPageGeneral::OnConfigure
  1416. -
  1417. Author: KennT
  1418. ---------------------------------------------------------------------------*/
  1419. void PortsPageGeneral::OnConfigure()
  1420. {
  1421. // Windows NT Bug : 322955
  1422. // Always mark the page dirty. This is needed because the OnOK()
  1423. // will call OnApply() on the property sheet before the dialog is
  1424. // exited. This is called to force the changes to save back before
  1425. // the restart is called.
  1426. // ----------------------------------------------------------------
  1427. SetDirty(TRUE);
  1428. SetModified();
  1429. OnConfigurePorts(m_spRouter->GetMachineName(),
  1430. m_pPortsPropSheet->m_pPortsNodeHandle->GetActivePorts(),
  1431. this,
  1432. &m_listCtrl);
  1433. }
  1434. /*---------------------------------------------------------------------------
  1435. PortsDataEntry implementation
  1436. ---------------------------------------------------------------------------*/
  1437. PortsDataEntry::PortsDataEntry()
  1438. {
  1439. m_fReadFromRegistry = TRUE;
  1440. }
  1441. PortsDataEntry::~PortsDataEntry()
  1442. {
  1443. }
  1444. /*!--------------------------------------------------------------------------
  1445. PortsDataEntry::Initialize
  1446. -
  1447. Author: KennT
  1448. ---------------------------------------------------------------------------*/
  1449. HRESULT PortsDataEntry::Initialize(LPCTSTR pszMachineName)
  1450. {
  1451. DWORD dwErr;
  1452. HRESULT hr = hrOK;
  1453. HKEY hkeyMachine;
  1454. m_fRestrictDialin = TRUE;
  1455. m_regkeyMachine.Close();
  1456. m_stMachine = pszMachineName;
  1457. dwErr = ConnectRegistry( m_stMachine, &hkeyMachine);
  1458. if( dwErr == NO_ERROR)
  1459. {
  1460. m_regkeyMachine.Attach(hkeyMachine);
  1461. hr = CheckForDialinRestriction();
  1462. }
  1463. else
  1464. {
  1465. hr = HRESULT_FROM_WIN32(dwErr);
  1466. }
  1467. return hr;
  1468. }
  1469. /*!--------------------------------------------------------------------------
  1470. PortsDataEntry::LoadDevices
  1471. -
  1472. Author: KennT
  1473. ---------------------------------------------------------------------------*/
  1474. HRESULT PortsDataEntry::LoadDevices(PortsDeviceList *pList)
  1475. {
  1476. HRESULT hr = hrOK;
  1477. POSITION pos;
  1478. PortsDeviceEntry * pEntry;
  1479. // Try to load the devices from the router (actually rasman),
  1480. // if that fails then try the registry
  1481. hr = LoadDevicesFromRouter(pList);
  1482. if (!FHrSucceeded(hr))
  1483. hr = LoadDevicesFromRegistry(pList);
  1484. return hr;
  1485. }
  1486. /*!--------------------------------------------------------------------------
  1487. PortsDataEntry::LoadDevicesFromRegistry
  1488. -
  1489. Author: KennT
  1490. ---------------------------------------------------------------------------*/
  1491. HRESULT PortsDataEntry::LoadDevicesFromRegistry(PortsDeviceList *pList)
  1492. {
  1493. HRESULT hr = hrOK;
  1494. RegKey regkey;
  1495. RegKey regkeyDevice;
  1496. RegKey regkeyEnable;
  1497. RegKeyIterator regkeyIter;
  1498. HRESULT hrIter;
  1499. CString stKey;
  1500. CString st;
  1501. CString stFullText;
  1502. CString stComponentId;
  1503. DWORD dwEnableRas;
  1504. DWORD dwEnableRouting;
  1505. DWORD dwEnableOutboundRouting;
  1506. DWORD dwT;
  1507. DWORD dwErr;
  1508. PortsDeviceEntry * pEntry;
  1509. WCHAR devName[MAX_DEVICE_NAME + 1];
  1510. COM_PROTECT_TRY
  1511. {
  1512. // Connect to the machine
  1513. // ------------------------------------------------------------
  1514. if (m_regkeyMachine == NULL)
  1515. {
  1516. CORg(ERROR_CAN_NOT_COMPLETE);
  1517. }
  1518. // Get the list of devices
  1519. // ------------------------------------------------------------
  1520. // Open HKLM\System\CurrentControlSet\Control\Class\<Modem GUID>
  1521. // ------------------------------------------------------------
  1522. CWRg( regkey.Open(m_regkeyMachine, c_szModemKey, KEY_READ) );
  1523. // Enumerate through the list of modems
  1524. // ------------------------------------------------------------
  1525. CORg( regkeyIter.Init(&regkey) );
  1526. for (hrIter = regkeyIter.Next(&stKey); hrIter == hrOK; stKey.Empty(), hrIter = regkeyIter.Next(&stKey))
  1527. {
  1528. // Cleanup from the previous loop
  1529. // --------------------------------------------------------
  1530. regkeyDevice.Close();
  1531. regkeyEnable.Close();
  1532. // Open the key
  1533. // --------------------------------------------------------
  1534. dwErr = regkeyDevice.Open(regkey, stKey, KEY_READ | KEY_WRITE);
  1535. if (dwErr != ERROR_SUCCESS)
  1536. continue;
  1537. // Need to check for the EnableForRas subkey
  1538. // --------------------------------------------------------
  1539. dwErr = regkeyEnable.Open(regkeyDevice, c_szClientsRasKey, KEY_READ);
  1540. if (dwErr == ERROR_SUCCESS)
  1541. {
  1542. dwErr = regkeyEnable.QueryValue(c_szEnableForRas, dwEnableRas);
  1543. }
  1544. // Default: assume that the modems are RAS-enabled
  1545. // --------------------------------------------------------
  1546. if (dwErr != ERROR_SUCCESS)
  1547. dwEnableRas = 1;
  1548. // Need to check for the EnableForRouting subkey
  1549. // --------------------------------------------------------
  1550. dwErr = regkeyEnable.QueryValue(c_szEnableForRouting, dwEnableRouting);
  1551. // Default: assume that the modems are not routing-enabled
  1552. // --------------------------------------------------------
  1553. if (dwErr != ERROR_SUCCESS)
  1554. dwEnableRouting = 0;
  1555. // Need to check for the EnableForOutboundRouting subkey
  1556. // --------------------------------------------------------
  1557. dwErr = regkeyEnable.QueryValue(
  1558. c_szEnableForOutboundRouting, dwEnableOutboundRouting
  1559. );
  1560. // Default: assume that the modems are not routing-enabled
  1561. // --------------------------------------------------------
  1562. if (dwErr != ERROR_SUCCESS)
  1563. dwEnableOutboundRouting = 0;
  1564. CString stDisplay;
  1565. // Do allocation before adding the text to the UI
  1566. // --------------------------------------------------------
  1567. pEntry = new PortsDeviceEntry;
  1568. pEntry->m_fModified = FALSE;
  1569. pEntry->m_dwPorts = 1;
  1570. pEntry->m_fWriteable = FALSE; // # of ports can't be changed
  1571. pEntry->m_dwMinPorts = pEntry->m_dwPorts;
  1572. pEntry->m_dwMaxPorts = pEntry->m_dwPorts;
  1573. pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
  1574. pEntry->m_dwEnableRas = dwEnableRas;
  1575. pEntry->m_dwEnableRouting = dwEnableRouting;
  1576. pEntry->m_dwEnableOutboundRouting = dwEnableOutboundRouting;
  1577. pEntry->m_eDeviceType = RDT_Modem;
  1578. // Save the old values
  1579. // --------------------------------------------------------
  1580. pEntry->m_dwOldPorts = pEntry->m_dwPorts;
  1581. // Add this modem to the list
  1582. // --------------------------------------------------------
  1583. regkeyDevice.QueryValue(c_szFriendlyName, stFullText);
  1584. regkeyDevice.QueryValue(c_szAttachedTo, st);
  1585. stDisplay.Format(IDS_PORTS_NAME_FORMAT, stFullText, st);
  1586. swprintf(devName, L"%S",(LPCTSTR)stDisplay);
  1587. pEntry->m_stDisplayName = devName;
  1588. // Read in all data from the registry key BEFORE here
  1589. // --------------------------------------------------------
  1590. pEntry->m_fRegistry = TRUE;
  1591. pEntry->m_hKey = regkeyDevice;
  1592. regkeyDevice.Detach();
  1593. pList->AddTail(pEntry);
  1594. pEntry = NULL;
  1595. }
  1596. // Enumerate through the list of adapters that have the EnableForRas flag
  1597. // Open HKLM\System\CurrentControlSet\Control\Class\GUID_DEVCLASS_NET
  1598. // ------------------------------------------------------------
  1599. regkey.Close();
  1600. CWRg( regkey.Open(m_regkeyMachine, c_szRegKeyGUID_DEVCLASS_NET, KEY_READ | KEY_WRITE) );
  1601. // Enumerate through the list of adapters
  1602. // ------------------------------------------------------------
  1603. CORg( regkeyIter.Init(&regkey) );
  1604. stKey.Empty();
  1605. for (hrIter = regkeyIter.Next(&stKey); hrIter == hrOK; hrIter = regkeyIter.Next(&stKey))
  1606. {
  1607. // Cleanup from the previous loop
  1608. // --------------------------------------------------------
  1609. regkeyDevice.Close();
  1610. // Open the key
  1611. // --------------------------------------------------------
  1612. dwErr = regkeyDevice.Open(regkey, stKey, KEY_READ | KEY_WRITE);
  1613. if (dwErr == ERROR_SUCCESS)
  1614. {
  1615. CString stDisplay;
  1616. DWORD dwEndpoints;
  1617. // Need to get the ComponentId to check for PPTP/PTI
  1618. // ------------------------------------------------
  1619. dwErr = regkeyDevice.QueryValue(c_szRegValMatchingDeviceId,
  1620. stComponentId);
  1621. if (dwErr != ERROR_SUCCESS)
  1622. {
  1623. dwErr = regkeyDevice.QueryValue(c_szRegValComponentId,
  1624. stComponentId);
  1625. if (dwErr != ERROR_SUCCESS)
  1626. stComponentId.Empty();
  1627. }
  1628. // Check to see if it has the EnableForRas flag
  1629. // ----------------------------------------------------
  1630. dwErr = regkeyDevice.QueryValue(c_szEnableForRas, dwEnableRas);
  1631. // Default: assume that adapters are RAS-enabled
  1632. // ----------------------------------------------------
  1633. if (dwErr != ERROR_SUCCESS)
  1634. {
  1635. // Windows NT Bug : 292615
  1636. // If this is a parallel port, do not enable RAS
  1637. // by default.
  1638. // ------------------------------------------------
  1639. if (stComponentId.CompareNoCase(c_szPtiMiniPort) == 0)
  1640. dwEnableRas = 0;
  1641. else
  1642. dwEnableRas = 1;
  1643. }
  1644. // Check to see if it has the EnableForRouting flag
  1645. // ----------------------------------------------------
  1646. dwErr = regkeyDevice.QueryValue(c_szEnableForRouting,
  1647. dwEnableRouting);
  1648. // Default: assume that adapters are not routing-enabled
  1649. // ----------------------------------------------------
  1650. if (dwErr != ERROR_SUCCESS)
  1651. dwEnableRouting = 0;
  1652. // Need to check for the EnableForOutboundRouting subkey
  1653. // --------------------------------------------------------
  1654. dwErr = regkeyEnable.QueryValue(
  1655. c_szEnableForOutboundRouting, dwEnableOutboundRouting
  1656. );
  1657. // Default: assume that the adapters are not routing-enabled
  1658. // --------------------------------------------------------
  1659. if (dwErr != ERROR_SUCCESS)
  1660. dwEnableOutboundRouting = 0;
  1661. dwErr = regkeyDevice.QueryValue(c_szWanEndpoints, dwEndpoints);
  1662. // If there is no WanEndpoints key, then we assume
  1663. // that the device isn't RAS-capable
  1664. // ----------------------------------------------------
  1665. if (dwErr == ERROR_SUCCESS)
  1666. {
  1667. // Do allocation before adding the text to the UI
  1668. // ------------------------------------------------
  1669. pEntry = new PortsDeviceEntry;
  1670. pEntry->m_fModified = FALSE;
  1671. pEntry->m_dwEnableRas = dwEnableRas;
  1672. pEntry->m_dwEnableRouting = dwEnableRouting;
  1673. pEntry->m_dwEnableOutboundRouting =
  1674. dwEnableOutboundRouting;
  1675. pEntry->m_dwPorts = dwEndpoints;
  1676. // If this is PPTP, then set the eDeviceType flag
  1677. // ------------------------------------------------
  1678. if (stComponentId.CompareNoCase(c_szPPTPMiniPort) == 0)
  1679. pEntry->m_eDeviceType = RDT_Tunnel_Pptp;
  1680. else if (stComponentId.CompareNoCase(c_szL2TPMiniPort) == 0)
  1681. pEntry->m_eDeviceType = RDT_Tunnel_L2tp;
  1682. else if (stComponentId.CompareNoCase(c_szPPPoEMiniPort) == 0)
  1683. pEntry->m_eDeviceType = RDT_PPPoE;
  1684. else if (stComponentId.CompareNoCase(c_szPtiMiniPort) == 0)
  1685. pEntry->m_eDeviceType = RDT_Parallel;
  1686. else
  1687. pEntry->m_eDeviceType = (RASDEVICETYPE) RDT_Other;
  1688. // Save the old values
  1689. // ------------------------------------------------
  1690. pEntry->m_dwOldPorts = pEntry->m_dwPorts;
  1691. // Look for min and max values
  1692. // If the MinWanEndpoints and MaxWanEndpoints keys
  1693. // exist then this is writeable.
  1694. // ------------------------------------------------
  1695. dwErr = regkeyDevice.QueryValue(c_szMinWanEndpoints, dwT);
  1696. pEntry->m_dwMinPorts = dwT;
  1697. if (dwErr == ERROR_SUCCESS)
  1698. dwErr = regkeyDevice.QueryValue(c_szMaxWanEndpoints, dwT);
  1699. if (dwErr != ERROR_SUCCESS)
  1700. {
  1701. pEntry->m_fWriteable = FALSE;
  1702. pEntry->m_dwMinPorts = pEntry->m_dwPorts;
  1703. pEntry->m_dwMaxPorts = pEntry->m_dwPorts;
  1704. }
  1705. else
  1706. {
  1707. pEntry->m_fWriteable = TRUE;
  1708. pEntry->m_dwMaxPorts = dwT;
  1709. }
  1710. pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
  1711. //$PPTP
  1712. // For PPTP, we can change the m_dwMaxMaxPorts
  1713. // ------------------------------------------------
  1714. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  1715. {
  1716. pEntry->m_dwMaxMaxPorts = m_fRestrictDialin ?
  1717. MAX_ALLOWED_DIALIN :
  1718. PPTP_MAX_PORTS;
  1719. }
  1720. //$L2TP
  1721. // For L2TP, change the dwMaxMaxPorts
  1722. // ------------------------------------------------
  1723. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)
  1724. {
  1725. pEntry->m_dwMaxMaxPorts = m_fRestrictDialin ?
  1726. MAX_ALLOWED_DIALIN :
  1727. L2TP_MAX_PORTS;
  1728. }
  1729. //$PPPoE
  1730. // For PPPoE, we cannot change the number of endpoints
  1731. // ------------------------------------------------
  1732. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_PPPoE)
  1733. {
  1734. pEntry->m_fWriteable = FALSE;
  1735. }
  1736. // Verify current set of endpoints is within range
  1737. //-------------------------------------------------
  1738. if (pEntry->m_dwMaxPorts > pEntry->m_dwMaxMaxPorts)
  1739. {
  1740. pEntry->m_dwMaxPorts = pEntry->m_dwMaxMaxPorts;
  1741. }
  1742. if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)
  1743. {
  1744. pEntry->m_dwPorts = pEntry->m_dwMaxPorts;
  1745. }
  1746. // Add this device to the list
  1747. // ------------------------------------------------
  1748. regkeyDevice.QueryValue(c_szRegValDriverDesc, stDisplay);
  1749. pEntry->m_stDisplayName = stDisplay;
  1750. // Store the value so that we can use it to write
  1751. // ------------------------------------------------
  1752. pEntry->m_fRegistry = TRUE;
  1753. pEntry->m_hKey = regkeyDevice;
  1754. regkeyDevice.Detach();
  1755. pList->AddTail(pEntry);
  1756. pEntry = NULL;
  1757. }
  1758. }
  1759. stKey.Empty();
  1760. }
  1761. COM_PROTECT_ERROR_LABEL;
  1762. }
  1763. COM_PROTECT_CATCH;
  1764. if (FHrSucceeded(hr))
  1765. m_fReadFromRegistry = TRUE;
  1766. return hr;
  1767. }
  1768. /*!--------------------------------------------------------------------------
  1769. PortsDataEntry::LoadDevicesFromRouter
  1770. -
  1771. Author: KennT
  1772. ---------------------------------------------------------------------------*/
  1773. HRESULT PortsDataEntry::LoadDevicesFromRouter(PortsDeviceList *pList)
  1774. {
  1775. HRESULT hr = hrOK;
  1776. HANDLE hConnection = 0;
  1777. DWORD cDevices = 0;
  1778. DWORD cbData = 0;
  1779. BYTE * pbData = NULL;
  1780. RAS_DEVICE_INFO * pDevInfo = NULL;
  1781. PortsDeviceEntry * pEntry = NULL;
  1782. DWORD dwVersion;
  1783. UINT i;
  1784. DWORD dwErr;
  1785. WCHAR devName[MAX_DEVICE_NAME + 1];
  1786. USES_CONVERSION;
  1787. COM_PROTECT_TRY
  1788. {
  1789. // Connect to the server
  1790. CWRg( RasRpcConnectServer((LPTSTR) (LPCTSTR)m_stMachine, &hConnection) );
  1791. dwVersion = RasGetServerVersion(hConnection);
  1792. // Get the device information from the router
  1793. dwErr = RasGetDeviceConfigInfo(hConnection,
  1794. &dwVersion,
  1795. &cDevices,
  1796. &cbData,
  1797. NULL);
  1798. if (dwErr == ERROR_BUFFER_TOO_SMALL)
  1799. dwErr = ERROR_SUCCESS;
  1800. CWRg(dwErr);
  1801. pbData = (BYTE *) new char[cbData];
  1802. // Go out and actually grab the data
  1803. CWRg( RasGetDeviceConfigInfo(hConnection,
  1804. &dwVersion,
  1805. &cDevices,
  1806. &cbData,
  1807. pbData));
  1808. pDevInfo = (RAS_DEVICE_INFO *) pbData;
  1809. // If we found something and we don't understand the dev version,
  1810. // just punt.
  1811. if (cDevices && pDevInfo->dwVersion != 0 && pDevInfo->dwVersion != VERSION_501)
  1812. {
  1813. // We don't understand the version information
  1814. hr = E_FAIL;
  1815. goto Error;
  1816. }
  1817. if(dwVersion == VERSION_501)
  1818. {
  1819. for (i=0; i<cDevices; i++, pDevInfo++)
  1820. {
  1821. pEntry = new PortsDeviceEntry;
  1822. pEntry->m_fModified = FALSE;
  1823. pEntry->m_dwEnableRas = pDevInfo->fRasEnabled;
  1824. pEntry->m_dwEnableRouting = pDevInfo->fRouterEnabled;
  1825. pEntry->m_dwEnableOutboundRouting =
  1826. pDevInfo->fRouterOutboundEnabled;
  1827. pEntry->m_stDisplayName = pDevInfo->wszDeviceName;
  1828. pEntry->m_dwPorts = pDevInfo->dwNumEndPoints;
  1829. pEntry->m_eDeviceType = pDevInfo->eDeviceType;
  1830. // Save the old values
  1831. pEntry->m_dwOldPorts = pEntry->m_dwPorts;
  1832. pEntry->m_dwMinPorts = pDevInfo->dwMinWanEndPoints;
  1833. pEntry->m_dwMaxPorts = pDevInfo->dwMaxWanEndPoints;
  1834. pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
  1835. //$PPTP
  1836. // For PPTP, we can adjust the value of m_dwMaxPorts
  1837. // --------------------------------------------------------
  1838. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  1839. {
  1840. pEntry->m_dwMaxMaxPorts = m_fRestrictDialin ?
  1841. MAX_ALLOWED_DIALIN :
  1842. PPTP_MAX_PORTS;
  1843. }
  1844. //$L2TP
  1845. // For L2TP, we can adjust the value of m_dwMaxPorts
  1846. // --------------------------------------------------------
  1847. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)
  1848. {
  1849. pEntry->m_dwMaxMaxPorts = m_fRestrictDialin ?
  1850. MAX_ALLOWED_DIALIN :
  1851. L2TP_MAX_PORTS;
  1852. }
  1853. // Verify current set of endpoints is within range
  1854. //-------------------------------------------------
  1855. if (pEntry->m_dwMaxPorts > pEntry->m_dwMaxMaxPorts)
  1856. {
  1857. pEntry->m_dwMaxPorts = pEntry->m_dwMaxMaxPorts;
  1858. }
  1859. if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)
  1860. {
  1861. pEntry->m_dwPorts = pEntry->m_dwMaxPorts;
  1862. }
  1863. pEntry->m_fWriteable =
  1864. (pEntry->m_dwMinPorts != pEntry->m_dwMaxPorts) &&
  1865. (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) != RDT_PPPoE);
  1866. pEntry->m_fRegistry = FALSE;
  1867. pEntry->m_hKey = NULL;
  1868. // Make a copy of the data
  1869. pEntry->m_RasDeviceInfo = *pDevInfo;
  1870. pList->AddTail(pEntry);
  1871. pEntry = NULL;
  1872. }
  1873. }
  1874. else
  1875. {
  1876. RAS_DEVICE_INFO_V500 * pDevInfo500 = (RAS_DEVICE_INFO_V500 *)pbData;
  1877. for (i=0; i<cDevices; i++, pDevInfo500++)
  1878. {
  1879. pEntry = new PortsDeviceEntry;
  1880. pEntry->m_fModified = FALSE;
  1881. pEntry->m_dwEnableRas = pDevInfo500->fRasEnabled;
  1882. pEntry->m_dwEnableRouting = pDevInfo500->fRouterEnabled;
  1883. swprintf(devName, L"%S", pDevInfo500->szDeviceName);
  1884. pEntry->m_stDisplayName = devName;
  1885. pEntry->m_dwPorts = pDevInfo500->dwNumEndPoints;
  1886. pEntry->m_eDeviceType = pDevInfo500->eDeviceType;
  1887. // Save the old values
  1888. pEntry->m_dwOldPorts = pEntry->m_dwPorts;
  1889. pEntry->m_dwMinPorts = pDevInfo500->dwMinWanEndPoints;
  1890. pEntry->m_dwMaxPorts = pDevInfo500->dwMaxWanEndPoints;
  1891. pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
  1892. //$PPTP
  1893. // For PPTP, we can adjust the value of m_dwMaxPorts
  1894. // --------------------------------------------------------
  1895. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  1896. {
  1897. pEntry->m_dwMaxMaxPorts = PPTP_MAX_PORTS;
  1898. }
  1899. //$L2TP
  1900. // For L2TP, we can adjust the value of m_dwMaxPorts
  1901. // --------------------------------------------------------
  1902. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)
  1903. {
  1904. pEntry->m_dwMaxMaxPorts = L2TP_MAX_PORTS;
  1905. }
  1906. pEntry->m_fWriteable =
  1907. (pEntry->m_dwMinPorts != pEntry->m_dwMaxPorts) &&
  1908. (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) != RDT_PPPoE);
  1909. pEntry->m_fRegistry = FALSE;
  1910. pEntry->m_hKey = NULL;
  1911. // Make a copy of the data
  1912. // pEntry->m_RasDeviceInfo = *pDevInfo;
  1913. memcpy(&pEntry->m_RasDeviceInfo, pDevInfo500,
  1914. FIELD_OFFSET(RAS_DEVICE_INFO, fRouterOutboundEnabled));
  1915. memcpy(&pEntry->m_RasDeviceInfo.dwTapiLineId,
  1916. &pDevInfo500->dwTapiLineId,
  1917. sizeof(RAS_DEVICE_INFO)
  1918. - FIELD_OFFSET(RAS_DEVICE_INFO, dwTapiLineId));
  1919. pList->AddTail(pEntry);
  1920. pEntry = NULL;
  1921. }
  1922. }
  1923. COM_PROTECT_ERROR_LABEL;
  1924. }
  1925. COM_PROTECT_CATCH;
  1926. if (FHrSucceeded(hr))
  1927. m_fReadFromRegistry = FALSE;
  1928. // If the function didn't succeed, clean out the list
  1929. if (!FHrSucceeded(hr))
  1930. {
  1931. while (!pList->IsEmpty())
  1932. delete pList->RemoveHead();
  1933. }
  1934. delete [] pbData;
  1935. delete pEntry;
  1936. if (hConnection)
  1937. RasRpcDisconnectServer(hConnection);
  1938. return hr;
  1939. }
  1940. /*!--------------------------------------------------------------------------
  1941. PortsDataEntry::SaveDevices
  1942. -
  1943. Author: KennT
  1944. ---------------------------------------------------------------------------*/
  1945. HRESULT PortsDataEntry::SaveDevices(PortsDeviceList *pList)
  1946. {
  1947. HRESULT hr = hrOK;
  1948. CWaitCursor wait;
  1949. if (m_fReadFromRegistry)
  1950. hr = SaveDevicesToRegistry(pList);
  1951. else
  1952. hr = SaveDevicesToRouter(pList);
  1953. return hr;
  1954. }
  1955. /*!--------------------------------------------------------------------------
  1956. PortsDataEntry::SaveDevicesToRegistry
  1957. -
  1958. Author: KennT
  1959. ---------------------------------------------------------------------------*/
  1960. HRESULT PortsDataEntry::SaveDevicesToRegistry(PortsDeviceList *pList)
  1961. {
  1962. HRESULT hr = hrOK;
  1963. RegKey regkeyDevice;
  1964. RegKey regkeyPptpProtocol;
  1965. POSITION pos;
  1966. PortsDeviceEntry * pEntry = NULL;
  1967. DWORD dwErr;
  1968. Assert(pList);
  1969. // Write any changes made to the per-device configuration
  1970. // and write that back out to the registry
  1971. // ----------------------------------------------------------------
  1972. pos = pList->GetHeadPosition();
  1973. while (pos)
  1974. {
  1975. pEntry = pList->GetNext(pos);
  1976. if (pEntry->m_fModified)
  1977. {
  1978. Assert(pEntry->m_hKey);
  1979. regkeyDevice.Attach(pEntry->m_hKey);
  1980. COM_PROTECT_TRY
  1981. {
  1982. RegKey regkeyModem;
  1983. RegKey * pRegkeyDevice = NULL;
  1984. if (pEntry->m_fWriteable)
  1985. {
  1986. if (m_fRestrictDialin &&
  1987. (pEntry->m_dwPorts > MAX_ALLOWED_DIALIN))
  1988. {
  1989. pEntry->m_dwPorts = MAX_ALLOWED_DIALIN;
  1990. }
  1991. regkeyDevice.SetValue(c_szWanEndpoints,
  1992. pEntry->m_dwPorts);
  1993. //$PPTP
  1994. // We need to adjust the upper limit for the
  1995. // number of PPTP ports.
  1996. // ------------------------------------------------
  1997. if ((RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) &&
  1998. (pEntry->m_dwPorts > pEntry->m_dwMaxPorts))
  1999. {
  2000. DWORD dwPorts;
  2001. //$PPTP
  2002. // Keep the value of the number of PPTP ports
  2003. // below the max.
  2004. // --------------------------------------------
  2005. if (m_fRestrictDialin)
  2006. dwPorts = MAX_ALLOWED_DIALIN;
  2007. else
  2008. dwPorts = min(pEntry->m_dwPorts, PPTP_MAX_PORTS);
  2009. regkeyDevice.SetValue(c_szMaxWanEndpoints, dwPorts);
  2010. }
  2011. //$L2TP
  2012. // We need to adjust the upper limit for the
  2013. // number of L2TP ports.
  2014. // ------------------------------------------------
  2015. if ((RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp) &&
  2016. (pEntry->m_dwPorts > pEntry->m_dwMaxPorts))
  2017. {
  2018. DWORD dwPorts;
  2019. //$L2TP
  2020. // Keep the value of the number of L2TP ports
  2021. // below the max.
  2022. // --------------------------------------------
  2023. if (m_fRestrictDialin)
  2024. dwPorts = MAX_ALLOWED_DIALIN;
  2025. else
  2026. dwPorts = min(pEntry->m_dwPorts, L2TP_MAX_PORTS);
  2027. regkeyDevice.SetValue(c_szMaxWanEndpoints, dwPorts);
  2028. }
  2029. }
  2030. // Get the clients subkey (if for a modem)
  2031. // else use the device key
  2032. // ----------------------------------------------------
  2033. if (pEntry->m_eDeviceType == RDT_Modem)
  2034. {
  2035. dwErr = regkeyModem.Create(regkeyDevice, c_szClientsRasKey);
  2036. pRegkeyDevice = &regkeyModem;
  2037. }
  2038. else
  2039. {
  2040. pRegkeyDevice = &regkeyDevice;
  2041. dwErr = ERROR_SUCCESS;
  2042. }
  2043. if (dwErr == ERROR_SUCCESS)
  2044. {
  2045. pRegkeyDevice->SetValue(c_szEnableForRas,
  2046. pEntry->m_dwEnableRas);
  2047. pRegkeyDevice->SetValue(c_szEnableForRouting,
  2048. pEntry->m_dwEnableRouting);
  2049. pRegkeyDevice->SetValue(c_szEnableForOutboundRouting,
  2050. pEntry->m_dwEnableOutboundRouting);
  2051. }
  2052. }
  2053. COM_PROTECT_CATCH;
  2054. regkeyDevice.Detach();
  2055. // The NumberLineDevices is no longer used in NT5.
  2056. // if this is for PPTP, then we need to special case the
  2057. // code to set the PPTP number of devices
  2058. // --------------------------------------------------------
  2059. if (pEntry->m_fWriteable &&
  2060. pEntry->m_fModified &&
  2061. RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  2062. {
  2063. // Open the PPTP registry key
  2064. // ----------------------------------------------------
  2065. dwErr = regkeyPptpProtocol.Open(m_regkeyMachine,
  2066. c_szRegKeyPptpProtocolParam);
  2067. // set the NumberLineDevices registry value
  2068. // ----------------------------------------------------
  2069. if (dwErr == ERROR_SUCCESS)
  2070. regkeyPptpProtocol.SetValue(c_szRegValNumberLineDevices,
  2071. pEntry->m_dwPorts);
  2072. regkeyPptpProtocol.Close();
  2073. }
  2074. }
  2075. // Windows NT Bug: 136858 (add called id support)
  2076. // Save called id info
  2077. // ------------------------------------------------------------
  2078. if (pEntry->m_fSaveCalledIdInfo)
  2079. {
  2080. Assert(pEntry->m_fCalledIdInfoLoaded);
  2081. regkeyDevice.Attach(pEntry->m_hKey);
  2082. regkeyDevice.SetValueExplicit(c_szRegValCalledIdInformation,
  2083. REG_MULTI_SZ,
  2084. pEntry->m_pCalledIdInfo->dwSize,
  2085. (PBYTE) pEntry->m_pCalledIdInfo->bCalledId
  2086. );
  2087. regkeyDevice.Detach();
  2088. }
  2089. }
  2090. return hr;
  2091. }
  2092. /*!--------------------------------------------------------------------------
  2093. PortsDataEntry::SaveDevicesToRouter
  2094. -
  2095. Author: KennT
  2096. ---------------------------------------------------------------------------*/
  2097. HRESULT PortsDataEntry::SaveDevicesToRouter(PortsDeviceList *pList)
  2098. {
  2099. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2100. HRESULT hr = hrOK, hrTemp;
  2101. HANDLE hConnection = 0;
  2102. DWORD cDevices = 0;
  2103. BYTE * pbData = NULL;
  2104. RAS_DEVICE_INFO * pDevInfo = NULL;
  2105. PortsDeviceEntry * pEntry = NULL;
  2106. POSITION pos;
  2107. UINT i;
  2108. RAS_CALLEDID_INFO calledIdInfo;
  2109. DWORD dwErr = ERROR_SUCCESS;
  2110. TCHAR szErr[512];
  2111. DWORD dwVersion;
  2112. Assert(pList);
  2113. COM_PROTECT_TRY
  2114. {
  2115. // Connect to the server
  2116. // ------------------------------------------------------------
  2117. CWRg( RasRpcConnectServer((LPTSTR)(LPCTSTR)m_stMachine, &hConnection) );
  2118. dwVersion = RasGetServerVersion(hConnection);
  2119. // Allocate space for the data
  2120. // ------------------------------------------------------------
  2121. pbData = (BYTE *) new RAS_DEVICE_INFO[pList->GetCount()];
  2122. pDevInfo = (RAS_DEVICE_INFO *) pbData;
  2123. pos = pList->GetHeadPosition();
  2124. cDevices = pList->GetCount();
  2125. if(dwVersion == VERSION_501)
  2126. {
  2127. for (i=0; i<cDevices; i++, pDevInfo++)
  2128. {
  2129. Assert(pos);
  2130. pEntry = pList->GetNext(pos);
  2131. // Get the information needed to calculate the number
  2132. // of ports
  2133. // --------------------------------------------------------
  2134. *pDevInfo = pEntry->m_RasDeviceInfo;
  2135. pDevInfo->fWrite = TRUE;
  2136. pDevInfo->fRasEnabled = pEntry->m_dwEnableRas;
  2137. pDevInfo->fRouterEnabled = pEntry->m_dwEnableRouting;
  2138. pDevInfo->fRouterOutboundEnabled =
  2139. pEntry->m_dwEnableOutboundRouting;
  2140. if ((m_fRestrictDialin) &&
  2141. (pEntry->m_dwPorts > MAX_ALLOWED_DIALIN))
  2142. {
  2143. pEntry->m_dwPorts = MAX_ALLOWED_DIALIN;
  2144. }
  2145. pDevInfo->dwNumEndPoints = pEntry->m_dwPorts;
  2146. pDevInfo->dwMaxWanEndPoints = pEntry->m_dwMaxPorts;
  2147. // Windows NT Bug : 168364
  2148. // From RaoS, I also need to set the maximum incoming/outging
  2149. // --------------------------------------------------------
  2150. // Windows NT Bug : ?
  2151. // Use the defaults for now,
  2152. // This will get removed later.
  2153. // --------------------------------------------------------
  2154. pDevInfo->dwMaxInCalls = (-1);
  2155. pDevInfo->dwMaxOutCalls = 3;
  2156. // if this is for PPTP, then we need to special case the
  2157. // code to set the PPTP number of devices
  2158. // --------------------------------------------------------
  2159. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  2160. {
  2161. //$PPTP
  2162. // We need to adjust the upper limit for the
  2163. // number of PPTP ports.
  2164. // ------------------------------------------------
  2165. if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)
  2166. {
  2167. DWORD dwPorts;
  2168. //$PPTP
  2169. // Keep the value of the number of PPTP ports
  2170. // below the max.
  2171. // --------------------------------------------
  2172. if (m_fRestrictDialin)
  2173. dwPorts = MAX_ALLOWED_DIALIN;
  2174. else
  2175. dwPorts = min(pEntry->m_dwPorts, PPTP_MAX_PORTS);
  2176. pDevInfo->dwMaxWanEndPoints = dwPorts;
  2177. }
  2178. RegKey regkeyMachine;
  2179. RegKey regkeyPptpProtocol;
  2180. HKEY hkeyMachine;
  2181. // Connect to the machine
  2182. dwErr = ConnectRegistry(m_stMachine, &hkeyMachine);
  2183. regkeyMachine.Attach(hkeyMachine);
  2184. // Open the PPTP registry key
  2185. dwErr = regkeyPptpProtocol.Open(regkeyMachine,
  2186. c_szRegKeyPptpProtocolParam);
  2187. // set the NumberLineDevices registry value
  2188. if (dwErr == ERROR_SUCCESS)
  2189. regkeyPptpProtocol.SetValue(c_szRegValNumberLineDevices,
  2190. pEntry->m_dwPorts);
  2191. regkeyPptpProtocol.Close();
  2192. regkeyMachine.Close();
  2193. }
  2194. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)
  2195. {
  2196. //$L2TP
  2197. // We need to adjust the upper limit for the
  2198. // number of L2TP ports.
  2199. // ------------------------------------------------
  2200. if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)
  2201. {
  2202. DWORD dwPorts;
  2203. //$L2TP
  2204. // Keep the value of the number of L2TP ports
  2205. // below the max.
  2206. // --------------------------------------------
  2207. if (m_fRestrictDialin)
  2208. dwPorts = MAX_ALLOWED_DIALIN;
  2209. else
  2210. dwPorts = min(pEntry->m_dwPorts, L2TP_MAX_PORTS);
  2211. pDevInfo->dwMaxWanEndPoints = dwPorts;
  2212. }
  2213. }
  2214. // Windows NT Bug : 136858 (add called id support)
  2215. // Do we need to save the called id info?
  2216. // --------------------------------------------------------
  2217. if (pEntry->m_fSaveCalledIdInfo && pEntry->m_pCalledIdInfo)
  2218. {
  2219. Assert(pEntry->m_fCalledIdInfoLoaded);
  2220. //: if the call fails, what should we do? -- save it later
  2221. hrTemp = RasSetCalledIdInfo(hConnection,
  2222. pDevInfo,
  2223. pEntry->m_pCalledIdInfo,
  2224. TRUE);
  2225. // We've saved it, we don't need to save it again
  2226. // unless it changes.
  2227. // ----------------------------------------------------
  2228. if (FHrSucceeded(hrTemp))
  2229. pEntry->m_fSaveCalledIdInfo = FALSE;
  2230. }
  2231. }
  2232. dwErr = RasSetDeviceConfigInfo(hConnection,
  2233. cDevices,
  2234. sizeof(RAS_DEVICE_INFO)*cDevices,
  2235. pbData);
  2236. }
  2237. else
  2238. {
  2239. RAS_DEVICE_INFO_V500 *pDevInfo500 = (RAS_DEVICE_INFO_V500 *) pbData;
  2240. for (i=0; i<cDevices; i++, pDevInfo500++)
  2241. {
  2242. Assert(pos);
  2243. pEntry = pList->GetNext(pos);
  2244. // Get the information needed to calculate the number
  2245. // of ports
  2246. // --------------------------------------------------------
  2247. // *pDevInfo = pEntry->m_RasDeviceInfo;
  2248. memcpy(pDevInfo500, &pEntry->m_RasDeviceInfo,
  2249. FIELD_OFFSET(RAS_DEVICE_INFO, fRouterOutboundEnabled));
  2250. memcpy(&pDevInfo500->dwTapiLineId,
  2251. &pEntry->m_RasDeviceInfo.dwTapiLineId,
  2252. sizeof(RAS_DEVICE_INFO)
  2253. - FIELD_OFFSET(RAS_DEVICE_INFO, dwTapiLineId));
  2254. pDevInfo500->fWrite = TRUE;
  2255. pDevInfo500->fRasEnabled = pEntry->m_dwEnableRas;
  2256. pDevInfo500->fRouterEnabled = pEntry->m_dwEnableRouting;
  2257. pDevInfo500->dwNumEndPoints = pEntry->m_dwPorts;
  2258. pDevInfo500->dwMaxWanEndPoints = pEntry->m_dwMaxPorts;
  2259. // Windows NT Bug : 168364
  2260. // From RaoS, I also need to set the maximum incoming/outging
  2261. // --------------------------------------------------------
  2262. // Windows NT Bug : ?
  2263. // Use the defaults for now,
  2264. // This will get removed later.
  2265. // --------------------------------------------------------
  2266. pDevInfo500->dwMaxInCalls = (-1);
  2267. pDevInfo500->dwMaxOutCalls = 3;
  2268. // if this is for PPTP, then we need to special case the
  2269. // code to set the PPTP number of devices
  2270. // --------------------------------------------------------
  2271. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  2272. {
  2273. //$PPTP
  2274. // We need to adjust the upper limit for the
  2275. // number of PPTP ports.
  2276. // ------------------------------------------------
  2277. if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)
  2278. {
  2279. DWORD dwPorts;
  2280. //$PPTP
  2281. // Keep the value of the number of PPTP ports
  2282. // below the max.
  2283. // --------------------------------------------
  2284. dwPorts = min(pEntry->m_dwPorts, PPTP_MAX_PORTS);
  2285. pDevInfo500->dwMaxWanEndPoints = dwPorts;
  2286. }
  2287. RegKey regkeyMachine;
  2288. RegKey regkeyPptpProtocol;
  2289. HKEY hkeyMachine;
  2290. // Connect to the machine
  2291. dwErr = ConnectRegistry(m_stMachine, &hkeyMachine);
  2292. regkeyMachine.Attach(hkeyMachine);
  2293. // Open the PPTP registry key
  2294. dwErr = regkeyPptpProtocol.Open(regkeyMachine,
  2295. c_szRegKeyPptpProtocolParam);
  2296. // set the NumberLineDevices registry value
  2297. if (dwErr == ERROR_SUCCESS)
  2298. regkeyPptpProtocol.SetValue(c_szRegValNumberLineDevices,
  2299. pEntry->m_dwPorts);
  2300. regkeyPptpProtocol.Close();
  2301. regkeyMachine.Close();
  2302. }
  2303. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)
  2304. {
  2305. //$L2TP
  2306. // We need to adjust the upper limit for the
  2307. // number of L2TP ports.
  2308. // ------------------------------------------------
  2309. if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)
  2310. {
  2311. DWORD dwPorts;
  2312. //$L2TP
  2313. // Keep the value of the number of L2TP ports
  2314. // below the max.
  2315. // --------------------------------------------
  2316. dwPorts = min(pEntry->m_dwPorts, L2TP_MAX_PORTS);
  2317. pDevInfo500->dwMaxWanEndPoints = dwPorts;
  2318. }
  2319. }
  2320. // Windows NT Bug : 136858 (add called id support)
  2321. // Do we need to save the called id info?
  2322. // --------------------------------------------------------
  2323. if (pEntry->m_fSaveCalledIdInfo && pEntry->m_pCalledIdInfo)
  2324. {
  2325. Assert(pEntry->m_fCalledIdInfoLoaded);
  2326. //: if the call fails, what should we do? -- save it later
  2327. hrTemp = RasSetCalledIdInfo(hConnection,
  2328. (RAS_DEVICE_INFO *) pDevInfo500,
  2329. pEntry->m_pCalledIdInfo,
  2330. TRUE);
  2331. // We've saved it, we don't need to save it again
  2332. // unless it changes.
  2333. // ----------------------------------------------------
  2334. if (FHrSucceeded(hrTemp))
  2335. pEntry->m_fSaveCalledIdInfo = FALSE;
  2336. }
  2337. }
  2338. dwErr = RasSetDeviceConfigInfo(hConnection,
  2339. cDevices,
  2340. sizeof(RAS_DEVICE_INFO_V500)*cDevices,
  2341. pbData);
  2342. }
  2343. if (dwErr != ERROR_SUCCESS)
  2344. {
  2345. CString stErr;
  2346. CString stErrCode;
  2347. BOOL fErr = FALSE;
  2348. if(dwVersion == VERSION_501)
  2349. {
  2350. RAS_DEVICE_INFO * pDevice;
  2351. // Need to grab the error information out of the
  2352. // info struct an set the error strings.
  2353. // Could not save the information for the following
  2354. // devices
  2355. pDevice = (RAS_DEVICE_INFO *) pbData;
  2356. stErr.LoadString(IDS_ERR_SETDEVICECONFIGINFO_GEEK);
  2357. for (i=0; i<cDevices; i++, pDevice++)
  2358. {
  2359. if (pDevice->dwError)
  2360. {
  2361. CString stErrString;
  2362. FormatError(HRESULT_FROM_WIN32(pDevice->dwError),
  2363. szErr, DimensionOf(szErr));
  2364. stErrCode.Format(_T("%s (%08lx)"), szErr,
  2365. pDevice->dwError);
  2366. stErr += _T(" ");
  2367. stErr += pDevice->szDeviceName;
  2368. stErr += _T(" ");
  2369. stErr += stErrCode;
  2370. stErr += _T("\n");
  2371. fErr = TRUE;
  2372. }
  2373. }
  2374. }
  2375. else
  2376. {
  2377. RAS_DEVICE_INFO_V500 * pDevice;
  2378. // Need to grab the error information out of the
  2379. // info struct an set the error strings.
  2380. // Could not save the information for the following
  2381. // devices
  2382. pDevice = (RAS_DEVICE_INFO_V500 *) pbData;
  2383. stErr.LoadString(IDS_ERR_SETDEVICECONFIGINFO_GEEK);
  2384. for (i=0; i<cDevices; i++, pDevice++)
  2385. {
  2386. if (pDevice->dwError)
  2387. {
  2388. CString stErrString;
  2389. FormatError(HRESULT_FROM_WIN32(pDevice->dwError),
  2390. szErr, DimensionOf(szErr));
  2391. stErrCode.Format(_T("%s (%08lx)"), szErr,
  2392. pDevice->dwError);
  2393. stErr += _T(" ");
  2394. stErr += pDevice->szDeviceName;
  2395. stErr += _T(" ");
  2396. stErr += stErrCode;
  2397. stErr += _T("\n");
  2398. fErr = TRUE;
  2399. }
  2400. }
  2401. }
  2402. if (fErr)
  2403. AddGeekLevelErrorString(stErr);
  2404. CWRg(dwErr);
  2405. }
  2406. COM_PROTECT_ERROR_LABEL;
  2407. }
  2408. COM_PROTECT_CATCH;
  2409. delete [] pbData;
  2410. if (hConnection)
  2411. RasRpcDisconnectServer(hConnection);
  2412. return hr;
  2413. }
  2414. /*!--------------------------------------------------------------------------
  2415. IsMaxDialinPortsRestricted
  2416. -
  2417. Author: KennT
  2418. ---------------------------------------------------------------------------*/
  2419. HRESULT PortsDataEntry::CheckForDialinRestriction()
  2420. {
  2421. DWORD dwMajor, dwMinor, dwErr;
  2422. HRESULT hr = hrOK;
  2423. RegKey regkeyProduct;
  2424. CString stProductType, stSuite;
  2425. CStringList stlProductSuite;
  2426. COM_PROTECT_TRY
  2427. {
  2428. dwErr = GetNTVersion(m_regkeyMachine, &dwMajor, &dwMinor, NULL);
  2429. if ( (dwErr == NO_ERROR) &&
  2430. ( (dwMajor > 5) ||
  2431. ((dwMajor == 5) && (dwMinor > 1)) ) )
  2432. {
  2433. CWRg( regkeyProduct.Open(
  2434. m_regkeyMachine, c_szRegKeyProductOptions, KEY_READ
  2435. ));
  2436. CWRg( regkeyProduct.QueryValue(c_szRegValProductType, stProductType) );
  2437. if (stProductType.Compare(c_szServerNT) == 0)
  2438. {
  2439. //
  2440. // ok, this is a server box
  2441. //
  2442. CWRg( regkeyProduct.QueryValue(
  2443. c_szRegValProductSuite, stlProductSuite
  2444. ) );
  2445. POSITION pos = stlProductSuite.GetHeadPosition();
  2446. while( pos != NULL )
  2447. {
  2448. stSuite = stlProductSuite.GetNext(pos);
  2449. if(( stSuite.Compare(c_szEnterprise) == 0) ||
  2450. ( stSuite.Compare(c_szDataCenter) == 0) ||
  2451. ( stSuite.Compare(c_szSecurityAppliance) == 0 ))
  2452. {
  2453. //
  2454. // This is either a DataCenter or Enterprise version
  2455. //
  2456. m_fRestrictDialin = FALSE;
  2457. }
  2458. }
  2459. }
  2460. }
  2461. else
  2462. {
  2463. m_fRestrictDialin = FALSE;
  2464. }
  2465. COM_PROTECT_ERROR_LABEL;
  2466. }
  2467. COM_PROTECT_CATCH;
  2468. return hr;
  2469. }
  2470. /*---------------------------------------------------------------------------
  2471. PortsDeviceConfigDlg implementation
  2472. ---------------------------------------------------------------------------*/
  2473. BEGIN_MESSAGE_MAP(PortsDeviceConfigDlg, CBaseDialog)
  2474. //{{AFX_MSG_MAP(PortsPageGeneral)
  2475. //}}AFX_MSG_MAP
  2476. END_MESSAGE_MAP()
  2477. void PortsDeviceConfigDlg::DoDataExchange(CDataExchange *pDX)
  2478. {
  2479. CBaseDialog::DoDataExchange(pDX);
  2480. DDX_Control(pDX, IDC_DEVCFG_SPIN_PORTS, m_spinPorts);
  2481. }
  2482. void PortsDeviceConfigDlg::SetDevice(PortsDeviceEntry *pEntry, DWORD dwTotalActivePorts)
  2483. {
  2484. Assert(pEntry);
  2485. m_pEntry = pEntry;
  2486. m_dwTotalActivePorts = dwTotalActivePorts;
  2487. }
  2488. BOOL PortsDeviceConfigDlg::OnInitDialog()
  2489. {
  2490. HRESULT hr;
  2491. CString stCalledIdInfo;
  2492. CString stDisplay;
  2493. Assert(m_pEntry);
  2494. CBaseDialog::OnInitDialog();
  2495. if (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE)
  2496. {
  2497. CheckDlgButton(IDC_DEVCFG_BTN_RAS, FALSE);
  2498. GetDlgItem(IDC_DEVCFG_BTN_RAS)->EnableWindow(FALSE);
  2499. CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, FALSE);
  2500. GetDlgItem(IDC_DEVCFG_BTN_ROUTING)->EnableWindow(FALSE);
  2501. CheckDlgButton(
  2502. IDC_DEVCFG_BTN_OUTBOUND_ROUTING,
  2503. m_pEntry->m_dwEnableOutboundRouting
  2504. );
  2505. }
  2506. else
  2507. {
  2508. CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_pEntry->m_dwEnableRas);
  2509. CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_pEntry->m_dwEnableRouting);
  2510. CheckDlgButton(IDC_DEVCFG_BTN_OUTBOUND_ROUTING, FALSE);
  2511. GetDlgItem(IDC_DEVCFG_BTN_OUTBOUND_ROUTING)->EnableWindow(FALSE);
  2512. }
  2513. m_spinPorts.SetBuddy(GetDlgItem(IDC_DEVCFG_EDIT_PORTS));
  2514. m_spinPorts.SetRange(m_pEntry->m_dwMinPorts, m_pEntry->m_dwMaxMaxPorts);
  2515. m_spinPorts.SetPos(m_pEntry->m_dwPorts);
  2516. // If we can edit/change the number of ports, set it up here
  2517. // ----------------------------------------------------------------
  2518. if (!m_pEntry->m_fWriteable || (m_pEntry->m_dwMinPorts == m_pEntry->m_dwMaxPorts))
  2519. {
  2520. GetDlgItem(IDC_DEVCFG_SPIN_PORTS)->EnableWindow(FALSE);
  2521. GetDlgItem(IDC_DEVCFG_EDIT_PORTS)->EnableWindow(FALSE);
  2522. GetDlgItem(IDC_DEVCFG_TEXT_PORTS)->EnableWindow(FALSE);
  2523. GetDlgItem(IDC_DEVCFG_TEXT)->EnableWindow(FALSE);
  2524. }
  2525. // Windows NT Bug : 136858 - Get the called id info
  2526. // ----------------------------------------------------------------
  2527. LoadCalledIdInfo();
  2528. // Get the called id info, format it into a string and add it to
  2529. // the display
  2530. // ----------------------------------------------------------------
  2531. CalledIdInfoToString(&stCalledIdInfo);
  2532. GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->SetWindowText(stCalledIdInfo);
  2533. ((CEdit *)GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID))->SetModify(FALSE);
  2534. if ((RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Parallel) ||
  2535. (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE)){
  2536. GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->EnableWindow(FALSE);
  2537. GetDlgItem(IDC_DEVCFG_TEXT_CALLEDID)->EnableWindow(FALSE);
  2538. }
  2539. // Set the window title to include the display name of the adapter
  2540. // ----------------------------------------------------------------
  2541. stDisplay.Format(IDS_TITLE_CONFIGURE_PORTS,
  2542. (LPCTSTR) m_pEntry->m_stDisplayName);
  2543. SetWindowText(stDisplay);
  2544. return TRUE;
  2545. }
  2546. /*!--------------------------------------------------------------------------
  2547. PortsDeviceConfigDlg::OnOK
  2548. -
  2549. Author: KennT
  2550. ---------------------------------------------------------------------------*/
  2551. void PortsDeviceConfigDlg::OnOK()
  2552. {
  2553. BOOL fChanged = FALSE;
  2554. BOOL fReboot = FALSE;
  2555. DWORD dwNewEnableRas, dwNewEnableRouting,
  2556. dwNewEnableOutboundRouting, dwNewPorts;
  2557. // Check to see if the values changed
  2558. dwNewEnableRas = (IsDlgButtonChecked(IDC_DEVCFG_BTN_RAS) != 0);
  2559. dwNewEnableRouting = (IsDlgButtonChecked(IDC_DEVCFG_BTN_ROUTING) != 0);
  2560. dwNewEnableOutboundRouting =
  2561. (IsDlgButtonChecked(IDC_DEVCFG_BTN_OUTBOUND_ROUTING) != 0);
  2562. dwNewPorts = m_spinPorts.GetPos();
  2563. // Make sure that we have a valid size
  2564. // ----------------------------------------------------------------
  2565. if ((dwNewPorts < m_pEntry->m_dwMinPorts) ||
  2566. (dwNewPorts > m_pEntry->m_dwMaxMaxPorts))
  2567. {
  2568. CString st;
  2569. st.Format(IDS_ERR_PORTS_BOGUS_SIZE, m_pEntry->m_dwMinPorts,
  2570. m_pEntry->m_dwMaxMaxPorts);
  2571. AfxMessageBox(st);
  2572. return;
  2573. }
  2574. // Windows NT Bug : 174803
  2575. // We do not allow the user to change the number of PPTP ports down
  2576. // to 0.
  2577. // ----------------------------------------------------------------
  2578. if ((RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) &&
  2579. (dwNewPorts == 0))
  2580. {
  2581. AfxMessageBox(IDS_ERR_PPTP_PORTS_EQUAL_ZERO);
  2582. return;
  2583. }
  2584. // Windows NT Bugs : 165862
  2585. // If we are changing the number of ports for PPTP
  2586. // then we need to warn the user (since PPTP is not yet
  2587. // fully PnP (4/23/98).
  2588. //
  2589. //$PPTP
  2590. // For PPTP, if the value of m_dwPorts exceeds the value of
  2591. // m_dwMaxPorts, then we have to reboot (we also need to adjust
  2592. // the appropriate registry entries).
  2593. // ----------------------------------------------------------------
  2594. if ((dwNewPorts > m_pEntry->m_dwMaxPorts) &&
  2595. (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_Pptp))
  2596. {
  2597. // If we have a page, then we can do a reboot, otherwise we
  2598. // are in the wizard and can't do a reboot at this point.
  2599. // ------------------------------------------------------------
  2600. if (m_pageGeneral)
  2601. {
  2602. // The user chose Yes indicating that he wants to be prompted to
  2603. // reboot, so set this flag to trigger a reboot request.
  2604. // --------------------------------------------------------
  2605. if (AfxMessageBox(IDS_WRN_PPTP_NUMPORTS_CHANGING, MB_YESNO) == IDYES)
  2606. {
  2607. fReboot = TRUE;
  2608. }
  2609. }
  2610. else
  2611. AfxMessageBox(IDS_WRN_PPTP_NUMPORTS_CHANGING2, MB_OK);
  2612. }
  2613. //$L2TP
  2614. // For L2TP, if the value of m_dwPorts exceeds the value of
  2615. // m_dwMaxPorts, then we have to reboot (we also need to adjust
  2616. // the appropriate registry entries).
  2617. // ----------------------------------------------------------------
  2618. if ((dwNewPorts > m_pEntry->m_dwMaxPorts) &&
  2619. (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_L2tp))
  2620. {
  2621. // If we have a page, then we can do a reboot, otherwise we
  2622. // are in the wizard and can't do a reboot at this point.
  2623. // ------------------------------------------------------------
  2624. if (m_pageGeneral)
  2625. {
  2626. // The user chose Yes indicating that he wants to be prompted to
  2627. // reboot, so set this flag to trigger a reboot request.
  2628. // --------------------------------------------------------
  2629. if (AfxMessageBox(IDS_WRN_L2TP_NUMPORTS_CHANGING, MB_YESNO) == IDYES)
  2630. {
  2631. fReboot = TRUE;
  2632. }
  2633. }
  2634. else
  2635. AfxMessageBox(IDS_WRN_L2TP_NUMPORTS_CHANGING2, MB_OK);
  2636. }
  2637. if ((dwNewEnableRas != m_pEntry->m_dwEnableRas) ||
  2638. (dwNewEnableRouting != m_pEntry->m_dwEnableRouting) ||
  2639. (dwNewEnableOutboundRouting !=
  2640. m_pEntry->m_dwEnableOutboundRouting) ||
  2641. (dwNewPorts != m_pEntry->m_dwPorts))
  2642. {
  2643. // warning user -- client could be disconnected -- BUG 165862
  2644. // when disable router / ras
  2645. // decreasing the number of ports
  2646. // ras
  2647. if(!dwNewEnableRas &&
  2648. m_pEntry->m_dwEnableRas &&
  2649. m_dwTotalActivePorts > 0 &&
  2650. AfxMessageBox(IDS_WRN_PORTS_DISABLERAS, MB_YESNO | MB_DEFBUTTON2) == IDNO)
  2651. goto L_RESTORE;
  2652. // routing
  2653. if (((!dwNewEnableRouting &&
  2654. m_pEntry->m_dwEnableRouting) ||
  2655. (!dwNewEnableOutboundRouting &&
  2656. m_pEntry->m_dwEnableOutboundRouting)) &&
  2657. m_dwTotalActivePorts > 0 &&
  2658. AfxMessageBox(IDS_WRN_PORTS_DISABLEROUTING, MB_YESNO | MB_DEFBUTTON2) == IDNO)
  2659. goto L_RESTORE;
  2660. // Bug 263958
  2661. //ports -- We cannot count the number of outgoing connection remotely.
  2662. // Therefore if we reduce the number of port, give warning without counting total
  2663. // active connections.
  2664. if(dwNewPorts < m_pEntry->m_dwPorts &&
  2665. AfxMessageBox(IDS_WRN_PORTS_DECREASE, MB_YESNO | MB_DEFBUTTON2) == IDNO)
  2666. goto L_RESTORE;
  2667. m_pEntry->m_dwEnableRas = dwNewEnableRas;
  2668. m_pEntry->m_dwEnableRouting = dwNewEnableRouting;
  2669. m_pEntry->m_dwEnableOutboundRouting =
  2670. dwNewEnableOutboundRouting;
  2671. m_pEntry->m_dwPorts = dwNewPorts;
  2672. m_pEntry->m_fModified = TRUE;
  2673. }
  2674. // Get the called id info string (if the field changed)
  2675. // ----------------------------------------------------------------
  2676. if (((CEdit *) GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID))->GetModify())
  2677. {
  2678. CString st;
  2679. GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->GetWindowText(st);
  2680. StringToCalledIdInfo((LPCTSTR) st);
  2681. // Now set the changed state on the structure
  2682. // We need to save this data back to the registry
  2683. // ------------------------------------------------------------
  2684. m_pEntry->m_fSaveCalledIdInfo = TRUE;
  2685. }
  2686. CBaseDialog::OnOK();
  2687. if(fReboot == TRUE)
  2688. {
  2689. Assert(m_pageGeneral);
  2690. // force an OnApply to save data before shut down
  2691. // ------------------------------------------------------------
  2692. if (m_pageGeneral->OnApply()) {
  2693. WCHAR szComputer[MAX_COMPUTERNAME_LENGTH + 1];
  2694. DWORD dwLength = MAX_COMPUTERNAME_LENGTH;
  2695. GetComputerName(szComputer, &dwLength );
  2696. if (lstrcmpi(szComputer, (LPTSTR)m_pageGeneral->m_spRouter->GetMachineName()))
  2697. {
  2698. ::RestartComputer((LPTSTR)m_pageGeneral->m_spRouter->GetMachineName());
  2699. }
  2700. else
  2701. ::RestartComputer((LPTSTR)NULL);
  2702. }
  2703. }
  2704. return;
  2705. L_RESTORE:
  2706. if (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE)
  2707. {
  2708. CheckDlgButton(
  2709. IDC_DEVCFG_BTN_OUTBOUND_ROUTING,
  2710. m_pEntry->m_dwEnableOutboundRouting
  2711. );
  2712. }
  2713. else
  2714. {
  2715. CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_pEntry->m_dwEnableRas);
  2716. CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_pEntry->m_dwEnableRouting);
  2717. }
  2718. m_spinPorts.SetPos(m_pEntry->m_dwPorts);
  2719. return;
  2720. }
  2721. /*!--------------------------------------------------------------------------
  2722. PortsDeviceConfigDlg::LoadCalledIdInfo
  2723. -
  2724. Author: KennT
  2725. ---------------------------------------------------------------------------*/
  2726. HRESULT PortsDeviceConfigDlg::LoadCalledIdInfo()
  2727. {
  2728. HRESULT hr = hrOK;
  2729. if (!m_pEntry->m_fCalledIdInfoLoaded)
  2730. {
  2731. // Read the data from the registry
  2732. // ------------------------------------------------------------
  2733. if (m_pEntry->m_fRegistry)
  2734. {
  2735. DWORD dwType;
  2736. DWORD dwSize;
  2737. LPBYTE pbData = NULL;
  2738. DWORD dwErr;
  2739. RegKey regkeyDevice;
  2740. regkeyDevice.Attach(m_pEntry->m_hKey);
  2741. dwErr = regkeyDevice.QueryValueExplicit(c_szRegValCalledIdInformation,
  2742. &dwType,
  2743. &dwSize,
  2744. &pbData);
  2745. hr = HRESULT_FROM_WIN32(dwErr);
  2746. if ((dwErr == ERROR_SUCCESS) &&
  2747. (dwType == REG_MULTI_SZ))
  2748. {
  2749. // Allocate space for a new called id structure
  2750. // ----------------------------------------------------
  2751. delete (BYTE *) m_pEntry->m_pCalledIdInfo;
  2752. hr = AllocateCalledId(dwSize, &(m_pEntry->m_pCalledIdInfo));
  2753. if (FHrSucceeded(hr))
  2754. {
  2755. memcpy(m_pEntry->m_pCalledIdInfo->bCalledId,
  2756. pbData,
  2757. dwSize);
  2758. }
  2759. }
  2760. delete pbData;
  2761. regkeyDevice.Detach();
  2762. }
  2763. else
  2764. {
  2765. HANDLE hConnection = NULL;
  2766. DWORD dwSize = 0;
  2767. DWORD dwErr;
  2768. // use Rao's API
  2769. // Connect to the server
  2770. // --------------------------------------------------------
  2771. dwErr = RasRpcConnectServer((LPTSTR) (LPCTSTR)m_stMachine,
  2772. &hConnection);
  2773. // Call it once to get the size information
  2774. // --------------------------------------------------------
  2775. if (dwErr == ERROR_SUCCESS)
  2776. dwErr = RasGetCalledIdInfo(hConnection,
  2777. &m_pEntry->m_RasDeviceInfo,
  2778. &dwSize,
  2779. NULL);
  2780. hr = HRESULT_FROM_WIN32(dwErr);
  2781. if ((dwErr == ERROR_BUFFER_TOO_SMALL) ||
  2782. (dwErr == ERROR_SUCCESS))
  2783. {
  2784. // Allocate space for a new called id structure
  2785. // ----------------------------------------------------
  2786. delete (BYTE *) m_pEntry->m_pCalledIdInfo;
  2787. AllocateCalledId(dwSize, &(m_pEntry->m_pCalledIdInfo));
  2788. dwErr = RasGetCalledIdInfo(hConnection,
  2789. &m_pEntry->m_RasDeviceInfo,
  2790. &dwSize,
  2791. m_pEntry->m_pCalledIdInfo
  2792. );
  2793. hr = HRESULT_FROM_WIN32(dwErr);
  2794. }
  2795. if (hConnection)
  2796. RasRpcDisconnectServer(hConnection);
  2797. }
  2798. // Set the status flags, depending on whether the operation
  2799. // succeeded or not
  2800. // ------------------------------------------------------------
  2801. // We always set the save value to FALSE after we have read
  2802. // something in (or tried to read something in).
  2803. // ------------------------------------------------------------
  2804. m_pEntry->m_fSaveCalledIdInfo = FALSE;
  2805. // We always set the load value to TRUE (we have tried to load
  2806. // the information but it failed, for example the registry
  2807. // key may not exist).
  2808. // ------------------------------------------------------------
  2809. m_pEntry->m_fCalledIdInfoLoaded = TRUE;
  2810. if (!FHrSucceeded(hr))
  2811. {
  2812. delete m_pEntry->m_pCalledIdInfo;
  2813. m_pEntry->m_pCalledIdInfo = NULL;
  2814. }
  2815. }
  2816. //Error:
  2817. return hr;
  2818. }
  2819. /*!--------------------------------------------------------------------------
  2820. PortsDeviceConfigDlg::AllocateCalledId
  2821. -
  2822. Author: KennT
  2823. ---------------------------------------------------------------------------*/
  2824. HRESULT PortsDeviceConfigDlg::AllocateCalledId(DWORD dwSize,
  2825. RAS_CALLEDID_INFO **ppCalledId)
  2826. {
  2827. HRESULT hr = hrOK;
  2828. *ppCalledId = NULL;
  2829. COM_PROTECT_TRY
  2830. {
  2831. *ppCalledId =
  2832. (RAS_CALLEDID_INFO *) new BYTE[sizeof(RAS_CALLEDID_INFO) +
  2833. dwSize];
  2834. (*ppCalledId)->dwSize = dwSize;
  2835. }
  2836. COM_PROTECT_CATCH;
  2837. return hr;
  2838. }
  2839. /*!--------------------------------------------------------------------------
  2840. PortsDeviceConfigDlg::CalledIdInfoToString
  2841. Converts the data in the called id info structure into a
  2842. semi-colon separated string.
  2843. Author: KennT
  2844. ---------------------------------------------------------------------------*/
  2845. HRESULT PortsDeviceConfigDlg::CalledIdInfoToString(CString *pst)
  2846. {
  2847. WCHAR * pswz = NULL;
  2848. HRESULT hr = hrOK;
  2849. USES_CONVERSION;
  2850. Assert(pst);
  2851. Assert(m_pEntry);
  2852. COM_PROTECT_TRY
  2853. {
  2854. pst->Empty();
  2855. if (m_pEntry->m_pCalledIdInfo)
  2856. pswz = (WCHAR *) (m_pEntry->m_pCalledIdInfo->bCalledId);
  2857. if (pswz && *pswz)
  2858. {
  2859. *pst += W2T(pswz);
  2860. // Skip over the terminating NULL
  2861. // --------------------------------------------------------
  2862. pswz += StrLenW(pswz)+1;
  2863. while (*pswz)
  2864. {
  2865. *pst += _T("; ");
  2866. *pst += W2T(pswz);
  2867. // Skip over the terminating NULL
  2868. // --------------------------------------------------------
  2869. pswz += StrLenW(pswz)+1;
  2870. }
  2871. }
  2872. }
  2873. COM_PROTECT_CATCH;
  2874. if (!FHrSucceeded(hr))
  2875. pst->Empty();
  2876. return hr;
  2877. }
  2878. /*!--------------------------------------------------------------------------
  2879. PortsDeviceConfigDlg::StringToCalledIdInfo
  2880. -
  2881. Author: KennT
  2882. ---------------------------------------------------------------------------*/
  2883. HRESULT PortsDeviceConfigDlg::StringToCalledIdInfo(LPCTSTR psz)
  2884. {
  2885. DWORD cchSize;
  2886. WCHAR * pswzData = NULL;
  2887. WCHAR * pswzCurrent;
  2888. LPTSTR pszBufferStart = NULL;
  2889. LPTSTR pszBuffer = NULL;
  2890. RAS_CALLEDID_INFO * pCalledInfo = NULL;
  2891. HRESULT hr = hrOK;
  2892. CString stTemp;
  2893. // We need to parse the string (look for separators)
  2894. // ----------------------------------------------------------------
  2895. COM_PROTECT_TRY
  2896. {
  2897. // Allocate some space for the called id info (it's just as long
  2898. // as the string, maybe even somewhat smaller).
  2899. // Allocate twice the space so that we are sure of getting
  2900. // all of the NULL terminating characters
  2901. // ------------------------------------------------------------
  2902. pswzData = new WCHAR[2*(StrLen(psz)+1) + 1];
  2903. pswzCurrent = pswzData;
  2904. // Copy the string into a buffer
  2905. // ------------------------------------------------------------
  2906. pszBufferStart = StrDup(psz);
  2907. pszBuffer = pszBufferStart;
  2908. _tcstok(pszBuffer, _T(";"));
  2909. while (pszBuffer && *pszBuffer)
  2910. {
  2911. // Trim the string (get rid of whitespace, before and after).
  2912. // --------------------------------------------------------
  2913. stTemp = pszBuffer;
  2914. stTemp.TrimLeft();
  2915. stTemp.TrimRight();
  2916. if (!stTemp.IsEmpty())
  2917. {
  2918. StrCpyWFromT(pswzCurrent, (LPCTSTR) stTemp);
  2919. pswzCurrent += stTemp.GetLength()+1;
  2920. }
  2921. pszBuffer = _tcstok(NULL, _T(";"));
  2922. }
  2923. // Add extra terminating NULL character (so that it conforms
  2924. // to the REG_MULTI_SZ format).
  2925. // ------------------------------------------------------------
  2926. *pswzCurrent = 0;
  2927. cchSize = pswzCurrent - pswzData + 1;
  2928. // Allocate the real data structure
  2929. // Allocate and copy into a temporary so that in case
  2930. // of an exception, we don't lose the original data
  2931. // ------------------------------------------------------------
  2932. AllocateCalledId(cchSize*sizeof(WCHAR), &pCalledInfo);
  2933. memcpy(pCalledInfo->bCalledId,
  2934. pswzData,
  2935. cchSize*sizeof(WCHAR));
  2936. delete (BYTE *) m_pEntry->m_pCalledIdInfo;
  2937. m_pEntry->m_pCalledIdInfo = pCalledInfo;
  2938. // Set to NULL so that we don't delete our new pointer
  2939. // on exit.
  2940. // ------------------------------------------------------------
  2941. pCalledInfo = NULL;
  2942. }
  2943. COM_PROTECT_CATCH;
  2944. delete pszBufferStart;
  2945. delete pswzData;
  2946. delete pCalledInfo;
  2947. return hr;
  2948. }
  2949. /*---------------------------------------------------------------------------
  2950. PortsSimpleDeviceConfigDlg implementation
  2951. ---------------------------------------------------------------------------*/
  2952. BEGIN_MESSAGE_MAP(PortsSimpleDeviceConfigDlg, CBaseDialog)
  2953. //{{AFX_MSG_MAP(PortsPageGeneral)
  2954. //}}AFX_MSG_MAP
  2955. END_MESSAGE_MAP()
  2956. void PortsSimpleDeviceConfigDlg::DoDataExchange(CDataExchange *pDX)
  2957. {
  2958. CBaseDialog::DoDataExchange(pDX);
  2959. }
  2960. BOOL PortsSimpleDeviceConfigDlg::OnInitDialog()
  2961. {
  2962. HRESULT hr;
  2963. CBaseDialog::OnInitDialog();
  2964. // If we are using the BIG dialog, then we need to disable
  2965. // the unapplicable controls.
  2966. if (GetDlgItem(IDC_DEVCFG_TEXT_CALLEDID))
  2967. {
  2968. MultiEnableWindow(GetSafeHwnd(),
  2969. FALSE,
  2970. IDC_DEVCFG_TEXT_CALLEDID,
  2971. IDC_DEVCFG_EDIT_CALLEDID,
  2972. IDC_DEVCFG_TEXT_PORTS,
  2973. IDC_DEVCFG_EDIT_PORTS,
  2974. IDC_DEVCFG_SPIN_PORTS,
  2975. IDC_DEVCFG_TEXT,
  2976. 0);
  2977. }
  2978. CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_dwEnableRas);
  2979. CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_dwEnableRouting);
  2980. GetDlgItem(IDC_DEVCFG_BTN_OUTBOUND_ROUTING)->EnableWindow(FALSE);
  2981. return TRUE;
  2982. }
  2983. /*!--------------------------------------------------------------------------
  2984. PortsSimpleDeviceConfigDlg::OnOK
  2985. -
  2986. Author: KennT
  2987. ---------------------------------------------------------------------------*/
  2988. void PortsSimpleDeviceConfigDlg::OnOK()
  2989. {
  2990. // Check to see if the values changed
  2991. m_dwEnableRas = (IsDlgButtonChecked(IDC_DEVCFG_BTN_RAS) != 0);
  2992. m_dwEnableRouting = (IsDlgButtonChecked(IDC_DEVCFG_BTN_ROUTING) != 0);
  2993. CBaseDialog::OnOK();
  2994. return;
  2995. }
  2996. /*---------------------------------------------------------------------------
  2997. PortsDeviceEntry implementation
  2998. ---------------------------------------------------------------------------*/
  2999. PortsDeviceEntry::PortsDeviceEntry()
  3000. : m_hKey(NULL),
  3001. m_fRegistry(FALSE),
  3002. m_fSaveCalledIdInfo(FALSE),
  3003. m_fCalledIdInfoLoaded(FALSE),
  3004. m_pCalledIdInfo(NULL)
  3005. {
  3006. }
  3007. PortsDeviceEntry::~PortsDeviceEntry()
  3008. {
  3009. delete (BYTE *) m_pCalledIdInfo;
  3010. if (m_hKey)
  3011. DisconnectRegistry(m_hKey);
  3012. m_hKey = NULL;
  3013. }
  3014. BOOL
  3015. RestartComputer(LPTSTR szMachineName)
  3016. /* Called if user chooses to shut down the computer.
  3017. **
  3018. ** Return false if failure, true otherwise
  3019. */
  3020. {
  3021. HANDLE hToken; /* handle to process token */
  3022. TOKEN_PRIVILEGES tkp; /* ptr. to token structure */
  3023. BOOL fResult; /* system shutdown flag */
  3024. CString str;
  3025. TRACE(L"RestartComputer");
  3026. /* Enable the shutdown privilege */
  3027. if (!OpenProcessToken( GetCurrentProcess(),
  3028. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  3029. &hToken))
  3030. return FALSE;
  3031. /* Get the LUID for shutdown privilege. */
  3032. if (szMachineName)
  3033. LookupPrivilegeValue(NULL, SE_REMOTE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
  3034. else
  3035. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
  3036. tkp.PrivilegeCount = 1; /* one privilege to set */
  3037. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  3038. /* Get shutdown privilege for this process. */
  3039. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
  3040. /* Cannot test the return value of AdjustTokenPrivileges. */
  3041. if (GetLastError() != ERROR_SUCCESS)
  3042. return FALSE;
  3043. str.LoadString(IDS_SHUTDOWN_WARNING);
  3044. fResult = InitiateSystemShutdownEx(
  3045. szMachineName, // computer to shutdown
  3046. str.GetBuffer(10), // msg. to user
  3047. 20, // time out period - shut down right away
  3048. FALSE, // forcibly close open apps
  3049. TRUE, // Reboot after shutdown
  3050. SHTDN_REASON_FLAG_PLANNED |
  3051. SHTDN_REASON_MAJOR_OPERATINGSYSTEM |
  3052. SHTDN_REASON_MINOR_RECONFIG
  3053. );
  3054. str.ReleaseBuffer();
  3055. if (!fResult)
  3056. {
  3057. return FALSE;
  3058. }
  3059. if( !ExitWindowsEx(EWX_REBOOT, 0))
  3060. return FALSE;
  3061. /* Disable shutdown privilege. */
  3062. tkp.Privileges[0].Attributes = 0;
  3063. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
  3064. if (GetLastError() != ERROR_SUCCESS)
  3065. return FALSE;
  3066. return TRUE;
  3067. }
  3068. /*!--------------------------------------------------------------------------
  3069. OnConfigurePorts
  3070. Returns TRUE if something has changed. FALSE otherwise.
  3071. Author: KennT
  3072. ---------------------------------------------------------------------------*/
  3073. BOOL OnConfigurePorts(LPCTSTR pszMachineName,
  3074. DWORD dwTotalActivePorts,
  3075. PortsPageGeneral *pPage,
  3076. CListCtrlEx *pListCtrl)
  3077. {
  3078. BOOL fChanged = FALSE;
  3079. // Need to determine if multiple items are selected or not
  3080. if (pListCtrl->GetSelectedCount() == 1)
  3081. {
  3082. PortsDeviceConfigDlg configdlg(pPage, pszMachineName);
  3083. int iPos;
  3084. PortsDeviceEntry * pEntry;
  3085. CString st;
  3086. int iType;
  3087. TCHAR szNumber[32];
  3088. if ((iPos = pListCtrl->GetNextItem(-1, LVNI_SELECTED)) == -1)
  3089. return FALSE;
  3090. pEntry = (PortsDeviceEntry *) pListCtrl->GetItemData(iPos);
  3091. // total number of active ports are passed over to dialog, so if user tries to reduce total number of port
  3092. // below this total number, give a warning message
  3093. configdlg.SetDevice(pEntry, dwTotalActivePorts);
  3094. if (configdlg.DoModal() == IDOK)
  3095. {
  3096. // Get the values from pEntry and update the list control entry
  3097. iType = (pEntry->m_dwEnableRas * 2) +
  3098. (pEntry->m_dwEnableRouting ||
  3099. pEntry->m_dwEnableOutboundRouting);
  3100. st = PortsDeviceTypeToCString(iType);
  3101. pListCtrl->SetItemText(iPos, PORTS_COL_USAGE, (LPCTSTR) st);
  3102. FormatNumber(pEntry->m_dwPorts, szNumber,
  3103. DimensionOf(szNumber), FALSE);
  3104. pListCtrl->SetItemText(iPos, PORTS_COL_NUMBER, (LPCTSTR) szNumber);
  3105. fChanged = TRUE;
  3106. }
  3107. }
  3108. return fChanged;
  3109. }
  3110. /*---------------------------------------------------------------------------
  3111. RasmanPortMap implementation
  3112. ---------------------------------------------------------------------------*/
  3113. RasmanPortMap::~RasmanPortMap()
  3114. {
  3115. m_map.RemoveAll();
  3116. }
  3117. HRESULT RasmanPortMap::Init(HANDLE hRasHandle,
  3118. RASMAN_PORT *pPort,
  3119. DWORD dwPorts)
  3120. {
  3121. RASMAN_INFO rasmaninfo;
  3122. DWORD i;
  3123. DWORD dwErr = NO_ERROR;
  3124. HRESULT hr = hrOK;
  3125. if (pPort == NULL)
  3126. {
  3127. m_map.RemoveAll();
  3128. return hr;
  3129. }
  3130. for (i=0; i<dwPorts; i++, pPort++)
  3131. {
  3132. // If the port is closed, there is no need
  3133. // to go any further. (No need to do an RPC for this).
  3134. // ----------------------------------------------------
  3135. if (pPort->P_Status == CLOSED)
  3136. continue;
  3137. dwErr = RasGetInfo(hRasHandle,
  3138. pPort->P_Handle,
  3139. &rasmaninfo);
  3140. if (dwErr != ERROR_SUCCESS)
  3141. continue;
  3142. // If this is a dial-out port and in use
  3143. // mark it as active
  3144. // --------------------------------------------
  3145. if ((rasmaninfo.RI_ConnState == CONNECTED) &&
  3146. (pPort->P_ConfiguredUsage & (CALL_IN | CALL_ROUTER)) &&
  3147. (rasmaninfo.RI_CurrentUsage & CALL_OUT))
  3148. {
  3149. // Ok, this is a candidate. Add it to the list
  3150. // ----------------------------------------
  3151. WCHAR swzPortName[MAX_PORT_NAME+1];
  3152. StrnCpyWFromA(swzPortName,
  3153. pPort->P_PortName,
  3154. MAX_PORT_NAME);
  3155. m_map.SetAt(swzPortName, pPort);
  3156. }
  3157. }
  3158. return hr;
  3159. }
  3160. BOOL RasmanPortMap::FIsDialoutActive(LPCWSTR pswzPortName)
  3161. {
  3162. LPVOID pv;
  3163. return m_map.Lookup(pswzPortName, pv);
  3164. }