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

890 lines
29 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: C H K L I S T . C P P
  7. //
  8. // Contents: Implements bindings checkbox related utility functions
  9. // and classes.
  10. //
  11. // Notes:
  12. //
  13. // Created: tongl 20 Nov 1997
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "ncnetcfg.h"
  19. #include "ncui.h"
  20. #include "ncstl.h"
  21. #include "lanuiobj.h"
  22. #include "lanui.h"
  23. #include "util.h"
  24. #include "chklist.h"
  25. #include "ncperms.h"
  26. //+---------------------------------------------------------------------------
  27. //
  28. // Member: HrRebuildBindingPathObjCollection
  29. //
  30. // Purpose: Build or rebuild a list of BindingPathObjects,
  31. // establish the links between sub-paths and super-paths,
  32. // as well as between ComponentObjects in the list view
  33. // and elements of the BindingPathObject collection
  34. //
  35. // Arguments:
  36. // [IN] pnccAdapter
  37. // [IN] hList
  38. // [INOUT] pListObj
  39. //
  40. // Returns: TRUE
  41. //
  42. // Author: tongl 20 Nov 1997
  43. //
  44. // Notes:
  45. //
  46. HRESULT HrRebuildBindingPathObjCollection(INetCfgComponent * pnccAdapter,
  47. ListBPObj * pListBPObj)
  48. {
  49. HRESULT hr = S_OK;
  50. // now, add new BindingPathObjects to our list
  51. CIterNetCfgUpperBindingPath ncbpIter(pnccAdapter);
  52. INetCfgBindingPath * pncbp;
  53. TraceTag(ttidLanUi, "*** List of binding paths: begin ***");
  54. // Go through all upper binding paths starting from the current LAN
  55. // adapter, and add to our list of BindingPathObjects:
  56. while(SUCCEEDED(hr) && (hr = ncbpIter.HrNext(&pncbp)) == S_OK)
  57. {
  58. PrintBindingPath(ttidLanUi, pncbp, NULL);
  59. // create a new BindingPathObj
  60. CBindingPathObj * pBPObj = new CBindingPathObj(pncbp);
  61. // insert to our list, sorted by the length of the path
  62. // and establish super/sub path lists with existing items in
  63. // the list
  64. hr = HrInsertBindingPathObj(pListBPObj, pBPObj);
  65. ReleaseObj(pncbp);
  66. }
  67. TraceTag(ttidLanUi, "*** List of binding paths: end ***");
  68. #if DBG
  69. TraceTag(ttidLanUi, "%%% Begin dump the subpath list %%%");
  70. for (ListBPObj_ITER iter = pListBPObj->begin(); iter != pListBPObj->end(); iter++)
  71. {
  72. (*iter)->DumpSubPathList();
  73. }
  74. TraceTag(ttidLanUi, "%%% End dump the subpath list %%%");
  75. #endif
  76. if (hr == S_FALSE) // We just got to the end of the loop
  77. hr = S_OK;
  78. TraceError("HrRebuildBindingPathObjCollection", hr);
  79. return hr;
  80. }
  81. //+---------------------------------------------------------------------------
  82. //
  83. // Member: HrInsertBindingPathObj
  84. //
  85. // Purpose: Insert a BindingPathObj to a list of BindingPathObj's,
  86. // keep the list sorted by the length of paths.
  87. // Also establishs super/sub path lists with existing items
  88. // in the list.
  89. //
  90. // Arguments:
  91. // [INOUT] pListBPObj
  92. // [IN] pBPObj
  93. //
  94. // Returns: S_OK if succeeded,
  95. // otherwise return a failure code
  96. //
  97. // Author: tongl 20 Nov 1997
  98. //
  99. // Notes:
  100. //
  101. HRESULT HrInsertBindingPathObj(ListBPObj * pListBPObj,
  102. CBindingPathObj * pBPObj)
  103. {
  104. HRESULT hr = S_OK;
  105. HRESULT hrTmp = S_OK;
  106. ListBPObj_ITER iter;
  107. // insert the new element
  108. for (iter = pListBPObj->begin();iter != pListBPObj->end(); iter++)
  109. {
  110. if ((*iter)->GetDepth() > pBPObj->GetDepth())
  111. break;
  112. }
  113. // insert at the current position
  114. ListBPObj_ITER iterNewItem = pListBPObj->insert(iter, pBPObj);
  115. // set subpaths and superpaths
  116. // Because of the change in the new binding engine for paths for DONT_EXPOSE_LOWER
  117. // components, we have to compare with every item in the list because the length
  118. // no longer garantees which one is the subpath..
  119. for (iter = pListBPObj->begin(); iter != pListBPObj->end(); iter++)
  120. {
  121. // Is this a sub-path ?
  122. hrTmp = ((*iter)->m_pncbp)->IsSubPathOf((*iterNewItem)->m_pncbp);
  123. if (S_OK == hrTmp)
  124. {
  125. hrTmp = (*iter)->HrInsertSuperPath(*iterNewItem);
  126. if SUCCEEDED(hr)
  127. hr = hrTmp;
  128. hrTmp = (*iterNewItem)->HrInsertSubPath(*iter);
  129. if SUCCEEDED(hr)
  130. hr = hrTmp;
  131. }
  132. // Is this a super-path ?
  133. hrTmp = ((*iterNewItem)->m_pncbp)->IsSubPathOf((*iter)->m_pncbp);
  134. if (S_OK == hrTmp)
  135. {
  136. hrTmp = (*iter)->HrInsertSubPath(*iterNewItem);
  137. if SUCCEEDED(hr)
  138. hr = hrTmp;
  139. hrTmp = (*iterNewItem)->HrInsertSuperPath(*iter);
  140. if SUCCEEDED(hr)
  141. hr = hrTmp;
  142. }
  143. }
  144. TraceError("HrInsertBindingPathObj", hr);
  145. return hr;
  146. }
  147. //+---------------------------------------------------------------------------
  148. //
  149. // Member: HrRefreshBindingPathObjCollectionState
  150. //
  151. // Purpose: Refresh the binding state of all items in the collection
  152. // of BindingPathObjects
  153. //
  154. // Arguments:
  155. // [INOUT] pListBPObj
  156. //
  157. // Returns: S_OK if succeeded,
  158. // otherwise return a failure code
  159. //
  160. // Author: tongl 20 Nov 1997
  161. //
  162. // Notes:
  163. //
  164. HRESULT HrRefreshBindingPathObjCollectionState(ListBPObj * plistBPObj)
  165. {
  166. HRESULT hr = S_OK;
  167. ListBPObj_ITER iter;
  168. // first, clearup any existing state
  169. for (iter = plistBPObj->begin();iter != plistBPObj->end(); iter++)
  170. {
  171. (*iter)->SetBindingState(BPOBJ_UNSET);
  172. }
  173. // now set the new states
  174. TraceTag(ttidLanUi, "*** List of binding paths: begin ***");
  175. for (iter = plistBPObj->begin();iter != plistBPObj->end(); iter++)
  176. {
  177. Assert((*iter)->GetBindingState() != BPOBJ_ENABLED);
  178. #if DBG
  179. PrintBindingPath (ttidLanUi, (*iter)->m_pncbp, NULL);
  180. #endif
  181. if (BPOBJ_UNSET != (*iter)->GetBindingState())
  182. {
  183. continue;
  184. }
  185. // if it's not disabled yet, i.e. all of its sub paths
  186. // are enabled.
  187. hr = ((*iter)->m_pncbp)->IsEnabled();
  188. if (S_OK == hr) // enabled
  189. {
  190. (*iter)->SetBindingState(BPOBJ_ENABLED);
  191. continue;
  192. }
  193. else if (S_FALSE == hr) // disabled
  194. {
  195. // normal disabled case
  196. (*iter)->SetBindingState(BPOBJ_DISABLED);
  197. // special cases:
  198. // if the check state of the corresponding component is intent_check or mixed or checked
  199. if ((*iter)->m_pCompObj != NULL)
  200. {
  201. // if user is not intentionally unchecking this component
  202. if ((*iter)->m_pCompObj->m_ExpCheckState != UNCHECKED)
  203. {
  204. // if the component should be checked or if it's hidden
  205. if ((((*iter)->m_pCompObj)->m_CheckState == INTENT_CHECKED) ||
  206. (((*iter)->m_pCompObj)->m_CheckState == MIXED) ||
  207. (((*iter)->m_pCompObj)->m_CheckState == CHECKED))
  208. {
  209. // (#297772) We should only do this if one of the subpaths has just
  210. // been re-enabled by user
  211. BOOL fSubPathEnabled = FALSE;
  212. ListBPObj_ITER iterSub;
  213. for (iterSub = (*iter)->m_listSubPaths.begin();
  214. iterSub != (*iter)->m_listSubPaths.end();
  215. iterSub++)
  216. {
  217. // is the top component just enabled ?
  218. INetCfgComponent * pncc;
  219. hr = (*iterSub)->m_pncbp->GetOwner(&pncc);
  220. if (SUCCEEDED(hr))
  221. {
  222. if (((*iterSub)->m_pCompObj != NULL) &&
  223. (CHECKED == (*iterSub)->m_pCompObj->m_ExpCheckState))
  224. {
  225. fSubPathEnabled = TRUE;
  226. }
  227. ReleaseObj(pncc);
  228. if (fSubPathEnabled)
  229. break;
  230. }
  231. }
  232. if (fSubPathEnabled)
  233. {
  234. // Special case: enable the following binding path because
  235. // 1) it's check state is intent or mixed, and
  236. // 2) one of it's sub-paths is newly enabled
  237. #if DBG
  238. TraceTag(ttidLanUi, "Special case, enable the following path:");
  239. PrintBindingPath(ttidLanUi, (*iter)->m_pncbp, "\n");
  240. #endif
  241. hr = HrEnableBindingPath((*iter)->m_pncbp, TRUE);
  242. if (S_OK == hr)
  243. {
  244. (*iter)->SetBindingState(BPOBJ_ENABLED);
  245. continue;
  246. }
  247. }
  248. }
  249. }
  250. }
  251. }
  252. }
  253. TraceTag(ttidLanUi, "*** List of binding paths: end ***");
  254. TraceError("HrRefreshBindingPathObjCollectionState", hr);
  255. return hr;
  256. }
  257. //+---------------------------------------------------------------------------
  258. //
  259. // Member: HrRefreshCheckListState
  260. //
  261. // Purpose: Refresh the check state of all components in the list view
  262. //
  263. // Arguments:
  264. // hwndList[in]: Handle of the list view
  265. // pChangedCompObj[in]: Component object which state has
  266. // changed and has induced this refresh call.
  267. // This is used to keep a corresponding "undo" flag
  268. // for the changed component in case other components
  269. // are dependend on this component and the user decides
  270. // not to go through with the change.
  271. // Set to NULL if not applicable.
  272. //
  273. // Returns: S_OK if succeeded,
  274. // otherwise return a failure code
  275. //
  276. // Author: tongl 20 Nov 1997
  277. //
  278. // Notes:
  279. //
  280. HRESULT HrRefreshCheckListState(HWND hListView,
  281. CComponentObj *pChangedCompObj)
  282. {
  283. HRESULT hr = S_OK;
  284. TraceTag(ttidLanUi, "<<<<<Entering HrRefreshCheckListState");
  285. // for each item in the list view
  286. int nlvCount = ListView_GetItemCount(hListView);
  287. LV_ITEM lvItem;
  288. for (int i=0; i< nlvCount; i++)
  289. {
  290. lvItem.iItem = i;
  291. lvItem.iSubItem = 0;
  292. lvItem.mask = LVIF_PARAM;
  293. if (ListView_GetItem(hListView, &lvItem))
  294. {
  295. NET_ITEM_DATA * pnid;
  296. pnid = reinterpret_cast<NET_ITEM_DATA *>(lvItem.lParam);
  297. if (pnid)
  298. {
  299. // get the component object associated with this item
  300. CComponentObj * pCompObj = pnid->pCompObj;
  301. // assume the current component is not dependend on the
  302. // supplied changed component
  303. BOOL fDependedOnChangedComponent = FALSE;
  304. // get counts for enabled & disabled paths
  305. int iEnabled = 0;
  306. int iDisabled =0;
  307. // for each ComponentObject on the list
  308. ListBPObj_ITER iter;
  309. for (iter = (pCompObj->m_listBPObj).begin();
  310. iter != (pCompObj->m_listBPObj).end();
  311. iter++)
  312. {
  313. // the state should not be unset
  314. Assert((*iter)->m_BindingState != BPOBJ_UNSET);
  315. // if enabled
  316. switch ((*iter)->m_BindingState)
  317. {
  318. case BPOBJ_ENABLED:
  319. PrintBindingPath(ttidLanUi, (*iter)->m_pncbp, "is enabled");
  320. iEnabled++;
  321. break;
  322. case BPOBJ_DISABLED:
  323. PrintBindingPath(ttidLanUi, (*iter)->m_pncbp, "is disabled");
  324. // $REVIEW(tongl 1/19/98): According to SteveFal,
  325. // for paths with length>1, we only count "disabled" if
  326. // the sub paths are all enabled but the main path is disabled.
  327. // Bug #304606, can't use length any more with IPX special case
  328. {
  329. // Is all the subpaths enabled ?
  330. BOOL fAllSubPathsEnabled = TRUE;
  331. ListBPObj_ITER iterSubPath;
  332. for (iterSubPath = ((*iter)->m_listSubPaths).begin();
  333. iterSubPath != ((*iter)->m_listSubPaths).end();
  334. iterSubPath++)
  335. {
  336. if ((*iterSubPath)->m_BindingState == BPOBJ_DISABLED)
  337. {
  338. fAllSubPathsEnabled = FALSE;
  339. // Is the changed component part of this
  340. // component's sub paths?
  341. if (pChangedCompObj)
  342. {
  343. ListBPObj_ITER changedIter;
  344. for (changedIter = (pChangedCompObj->m_listBPObj).begin();
  345. changedIter != (pChangedCompObj->m_listBPObj).end();
  346. changedIter++)
  347. {
  348. // Don't need to compare sub path to itself
  349. if (pCompObj != pChangedCompObj)
  350. {
  351. hr = (*changedIter)->m_pncbp->IsSubPathOf((*iterSubPath)->m_pncbp);
  352. if (S_OK == hr)
  353. {
  354. fDependedOnChangedComponent = TRUE;
  355. break;
  356. }
  357. }
  358. }
  359. }
  360. break;
  361. }
  362. }
  363. if (fAllSubPathsEnabled)
  364. {
  365. // Is the binding path itself enabled ?
  366. hr = ((*iter)->m_pncbp)->IsEnabled();
  367. if (S_FALSE == hr)
  368. {
  369. iDisabled++;
  370. hr = S_OK;
  371. }
  372. }
  373. }
  374. break;
  375. default:
  376. PrintBindingPath(ttidLanUi, (*iter)->m_pncbp, "*** has an invalid binding state ***");
  377. break;
  378. }
  379. }
  380. UINT iChkIndex = 0;
  381. BOOL fHasPermission = FHasPermission(NCPERM_ChangeBindState);
  382. if (pnid->dwFlags & NCF_FIXED_BINDING)
  383. {
  384. // Don't change the checked state, we just want to prevent
  385. // the user from changing it.
  386. iChkIndex = SELS_FIXEDBINDING_ENABLED;
  387. }
  388. else if ((iEnabled >0) && (iDisabled == 0))
  389. {
  390. if (!fHasPermission)
  391. {
  392. iChkIndex = SELS_FIXEDBINDING_ENABLED;
  393. }
  394. else
  395. {
  396. // if we enabled the changed component,
  397. // it should not have any dependable
  398. // components anymore to "undo"
  399. if (pCompObj == pChangedCompObj)
  400. {
  401. pCompObj->m_DepStateChanged = FALSE;
  402. }
  403. // current state is "checked"
  404. pCompObj->m_CheckState = CHECKED;
  405. iChkIndex = SELS_CHECKED;
  406. }
  407. }
  408. else if ((iEnabled >0) && (iDisabled > 0))
  409. {
  410. if (!fHasPermission)
  411. {
  412. iChkIndex = SELS_FIXEDBINDING_ENABLED;
  413. }
  414. else
  415. {
  416. // current state is "mixed"
  417. pCompObj->m_CheckState = MIXED;
  418. iChkIndex = SELS_INTERMEDIATE;
  419. }
  420. }
  421. else //iEnabled ==0
  422. {
  423. if (!fHasPermission)
  424. {
  425. iChkIndex = SELS_FIXEDBINDING_DISABLED;
  426. }
  427. else
  428. {
  429. if (pCompObj->m_ExpCheckState == CHECKED)
  430. {
  431. // mark the component who caused this state
  432. // in order to be able to "undo" it later
  433. if ((pChangedCompObj) &&
  434. (fDependedOnChangedComponent))
  435. {
  436. pChangedCompObj->m_DepStateChanged = TRUE;
  437. }
  438. // change current state to "intent checked"
  439. pCompObj->m_CheckState = INTENT_CHECKED;
  440. // $REVIEW(tongl 1/19/98): SteveFal wants to show the
  441. // intent state as checked in the display
  442. // iChkIndex = SELS_INTENTCHECKED;
  443. iChkIndex = SELS_CHECKED;
  444. }
  445. else if (pCompObj->m_ExpCheckState == UNSET)
  446. {
  447. // we are not changing this component
  448. if ((pCompObj->m_CheckState == CHECKED) ||
  449. (pCompObj->m_CheckState == MIXED) ||
  450. (pCompObj->m_CheckState == INTENT_CHECKED))
  451. {
  452. // mark the component who caused this state
  453. // in order to be able to "undo" it later
  454. if ((pChangedCompObj) &&
  455. (fDependedOnChangedComponent))
  456. {
  457. pChangedCompObj->m_DepStateChanged = TRUE;
  458. }
  459. // set current state to "intent checked"
  460. pCompObj->m_CheckState = INTENT_CHECKED;
  461. // $REVIEW(tongl 1/19/98): SteveFal wants to show the
  462. // intent state as checked in the display
  463. // iChkIndex = SELS_INTENTCHECKED;
  464. iChkIndex = SELS_CHECKED;
  465. }
  466. else
  467. {
  468. // set current state to "unchecked"
  469. pCompObj->m_CheckState = UNCHECKED;
  470. iChkIndex = SELS_UNCHECKED;
  471. }
  472. }
  473. else
  474. {
  475. // current state is "unchecked"
  476. pCompObj->m_CheckState = UNCHECKED;
  477. iChkIndex = SELS_UNCHECKED;
  478. }
  479. }
  480. }
  481. // clear up expected check state
  482. pCompObj->m_ExpCheckState = UNSET;
  483. // update the checkmark
  484. AssertSz(iChkIndex, "What's the new check state ??");
  485. lvItem.mask = LVIF_STATE;
  486. lvItem.stateMask = LVIS_STATEIMAGEMASK;
  487. lvItem.state = INDEXTOSTATEIMAGEMASK(iChkIndex);
  488. BOOL ret = ListView_SetItem(hListView, &lvItem);
  489. }
  490. }
  491. }
  492. TraceError("HrRefreshCheckListState", hr);
  493. TraceTag(ttidLanUi, ">>>>>Leaving HrRefreshCheckListState");
  494. return hr;
  495. }
  496. //+---------------------------------------------------------------------------
  497. //
  498. // Member: HrEnableBindingPath
  499. //
  500. // Purpose: Wraps the INetCfgBindingPath->Enable method with the following
  501. // flags: if enabling, it applies to all hidden super paths, if
  502. // disabling, it applies to all super paths.
  503. //
  504. //
  505. // Arguments:
  506. // [IN] pncbp : the binding path to enable or disable
  507. // [IN] fEnable : Enable = TRUE; disable = FALSE
  508. //
  509. // Returns: S_OK if succeeded,
  510. // otherwise return a failure code
  511. //
  512. // Author: tongl 5 Dec 1997
  513. //
  514. // Notes:
  515. //
  516. HRESULT HrEnableBindingPath(INetCfgBindingPath * pncbpThis, BOOL fEnable)
  517. {
  518. HRESULT hr;
  519. hr = pncbpThis->Enable(fEnable);
  520. return hr;
  521. }
  522. //+---------------------------------------------------------------------------
  523. //
  524. // Member: CBindingPathObj implementation
  525. //
  526. // Author: tongl 20 Nov 1997
  527. //
  528. // Notes:
  529. //
  530. CBindingPathObj::CBindingPathObj(INetCfgBindingPath * pncbp)
  531. {
  532. Assert(pncbp);
  533. m_pncbp = pncbp;
  534. m_pncbp->AddRef();
  535. // Initialize other members
  536. m_pCompObj = NULL;
  537. m_BindingState = BPOBJ_UNSET;
  538. HRESULT hr = pncbp->GetDepth(&m_ulPathLen);
  539. TraceError("CBindingPathObj::CBindingPathObj failed on GetDepth", hr);
  540. }
  541. CBindingPathObj::~CBindingPathObj()
  542. {
  543. ReleaseObj(m_pncbp);
  544. m_listSubPaths.erase (m_listSubPaths.begin(), m_listSubPaths.end());
  545. m_listSuperPaths.erase (m_listSuperPaths.begin(), m_listSuperPaths.end());
  546. }
  547. HRESULT CBindingPathObj::HrInsertSuperPath(CBindingPathObj * pbpobjSuperPath)
  548. {
  549. HRESULT hr = S_OK;
  550. ListBPObj_ITER iter;
  551. // insert the new super path into the list, in increasing order of length
  552. for (iter = m_listSuperPaths.begin();
  553. iter != m_listSuperPaths.end();
  554. iter++)
  555. {
  556. if ((*iter)->GetDepth() > pbpobjSuperPath->GetDepth())
  557. break;
  558. }
  559. // insert at the current position
  560. ListBPObj_ITER iterNewItem = m_listSuperPaths.insert(iter, pbpobjSuperPath);
  561. TraceError("CBindingPathObj::HrInsertSuperPath", hr);
  562. return hr;
  563. }
  564. HRESULT CBindingPathObj::HrInsertSubPath(CBindingPathObj * pbpobjSubPath)
  565. {
  566. HRESULT hr = S_OK;
  567. ListBPObj_ITER iter;
  568. // insert the new sub path into the list, in decreasing order of length
  569. for (iter = m_listSubPaths.begin();
  570. iter != m_listSubPaths.end();
  571. iter++)
  572. {
  573. if ((*iter)->GetDepth() < pbpobjSubPath->GetDepth())
  574. break;
  575. }
  576. // insert at the current position
  577. ListBPObj_ITER iterNewItem = m_listSubPaths.insert(iter, pbpobjSubPath);
  578. TraceError("CBindingPathObj::HrInsertSubPath", hr);
  579. return hr;
  580. }
  581. HRESULT CBindingPathObj::HrEnable(ListBPObj * plistBPObj)
  582. {
  583. HRESULT hr = S_OK;
  584. #if DBG
  585. if (m_BindingState == BPOBJ_ENABLED)
  586. {
  587. TraceTag(ttidError, "Why trying to enable a path that is already enabled ?");
  588. }
  589. #endif
  590. AssertSz(m_ulPathLen > 1, "binding path length must be > 1");
  591. if (m_ulPathLen == 2)
  592. {
  593. // enable the current path
  594. hr = HrEnableBindingPath(m_pncbp, TRUE);
  595. }
  596. else
  597. {
  598. if (m_listSubPaths.size() <= 0)
  599. {
  600. PrintBindingPath(ttidLanUi, m_pncbp, "m_ulPathLen > 1, but no subpaths");
  601. AssertSz(FALSE, "if pathLen>1, there must be subpaths");
  602. }
  603. else
  604. {
  605. // check if the sub-path object is enabled, if not then we can't
  606. // enable this path ..
  607. if (m_listSubPaths.back()->m_BindingState == BPOBJ_ENABLED)
  608. {
  609. hr = HrEnableBindingPath(m_pncbp, TRUE);
  610. }
  611. }
  612. }
  613. // now refresh the BindingPathObjectList
  614. ::HrRefreshBindingPathObjCollectionState(plistBPObj);
  615. TraceError("CBindingPathObj::HrEnable", hr);
  616. return hr;
  617. }
  618. HRESULT CBindingPathObj::HrDisable(ListBPObj * plistBPObj)
  619. {
  620. HRESULT hr = S_OK;
  621. // Disable the current path
  622. hr = ::HrEnableBindingPath(m_pncbp, FALSE);
  623. if (S_OK == hr)
  624. {
  625. hr = ::HrRefreshBindingPathObjCollectionState(plistBPObj);
  626. }
  627. TraceError("CBindingPathObj::HrDisable", hr);
  628. return hr;
  629. }
  630. #if DBG
  631. VOID CBindingPathObj::DumpSubPathList()
  632. {
  633. TraceTag(ttidLanUi, " +++ Path: +++");
  634. PrintBindingPath(ttidLanUi, m_pncbp, NULL);
  635. if (m_listSubPaths.size())
  636. {
  637. TraceTag(ttidLanUi, "=== Subpaths: ===");
  638. for (ListBPObj_ITER iter = m_listSubPaths.begin();
  639. iter != m_listSubPaths.end();
  640. iter++)
  641. {
  642. (*iter)->DumpPath();
  643. }
  644. }
  645. }
  646. VOID CBindingPathObj::DumpPath()
  647. {
  648. PrintBindingPath(ttidLanUi, m_pncbp, NULL);
  649. }
  650. #endif
  651. //+---------------------------------------------------------------------------
  652. //
  653. // Member: CComponentObj implementation
  654. //
  655. // Author: tongl 20 Nov 1997
  656. //
  657. // Notes:
  658. //
  659. CComponentObj::CComponentObj(INetCfgComponent * pncc)
  660. {
  661. Assert(pncc);
  662. m_pncc = pncc;
  663. m_pncc->AddRef();
  664. // Initialize other members
  665. m_CheckState = UNSET;
  666. m_ExpCheckState = UNSET;
  667. m_DepStateChanged = FALSE;
  668. }
  669. CComponentObj::~CComponentObj()
  670. {
  671. ReleaseObj(m_pncc);
  672. m_listBPObj.erase (m_listBPObj.begin(), m_listBPObj.end());
  673. }
  674. HRESULT CComponentObj::HrInit(ListBPObj * plistBindingPaths)
  675. {
  676. PWSTR pszwThisId;
  677. HRESULT hr = m_pncc->GetId(&pszwThisId);
  678. if (SUCCEEDED(hr))
  679. {
  680. // builds the connection between a component object and a list of
  681. // binding path objects
  682. ListBPObj_ITER iter;
  683. for (iter = plistBindingPaths->begin();
  684. iter != plistBindingPaths->end();
  685. iter ++)
  686. {
  687. INetCfgComponent * pncc;
  688. hr = (*iter)->m_pncbp->GetOwner(&pncc);
  689. if SUCCEEDED(hr)
  690. {
  691. // check if the top component of the binding path is the
  692. // same component by comparing INF id
  693. PWSTR pszwId;
  694. hr = pncc->GetId (&pszwId);
  695. if (SUCCEEDED(hr))
  696. {
  697. if (FEqualComponentId (pszwId, pszwThisId))
  698. {
  699. // Add the BindingPathObj to the end of m_listBPObj
  700. m_listBPObj.push_back((*iter));
  701. // Make m_pCompObj of the BindingPathObj point to this ComponentObj
  702. Assert(NULL == (*iter)->m_pCompObj);
  703. (*iter)->m_pCompObj = this;
  704. }
  705. CoTaskMemFree(pszwId);
  706. }
  707. ReleaseObj(pncc);
  708. }
  709. }
  710. CoTaskMemFree(pszwThisId);
  711. }
  712. TraceError ("CComponentObj::HrInit", hr);
  713. return hr;
  714. }
  715. HRESULT CComponentObj::HrCheck(ListBPObj * plistBPObj)
  716. {
  717. HRESULT hr = S_OK;
  718. HRESULT hrTmp = S_OK;
  719. Assert(m_CheckState == UNCHECKED);
  720. // remember that user wanted to check (enable) this component
  721. m_ExpCheckState = CHECKED;
  722. ListBPObj_ITER iter;
  723. for (iter = m_listBPObj.begin();iter != m_listBPObj.end(); iter++)
  724. {
  725. // enable each binding path with enabled subpath
  726. hrTmp = (*iter)->HrEnable(plistBPObj);
  727. if SUCCEEDED(hr)
  728. hr = hrTmp;
  729. }
  730. TraceError("CComponentObj::HrCheck", hr);
  731. return hr;
  732. }
  733. HRESULT CComponentObj::HrUncheck(ListBPObj * plistBPObj)
  734. {
  735. HRESULT hr = S_OK;
  736. HRESULT hrTmp = S_OK;
  737. Assert(m_CheckState != UNCHECKED);
  738. // remember that user wanted to uncheck (disable) this component
  739. m_ExpCheckState = UNCHECKED;
  740. if (INTENT_CHECKED == m_CheckState)
  741. {
  742. m_CheckState = UNCHECKED;
  743. }
  744. else
  745. {
  746. ListBPObj_ITER iter;
  747. for (iter = m_listBPObj.begin();iter != m_listBPObj.end(); iter++)
  748. {
  749. // disable each binding path with enabled subpath
  750. hrTmp = (*iter)->HrDisable(plistBPObj);
  751. if SUCCEEDED(hr)
  752. hr = hrTmp;
  753. }
  754. }
  755. TraceError("CComponentObj::HrUnCheck", hr);
  756. return hr;
  757. }