//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1999. // // File: I C O M P . C P P // // Contents: Implements the INetCfgComponent COM interface. // // Notes: // // Author: shaunco 15 Jan 1999 // //---------------------------------------------------------------------------- #include #pragma hdrstop #include "ibind.h" #include "icomp.h" #include "ienum.h" #include "nccfgmgr.h" #include "ncreg.h" #include "ncsetup.h" #include "ncvalid.h" #include "netcfg.h" #include "netconp.h" #include "util.h" HRESULT HrIsValidINetCfgComponent ( IN INetCfgComponent* pICompInterface) { Assert (pICompInterface); CImplINetCfgComponent* pIComp; pIComp = (CImplINetCfgComponent*)pICompInterface; if (pIComp == NULL) { return(E_OUTOFMEMORY); } return pIComp->HrIsValidInterface (IF_DEFAULT); } CComponent* PComponentFromComInterface ( IN INetCfgComponent* pICompInterface) { Assert (pICompInterface); CImplINetCfgComponent* pIComp; pIComp = (CImplINetCfgComponent*)pICompInterface; // Can't do the following assert because we may be referencing the // component before it has been added to the core. This case is possible // when installing a new component that installed a required component // on behalf of itself. We will wind up in the function when adding // the refernce for the obo token. // //Assert (S_OK == pIComp->HrIsValidInterface (dwFlags)); Assert (pIComp->m_pComponent); return pIComp->m_pComponent; } // static HRESULT CImplINetCfgComponent::HrCreateInstance ( IN CImplINetCfg* pINetCfg, IN CComponent* pComponent, OUT CImplINetCfgComponent** ppIComp) { HRESULT hr = E_OUTOFMEMORY; CImplINetCfgComponent* pObj; pObj = new CComObject ; if (pObj) { // Initialize our members. // pObj->m_pComponent = pComponent; // Do the standard CComCreator::CreateInstance stuff. // pObj->SetVoid (NULL); pObj->InternalFinalConstructAddRef (); hr = pObj->FinalConstruct (); pObj->InternalFinalConstructRelease (); if (S_OK == hr) { // The last thing we do is addref any interfaces we hold. // We only do this if we are returning success. // pObj->HoldINetCfg (pINetCfg); AddRefObj (pObj->GetUnknown()); *ppIComp = pObj; } if (S_OK != hr) { delete pObj; } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::HrCreateInstance"); return hr; } HRESULT CImplINetCfgComponent::HrIsValidInterface ( IN DWORD dwFlags) { HRESULT hr; hr = m_pINetCfg->HrIsValidInterface (dwFlags); if (S_OK != hr) { return hr; } // Check for deleted component. // if (!m_pComponent) { return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE); } // If we made it this far, the component this interface represents // should definately be in the core component list or in the core // that we started with in the case that this component is in the middle // of being removed. // Assert(m_pINetCfg->m_pNetConfig->Core.Components. FComponentInList (m_pComponent) || m_pINetCfg->m_pNetConfig->ModifyCtx.m_CoreStartedWith.Components. FComponentInList (m_pComponent)); if (dwFlags & IF_NEED_COMPONENT_DATA) { hr = m_pComponent->Ext.HrEnsureExternalDataLoaded (); } return hr; } // We need to override CImplINetCfgHolder::HrLockAndTestForValidInterface // because we have our own HrIsValidInterface to be called. // HRESULT CImplINetCfgComponent::HrLockAndTestForValidInterface ( IN DWORD dwFlags, IN INetCfgComponent* pIOtherComp, OPTIONAL OUT CComponent** ppOtherComp OPTIONAL) { HRESULT hr; Lock(); hr = HrIsValidInterface (dwFlags); // If pIOtherComp was passed in, the caller wants that interface // validated and the internal CComponent pointer for it returned. // if ((S_OK == hr) && pIOtherComp) { CImplINetCfgComponent* pOther; Assert (ppOtherComp); pOther = (CImplINetCfgComponent*)pIOtherComp; hr = pOther->HrIsValidInterface (IF_NEED_COMPONENT_DATA); if (S_OK == hr) { *ppOtherComp = pOther->m_pComponent; } } if (S_OK != hr) { Unlock(); } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::HrLockAndTestForValidInterface"); return hr; } HRESULT CImplINetCfgComponent::HrAccessExternalStringAtOffsetAndCopy ( IN UINT unOffset, OUT PWSTR* ppszDst) { HRESULT hr; // Validate parameter. // if (FBadOutPtr (ppszDst)) { hr = E_POINTER; } else { *ppszDst = NULL; hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL); if (S_OK == hr) { hr = HrCoTaskMemAllocAndDupSz ( m_pComponent->Ext.PszAtOffset (unOffset), ppszDst, MAX_INF_STRING_LENGTH); Unlock(); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::HrAccessExternalStringAtOffsetAndCopy"); return hr; } //+--------------------------------------------------------------------------- // INetCfgComponent - // STDMETHODIMP CImplINetCfgComponent::GetDisplayName ( OUT PWSTR* ppszDisplayName) { HRESULT hr; hr = HrAccessExternalStringAtOffsetAndCopy ( ECD_OFFSET(m_pszDescription), ppszDisplayName); TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetDisplayName"); return hr; } STDMETHODIMP CImplINetCfgComponent::SetDisplayName ( IN PCWSTR pszDisplayName) { HRESULT hr; // Validate parameter. // if (FBadInPtr (pszDisplayName)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL); if (S_OK == hr) { // We only allow changing the display name (SPDRP_FRIENDLYNAME, // actually) of enumerated components. // if (FIsEnumerated(m_pComponent->Class())) { HDEVINFO hdi; SP_DEVINFO_DATA deid; hr = m_pComponent->HrOpenDeviceInfo (&hdi, &deid); if (S_OK == hr) { hr = HrSetupDiSetDeviceName (hdi, &deid, pszDisplayName); if (S_OK == hr) { m_pComponent->Ext.HrSetDescription (pszDisplayName); } SetupDiDestroyDeviceInfoList (hdi); } } else { hr = E_NOTIMPL; } Unlock(); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::SetDisplayName"); return hr; } STDMETHODIMP CImplINetCfgComponent::GetHelpText ( OUT PWSTR* pszHelpText) { HRESULT hr; hr = HrAccessExternalStringAtOffsetAndCopy ( ECD_OFFSET(m_pszHelpText), pszHelpText); TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetHelpText"); return hr; } STDMETHODIMP CImplINetCfgComponent::GetId ( OUT PWSTR* ppszId) { HRESULT hr; // Validate parameters. // if (FBadOutPtr (ppszId)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL); if (S_OK == hr) { hr = HrCoTaskMemAllocAndDupSz ( m_pComponent->m_pszInfId, ppszId, MAX_DEVICE_ID_LEN); Unlock(); } else { *ppszId = NULL; } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetId"); return hr; } STDMETHODIMP CImplINetCfgComponent::GetCharacteristics ( OUT LPDWORD pdwCharacteristics) { HRESULT hr; // Validate parameters. // if (FBadOutPtr (pdwCharacteristics)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL); if (S_OK == hr) { *pdwCharacteristics = m_pComponent->m_dwCharacter; Unlock(); } else { *pdwCharacteristics = 0; } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetCharacteristics"); return hr; } STDMETHODIMP CImplINetCfgComponent::GetInstanceGuid ( OUT GUID* pInstanceGuid) { HRESULT hr; // Validate parameters. // if (FBadOutPtr (pInstanceGuid)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL); if (S_OK == hr) { *pInstanceGuid = m_pComponent->m_InstanceGuid; Unlock(); } else { *pInstanceGuid = GUID_NULL; } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetInstanceGuid"); return hr; } STDMETHODIMP CImplINetCfgComponent::GetPnpDevNodeId ( OUT PWSTR* ppszDevNodeId) { HRESULT hr; // Validate parameters. // if (FBadOutPtr (ppszDevNodeId)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL); if (S_OK == hr) { if (FIsEnumerated(m_pComponent->Class())) { hr = HrCoTaskMemAllocAndDupSz ( m_pComponent->m_pszPnpId, ppszDevNodeId, MAX_DEVICE_ID_LEN); } else { hr = E_NOTIMPL; } Unlock(); } else { *ppszDevNodeId = NULL; } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetPnpDevNodeId"); return hr; } STDMETHODIMP CImplINetCfgComponent::GetClassGuid ( OUT GUID* pguidClass) { HRESULT hr; // Validate parameters. // if (FBadOutPtr (pguidClass)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL); if (S_OK == hr) { *pguidClass = *MAP_NETCLASS_TO_GUID[m_pComponent->Class()]; Unlock(); } else { *pguidClass = GUID_NULL; } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetClassGuid"); return hr; } STDMETHODIMP CImplINetCfgComponent::GetBindName ( OUT PWSTR* ppszBindName) { HRESULT hr; hr = HrAccessExternalStringAtOffsetAndCopy ( ECD_OFFSET(m_pszBindName), ppszBindName); TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetBindName"); return hr; } STDMETHODIMP CImplINetCfgComponent::GetDeviceStatus ( OUT ULONG* pulStatus) { HRESULT hr; // Validate parameters. // if (FBadOutPtr (pulStatus)) { hr = E_POINTER; } else { *pulStatus = 0; hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL); if (S_OK == hr) { if (!FIsEnumerated(m_pComponent->Class())) { hr = E_UNEXPECTED; } else { HDEVINFO hdi; SP_DEVINFO_DATA deid; hr = m_pComponent->HrOpenDeviceInfo (&hdi, &deid); if (S_OK == hr) { ULONG ulStatus; ULONG ulProblem; CONFIGRET cfgRet; cfgRet = CM_Get_DevNode_Status_Ex ( &ulStatus, &ulProblem, deid.DevInst, 0, NULL); if (CR_SUCCESS == cfgRet) { hr = S_OK; *pulStatus = ulProblem; } else if(CR_NO_SUCH_DEVINST == cfgRet) { hr = NETCFG_E_ADAPTER_NOT_FOUND; } else { TraceTag (ttidError, "CM_Get_DevNode_Status_Ex for " "%S returned cfgRet=0x%08x, ulStatus=0x%08x, ulProblem=0x%08x", m_pComponent->m_pszPnpId, cfgRet, ulStatus, ulProblem); hr = HrFromConfigManagerError (cfgRet, E_FAIL); } SetupDiDestroyDeviceInfoList (hdi); } } Unlock(); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::GetDeviceStatus"); return hr; } STDMETHODIMP CImplINetCfgComponent::OpenParamKey ( OUT HKEY* phkey) { HRESULT hr; // Validate parameters. // if (FBadOutPtr (phkey)) { hr = E_POINTER; } else { *phkey = NULL; hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL); if (S_OK == hr) { // Get the correct REGSAM value base on? // REGSAM samDesired = KEY_READ_WRITE; // For enumerated components, the parameter key is the // instance key. // if (FIsEnumerated (m_pComponent->Class())) { hr = m_pComponent->HrOpenInstanceKey ( samDesired, phkey, NULL, NULL); } // For non-enumerated components, the parameter is either under // the service key (if the component has a service) or it is // under the instance key. // else { // Get the parent of the parameters key. // HKEY hkeyParent; #if DBG hkeyParent = NULL; #endif if (m_pComponent->FHasService()) { hr = m_pComponent->HrOpenServiceKey ( samDesired, &hkeyParent); } else { hr = m_pComponent->HrOpenInstanceKey ( samDesired, &hkeyParent, NULL, NULL); } if (S_OK == hr) { Assert (hkeyParent); DWORD dwDisposition; hr = HrRegCreateKeyEx ( hkeyParent, L"Parameters", REG_OPTION_NON_VOLATILE, samDesired, NULL, phkey, &dwDisposition); RegCloseKey (hkeyParent); } } Unlock(); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::OpenParamKey"); return hr; } STDMETHODIMP CImplINetCfgComponent::RaisePropertyUi ( IN HWND hwndParent, IN DWORD dwFlags, /* NCRP_FLAGS */ IN IUnknown* punkContext OPTIONAL) { HRESULT hr; // Validate parameters. // if ((!IsWindow (hwndParent) && (dwFlags & NCRP_SHOW_PROPERTY_UI)) || !(dwFlags & (NCRP_QUERY_PROPERTY_UI | NCRP_SHOW_PROPERTY_UI)) || ((dwFlags & NCRP_QUERY_PROPERTY_UI) && (dwFlags & NCRP_SHOW_PROPERTY_UI))) { hr = E_INVALIDARG; } else if (FBadInPtrOptional (punkContext)) { hr = E_POINTER; } else { DWORD dwIfFlags = IF_NEED_WRITE_LOCK; BOOL fReadOnlyRasUiContext = FALSE; // Special case: for RAS UI. We need to allow raising property // sheets within the context of a RAS connection even when we // don't have the write lock. This is because non-admins need to be // able to change TCP/IP properties for their connections. The // property values will be stored in the phonebook and we won't need // to make any netcfg changes anyway. Therefore, if we have a // punkContext, we'll check to see if it supports the private // interface that we know RAS uses when it raises properties. // If this interface is present, we won't require the write lock // to proceed // if (punkContext && !m_pINetCfg->m_WriteLock.FIsOwnedByMe ()) { INetRasConnectionIpUiInfo* pRasUiInfo; hr = punkContext->QueryInterface (IID_INetRasConnectionIpUiInfo, (PVOID*)&pRasUiInfo); if (S_OK == hr) { dwIfFlags &= ~IF_NEED_WRITE_LOCK; dwIfFlags |= IF_NEED_COMPONENT_DATA; fReadOnlyRasUiContext = TRUE; ReleaseObj (pRasUiInfo); } hr = S_OK; } // End special case hr = HrLockAndTestForValidInterface (dwIfFlags, NULL, NULL); if (S_OK == hr) { // Special case: (see above) // if (fReadOnlyRasUiContext) { if (0 == wcscmp (m_pComponent->m_pszInfId, L"ms_tcpip")) { hr = m_pComponent->Notify.HrEnsureNotifyObjectInitialized ( m_pINetCfg, FALSE); } else { hr = NETCFG_E_NO_WRITE_LOCK; } } // End special case if (S_OK == hr) { if (dwFlags & NCRP_QUERY_PROPERTY_UI) { hr = m_pComponent->Notify.HrQueryPropertyUi ( m_pINetCfg, punkContext); } else { Assert (dwFlags & NCRP_SHOW_PROPERTY_UI); hr = m_pComponent->Notify.HrShowPropertyUi ( m_pINetCfg, hwndParent, punkContext); } } Unlock (); } } TraceHr (ttidError, FAL, hr, (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr) || (S_FALSE == hr), "CImplINetCfgComponent::RaisePropertyUi"); return hr; } //+--------------------------------------------------------------------------- // INetCfgComponentBindings - // HRESULT CImplINetCfgComponent::HrBindToOrUnbindFrom ( IN INetCfgComponent* pIOtherComp, IN DWORD dwChangeFlag) { HRESULT hr; Assert ((dwChangeFlag == NCN_ENABLE) || (dwChangeFlag == NCN_DISABLE)); // Validate parameters. // if (FBadInPtr (pIOtherComp)) { hr = E_POINTER; } else { CComponent* pLower; hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK, pIOtherComp, &pLower); if (S_OK == hr) { const CComponent* pUpper = m_pComponent; // Assume the components do not bind. // hr = S_FALSE; if (pUpper != pLower) { CBindingSet BindingSet; hr = m_pINetCfg->m_pNetConfig->Core.HrGetComponentBindings ( pUpper, GBF_DEFAULT, &BindingSet); if (S_OK == hr) { CBindPath* pBindPath; // Assume we don't find the component in any bindings. // hr = S_FALSE; for (pBindPath = BindingSet.begin(); pBindPath != BindingSet.end(); pBindPath++) { // Skip bindpaths that don't contain the lower // component. // if (!pBindPath->FContainsComponent (pLower)) { continue; } hr = m_pINetCfg->m_pNetConfig->ModifyCtx. HrEnableOrDisableBindPath ( dwChangeFlag, pBindPath, NULL); if (S_OK != hr) { break; } } } } Unlock(); } } TraceHr (ttidError, FAL, hr, S_FALSE == hr, "CImplINetCfgComponent::HrBindToOrUnbindFrom"); return hr; } STDMETHODIMP CImplINetCfgComponent::BindTo ( IN INetCfgComponent* pIOtherComp) { HRESULT hr; hr = HrBindToOrUnbindFrom (pIOtherComp, NCN_ENABLE); TraceHr (ttidError, FAL, hr, S_FALSE == hr, "CImplINetCfgComponent::BindTo"); return hr; } STDMETHODIMP CImplINetCfgComponent::UnbindFrom ( IN INetCfgComponent* pIOtherComp) { HRESULT hr; hr = HrBindToOrUnbindFrom (pIOtherComp, NCN_DISABLE); TraceHr (ttidError, FAL, hr, S_FALSE == hr, "CImplINetCfgComponent::UnbindFrom"); return hr; } STDMETHODIMP CImplINetCfgComponent::SupportsBindingInterface ( IN DWORD dwFlags, IN PCWSTR pszInterfaceName) { HRESULT hr; // Validate parameters. // if (!((dwFlags & NCF_UPPER) || (dwFlags & NCF_LOWER))) { hr = E_INVALIDARG; } else if (FBadInPtr (pszInterfaceName)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL); if (S_OK == hr) { PCWSTR pszRange; pszRange = (dwFlags & NCF_LOWER) ? m_pComponent->Ext.PszLowerRange() : m_pComponent->Ext.PszUpperRange(); hr = (FSubstringMatch (pszRange, pszInterfaceName, NULL, NULL)) ? S_OK : S_FALSE; Unlock(); } } TraceHr (ttidError, FAL, hr, S_FALSE == hr, "CImplINetCfgComponent::SupportsBindingInterface"); return hr; } STDMETHODIMP CImplINetCfgComponent::IsBoundTo ( IN INetCfgComponent* pIOtherComp) { HRESULT hr; // Validate parameters. // if (FBadInPtr (pIOtherComp)) { hr = E_POINTER; } else { CComponent* pLower; hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, pIOtherComp, &pLower); if (S_OK == hr) { const CComponent* pUpper = m_pComponent; hr = S_FALSE; // assume it is not bound or is disabled if (pUpper != pLower) { CBindingSet BindingSet; hr = m_pINetCfg->m_pNetConfig->Core.HrGetComponentBindings ( pUpper, GBF_DEFAULT, &BindingSet); // If we think its bound, make sure it exists in at least // one bindpath that is not disabled. // if (S_OK == hr) { CBindPath* pBindPath; // Assume we don't fint it in at least one enabled // bindpath. // hr = S_FALSE; for (pBindPath = BindingSet.begin(); pBindPath != BindingSet.end(); pBindPath++) { // If the bindpath contains the component, and it is // not a disabled bindpath, it means pUpper has a // path to pLower. // if (pBindPath->FContainsComponent (pLower) && !m_pINetCfg->m_pNetConfig->Core. FIsBindPathDisabled (pBindPath, IBD_MATCH_SUBPATHS_TOO)) { hr = S_OK; break; } } } } Unlock(); } } TraceHr (ttidError, FAL, hr, S_FALSE == hr, "CImplINetCfgComponent::IsBoundTo"); return hr; } STDMETHODIMP CImplINetCfgComponent::IsBindableTo ( IN INetCfgComponent* pIOtherComp) { HRESULT hr; // Validate parameters. // if (FBadInPtr (pIOtherComp)) { hr = E_POINTER; } else { CComponent* pLower; hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, pIOtherComp, &pLower); if (S_OK == hr) { const CComponent* pUpper = m_pComponent; hr = S_FALSE; // assume it does not bind if (pUpper != pLower) { CBindingSet BindingSet; hr = m_pINetCfg->m_pNetConfig->Core.HrGetComponentBindings ( pUpper, GBF_DEFAULT, &BindingSet); if (S_OK == hr) { hr = (BindingSet.FContainsComponent (pLower)) ? S_OK : S_FALSE; } } Unlock(); } } TraceHr (ttidError, FAL, hr, S_FALSE == hr, "CImplINetCfgComponent::IsBindableTo"); return hr; } STDMETHODIMP CImplINetCfgComponent::EnumBindingPaths ( IN DWORD dwFlags, OUT IEnumNetCfgBindingPath** ppIEnum) { HRESULT hr; // Validate parameters. // if (FBadOutPtr (ppIEnum)) { hr = E_POINTER; } else if ((EBP_ABOVE != dwFlags) && (EBP_BELOW != dwFlags)) { hr = E_INVALIDARG; } else { *ppIEnum = NULL; hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL); if (S_OK == hr) { CImplIEnumNetCfgBindingPath* pIEnum; // Create an empty bindpath enumerator. We create it empty // before we get the set of bindings so we don't have to copy // the bindings. // hr = CImplIEnumNetCfgBindingPath::HrCreateInstance ( m_pINetCfg, NULL, EBPC_CREATE_EMPTY, &pIEnum); if (S_OK == hr) { // Get the bindset and store it directly in the enumerator // for its exclusive use. // if (EBP_ABOVE == dwFlags) { hr = m_pINetCfg->m_pNetConfig->Core. HrGetBindingsInvolvingComponent ( m_pComponent, GBF_DEFAULT, &pIEnum->m_InternalBindSet); } else { hr = m_pINetCfg->m_pNetConfig->Core. HrGetComponentBindings ( m_pComponent, GBF_DEFAULT, &pIEnum->m_InternalBindSet); } if (S_OK == hr) { // Must Reset so that the internal iterator is setup properly // after we initialized the InternalBindSet above. // hr = pIEnum->Reset (); Assert (S_OK == hr); AddRefObj (pIEnum->GetUnknown()); *ppIEnum = pIEnum; } ReleaseObj (pIEnum->GetUnknown()); } Unlock(); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::EnumBindingPaths"); return hr; } HRESULT CImplINetCfgComponent::HrMoveBindPath ( IN INetCfgBindingPath* pIPathSrc, IN INetCfgBindingPath* pIPathDst, IN MOVE_FLAG Flag) { HRESULT hr; // Validate parameters. // if (FBadInPtr(pIPathSrc) || FBadInPtrOptional (pIPathDst)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK, NULL, NULL); if (S_OK == hr) { CImplINetCfgBindingPath* pISrc; CImplINetCfgBindingPath* pIDst; CBindPath SrcBindPath; CBindPath DstBindPath; CBindPath::const_iterator iterSrc; CBindPath::const_iterator iterDst; CStackEntry SrcEntry; CStackEntry DstEntry; Assert (m_pINetCfg); Assert (m_pINetCfg->m_pNetConfig->ModifyCtx.m_fPrepared); pISrc = (CImplINetCfgBindingPath*)pIPathSrc; pIDst = (CImplINetCfgBindingPath*)pIPathDst; hr = pISrc->HrIsValidInterface (IF_NEED_WRITE_LOCK, &SrcBindPath); if (S_OK != hr) { goto unlock; } // pIPathDst (hence pIDst) may be NULL. // if (pIDst) { hr = pIDst->HrIsValidInterface (IF_NEED_WRITE_LOCK, &DstBindPath); if (S_OK != hr) { goto unlock; } } // The first component of both bindpaths must be this component. // if ((m_pComponent != SrcBindPath.POwner()) || (pIDst && (m_pComponent != DstBindPath.POwner()))) { hr = E_INVALIDARG; goto unlock; } if (pIDst) { // Scan down both bindpaths until we find the first components // that don't match. Assume we don't find this occurance and // return E_INVALIDARG if we don't. // hr = E_INVALIDARG; for (iterSrc = SrcBindPath.begin(), iterDst = DstBindPath.begin(); iterSrc != SrcBindPath.end() && iterDst != DstBindPath.end(); iterSrc++, iterDst++) { // First time through *iterSrc is guaranteed to be the // sameas *iterDst because the first component in both // bindpaths is m_pComponent as tested above. // if (*iterSrc != *iterDst) { SrcEntry.pLower = *iterSrc; Assert (SrcEntry.pLower); DstEntry.pLower = *iterDst; Assert (DstEntry.pUpper); Assert (SrcEntry.pUpper == DstEntry.pUpper); Assert (SrcEntry.pLower != DstEntry.pLower); hr = m_pINetCfg->m_pNetConfig->Core.StackTable. HrMoveStackEntries ( &SrcEntry, &DstEntry, Flag, &m_pINetCfg->m_pNetConfig->ModifyCtx); if(SUCCEEDED(hr)) { // Mark this component as dirty so it's bindings will be written out and // NDIS will be notified. m_pINetCfg->m_pNetConfig->ModifyCtx. HrDirtyComponentAndComponentsAbove(SrcEntry.pUpper); m_pINetCfg->m_pNetConfig->ModifyCtx. HrDirtyComponentAndComponentsAbove(DstEntry.pUpper); } break; } // Remember the upper components as we are about to // advance past them. // SrcEntry.pUpper = *iterSrc; Assert (SrcEntry.pUpper); DstEntry.pUpper = *iterDst; Assert (SrcEntry.pUpper); Assert (SrcEntry.pUpper == DstEntry.pUpper); } } else { SrcEntry.pUpper = SrcBindPath.POwner(); Assert ((SrcBindPath.begin() + 1) != SrcBindPath.end()); SrcEntry.pLower = *(SrcBindPath.begin() + 1); hr = m_pINetCfg->m_pNetConfig->Core.StackTable. HrMoveStackEntries ( &SrcEntry, NULL, Flag, &m_pINetCfg->m_pNetConfig->ModifyCtx); if(SUCCEEDED(hr)) { // Mark this component as dirty so it's bindings will be written out and // NDIS will be notified. m_pINetCfg->m_pNetConfig->ModifyCtx. HrDirtyComponentAndComponentsAbove(SrcEntry.pUpper); } } unlock: Unlock(); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::HrMoveBindPath"); return hr; } STDMETHODIMP CImplINetCfgComponent::MoveBefore ( IN INetCfgBindingPath* pIPathSrc, IN INetCfgBindingPath* pIPathDst) { HRESULT hr; hr = HrMoveBindPath (pIPathSrc, pIPathDst, MOVE_BEFORE); TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::MoveBefore"); return hr; } STDMETHODIMP CImplINetCfgComponent::MoveAfter ( IN INetCfgBindingPath* pIPathSrc, IN INetCfgBindingPath* pIPathDst) { HRESULT hr; hr = HrMoveBindPath (pIPathSrc, pIPathDst, MOVE_AFTER); TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::MoveAfter"); return hr; } //+--------------------------------------------------------------------------- // INetCfgComponentPrivate - // STDMETHODIMP CImplINetCfgComponent::QueryNotifyObject ( IN REFIID riid, OUT VOID** ppvObject) { HRESULT hr; // Validate parameters. // if (FBadInPtr(&riid) || FBadOutPtr (ppvObject)) { hr = E_POINTER; } else { *ppvObject = NULL; hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL); if (S_OK == hr) { hr = m_pComponent->Notify.QueryNotifyObject ( m_pINetCfg, riid, ppvObject); Unlock(); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::QueryNotifyObject"); return hr; } STDMETHODIMP CImplINetCfgComponent::SetDirty () { HRESULT hr; hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK, NULL, NULL); if (S_OK == hr) { hr = m_pINetCfg->m_pNetConfig->ModifyCtx.HrDirtyComponent( m_pComponent); Unlock (); } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::SetDirty"); return hr; } STDMETHODIMP CImplINetCfgComponent::NotifyUpperEdgeConfigChange () { HRESULT hr; hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK, NULL, NULL); if (S_OK == hr) { hr = m_pINetCfg->m_pNetConfig->ModifyCtx. HrDirtyComponentAndComponentsAbove (m_pComponent); Unlock (); } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::NotifyUpperEdgeConfigChange"); return hr; }