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
890 lines
29 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: C H K L I S T . C P P
|
|
//
|
|
// Contents: Implements bindings checkbox related utility functions
|
|
// and classes.
|
|
//
|
|
// Notes:
|
|
//
|
|
// Created: tongl 20 Nov 1997
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include "ncnetcfg.h"
|
|
#include "ncui.h"
|
|
#include "ncstl.h"
|
|
#include "lanuiobj.h"
|
|
#include "lanui.h"
|
|
#include "util.h"
|
|
#include "chklist.h"
|
|
#include "ncperms.h"
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrRebuildBindingPathObjCollection
|
|
//
|
|
// Purpose: Build or rebuild a list of BindingPathObjects,
|
|
// establish the links between sub-paths and super-paths,
|
|
// as well as between ComponentObjects in the list view
|
|
// and elements of the BindingPathObject collection
|
|
//
|
|
// Arguments:
|
|
// [IN] pnccAdapter
|
|
// [IN] hList
|
|
// [INOUT] pListObj
|
|
//
|
|
// Returns: TRUE
|
|
//
|
|
// Author: tongl 20 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrRebuildBindingPathObjCollection(INetCfgComponent * pnccAdapter,
|
|
ListBPObj * pListBPObj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// now, add new BindingPathObjects to our list
|
|
CIterNetCfgUpperBindingPath ncbpIter(pnccAdapter);
|
|
INetCfgBindingPath * pncbp;
|
|
|
|
TraceTag(ttidLanUi, "*** List of binding paths: begin ***");
|
|
|
|
// Go through all upper binding paths starting from the current LAN
|
|
// adapter, and add to our list of BindingPathObjects:
|
|
while(SUCCEEDED(hr) && (hr = ncbpIter.HrNext(&pncbp)) == S_OK)
|
|
{
|
|
PrintBindingPath(ttidLanUi, pncbp, NULL);
|
|
|
|
// create a new BindingPathObj
|
|
CBindingPathObj * pBPObj = new CBindingPathObj(pncbp);
|
|
|
|
// insert to our list, sorted by the length of the path
|
|
// and establish super/sub path lists with existing items in
|
|
// the list
|
|
hr = HrInsertBindingPathObj(pListBPObj, pBPObj);
|
|
ReleaseObj(pncbp);
|
|
}
|
|
|
|
TraceTag(ttidLanUi, "*** List of binding paths: end ***");
|
|
|
|
#if DBG
|
|
TraceTag(ttidLanUi, "%%% Begin dump the subpath list %%%");
|
|
|
|
for (ListBPObj_ITER iter = pListBPObj->begin(); iter != pListBPObj->end(); iter++)
|
|
{
|
|
(*iter)->DumpSubPathList();
|
|
}
|
|
|
|
TraceTag(ttidLanUi, "%%% End dump the subpath list %%%");
|
|
#endif
|
|
|
|
if (hr == S_FALSE) // We just got to the end of the loop
|
|
hr = S_OK;
|
|
|
|
TraceError("HrRebuildBindingPathObjCollection", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrInsertBindingPathObj
|
|
//
|
|
// Purpose: Insert a BindingPathObj to a list of BindingPathObj's,
|
|
// keep the list sorted by the length of paths.
|
|
// Also establishs super/sub path lists with existing items
|
|
// in the list.
|
|
//
|
|
// Arguments:
|
|
// [INOUT] pListBPObj
|
|
// [IN] pBPObj
|
|
//
|
|
// Returns: S_OK if succeeded,
|
|
// otherwise return a failure code
|
|
//
|
|
// Author: tongl 20 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrInsertBindingPathObj(ListBPObj * pListBPObj,
|
|
CBindingPathObj * pBPObj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HRESULT hrTmp = S_OK;
|
|
|
|
ListBPObj_ITER iter;
|
|
|
|
// insert the new element
|
|
for (iter = pListBPObj->begin();iter != pListBPObj->end(); iter++)
|
|
{
|
|
if ((*iter)->GetDepth() > pBPObj->GetDepth())
|
|
break;
|
|
}
|
|
|
|
// insert at the current position
|
|
ListBPObj_ITER iterNewItem = pListBPObj->insert(iter, pBPObj);
|
|
|
|
// set subpaths and superpaths
|
|
// Because of the change in the new binding engine for paths for DONT_EXPOSE_LOWER
|
|
// components, we have to compare with every item in the list because the length
|
|
// no longer garantees which one is the subpath..
|
|
|
|
for (iter = pListBPObj->begin(); iter != pListBPObj->end(); iter++)
|
|
{
|
|
// Is this a sub-path ?
|
|
hrTmp = ((*iter)->m_pncbp)->IsSubPathOf((*iterNewItem)->m_pncbp);
|
|
if (S_OK == hrTmp)
|
|
{
|
|
hrTmp = (*iter)->HrInsertSuperPath(*iterNewItem);
|
|
if SUCCEEDED(hr)
|
|
hr = hrTmp;
|
|
|
|
hrTmp = (*iterNewItem)->HrInsertSubPath(*iter);
|
|
if SUCCEEDED(hr)
|
|
hr = hrTmp;
|
|
}
|
|
|
|
// Is this a super-path ?
|
|
hrTmp = ((*iterNewItem)->m_pncbp)->IsSubPathOf((*iter)->m_pncbp);
|
|
if (S_OK == hrTmp)
|
|
{
|
|
hrTmp = (*iter)->HrInsertSubPath(*iterNewItem);
|
|
if SUCCEEDED(hr)
|
|
hr = hrTmp;
|
|
|
|
hrTmp = (*iterNewItem)->HrInsertSuperPath(*iter);
|
|
if SUCCEEDED(hr)
|
|
hr = hrTmp;
|
|
}
|
|
}
|
|
|
|
TraceError("HrInsertBindingPathObj", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrRefreshBindingPathObjCollectionState
|
|
//
|
|
// Purpose: Refresh the binding state of all items in the collection
|
|
// of BindingPathObjects
|
|
//
|
|
// Arguments:
|
|
// [INOUT] pListBPObj
|
|
//
|
|
// Returns: S_OK if succeeded,
|
|
// otherwise return a failure code
|
|
//
|
|
// Author: tongl 20 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrRefreshBindingPathObjCollectionState(ListBPObj * plistBPObj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ListBPObj_ITER iter;
|
|
|
|
// first, clearup any existing state
|
|
for (iter = plistBPObj->begin();iter != plistBPObj->end(); iter++)
|
|
{
|
|
(*iter)->SetBindingState(BPOBJ_UNSET);
|
|
}
|
|
|
|
// now set the new states
|
|
TraceTag(ttidLanUi, "*** List of binding paths: begin ***");
|
|
|
|
for (iter = plistBPObj->begin();iter != plistBPObj->end(); iter++)
|
|
{
|
|
Assert((*iter)->GetBindingState() != BPOBJ_ENABLED);
|
|
|
|
#if DBG
|
|
PrintBindingPath (ttidLanUi, (*iter)->m_pncbp, NULL);
|
|
#endif
|
|
|
|
if (BPOBJ_UNSET != (*iter)->GetBindingState())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// if it's not disabled yet, i.e. all of its sub paths
|
|
// are enabled.
|
|
hr = ((*iter)->m_pncbp)->IsEnabled();
|
|
if (S_OK == hr) // enabled
|
|
{
|
|
(*iter)->SetBindingState(BPOBJ_ENABLED);
|
|
continue;
|
|
}
|
|
else if (S_FALSE == hr) // disabled
|
|
{
|
|
// normal disabled case
|
|
(*iter)->SetBindingState(BPOBJ_DISABLED);
|
|
|
|
// special cases:
|
|
// if the check state of the corresponding component is intent_check or mixed or checked
|
|
if ((*iter)->m_pCompObj != NULL)
|
|
{
|
|
// if user is not intentionally unchecking this component
|
|
if ((*iter)->m_pCompObj->m_ExpCheckState != UNCHECKED)
|
|
{
|
|
// if the component should be checked or if it's hidden
|
|
if ((((*iter)->m_pCompObj)->m_CheckState == INTENT_CHECKED) ||
|
|
(((*iter)->m_pCompObj)->m_CheckState == MIXED) ||
|
|
(((*iter)->m_pCompObj)->m_CheckState == CHECKED))
|
|
{
|
|
// (#297772) We should only do this if one of the subpaths has just
|
|
// been re-enabled by user
|
|
BOOL fSubPathEnabled = FALSE;
|
|
|
|
ListBPObj_ITER iterSub;
|
|
for (iterSub = (*iter)->m_listSubPaths.begin();
|
|
iterSub != (*iter)->m_listSubPaths.end();
|
|
iterSub++)
|
|
{
|
|
// is the top component just enabled ?
|
|
INetCfgComponent * pncc;
|
|
hr = (*iterSub)->m_pncbp->GetOwner(&pncc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (((*iterSub)->m_pCompObj != NULL) &&
|
|
(CHECKED == (*iterSub)->m_pCompObj->m_ExpCheckState))
|
|
{
|
|
fSubPathEnabled = TRUE;
|
|
}
|
|
ReleaseObj(pncc);
|
|
|
|
if (fSubPathEnabled)
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fSubPathEnabled)
|
|
{
|
|
// Special case: enable the following binding path because
|
|
// 1) it's check state is intent or mixed, and
|
|
// 2) one of it's sub-paths is newly enabled
|
|
#if DBG
|
|
TraceTag(ttidLanUi, "Special case, enable the following path:");
|
|
PrintBindingPath(ttidLanUi, (*iter)->m_pncbp, "\n");
|
|
#endif
|
|
|
|
hr = HrEnableBindingPath((*iter)->m_pncbp, TRUE);
|
|
if (S_OK == hr)
|
|
{
|
|
(*iter)->SetBindingState(BPOBJ_ENABLED);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
TraceTag(ttidLanUi, "*** List of binding paths: end ***");
|
|
|
|
TraceError("HrRefreshBindingPathObjCollectionState", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrRefreshCheckListState
|
|
//
|
|
// Purpose: Refresh the check state of all components in the list view
|
|
//
|
|
// Arguments:
|
|
// hwndList[in]: Handle of the list view
|
|
// pChangedCompObj[in]: Component object which state has
|
|
// changed and has induced this refresh call.
|
|
// This is used to keep a corresponding "undo" flag
|
|
// for the changed component in case other components
|
|
// are dependend on this component and the user decides
|
|
// not to go through with the change.
|
|
// Set to NULL if not applicable.
|
|
//
|
|
// Returns: S_OK if succeeded,
|
|
// otherwise return a failure code
|
|
//
|
|
// Author: tongl 20 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT HrRefreshCheckListState(HWND hListView,
|
|
CComponentObj *pChangedCompObj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceTag(ttidLanUi, "<<<<<Entering HrRefreshCheckListState");
|
|
|
|
// for each item in the list view
|
|
int nlvCount = ListView_GetItemCount(hListView);
|
|
|
|
LV_ITEM lvItem;
|
|
|
|
for (int i=0; i< nlvCount; i++)
|
|
{
|
|
lvItem.iItem = i;
|
|
lvItem.iSubItem = 0;
|
|
|
|
lvItem.mask = LVIF_PARAM;
|
|
if (ListView_GetItem(hListView, &lvItem))
|
|
{
|
|
NET_ITEM_DATA * pnid;
|
|
|
|
pnid = reinterpret_cast<NET_ITEM_DATA *>(lvItem.lParam);
|
|
|
|
if (pnid)
|
|
{
|
|
// get the component object associated with this item
|
|
CComponentObj * pCompObj = pnid->pCompObj;
|
|
|
|
// assume the current component is not dependend on the
|
|
// supplied changed component
|
|
BOOL fDependedOnChangedComponent = FALSE;
|
|
|
|
// get counts for enabled & disabled paths
|
|
int iEnabled = 0;
|
|
int iDisabled =0;
|
|
|
|
// for each ComponentObject on the list
|
|
ListBPObj_ITER iter;
|
|
for (iter = (pCompObj->m_listBPObj).begin();
|
|
iter != (pCompObj->m_listBPObj).end();
|
|
iter++)
|
|
{
|
|
// the state should not be unset
|
|
Assert((*iter)->m_BindingState != BPOBJ_UNSET);
|
|
|
|
// if enabled
|
|
switch ((*iter)->m_BindingState)
|
|
{
|
|
case BPOBJ_ENABLED:
|
|
|
|
PrintBindingPath(ttidLanUi, (*iter)->m_pncbp, "is enabled");
|
|
|
|
iEnabled++;
|
|
break;
|
|
|
|
case BPOBJ_DISABLED:
|
|
|
|
PrintBindingPath(ttidLanUi, (*iter)->m_pncbp, "is disabled");
|
|
|
|
// $REVIEW(tongl 1/19/98): According to SteveFal,
|
|
// for paths with length>1, we only count "disabled" if
|
|
// the sub paths are all enabled but the main path is disabled.
|
|
|
|
// Bug #304606, can't use length any more with IPX special case
|
|
{
|
|
// Is all the subpaths enabled ?
|
|
BOOL fAllSubPathsEnabled = TRUE;
|
|
ListBPObj_ITER iterSubPath;
|
|
for (iterSubPath = ((*iter)->m_listSubPaths).begin();
|
|
iterSubPath != ((*iter)->m_listSubPaths).end();
|
|
iterSubPath++)
|
|
{
|
|
|
|
if ((*iterSubPath)->m_BindingState == BPOBJ_DISABLED)
|
|
{
|
|
fAllSubPathsEnabled = FALSE;
|
|
|
|
// Is the changed component part of this
|
|
// component's sub paths?
|
|
if (pChangedCompObj)
|
|
{
|
|
ListBPObj_ITER changedIter;
|
|
for (changedIter = (pChangedCompObj->m_listBPObj).begin();
|
|
changedIter != (pChangedCompObj->m_listBPObj).end();
|
|
changedIter++)
|
|
{
|
|
// Don't need to compare sub path to itself
|
|
if (pCompObj != pChangedCompObj)
|
|
{
|
|
hr = (*changedIter)->m_pncbp->IsSubPathOf((*iterSubPath)->m_pncbp);
|
|
if (S_OK == hr)
|
|
{
|
|
fDependedOnChangedComponent = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fAllSubPathsEnabled)
|
|
{
|
|
// Is the binding path itself enabled ?
|
|
hr = ((*iter)->m_pncbp)->IsEnabled();
|
|
if (S_FALSE == hr)
|
|
{
|
|
iDisabled++;
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
PrintBindingPath(ttidLanUi, (*iter)->m_pncbp, "*** has an invalid binding state ***");
|
|
break;
|
|
}
|
|
}
|
|
|
|
UINT iChkIndex = 0;
|
|
BOOL fHasPermission = FHasPermission(NCPERM_ChangeBindState);
|
|
|
|
if (pnid->dwFlags & NCF_FIXED_BINDING)
|
|
{
|
|
// Don't change the checked state, we just want to prevent
|
|
// the user from changing it.
|
|
iChkIndex = SELS_FIXEDBINDING_ENABLED;
|
|
}
|
|
else if ((iEnabled >0) && (iDisabled == 0))
|
|
{
|
|
if (!fHasPermission)
|
|
{
|
|
iChkIndex = SELS_FIXEDBINDING_ENABLED;
|
|
}
|
|
else
|
|
{
|
|
// if we enabled the changed component,
|
|
// it should not have any dependable
|
|
// components anymore to "undo"
|
|
if (pCompObj == pChangedCompObj)
|
|
{
|
|
pCompObj->m_DepStateChanged = FALSE;
|
|
}
|
|
|
|
// current state is "checked"
|
|
pCompObj->m_CheckState = CHECKED;
|
|
iChkIndex = SELS_CHECKED;
|
|
}
|
|
}
|
|
else if ((iEnabled >0) && (iDisabled > 0))
|
|
{
|
|
if (!fHasPermission)
|
|
{
|
|
iChkIndex = SELS_FIXEDBINDING_ENABLED;
|
|
}
|
|
else
|
|
{
|
|
// current state is "mixed"
|
|
pCompObj->m_CheckState = MIXED;
|
|
iChkIndex = SELS_INTERMEDIATE;
|
|
}
|
|
}
|
|
else //iEnabled ==0
|
|
{
|
|
if (!fHasPermission)
|
|
{
|
|
iChkIndex = SELS_FIXEDBINDING_DISABLED;
|
|
}
|
|
else
|
|
{
|
|
if (pCompObj->m_ExpCheckState == CHECKED)
|
|
{
|
|
// mark the component who caused this state
|
|
// in order to be able to "undo" it later
|
|
if ((pChangedCompObj) &&
|
|
(fDependedOnChangedComponent))
|
|
{
|
|
pChangedCompObj->m_DepStateChanged = TRUE;
|
|
}
|
|
|
|
// change current state to "intent checked"
|
|
pCompObj->m_CheckState = INTENT_CHECKED;
|
|
|
|
// $REVIEW(tongl 1/19/98): SteveFal wants to show the
|
|
// intent state as checked in the display
|
|
// iChkIndex = SELS_INTENTCHECKED;
|
|
iChkIndex = SELS_CHECKED;
|
|
}
|
|
else if (pCompObj->m_ExpCheckState == UNSET)
|
|
{
|
|
// we are not changing this component
|
|
if ((pCompObj->m_CheckState == CHECKED) ||
|
|
(pCompObj->m_CheckState == MIXED) ||
|
|
(pCompObj->m_CheckState == INTENT_CHECKED))
|
|
{
|
|
// mark the component who caused this state
|
|
// in order to be able to "undo" it later
|
|
if ((pChangedCompObj) &&
|
|
(fDependedOnChangedComponent))
|
|
{
|
|
pChangedCompObj->m_DepStateChanged = TRUE;
|
|
}
|
|
|
|
// set current state to "intent checked"
|
|
pCompObj->m_CheckState = INTENT_CHECKED;
|
|
|
|
// $REVIEW(tongl 1/19/98): SteveFal wants to show the
|
|
// intent state as checked in the display
|
|
// iChkIndex = SELS_INTENTCHECKED;
|
|
iChkIndex = SELS_CHECKED;
|
|
}
|
|
else
|
|
{
|
|
// set current state to "unchecked"
|
|
pCompObj->m_CheckState = UNCHECKED;
|
|
iChkIndex = SELS_UNCHECKED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// current state is "unchecked"
|
|
pCompObj->m_CheckState = UNCHECKED;
|
|
iChkIndex = SELS_UNCHECKED;
|
|
}
|
|
}
|
|
}
|
|
|
|
// clear up expected check state
|
|
pCompObj->m_ExpCheckState = UNSET;
|
|
|
|
// update the checkmark
|
|
AssertSz(iChkIndex, "What's the new check state ??");
|
|
|
|
lvItem.mask = LVIF_STATE;
|
|
lvItem.stateMask = LVIS_STATEIMAGEMASK;
|
|
lvItem.state = INDEXTOSTATEIMAGEMASK(iChkIndex);
|
|
BOOL ret = ListView_SetItem(hListView, &lvItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceError("HrRefreshCheckListState", hr);
|
|
|
|
TraceTag(ttidLanUi, ">>>>>Leaving HrRefreshCheckListState");
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrEnableBindingPath
|
|
//
|
|
// Purpose: Wraps the INetCfgBindingPath->Enable method with the following
|
|
// flags: if enabling, it applies to all hidden super paths, if
|
|
// disabling, it applies to all super paths.
|
|
//
|
|
//
|
|
// Arguments:
|
|
// [IN] pncbp : the binding path to enable or disable
|
|
// [IN] fEnable : Enable = TRUE; disable = FALSE
|
|
//
|
|
// Returns: S_OK if succeeded,
|
|
// otherwise return a failure code
|
|
//
|
|
// Author: tongl 5 Dec 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrEnableBindingPath(INetCfgBindingPath * pncbpThis, BOOL fEnable)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = pncbpThis->Enable(fEnable);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBindingPathObj implementation
|
|
//
|
|
// Author: tongl 20 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
CBindingPathObj::CBindingPathObj(INetCfgBindingPath * pncbp)
|
|
{
|
|
Assert(pncbp);
|
|
m_pncbp = pncbp;
|
|
m_pncbp->AddRef();
|
|
|
|
// Initialize other members
|
|
m_pCompObj = NULL;
|
|
|
|
m_BindingState = BPOBJ_UNSET;
|
|
|
|
HRESULT hr = pncbp->GetDepth(&m_ulPathLen);
|
|
TraceError("CBindingPathObj::CBindingPathObj failed on GetDepth", hr);
|
|
}
|
|
|
|
CBindingPathObj::~CBindingPathObj()
|
|
{
|
|
ReleaseObj(m_pncbp);
|
|
|
|
m_listSubPaths.erase (m_listSubPaths.begin(), m_listSubPaths.end());
|
|
m_listSuperPaths.erase (m_listSuperPaths.begin(), m_listSuperPaths.end());
|
|
}
|
|
|
|
HRESULT CBindingPathObj::HrInsertSuperPath(CBindingPathObj * pbpobjSuperPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
ListBPObj_ITER iter;
|
|
|
|
// insert the new super path into the list, in increasing order of length
|
|
for (iter = m_listSuperPaths.begin();
|
|
iter != m_listSuperPaths.end();
|
|
iter++)
|
|
{
|
|
if ((*iter)->GetDepth() > pbpobjSuperPath->GetDepth())
|
|
break;
|
|
}
|
|
|
|
// insert at the current position
|
|
ListBPObj_ITER iterNewItem = m_listSuperPaths.insert(iter, pbpobjSuperPath);
|
|
|
|
TraceError("CBindingPathObj::HrInsertSuperPath", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CBindingPathObj::HrInsertSubPath(CBindingPathObj * pbpobjSubPath)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
ListBPObj_ITER iter;
|
|
|
|
// insert the new sub path into the list, in decreasing order of length
|
|
for (iter = m_listSubPaths.begin();
|
|
iter != m_listSubPaths.end();
|
|
iter++)
|
|
{
|
|
if ((*iter)->GetDepth() < pbpobjSubPath->GetDepth())
|
|
break;
|
|
}
|
|
|
|
// insert at the current position
|
|
ListBPObj_ITER iterNewItem = m_listSubPaths.insert(iter, pbpobjSubPath);
|
|
|
|
TraceError("CBindingPathObj::HrInsertSubPath", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CBindingPathObj::HrEnable(ListBPObj * plistBPObj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
#if DBG
|
|
if (m_BindingState == BPOBJ_ENABLED)
|
|
{
|
|
TraceTag(ttidError, "Why trying to enable a path that is already enabled ?");
|
|
}
|
|
#endif
|
|
|
|
AssertSz(m_ulPathLen > 1, "binding path length must be > 1");
|
|
|
|
if (m_ulPathLen == 2)
|
|
{
|
|
// enable the current path
|
|
hr = HrEnableBindingPath(m_pncbp, TRUE);
|
|
}
|
|
else
|
|
{
|
|
if (m_listSubPaths.size() <= 0)
|
|
{
|
|
PrintBindingPath(ttidLanUi, m_pncbp, "m_ulPathLen > 1, but no subpaths");
|
|
AssertSz(FALSE, "if pathLen>1, there must be subpaths");
|
|
}
|
|
else
|
|
{
|
|
// check if the sub-path object is enabled, if not then we can't
|
|
// enable this path ..
|
|
if (m_listSubPaths.back()->m_BindingState == BPOBJ_ENABLED)
|
|
{
|
|
hr = HrEnableBindingPath(m_pncbp, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
// now refresh the BindingPathObjectList
|
|
::HrRefreshBindingPathObjCollectionState(plistBPObj);
|
|
|
|
TraceError("CBindingPathObj::HrEnable", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CBindingPathObj::HrDisable(ListBPObj * plistBPObj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Disable the current path
|
|
hr = ::HrEnableBindingPath(m_pncbp, FALSE);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
hr = ::HrRefreshBindingPathObjCollectionState(plistBPObj);
|
|
}
|
|
|
|
TraceError("CBindingPathObj::HrDisable", hr);
|
|
return hr;
|
|
}
|
|
|
|
#if DBG
|
|
VOID CBindingPathObj::DumpSubPathList()
|
|
{
|
|
TraceTag(ttidLanUi, " +++ Path: +++");
|
|
|
|
PrintBindingPath(ttidLanUi, m_pncbp, NULL);
|
|
|
|
if (m_listSubPaths.size())
|
|
{
|
|
TraceTag(ttidLanUi, "=== Subpaths: ===");
|
|
|
|
for (ListBPObj_ITER iter = m_listSubPaths.begin();
|
|
iter != m_listSubPaths.end();
|
|
iter++)
|
|
{
|
|
(*iter)->DumpPath();
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID CBindingPathObj::DumpPath()
|
|
{
|
|
PrintBindingPath(ttidLanUi, m_pncbp, NULL);
|
|
}
|
|
#endif
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CComponentObj implementation
|
|
//
|
|
// Author: tongl 20 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
CComponentObj::CComponentObj(INetCfgComponent * pncc)
|
|
{
|
|
Assert(pncc);
|
|
m_pncc = pncc;
|
|
m_pncc->AddRef();
|
|
|
|
// Initialize other members
|
|
m_CheckState = UNSET;
|
|
m_ExpCheckState = UNSET;
|
|
m_DepStateChanged = FALSE;
|
|
}
|
|
|
|
CComponentObj::~CComponentObj()
|
|
{
|
|
ReleaseObj(m_pncc);
|
|
m_listBPObj.erase (m_listBPObj.begin(), m_listBPObj.end());
|
|
}
|
|
|
|
HRESULT CComponentObj::HrInit(ListBPObj * plistBindingPaths)
|
|
{
|
|
PWSTR pszwThisId;
|
|
HRESULT hr = m_pncc->GetId(&pszwThisId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// builds the connection between a component object and a list of
|
|
// binding path objects
|
|
|
|
ListBPObj_ITER iter;
|
|
|
|
for (iter = plistBindingPaths->begin();
|
|
iter != plistBindingPaths->end();
|
|
iter ++)
|
|
{
|
|
INetCfgComponent * pncc;
|
|
hr = (*iter)->m_pncbp->GetOwner(&pncc);
|
|
|
|
if SUCCEEDED(hr)
|
|
{
|
|
// check if the top component of the binding path is the
|
|
// same component by comparing INF id
|
|
PWSTR pszwId;
|
|
hr = pncc->GetId (&pszwId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (FEqualComponentId (pszwId, pszwThisId))
|
|
{
|
|
// Add the BindingPathObj to the end of m_listBPObj
|
|
m_listBPObj.push_back((*iter));
|
|
|
|
// Make m_pCompObj of the BindingPathObj point to this ComponentObj
|
|
Assert(NULL == (*iter)->m_pCompObj);
|
|
(*iter)->m_pCompObj = this;
|
|
}
|
|
|
|
CoTaskMemFree(pszwId);
|
|
}
|
|
|
|
ReleaseObj(pncc);
|
|
}
|
|
}
|
|
|
|
CoTaskMemFree(pszwThisId);
|
|
}
|
|
|
|
TraceError ("CComponentObj::HrInit", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CComponentObj::HrCheck(ListBPObj * plistBPObj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HRESULT hrTmp = S_OK;
|
|
|
|
Assert(m_CheckState == UNCHECKED);
|
|
|
|
// remember that user wanted to check (enable) this component
|
|
m_ExpCheckState = CHECKED;
|
|
|
|
ListBPObj_ITER iter;
|
|
for (iter = m_listBPObj.begin();iter != m_listBPObj.end(); iter++)
|
|
{
|
|
// enable each binding path with enabled subpath
|
|
hrTmp = (*iter)->HrEnable(plistBPObj);
|
|
|
|
if SUCCEEDED(hr)
|
|
hr = hrTmp;
|
|
}
|
|
|
|
TraceError("CComponentObj::HrCheck", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CComponentObj::HrUncheck(ListBPObj * plistBPObj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HRESULT hrTmp = S_OK;
|
|
|
|
Assert(m_CheckState != UNCHECKED);
|
|
|
|
// remember that user wanted to uncheck (disable) this component
|
|
m_ExpCheckState = UNCHECKED;
|
|
|
|
if (INTENT_CHECKED == m_CheckState)
|
|
{
|
|
m_CheckState = UNCHECKED;
|
|
}
|
|
else
|
|
{
|
|
ListBPObj_ITER iter;
|
|
for (iter = m_listBPObj.begin();iter != m_listBPObj.end(); iter++)
|
|
{
|
|
// disable each binding path with enabled subpath
|
|
hrTmp = (*iter)->HrDisable(plistBPObj);
|
|
|
|
if SUCCEEDED(hr)
|
|
hr = hrTmp;
|
|
}
|
|
}
|
|
|
|
TraceError("CComponentObj::HrUnCheck", hr);
|
|
return hr;
|
|
}
|
|
|