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.

1892 lines
62 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C N E T C F G . C P P
  7. //
  8. // Contents: Common routines for dealing with INetCfg interfaces.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 24 Mar 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include "netcfgx.h"
  18. #include "netcfgn.h"
  19. #include "netcfgp.h"
  20. #include "ncdebug.h"
  21. #include "ncbase.h"
  22. #include "ncmisc.h"
  23. #include "ncnetcfg.h"
  24. #include "ncreg.h"
  25. #include "ncvalid.h"
  26. extern const WCHAR c_szRegKeyAnswerFileMap[];
  27. extern const WCHAR c_szInfId_MS_AppleTalk[];
  28. extern const WCHAR c_szInfId_MS_AtmArps[];
  29. extern const WCHAR c_szInfId_MS_AtmElan[];
  30. extern const WCHAR c_szInfId_MS_AtmLane[];
  31. extern const WCHAR c_szInfId_MS_AtmUni[];
  32. extern const WCHAR c_szInfId_MS_DHCPServer[];
  33. extern const WCHAR c_szInfId_MS_GPC[];
  34. extern const WCHAR c_szInfId_MS_IrDA[];
  35. extern const WCHAR c_szInfId_MS_IrdaMiniport[];
  36. extern const WCHAR c_szInfId_MS_IrModemMiniport[];
  37. extern const WCHAR c_szInfId_MS_Isotpsys[];
  38. extern const WCHAR c_szInfId_MS_L2TP[];
  39. extern const WCHAR c_szInfId_MS_L2tpMiniport[];
  40. extern const WCHAR c_szInfId_MS_MSClient[];
  41. extern const WCHAR c_szInfId_MS_NdisWan[];
  42. extern const WCHAR c_szInfId_MS_NdisWanAtalk[];
  43. extern const WCHAR c_szInfId_MS_NdisWanBh[];
  44. extern const WCHAR c_szInfId_MS_NdisWanIp[];
  45. extern const WCHAR c_szInfId_MS_NdisWanIpx[];
  46. extern const WCHAR c_szInfId_MS_NdisWanNbfIn[];
  47. extern const WCHAR c_szInfId_MS_NdisWanNbfOut[];
  48. extern const WCHAR c_szInfId_MS_NetBIOS[];
  49. extern const WCHAR c_szInfId_MS_NetBT[];
  50. extern const WCHAR c_szInfId_MS_NetBT_SMB[];
  51. extern const WCHAR c_szInfId_MS_NetMon[];
  52. extern const WCHAR c_szInfId_MS_NWClient[];
  53. extern const WCHAR c_szInfId_MS_NWIPX[];
  54. extern const WCHAR c_szInfId_MS_NWNB[];
  55. extern const WCHAR c_szInfId_MS_NwSapAgent[];
  56. extern const WCHAR c_szInfId_MS_NWSPX[];
  57. extern const WCHAR c_szInfId_MS_PPPOE[];
  58. extern const WCHAR c_szInfId_MS_PppoeMiniport[];
  59. extern const WCHAR c_szInfId_MS_PPTP[];
  60. extern const WCHAR c_szInfId_MS_PptpMiniport[];
  61. extern const WCHAR c_szInfId_MS_PSched[];
  62. extern const WCHAR c_szInfId_MS_PSchedMP[];
  63. extern const WCHAR c_szInfId_MS_PSchedPC[];
  64. extern const WCHAR c_szInfId_MS_PtiMiniport[];
  65. extern const WCHAR c_szInfId_MS_RasCli[];
  66. extern const WCHAR c_szInfId_MS_RasMan[];
  67. extern const WCHAR c_szInfId_MS_RasSrv[];
  68. extern const WCHAR c_szInfId_MS_RawWan[];
  69. extern const WCHAR c_szInfId_MS_Server[];
  70. extern const WCHAR c_szInfId_MS_Steelhead[];
  71. extern const WCHAR c_szInfId_MS_Streams[];
  72. extern const WCHAR c_szInfId_MS_TCPIP[];
  73. #pragma BEGIN_CONST_SECTION
  74. // Warning: This must stay sorted on component id!
  75. // Hint: With VSlick, use 'sort_on_selection AI' to resort this.
  76. //
  77. extern const __declspec(selectany) COMPONENT_INFO c_mapComponents [] =
  78. {
  79. { c_szInfId_MS_AppleTalk, &GUID_DEVCLASS_NETTRANS, L"netatlk.inf" },
  80. { c_szInfId_MS_AtmArps, &GUID_DEVCLASS_NETTRANS, L"netaarps.inf"},
  81. { c_szInfId_MS_AtmElan, &GUID_DEVCLASS_NET, L"netlanem.inf"},
  82. { c_szInfId_MS_AtmLane, &GUID_DEVCLASS_NETTRANS, L"netlanep.inf"},
  83. { c_szInfId_MS_AtmUni, &GUID_DEVCLASS_NETTRANS, L"netauni.inf"},
  84. { c_szInfId_MS_DHCPServer, &GUID_DEVCLASS_NETSERVICE, L"netdhcps.inf" },
  85. { c_szInfId_MS_IrDA, &GUID_DEVCLASS_NETTRANS, L"netirda.inf" },
  86. { c_szInfId_MS_IrdaMiniport, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  87. { c_szInfId_MS_IrModemMiniport, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  88. { c_szInfId_MS_Isotpsys, &GUID_DEVCLASS_NETTRANS, L"nettp4.inf" },
  89. { c_szInfId_MS_L2TP, &GUID_DEVCLASS_NETTRANS, L"netrast.inf" },
  90. { c_szInfId_MS_L2tpMiniport, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  91. { c_szInfId_MS_MSClient, &GUID_DEVCLASS_NETCLIENT, L"netmscli.inf" },
  92. { c_szInfId_MS_NdisWan, &GUID_DEVCLASS_NETTRANS, L"netrast.inf" },
  93. { c_szInfId_MS_NdisWanAtalk, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  94. { c_szInfId_MS_NdisWanBh, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  95. { c_szInfId_MS_NdisWanIp, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  96. { c_szInfId_MS_NdisWanIpx, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  97. { c_szInfId_MS_NdisWanNbfIn, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  98. { c_szInfId_MS_NdisWanNbfOut, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  99. { c_szInfId_MS_NetBIOS, &GUID_DEVCLASS_NETSERVICE, L"netnb.inf" },
  100. { c_szInfId_MS_NetBT, &GUID_DEVCLASS_NETTRANS, L"nettcpip.inf" },
  101. { c_szInfId_MS_NetBT_SMB, &GUID_DEVCLASS_NETTRANS, L"nettcpip.inf" },
  102. { c_szInfId_MS_NetMon, &GUID_DEVCLASS_NETTRANS, L"netnm.inf" },
  103. { c_szInfId_MS_NWClient, &GUID_DEVCLASS_NETCLIENT, L"netnwcli.inf" },
  104. { c_szInfId_MS_NWIPX, &GUID_DEVCLASS_NETTRANS, L"netnwlnk.inf" },
  105. { c_szInfId_MS_NWNB, &GUID_DEVCLASS_NETTRANS, L"netnwlnk.inf" },
  106. { c_szInfId_MS_NwSapAgent, &GUID_DEVCLASS_NETSERVICE, L"netsap.inf" },
  107. { c_szInfId_MS_NWSPX, &GUID_DEVCLASS_NETTRANS, L"netnwlnk.inf" },
  108. { c_szInfId_MS_PPPOE, &GUID_DEVCLASS_NETTRANS, L"netrast.inf" },
  109. { c_szInfId_MS_PppoeMiniport, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  110. { c_szInfId_MS_PPTP, &GUID_DEVCLASS_NETTRANS, L"netrast.inf" },
  111. { c_szInfId_MS_PptpMiniport, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  112. { c_szInfId_MS_PSched, &GUID_DEVCLASS_NETSERVICE, L"netpschd.inf" },
  113. { c_szInfId_MS_PSchedMP, &GUID_DEVCLASS_NET, L"netpsa.inf" },
  114. { c_szInfId_MS_PSchedPC, &GUID_DEVCLASS_NETSERVICE, L"netpschd.inf" },
  115. { c_szInfId_MS_PtiMiniport, &GUID_DEVCLASS_NET, L"netrasa.inf" },
  116. { c_szInfId_MS_RasCli, &GUID_DEVCLASS_NETSERVICE, L"netrass.inf" },
  117. { c_szInfId_MS_RasMan, &GUID_DEVCLASS_NETSERVICE, L"netrass.inf" },
  118. { c_szInfId_MS_RasSrv, &GUID_DEVCLASS_NETSERVICE, L"netrass.inf" },
  119. { c_szInfId_MS_RawWan, &GUID_DEVCLASS_NETTRANS, L"netrwan.inf" },
  120. { c_szInfId_MS_Server, &GUID_DEVCLASS_NETSERVICE, L"netserv.inf" },
  121. { c_szInfId_MS_Steelhead, &GUID_DEVCLASS_NETSERVICE, L"netrass.inf" },
  122. { c_szInfId_MS_Streams, &GUID_DEVCLASS_NETTRANS, L"netstrm.inf" },
  123. { c_szInfId_MS_TCPIP, &GUID_DEVCLASS_NETTRANS, L"nettcpip.inf" },
  124. { L"ms_wanarp", &GUID_DEVCLASS_NET, L"netrast.inf" },
  125. };
  126. #pragma END_CONST_SECTION
  127. //+---------------------------------------------------------------------------
  128. //
  129. // Function: NCompareComponentIds
  130. //
  131. // Purpose: Compare function for bsearch.
  132. //
  133. // Arguments:
  134. // ppszComp1 [in] pointer to pointer to a component id
  135. // ppszComp2 [in] pointer to pointer to a component id
  136. //
  137. // Returns: < 0 if pvComp1 is less than pvComp2
  138. // 0 if they are equal
  139. // > 0 if pvComp1 is greater than pvComp2
  140. //
  141. // Author: shaunco 27 Jul 1997
  142. //
  143. // Notes:
  144. //
  145. int __cdecl
  146. NCompareComponentIds (
  147. IN const PCWSTR* ppszComp1,
  148. IN const PCWSTR* ppszComp2)
  149. {
  150. return lstrcmpiW (*ppszComp1, *ppszComp2);
  151. }
  152. //+---------------------------------------------------------------------------
  153. //
  154. // Function: PComponentInfoFromComponentId
  155. //
  156. // Purpose: Return the COMPONENT_INFO record within c_mapComponents
  157. // having the specified component id.
  158. //
  159. // Arguments:
  160. // pszComponentId [in] The requested component id.
  161. //
  162. // Returns: NULL if not found.
  163. //
  164. // Author: shaunco 27 Jul 1997
  165. //
  166. // Notes:
  167. //
  168. inline
  169. const COMPONENT_INFO*
  170. PComponentInfoFromComponentId (
  171. PCWSTR pszComponentId)
  172. {
  173. // For debug builds, check that c_mapComponents is sorted properley.
  174. // If it isn't, bsearch (called below) won't work. Only perform this
  175. // check once because the map doesn't change.
  176. //
  177. #ifdef DBG
  178. static BOOL fCheckedSorted = FALSE;
  179. if (!fCheckedSorted)
  180. {
  181. fCheckedSorted = TRUE;
  182. for (UINT i = 1; i < celems (c_mapComponents); i++)
  183. {
  184. PCWSTR pszComp1 = c_mapComponents [i-1].pszComponentId;
  185. PCWSTR pszComp2 = c_mapComponents [i] .pszComponentId;
  186. if (NCompareComponentIds (&pszComp1, &pszComp2) >= 0)
  187. {
  188. AssertFmt (FALSE, FAL,
  189. "'%S' in c_mapComponents is out of order! "
  190. "Component installation may fail in bizarre ways!",
  191. pszComp2);
  192. }
  193. }
  194. }
  195. #endif
  196. typedef int (__cdecl *PFNCOMPARE)(const void *, const void *);
  197. PFNCOMPARE pfn = reinterpret_cast<PFNCOMPARE>(NCompareComponentIds);
  198. return static_cast<const COMPONENT_INFO*>
  199. (bsearch (&pszComponentId,
  200. &c_mapComponents->pszComponentId,
  201. celems (c_mapComponents),
  202. sizeof (c_mapComponents[0]),
  203. pfn));
  204. }
  205. //+---------------------------------------------------------------------------
  206. //
  207. // Function: FClassGuidFromComponentId
  208. //
  209. // Purpose: Given a component id, returns the class guid associated with
  210. // it.
  211. //
  212. // Arguments:
  213. // pszComponentId [in] Component id to look up.
  214. // pguidClass [out] Class guid to be returned.
  215. //
  216. // Returns: TRUE if component was found, FALSE if not.
  217. //
  218. // Author: danielwe 17 Jun 1997
  219. //
  220. // Notes:
  221. //
  222. BOOL
  223. FClassGuidFromComponentId (
  224. PCWSTR pszComponentId,
  225. const GUID** ppguidClass)
  226. {
  227. Assert(ppguidClass);
  228. // Initialize output parameter.
  229. //
  230. *ppguidClass = NULL;
  231. const COMPONENT_INFO* pComponentInfo =
  232. PComponentInfoFromComponentId (pszComponentId);
  233. if (pComponentInfo)
  234. {
  235. *ppguidClass = pComponentInfo->pguidClass;
  236. return TRUE;
  237. }
  238. TraceTag (ttidNetcfgBase,
  239. "Found no match for %S in FClassGuidFromComponentId.",
  240. pszComponentId);
  241. return FALSE;
  242. }
  243. //+---------------------------------------------------------------------------
  244. //
  245. // Function: FInfFileFromComponentId
  246. //
  247. // Purpose: Given a component ID, returns the INF file name it lives in.
  248. //
  249. // Arguments:
  250. // pszComponentId [in] Component id to look up.
  251. // pszInfFile [out] INF file name to be returned.
  252. // (must be _MAX_PATH long).
  253. //
  254. // Returns: TRUE if component was found, FALSE if not.
  255. //
  256. // Author: shaunco 27 Jul 1997
  257. //
  258. // Notes:
  259. //
  260. BOOL
  261. FInfFileFromComponentId (
  262. PCWSTR pszComponentId,
  263. PWSTR pszInfFile)
  264. {
  265. Assert(pszComponentId);
  266. Assert(pszInfFile);
  267. // Initialize output parameter.
  268. //
  269. *pszInfFile = 0;
  270. const COMPONENT_INFO* pComponentInfo =
  271. PComponentInfoFromComponentId (pszComponentId);
  272. if (pComponentInfo)
  273. {
  274. wcsncpy (pszInfFile, pComponentInfo->pszInfFile, _MAX_PATH);
  275. pszInfFile [_MAX_PATH - 1] = 0;
  276. return TRUE;
  277. }
  278. TraceTag (ttidNetcfgBase,
  279. "Found no match for %S in FInfFileFromComponentId.",
  280. pszComponentId);
  281. return FALSE;
  282. }
  283. //+---------------------------------------------------------------------------
  284. //
  285. // Function: FGetInstanceGuidOfComponentFromAnswerFileMap
  286. //
  287. // Purpose: Maps a component instance in the answer file to
  288. // its instance guid.
  289. //
  290. // Arguments:
  291. // pszComponentId [in] Name of component to get guid of.
  292. // pguid [out] Returns instance GUID of that component.
  293. //
  294. // Returns: TRUE if successful, FALSE if the component was not located.
  295. //
  296. BOOL
  297. FGetInstanceGuidOfComponentFromAnswerFileMap (
  298. IN PCWSTR pszComponentId,
  299. OUT GUID* pguid)
  300. {
  301. HRESULT hr;
  302. BOOL fFound = FALSE;
  303. // Component not found as already installed. Need to examine the
  304. // AnswerFileMap in the registry.
  305. //
  306. HKEY hkey;
  307. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyAnswerFileMap,
  308. KEY_QUERY_VALUE, &hkey);
  309. if (S_OK == hr)
  310. {
  311. WCHAR szGuid [c_cchGuidWithTerm];
  312. DWORD cbData = sizeof (szGuid);
  313. hr = HrRegQuerySzBuffer(hkey, pszComponentId, szGuid, &cbData);
  314. if (S_OK == hr)
  315. {
  316. hr = IIDFromString(szGuid, pguid);
  317. fFound = (S_OK == hr);
  318. }
  319. RegCloseKey(hkey);
  320. }
  321. #ifdef ENABLETRACE
  322. if (FAILED(hr))
  323. {
  324. TraceTag(ttidNetcfgBase, "FGetInstanceGuidOfComponentInAnswerFile: "
  325. "could not locate instance GUID of %S", pszComponentId);
  326. }
  327. #endif
  328. return fFound;
  329. }
  330. //+---------------------------------------------------------------------------
  331. //
  332. // Function: FGetInstanceGuidOfComponentInAnswerFile
  333. //
  334. // Purpose: Maps a component instance in the answer file to
  335. // its instance guid.
  336. //
  337. // Arguments:
  338. // pszComponentId [in] Name of component to get guid of.
  339. // pnc [in] INetCfg interface
  340. // pguid [out] Returns instance GUID of that component.
  341. //
  342. // Returns: TRUE if successful, FALSE if the component was not located.
  343. //
  344. BOOL
  345. FGetInstanceGuidOfComponentInAnswerFile(
  346. IN PCWSTR pszComponentId,
  347. IN INetCfg* pnc,
  348. OUT LPGUID pguid)
  349. {
  350. static char __FUNCNAME__[] = "FGetInstanceGuidOfComponentInAnswerFile";
  351. Assert (pszComponentId);
  352. AssertValidReadPtr(pnc);
  353. AssertValidWritePtr(pguid);
  354. // Search for the component.
  355. //
  356. INetCfgComponent* pncc;
  357. HRESULT hr = pnc->FindComponent (pszComponentId, &pncc);
  358. if (S_OK == hr)
  359. {
  360. hr = pncc->GetInstanceGuid (pguid);
  361. ReleaseObj(pncc);
  362. }
  363. else
  364. {
  365. // Component not found as already installed. Need to examine the
  366. // AnswerFileMap in the registry.
  367. //
  368. HKEY hkey;
  369. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyAnswerFileMap,
  370. KEY_QUERY_VALUE, &hkey);
  371. if (S_OK == hr)
  372. {
  373. WCHAR szGuid [c_cchGuidWithTerm];
  374. DWORD cbData = sizeof (szGuid);
  375. hr = HrRegQuerySzBuffer(hkey, pszComponentId, szGuid, &cbData);
  376. if (S_OK == hr)
  377. {
  378. hr = IIDFromString(szGuid, pguid);
  379. }
  380. RegCloseKey(hkey);
  381. }
  382. #ifdef ENABLETRACE
  383. if (FAILED(hr))
  384. {
  385. TraceTag(ttidNetcfgBase, "%s: could not locate instance GUID of %S",
  386. __FUNCNAME__, pszComponentId);
  387. }
  388. #endif
  389. }
  390. TraceHr(ttidError, FAL, hr, (S_FALSE == hr), __FUNCNAME__);
  391. return (SUCCEEDED(hr)) ? TRUE : FALSE;
  392. }
  393. //+---------------------------------------------------------------------------
  394. //
  395. // Function: FIsBindingName
  396. //
  397. // Purpose: Returns TRUE if a binding interface is of the specified name.
  398. //
  399. // Arguments:
  400. // pszName [in] Name of the binding interface to check for.
  401. // dwFlags [in] FIBN_ flags
  402. // pncbi [in] Binding interface pointer.
  403. //
  404. // Returns: TRUE if the binding interface is of the specified name.
  405. //
  406. // Author: shaunco 24 Mar 1997
  407. //
  408. // Notes:
  409. //
  410. BOOL
  411. FIsBindingName (
  412. PCWSTR pszName,
  413. DWORD dwFlags,
  414. INetCfgBindingInterface* pncbi)
  415. {
  416. Assert (pszName);
  417. Assert (pncbi);
  418. BOOL fRet = FALSE;
  419. PWSTR pszInterfaceName;
  420. if (SUCCEEDED(pncbi->GetName (&pszInterfaceName)))
  421. {
  422. INT c_cchPrefix = (FIBN_PREFIX & dwFlags) ? lstrlenW (pszName) : -1;
  423. fRet = (2 == CompareStringW (LOCALE_SYSTEM_DEFAULT, 0,
  424. pszName, c_cchPrefix,
  425. pszInterfaceName, c_cchPrefix));
  426. CoTaskMemFree (pszInterfaceName);
  427. }
  428. return fRet;
  429. }
  430. //+---------------------------------------------------------------------------
  431. //
  432. // Function: FIsComponentId
  433. //
  434. // Purpose: Returns TRUE if a component is of the specified id.
  435. //
  436. // Arguments:
  437. // pszComponentId [in] Component Id to check for.
  438. // pncc [in] Component interface pointer.
  439. //
  440. // Returns: TRUE if component is of the specified id.
  441. //
  442. // Author: shaunco 24 Mar 1997
  443. //
  444. // Notes:
  445. //
  446. BOOL
  447. FIsComponentId (
  448. PCWSTR pszComponentId,
  449. INetCfgComponent* pncc)
  450. {
  451. Assert (pszComponentId);
  452. Assert (pncc);
  453. BOOL fRet = FALSE;
  454. PWSTR pszId;
  455. if (SUCCEEDED(pncc->GetId (&pszId)))
  456. {
  457. if (FEqualComponentId (pszComponentId, pszId))
  458. fRet = TRUE;
  459. CoTaskMemFree (pszId);
  460. }
  461. return fRet;
  462. }
  463. //+---------------------------------------------------------------------------
  464. //
  465. // Function: HrAddOrRemoveAdapter
  466. //
  467. // Purpose:
  468. //
  469. // Arguments:
  470. // pnc [in] pointer to an INetCfg object.
  471. // pszComponentId [in] component INF id.
  472. // dwFlags [in]
  473. //
  474. // ARA_ADD : Add the component
  475. // ARA_REMOVE : Remove the component. Cannot be specified
  476. // with ARA_ADD.
  477. // pOboToken [in] If specified, refcount the adapter. This is the
  478. // on behalf of token adding or removing the specified
  479. // component. This allows per-component reference
  480. // counts of another.
  481. // cInstances [in] this specifies how many instances (or references)
  482. // to add or remove.
  483. // ppncc [out] (optional). The newly added component. Can only
  484. // be specified when adding one component.
  485. //
  486. // Returns: S_OK or an error
  487. //
  488. // Author: shaunco 28 Mar 1997
  489. //
  490. // Notes:
  491. //
  492. HRESULT
  493. HrAddOrRemoveAdapter (
  494. INetCfg* pnc,
  495. PCWSTR pszComponentId,
  496. DWORD dwFlags,
  497. OBO_TOKEN* pOboToken,
  498. UINT cInstances,
  499. INetCfgComponent** ppncc)
  500. {
  501. Assert (pnc);
  502. Assert (pszComponentId);
  503. Assert (dwFlags);
  504. Assert (cInstances);
  505. #ifdef DBG
  506. AssertSz ((dwFlags & ARA_ADD) || (dwFlags & ARA_REMOVE),
  507. "Need to add or remove. Can't do neither.");
  508. if (dwFlags & ARA_ADD)
  509. {
  510. AssertSz (!(dwFlags & ARA_REMOVE), "Can't remove AND add.");
  511. }
  512. if (dwFlags & ARA_REMOVE)
  513. {
  514. AssertSz (!(dwFlags & ARA_ADD), "Can't add AND remove.");
  515. }
  516. AssertSz (FImplies(1 != cInstances, NULL == ppncc),
  517. "Can't return ppncc when cInstances is greater than one.");
  518. AssertSz (FImplies(ppncc, 1 == cInstances),
  519. "Can only add one instance when returning ppncc.");
  520. AssertSz (FImplies(ppncc, dwFlags & ARA_ADD),
  521. "Can't return ppncc when removing.");
  522. #endif
  523. // Get the component class object for adapters.
  524. INetCfgClass* pncclass;
  525. HRESULT hr = pnc->QueryNetCfgClass (&GUID_DEVCLASS_NET, IID_INetCfgClass,
  526. reinterpret_cast<void**>(&pncclass));
  527. if (S_OK == hr)
  528. {
  529. INetCfgClassSetup* pncclasssetup;
  530. hr = pncclass->QueryInterface (IID_INetCfgClassSetup,
  531. reinterpret_cast<void**>(&pncclasssetup));
  532. if (S_OK == hr)
  533. {
  534. if (dwFlags & ARA_ADD)
  535. {
  536. // Install the component the specified number of times.
  537. //
  538. while (SUCCEEDED(hr) && cInstances--)
  539. {
  540. hr = pncclasssetup->Install(pszComponentId, pOboToken,
  541. 0, 0, NULL, NULL, ppncc );
  542. }
  543. }
  544. else
  545. {
  546. // Remove the component the specified number of times.
  547. //
  548. AssertSz(S_OK == hr, "hr should be S_OK here to make sure the "
  549. "loop is given a chance.");
  550. while (SUCCEEDED(hr) && cInstances)
  551. {
  552. // Find and remove the component.
  553. //
  554. INetCfgComponent* pncc;
  555. hr = pncclass->FindComponent (pszComponentId, &pncc);
  556. if (S_OK == hr)
  557. {
  558. hr = pncclasssetup->DeInstall (pncc,
  559. pOboToken, NULL);
  560. cInstances--;
  561. ReleaseObj (pncc);
  562. }
  563. else if (S_FALSE == hr)
  564. {
  565. // If it wasn't found, get out.
  566. break;
  567. }
  568. }
  569. AssertSz (FImplies(SUCCEEDED(hr), (0 == cInstances)),
  570. "cInstances should be zero. This assert means "
  571. "that we were asked to remove more instances than "
  572. "were installed.");
  573. }
  574. // Normalize the HRESULT.
  575. // Possible values of hr at this point are S_FALSE,
  576. // NETCFG_S_REBOOT, and NETCFG_S_STILL_REFERENCED.
  577. //
  578. if (SUCCEEDED(hr))
  579. {
  580. hr = S_OK;
  581. }
  582. ReleaseObj( pncclasssetup );
  583. }
  584. ReleaseObj (pncclass);
  585. }
  586. TraceHr (ttidError, FAL, hr, FALSE, "HrAddOrRemoveAdapter");
  587. return hr;
  588. }
  589. //+---------------------------------------------------------------------------
  590. //
  591. // Function: HrFindAndRemoveAllInstancesOfAdapter
  592. //
  593. // Purpose: Remove all instances of the adapter with the specified
  594. // component id.
  595. //
  596. // Arguments:
  597. // pnc [in] INetCfg pointer.
  598. // pszComponentId [in] Component id to search for and remove.
  599. //
  600. // Returns: S_OK or an error code
  601. //
  602. // Author: shaunco 4 Jan 1998
  603. //
  604. // Notes:
  605. //
  606. HRESULT
  607. HrFindAndRemoveAllInstancesOfAdapter (
  608. INetCfg* pnc,
  609. PCWSTR pszComponentId)
  610. {
  611. Assert (pnc);
  612. Assert (pszComponentId);
  613. PCWSTR apszComponentId [1];
  614. apszComponentId[0] = pszComponentId;
  615. HRESULT hr = HrFindAndRemoveAllInstancesOfAdapters (pnc,
  616. 1, apszComponentId);
  617. TraceHr (ttidError, FAL, hr, FALSE,
  618. "HrFindAndRemoveAllInstancesOfAdapter");
  619. return hr;
  620. }
  621. //+---------------------------------------------------------------------------
  622. //
  623. // Function: HrFindAndRemoveAllInstancesOfAdapters
  624. //
  625. // Purpose: Remove all instances of the adapters with the specified
  626. // component ids.
  627. //
  628. // Arguments:
  629. // pnc [in] INetCfg pointer.
  630. // cComponents [in] Count of component ids in the array.
  631. // apszComponentId [in] Array of compoennt ids to search for and
  632. // remove.
  633. //
  634. // Returns: S_OK or an error code.
  635. //
  636. // Author: shaunco 4 Jan 1998
  637. //
  638. // Notes:
  639. //
  640. HRESULT
  641. HrFindAndRemoveAllInstancesOfAdapters (
  642. INetCfg* pnc,
  643. ULONG cComponents,
  644. const PCWSTR* apszComponentId)
  645. {
  646. Assert (pnc);
  647. Assert (cComponents);
  648. Assert (apszComponentId);
  649. // Get the class object for adapters.
  650. INetCfgClass* pncclass;
  651. INetCfgClassSetup* pncclasssetup;
  652. HRESULT hr = pnc->QueryNetCfgClass (&GUID_DEVCLASS_NET,
  653. IID_INetCfgClass,
  654. reinterpret_cast<void**>(&pncclass));
  655. if (S_OK == hr)
  656. {
  657. hr = pncclass->QueryInterface (IID_INetCfgClassSetup,
  658. reinterpret_cast<void**>(&pncclasssetup));
  659. if (S_OK == hr)
  660. {
  661. for (ULONG i = 0; (i < cComponents) && SUCCEEDED(hr); i++)
  662. {
  663. // Find and remove all instances of the component.
  664. INetCfgComponent* pncc;
  665. while ((SUCCEEDED(hr)) &&
  666. (S_OK == (hr = pncclass->FindComponent (
  667. apszComponentId[i], &pncc))))
  668. {
  669. hr = pncclasssetup->DeInstall (pncc, NULL, NULL);
  670. ReleaseObj (pncc);
  671. }
  672. // Normalize the HRESULT.
  673. //
  674. if (SUCCEEDED(hr))
  675. {
  676. hr = S_OK;
  677. }
  678. }
  679. ReleaseObj (pncclasssetup);
  680. }
  681. ReleaseObj (pncclass);
  682. }
  683. TraceHr (ttidError, FAL, hr, FALSE,
  684. "HrFindAndRemoveAllInstancesOfAdapters");
  685. return hr;
  686. }
  687. //+---------------------------------------------------------------------------
  688. //
  689. // Function: HrFindAndRemoveComponent
  690. //
  691. // Purpose: Find and remove the component with the specified id.
  692. //
  693. // Arguments:
  694. // pnc [in] INetCfg pointer.
  695. // pguidClass [in] Class GUID of the component.
  696. // pszComponentId [in] Component id to search for and remove.
  697. // pOboToken [in] (Optional) If specified, remove on behalf of.
  698. //
  699. // Returns: S_OK, NETCFG_S_STILL_REFERENCED, or an error code.
  700. //
  701. // Author: shaunco 4 Jan 1998
  702. //
  703. // Notes:
  704. //
  705. HRESULT
  706. HrFindAndRemoveComponent (
  707. INetCfg* pnc,
  708. const GUID* pguidClass,
  709. PCWSTR pszComponentId,
  710. OBO_TOKEN* pOboToken)
  711. {
  712. Assert (pnc);
  713. Assert (pguidClass);
  714. Assert (pszComponentId);
  715. AssertSz (GUID_DEVCLASS_NET != *pguidClass,
  716. "Don't use this to remove adapters.");
  717. // Get the component class object.
  718. //
  719. INetCfgClass* pncclass;
  720. HRESULT hr = pnc->QueryNetCfgClass (pguidClass, IID_INetCfgClass,
  721. reinterpret_cast<void**>(&pncclass));
  722. if (SUCCEEDED(hr))
  723. {
  724. // Find the component to remove.
  725. //
  726. INetCfgComponent* pnccRemove;
  727. hr = pncclass->FindComponent (pszComponentId, &pnccRemove);
  728. if (S_OK == hr)
  729. {
  730. INetCfgClassSetup* pncclasssetup;
  731. hr = pncclass->QueryInterface (IID_INetCfgClassSetup,
  732. reinterpret_cast<void**>(&pncclasssetup));
  733. if (SUCCEEDED(hr))
  734. {
  735. hr = pncclasssetup->DeInstall (pnccRemove, pOboToken, NULL);
  736. ReleaseObj (pncclasssetup);
  737. }
  738. ReleaseObj (pnccRemove);
  739. }
  740. else if (S_FALSE == hr)
  741. {
  742. hr = S_OK;
  743. }
  744. ReleaseObj (pncclass);
  745. }
  746. TraceHr (ttidError, FAL, hr,
  747. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  748. "HrFindAndRemoveComponent");
  749. return hr;
  750. }
  751. //+---------------------------------------------------------------------------
  752. //
  753. // Function: HrFindAndRemoveComponents
  754. //
  755. // Purpose: Find and remove the components with the specified ids.
  756. //
  757. // Arguments:
  758. // pnc [in] INetCfg pointer.
  759. // cComponents [in] Count of components in the array.
  760. // apguidClass [in] Array of class GUIDs corresponding to the
  761. // array of component ids.
  762. // apszComponentId [in] Array of component ids to search for and
  763. // remove.
  764. // pOboToken [in] (Optional) If specified, remove on behalf of.
  765. //
  766. // Returns: S_OK, NETCFG_S_STILL_REFERENCED, or an error code.
  767. //
  768. // Author: shaunco 4 Jan 1998
  769. //
  770. // Notes:
  771. //
  772. HRESULT
  773. HrFindAndRemoveComponents (
  774. INetCfg* pnc,
  775. ULONG cComponents,
  776. const GUID** apguidClass,
  777. const PCWSTR* apszComponentId,
  778. OBO_TOKEN* pOboToken)
  779. {
  780. Assert (pnc);
  781. Assert (cComponents);
  782. Assert (apguidClass);
  783. Assert (apszComponentId);
  784. HRESULT hr = S_OK;
  785. for (ULONG i = 0; (i < cComponents) && SUCCEEDED(hr); i++)
  786. {
  787. hr = HrFindAndRemoveComponent (pnc, apguidClass[i],
  788. apszComponentId[i], pOboToken);
  789. }
  790. TraceHr (ttidError, FAL, hr,
  791. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  792. "HrFindAndRemoveComponents");
  793. return hr;
  794. }
  795. //+---------------------------------------------------------------------------
  796. //
  797. // Function: HrFindAndRemoveComponentsOboComponent
  798. //
  799. // Purpose: Remove multiple components on behalf of one component.
  800. //
  801. // Arguments:
  802. // pnc [in] pointer to an INetCfg object.
  803. // cComponents [in] count of class guid pointers and component id
  804. // pointers.
  805. // apguidClass [in] array of class guid pointers.
  806. // apszId [in] array of component id pointers.
  807. // pnccObo [in] the component requesting the remove. (i.e. the
  808. // "on behalf of" component.)
  809. //
  810. // Returns: S_OK, NETCFG_S_STILL_REFERENCED, or an error code.
  811. //
  812. // Author: shaunco 13 Apr 1997
  813. //
  814. // Notes:
  815. //
  816. HRESULT
  817. HrFindAndRemoveComponentsOboComponent (
  818. INetCfg* pnc,
  819. ULONG cComponents,
  820. const GUID** apguidClass,
  821. const PCWSTR* apszComponentId,
  822. INetCfgComponent* pnccObo)
  823. {
  824. Assert (pnc);
  825. Assert (cComponents);
  826. Assert (apguidClass);
  827. Assert (apszComponentId);
  828. Assert (pnccObo);
  829. // Make an "on behalf of" token for the requesting component.
  830. //
  831. OBO_TOKEN OboToken;
  832. ZeroMemory (&OboToken, sizeof(OboToken));
  833. OboToken.Type = OBO_COMPONENT;
  834. OboToken.pncc = pnccObo;
  835. HRESULT hr = HrFindAndRemoveComponents (pnc, cComponents,
  836. apguidClass, apszComponentId, &OboToken);
  837. TraceHr (ttidError, FAL, hr,
  838. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  839. "HrFindAndRemoveComponentsOboComponent");
  840. return hr;
  841. }
  842. //+---------------------------------------------------------------------------
  843. //
  844. // Function: HrFindAndRemoveComponentsOboUser
  845. //
  846. // Purpose: Remove multiple components on behalf of one component.
  847. //
  848. // Arguments:
  849. // pnc [in] pointer to an INetCfg object.
  850. // cComponents [in] count of class guid pointers and component id
  851. // pointers.
  852. // apguidClass [in] array of class guid pointers.
  853. // apszId [in] array of component id pointers.
  854. //
  855. // Returns: S_OK, NETCFG_S_STILL_REFERENCED, or an error code.
  856. //
  857. // Author: shaunco 13 Apr 1997
  858. //
  859. // Notes:
  860. //
  861. HRESULT
  862. HrFindAndRemoveComponentsOboUser (
  863. INetCfg* pnc,
  864. ULONG cComponents,
  865. const GUID** apguidClass,
  866. const PCWSTR* apszComponentId)
  867. {
  868. Assert (pnc);
  869. Assert (cComponents);
  870. Assert (apguidClass);
  871. Assert (apszComponentId);
  872. // Make an "on behalf of" token for the user.
  873. //
  874. OBO_TOKEN OboToken;
  875. ZeroMemory (&OboToken, sizeof(OboToken));
  876. OboToken.Type = OBO_USER;
  877. HRESULT hr = HrFindAndRemoveComponents (pnc, cComponents,
  878. apguidClass, apszComponentId, &OboToken);
  879. TraceHr (ttidError, FAL, hr,
  880. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  881. "HrFindAndRemoveComponentsOboUser");
  882. return hr;
  883. }
  884. //+---------------------------------------------------------------------------
  885. //
  886. // Function: HrFindComponents
  887. //
  888. // Purpose: Find multiple INetCfgComponents with one call. This makes
  889. // the error handling associated with multiple calls to
  890. // QueryNetCfgClass and Find much easier.
  891. //
  892. // Arguments:
  893. // pnc [in] pointer to INetCfg object
  894. // cComponents [in] count of class guid pointers, component id
  895. // pointers, and INetCfgComponent output pointers.
  896. // apguidClass [in] array of class guid pointers.
  897. // apszComponentId [in] array of component id pointers.
  898. // apncc [out] array of returned INetCfgComponet pointers.
  899. //
  900. // Returns: S_OK or an error code.
  901. //
  902. // Author: shaunco 22 Mar 1997
  903. //
  904. // Notes: cComponents is the count of pointers in all three arrays.
  905. // S_OK will still be returned even if no components were
  906. // found! This is by design.
  907. //
  908. HRESULT
  909. HrFindComponents (
  910. INetCfg* pnc,
  911. ULONG cComponents,
  912. const GUID** apguidClass,
  913. const PCWSTR* apszComponentId,
  914. INetCfgComponent** apncc)
  915. {
  916. Assert (pnc);
  917. Assert (cComponents);
  918. Assert (apguidClass);
  919. Assert (apszComponentId);
  920. Assert (apncc);
  921. // Initialize the output parameters.
  922. //
  923. ZeroMemory (apncc, cComponents * sizeof(*apncc));
  924. // Find all of the components requested.
  925. // Variable initialization is important here.
  926. HRESULT hr = S_OK;
  927. ULONG i;
  928. for (i = 0; (i < cComponents) && SUCCEEDED(hr); i++)
  929. {
  930. // Get the class object for this component.
  931. INetCfgClass* pncclass;
  932. hr = pnc->QueryNetCfgClass (apguidClass[i], IID_INetCfgClass,
  933. reinterpret_cast<void**>(&pncclass));
  934. if (SUCCEEDED(hr))
  935. {
  936. // Find the component.
  937. hr = pncclass->FindComponent (apszComponentId[i], &apncc[i]);
  938. AssertSz (SUCCEEDED(hr), "pncclass->Find failed.");
  939. ReleaseObj (pncclass);
  940. }
  941. }
  942. // On any error, release what we found and set the output to NULL.
  943. if (FAILED(hr))
  944. {
  945. for (i = 0; i < cComponents; i++)
  946. {
  947. ReleaseObj (apncc[i]);
  948. apncc[i] = NULL;
  949. }
  950. }
  951. // Otherwise, normalize the HRESULT. (i.e. don't return S_FALSE)
  952. else
  953. {
  954. hr = S_OK;
  955. }
  956. TraceHr (ttidError, FAL, hr, FALSE, "HrFindComponents");
  957. return hr;
  958. }
  959. //+---------------------------------------------------------------------------
  960. //
  961. // Function: HrGetBindingInterfaceComponents
  962. //
  963. // Purpose: Get both upper and lower components involved in a
  964. // binding interface.
  965. //
  966. // Arguments:
  967. // pncbi [in] binding interface.
  968. // ppnccUpper [out] output upper component.
  969. // ppnccLower [out] output lower compoenet.
  970. //
  971. // Returns: S_OK or an error code.
  972. //
  973. // Author: shaunco 18 Apr 1997
  974. //
  975. // Notes:
  976. //
  977. HRESULT
  978. HrGetBindingInterfaceComponents (
  979. INetCfgBindingInterface* pncbi,
  980. INetCfgComponent** ppnccUpper,
  981. INetCfgComponent** ppnccLower)
  982. {
  983. Assert (pncbi);
  984. Assert (ppnccUpper);
  985. Assert (ppnccLower);
  986. // Initialize the output parameters.
  987. *ppnccUpper = NULL;
  988. *ppnccLower = NULL;
  989. INetCfgComponent* pnccUpper;
  990. HRESULT hr = pncbi->GetUpperComponent (&pnccUpper);
  991. if (SUCCEEDED(hr))
  992. {
  993. INetCfgComponent* pnccLower;
  994. hr = pncbi->GetLowerComponent (&pnccLower);
  995. if (SUCCEEDED(hr))
  996. {
  997. *ppnccUpper = pnccUpper;
  998. *ppnccLower = pnccLower;
  999. }
  1000. else
  1001. {
  1002. // Rather than AddRef this in the above SUCCEEDED block followed
  1003. // by the normal unconditional Release, just Release here in
  1004. // the case of failure to get the lower component.
  1005. ReleaseObj (pnccUpper);
  1006. }
  1007. }
  1008. TraceHr (ttidError, FAL, hr, FALSE, "HrGetBindingInterfaceComponents");
  1009. return hr;
  1010. }
  1011. //+---------------------------------------------------------------------------
  1012. //
  1013. // Function: HrInstallComponent
  1014. //
  1015. // Purpose: Install the component with a specified id.
  1016. //
  1017. // Arguments:
  1018. // pnc [in] INetCfg pointer.
  1019. // pnip [in] (Optional) If specified, perform the installation
  1020. // using the answer file.
  1021. // pguidClass [in] Class guid of the component to install.
  1022. // pszComponentId [in] Component id to install.
  1023. // pOboToken [in] (Optional) If specified, perform the installation
  1024. // on behalf of this token.
  1025. // ppncc [out] (Optional) Returned component that was
  1026. // installed.
  1027. //
  1028. // Returns: S_OK or an error code.
  1029. //
  1030. // Author: shaunco 4 Jan 1998
  1031. //
  1032. // Notes:
  1033. //
  1034. HRESULT
  1035. HrInstallComponent (
  1036. INetCfg* pnc,
  1037. const NETWORK_INSTALL_PARAMS* pnip,
  1038. const GUID* pguidClass,
  1039. PCWSTR pszComponentId,
  1040. OBO_TOKEN* pOboToken,
  1041. INetCfgComponent** ppncc)
  1042. {
  1043. Assert (pnc);
  1044. Assert (pszComponentId);
  1045. // Initialize output parameter.
  1046. //
  1047. if (ppncc)
  1048. {
  1049. *ppncc = NULL;
  1050. }
  1051. // Get the class setup object.
  1052. //
  1053. INetCfgClassSetup* pncclasssetup;
  1054. HRESULT hr = pnc->QueryNetCfgClass (pguidClass, IID_INetCfgClassSetup,
  1055. reinterpret_cast<void**>(&pncclasssetup));
  1056. if (SUCCEEDED(hr))
  1057. {
  1058. if (pnip)
  1059. {
  1060. hr = pncclasssetup->Install (
  1061. pszComponentId,
  1062. pOboToken,
  1063. pnip->dwSetupFlags,
  1064. pnip->dwUpgradeFromBuildNo,
  1065. pnip->pszAnswerFile,
  1066. pnip->pszAnswerSection,
  1067. ppncc);
  1068. }
  1069. else
  1070. {
  1071. hr = pncclasssetup->Install (pszComponentId,
  1072. pOboToken, 0, 0, NULL, NULL, ppncc);
  1073. }
  1074. ReleaseObj (pncclasssetup);
  1075. }
  1076. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  1077. "HrInstallComponent (%S)", pszComponentId);
  1078. return hr;
  1079. }
  1080. //+---------------------------------------------------------------------------
  1081. //
  1082. // Function: HrInstallComponents
  1083. //
  1084. // Purpose: Install the components with the specified ids.
  1085. //
  1086. // Arguments:
  1087. // pnc [in] INetCfg pointer.
  1088. // pnip [in] (Optional) If specified, perform the installation
  1089. // using the answer file.
  1090. // cComponents [in] Count of components in the arrays.
  1091. // apguidClass [in] Array of class guids for the specified components.
  1092. // apszComponentId [in] Array of component ids to install.
  1093. // pOboToken [in] (Optional) If specified, perform the installation
  1094. // on behalf of this token.
  1095. //
  1096. // Returns: S_OK or an error code.
  1097. //
  1098. // Author: shaunco 4 Jan 1998
  1099. //
  1100. // Notes:
  1101. //
  1102. HRESULT
  1103. HrInstallComponents (
  1104. INetCfg* pnc,
  1105. const NETWORK_INSTALL_PARAMS* pnip,
  1106. ULONG cComponents,
  1107. const GUID** apguidClass,
  1108. const PCWSTR* apszComponentId,
  1109. OBO_TOKEN* pOboToken)
  1110. {
  1111. Assert (pnc);
  1112. Assert (cComponents);
  1113. Assert (apguidClass);
  1114. Assert (apszComponentId);
  1115. HRESULT hr = S_OK;
  1116. for (ULONG i = 0; (i < cComponents) && SUCCEEDED(hr); i++)
  1117. {
  1118. hr = HrInstallComponent (pnc, pnip,
  1119. apguidClass[i], apszComponentId[i], pOboToken, NULL);
  1120. }
  1121. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  1122. "HrInstallComponents");
  1123. return hr;
  1124. }
  1125. //+---------------------------------------------------------------------------
  1126. //
  1127. // Function: HrInstallComponentsOboComponent
  1128. //
  1129. // Purpose: Install multiple components on behalf of one component.
  1130. //
  1131. // Arguments:
  1132. // pnc [in] pointer to an INetCfg object.
  1133. // pnip [in] (Optional) pointer to network install parameters.
  1134. // If non-NULL, a network install is performed,
  1135. // otherwise a normal install is performed.
  1136. // cComponents [in] count of class guid pointers and component id
  1137. // pointers.
  1138. // apguidClass [in] array of class guid pointers.
  1139. // apszComponentId [in] array of component id pointers.
  1140. // pnccObo [in] the component requesting the install. (i.e. the
  1141. // "on behalf of" component.)
  1142. //
  1143. // Returns: S_OK or an error code.
  1144. //
  1145. // Author: shaunco 13 Apr 1997
  1146. //
  1147. // Notes:
  1148. //
  1149. HRESULT
  1150. HrInstallComponentsOboComponent (
  1151. INetCfg* pnc,
  1152. const NETWORK_INSTALL_PARAMS* pnip,
  1153. ULONG cComponents,
  1154. const GUID** apguidClass,
  1155. const PCWSTR* apszComponentId,
  1156. INetCfgComponent* pnccObo)
  1157. {
  1158. Assert (pnccObo);
  1159. // Make an "on behalf of" token for the requesting component.
  1160. //
  1161. OBO_TOKEN OboToken;
  1162. ZeroMemory (&OboToken, sizeof(OboToken));
  1163. OboToken.Type = OBO_COMPONENT;
  1164. OboToken.pncc = pnccObo;
  1165. HRESULT hr = HrInstallComponents (pnc, pnip, cComponents, apguidClass,
  1166. apszComponentId, &OboToken);
  1167. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  1168. "HrInstallComponentsOboComponent");
  1169. return hr;
  1170. }
  1171. //+---------------------------------------------------------------------------
  1172. //
  1173. // Function: HrInstallComponentsOboUser
  1174. //
  1175. // Purpose: Install multiple components on behalf of the user.
  1176. //
  1177. // Arguments:
  1178. // pnc [in] INetCfg pointer.
  1179. // pnip [in] (Optional) If specified, perform the installation
  1180. // using the answer file.
  1181. // cComponents [in] Count of components in the arrays.
  1182. // apguidClass [in] Array of class guids for the specified components.
  1183. // apszComponentId [in] Array of component ids to install.
  1184. //
  1185. // Returns:
  1186. //
  1187. // Author: shaunco 4 Jan 1998
  1188. //
  1189. // Notes:
  1190. //
  1191. HRESULT
  1192. HrInstallComponentsOboUser (
  1193. INetCfg* pnc,
  1194. const NETWORK_INSTALL_PARAMS* pnip,
  1195. ULONG cComponents,
  1196. const GUID** apguidClass,
  1197. const PCWSTR* apszComponentId)
  1198. {
  1199. // Make an "on behalf of" token for the user.
  1200. //
  1201. OBO_TOKEN OboToken;
  1202. ZeroMemory (&OboToken, sizeof(OboToken));
  1203. OboToken.Type = OBO_USER;
  1204. HRESULT hr = HrInstallComponents (pnc, pnip, cComponents, apguidClass,
  1205. apszComponentId, &OboToken);
  1206. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  1207. "HrInstallComponentsOboUser");
  1208. return hr;
  1209. }
  1210. //+---------------------------------------------------------------------------
  1211. //
  1212. // Function: HrInstallComponentOboComponent
  1213. //
  1214. // Purpose: Installs a component on behalf of another. If the component
  1215. // is already installed, it reference count is incremented on
  1216. // behalf of the component doing the install. When one
  1217. // component calls this function to install another, it is
  1218. // saying that it has a depencency on the component being
  1219. // installed. This dependency will prevent even the user from
  1220. // removing the component.
  1221. //
  1222. // Arguments:
  1223. // pnc [in] pointer to an INetCfg object.
  1224. // pnip [in] (Optional) pointer to network install parameters.
  1225. // If non-NULL, a network install is performed,
  1226. // otherwise a normal install is performed.
  1227. // rguid [in] class GUID of the component being installed.
  1228. // pszComponentId [in] component INF id of the component being installed.
  1229. // pnccObo [in] the component requesting the install. (i.e. the
  1230. // "on behalf of" component.)
  1231. // ppncc [out] (Optional) set on return to the previously
  1232. // installed component or the one that was installed.
  1233. //
  1234. // Returns: S_OK or an error.
  1235. //
  1236. // Author: shaunco 7 Apr 1997
  1237. //
  1238. // Notes:
  1239. //
  1240. HRESULT
  1241. HrInstallComponentOboComponent (
  1242. INetCfg* pnc,
  1243. const NETWORK_INSTALL_PARAMS* pnip,
  1244. const GUID& rguid,
  1245. PCWSTR pszComponentId,
  1246. INetCfgComponent* pnccObo,
  1247. INetCfgComponent** ppncc)
  1248. {
  1249. Assert (pnc);
  1250. Assert (pszComponentId);
  1251. Assert (pnccObo);
  1252. // Initialize output parameter.
  1253. //
  1254. if (ppncc)
  1255. {
  1256. *ppncc = NULL;
  1257. }
  1258. // Make an "on behalf of" token for the requesting component.
  1259. //
  1260. OBO_TOKEN OboToken;
  1261. ZeroMemory (&OboToken, sizeof(OboToken));
  1262. OboToken.Type = OBO_COMPONENT;
  1263. OboToken.pncc = pnccObo;
  1264. HRESULT hr = HrInstallComponent (pnc, pnip, &rguid, pszComponentId,
  1265. &OboToken, ppncc);
  1266. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  1267. "HrInstallComponentOboComponent");
  1268. return hr;
  1269. }
  1270. //+---------------------------------------------------------------------------
  1271. //
  1272. // Function: HrInstallComponentOboSoftware
  1273. //
  1274. // Purpose: Installs a component on behalf of a piece of software.
  1275. // If the component is already installed, it's reference count
  1276. // is incremented on behalf of the indicated software piece.
  1277. // This is useful for a component to call
  1278. // when it is installing another component as a convienience for
  1279. // the user. The user can then remove the component with no
  1280. // ill-effects for the component that called this function.
  1281. //
  1282. // Arguments:
  1283. // pnc [in] pointer to an INetCfg object.
  1284. // pnip [in] (Optional) pointer to network install parameters.
  1285. // If non-NULL, a network install is performed,
  1286. // otherwise a normal install is performed.
  1287. // rguid [in] class GUID of the component being installed.
  1288. // pszComponentId [in] component INF id of the component being installed.
  1289. // pszManufacturer [in] Manufacturer name of software.
  1290. // pszProduct [in] Product name of software.
  1291. // pszDisplayName [in] Full display name of software.
  1292. // ppncc [out] (Optional) set on return to the previously
  1293. // installed component or the one that was installed.
  1294. //
  1295. // Returns:
  1296. //
  1297. // Author: danielwe 5 May 1997
  1298. //
  1299. // Notes:
  1300. //
  1301. HRESULT
  1302. HrInstallComponentOboSoftware (
  1303. INetCfg* pnc,
  1304. const NETWORK_INSTALL_PARAMS* pnip,
  1305. const GUID& rguid,
  1306. PCWSTR pszComponentId,
  1307. PCWSTR pszManufacturer,
  1308. PCWSTR pszProduct,
  1309. PCWSTR pszDisplayName,
  1310. INetCfgComponent** ppncc)
  1311. {
  1312. Assert (pnc);
  1313. Assert (pszComponentId);
  1314. Assert (pszManufacturer);
  1315. Assert (pszDisplayName);
  1316. Assert (pszProduct);
  1317. AssertSz (GUID_DEVCLASS_NET != rguid, "Don't use this to install adapters.");
  1318. // Initialize output parameter.
  1319. //
  1320. if (ppncc)
  1321. {
  1322. *ppncc = NULL;
  1323. }
  1324. // Make an "on behalf of" token for the software.
  1325. //
  1326. OBO_TOKEN OboToken;
  1327. ZeroMemory (&OboToken, sizeof(OboToken));
  1328. OboToken.Type = OBO_SOFTWARE;
  1329. OboToken.pszwManufacturer = pszManufacturer;
  1330. OboToken.pszwProduct = pszProduct;
  1331. OboToken.pszwDisplayName = pszDisplayName;
  1332. HRESULT hr = HrInstallComponent (pnc, pnip, &rguid, pszComponentId,
  1333. &OboToken, ppncc);
  1334. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  1335. "HrInstallComponentOboSoftware");
  1336. return hr;
  1337. }
  1338. //+---------------------------------------------------------------------------
  1339. //
  1340. // Function: HrInstallComponentOboUser
  1341. //
  1342. // Purpose: Installs a component on behalf of the user. If the component
  1343. // is already installed, it reference count is incremented on
  1344. // behalf of the user. This is useful for a component to call
  1345. // when it is installing another component as a convienience for
  1346. // the user. The user can then remove the component with no
  1347. // ill-effects for the component that called this function.
  1348. //
  1349. // Arguments:
  1350. // pnc [in] pointer to an INetCfg object.
  1351. // pnip [in] (Optional) pointer to network install parameters.
  1352. // If non-NULL, a network install is performed,
  1353. // otherwise a normal install is performed.
  1354. // rguid [in] class GUID of the component being installed.
  1355. // pszComponentId [in] component INF id of the component being installed.
  1356. // ppncc [out] (Optional) set on return to the previously
  1357. // installed component or the one that was installed.
  1358. //
  1359. // Returns: S_OK or an error.
  1360. //
  1361. // Author: shaunco 7 Apr 1997
  1362. //
  1363. // Notes:
  1364. //
  1365. HRESULT
  1366. HrInstallComponentOboUser (
  1367. INetCfg* pnc,
  1368. const NETWORK_INSTALL_PARAMS* pnip,
  1369. const GUID& rguid,
  1370. PCWSTR pszComponentId,
  1371. INetCfgComponent** ppncc)
  1372. {
  1373. Assert (pnc);
  1374. Assert (&rguid);
  1375. Assert (pszComponentId);
  1376. AssertSz (GUID_DEVCLASS_NET != rguid, "Don't use this to install adapters.");
  1377. // Initialize output parameter.
  1378. //
  1379. if (ppncc)
  1380. {
  1381. *ppncc = NULL;
  1382. }
  1383. // Make an "on behalf of" token for the user.
  1384. //
  1385. OBO_TOKEN OboToken;
  1386. ZeroMemory (&OboToken, sizeof(OboToken));
  1387. OboToken.Type = OBO_USER;
  1388. HRESULT hr = HrInstallComponent (pnc, pnip, &rguid, pszComponentId,
  1389. &OboToken, ppncc);
  1390. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  1391. "HrInstallComponentOboUser");
  1392. return hr;
  1393. }
  1394. //+---------------------------------------------------------------------------
  1395. //
  1396. // Function: HrInstallRasIfNeeded
  1397. //
  1398. // Purpose: Install RAS services on behalf of the user. No need to
  1399. // check first as we install on behalf of the user which is
  1400. // implicilty checked.
  1401. //
  1402. // Arguments:
  1403. // pnc [in] INetCfg pointer to use
  1404. //
  1405. // Returns: S_OK or an error code.
  1406. //
  1407. // Author: shaunco 30 Aug 1997
  1408. //
  1409. // Notes:
  1410. // (shaunco) 10 Sep 1997: Don't install RAS Server for Beta1.
  1411. // DHCP addresses get eaten up too quickly. For Beta2, it will be
  1412. // installed but disabled.
  1413. //
  1414. // (shaunco) 20 Dec 1997: We used to install RAS Server only on NTS.
  1415. // We now install it always but its set to not start automatically.
  1416. //
  1417. HRESULT
  1418. HrInstallRasIfNeeded (
  1419. INetCfg* pnc)
  1420. {
  1421. Assert (pnc);
  1422. static const GUID* c_apguidInstalledComponentClasses [] =
  1423. {
  1424. &GUID_DEVCLASS_NETSERVICE, // RasCli
  1425. &GUID_DEVCLASS_NETSERVICE, // RasSrv
  1426. };
  1427. static const PCWSTR c_apszInstalledComponentIds [] =
  1428. {
  1429. c_szInfId_MS_RasCli,
  1430. c_szInfId_MS_RasSrv,
  1431. };
  1432. HRESULT hr = HrInstallComponentsOboUser (pnc, NULL,
  1433. celems (c_apguidInstalledComponentClasses),
  1434. c_apguidInstalledComponentClasses,
  1435. c_apszInstalledComponentIds);
  1436. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  1437. "HrInstallRasIfNeeded");
  1438. return hr;
  1439. }
  1440. //+---------------------------------------------------------------------------
  1441. //
  1442. // Function: HrQueryNotifyObject
  1443. //
  1444. // Purpose: Helper function to call QueryNotifyObject given an
  1445. // INetCfgComponent. (Saves the intermediate QI.)
  1446. //
  1447. // Arguments:
  1448. // pncc [in] INetCfgComponent to call QueryNotifyObject on.
  1449. // riid [in] Requested interface identifier.
  1450. // ppvObject [out] Address of pointer to return the requested interface.
  1451. //
  1452. // Returns: S_OK or an error code.
  1453. //
  1454. // Author: shaunco 2 Sep 1998
  1455. //
  1456. // Notes:
  1457. //
  1458. HRESULT
  1459. HrQueryNotifyObject (
  1460. INetCfgComponent* pncc,
  1461. REFIID riid,
  1462. VOID** ppvObject)
  1463. {
  1464. Assert (pncc);
  1465. Assert (ppvObject);
  1466. // Initialize the output parameter.
  1467. //
  1468. *ppvObject = NULL;
  1469. // First, QI for the component private interface.
  1470. //
  1471. INetCfgComponentPrivate* pPrivate;
  1472. HRESULT hr = pncc->QueryInterface(
  1473. IID_INetCfgComponentPrivate,
  1474. reinterpret_cast<VOID**>(&pPrivate));
  1475. if (SUCCEEDED(hr))
  1476. {
  1477. // Now query the notify object for the requested interface.
  1478. //
  1479. hr = pPrivate->QueryNotifyObject (riid, ppvObject);
  1480. ReleaseObj (pPrivate);
  1481. }
  1482. TraceHr (ttidError, FAL, hr, FALSE, "HrQueryNotifyObject");
  1483. return hr;
  1484. }
  1485. //+---------------------------------------------------------------------------
  1486. //
  1487. // Function: HrRemoveComponent
  1488. //
  1489. // Purpose: Remove the specified component.
  1490. //
  1491. // Arguments:
  1492. // pnc [in] INetCfg pointer.
  1493. // pnccToRemove [in] Component to remove.
  1494. // pOboToken [in] (Optional) If specified, remove the component
  1495. // on behalf of this token.
  1496. // pmszRefs [out] (Optional) Returns Multi-Sz of components that
  1497. // still reference this one. NOTE: This will be NULL
  1498. // if the return value is not
  1499. // NETCFG_S_STILL_REFERENCED
  1500. //
  1501. // Returns: S_OK, NETCFG_S_STILL_REFERENCED, or an error code.
  1502. //
  1503. // Author: shaunco 4 Jan 1998
  1504. //
  1505. // Notes:
  1506. //
  1507. HRESULT
  1508. HrRemoveComponent (
  1509. INetCfg* pnc,
  1510. INetCfgComponent* pnccToRemove,
  1511. OBO_TOKEN* pOboToken,
  1512. PWSTR * pmszRefs)
  1513. {
  1514. Assert (pnc);
  1515. Assert (pnccToRemove);
  1516. // Get the class setup interface for this component.
  1517. //
  1518. GUID guidClass;
  1519. HRESULT hr = pnccToRemove->GetClassGuid (&guidClass);
  1520. if (SUCCEEDED(hr))
  1521. {
  1522. // Use the class setup interface to remove the component.
  1523. //
  1524. INetCfgClassSetup* pSetup;
  1525. hr = pnc->QueryNetCfgClass (&guidClass,
  1526. IID_INetCfgClassSetup,
  1527. reinterpret_cast<void**>(&pSetup));
  1528. if (SUCCEEDED(hr))
  1529. {
  1530. hr = pSetup->DeInstall (pnccToRemove, pOboToken, pmszRefs);
  1531. ReleaseObj (pSetup);
  1532. }
  1533. }
  1534. TraceHr (ttidError, FAL, hr,
  1535. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  1536. "HrRemoveComponent");
  1537. return hr;
  1538. }
  1539. //+---------------------------------------------------------------------------
  1540. //
  1541. // Function: HrRemoveComponentOboComponent
  1542. //
  1543. // Purpose: Removes a component previously installed by another.
  1544. // Effectively balances a call to HrInstallComponentOboComponent().
  1545. // The reference count of the component is decremented and,
  1546. // if it is zero, the component is removed from the system.
  1547. //
  1548. // Arguments:
  1549. // pnc [in] pointer to an INetCfg object.
  1550. // rguidClass [in] class GUID of the component being removed.
  1551. // pszComponentId [in] component INF id of the component being removed.
  1552. // pnccObo [in] the component requesting the removal.
  1553. //
  1554. // Returns: S_OK, NETCFG_S_STILL_REFERENCED or an error.
  1555. //
  1556. // Author: shaunco 7 Apr 1997
  1557. //
  1558. // Notes:
  1559. //
  1560. HRESULT
  1561. HrRemoveComponentOboComponent (
  1562. INetCfg* pnc,
  1563. const GUID& rguidClass,
  1564. PCWSTR pszComponentId,
  1565. INetCfgComponent* pnccObo)
  1566. {
  1567. // Make an "on behalf of" token for the requesting component.
  1568. //
  1569. OBO_TOKEN OboToken;
  1570. ZeroMemory (&OboToken, sizeof(OboToken));
  1571. OboToken.Type = OBO_COMPONENT;
  1572. OboToken.pncc = pnccObo;
  1573. HRESULT hr = HrFindAndRemoveComponent (pnc, &rguidClass, pszComponentId,
  1574. &OboToken);
  1575. TraceHr (ttidError, FAL, hr,
  1576. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  1577. "HrRemoveComponentOboComponent");
  1578. return hr;
  1579. }
  1580. //+---------------------------------------------------------------------------
  1581. //
  1582. // Function: HrRemoveComponentOboSoftware
  1583. //
  1584. // Purpose: Removes a component previously installed by some software
  1585. // entity. Effectively balances a call to
  1586. // HrAddComponentOboSoftware(). The reference count of the
  1587. // component is decremented and, if it is zero, the component
  1588. // is removed from the system.
  1589. //
  1590. // Arguments:
  1591. // pnc [in] pointer to an INetCfg object.
  1592. // rguidClass [in] class GUID of the component being removed.
  1593. // pszComponentId [in] component INF id of the component being removed.
  1594. // pszManufacturer [in] Manufacturer name of software.
  1595. // pszProduct [in] Product name of software.
  1596. // pszDisplayName [in] Full display name of software.
  1597. // pnccObo [in] the component requesting the removal.
  1598. //
  1599. // Returns: S_OK, NETCFG_S_STILL_REFERENCED or an error.
  1600. //
  1601. // Author: jeffspr 13 Jun 1997
  1602. //
  1603. // Notes:
  1604. //
  1605. HRESULT
  1606. HrRemoveComponentOboSoftware (
  1607. INetCfg* pnc,
  1608. const GUID& rguidClass,
  1609. PCWSTR pszComponentId,
  1610. PCWSTR pszManufacturer,
  1611. PCWSTR pszProduct,
  1612. PCWSTR pszDisplayName)
  1613. {
  1614. // Make an "on behalf of" token for the software.
  1615. //
  1616. OBO_TOKEN OboToken;
  1617. ZeroMemory (&OboToken, sizeof(OboToken));
  1618. OboToken.Type = OBO_SOFTWARE;
  1619. OboToken.pszwManufacturer = pszManufacturer;
  1620. OboToken.pszwProduct = pszProduct;
  1621. OboToken.pszwDisplayName = pszDisplayName;
  1622. HRESULT hr = HrFindAndRemoveComponent (pnc, &rguidClass, pszComponentId,
  1623. &OboToken);
  1624. TraceHr (ttidError, FAL, hr,
  1625. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  1626. "HrRemoveComponentOboSoftware");
  1627. return hr;
  1628. }
  1629. //+---------------------------------------------------------------------------
  1630. //
  1631. // Function: HrRemoveComponentOboUser
  1632. //
  1633. // Purpose: Removes a component previously installed by the user.
  1634. // Effectively balances a call to HrAddComponentOboUser().
  1635. // The reference count of the component is decremented and,
  1636. // if it is zero, the component is removed from the system.
  1637. //
  1638. // Arguments:
  1639. // pnc [in] pointer to an INetCfg object.
  1640. // rguidClass [in] class GUID of the component being removed.
  1641. // pszComponentId [in] component INF id of the component being removed.
  1642. //
  1643. // Returns: S_OK, NETCFG_S_STILL_REFERENCED or an error.
  1644. //
  1645. // Author: shaunco 7 Apr 1997
  1646. //
  1647. // Notes:
  1648. //
  1649. HRESULT
  1650. HrRemoveComponentOboUser (
  1651. INetCfg* pnc,
  1652. const GUID& rguidClass,
  1653. PCWSTR pszComponentId)
  1654. {
  1655. // Make an "on behalf of" token for the user.
  1656. //
  1657. OBO_TOKEN OboToken;
  1658. ZeroMemory (&OboToken, sizeof(OboToken));
  1659. OboToken.Type = OBO_USER;
  1660. HRESULT hr = HrFindAndRemoveComponent (pnc, &rguidClass, pszComponentId,
  1661. &OboToken);
  1662. TraceHr (ttidError, FAL, hr,
  1663. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  1664. "HrRemoveComponentOboUser");
  1665. return hr;
  1666. }
  1667. //+---------------------------------------------------------------------------
  1668. //
  1669. // Function: HrGetLastComponentAndInterface
  1670. //
  1671. // Purpose: This function enumerates a binding path, returns the last
  1672. // component on the path and optionally return the last binding
  1673. // interface name in this path.
  1674. //
  1675. // Arguments:
  1676. // pncbp [in] The INetCfgBindingPath *
  1677. // ppncc [out] The INetCfgComponent * of the last component on the path
  1678. // ppszInterfaceName [out] The interface name of the last binding interface of the path
  1679. //
  1680. // Returns: S_OK, or an error.
  1681. //
  1682. // Author: tongl 5 Dec 1997
  1683. //
  1684. // Notes:
  1685. //
  1686. HRESULT
  1687. HrGetLastComponentAndInterface (
  1688. INetCfgBindingPath* pncbp,
  1689. INetCfgComponent** ppncc,
  1690. PWSTR* ppszInterfaceName)
  1691. {
  1692. Assert(pncbp);
  1693. // Initialize output parameters.
  1694. //
  1695. *ppncc = NULL;
  1696. if (ppszInterfaceName)
  1697. {
  1698. *ppszInterfaceName = NULL;
  1699. }
  1700. // Enumerate binding interfaces and keep track of
  1701. // the last interface.
  1702. //
  1703. HRESULT hr = S_OK;
  1704. CIterNetCfgBindingInterface ncbiIter(pncbp);
  1705. INetCfgBindingInterface* pncbi;
  1706. INetCfgBindingInterface* pncbiLast = NULL;
  1707. while(SUCCEEDED(hr) && (hr = ncbiIter.HrNext(&pncbi)) == S_OK)
  1708. {
  1709. ReleaseObj (pncbiLast);
  1710. pncbiLast = pncbi;
  1711. }
  1712. if (S_FALSE == hr) // we got to the end of the loop
  1713. {
  1714. hr = S_OK;
  1715. Assert (pncbiLast);
  1716. INetCfgComponent* pnccLowerComponent;
  1717. hr = pncbiLast->GetLowerComponent(&pnccLowerComponent);
  1718. if (S_OK == hr)
  1719. {
  1720. // Get the name of the interface if requested.
  1721. //
  1722. if (ppszInterfaceName)
  1723. {
  1724. hr = pncbiLast->GetName(ppszInterfaceName);
  1725. }
  1726. // If we've succeded everything, (including the optional
  1727. // return of the interface name above) then assign and addref
  1728. // the output interface.
  1729. //
  1730. if (S_OK == hr)
  1731. {
  1732. AddRefObj (pnccLowerComponent);
  1733. *ppncc = pnccLowerComponent;
  1734. }
  1735. // Important to release our use of this interface in case
  1736. // we failed and didn't assign it as an output parameter.
  1737. //
  1738. ReleaseObj (pnccLowerComponent);
  1739. }
  1740. }
  1741. // Don't forget to release the binding interface itself.
  1742. //
  1743. ReleaseObj (pncbiLast);
  1744. TraceHr (ttidError, FAL, hr, FALSE, "HrGetLastComponentAndInterface");
  1745. return hr;
  1746. }