Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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