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.

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