Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3515 lines
115 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. entry.m_fActiveDialOut = FALSE;
  629. // find out if ras / routing is enabled on the port
  630. entry.m_dwEnableRas = 0; // = 1 if RAS is enabled on this device
  631. entry.m_dwEnableRouting = 0; // = 1 if Routing is enabled on this device
  632. entry.m_dwEnableOutboundRouting = 0; // = 1 if outbound
  633. // routing is enabled
  634. // on this device
  635. POSITION pos;
  636. pos = portsDeviceList.GetHeadPosition();
  637. while(pos != NULL)
  638. {
  639. PortsDeviceEntry * pPortEntry = portsDeviceList.GetNext(pos);
  640. CString strPortName = entry.m_rp0.wszDeviceName;
  641. if(strPortName == pPortEntry->m_stDisplayName)
  642. {
  643. entry.m_dwEnableRas = pPortEntry->m_dwEnableRas;
  644. entry.m_dwEnableRouting = pPortEntry->m_dwEnableRouting;
  645. entry.m_dwEnableOutboundRouting =
  646. pPortEntry->m_dwEnableOutboundRouting;
  647. break;
  648. }
  649. }
  650. pList->AddTail(entry);
  651. }
  652. spMpr.Free();
  653. Error:
  654. delete [] pbPorts;
  655. if (hRasHandle != INVALID_HANDLE_VALUE)
  656. RasRpcDisconnectServer(hRasHandle);
  657. return hr;
  658. }
  659. ImplementEmbeddedUnknown(PortsNodeHandler, IRtrAdviseSink)
  660. STDMETHODIMP PortsNodeHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  661. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  662. {
  663. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  664. InitPThis(PortsNodeHandler, IRtrAdviseSink);
  665. SPITFSNode spThisNode;
  666. HRESULT hr = hrOK;
  667. COM_PROTECT_TRY
  668. {
  669. pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spThisNode);
  670. if (dwChangeType == ROUTER_REFRESH)
  671. {
  672. // Ok, just call the synchronize on this node
  673. pThis->SynchronizeNodeData(spThisNode);
  674. }
  675. else if (dwChangeType == ROUTER_DO_DISCONNECT)
  676. {
  677. PortsNodeData * pData = GET_PORTSNODEDATA(spThisNode);
  678. Assert(pData);
  679. // Release the handle
  680. pData->ReleaseHandles();
  681. }
  682. }
  683. COM_PROTECT_CATCH;
  684. return hr;
  685. }
  686. /*!--------------------------------------------------------------------------
  687. PortsNodeHandler::CompareItems
  688. Implementation of ITFSResultHandler::CompareItems
  689. Author: KennT
  690. ---------------------------------------------------------------------------*/
  691. STDMETHODIMP_(int) PortsNodeHandler::CompareItems(
  692. ITFSComponent * pComponent,
  693. MMC_COOKIE cookieA,
  694. MMC_COOKIE cookieB,
  695. int nCol)
  696. {
  697. // Get the strings from the nodes and use that as a basis for
  698. // comparison.
  699. SPITFSNode spNode;
  700. SPITFSResultHandler spResult;
  701. m_spNodeMgr->FindNode(cookieA, &spNode);
  702. spNode->GetResultHandler(&spResult);
  703. return spResult->CompareItems(pComponent, cookieA, cookieB, nCol);
  704. }
  705. /*!--------------------------------------------------------------------------
  706. PortsNodeHandler::AddPortsUserNode
  707. Adds a user to the UI. This will create a new result item
  708. node for each interface.
  709. Author: KennT
  710. ---------------------------------------------------------------------------*/
  711. HRESULT PortsNodeHandler::AddPortsUserNode(ITFSNode *pParent, const PortsListEntry& PortsEntry)
  712. {
  713. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  714. PortsUserHandler * pHandler;
  715. SPITFSResultHandler spHandler;
  716. SPITFSNode spNode;
  717. HRESULT hr = hrOK;
  718. pHandler = new PortsUserHandler(m_spTFSCompData);
  719. spHandler = pHandler;
  720. CORg( pHandler->Init(m_spRouterInfo, pParent) );
  721. CORg( CreateLeafTFSNode(&spNode,
  722. NULL,
  723. static_cast<ITFSNodeHandler *>(pHandler),
  724. static_cast<ITFSResultHandler *>(pHandler),
  725. m_spNodeMgr) );
  726. CORg( pHandler->ConstructNode(spNode, NULL, &PortsEntry) );
  727. SetUserData(spNode, PortsEntry);
  728. // Make the node immediately visible
  729. CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
  730. CORg( pParent->AddChild(spNode) );
  731. Error:
  732. return hr;
  733. }
  734. /*!--------------------------------------------------------------------------
  735. PortsNodeHandler::UnmarkAllNodes
  736. -
  737. Author: KennT
  738. ---------------------------------------------------------------------------*/
  739. HRESULT PortsNodeHandler::UnmarkAllNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
  740. {
  741. SPITFSNode spChildNode;
  742. InterfaceNodeData * pNodeData;
  743. pEnum->Reset();
  744. for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  745. {
  746. pNodeData = GET_INTERFACENODEDATA(spChildNode);
  747. Assert(pNodeData);
  748. pNodeData->dwMark = FALSE;
  749. }
  750. return hrOK;
  751. }
  752. /*!--------------------------------------------------------------------------
  753. PortsNodeHandler::RemoveAllUnmarkedNodes
  754. -
  755. Author: KennT
  756. ---------------------------------------------------------------------------*/
  757. HRESULT PortsNodeHandler::RemoveAllUnmarkedNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
  758. {
  759. HRESULT hr = hrOK;
  760. SPITFSNode spChildNode;
  761. InterfaceNodeData * pNodeData;
  762. pEnum->Reset();
  763. for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  764. {
  765. pNodeData = GET_INTERFACENODEDATA(spChildNode);
  766. Assert(pNodeData);
  767. if (pNodeData->dwMark == FALSE)
  768. {
  769. pNode->RemoveChild(spChildNode);
  770. spChildNode->Destroy();
  771. }
  772. }
  773. return hr;
  774. }
  775. /*---------------------------------------------------------------------------
  776. PortsUserHandler implementation
  777. ---------------------------------------------------------------------------*/
  778. DEBUG_DECLARE_INSTANCE_COUNTER(PortsUserHandler)
  779. IMPLEMENT_ADDREF_RELEASE(PortsUserHandler)
  780. STDMETHODIMP PortsUserHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  781. {
  782. // Is the pointer bad?
  783. if (ppv == NULL)
  784. return E_INVALIDARG;
  785. // Place NULL in *ppv in case of failure
  786. *ppv = NULL;
  787. // This is the non-delegating IUnknown implementation
  788. if (riid == IID_IUnknown)
  789. *ppv = (LPVOID) this;
  790. else if (riid == IID_IRtrAdviseSink)
  791. *ppv = &m_IRtrAdviseSink;
  792. else
  793. return CBaseResultHandler::QueryInterface(riid, ppv);
  794. // If we're going to return an interface, AddRef it first
  795. if (*ppv)
  796. {
  797. ((LPUNKNOWN) *ppv)->AddRef();
  798. return hrOK;
  799. }
  800. else
  801. return E_NOINTERFACE;
  802. }
  803. /*---------------------------------------------------------------------------
  804. NodeHandler implementation
  805. ---------------------------------------------------------------------------*/
  806. PortsUserHandler::PortsUserHandler(ITFSComponentData *pCompData)
  807. : BaseRouterHandler(pCompData),
  808. m_ulConnId(0)
  809. {
  810. DEBUG_INCREMENT_INSTANCE_COUNTER(PortsUserHandler);
  811. // Enable Refresh from the node itself
  812. // ----------------------------------------------------------------
  813. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  814. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  815. }
  816. /*!--------------------------------------------------------------------------
  817. PortsUserHandler::Init
  818. -
  819. Author: KennT
  820. ---------------------------------------------------------------------------*/
  821. HRESULT PortsUserHandler::Init(IRouterInfo *pInfo, ITFSNode *pParent)
  822. {
  823. m_spRouterInfo.Set(pInfo);
  824. return hrOK;
  825. }
  826. /*!--------------------------------------------------------------------------
  827. PortsUserHandler::DestroyResultHandler
  828. -
  829. Author: KennT
  830. ---------------------------------------------------------------------------*/
  831. STDMETHODIMP PortsUserHandler::DestroyResultHandler(MMC_COOKIE cookie)
  832. {
  833. SPITFSNode spNode;
  834. m_spNodeMgr->FindNode(cookie, &spNode);
  835. InterfaceNodeData::Free(spNode);
  836. CHandler::DestroyResultHandler(cookie);
  837. return hrOK;
  838. }
  839. static DWORD s_rgInterfaceImageMap[] =
  840. {
  841. ROUTER_IF_TYPE_HOME_ROUTER, IMAGE_IDX_WAN_CARD,
  842. ROUTER_IF_TYPE_FULL_ROUTER, IMAGE_IDX_WAN_CARD,
  843. ROUTER_IF_TYPE_CLIENT, IMAGE_IDX_WAN_CARD,
  844. ROUTER_IF_TYPE_DEDICATED, IMAGE_IDX_LAN_CARD,
  845. ROUTER_IF_TYPE_INTERNAL, IMAGE_IDX_LAN_CARD,
  846. ROUTER_IF_TYPE_LOOPBACK, IMAGE_IDX_LAN_CARD,
  847. -1, IMAGE_IDX_WAN_CARD, // sentinel value
  848. };
  849. /*!--------------------------------------------------------------------------
  850. PortsUserHandler::ConstructNode
  851. Initializes the Domain node (sets it up).
  852. Author: KennT
  853. ---------------------------------------------------------------------------*/
  854. HRESULT PortsUserHandler::ConstructNode(ITFSNode *pNode,
  855. IInterfaceInfo *pIfInfo,
  856. const PortsListEntry *pEntry)
  857. {
  858. HRESULT hr = hrOK;
  859. int i;
  860. InterfaceNodeData * pData;
  861. Assert(pEntry);
  862. if (pNode == NULL)
  863. return hrOK;
  864. COM_PROTECT_TRY
  865. {
  866. // Need to initialize the data for the Domain node
  867. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_WAN_CARD);
  868. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_WAN_CARD);
  869. pNode->SetData(TFS_DATA_SCOPEID, 0);
  870. pNode->SetData(TFS_DATA_COOKIE, reinterpret_cast<LONG_PTR>(pNode));
  871. //$ Review: kennt, what are the different type of interfaces
  872. // do we distinguish based on the same list as above? (i.e. the
  873. // one for image indexes).
  874. pNode->SetNodeType(&GUID_RouterPortsResultNodeType);
  875. m_entry = *pEntry;
  876. InterfaceNodeData::Init(pNode, pIfInfo);
  877. // We need to save this pointer so that it can be modified
  878. // (and updated) at a later time.
  879. // ------------------------------------------------------------
  880. pData = GET_INTERFACENODEDATA(pNode);
  881. pData->lParamPrivate = (LPARAM) &m_entry;
  882. }
  883. COM_PROTECT_CATCH
  884. return hr;
  885. }
  886. /*!--------------------------------------------------------------------------
  887. PortsUserHandler::GetString
  888. -
  889. Author: KennT
  890. ---------------------------------------------------------------------------*/
  891. STDMETHODIMP_(LPCTSTR) PortsUserHandler::GetString(ITFSComponent * pComponent,
  892. MMC_COOKIE cookie,
  893. int nCol)
  894. {
  895. Assert(m_spNodeMgr);
  896. SPITFSNode spNode;
  897. InterfaceNodeData * pData;
  898. ConfigStream * pConfig;
  899. m_spNodeMgr->FindNode(cookie, &spNode);
  900. Assert(spNode);
  901. pData = GET_INTERFACENODEDATA(spNode);
  902. Assert(pData);
  903. pComponent->GetUserData((LONG_PTR *) &pConfig);
  904. Assert(pConfig);
  905. return pData->m_rgData[pConfig->MapColumnToSubitem(DM_COLUMNS_PORTS, nCol)].m_stData;
  906. }
  907. /*!--------------------------------------------------------------------------
  908. PortsUserHandler::CompareItems
  909. -
  910. Author: KennT
  911. ---------------------------------------------------------------------------*/
  912. STDMETHODIMP_(int) PortsUserHandler::CompareItems(ITFSComponent * pComponent,
  913. MMC_COOKIE cookieA,
  914. MMC_COOKIE cookieB,
  915. int nCol)
  916. {
  917. return StriCmpW(GetString(pComponent, cookieA, nCol),
  918. GetString(pComponent, cookieB, nCol));
  919. }
  920. static const SRouterNodeMenu s_rgIfNodeMenu[] =
  921. {
  922. { IDS_MENU_PORTS_STATUS, 0,
  923. CCM_INSERTIONPOINTID_PRIMARY_TOP},
  924. { IDS_MENU_PORTS_DISCONNECT, PortsUserHandler::GetDisconnectMenuState,
  925. CCM_INSERTIONPOINTID_PRIMARY_TOP},
  926. };
  927. ULONG PortsUserHandler::GetDisconnectMenuState(const SRouterNodeMenu *pMenuData,
  928. INT_PTR pUserData)
  929. {
  930. InterfaceNodeData * pNodeData;
  931. SMenuData * pData = reinterpret_cast<SMenuData *>(pUserData);
  932. pNodeData = GET_INTERFACENODEDATA(pData->m_spNode);
  933. Assert(pNodeData);
  934. if (pNodeData->m_rgData[PORTS_SI_STATUS].m_dwData == RAS_PORT_AUTHENTICATED)
  935. return 0;
  936. else
  937. return MF_GRAYED;
  938. }
  939. /*!--------------------------------------------------------------------------
  940. PortsUserHandler::AddMenuItems
  941. Implementation of ITFSResultHandler::OnAddMenuItems
  942. Author: KennT
  943. ---------------------------------------------------------------------------*/
  944. STDMETHODIMP PortsUserHandler::AddMenuItems(ITFSComponent *pComponent,
  945. MMC_COOKIE cookie,
  946. LPDATAOBJECT lpDataObject,
  947. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  948. long *pInsertionAllowed)
  949. {
  950. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  951. HRESULT hr = S_OK;
  952. SPITFSNode spNode;
  953. PortsUserHandler::SMenuData menuData;
  954. // We don't allow any actions on active dialout connections
  955. // ------------------------------------------------------------
  956. if (m_entry.m_fActiveDialOut)
  957. return hrOK;
  958. COM_PROTECT_TRY
  959. {
  960. m_spNodeMgr->FindNode(cookie, &spNode);
  961. // Now go through and add our menu items
  962. menuData.m_spNode.Set(spNode);
  963. hr = AddArrayOfMenuItems(spNode, s_rgIfNodeMenu,
  964. DimensionOf(s_rgIfNodeMenu),
  965. pContextMenuCallback,
  966. *pInsertionAllowed,
  967. reinterpret_cast<INT_PTR>(&menuData));
  968. }
  969. COM_PROTECT_CATCH;
  970. return hr;
  971. }
  972. /*!--------------------------------------------------------------------------
  973. PortsUserHandler::Command
  974. -
  975. Author: KennT
  976. ---------------------------------------------------------------------------*/
  977. STDMETHODIMP PortsUserHandler::Command(ITFSComponent *pComponent,
  978. MMC_COOKIE cookie,
  979. int nCommandId,
  980. LPDATAOBJECT pDataObject)
  981. {
  982. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  983. SPITFSNode spNode;
  984. SPITFSNode spNodeParent;
  985. SPITFSNodeHandler spParentHandler;
  986. PortsNodeData * pData;
  987. HRESULT hr = S_OK;
  988. COM_PROTECT_TRY
  989. {
  990. switch (nCommandId)
  991. {
  992. case IDS_MENU_PORTS_STATUS:
  993. {
  994. BOOL fRefresh = FALSE;
  995. DWORD dwInterval = 60;
  996. SPIRouterRefresh spRefresh;
  997. if (m_spRouterInfo)
  998. m_spRouterInfo->GetRefreshObject(&spRefresh);
  999. // Stop the auto refresh (if it is turned on)
  1000. // ------------------------------------------------
  1001. if (spRefresh && FHrOK(spRefresh->IsRefreshStarted()))
  1002. {
  1003. fRefresh = TRUE;
  1004. spRefresh->GetRefreshInterval(&dwInterval);
  1005. spRefresh->Stop();
  1006. }
  1007. // NOTE: This function gets called from other places
  1008. // in the code (for which pDataObject==NULL)
  1009. // Get the hServer and hPort
  1010. m_spNodeMgr->FindNode(cookie, &spNode);
  1011. spNode->GetParent(&spNodeParent);
  1012. pData = GET_PORTSNODEDATA(spNodeParent);
  1013. CPortDlg portdlg((LPCTSTR) pData->m_stMachineName,
  1014. pData->GetHandle(),
  1015. m_entry.m_rp0.hPort,
  1016. spNodeParent
  1017. );
  1018. portdlg.DoModal();
  1019. // if (portdlg.m_bChanged)
  1020. RefreshInterface(cookie);
  1021. // Restart the refresh mechanism
  1022. // ------------------------------------------------
  1023. if (fRefresh && spRefresh)
  1024. {
  1025. spRefresh->SetRefreshInterval(dwInterval);
  1026. spRefresh->Start(dwInterval);
  1027. }
  1028. }
  1029. break;
  1030. case IDS_MENU_PORTS_DISCONNECT:
  1031. {
  1032. // Get the hServer and hPort
  1033. m_spNodeMgr->FindNode(cookie, &spNode);
  1034. spNode->GetParent(&spNodeParent);
  1035. pData = GET_PORTSNODEDATA(spNodeParent);
  1036. ::MprAdminPortDisconnect(
  1037. pData->GetHandle(),
  1038. m_entry.m_rp0.hPort);
  1039. RefreshInterface(cookie);
  1040. }
  1041. break;
  1042. default:
  1043. break;
  1044. };
  1045. }
  1046. COM_PROTECT_CATCH;
  1047. return hr;
  1048. }
  1049. ImplementEmbeddedUnknown(PortsUserHandler, IRtrAdviseSink)
  1050. STDMETHODIMP PortsUserHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  1051. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  1052. {
  1053. InitPThis(PortsUserHandler, IRtrAdviseSink);
  1054. HRESULT hr = hrOK;
  1055. return hr;
  1056. }
  1057. /*!--------------------------------------------------------------------------
  1058. PortsUserHandler::OnCreateDataObject
  1059. Implementation of ITFSResultHandler::OnCreateDataObject
  1060. Author: KennT
  1061. ---------------------------------------------------------------------------*/
  1062. STDMETHODIMP PortsUserHandler::OnCreateDataObject(ITFSComponent *pComp,
  1063. MMC_COOKIE cookie,
  1064. DATA_OBJECT_TYPES type,
  1065. IDataObject **ppDataObject)
  1066. {
  1067. HRESULT hr = hrOK;
  1068. COM_PROTECT_TRY
  1069. {
  1070. CORg( CreateDataObjectFromRouterInfo(m_spRouterInfo,
  1071. m_spRouterInfo->GetMachineName(),
  1072. type, cookie, m_spTFSCompData,
  1073. ppDataObject, NULL, FALSE) );
  1074. COM_PROTECT_ERROR_LABEL;
  1075. }
  1076. COM_PROTECT_CATCH;
  1077. return hr;
  1078. }
  1079. STDMETHODIMP PortsUserHandler::HasPropertyPages (
  1080. ITFSComponent *pComp,
  1081. MMC_COOKIE cookie,
  1082. LPDATAOBJECT pDataObject)
  1083. {
  1084. return hrFalse;
  1085. }
  1086. /*!--------------------------------------------------------------------------
  1087. PortsUserHandler::RefreshInterface
  1088. -
  1089. Author: KennT
  1090. ---------------------------------------------------------------------------*/
  1091. void PortsUserHandler::RefreshInterface(MMC_COOKIE cookie)
  1092. {
  1093. ForceGlobalRefresh(m_spRouterInfo);
  1094. }
  1095. /*!--------------------------------------------------------------------------
  1096. PortsUserHandler::OnResultItemClkOrDblClk
  1097. -
  1098. Author: KennT
  1099. ---------------------------------------------------------------------------*/
  1100. HRESULT PortsUserHandler::OnResultItemClkOrDblClk(ITFSComponent *pComponent,
  1101. MMC_COOKIE cookie,
  1102. LPARAM arg,
  1103. LPARAM lParam ,
  1104. BOOL bDoubleClick)
  1105. {
  1106. HRESULT hr = hrOK;
  1107. // We don't allow any actions on active dialout connections
  1108. // ------------------------------------------------------------
  1109. if (m_entry.m_fActiveDialOut)
  1110. return hrOK;
  1111. if (bDoubleClick)
  1112. {
  1113. // Bring up the status dialog on this port
  1114. CORg( Command(pComponent, cookie, IDS_MENU_PORTS_STATUS,
  1115. NULL) );
  1116. }
  1117. Error:
  1118. return hr;
  1119. }
  1120. /*---------------------------------------------------------------------------
  1121. PortsProperties implementation
  1122. ---------------------------------------------------------------------------*/
  1123. PortsProperties::PortsProperties(ITFSNode *pNode,
  1124. IComponentData *pComponentData,
  1125. ITFSComponentData *pTFSCompData,
  1126. LPCTSTR pszSheetName,
  1127. CWnd *pParent,
  1128. UINT iPage,
  1129. BOOL fScopePane)
  1130. : RtrPropertySheet(pNode, pComponentData, pTFSCompData,
  1131. pszSheetName, pParent, iPage, fScopePane),
  1132. m_pageGeneral(IDD_PORTS_GLOBAL_GENERAL),
  1133. m_pPortsNodeHandle(NULL),
  1134. m_dwThreadId(0)
  1135. {
  1136. }
  1137. PortsProperties::~PortsProperties()
  1138. {
  1139. if (m_dwThreadId)
  1140. DestroyTFSErrorInfoForThread(m_dwThreadId, 0);
  1141. if(m_pPortsNodeHandle)
  1142. {
  1143. m_pPortsNodeHandle->Release();
  1144. m_pPortsNodeHandle = NULL;
  1145. }
  1146. }
  1147. /*!--------------------------------------------------------------------------
  1148. PortsProperties::Init
  1149. Initialize the property sheets. The general action here will be
  1150. to initialize/add the various pages.
  1151. Author: KennT
  1152. ---------------------------------------------------------------------------*/
  1153. HRESULT PortsProperties::Init(IRouterInfo *pRouter, PortsNodeHandler* pPortsNodeHandle)
  1154. {
  1155. Assert(pRouter);
  1156. HRESULT hr = hrOK;
  1157. m_spRouter.Set(pRouter);
  1158. m_pPortsNodeHandle = pPortsNodeHandle;
  1159. if(m_pPortsNodeHandle) m_pPortsNodeHandle->AddRef();
  1160. // The pages are embedded members of the class
  1161. // do not delete them.
  1162. m_bAutoDeletePages = FALSE;
  1163. m_pageGeneral.Init(this, pRouter);
  1164. AddPageToList((CPropertyPageBase*) &m_pageGeneral);
  1165. //Error:
  1166. return hr;
  1167. }
  1168. /*!--------------------------------------------------------------------------
  1169. PortsProperties::SetThreadInfo
  1170. -
  1171. Author: KennT
  1172. ---------------------------------------------------------------------------*/
  1173. void PortsProperties::SetThreadInfo(DWORD dwThreadId)
  1174. {
  1175. m_dwThreadId = dwThreadId;
  1176. }
  1177. /*---------------------------------------------------------------------------
  1178. PortsPageGeneral
  1179. ---------------------------------------------------------------------------*/
  1180. BEGIN_MESSAGE_MAP(PortsPageGeneral, RtrPropertyPage)
  1181. //{{AFX_MSG_MAP(PortsPageGeneral)
  1182. ON_BN_CLICKED(IDC_PGG_BTN_CONFIGURE, OnConfigure)
  1183. ON_NOTIFY(NM_DBLCLK, IDC_PGG_LIST, OnListDblClk)
  1184. ON_NOTIFY(LVN_ITEMCHANGED, IDC_PGG_LIST, OnNotifyListItemChanged)
  1185. //}}AFX_MSG_MAP
  1186. END_MESSAGE_MAP()
  1187. PortsPageGeneral::~PortsPageGeneral()
  1188. {
  1189. while (!m_deviceList.IsEmpty())
  1190. delete m_deviceList.RemoveHead();
  1191. }
  1192. /*!--------------------------------------------------------------------------
  1193. PortsPageGeneral::Init
  1194. -
  1195. Author: KennT
  1196. ---------------------------------------------------------------------------*/
  1197. HRESULT PortsPageGeneral::Init(PortsProperties *pPropSheet, IRouterInfo *pRouter)
  1198. {
  1199. m_pPortsPropSheet = pPropSheet;
  1200. m_spRouter.Set(pRouter);
  1201. RouterVersionInfo routerVersion;
  1202. // Get the version info. Needed later on.
  1203. // ----------------------------------------------------------------
  1204. ASSERT(m_spRouter.p);
  1205. m_spRouter->GetRouterVersionInfo(&routerVersion);
  1206. m_bShowContent = (routerVersion.dwRouterVersion >= 5);
  1207. return hrOK;
  1208. }
  1209. /*!--------------------------------------------------------------------------
  1210. PortsPageGeneral::OnInitDialog
  1211. -
  1212. Author: KennT
  1213. ---------------------------------------------------------------------------*/
  1214. BOOL PortsPageGeneral::OnInitDialog()
  1215. {
  1216. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1217. HRESULT hr= hrOK;
  1218. int i;
  1219. CString st;
  1220. UINT cRows = 0;
  1221. PortsDeviceEntry * pEntry = NULL;
  1222. TCHAR szNumber[32];
  1223. HRESULT hrT;
  1224. RECT rc;
  1225. int nWidth, nUsageWidth;
  1226. int nListWidth;
  1227. POSITION pos;
  1228. INT iPos;
  1229. HKEY hkeyMachine = 0;
  1230. INT iType, idsType;
  1231. DWORD dwIn, dwOut;
  1232. // if focus on NT4 machine, not to display the content of the dialog, only display some text
  1233. // for the user that the snapin only shows property of NT5 server
  1234. if (!m_bShowContent)
  1235. {
  1236. CString st;
  1237. st.LoadString(IDS_ERR_NOPORTINFO_ON_NT4);
  1238. EnableChildControls(GetSafeHwnd(), PROPPAGE_CHILD_HIDE | PROPPAGE_CHILD_DISABLE);
  1239. GetDlgItem(IDC_PGG_TXT_NOINFO)->SetWindowText(st);
  1240. GetDlgItem(IDC_PGG_TXT_NOINFO)->ShowWindow(SW_SHOW);
  1241. GetDlgItem(IDC_PGG_TXT_NOINFO)->EnableWindow(TRUE);
  1242. return TRUE;
  1243. }
  1244. // hide the warning text if on NT5 servers
  1245. GetDlgItem(IDC_PGG_TXT_NOINFO)->ShowWindow(SW_HIDE);
  1246. COM_PROTECT_TRY
  1247. {
  1248. // This assumes that this page will always come up.
  1249. // Create the error info for this thread!
  1250. // ------------------------------------------------------------
  1251. CreateTFSErrorInfo(0);
  1252. m_pPortsPropSheet->SetThreadInfo(GetCurrentThreadId());
  1253. RtrPropertyPage::OnInitDialog();
  1254. ListView_SetExtendedListViewStyle(m_listCtrl.GetSafeHwnd(),
  1255. LVS_EX_FULLROWSELECT);
  1256. // Initialize the list control (with the list of devices)
  1257. // Determine optimal width for the header control
  1258. GetDlgItem(IDC_PGG_LIST)->GetWindowRect(&rc);
  1259. nListWidth = rc.right - rc.left;
  1260. // Figure out the size of Ras/Routing
  1261. st.LoadString(IDS_PORTSDLG_COL_RASROUTING);
  1262. st += _T("WW"); // add extra padding to get a little wider
  1263. nUsageWidth = m_listCtrl.GetStringWidth(st);
  1264. // Remove the Ras/Routing column from the rest of the width
  1265. nListWidth -= nUsageWidth;
  1266. // Remove four pixels off the end (for the borders?)
  1267. nListWidth -= 4;
  1268. // Split the width into fifths
  1269. nWidth = nListWidth / 5;
  1270. // Create the column headers.
  1271. // Column 0...Usage
  1272. st.LoadString(IDS_PORTSDLG_COL_USAGE);
  1273. m_listCtrl.InsertColumn(PORTS_COL_USAGE, st, LVCFMT_LEFT, nUsageWidth, 0);
  1274. // Column 1...Device
  1275. st.LoadString(IDS_PORTSDLG_COL_NAME);
  1276. m_listCtrl.InsertColumn(PORTS_COL_DEVICE, st, LVCFMT_LEFT, 3*nWidth, 0);
  1277. // Column 2...Type
  1278. st.LoadString(IDS_PORTSDLG_COL_TYPE);
  1279. m_listCtrl.InsertColumn(PORTS_COL_TYPE, st, LVCFMT_LEFT, nWidth, 0);
  1280. // Column 3...Number of Ports
  1281. st.LoadString(IDS_PORTSDLG_COL_NUM_PORTS);
  1282. m_listCtrl.InsertColumn(PORTS_COL_NUMBER, st, LVCFMT_LEFT, nWidth, 0);
  1283. // Query for the ports' data.
  1284. m_deviceDataEntry.Initialize(m_spRouter->GetMachineName());
  1285. m_deviceDataEntry.LoadDevices(&m_deviceList);
  1286. // Walk the list of ports and construct the row entry for the table
  1287. // for the given port.
  1288. pos = m_deviceList.GetHeadPosition();
  1289. while (pos)
  1290. {
  1291. pEntry = m_deviceList.GetNext(pos);
  1292. Assert(!::IsBadReadPtr(pEntry, sizeof(PortsDeviceEntry)));
  1293. // Column 1...Device
  1294. iPos = m_listCtrl.InsertItem(cRows, pEntry->m_stDisplayName);
  1295. m_listCtrl.SetItemText(iPos, PORTS_COL_DEVICE,
  1296. (LPCTSTR) pEntry->m_stDisplayName);
  1297. // Column 2...Type
  1298. st = PortTypeToCString(RAS_DEVICE_TYPE(pEntry->m_eDeviceType));
  1299. m_listCtrl.SetItemText(iPos, PORTS_COL_TYPE, (LPCTSTR) st);
  1300. // Column 3...Number of Ports
  1301. FormatNumber(pEntry->m_dwPorts, szNumber,
  1302. DimensionOf(szNumber), FALSE);
  1303. m_listCtrl.SetItemText(iPos, PORTS_COL_NUMBER, (LPCTSTR) szNumber);
  1304. m_listCtrl.SetItemData(iPos, (LONG_PTR) pEntry);
  1305. // Column 0...Usage
  1306. iType = (pEntry->m_dwEnableRas * 2) +
  1307. (pEntry->m_dwEnableRouting |
  1308. pEntry->m_dwEnableOutboundRouting);
  1309. st = PortsDeviceTypeToCString(iType);
  1310. m_listCtrl.SetItemText(iPos, PORTS_COL_USAGE, (LPCTSTR) st);
  1311. // How many rows now?
  1312. ++cRows; // preincrement faster operation on Pentium chips...
  1313. }
  1314. // As a default, disable the maximum ports dialog
  1315. GetDlgItem(IDC_PGG_BTN_CONFIGURE)->EnableWindow(FALSE);
  1316. if (cRows)
  1317. {
  1318. // Select the first entry in the list control
  1319. m_listCtrl.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
  1320. }
  1321. }
  1322. COM_PROTECT_CATCH;
  1323. SetDirty(FALSE);
  1324. if (!FHrSucceeded(hr))
  1325. {
  1326. delete pEntry;
  1327. Cancel();
  1328. }
  1329. return FHrSucceeded(hr) ? TRUE : FALSE;
  1330. }
  1331. /*!--------------------------------------------------------------------------
  1332. PortsPageGeneral::DoDataExchange
  1333. -
  1334. Author: KennT
  1335. ---------------------------------------------------------------------------*/
  1336. void PortsPageGeneral::DoDataExchange(CDataExchange *pDX)
  1337. {
  1338. if (!m_bShowContent) return;
  1339. RtrPropertyPage::DoDataExchange(pDX);
  1340. //{{AFX_DATA_MAP(PortsPageGeneral)
  1341. DDX_Control(pDX, IDC_PGG_LIST, m_listCtrl);
  1342. //}}AFX_DATA_MAP
  1343. }
  1344. /*!--------------------------------------------------------------------------
  1345. PortsPageGeneral::OnApply
  1346. -
  1347. Author: KennT
  1348. ---------------------------------------------------------------------------*/
  1349. BOOL PortsPageGeneral::OnApply()
  1350. {
  1351. if (!m_bShowContent) return TRUE;
  1352. if (m_pPortsPropSheet->IsCancel())
  1353. return TRUE;
  1354. if(!IsDirty())
  1355. return TRUE;
  1356. BOOL fReturn;
  1357. HRESULT hr = hrOK;
  1358. HRESULT hrT = hrOK;
  1359. DWORD dwErr, dwInValue, dwOutValue;
  1360. HKEY hkeyMachine;
  1361. RegKey regkeyMachine;
  1362. POSITION pos;
  1363. PortsDeviceEntry * pEntry;
  1364. // Create an error object (just in case)
  1365. CreateTFSErrorInfo(0);
  1366. ClearTFSErrorInfo(0);
  1367. CWRg( ConnectRegistry(m_spRouter->GetMachineName(), &hkeyMachine) );
  1368. regkeyMachine.Attach(hkeyMachine);
  1369. // We ignore the error code from the SaveDevices(). The reason
  1370. // is that for most of the failures, it's only a partial failure
  1371. // (especially for the RasSetDeviceConfigInfo() call.
  1372. hrT = m_deviceDataEntry.SaveDevices(&m_deviceList);
  1373. AddSystemErrorMessage(hrT);
  1374. Error:
  1375. if (!FHrSucceeded(hr) || !FHrSucceeded(hrT))
  1376. {
  1377. AddHighLevelErrorStringId(IDS_ERR_CANNOT_SAVE_PORTINFO);
  1378. DisplayTFSErrorMessage(NULL);
  1379. // Set focus back to the property sheet
  1380. BringWindowToTop();
  1381. // If the only thing that reports failure is hrT (or the
  1382. // SaveDevices() code), then we continue on.
  1383. if (FHrSucceeded(hr))
  1384. fReturn = RtrPropertyPage::OnApply();
  1385. else
  1386. fReturn = FALSE;
  1387. }
  1388. else
  1389. fReturn = RtrPropertyPage::OnApply();
  1390. // Windows NT Bug : 174916 - need to force a refresh through
  1391. ForceGlobalRefresh(m_spRouter);
  1392. return fReturn;
  1393. }
  1394. void PortsPageGeneral::OnListDblClk(NMHDR *pNMHdr, LRESULT *pResult)
  1395. {
  1396. OnConfigure();
  1397. *pResult = 0;
  1398. }
  1399. /*!--------------------------------------------------------------------------
  1400. PortsPageGeneral::OnNotifyListItemChanged
  1401. -
  1402. Author: KennT
  1403. ---------------------------------------------------------------------------*/
  1404. void PortsPageGeneral::OnNotifyListItemChanged(NMHDR *pNmHdr, LRESULT *pResult)
  1405. {
  1406. // NMLISTVIEW * pnmlv = reinterpret_cast<NMLISTVIEW *>(pNmHdr);
  1407. // BOOL fEnable = !!(pnmlv->uNewState & LVIS_SELECTED);
  1408. BOOL fEnable = (m_listCtrl.GetSelectedCount() != 0);
  1409. GetDlgItem(IDC_PGG_BTN_CONFIGURE)->EnableWindow(fEnable);
  1410. *pResult = 0;
  1411. }
  1412. /*!--------------------------------------------------------------------------
  1413. PortsPageGeneral::OnConfigure
  1414. -
  1415. Author: KennT
  1416. ---------------------------------------------------------------------------*/
  1417. void PortsPageGeneral::OnConfigure()
  1418. {
  1419. // Windows NT Bug : 322955
  1420. // Always mark the page dirty. This is needed because the OnOK()
  1421. // will call OnApply() on the property sheet before the dialog is
  1422. // exited. This is called to force the changes to save back before
  1423. // the restart is called.
  1424. // ----------------------------------------------------------------
  1425. SetDirty(TRUE);
  1426. SetModified();
  1427. OnConfigurePorts(m_spRouter->GetMachineName(),
  1428. m_pPortsPropSheet->m_pPortsNodeHandle->GetActivePorts(),
  1429. this,
  1430. &m_listCtrl);
  1431. }
  1432. /*---------------------------------------------------------------------------
  1433. PortsDataEntry implementation
  1434. ---------------------------------------------------------------------------*/
  1435. PortsDataEntry::PortsDataEntry()
  1436. {
  1437. m_fReadFromRegistry = TRUE;
  1438. }
  1439. PortsDataEntry::~PortsDataEntry()
  1440. {
  1441. }
  1442. /*!--------------------------------------------------------------------------
  1443. PortsDataEntry::Initialize
  1444. -
  1445. Author: KennT
  1446. ---------------------------------------------------------------------------*/
  1447. HRESULT PortsDataEntry::Initialize(LPCTSTR pszMachineName)
  1448. {
  1449. HRESULT hr = hrOK;
  1450. m_regkeyMachine.Close();
  1451. m_stMachine = pszMachineName;
  1452. return hr;
  1453. }
  1454. /*!--------------------------------------------------------------------------
  1455. PortsDataEntry::LoadDevices
  1456. -
  1457. Author: KennT
  1458. ---------------------------------------------------------------------------*/
  1459. HRESULT PortsDataEntry::LoadDevices(PortsDeviceList *pList)
  1460. {
  1461. HRESULT hr = hrOK;
  1462. POSITION pos;
  1463. PortsDeviceEntry * pEntry;
  1464. // Try to load the devices from the router (actually rasman),
  1465. // if that fails then try the registry
  1466. hr = LoadDevicesFromRouter(pList);
  1467. if (!FHrSucceeded(hr))
  1468. hr = LoadDevicesFromRegistry(pList);
  1469. return hr;
  1470. }
  1471. /*!--------------------------------------------------------------------------
  1472. PortsDataEntry::LoadDevicesFromRegistry
  1473. -
  1474. Author: KennT
  1475. ---------------------------------------------------------------------------*/
  1476. HRESULT PortsDataEntry::LoadDevicesFromRegistry(PortsDeviceList *pList)
  1477. {
  1478. HRESULT hr = hrOK;
  1479. RegKey regkey;
  1480. RegKey regkeyDevice;
  1481. RegKey regkeyEnable;
  1482. RegKeyIterator regkeyIter;
  1483. HRESULT hrIter;
  1484. HKEY hkeyMachine;
  1485. CString stKey;
  1486. CString st;
  1487. CString stFullText;
  1488. CString stComponentId;
  1489. DWORD dwEnableRas;
  1490. DWORD dwEnableRouting;
  1491. DWORD dwEnableOutboundRouting;
  1492. DWORD dwT;
  1493. DWORD dwErr;
  1494. PortsDeviceEntry * pEntry;
  1495. COM_PROTECT_TRY
  1496. {
  1497. // Connect to the machine
  1498. // ------------------------------------------------------------
  1499. if (m_regkeyMachine == NULL)
  1500. {
  1501. CWRg( ConnectRegistry(m_stMachine, &hkeyMachine) );
  1502. m_regkeyMachine.Attach(hkeyMachine);
  1503. }
  1504. // Get the list of devices
  1505. // ------------------------------------------------------------
  1506. // Open HKLM\System\CurrentControlSet\Control\Class\<Modem GUID>
  1507. // ------------------------------------------------------------
  1508. CWRg( regkey.Open(m_regkeyMachine, c_szModemKey, KEY_READ) );
  1509. // Enumerate through the list of modems
  1510. // ------------------------------------------------------------
  1511. CORg( regkeyIter.Init(&regkey) );
  1512. for (hrIter = regkeyIter.Next(&stKey); hrIter == hrOK; stKey.Empty(), hrIter = regkeyIter.Next(&stKey))
  1513. {
  1514. // Cleanup from the previous loop
  1515. // --------------------------------------------------------
  1516. regkeyDevice.Close();
  1517. regkeyEnable.Close();
  1518. // Open the key
  1519. // --------------------------------------------------------
  1520. dwErr = regkeyDevice.Open(regkey, stKey, KEY_READ | KEY_WRITE);
  1521. if (dwErr != ERROR_SUCCESS)
  1522. continue;
  1523. // Need to check for the EnableForRas subkey
  1524. // --------------------------------------------------------
  1525. dwErr = regkeyEnable.Open(regkeyDevice, c_szClientsRasKey, KEY_READ);
  1526. if (dwErr == ERROR_SUCCESS)
  1527. {
  1528. dwErr = regkeyEnable.QueryValue(c_szEnableForRas, dwEnableRas);
  1529. }
  1530. // Default: assume that the modems are RAS-enabled
  1531. // --------------------------------------------------------
  1532. if (dwErr != ERROR_SUCCESS)
  1533. dwEnableRas = 1;
  1534. // Need to check for the EnableForRouting subkey
  1535. // --------------------------------------------------------
  1536. dwErr = regkeyEnable.QueryValue(c_szEnableForRouting, dwEnableRouting);
  1537. // Default: assume that the modems are not routing-enabled
  1538. // --------------------------------------------------------
  1539. if (dwErr != ERROR_SUCCESS)
  1540. dwEnableRouting = 0;
  1541. // Need to check for the EnableForOutboundRouting subkey
  1542. // --------------------------------------------------------
  1543. dwErr = regkeyEnable.QueryValue(
  1544. c_szEnableForOutboundRouting, dwEnableOutboundRouting
  1545. );
  1546. // Default: assume that the modems are not routing-enabled
  1547. // --------------------------------------------------------
  1548. if (dwErr != ERROR_SUCCESS)
  1549. dwEnableOutboundRouting = 0;
  1550. CString stDisplay;
  1551. // Do allocation before adding the text to the UI
  1552. // --------------------------------------------------------
  1553. pEntry = new PortsDeviceEntry;
  1554. pEntry->m_fModified = FALSE;
  1555. pEntry->m_dwPorts = 1;
  1556. pEntry->m_fWriteable = FALSE; // # of ports can't be changed
  1557. pEntry->m_dwMinPorts = pEntry->m_dwPorts;
  1558. pEntry->m_dwMaxPorts = pEntry->m_dwPorts;
  1559. pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
  1560. pEntry->m_dwEnableRas = dwEnableRas;
  1561. pEntry->m_dwEnableRouting = dwEnableRouting;
  1562. pEntry->m_dwEnableOutboundRouting = dwEnableOutboundRouting;
  1563. pEntry->m_eDeviceType = RDT_Modem;
  1564. // Save the old values
  1565. // --------------------------------------------------------
  1566. pEntry->m_dwOldPorts = pEntry->m_dwPorts;
  1567. // Add this modem to the list
  1568. // --------------------------------------------------------
  1569. regkeyDevice.QueryValue(c_szFriendlyName, stFullText);
  1570. regkeyDevice.QueryValue(c_szAttachedTo, st);
  1571. stDisplay.Format(IDS_PORTS_NAME_FORMAT, stFullText, st);
  1572. pEntry->m_stDisplayName = stDisplay;
  1573. // Read in all data from the registry key BEFORE here
  1574. // --------------------------------------------------------
  1575. pEntry->m_fRegistry = TRUE;
  1576. pEntry->m_hKey = regkeyDevice;
  1577. regkeyDevice.Detach();
  1578. pList->AddTail(pEntry);
  1579. pEntry = NULL;
  1580. }
  1581. // Enumerate through the list of adapters that have the EnableForRas flag
  1582. // Open HKLM\System\CurrentControlSet\Control\Class\GUID_DEVCLASS_NET
  1583. // ------------------------------------------------------------
  1584. regkey.Close();
  1585. CWRg( regkey.Open(m_regkeyMachine, c_szRegKeyGUID_DEVCLASS_NET, KEY_READ | KEY_WRITE) );
  1586. // Enumerate through the list of adapters
  1587. // ------------------------------------------------------------
  1588. CORg( regkeyIter.Init(&regkey) );
  1589. stKey.Empty();
  1590. for (hrIter = regkeyIter.Next(&stKey); hrIter == hrOK; hrIter = regkeyIter.Next(&stKey))
  1591. {
  1592. // Cleanup from the previous loop
  1593. // --------------------------------------------------------
  1594. regkeyDevice.Close();
  1595. // Open the key
  1596. // --------------------------------------------------------
  1597. dwErr = regkeyDevice.Open(regkey, stKey, KEY_READ | KEY_WRITE);
  1598. if (dwErr == ERROR_SUCCESS)
  1599. {
  1600. CString stDisplay;
  1601. DWORD dwEndpoints;
  1602. // Need to get the ComponentId to check for PPTP/PTI
  1603. // ------------------------------------------------
  1604. dwErr = regkeyDevice.QueryValue(c_szRegValMatchingDeviceId,
  1605. stComponentId);
  1606. if (dwErr != ERROR_SUCCESS)
  1607. {
  1608. dwErr = regkeyDevice.QueryValue(c_szRegValComponentId,
  1609. stComponentId);
  1610. if (dwErr != ERROR_SUCCESS)
  1611. stComponentId.Empty();
  1612. }
  1613. // Check to see if it has the EnableForRas flag
  1614. // ----------------------------------------------------
  1615. dwErr = regkeyDevice.QueryValue(c_szEnableForRas, dwEnableRas);
  1616. // Default: assume that adapters are RAS-enabled
  1617. // ----------------------------------------------------
  1618. if (dwErr != ERROR_SUCCESS)
  1619. {
  1620. // Windows NT Bug : 292615
  1621. // If this is a parallel port, do not enable RAS
  1622. // by default.
  1623. // ------------------------------------------------
  1624. if (stComponentId.CompareNoCase(c_szPtiMiniPort) == 0)
  1625. dwEnableRas = 0;
  1626. else
  1627. dwEnableRas = 1;
  1628. }
  1629. // Check to see if it has the EnableForRouting flag
  1630. // ----------------------------------------------------
  1631. dwErr = regkeyDevice.QueryValue(c_szEnableForRouting,
  1632. dwEnableRouting);
  1633. // Default: assume that adapters are not routing-enabled
  1634. // ----------------------------------------------------
  1635. if (dwErr != ERROR_SUCCESS)
  1636. dwEnableRouting = 0;
  1637. // Need to check for the EnableForOutboundRouting subkey
  1638. // --------------------------------------------------------
  1639. dwErr = regkeyEnable.QueryValue(
  1640. c_szEnableForOutboundRouting, dwEnableOutboundRouting
  1641. );
  1642. // Default: assume that the adapters are not routing-enabled
  1643. // --------------------------------------------------------
  1644. if (dwErr != ERROR_SUCCESS)
  1645. dwEnableOutboundRouting = 0;
  1646. dwErr = regkeyDevice.QueryValue(c_szWanEndpoints, dwEndpoints);
  1647. // If there is no WanEndpoints key, then we assume
  1648. // that the device isn't RAS-capable
  1649. // ----------------------------------------------------
  1650. if (dwErr == ERROR_SUCCESS)
  1651. {
  1652. // Do allocation before adding the text to the UI
  1653. // ------------------------------------------------
  1654. pEntry = new PortsDeviceEntry;
  1655. pEntry->m_fModified = FALSE;
  1656. pEntry->m_dwEnableRas = dwEnableRas;
  1657. pEntry->m_dwEnableRouting = dwEnableRouting;
  1658. pEntry->m_dwEnableOutboundRouting =
  1659. dwEnableOutboundRouting;
  1660. pEntry->m_dwPorts = dwEndpoints;
  1661. // If this is PPTP, then set the eDeviceType flag
  1662. // ------------------------------------------------
  1663. if (stComponentId.CompareNoCase(c_szPPTPMiniPort) == 0)
  1664. pEntry->m_eDeviceType = RDT_Tunnel_Pptp;
  1665. else if (stComponentId.CompareNoCase(c_szL2TPMiniPort) == 0)
  1666. pEntry->m_eDeviceType = RDT_Tunnel_L2tp;
  1667. else if (stComponentId.CompareNoCase(c_szPPPoEMiniPort) == 0)
  1668. pEntry->m_eDeviceType = RDT_PPPoE;
  1669. else if (stComponentId.CompareNoCase(c_szPtiMiniPort) == 0)
  1670. pEntry->m_eDeviceType = RDT_Parallel;
  1671. else
  1672. pEntry->m_eDeviceType = (RASDEVICETYPE) RDT_Other;
  1673. // Save the old values
  1674. // ------------------------------------------------
  1675. pEntry->m_dwOldPorts = pEntry->m_dwPorts;
  1676. // Look for min and max values
  1677. // If the MinWanEndpoints and MaxWanEndpoints keys
  1678. // exist then this is writeable.
  1679. // ------------------------------------------------
  1680. dwErr = regkeyDevice.QueryValue(c_szMinWanEndpoints, dwT);
  1681. pEntry->m_dwMinPorts = dwT;
  1682. if (dwErr == ERROR_SUCCESS)
  1683. dwErr = regkeyDevice.QueryValue(c_szMaxWanEndpoints, dwT);
  1684. if (dwErr != ERROR_SUCCESS)
  1685. {
  1686. pEntry->m_fWriteable = FALSE;
  1687. pEntry->m_dwMinPorts = pEntry->m_dwPorts;
  1688. pEntry->m_dwMaxPorts = pEntry->m_dwPorts;
  1689. }
  1690. else
  1691. {
  1692. pEntry->m_fWriteable = TRUE;
  1693. pEntry->m_dwMaxPorts = dwT;
  1694. }
  1695. pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
  1696. //$PPTP
  1697. // For PPTP, we can change the m_dwMaxMaxPorts
  1698. // ------------------------------------------------
  1699. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  1700. {
  1701. pEntry->m_dwMaxMaxPorts = PPTP_MAX_PORTS;
  1702. }
  1703. //$L2TP
  1704. // For L2TP, change the dwMaxMaxPorts
  1705. // ------------------------------------------------
  1706. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)
  1707. {
  1708. pEntry->m_dwMaxMaxPorts = L2TP_MAX_PORTS;
  1709. }
  1710. //$PPPoE
  1711. // For PPPoE, we cannot change the number of endpoints
  1712. // ------------------------------------------------
  1713. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_PPPoE)
  1714. {
  1715. pEntry->m_fWriteable = FALSE;
  1716. }
  1717. // Add this device to the list
  1718. // ------------------------------------------------
  1719. regkeyDevice.QueryValue(c_szRegValDriverDesc, stDisplay);
  1720. pEntry->m_stDisplayName = stDisplay;
  1721. // Store the value so that we can use it to write
  1722. // ------------------------------------------------
  1723. pEntry->m_fRegistry = TRUE;
  1724. pEntry->m_hKey = regkeyDevice;
  1725. regkeyDevice.Detach();
  1726. pList->AddTail(pEntry);
  1727. pEntry = NULL;
  1728. }
  1729. }
  1730. stKey.Empty();
  1731. }
  1732. COM_PROTECT_ERROR_LABEL;
  1733. }
  1734. COM_PROTECT_CATCH;
  1735. if (FHrSucceeded(hr))
  1736. m_fReadFromRegistry = TRUE;
  1737. return hr;
  1738. }
  1739. /*!--------------------------------------------------------------------------
  1740. PortsDataEntry::LoadDevicesFromRouter
  1741. -
  1742. Author: KennT
  1743. ---------------------------------------------------------------------------*/
  1744. HRESULT PortsDataEntry::LoadDevicesFromRouter(PortsDeviceList *pList)
  1745. {
  1746. HRESULT hr = hrOK;
  1747. HANDLE hConnection = 0;
  1748. DWORD cDevices = 0;
  1749. DWORD cbData = 0;
  1750. BYTE * pbData = NULL;
  1751. RAS_DEVICE_INFO * pDevInfo = NULL;
  1752. PortsDeviceEntry * pEntry = NULL;
  1753. DWORD dwVersion = 5;
  1754. UINT i;
  1755. DWORD dwErr;
  1756. USES_CONVERSION;
  1757. COM_PROTECT_TRY
  1758. {
  1759. // Connect to the server
  1760. CWRg( RasRpcConnectServer((LPTSTR) (LPCTSTR)m_stMachine, &hConnection) );
  1761. // Get the device information from the router
  1762. dwErr = RasGetDeviceConfigInfo(hConnection,
  1763. &dwVersion,
  1764. &cDevices,
  1765. &cbData,
  1766. NULL);
  1767. if (dwErr == ERROR_BUFFER_TOO_SMALL)
  1768. dwErr = ERROR_SUCCESS;
  1769. CWRg(dwErr);
  1770. pbData = (BYTE *) new char[cbData];
  1771. // Go out and actually grab the data
  1772. CWRg( RasGetDeviceConfigInfo(hConnection,
  1773. &dwVersion,
  1774. &cDevices,
  1775. &cbData,
  1776. pbData));
  1777. pDevInfo = (RAS_DEVICE_INFO *) pbData;
  1778. // If we found something and we don't understand the dev version,
  1779. // just punt.
  1780. if (cDevices && pDevInfo->dwVersion != 0)
  1781. {
  1782. // We don't understand the version information
  1783. hr = E_FAIL;
  1784. goto Error;
  1785. }
  1786. for (i=0; i<cDevices; i++, pDevInfo++)
  1787. {
  1788. pEntry = new PortsDeviceEntry;
  1789. pEntry->m_fModified = FALSE;
  1790. pEntry->m_dwEnableRas = pDevInfo->fRasEnabled;
  1791. pEntry->m_dwEnableRouting = pDevInfo->fRouterEnabled;
  1792. pEntry->m_dwEnableOutboundRouting =
  1793. pDevInfo->fRouterOutboundEnabled;
  1794. pEntry->m_stDisplayName = A2T(pDevInfo->szDeviceName);
  1795. pEntry->m_dwPorts = pDevInfo->dwNumEndPoints;
  1796. pEntry->m_eDeviceType = pDevInfo->eDeviceType;
  1797. // Save the old values
  1798. pEntry->m_dwOldPorts = pEntry->m_dwPorts;
  1799. pEntry->m_dwMinPorts = pDevInfo->dwMinWanEndPoints;
  1800. pEntry->m_dwMaxPorts = pDevInfo->dwMaxWanEndPoints;
  1801. pEntry->m_dwMaxMaxPorts = pEntry->m_dwMaxPorts;
  1802. //$PPTP
  1803. // For PPTP, we can adjust the value of m_dwMaxPorts
  1804. // --------------------------------------------------------
  1805. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  1806. {
  1807. pEntry->m_dwMaxMaxPorts = PPTP_MAX_PORTS;
  1808. }
  1809. //$L2TP
  1810. // For L2TP, we can adjust the value of m_dwMaxPorts
  1811. // --------------------------------------------------------
  1812. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)
  1813. {
  1814. pEntry->m_dwMaxMaxPorts = L2TP_MAX_PORTS;
  1815. }
  1816. pEntry->m_fWriteable =
  1817. (pEntry->m_dwMinPorts != pEntry->m_dwMaxPorts) &&
  1818. (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) != RDT_PPPoE);
  1819. pEntry->m_fRegistry = FALSE;
  1820. pEntry->m_hKey = NULL;
  1821. // Make a copy of the data
  1822. pEntry->m_RasDeviceInfo = *pDevInfo;
  1823. pList->AddTail(pEntry);
  1824. pEntry = NULL;
  1825. }
  1826. COM_PROTECT_ERROR_LABEL;
  1827. }
  1828. COM_PROTECT_CATCH;
  1829. if (FHrSucceeded(hr))
  1830. m_fReadFromRegistry = FALSE;
  1831. // If the function didn't succeed, clean out the list
  1832. if (!FHrSucceeded(hr))
  1833. {
  1834. while (!pList->IsEmpty())
  1835. delete pList->RemoveHead();
  1836. }
  1837. delete [] pbData;
  1838. delete pEntry;
  1839. if (hConnection)
  1840. RasRpcDisconnectServer(hConnection);
  1841. return hr;
  1842. }
  1843. /*!--------------------------------------------------------------------------
  1844. PortsDataEntry::SaveDevices
  1845. -
  1846. Author: KennT
  1847. ---------------------------------------------------------------------------*/
  1848. HRESULT PortsDataEntry::SaveDevices(PortsDeviceList *pList)
  1849. {
  1850. HRESULT hr = hrOK;
  1851. CWaitCursor wait;
  1852. if (m_fReadFromRegistry)
  1853. hr = SaveDevicesToRegistry(pList);
  1854. else
  1855. hr = SaveDevicesToRouter(pList);
  1856. return hr;
  1857. }
  1858. /*!--------------------------------------------------------------------------
  1859. PortsDataEntry::SaveDevicesToRegistry
  1860. -
  1861. Author: KennT
  1862. ---------------------------------------------------------------------------*/
  1863. HRESULT PortsDataEntry::SaveDevicesToRegistry(PortsDeviceList *pList)
  1864. {
  1865. HRESULT hr = hrOK;
  1866. RegKey regkeyDevice;
  1867. RegKey regkeyPptpProtocol;
  1868. POSITION pos;
  1869. PortsDeviceEntry * pEntry = NULL;
  1870. DWORD dwErr;
  1871. Assert(pList);
  1872. // Write any changes made to the per-device configuration
  1873. // and write that back out to the registry
  1874. // ----------------------------------------------------------------
  1875. pos = pList->GetHeadPosition();
  1876. while (pos)
  1877. {
  1878. pEntry = pList->GetNext(pos);
  1879. if (pEntry->m_fModified)
  1880. {
  1881. Assert(pEntry->m_hKey);
  1882. regkeyDevice.Attach(pEntry->m_hKey);
  1883. COM_PROTECT_TRY
  1884. {
  1885. RegKey regkeyModem;
  1886. RegKey * pRegkeyDevice = NULL;
  1887. if (pEntry->m_fWriteable)
  1888. {
  1889. regkeyDevice.SetValue(c_szWanEndpoints,
  1890. pEntry->m_dwPorts);
  1891. //$PPTP
  1892. // We need to adjust the upper limit for the
  1893. // number of PPTP ports.
  1894. // ------------------------------------------------
  1895. if ((RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) &&
  1896. (pEntry->m_dwPorts > pEntry->m_dwMaxPorts))
  1897. {
  1898. DWORD dwPorts;
  1899. //$PPTP
  1900. // Keep the value of the number of PPTP ports
  1901. // below the max.
  1902. // --------------------------------------------
  1903. dwPorts = min(pEntry->m_dwPorts, PPTP_MAX_PORTS);
  1904. regkeyDevice.SetValue(c_szMaxWanEndpoints, dwPorts);
  1905. }
  1906. //$L2TP
  1907. // We need to adjust the upper limit for the
  1908. // number of L2TP ports.
  1909. // ------------------------------------------------
  1910. if ((RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp) &&
  1911. (pEntry->m_dwPorts > pEntry->m_dwMaxPorts))
  1912. {
  1913. DWORD dwPorts;
  1914. //$L2TP
  1915. // Keep the value of the number of L2TP ports
  1916. // below the max.
  1917. // --------------------------------------------
  1918. dwPorts = min(pEntry->m_dwPorts, L2TP_MAX_PORTS);
  1919. regkeyDevice.SetValue(c_szMaxWanEndpoints, dwPorts);
  1920. }
  1921. }
  1922. // Get the clients subkey (if for a modem)
  1923. // else use the device key
  1924. // ----------------------------------------------------
  1925. if (pEntry->m_eDeviceType == RDT_Modem)
  1926. {
  1927. dwErr = regkeyModem.Create(regkeyDevice, c_szClientsRasKey);
  1928. pRegkeyDevice = &regkeyModem;
  1929. }
  1930. else
  1931. {
  1932. pRegkeyDevice = &regkeyDevice;
  1933. dwErr = ERROR_SUCCESS;
  1934. }
  1935. if (dwErr == ERROR_SUCCESS)
  1936. {
  1937. pRegkeyDevice->SetValue(c_szEnableForRas,
  1938. pEntry->m_dwEnableRas);
  1939. pRegkeyDevice->SetValue(c_szEnableForRouting,
  1940. pEntry->m_dwEnableRouting);
  1941. pRegkeyDevice->SetValue(c_szEnableForOutboundRouting,
  1942. pEntry->m_dwEnableOutboundRouting);
  1943. }
  1944. }
  1945. COM_PROTECT_CATCH;
  1946. regkeyDevice.Detach();
  1947. // The NumberLineDevices is no longer used in NT5.
  1948. // if this is for PPTP, then we need to special case the
  1949. // code to set the PPTP number of devices
  1950. // --------------------------------------------------------
  1951. if (pEntry->m_fWriteable &&
  1952. pEntry->m_fModified &&
  1953. RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  1954. {
  1955. // Open the PPTP registry key
  1956. // ----------------------------------------------------
  1957. dwErr = regkeyPptpProtocol.Open(m_regkeyMachine,
  1958. c_szRegKeyPptpProtocolParam);
  1959. // set the NumberLineDevices registry value
  1960. // ----------------------------------------------------
  1961. if (dwErr == ERROR_SUCCESS)
  1962. regkeyPptpProtocol.SetValue(c_szRegValNumberLineDevices,
  1963. pEntry->m_dwPorts);
  1964. regkeyPptpProtocol.Close();
  1965. }
  1966. }
  1967. // Windows NT Bug: 136858 (add called id support)
  1968. // Save called id info
  1969. // ------------------------------------------------------------
  1970. if (pEntry->m_fSaveCalledIdInfo)
  1971. {
  1972. Assert(pEntry->m_fCalledIdInfoLoaded);
  1973. regkeyDevice.Attach(pEntry->m_hKey);
  1974. regkeyDevice.SetValueExplicit(c_szRegValCalledIdInformation,
  1975. REG_MULTI_SZ,
  1976. pEntry->m_pCalledIdInfo->dwSize,
  1977. (PBYTE) pEntry->m_pCalledIdInfo->bCalledId
  1978. );
  1979. regkeyDevice.Detach();
  1980. }
  1981. }
  1982. return hr;
  1983. }
  1984. /*!--------------------------------------------------------------------------
  1985. PortsDataEntry::SaveDevicesToRouter
  1986. -
  1987. Author: KennT
  1988. ---------------------------------------------------------------------------*/
  1989. HRESULT PortsDataEntry::SaveDevicesToRouter(PortsDeviceList *pList)
  1990. {
  1991. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1992. HRESULT hr = hrOK, hrTemp;
  1993. HANDLE hConnection = 0;
  1994. DWORD cDevices = 0;
  1995. BYTE * pbData = NULL;
  1996. RAS_DEVICE_INFO * pDevInfo = NULL;
  1997. PortsDeviceEntry * pEntry = NULL;
  1998. POSITION pos;
  1999. UINT i;
  2000. RAS_CALLEDID_INFO calledIdInfo;
  2001. DWORD dwErr = ERROR_SUCCESS;
  2002. TCHAR szErr[512];
  2003. Assert(pList);
  2004. COM_PROTECT_TRY
  2005. {
  2006. // Connect to the server
  2007. // ------------------------------------------------------------
  2008. CWRg( RasRpcConnectServer((LPTSTR)(LPCTSTR)m_stMachine, &hConnection) );
  2009. // Allocate space for the data
  2010. // ------------------------------------------------------------
  2011. pbData = (BYTE *) new RAS_DEVICE_INFO[pList->GetCount()];
  2012. pDevInfo = (RAS_DEVICE_INFO *) pbData;
  2013. pos = pList->GetHeadPosition();
  2014. cDevices = pList->GetCount();
  2015. for (i=0; i<cDevices; i++, pDevInfo++)
  2016. {
  2017. Assert(pos);
  2018. pEntry = pList->GetNext(pos);
  2019. // Get the information needed to calculate the number
  2020. // of ports
  2021. // --------------------------------------------------------
  2022. *pDevInfo = pEntry->m_RasDeviceInfo;
  2023. pDevInfo->fWrite = TRUE;
  2024. pDevInfo->fRasEnabled = pEntry->m_dwEnableRas;
  2025. pDevInfo->fRouterEnabled = pEntry->m_dwEnableRouting;
  2026. pDevInfo->fRouterOutboundEnabled =
  2027. pEntry->m_dwEnableOutboundRouting;
  2028. pDevInfo->dwNumEndPoints = pEntry->m_dwPorts;
  2029. pDevInfo->dwMaxWanEndPoints = pEntry->m_dwMaxPorts;
  2030. // Windows NT Bug : 168364
  2031. // From RaoS, I also need to set the maximum incoming/outging
  2032. // --------------------------------------------------------
  2033. // Windows NT Bug : ?
  2034. // Use the defaults for now,
  2035. // This will get removed later.
  2036. // --------------------------------------------------------
  2037. pDevInfo->dwMaxInCalls = (-1);
  2038. pDevInfo->dwMaxOutCalls = 3;
  2039. // if this is for PPTP, then we need to special case the
  2040. // code to set the PPTP number of devices
  2041. // --------------------------------------------------------
  2042. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp)
  2043. {
  2044. //$PPTP
  2045. // We need to adjust the upper limit for the
  2046. // number of PPTP ports.
  2047. // ------------------------------------------------
  2048. if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)
  2049. {
  2050. DWORD dwPorts;
  2051. //$PPTP
  2052. // Keep the value of the number of PPTP ports
  2053. // below the max.
  2054. // --------------------------------------------
  2055. dwPorts = min(pEntry->m_dwPorts, PPTP_MAX_PORTS);
  2056. pDevInfo->dwMaxWanEndPoints = dwPorts;
  2057. }
  2058. RegKey regkeyMachine;
  2059. RegKey regkeyPptpProtocol;
  2060. HKEY hkeyMachine;
  2061. // Connect to the machine
  2062. dwErr = ConnectRegistry(m_stMachine, &hkeyMachine);
  2063. regkeyMachine.Attach(hkeyMachine);
  2064. // Open the PPTP registry key
  2065. dwErr = regkeyPptpProtocol.Open(regkeyMachine,
  2066. c_szRegKeyPptpProtocolParam);
  2067. // set the NumberLineDevices registry value
  2068. if (dwErr == ERROR_SUCCESS)
  2069. regkeyPptpProtocol.SetValue(c_szRegValNumberLineDevices,
  2070. pEntry->m_dwPorts);
  2071. regkeyPptpProtocol.Close();
  2072. regkeyMachine.Close();
  2073. }
  2074. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp)
  2075. {
  2076. //$L2TP
  2077. // We need to adjust the upper limit for the
  2078. // number of L2TP ports.
  2079. // ------------------------------------------------
  2080. if (pEntry->m_dwPorts > pEntry->m_dwMaxPorts)
  2081. {
  2082. DWORD dwPorts;
  2083. //$L2TP
  2084. // Keep the value of the number of L2TP ports
  2085. // below the max.
  2086. // --------------------------------------------
  2087. dwPorts = min(pEntry->m_dwPorts, L2TP_MAX_PORTS);
  2088. pDevInfo->dwMaxWanEndPoints = dwPorts;
  2089. }
  2090. }
  2091. // Windows NT Bug : 136858 (add called id support)
  2092. // Do we need to save the called id info?
  2093. // --------------------------------------------------------
  2094. if (pEntry->m_fSaveCalledIdInfo && pEntry->m_pCalledIdInfo)
  2095. {
  2096. Assert(pEntry->m_fCalledIdInfoLoaded);
  2097. //: if the call fails, what should we do? -- save it later
  2098. hrTemp = RasSetCalledIdInfo(hConnection,
  2099. pDevInfo,
  2100. pEntry->m_pCalledIdInfo,
  2101. TRUE);
  2102. // We've saved it, we don't need to save it again
  2103. // unless it changes.
  2104. // ----------------------------------------------------
  2105. if (FHrSucceeded(hrTemp))
  2106. pEntry->m_fSaveCalledIdInfo = FALSE;
  2107. }
  2108. }
  2109. dwErr = RasSetDeviceConfigInfo(hConnection,
  2110. cDevices,
  2111. sizeof(RAS_DEVICE_INFO)*cDevices,
  2112. pbData);
  2113. if (dwErr != ERROR_SUCCESS)
  2114. {
  2115. CString stErr;
  2116. CString stErrCode;
  2117. RAS_DEVICE_INFO * pDevice;
  2118. BOOL fErr = FALSE;
  2119. // Need to grab the error information out of the
  2120. // info struct an set the error strings.
  2121. // Could not save the information for the following
  2122. // devices
  2123. pDevice = (RAS_DEVICE_INFO *) pbData;
  2124. stErr.LoadString(IDS_ERR_SETDEVICECONFIGINFO_GEEK);
  2125. for (i=0; i<cDevices; i++, pDevice++)
  2126. {
  2127. if (pDevice->dwError)
  2128. {
  2129. CString stErrString;
  2130. FormatError(HRESULT_FROM_WIN32(pDevice->dwError),
  2131. szErr, DimensionOf(szErr));
  2132. stErrCode.Format(_T("%s (%08lx)"), szErr,
  2133. pDevice->dwError);
  2134. stErr += _T(" ");
  2135. stErr += pDevice->szDeviceName;
  2136. stErr += _T(" ");
  2137. stErr += stErrCode;
  2138. stErr += _T("\n");
  2139. fErr = TRUE;
  2140. }
  2141. }
  2142. if (fErr)
  2143. AddGeekLevelErrorString(stErr);
  2144. CWRg(dwErr);
  2145. }
  2146. COM_PROTECT_ERROR_LABEL;
  2147. }
  2148. COM_PROTECT_CATCH;
  2149. delete [] pbData;
  2150. if (hConnection)
  2151. RasRpcDisconnectServer(hConnection);
  2152. return hr;
  2153. }
  2154. /*---------------------------------------------------------------------------
  2155. PortsDeviceConfigDlg implementation
  2156. ---------------------------------------------------------------------------*/
  2157. BEGIN_MESSAGE_MAP(PortsDeviceConfigDlg, CBaseDialog)
  2158. //{{AFX_MSG_MAP(PortsPageGeneral)
  2159. //}}AFX_MSG_MAP
  2160. END_MESSAGE_MAP()
  2161. void PortsDeviceConfigDlg::DoDataExchange(CDataExchange *pDX)
  2162. {
  2163. CBaseDialog::DoDataExchange(pDX);
  2164. DDX_Control(pDX, IDC_DEVCFG_SPIN_PORTS, m_spinPorts);
  2165. }
  2166. void PortsDeviceConfigDlg::SetDevice(PortsDeviceEntry *pEntry, DWORD dwTotalActivePorts)
  2167. {
  2168. Assert(pEntry);
  2169. m_pEntry = pEntry;
  2170. m_dwTotalActivePorts = dwTotalActivePorts;
  2171. }
  2172. BOOL PortsDeviceConfigDlg::OnInitDialog()
  2173. {
  2174. HRESULT hr;
  2175. CString stCalledIdInfo;
  2176. CString stDisplay;
  2177. Assert(m_pEntry);
  2178. CBaseDialog::OnInitDialog();
  2179. if (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE)
  2180. {
  2181. CheckDlgButton(IDC_DEVCFG_BTN_RAS, FALSE);
  2182. GetDlgItem(IDC_DEVCFG_BTN_RAS)->EnableWindow(FALSE);
  2183. CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, FALSE);
  2184. GetDlgItem(IDC_DEVCFG_BTN_ROUTING)->EnableWindow(FALSE);
  2185. CheckDlgButton(
  2186. IDC_DEVCFG_BTN_OUTBOUND_ROUTING,
  2187. m_pEntry->m_dwEnableOutboundRouting
  2188. );
  2189. }
  2190. else
  2191. {
  2192. CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_pEntry->m_dwEnableRas);
  2193. CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_pEntry->m_dwEnableRouting);
  2194. CheckDlgButton(IDC_DEVCFG_BTN_OUTBOUND_ROUTING, FALSE);
  2195. GetDlgItem(IDC_DEVCFG_BTN_OUTBOUND_ROUTING)->EnableWindow(FALSE);
  2196. }
  2197. m_spinPorts.SetBuddy(GetDlgItem(IDC_DEVCFG_EDIT_PORTS));
  2198. m_spinPorts.SetRange(m_pEntry->m_dwMinPorts, m_pEntry->m_dwMaxMaxPorts);
  2199. m_spinPorts.SetPos(m_pEntry->m_dwPorts);
  2200. // If we can edit/change the number of ports, set it up here
  2201. // ----------------------------------------------------------------
  2202. if (!m_pEntry->m_fWriteable || (m_pEntry->m_dwMinPorts == m_pEntry->m_dwMaxPorts))
  2203. {
  2204. GetDlgItem(IDC_DEVCFG_SPIN_PORTS)->EnableWindow(FALSE);
  2205. GetDlgItem(IDC_DEVCFG_EDIT_PORTS)->EnableWindow(FALSE);
  2206. }
  2207. // Windows NT Bug : 136858 - Get the called id info
  2208. // ----------------------------------------------------------------
  2209. LoadCalledIdInfo();
  2210. // Get the called id info, format it into a string and add it to
  2211. // the display
  2212. // ----------------------------------------------------------------
  2213. CalledIdInfoToString(&stCalledIdInfo);
  2214. GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->SetWindowText(stCalledIdInfo);
  2215. ((CEdit *)GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID))->SetModify(FALSE);
  2216. if ((RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Parallel) ||
  2217. (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE))
  2218. GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->EnableWindow(FALSE);
  2219. // Set the window title to include the display name of the adapter
  2220. // ----------------------------------------------------------------
  2221. stDisplay.Format(IDS_TITLE_CONFIGURE_PORTS,
  2222. (LPCTSTR) m_pEntry->m_stDisplayName);
  2223. SetWindowText(stDisplay);
  2224. return TRUE;
  2225. }
  2226. /*!--------------------------------------------------------------------------
  2227. PortsDeviceConfigDlg::OnOK
  2228. -
  2229. Author: KennT
  2230. ---------------------------------------------------------------------------*/
  2231. void PortsDeviceConfigDlg::OnOK()
  2232. {
  2233. BOOL fChanged = FALSE;
  2234. BOOL fReboot = FALSE;
  2235. DWORD dwNewEnableRas, dwNewEnableRouting,
  2236. dwNewEnableOutboundRouting, dwNewPorts;
  2237. // Check to see if the values changed
  2238. dwNewEnableRas = (IsDlgButtonChecked(IDC_DEVCFG_BTN_RAS) != 0);
  2239. dwNewEnableRouting = (IsDlgButtonChecked(IDC_DEVCFG_BTN_ROUTING) != 0);
  2240. dwNewEnableOutboundRouting =
  2241. (IsDlgButtonChecked(IDC_DEVCFG_BTN_OUTBOUND_ROUTING) != 0);
  2242. dwNewPorts = m_spinPorts.GetPos();
  2243. // Make sure that we have a valid size
  2244. // ----------------------------------------------------------------
  2245. if ((dwNewPorts < m_pEntry->m_dwMinPorts) ||
  2246. (dwNewPorts > m_pEntry->m_dwMaxMaxPorts))
  2247. {
  2248. CString st;
  2249. st.Format(IDS_ERR_PORTS_BOGUS_SIZE, m_pEntry->m_dwMinPorts,
  2250. m_pEntry->m_dwMaxMaxPorts);
  2251. AfxMessageBox(st);
  2252. return;
  2253. }
  2254. // Windows NT Bug : 174803
  2255. // We do not allow the user to change the number of PPTP ports down
  2256. // to 0.
  2257. // ----------------------------------------------------------------
  2258. if ((RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) &&
  2259. (dwNewPorts == 0))
  2260. {
  2261. AfxMessageBox(IDS_ERR_PPTP_PORTS_EQUAL_ZERO);
  2262. return;
  2263. }
  2264. // Windows NT Bugs : 165862
  2265. // If we are changing the number of ports for PPTP
  2266. // then we need to warn the user (since PPTP is not yet
  2267. // fully PnP (4/23/98).
  2268. //
  2269. //$PPTP
  2270. // For PPTP, if the value of m_dwPorts exceeds the value of
  2271. // m_dwMaxPorts, then we have to reboot (we also need to adjust
  2272. // the appropriate registry entries).
  2273. // ----------------------------------------------------------------
  2274. if ((dwNewPorts > m_pEntry->m_dwMaxPorts) &&
  2275. (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_Pptp))
  2276. {
  2277. // If we have a page, then we can do a reboot, otherwise we
  2278. // are in the wizard and can't do a reboot at this point.
  2279. // ------------------------------------------------------------
  2280. if (m_pageGeneral)
  2281. {
  2282. // The user chose Yes indicating that he wants to be prompted to
  2283. // reboot, so set this flag to trigger a reboot request.
  2284. // --------------------------------------------------------
  2285. if (AfxMessageBox(IDS_WRN_PPTP_NUMPORTS_CHANGING, MB_YESNO) == IDYES)
  2286. {
  2287. fReboot = TRUE;
  2288. }
  2289. }
  2290. else
  2291. AfxMessageBox(IDS_WRN_PPTP_NUMPORTS_CHANGING2, MB_OK);
  2292. }
  2293. //$L2TP
  2294. // For L2TP, if the value of m_dwPorts exceeds the value of
  2295. // m_dwMaxPorts, then we have to reboot (we also need to adjust
  2296. // the appropriate registry entries).
  2297. // ----------------------------------------------------------------
  2298. if ((dwNewPorts > m_pEntry->m_dwMaxPorts) &&
  2299. (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_Tunnel_L2tp))
  2300. {
  2301. // If we have a page, then we can do a reboot, otherwise we
  2302. // are in the wizard and can't do a reboot at this point.
  2303. // ------------------------------------------------------------
  2304. if (m_pageGeneral)
  2305. {
  2306. // The user chose Yes indicating that he wants to be prompted to
  2307. // reboot, so set this flag to trigger a reboot request.
  2308. // --------------------------------------------------------
  2309. if (AfxMessageBox(IDS_WRN_L2TP_NUMPORTS_CHANGING, MB_YESNO) == IDYES)
  2310. {
  2311. fReboot = TRUE;
  2312. }
  2313. }
  2314. else
  2315. AfxMessageBox(IDS_WRN_L2TP_NUMPORTS_CHANGING2, MB_OK);
  2316. }
  2317. if ((dwNewEnableRas != m_pEntry->m_dwEnableRas) ||
  2318. (dwNewEnableRouting != m_pEntry->m_dwEnableRouting) ||
  2319. (dwNewEnableOutboundRouting !=
  2320. m_pEntry->m_dwEnableOutboundRouting) ||
  2321. (dwNewPorts != m_pEntry->m_dwPorts))
  2322. {
  2323. // warning user -- client could be disconnected -- BUG 165862
  2324. // when disable router / ras
  2325. // decreasing the number of ports
  2326. // ras
  2327. if(!dwNewEnableRas &&
  2328. m_pEntry->m_dwEnableRas &&
  2329. m_dwTotalActivePorts > 0 &&
  2330. AfxMessageBox(IDS_WRN_PORTS_DISABLERAS, MB_YESNO | MB_DEFBUTTON2) == IDNO)
  2331. goto L_RESTORE;
  2332. // routing
  2333. if (((!dwNewEnableRouting &&
  2334. m_pEntry->m_dwEnableRouting) ||
  2335. (!dwNewEnableOutboundRouting &&
  2336. m_pEntry->m_dwEnableOutboundRouting)) &&
  2337. m_dwTotalActivePorts > 0 &&
  2338. AfxMessageBox(IDS_WRN_PORTS_DISABLEROUTING, MB_YESNO | MB_DEFBUTTON2) == IDNO)
  2339. goto L_RESTORE;
  2340. // Bug 263958
  2341. //ports -- We cannot count the number of outgoing connection remotely.
  2342. // Therefore if we reduce the number of port, give warning without counting total
  2343. // active connections.
  2344. if(dwNewPorts < m_pEntry->m_dwPorts &&
  2345. AfxMessageBox(IDS_WRN_PORTS_DECREASE, MB_YESNO | MB_DEFBUTTON2) == IDNO)
  2346. goto L_RESTORE;
  2347. m_pEntry->m_dwEnableRas = dwNewEnableRas;
  2348. m_pEntry->m_dwEnableRouting = dwNewEnableRouting;
  2349. m_pEntry->m_dwEnableOutboundRouting =
  2350. dwNewEnableOutboundRouting;
  2351. m_pEntry->m_dwPorts = dwNewPorts;
  2352. m_pEntry->m_fModified = TRUE;
  2353. }
  2354. // Get the called id info string (if the field changed)
  2355. // ----------------------------------------------------------------
  2356. if (((CEdit *) GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID))->GetModify())
  2357. {
  2358. CString st;
  2359. GetDlgItem(IDC_DEVCFG_EDIT_CALLEDID)->GetWindowText(st);
  2360. StringToCalledIdInfo((LPCTSTR) st);
  2361. // Now set the changed state on the structure
  2362. // We need to save this data back to the registry
  2363. // ------------------------------------------------------------
  2364. m_pEntry->m_fSaveCalledIdInfo = TRUE;
  2365. }
  2366. CBaseDialog::OnOK();
  2367. if(fReboot == TRUE)
  2368. {
  2369. Assert(m_pageGeneral);
  2370. // force an OnApply to save data before shut down
  2371. // ------------------------------------------------------------
  2372. if (m_pageGeneral->OnApply()) {
  2373. WCHAR szComputer[MAX_COMPUTERNAME_LENGTH + 1];
  2374. DWORD dwLength = MAX_COMPUTERNAME_LENGTH;
  2375. GetComputerName(szComputer, &dwLength );
  2376. if (lstrcmpi(szComputer, (LPTSTR)m_pageGeneral->m_spRouter->GetMachineName()))
  2377. {
  2378. ::RestartComputer((LPTSTR)m_pageGeneral->m_spRouter->GetMachineName());
  2379. }
  2380. else
  2381. ::RestartComputer((LPTSTR)NULL);
  2382. }
  2383. }
  2384. return;
  2385. L_RESTORE:
  2386. if (RAS_DEVICE_TYPE(m_pEntry->m_eDeviceType) == RDT_PPPoE)
  2387. {
  2388. CheckDlgButton(
  2389. IDC_DEVCFG_BTN_OUTBOUND_ROUTING,
  2390. m_pEntry->m_dwEnableOutboundRouting
  2391. );
  2392. }
  2393. else
  2394. {
  2395. CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_pEntry->m_dwEnableRas);
  2396. CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_pEntry->m_dwEnableRouting);
  2397. }
  2398. m_spinPorts.SetPos(m_pEntry->m_dwPorts);
  2399. return;
  2400. }
  2401. /*!--------------------------------------------------------------------------
  2402. PortsDeviceConfigDlg::LoadCalledIdInfo
  2403. -
  2404. Author: KennT
  2405. ---------------------------------------------------------------------------*/
  2406. HRESULT PortsDeviceConfigDlg::LoadCalledIdInfo()
  2407. {
  2408. HRESULT hr = hrOK;
  2409. if (!m_pEntry->m_fCalledIdInfoLoaded)
  2410. {
  2411. // Read the data from the registry
  2412. // ------------------------------------------------------------
  2413. if (m_pEntry->m_fRegistry)
  2414. {
  2415. DWORD dwType;
  2416. DWORD dwSize;
  2417. LPBYTE pbData = NULL;
  2418. DWORD dwErr;
  2419. RegKey regkeyDevice;
  2420. regkeyDevice.Attach(m_pEntry->m_hKey);
  2421. dwErr = regkeyDevice.QueryValueExplicit(c_szRegValCalledIdInformation,
  2422. &dwType,
  2423. &dwSize,
  2424. &pbData);
  2425. hr = HRESULT_FROM_WIN32(dwErr);
  2426. if ((dwErr == ERROR_SUCCESS) &&
  2427. (dwType == REG_MULTI_SZ))
  2428. {
  2429. // Allocate space for a new called id structure
  2430. // ----------------------------------------------------
  2431. delete (BYTE *) m_pEntry->m_pCalledIdInfo;
  2432. hr = AllocateCalledId(dwSize, &(m_pEntry->m_pCalledIdInfo));
  2433. if (FHrSucceeded(hr))
  2434. {
  2435. memcpy(m_pEntry->m_pCalledIdInfo->bCalledId,
  2436. pbData,
  2437. dwSize);
  2438. }
  2439. }
  2440. delete pbData;
  2441. regkeyDevice.Detach();
  2442. }
  2443. else
  2444. {
  2445. HANDLE hConnection = NULL;
  2446. DWORD dwSize = 0;
  2447. DWORD dwErr;
  2448. // use Rao's API
  2449. // Connect to the server
  2450. // --------------------------------------------------------
  2451. dwErr = RasRpcConnectServer((LPTSTR) (LPCTSTR)m_stMachine,
  2452. &hConnection);
  2453. // Call it once to get the size information
  2454. // --------------------------------------------------------
  2455. if (dwErr == ERROR_SUCCESS)
  2456. dwErr = RasGetCalledIdInfo(hConnection,
  2457. &m_pEntry->m_RasDeviceInfo,
  2458. &dwSize,
  2459. NULL);
  2460. hr = HRESULT_FROM_WIN32(dwErr);
  2461. if ((dwErr == ERROR_BUFFER_TOO_SMALL) ||
  2462. (dwErr == ERROR_SUCCESS))
  2463. {
  2464. // Allocate space for a new called id structure
  2465. // ----------------------------------------------------
  2466. delete (BYTE *) m_pEntry->m_pCalledIdInfo;
  2467. AllocateCalledId(dwSize, &(m_pEntry->m_pCalledIdInfo));
  2468. dwErr = RasGetCalledIdInfo(hConnection,
  2469. &m_pEntry->m_RasDeviceInfo,
  2470. &dwSize,
  2471. m_pEntry->m_pCalledIdInfo
  2472. );
  2473. hr = HRESULT_FROM_WIN32(dwErr);
  2474. }
  2475. if (hConnection)
  2476. RasRpcDisconnectServer(hConnection);
  2477. }
  2478. // Set the status flags, depending on whether the operation
  2479. // succeeded or not
  2480. // ------------------------------------------------------------
  2481. // We always set the save value to FALSE after we have read
  2482. // something in (or tried to read something in).
  2483. // ------------------------------------------------------------
  2484. m_pEntry->m_fSaveCalledIdInfo = FALSE;
  2485. // We always set the load value to TRUE (we have tried to load
  2486. // the information but it failed, for example the registry
  2487. // key may not exist).
  2488. // ------------------------------------------------------------
  2489. m_pEntry->m_fCalledIdInfoLoaded = TRUE;
  2490. if (!FHrSucceeded(hr))
  2491. {
  2492. delete m_pEntry->m_pCalledIdInfo;
  2493. m_pEntry->m_pCalledIdInfo = NULL;
  2494. }
  2495. }
  2496. //Error:
  2497. return hr;
  2498. }
  2499. /*!--------------------------------------------------------------------------
  2500. PortsDeviceConfigDlg::AllocateCalledId
  2501. -
  2502. Author: KennT
  2503. ---------------------------------------------------------------------------*/
  2504. HRESULT PortsDeviceConfigDlg::AllocateCalledId(DWORD dwSize,
  2505. RAS_CALLEDID_INFO **ppCalledId)
  2506. {
  2507. HRESULT hr = hrOK;
  2508. *ppCalledId = NULL;
  2509. COM_PROTECT_TRY
  2510. {
  2511. *ppCalledId =
  2512. (RAS_CALLEDID_INFO *) new BYTE[sizeof(RAS_CALLEDID_INFO) +
  2513. dwSize];
  2514. (*ppCalledId)->dwSize = dwSize;
  2515. }
  2516. COM_PROTECT_CATCH;
  2517. return hr;
  2518. }
  2519. /*!--------------------------------------------------------------------------
  2520. PortsDeviceConfigDlg::CalledIdInfoToString
  2521. Converts the data in the called id info structure into a
  2522. semi-colon separated string.
  2523. Author: KennT
  2524. ---------------------------------------------------------------------------*/
  2525. HRESULT PortsDeviceConfigDlg::CalledIdInfoToString(CString *pst)
  2526. {
  2527. WCHAR * pswz = NULL;
  2528. HRESULT hr = hrOK;
  2529. USES_CONVERSION;
  2530. Assert(pst);
  2531. Assert(m_pEntry);
  2532. COM_PROTECT_TRY
  2533. {
  2534. pst->Empty();
  2535. if (m_pEntry->m_pCalledIdInfo)
  2536. pswz = (WCHAR *) (m_pEntry->m_pCalledIdInfo->bCalledId);
  2537. if (pswz && *pswz)
  2538. {
  2539. *pst += W2T(pswz);
  2540. // Skip over the terminating NULL
  2541. // --------------------------------------------------------
  2542. pswz += StrLenW(pswz)+1;
  2543. while (*pswz)
  2544. {
  2545. *pst += _T("; ");
  2546. *pst += W2T(pswz);
  2547. // Skip over the terminating NULL
  2548. // --------------------------------------------------------
  2549. pswz += StrLenW(pswz)+1;
  2550. }
  2551. }
  2552. }
  2553. COM_PROTECT_CATCH;
  2554. if (!FHrSucceeded(hr))
  2555. pst->Empty();
  2556. return hr;
  2557. }
  2558. /*!--------------------------------------------------------------------------
  2559. PortsDeviceConfigDlg::StringToCalledIdInfo
  2560. -
  2561. Author: KennT
  2562. ---------------------------------------------------------------------------*/
  2563. HRESULT PortsDeviceConfigDlg::StringToCalledIdInfo(LPCTSTR psz)
  2564. {
  2565. DWORD cchSize;
  2566. WCHAR * pswzData = NULL;
  2567. WCHAR * pswzCurrent;
  2568. LPTSTR pszBufferStart = NULL;
  2569. LPTSTR pszBuffer = NULL;
  2570. RAS_CALLEDID_INFO * pCalledInfo = NULL;
  2571. HRESULT hr = hrOK;
  2572. CString stTemp;
  2573. // We need to parse the string (look for separators)
  2574. // ----------------------------------------------------------------
  2575. COM_PROTECT_TRY
  2576. {
  2577. // Allocate some space for the called id info (it's just as long
  2578. // as the string, maybe even somewhat smaller).
  2579. // Allocate twice the space so that we are sure of getting
  2580. // all of the NULL terminating characters
  2581. // ------------------------------------------------------------
  2582. pswzData = new WCHAR[2*(StrLen(psz)+1) + 1];
  2583. pswzCurrent = pswzData;
  2584. // Copy the string into a buffer
  2585. // ------------------------------------------------------------
  2586. pszBufferStart = StrDup(psz);
  2587. pszBuffer = pszBufferStart;
  2588. _tcstok(pszBuffer, _T(";"));
  2589. while (pszBuffer && *pszBuffer)
  2590. {
  2591. // Trim the string (get rid of whitespace, before and after).
  2592. // --------------------------------------------------------
  2593. stTemp = pszBuffer;
  2594. stTemp.TrimLeft();
  2595. stTemp.TrimRight();
  2596. if (!stTemp.IsEmpty())
  2597. {
  2598. StrCpyWFromT(pswzCurrent, (LPCTSTR) stTemp);
  2599. pswzCurrent += stTemp.GetLength()+1;
  2600. }
  2601. pszBuffer = _tcstok(NULL, _T(";"));
  2602. }
  2603. // Add extra terminating NULL character (so that it conforms
  2604. // to the REG_MULTI_SZ format).
  2605. // ------------------------------------------------------------
  2606. *pswzCurrent = 0;
  2607. cchSize = pswzCurrent - pswzData + 1;
  2608. // Allocate the real data structure
  2609. // Allocate and copy into a temporary so that in case
  2610. // of an exception, we don't lose the original data
  2611. // ------------------------------------------------------------
  2612. AllocateCalledId(cchSize*sizeof(WCHAR), &pCalledInfo);
  2613. memcpy(pCalledInfo->bCalledId,
  2614. pswzData,
  2615. cchSize*sizeof(WCHAR));
  2616. delete (BYTE *) m_pEntry->m_pCalledIdInfo;
  2617. m_pEntry->m_pCalledIdInfo = pCalledInfo;
  2618. // Set to NULL so that we don't delete our new pointer
  2619. // on exit.
  2620. // ------------------------------------------------------------
  2621. pCalledInfo = NULL;
  2622. }
  2623. COM_PROTECT_CATCH;
  2624. delete pszBufferStart;
  2625. delete pswzData;
  2626. delete pCalledInfo;
  2627. return hr;
  2628. }
  2629. /*---------------------------------------------------------------------------
  2630. PortsSimpleDeviceConfigDlg implementation
  2631. ---------------------------------------------------------------------------*/
  2632. BEGIN_MESSAGE_MAP(PortsSimpleDeviceConfigDlg, CBaseDialog)
  2633. //{{AFX_MSG_MAP(PortsPageGeneral)
  2634. //}}AFX_MSG_MAP
  2635. END_MESSAGE_MAP()
  2636. void PortsSimpleDeviceConfigDlg::DoDataExchange(CDataExchange *pDX)
  2637. {
  2638. CBaseDialog::DoDataExchange(pDX);
  2639. }
  2640. BOOL PortsSimpleDeviceConfigDlg::OnInitDialog()
  2641. {
  2642. HRESULT hr;
  2643. CBaseDialog::OnInitDialog();
  2644. // If we are using the BIG dialog, then we need to disable
  2645. // the unapplicable controls.
  2646. if (GetDlgItem(IDC_DEVCFG_TEXT_CALLEDID))
  2647. {
  2648. MultiEnableWindow(GetSafeHwnd(),
  2649. FALSE,
  2650. IDC_DEVCFG_TEXT_CALLEDID,
  2651. IDC_DEVCFG_EDIT_CALLEDID,
  2652. IDC_DEVCFG_TEXT_PORTS,
  2653. IDC_DEVCFG_EDIT_PORTS,
  2654. IDC_DEVCFG_SPIN_PORTS,
  2655. IDC_DEVCFG_TEXT,
  2656. 0);
  2657. }
  2658. CheckDlgButton(IDC_DEVCFG_BTN_RAS, m_dwEnableRas);
  2659. CheckDlgButton(IDC_DEVCFG_BTN_ROUTING, m_dwEnableRouting);
  2660. GetDlgItem(IDC_DEVCFG_BTN_OUTBOUND_ROUTING)->EnableWindow(FALSE);
  2661. return TRUE;
  2662. }
  2663. /*!--------------------------------------------------------------------------
  2664. PortsSimpleDeviceConfigDlg::OnOK
  2665. -
  2666. Author: KennT
  2667. ---------------------------------------------------------------------------*/
  2668. void PortsSimpleDeviceConfigDlg::OnOK()
  2669. {
  2670. // Check to see if the values changed
  2671. m_dwEnableRas = (IsDlgButtonChecked(IDC_DEVCFG_BTN_RAS) != 0);
  2672. m_dwEnableRouting = (IsDlgButtonChecked(IDC_DEVCFG_BTN_ROUTING) != 0);
  2673. CBaseDialog::OnOK();
  2674. return;
  2675. }
  2676. /*---------------------------------------------------------------------------
  2677. PortsDeviceEntry implementation
  2678. ---------------------------------------------------------------------------*/
  2679. PortsDeviceEntry::PortsDeviceEntry()
  2680. : m_hKey(NULL),
  2681. m_fRegistry(FALSE),
  2682. m_fSaveCalledIdInfo(FALSE),
  2683. m_fCalledIdInfoLoaded(FALSE),
  2684. m_pCalledIdInfo(NULL)
  2685. {
  2686. }
  2687. PortsDeviceEntry::~PortsDeviceEntry()
  2688. {
  2689. delete (BYTE *) m_pCalledIdInfo;
  2690. if (m_hKey)
  2691. DisconnectRegistry(m_hKey);
  2692. m_hKey = NULL;
  2693. }
  2694. BOOL
  2695. RestartComputer(LPTSTR szMachineName)
  2696. /* Called if user chooses to shut down the computer.
  2697. **
  2698. ** Return false if failure, true otherwise
  2699. */
  2700. {
  2701. HANDLE hToken; /* handle to process token */
  2702. TOKEN_PRIVILEGES tkp; /* ptr. to token structure */
  2703. BOOL fResult; /* system shutdown flag */
  2704. CString str;
  2705. TRACE(L"RestartComputer");
  2706. /* Enable the shutdown privilege */
  2707. if (!OpenProcessToken( GetCurrentProcess(),
  2708. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  2709. &hToken))
  2710. return FALSE;
  2711. /* Get the LUID for shutdown privilege. */
  2712. if (szMachineName)
  2713. LookupPrivilegeValue(NULL, SE_REMOTE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
  2714. else
  2715. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
  2716. tkp.PrivilegeCount = 1; /* one privilege to set */
  2717. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  2718. /* Get shutdown privilege for this process. */
  2719. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
  2720. /* Cannot test the return value of AdjustTokenPrivileges. */
  2721. if (GetLastError() != ERROR_SUCCESS)
  2722. return FALSE;
  2723. str.LoadString(IDS_SHUTDOWN_WARNING);
  2724. fResult = InitiateSystemShutdown(
  2725. szMachineName, // computer to shutdown
  2726. str.GetBuffer(10), // msg. to user
  2727. 20, // time out period - shut down right away
  2728. FALSE, // forcibly close open apps
  2729. TRUE // reboot after shutdown
  2730. );
  2731. str.ReleaseBuffer();
  2732. if (!fResult)
  2733. {
  2734. return FALSE;
  2735. }
  2736. if( !ExitWindowsEx(EWX_REBOOT, 0))
  2737. return FALSE;
  2738. /* Disable shutdown privilege. */
  2739. tkp.Privileges[0].Attributes = 0;
  2740. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
  2741. if (GetLastError() != ERROR_SUCCESS)
  2742. return FALSE;
  2743. return TRUE;
  2744. }
  2745. /*!--------------------------------------------------------------------------
  2746. OnConfigurePorts
  2747. Returns TRUE if something has changed. FALSE otherwise.
  2748. Author: KennT
  2749. ---------------------------------------------------------------------------*/
  2750. BOOL OnConfigurePorts(LPCTSTR pszMachineName,
  2751. DWORD dwTotalActivePorts,
  2752. PortsPageGeneral *pPage,
  2753. CListCtrlEx *pListCtrl)
  2754. {
  2755. BOOL fChanged = FALSE;
  2756. // Need to determine if multiple items are selected or not
  2757. if (pListCtrl->GetSelectedCount() == 1)
  2758. {
  2759. PortsDeviceConfigDlg configdlg(pPage, pszMachineName);
  2760. int iPos;
  2761. PortsDeviceEntry * pEntry;
  2762. CString st;
  2763. int iType;
  2764. TCHAR szNumber[32];
  2765. if ((iPos = pListCtrl->GetNextItem(-1, LVNI_SELECTED)) == -1)
  2766. return FALSE;
  2767. pEntry = (PortsDeviceEntry *) pListCtrl->GetItemData(iPos);
  2768. // total number of active ports are passed over to dialog, so if user tries to reduce total number of port
  2769. // below this total number, give a warning message
  2770. configdlg.SetDevice(pEntry, dwTotalActivePorts);
  2771. if (configdlg.DoModal() == IDOK)
  2772. {
  2773. // Get the values from pEntry and update the list control entry
  2774. iType = (pEntry->m_dwEnableRas * 2) +
  2775. (pEntry->m_dwEnableRouting ||
  2776. pEntry->m_dwEnableOutboundRouting);
  2777. st = PortsDeviceTypeToCString(iType);
  2778. pListCtrl->SetItemText(iPos, PORTS_COL_USAGE, (LPCTSTR) st);
  2779. FormatNumber(pEntry->m_dwPorts, szNumber,
  2780. DimensionOf(szNumber), FALSE);
  2781. pListCtrl->SetItemText(iPos, PORTS_COL_NUMBER, (LPCTSTR) szNumber);
  2782. fChanged = TRUE;
  2783. }
  2784. }
  2785. return fChanged;
  2786. }
  2787. /*---------------------------------------------------------------------------
  2788. RasmanPortMap implementation
  2789. ---------------------------------------------------------------------------*/
  2790. RasmanPortMap::~RasmanPortMap()
  2791. {
  2792. m_map.RemoveAll();
  2793. }
  2794. HRESULT RasmanPortMap::Init(HANDLE hRasHandle,
  2795. RASMAN_PORT *pPort,
  2796. DWORD dwPorts)
  2797. {
  2798. RASMAN_INFO rasmaninfo;
  2799. DWORD i;
  2800. DWORD dwErr = NO_ERROR;
  2801. HRESULT hr = hrOK;
  2802. if (pPort == NULL)
  2803. {
  2804. m_map.RemoveAll();
  2805. return hr;
  2806. }
  2807. for (i=0; i<dwPorts; i++, pPort++)
  2808. {
  2809. // If the port is closed, there is no need
  2810. // to go any further. (No need to do an RPC for this).
  2811. // ----------------------------------------------------
  2812. if (pPort->P_Status == CLOSED)
  2813. continue;
  2814. dwErr = RasGetInfo(hRasHandle,
  2815. pPort->P_Handle,
  2816. &rasmaninfo);
  2817. if (dwErr != ERROR_SUCCESS)
  2818. continue;
  2819. // If this is a dial-out port and in use
  2820. // mark it as active
  2821. // --------------------------------------------
  2822. if ((rasmaninfo.RI_ConnState == CONNECTED) &&
  2823. (pPort->P_ConfiguredUsage & (CALL_IN | CALL_ROUTER)) &&
  2824. (rasmaninfo.RI_CurrentUsage & CALL_OUT))
  2825. {
  2826. // Ok, this is a candidate. Add it to the list
  2827. // ----------------------------------------
  2828. WCHAR swzPortName[MAX_PORT_NAME+1];
  2829. StrnCpyWFromA(swzPortName,
  2830. pPort->P_PortName,
  2831. MAX_PORT_NAME);
  2832. m_map.SetAt(swzPortName, pPort);
  2833. }
  2834. }
  2835. return hr;
  2836. }
  2837. BOOL RasmanPortMap::FIsDialoutActive(LPCWSTR pswzPortName)
  2838. {
  2839. LPVOID pv;
  2840. return m_map.Lookup(pswzPortName, pv);
  2841. }