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.

1359 lines
35 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999.
  5. //
  6. // File: I C O M P . C P P
  7. //
  8. // Contents: Implements the INetCfgComponent COM interface.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 15 Jan 1999
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include "ibind.h"
  18. #include "icomp.h"
  19. #include "ienum.h"
  20. #include "nccfgmgr.h"
  21. #include "ncreg.h"
  22. #include "ncsetup.h"
  23. #include "ncvalid.h"
  24. #include "netcfg.h"
  25. #include "netconp.h"
  26. #include "util.h"
  27. HRESULT
  28. HrIsValidINetCfgComponent (
  29. IN INetCfgComponent* pICompInterface)
  30. {
  31. Assert (pICompInterface);
  32. CImplINetCfgComponent* pIComp;
  33. pIComp = (CImplINetCfgComponent*)pICompInterface;
  34. if (pIComp == NULL)
  35. {
  36. return(E_OUTOFMEMORY);
  37. }
  38. return pIComp->HrIsValidInterface (IF_DEFAULT);
  39. }
  40. CComponent*
  41. PComponentFromComInterface (
  42. IN INetCfgComponent* pICompInterface)
  43. {
  44. Assert (pICompInterface);
  45. CImplINetCfgComponent* pIComp;
  46. pIComp = (CImplINetCfgComponent*)pICompInterface;
  47. // Can't do the following assert because we may be referencing the
  48. // component before it has been added to the core. This case is possible
  49. // when installing a new component that installed a required component
  50. // on behalf of itself. We will wind up in the function when adding
  51. // the refernce for the obo token.
  52. //
  53. //Assert (S_OK == pIComp->HrIsValidInterface (dwFlags));
  54. Assert (pIComp->m_pComponent);
  55. return pIComp->m_pComponent;
  56. }
  57. // static
  58. HRESULT
  59. CImplINetCfgComponent::HrCreateInstance (
  60. IN CImplINetCfg* pINetCfg,
  61. IN CComponent* pComponent,
  62. OUT CImplINetCfgComponent** ppIComp)
  63. {
  64. HRESULT hr = E_OUTOFMEMORY;
  65. CImplINetCfgComponent* pObj;
  66. pObj = new CComObject <CImplINetCfgComponent>;
  67. if (pObj)
  68. {
  69. // Initialize our members.
  70. //
  71. pObj->m_pComponent = pComponent;
  72. // Do the standard CComCreator::CreateInstance stuff.
  73. //
  74. pObj->SetVoid (NULL);
  75. pObj->InternalFinalConstructAddRef ();
  76. hr = pObj->FinalConstruct ();
  77. pObj->InternalFinalConstructRelease ();
  78. if (S_OK == hr)
  79. {
  80. // The last thing we do is addref any interfaces we hold.
  81. // We only do this if we are returning success.
  82. //
  83. pObj->HoldINetCfg (pINetCfg);
  84. AddRefObj (pObj->GetUnknown());
  85. *ppIComp = pObj;
  86. }
  87. if (S_OK != hr)
  88. {
  89. delete pObj;
  90. }
  91. }
  92. TraceHr (ttidError, FAL, hr, FALSE,
  93. "CImplINetCfgComponent::HrCreateInstance");
  94. return hr;
  95. }
  96. HRESULT
  97. CImplINetCfgComponent::HrIsValidInterface (
  98. IN DWORD dwFlags)
  99. {
  100. HRESULT hr;
  101. hr = m_pINetCfg->HrIsValidInterface (dwFlags);
  102. if (S_OK != hr)
  103. {
  104. return hr;
  105. }
  106. // Check for deleted component.
  107. //
  108. if (!m_pComponent)
  109. {
  110. return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
  111. }
  112. // If we made it this far, the component this interface represents
  113. // should definately be in the core component list or in the core
  114. // that we started with in the case that this component is in the middle
  115. // of being removed.
  116. //
  117. Assert(m_pINetCfg->m_pNetConfig->Core.Components.
  118. FComponentInList (m_pComponent) ||
  119. m_pINetCfg->m_pNetConfig->ModifyCtx.m_CoreStartedWith.Components.
  120. FComponentInList (m_pComponent));
  121. if (dwFlags & IF_NEED_COMPONENT_DATA)
  122. {
  123. hr = m_pComponent->Ext.HrEnsureExternalDataLoaded ();
  124. }
  125. return hr;
  126. }
  127. // We need to override CImplINetCfgHolder::HrLockAndTestForValidInterface
  128. // because we have our own HrIsValidInterface to be called.
  129. //
  130. HRESULT
  131. CImplINetCfgComponent::HrLockAndTestForValidInterface (
  132. IN DWORD dwFlags,
  133. IN INetCfgComponent* pIOtherComp, OPTIONAL
  134. OUT CComponent** ppOtherComp OPTIONAL)
  135. {
  136. HRESULT hr;
  137. Lock();
  138. hr = HrIsValidInterface (dwFlags);
  139. // If pIOtherComp was passed in, the caller wants that interface
  140. // validated and the internal CComponent pointer for it returned.
  141. //
  142. if ((S_OK == hr) && pIOtherComp)
  143. {
  144. CImplINetCfgComponent* pOther;
  145. Assert (ppOtherComp);
  146. pOther = (CImplINetCfgComponent*)pIOtherComp;
  147. hr = pOther->HrIsValidInterface (IF_NEED_COMPONENT_DATA);
  148. if (S_OK == hr)
  149. {
  150. *ppOtherComp = pOther->m_pComponent;
  151. }
  152. }
  153. if (S_OK != hr)
  154. {
  155. Unlock();
  156. }
  157. TraceHr (ttidError, FAL, hr, FALSE,
  158. "CImplINetCfgComponent::HrLockAndTestForValidInterface");
  159. return hr;
  160. }
  161. HRESULT
  162. CImplINetCfgComponent::HrAccessExternalStringAtOffsetAndCopy (
  163. IN UINT unOffset,
  164. OUT PWSTR* ppszDst)
  165. {
  166. HRESULT hr;
  167. // Validate parameter.
  168. //
  169. if (FBadOutPtr (ppszDst))
  170. {
  171. hr = E_POINTER;
  172. }
  173. else
  174. {
  175. *ppszDst = NULL;
  176. hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL);
  177. if (S_OK == hr)
  178. {
  179. hr = HrCoTaskMemAllocAndDupSz (
  180. m_pComponent->Ext.PszAtOffset (unOffset),
  181. ppszDst);
  182. Unlock();
  183. }
  184. }
  185. TraceHr (ttidError, FAL, hr, FALSE,
  186. "CImplINetCfgComponent::HrAccessExternalStringAtOffsetAndCopy");
  187. return hr;
  188. }
  189. //+---------------------------------------------------------------------------
  190. // INetCfgComponent -
  191. //
  192. STDMETHODIMP
  193. CImplINetCfgComponent::GetDisplayName (
  194. OUT PWSTR* ppszDisplayName)
  195. {
  196. HRESULT hr;
  197. hr = HrAccessExternalStringAtOffsetAndCopy (
  198. ECD_OFFSET(m_pszDescription),
  199. ppszDisplayName);
  200. TraceHr (ttidError, FAL, hr, FALSE,
  201. "CImplINetCfgComponent::GetDisplayName");
  202. return hr;
  203. }
  204. STDMETHODIMP
  205. CImplINetCfgComponent::SetDisplayName (
  206. IN PCWSTR pszDisplayName)
  207. {
  208. HRESULT hr;
  209. // Validate parameter.
  210. //
  211. if (FBadInPtr (pszDisplayName))
  212. {
  213. hr = E_POINTER;
  214. }
  215. else
  216. {
  217. hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL);
  218. if (S_OK == hr)
  219. {
  220. // We only allow changing the display name (SPDRP_FRIENDLYNAME,
  221. // actually) of enumerated components.
  222. //
  223. if (FIsEnumerated(m_pComponent->Class()))
  224. {
  225. HDEVINFO hdi;
  226. SP_DEVINFO_DATA deid;
  227. hr = m_pComponent->HrOpenDeviceInfo (&hdi, &deid);
  228. if (S_OK == hr)
  229. {
  230. hr = HrSetupDiSetDeviceName (hdi, &deid, pszDisplayName);
  231. if (S_OK == hr)
  232. {
  233. m_pComponent->Ext.HrSetDescription (pszDisplayName);
  234. }
  235. SetupDiDestroyDeviceInfoList (hdi);
  236. }
  237. }
  238. else
  239. {
  240. hr = E_NOTIMPL;
  241. }
  242. Unlock();
  243. }
  244. }
  245. TraceHr (ttidError, FAL, hr, FALSE,
  246. "CImplINetCfgComponent::SetDisplayName");
  247. return hr;
  248. }
  249. STDMETHODIMP
  250. CImplINetCfgComponent::GetHelpText (
  251. OUT PWSTR* pszHelpText)
  252. {
  253. HRESULT hr;
  254. hr = HrAccessExternalStringAtOffsetAndCopy (
  255. ECD_OFFSET(m_pszHelpText),
  256. pszHelpText);
  257. TraceHr (ttidError, FAL, hr, FALSE,
  258. "CImplINetCfgComponent::GetHelpText");
  259. return hr;
  260. }
  261. STDMETHODIMP
  262. CImplINetCfgComponent::GetId (
  263. OUT PWSTR* ppszId)
  264. {
  265. HRESULT hr;
  266. // Validate parameters.
  267. //
  268. if (FBadOutPtr (ppszId))
  269. {
  270. hr = E_POINTER;
  271. }
  272. else
  273. {
  274. hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL);
  275. if (S_OK == hr)
  276. {
  277. hr = HrCoTaskMemAllocAndDupSz (
  278. m_pComponent->m_pszInfId,
  279. ppszId);
  280. Unlock();
  281. }
  282. else
  283. {
  284. *ppszId = NULL;
  285. }
  286. }
  287. TraceHr (ttidError, FAL, hr, FALSE,
  288. "CImplINetCfgComponent::GetId");
  289. return hr;
  290. }
  291. STDMETHODIMP
  292. CImplINetCfgComponent::GetCharacteristics (
  293. OUT LPDWORD pdwCharacteristics)
  294. {
  295. HRESULT hr;
  296. // Validate parameters.
  297. //
  298. if (FBadOutPtr (pdwCharacteristics))
  299. {
  300. hr = E_POINTER;
  301. }
  302. else
  303. {
  304. hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL);
  305. if (S_OK == hr)
  306. {
  307. *pdwCharacteristics = m_pComponent->m_dwCharacter;
  308. Unlock();
  309. }
  310. else
  311. {
  312. *pdwCharacteristics = 0;
  313. }
  314. }
  315. TraceHr (ttidError, FAL, hr, FALSE,
  316. "CImplINetCfgComponent::GetCharacteristics");
  317. return hr;
  318. }
  319. STDMETHODIMP
  320. CImplINetCfgComponent::GetInstanceGuid (
  321. OUT GUID* pInstanceGuid)
  322. {
  323. HRESULT hr;
  324. // Validate parameters.
  325. //
  326. if (FBadOutPtr (pInstanceGuid))
  327. {
  328. hr = E_POINTER;
  329. }
  330. else
  331. {
  332. hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL);
  333. if (S_OK == hr)
  334. {
  335. *pInstanceGuid = m_pComponent->m_InstanceGuid;
  336. Unlock();
  337. }
  338. else
  339. {
  340. *pInstanceGuid = GUID_NULL;
  341. }
  342. }
  343. TraceHr (ttidError, FAL, hr, FALSE,
  344. "CImplINetCfgComponent::GetInstanceGuid");
  345. return hr;
  346. }
  347. STDMETHODIMP
  348. CImplINetCfgComponent::GetPnpDevNodeId (
  349. OUT PWSTR* ppszDevNodeId)
  350. {
  351. HRESULT hr;
  352. // Validate parameters.
  353. //
  354. if (FBadOutPtr (ppszDevNodeId))
  355. {
  356. hr = E_POINTER;
  357. }
  358. else
  359. {
  360. hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL);
  361. if (S_OK == hr)
  362. {
  363. if (FIsEnumerated(m_pComponent->Class()))
  364. {
  365. hr = HrCoTaskMemAllocAndDupSz (
  366. m_pComponent->m_pszPnpId,
  367. ppszDevNodeId);
  368. }
  369. else
  370. {
  371. hr = E_NOTIMPL;
  372. }
  373. Unlock();
  374. }
  375. else
  376. {
  377. *ppszDevNodeId = NULL;
  378. }
  379. }
  380. TraceHr (ttidError, FAL, hr, FALSE,
  381. "CImplINetCfgComponent::GetPnpDevNodeId");
  382. return hr;
  383. }
  384. STDMETHODIMP
  385. CImplINetCfgComponent::GetClassGuid (
  386. OUT GUID* pguidClass)
  387. {
  388. HRESULT hr;
  389. // Validate parameters.
  390. //
  391. if (FBadOutPtr (pguidClass))
  392. {
  393. hr = E_POINTER;
  394. }
  395. else
  396. {
  397. hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL);
  398. if (S_OK == hr)
  399. {
  400. *pguidClass = *MAP_NETCLASS_TO_GUID[m_pComponent->Class()];
  401. Unlock();
  402. }
  403. else
  404. {
  405. *pguidClass = GUID_NULL;
  406. }
  407. }
  408. TraceHr (ttidError, FAL, hr, FALSE,
  409. "CImplINetCfgComponent::GetClassGuid");
  410. return hr;
  411. }
  412. STDMETHODIMP
  413. CImplINetCfgComponent::GetBindName (
  414. OUT PWSTR* ppszBindName)
  415. {
  416. HRESULT hr;
  417. hr = HrAccessExternalStringAtOffsetAndCopy (
  418. ECD_OFFSET(m_pszBindName),
  419. ppszBindName);
  420. TraceHr (ttidError, FAL, hr, FALSE,
  421. "CImplINetCfgComponent::GetBindName");
  422. return hr;
  423. }
  424. STDMETHODIMP
  425. CImplINetCfgComponent::GetDeviceStatus (
  426. OUT ULONG* pulStatus)
  427. {
  428. HRESULT hr;
  429. // Validate parameters.
  430. //
  431. if (FBadOutPtr (pulStatus))
  432. {
  433. hr = E_POINTER;
  434. }
  435. else
  436. {
  437. *pulStatus = 0;
  438. hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL);
  439. if (S_OK == hr)
  440. {
  441. if (!FIsEnumerated(m_pComponent->Class()))
  442. {
  443. hr = E_UNEXPECTED;
  444. }
  445. else
  446. {
  447. HDEVINFO hdi;
  448. SP_DEVINFO_DATA deid;
  449. hr = m_pComponent->HrOpenDeviceInfo (&hdi, &deid);
  450. if (S_OK == hr)
  451. {
  452. ULONG ulStatus;
  453. ULONG ulProblem;
  454. CONFIGRET cfgRet;
  455. cfgRet = CM_Get_DevNode_Status_Ex (
  456. &ulStatus, &ulProblem, deid.DevInst, 0, NULL);
  457. if (CR_SUCCESS == cfgRet)
  458. {
  459. hr = S_OK;
  460. *pulStatus = ulProblem;
  461. }
  462. else if(CR_NO_SUCH_DEVINST == cfgRet)
  463. {
  464. hr = NETCFG_E_ADAPTER_NOT_FOUND;
  465. }
  466. else
  467. {
  468. TraceTag (ttidError, "CM_Get_DevNode_Status_Ex for "
  469. "%S returned cfgRet=0x%08x, ulStatus=0x%08x, ulProblem=0x%08x",
  470. m_pComponent->m_pszPnpId,
  471. cfgRet,
  472. ulStatus,
  473. ulProblem);
  474. hr = HrFromConfigManagerError (cfgRet, E_FAIL);
  475. }
  476. SetupDiDestroyDeviceInfoList (hdi);
  477. }
  478. }
  479. Unlock();
  480. }
  481. }
  482. TraceHr (ttidError, FAL, hr, FALSE,
  483. "CImplINetCfgComponent::GetDeviceStatus");
  484. return hr;
  485. }
  486. STDMETHODIMP
  487. CImplINetCfgComponent::OpenParamKey (
  488. OUT HKEY* phkey)
  489. {
  490. HRESULT hr;
  491. // Validate parameters.
  492. //
  493. if (FBadOutPtr (phkey))
  494. {
  495. hr = E_POINTER;
  496. }
  497. else
  498. {
  499. *phkey = NULL;
  500. hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL);
  501. if (S_OK == hr)
  502. {
  503. // Get the correct REGSAM value base on?
  504. //
  505. REGSAM samDesired = KEY_READ_WRITE;
  506. // For enumerated components, the parameter key is the
  507. // instance key.
  508. //
  509. if (FIsEnumerated (m_pComponent->Class()))
  510. {
  511. hr = m_pComponent->HrOpenInstanceKey (
  512. samDesired, phkey, NULL, NULL);
  513. }
  514. // For non-enumerated components, the parameter is either under
  515. // the service key (if the component has a service) or it is
  516. // under the instance key.
  517. //
  518. else
  519. {
  520. // Get the parent of the parameters key.
  521. //
  522. HKEY hkeyParent;
  523. #if DBG
  524. hkeyParent = NULL;
  525. #endif
  526. if (m_pComponent->FHasService())
  527. {
  528. hr = m_pComponent->HrOpenServiceKey (
  529. samDesired, &hkeyParent);
  530. }
  531. else
  532. {
  533. hr = m_pComponent->HrOpenInstanceKey (
  534. samDesired, &hkeyParent, NULL, NULL);
  535. }
  536. if (S_OK == hr)
  537. {
  538. Assert (hkeyParent);
  539. DWORD dwDisposition;
  540. hr = HrRegCreateKeyEx (
  541. hkeyParent,
  542. L"Parameters",
  543. REG_OPTION_NON_VOLATILE,
  544. samDesired,
  545. NULL,
  546. phkey,
  547. &dwDisposition);
  548. RegCloseKey (hkeyParent);
  549. }
  550. }
  551. Unlock();
  552. }
  553. }
  554. TraceHr (ttidError, FAL, hr, FALSE,
  555. "CImplINetCfgComponent::OpenParamKey");
  556. return hr;
  557. }
  558. STDMETHODIMP
  559. CImplINetCfgComponent::RaisePropertyUi (
  560. IN HWND hwndParent,
  561. IN DWORD dwFlags, /* NCRP_FLAGS */
  562. IN IUnknown* punkContext OPTIONAL)
  563. {
  564. HRESULT hr;
  565. // Validate parameters.
  566. //
  567. if ((!IsWindow (hwndParent) && (dwFlags & NCRP_SHOW_PROPERTY_UI)) ||
  568. !(dwFlags & (NCRP_QUERY_PROPERTY_UI | NCRP_SHOW_PROPERTY_UI)) ||
  569. ((dwFlags & NCRP_QUERY_PROPERTY_UI) && (dwFlags & NCRP_SHOW_PROPERTY_UI)))
  570. {
  571. hr = E_INVALIDARG;
  572. }
  573. else if (FBadInPtrOptional (punkContext))
  574. {
  575. hr = E_POINTER;
  576. }
  577. else
  578. {
  579. DWORD dwIfFlags = IF_NEED_WRITE_LOCK;
  580. BOOL fReadOnlyRasUiContext = FALSE;
  581. // Special case: for RAS UI. We need to allow raising property
  582. // sheets within the context of a RAS connection even when we
  583. // don't have the write lock. This is because non-admins need to be
  584. // able to change TCP/IP properties for their connections. The
  585. // property values will be stored in the phonebook and we won't need
  586. // to make any netcfg changes anyway. Therefore, if we have a
  587. // punkContext, we'll check to see if it supports the private
  588. // interface that we know RAS uses when it raises properties.
  589. // If this interface is present, we won't require the write lock
  590. // to proceed
  591. //
  592. if (punkContext && !m_pINetCfg->m_WriteLock.FIsOwnedByMe ())
  593. {
  594. INetRasConnectionIpUiInfo* pRasUiInfo;
  595. hr = punkContext->QueryInterface (IID_INetRasConnectionIpUiInfo,
  596. (PVOID*)&pRasUiInfo);
  597. if (S_OK == hr)
  598. {
  599. dwIfFlags &= ~IF_NEED_WRITE_LOCK;
  600. dwIfFlags |= IF_NEED_COMPONENT_DATA;
  601. fReadOnlyRasUiContext = TRUE;
  602. ReleaseObj (pRasUiInfo);
  603. }
  604. hr = S_OK;
  605. }
  606. // End special case
  607. hr = HrLockAndTestForValidInterface (dwIfFlags, NULL, NULL);
  608. if (S_OK == hr)
  609. {
  610. // Special case: (see above)
  611. //
  612. if (fReadOnlyRasUiContext)
  613. {
  614. if (0 == wcscmp (m_pComponent->m_pszInfId, L"ms_tcpip"))
  615. {
  616. hr = m_pComponent->Notify.HrEnsureNotifyObjectInitialized (
  617. m_pINetCfg, FALSE);
  618. }
  619. else
  620. {
  621. hr = NETCFG_E_NO_WRITE_LOCK;
  622. }
  623. }
  624. // End special case
  625. if (S_OK == hr)
  626. {
  627. if (dwFlags & NCRP_QUERY_PROPERTY_UI)
  628. {
  629. hr = m_pComponent->Notify.HrQueryPropertyUi (
  630. m_pINetCfg,
  631. punkContext);
  632. }
  633. else
  634. {
  635. Assert (dwFlags & NCRP_SHOW_PROPERTY_UI);
  636. hr = m_pComponent->Notify.HrShowPropertyUi (
  637. m_pINetCfg,
  638. hwndParent,
  639. punkContext);
  640. }
  641. }
  642. Unlock ();
  643. }
  644. }
  645. TraceHr (ttidError, FAL, hr,
  646. (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr) ||
  647. (S_FALSE == hr),
  648. "CImplINetCfgComponent::RaisePropertyUi");
  649. return hr;
  650. }
  651. //+---------------------------------------------------------------------------
  652. // INetCfgComponentBindings -
  653. //
  654. HRESULT
  655. CImplINetCfgComponent::HrBindToOrUnbindFrom (
  656. IN INetCfgComponent* pIOtherComp,
  657. IN DWORD dwChangeFlag)
  658. {
  659. HRESULT hr;
  660. Assert ((dwChangeFlag == NCN_ENABLE) || (dwChangeFlag == NCN_DISABLE));
  661. // Validate parameters.
  662. //
  663. if (FBadInPtr (pIOtherComp))
  664. {
  665. hr = E_POINTER;
  666. }
  667. else
  668. {
  669. CComponent* pLower;
  670. hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK,
  671. pIOtherComp, &pLower);
  672. if (S_OK == hr)
  673. {
  674. const CComponent* pUpper = m_pComponent;
  675. // Assume the components do not bind.
  676. //
  677. hr = S_FALSE;
  678. if (pUpper != pLower)
  679. {
  680. CBindingSet BindingSet;
  681. hr = m_pINetCfg->m_pNetConfig->Core.HrGetComponentBindings (
  682. pUpper, GBF_DEFAULT, &BindingSet);
  683. if (S_OK == hr)
  684. {
  685. CBindPath* pBindPath;
  686. // Assume we don't find the component in any bindings.
  687. //
  688. hr = S_FALSE;
  689. for (pBindPath = BindingSet.begin();
  690. pBindPath != BindingSet.end();
  691. pBindPath++)
  692. {
  693. // Skip bindpaths that don't contain the lower
  694. // component.
  695. //
  696. if (!pBindPath->FContainsComponent (pLower))
  697. {
  698. continue;
  699. }
  700. hr = m_pINetCfg->m_pNetConfig->ModifyCtx.
  701. HrEnableOrDisableBindPath (
  702. dwChangeFlag,
  703. pBindPath,
  704. NULL);
  705. if (S_OK != hr)
  706. {
  707. break;
  708. }
  709. }
  710. }
  711. }
  712. Unlock();
  713. }
  714. }
  715. TraceHr (ttidError, FAL, hr, S_FALSE == hr,
  716. "CImplINetCfgComponent::HrBindToOrUnbindFrom");
  717. return hr;
  718. }
  719. STDMETHODIMP
  720. CImplINetCfgComponent::BindTo (
  721. IN INetCfgComponent* pIOtherComp)
  722. {
  723. HRESULT hr;
  724. hr = HrBindToOrUnbindFrom (pIOtherComp, NCN_ENABLE);
  725. TraceHr (ttidError, FAL, hr, S_FALSE == hr,
  726. "CImplINetCfgComponent::BindTo");
  727. return hr;
  728. }
  729. STDMETHODIMP
  730. CImplINetCfgComponent::UnbindFrom (
  731. IN INetCfgComponent* pIOtherComp)
  732. {
  733. HRESULT hr;
  734. hr = HrBindToOrUnbindFrom (pIOtherComp, NCN_DISABLE);
  735. TraceHr (ttidError, FAL, hr, S_FALSE == hr,
  736. "CImplINetCfgComponent::UnbindFrom");
  737. return hr;
  738. }
  739. STDMETHODIMP
  740. CImplINetCfgComponent::SupportsBindingInterface (
  741. IN DWORD dwFlags,
  742. IN PCWSTR pszInterfaceName)
  743. {
  744. HRESULT hr;
  745. // Validate parameters.
  746. //
  747. if (!((dwFlags & NCF_UPPER) || (dwFlags & NCF_LOWER)))
  748. {
  749. hr = E_INVALIDARG;
  750. }
  751. else if (FBadInPtr (pszInterfaceName))
  752. {
  753. hr = E_POINTER;
  754. }
  755. else
  756. {
  757. hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL);
  758. if (S_OK == hr)
  759. {
  760. PCWSTR pszRange;
  761. pszRange = (dwFlags & NCF_LOWER)
  762. ? m_pComponent->Ext.PszLowerRange()
  763. : m_pComponent->Ext.PszUpperRange();
  764. hr = (FSubstringMatch (pszRange, pszInterfaceName, NULL, NULL))
  765. ? S_OK
  766. : S_FALSE;
  767. Unlock();
  768. }
  769. }
  770. TraceHr (ttidError, FAL, hr, S_FALSE == hr,
  771. "CImplINetCfgComponent::SupportsBindingInterface");
  772. return hr;
  773. }
  774. STDMETHODIMP
  775. CImplINetCfgComponent::IsBoundTo (
  776. IN INetCfgComponent* pIOtherComp)
  777. {
  778. HRESULT hr;
  779. // Validate parameters.
  780. //
  781. if (FBadInPtr (pIOtherComp))
  782. {
  783. hr = E_POINTER;
  784. }
  785. else
  786. {
  787. CComponent* pLower;
  788. hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA,
  789. pIOtherComp, &pLower);
  790. if (S_OK == hr)
  791. {
  792. const CComponent* pUpper = m_pComponent;
  793. hr = S_FALSE; // assume it is not bound or is disabled
  794. if (pUpper != pLower)
  795. {
  796. CBindingSet BindingSet;
  797. hr = m_pINetCfg->m_pNetConfig->Core.HrGetComponentBindings (
  798. pUpper, GBF_DEFAULT, &BindingSet);
  799. // If we think its bound, make sure it exists in at least
  800. // one bindpath that is not disabled.
  801. //
  802. if (S_OK == hr)
  803. {
  804. CBindPath* pBindPath;
  805. // Assume we don't fint it in at least one enabled
  806. // bindpath.
  807. //
  808. hr = S_FALSE;
  809. for (pBindPath = BindingSet.begin();
  810. pBindPath != BindingSet.end();
  811. pBindPath++)
  812. {
  813. // If the bindpath contains the component, and it is
  814. // not a disabled bindpath, it means pUpper has a
  815. // path to pLower.
  816. //
  817. if (pBindPath->FContainsComponent (pLower) &&
  818. !m_pINetCfg->m_pNetConfig->Core.
  819. FIsBindPathDisabled (pBindPath,
  820. IBD_MATCH_SUBPATHS_TOO))
  821. {
  822. hr = S_OK;
  823. break;
  824. }
  825. }
  826. }
  827. }
  828. Unlock();
  829. }
  830. }
  831. TraceHr (ttidError, FAL, hr, S_FALSE == hr,
  832. "CImplINetCfgComponent::IsBoundTo");
  833. return hr;
  834. }
  835. STDMETHODIMP
  836. CImplINetCfgComponent::IsBindableTo (
  837. IN INetCfgComponent* pIOtherComp)
  838. {
  839. HRESULT hr;
  840. // Validate parameters.
  841. //
  842. if (FBadInPtr (pIOtherComp))
  843. {
  844. hr = E_POINTER;
  845. }
  846. else
  847. {
  848. CComponent* pLower;
  849. hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA,
  850. pIOtherComp, &pLower);
  851. if (S_OK == hr)
  852. {
  853. const CComponent* pUpper = m_pComponent;
  854. hr = S_FALSE; // assume it does not bind
  855. if (pUpper != pLower)
  856. {
  857. CBindingSet BindingSet;
  858. hr = m_pINetCfg->m_pNetConfig->Core.HrGetComponentBindings (
  859. pUpper, GBF_DEFAULT, &BindingSet);
  860. if (S_OK == hr)
  861. {
  862. hr = (BindingSet.FContainsComponent (pLower))
  863. ? S_OK : S_FALSE;
  864. }
  865. }
  866. Unlock();
  867. }
  868. }
  869. TraceHr (ttidError, FAL, hr, S_FALSE == hr,
  870. "CImplINetCfgComponent::IsBindableTo");
  871. return hr;
  872. }
  873. STDMETHODIMP
  874. CImplINetCfgComponent::EnumBindingPaths (
  875. IN DWORD dwFlags,
  876. OUT IEnumNetCfgBindingPath** ppIEnum)
  877. {
  878. HRESULT hr;
  879. // Validate parameters.
  880. //
  881. if (FBadOutPtr (ppIEnum))
  882. {
  883. hr = E_POINTER;
  884. }
  885. else if ((EBP_ABOVE != dwFlags) &&
  886. (EBP_BELOW != dwFlags))
  887. {
  888. hr = E_INVALIDARG;
  889. }
  890. else
  891. {
  892. *ppIEnum = NULL;
  893. hr = HrLockAndTestForValidInterface (IF_DEFAULT, NULL, NULL);
  894. if (S_OK == hr)
  895. {
  896. CImplIEnumNetCfgBindingPath* pIEnum;
  897. // Create an empty bindpath enumerator. We create it empty
  898. // before we get the set of bindings so we don't have to copy
  899. // the bindings.
  900. //
  901. hr = CImplIEnumNetCfgBindingPath::HrCreateInstance (
  902. m_pINetCfg,
  903. NULL,
  904. EBPC_CREATE_EMPTY,
  905. &pIEnum);
  906. if (S_OK == hr)
  907. {
  908. // Get the bindset and store it directly in the enumerator
  909. // for its exclusive use.
  910. //
  911. if (EBP_ABOVE == dwFlags)
  912. {
  913. hr = m_pINetCfg->m_pNetConfig->Core.
  914. HrGetBindingsInvolvingComponent (
  915. m_pComponent,
  916. GBF_DEFAULT,
  917. &pIEnum->m_InternalBindSet);
  918. }
  919. else
  920. {
  921. hr = m_pINetCfg->m_pNetConfig->Core.
  922. HrGetComponentBindings (
  923. m_pComponent,
  924. GBF_DEFAULT,
  925. &pIEnum->m_InternalBindSet);
  926. }
  927. if (S_OK == hr)
  928. {
  929. // Must Reset so that the internal iterator is setup properly
  930. // after we initialized the InternalBindSet above.
  931. //
  932. hr = pIEnum->Reset ();
  933. Assert (S_OK == hr);
  934. AddRefObj (pIEnum->GetUnknown());
  935. *ppIEnum = pIEnum;
  936. }
  937. ReleaseObj (pIEnum->GetUnknown());
  938. }
  939. Unlock();
  940. }
  941. }
  942. TraceHr (ttidError, FAL, hr, FALSE,
  943. "CImplINetCfgComponent::EnumBindingPaths");
  944. return hr;
  945. }
  946. HRESULT
  947. CImplINetCfgComponent::HrMoveBindPath (
  948. IN INetCfgBindingPath* pIPathSrc,
  949. IN INetCfgBindingPath* pIPathDst,
  950. IN MOVE_FLAG Flag)
  951. {
  952. HRESULT hr;
  953. // Validate parameters.
  954. //
  955. if (FBadInPtr(pIPathSrc) || FBadInPtrOptional (pIPathDst))
  956. {
  957. hr = E_POINTER;
  958. }
  959. else
  960. {
  961. hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK, NULL, NULL);
  962. if (S_OK == hr)
  963. {
  964. CImplINetCfgBindingPath* pISrc;
  965. CImplINetCfgBindingPath* pIDst;
  966. CBindPath SrcBindPath;
  967. CBindPath DstBindPath;
  968. CBindPath::const_iterator iterSrc;
  969. CBindPath::const_iterator iterDst;
  970. CStackEntry SrcEntry;
  971. CStackEntry DstEntry;
  972. Assert (m_pINetCfg);
  973. Assert (m_pINetCfg->m_pNetConfig->ModifyCtx.m_fPrepared);
  974. pISrc = (CImplINetCfgBindingPath*)pIPathSrc;
  975. pIDst = (CImplINetCfgBindingPath*)pIPathDst;
  976. hr = pISrc->HrIsValidInterface (IF_NEED_WRITE_LOCK, &SrcBindPath);
  977. if (S_OK != hr)
  978. {
  979. goto unlock;
  980. }
  981. // pIPathDst (hence pIDst) may be NULL.
  982. //
  983. if (pIDst)
  984. {
  985. hr = pIDst->HrIsValidInterface (IF_NEED_WRITE_LOCK, &DstBindPath);
  986. if (S_OK != hr)
  987. {
  988. goto unlock;
  989. }
  990. }
  991. // The first component of both bindpaths must be this component.
  992. //
  993. if ((m_pComponent != SrcBindPath.POwner()) ||
  994. (pIDst && (m_pComponent != DstBindPath.POwner())))
  995. {
  996. hr = E_INVALIDARG;
  997. goto unlock;
  998. }
  999. if (pIDst)
  1000. {
  1001. // Scan down both bindpaths until we find the first components
  1002. // that don't match. Assume we don't find this occurance and
  1003. // return E_INVALIDARG if we don't.
  1004. //
  1005. hr = E_INVALIDARG;
  1006. for (iterSrc = SrcBindPath.begin(), iterDst = DstBindPath.begin();
  1007. iterSrc != SrcBindPath.end() && iterDst != DstBindPath.end();
  1008. iterSrc++, iterDst++)
  1009. {
  1010. // First time through *iterSrc is guaranteed to be the
  1011. // sameas *iterDst because the first component in both
  1012. // bindpaths is m_pComponent as tested above.
  1013. //
  1014. if (*iterSrc != *iterDst)
  1015. {
  1016. SrcEntry.pLower = *iterSrc;
  1017. Assert (SrcEntry.pLower);
  1018. DstEntry.pLower = *iterDst;
  1019. Assert (DstEntry.pUpper);
  1020. Assert (SrcEntry.pUpper == DstEntry.pUpper);
  1021. Assert (SrcEntry.pLower != DstEntry.pLower);
  1022. hr = m_pINetCfg->m_pNetConfig->Core.StackTable.
  1023. HrMoveStackEntries (
  1024. &SrcEntry,
  1025. &DstEntry,
  1026. Flag,
  1027. &m_pINetCfg->m_pNetConfig->ModifyCtx);
  1028. if(SUCCEEDED(hr))
  1029. {
  1030. // Mark this component as dirty so it's bindings will be written out and
  1031. // NDIS will be notified.
  1032. m_pINetCfg->m_pNetConfig->ModifyCtx.
  1033. HrDirtyComponentAndComponentsAbove(SrcEntry.pUpper);
  1034. m_pINetCfg->m_pNetConfig->ModifyCtx.
  1035. HrDirtyComponentAndComponentsAbove(DstEntry.pUpper);
  1036. }
  1037. break;
  1038. }
  1039. // Remember the upper components as we are about to
  1040. // advance past them.
  1041. //
  1042. SrcEntry.pUpper = *iterSrc;
  1043. Assert (SrcEntry.pUpper);
  1044. DstEntry.pUpper = *iterDst;
  1045. Assert (SrcEntry.pUpper);
  1046. Assert (SrcEntry.pUpper == DstEntry.pUpper);
  1047. }
  1048. }
  1049. else
  1050. {
  1051. SrcEntry.pUpper = SrcBindPath.POwner();
  1052. Assert ((SrcBindPath.begin() + 1) != SrcBindPath.end());
  1053. SrcEntry.pLower = *(SrcBindPath.begin() + 1);
  1054. hr = m_pINetCfg->m_pNetConfig->Core.StackTable.
  1055. HrMoveStackEntries (
  1056. &SrcEntry,
  1057. NULL,
  1058. Flag,
  1059. &m_pINetCfg->m_pNetConfig->ModifyCtx);
  1060. if(SUCCEEDED(hr))
  1061. {
  1062. // Mark this component as dirty so it's bindings will be written out and
  1063. // NDIS will be notified.
  1064. m_pINetCfg->m_pNetConfig->ModifyCtx.
  1065. HrDirtyComponentAndComponentsAbove(SrcEntry.pUpper);
  1066. }
  1067. }
  1068. unlock:
  1069. Unlock();
  1070. }
  1071. }
  1072. TraceHr (ttidError, FAL, hr, FALSE,
  1073. "CImplINetCfgComponent::HrMoveBindPath");
  1074. return hr;
  1075. }
  1076. STDMETHODIMP
  1077. CImplINetCfgComponent::MoveBefore (
  1078. IN INetCfgBindingPath* pIPathSrc,
  1079. IN INetCfgBindingPath* pIPathDst)
  1080. {
  1081. HRESULT hr;
  1082. hr = HrMoveBindPath (pIPathSrc, pIPathDst, MOVE_BEFORE);
  1083. TraceHr (ttidError, FAL, hr, FALSE,
  1084. "CImplINetCfgComponent::MoveBefore");
  1085. return hr;
  1086. }
  1087. STDMETHODIMP
  1088. CImplINetCfgComponent::MoveAfter (
  1089. IN INetCfgBindingPath* pIPathSrc,
  1090. IN INetCfgBindingPath* pIPathDst)
  1091. {
  1092. HRESULT hr;
  1093. hr = HrMoveBindPath (pIPathSrc, pIPathDst, MOVE_AFTER);
  1094. TraceHr (ttidError, FAL, hr, FALSE,
  1095. "CImplINetCfgComponent::MoveAfter");
  1096. return hr;
  1097. }
  1098. //+---------------------------------------------------------------------------
  1099. // INetCfgComponentPrivate -
  1100. //
  1101. STDMETHODIMP
  1102. CImplINetCfgComponent::QueryNotifyObject (
  1103. IN REFIID riid,
  1104. OUT VOID** ppvObject)
  1105. {
  1106. HRESULT hr;
  1107. // Validate parameters.
  1108. //
  1109. if (FBadInPtr(&riid) || FBadOutPtr (ppvObject))
  1110. {
  1111. hr = E_POINTER;
  1112. }
  1113. else
  1114. {
  1115. *ppvObject = NULL;
  1116. hr = HrLockAndTestForValidInterface (IF_NEED_COMPONENT_DATA, NULL, NULL);
  1117. if (S_OK == hr)
  1118. {
  1119. hr = m_pComponent->Notify.QueryNotifyObject (
  1120. m_pINetCfg, riid, ppvObject);
  1121. Unlock();
  1122. }
  1123. }
  1124. TraceHr (ttidError, FAL, hr, FALSE,
  1125. "CImplINetCfgComponent::QueryNotifyObject");
  1126. return hr;
  1127. }
  1128. STDMETHODIMP
  1129. CImplINetCfgComponent::SetDirty ()
  1130. {
  1131. HRESULT hr;
  1132. hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK, NULL, NULL);
  1133. if (S_OK == hr)
  1134. {
  1135. hr = m_pINetCfg->m_pNetConfig->ModifyCtx.HrDirtyComponent(
  1136. m_pComponent);
  1137. Unlock ();
  1138. }
  1139. TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgComponent::SetDirty");
  1140. return hr;
  1141. }
  1142. STDMETHODIMP
  1143. CImplINetCfgComponent::NotifyUpperEdgeConfigChange ()
  1144. {
  1145. HRESULT hr;
  1146. hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK, NULL, NULL);
  1147. if (S_OK == hr)
  1148. {
  1149. hr = m_pINetCfg->m_pNetConfig->ModifyCtx.
  1150. HrDirtyComponentAndComponentsAbove (m_pComponent);
  1151. Unlock ();
  1152. }
  1153. TraceHr (ttidError, FAL, hr, FALSE,
  1154. "CImplINetCfgComponent::NotifyUpperEdgeConfigChange");
  1155. return hr;
  1156. }