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.

763 lines
18 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: N E T C F G A P I . C P P
  7. //
  8. // Contents: Functions to illustrate INetCfg API
  9. //
  10. // Notes:
  11. //
  12. // Author: Alok Sinha 15-May-01
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "NetCfgAPI.h"
  16. //
  17. // Function: HrGetINetCfg
  18. //
  19. // Purpose: Get a reference to INetCfg.
  20. //
  21. // Arguments:
  22. // fGetWriteLock [in] If TRUE, Write lock.requested.
  23. // lpszAppName [in] Application name requesting the reference.
  24. // ppnc [out] Reference to INetCfg.
  25. // lpszLockedBy [in] Optional. Application who holds the write lock.
  26. //
  27. // Returns: S_OK on sucess, otherwise an error code.
  28. //
  29. // Notes:
  30. //
  31. HRESULT HrGetINetCfg (IN BOOL fGetWriteLock,
  32. IN LPCWSTR lpszAppName,
  33. OUT INetCfg** ppnc,
  34. OUT LPWSTR *lpszLockedBy)
  35. {
  36. INetCfg *pnc = NULL;
  37. INetCfgLock *pncLock = NULL;
  38. HRESULT hr = S_OK;
  39. //
  40. // Initialize the output parameters.
  41. //
  42. *ppnc = NULL;
  43. if ( lpszLockedBy )
  44. {
  45. *lpszLockedBy = NULL;
  46. }
  47. //
  48. // Initialize COM
  49. //
  50. hr = CoInitialize( NULL );
  51. if ( hr == S_OK ) {
  52. //
  53. // Create the object implementing INetCfg.
  54. //
  55. hr = CoCreateInstance( CLSID_CNetCfg,
  56. NULL, CLSCTX_INPROC_SERVER,
  57. IID_INetCfg,
  58. (void**)&pnc );
  59. if ( hr == S_OK ) {
  60. if ( fGetWriteLock ) {
  61. //
  62. // Get the locking reference
  63. //
  64. hr = pnc->QueryInterface( IID_INetCfgLock,
  65. (LPVOID *)&pncLock );
  66. if ( hr == S_OK ) {
  67. //
  68. // Attempt to lock the INetCfg for read/write
  69. //
  70. hr = pncLock->AcquireWriteLock( LOCK_TIME_OUT,
  71. lpszAppName,
  72. lpszLockedBy);
  73. if (hr == S_FALSE ) {
  74. hr = NETCFG_E_NO_WRITE_LOCK;
  75. }
  76. }
  77. }
  78. if ( hr == S_OK ) {
  79. //
  80. // Initialize the INetCfg object.
  81. //
  82. hr = pnc->Initialize( NULL );
  83. if ( hr == S_OK ) {
  84. *ppnc = pnc;
  85. pnc->AddRef();
  86. }
  87. else {
  88. //
  89. // Initialize failed, if obtained lock, release it
  90. //
  91. if ( pncLock ) {
  92. pncLock->ReleaseWriteLock();
  93. }
  94. }
  95. }
  96. ReleaseRef( pncLock );
  97. ReleaseRef( pnc );
  98. }
  99. //
  100. // In case of error, uninitialize COM.
  101. //
  102. if ( hr != S_OK ) {
  103. CoUninitialize();
  104. }
  105. }
  106. return hr;
  107. }
  108. //
  109. // Function: HrReleaseINetCfg
  110. //
  111. // Purpose: Get a reference to INetCfg.
  112. //
  113. // Arguments:
  114. // pnc [in] Reference to INetCfg to release.
  115. // fHasWriteLock [in] If TRUE, reference was held with write lock.
  116. //
  117. // Returns: S_OK on sucess, otherwise an error code.
  118. //
  119. // Notes:
  120. //
  121. HRESULT HrReleaseINetCfg (IN INetCfg* pnc,
  122. IN BOOL fHasWriteLock)
  123. {
  124. INetCfgLock *pncLock = NULL;
  125. HRESULT hr = S_OK;
  126. //
  127. // Uninitialize INetCfg
  128. //
  129. hr = pnc->Uninitialize();
  130. //
  131. // If write lock is present, unlock it
  132. //
  133. if ( hr == S_OK && fHasWriteLock ) {
  134. //
  135. // Get the locking reference
  136. //
  137. hr = pnc->QueryInterface( IID_INetCfgLock,
  138. (LPVOID *)&pncLock);
  139. if ( hr == S_OK ) {
  140. hr = pncLock->ReleaseWriteLock();
  141. ReleaseRef( pncLock );
  142. }
  143. }
  144. ReleaseRef( pnc );
  145. //
  146. // Uninitialize COM.
  147. //
  148. CoUninitialize();
  149. return hr;
  150. }
  151. //
  152. // Function: HrInstallNetComponent
  153. //
  154. // Purpose: Install a network component(protocols, clients and services)
  155. // given its INF file.
  156. //
  157. // Arguments:
  158. // pnc [in] Reference to INetCfg.
  159. // lpszComponentId [in] PnpID of the network component.
  160. // pguidClass [in] Class GUID of the network component.
  161. // lpszInfFullPath [in] INF file to install from.
  162. //
  163. // Returns: S_OK on sucess, otherwise an error code.
  164. //
  165. // Notes:
  166. //
  167. HRESULT HrInstallNetComponent (IN INetCfg *pnc,
  168. IN LPCWSTR lpszComponentId,
  169. IN const GUID *pguidClass,
  170. IN LPCWSTR lpszInfFullPath)
  171. {
  172. DWORD dwError;
  173. HRESULT hr = S_OK;
  174. WCHAR Drive[_MAX_DRIVE];
  175. WCHAR Dir[_MAX_DIR];
  176. WCHAR DirWithDrive[_MAX_DRIVE+_MAX_DIR];
  177. //
  178. // If full path to INF has been specified, the INF
  179. // needs to be copied using Setup API to ensure that any other files
  180. // that the primary INF copies will be correctly found by Setup API
  181. //
  182. if ( lpszInfFullPath ) {
  183. //
  184. // Get the path where the INF file is.
  185. //
  186. _wsplitpath( lpszInfFullPath, Drive, Dir, NULL, NULL );
  187. wcscpy( DirWithDrive, Drive );
  188. wcscat( DirWithDrive, Dir );
  189. //
  190. // Copy the INF file and other files referenced in the INF file.
  191. //
  192. if ( !SetupCopyOEMInfW(lpszInfFullPath,
  193. DirWithDrive, // Other files are in the
  194. // same dir. as primary INF
  195. SPOST_PATH, // First param is path to INF
  196. 0, // Default copy style
  197. NULL, // Name of the INF after
  198. // it's copied to %windir%\inf
  199. 0, // Max buf. size for the above
  200. NULL, // Required size if non-null
  201. NULL) ) { // Optionally get the filename
  202. // part of Inf name after it is copied.
  203. dwError = GetLastError();
  204. hr = HRESULT_FROM_WIN32( dwError );
  205. }
  206. }
  207. if ( S_OK == hr ) {
  208. //
  209. // Install the network component.
  210. //
  211. hr = HrInstallComponent( pnc,
  212. lpszComponentId,
  213. pguidClass );
  214. if ( hr == S_OK ) {
  215. //
  216. // On success, apply the changes
  217. //
  218. hr = pnc->Apply();
  219. }
  220. }
  221. return hr;
  222. }
  223. //
  224. // Function: HrInstallComponent
  225. //
  226. // Purpose: Install a network component(protocols, clients and services)
  227. // given its INF file.
  228. // Arguments:
  229. // pnc [in] Reference to INetCfg.
  230. // lpszComponentId [in] PnpID of the network component.
  231. // pguidClass [in] Class GUID of the network component.
  232. //
  233. // Returns: S_OK on sucess, otherwise an error code.
  234. //
  235. // Notes:
  236. //
  237. HRESULT HrInstallComponent(IN INetCfg* pnc,
  238. IN LPCWSTR szComponentId,
  239. IN const GUID* pguidClass)
  240. {
  241. INetCfgClassSetup *pncClassSetup = NULL;
  242. INetCfgComponent *pncc = NULL;
  243. OBO_TOKEN OboToken;
  244. HRESULT hr = S_OK;
  245. //
  246. // OBO_TOKEN specifies on whose behalf this
  247. // component is being installed.
  248. // Set it to OBO_USER so that szComponentId will be installed
  249. // on behalf of the user.
  250. //
  251. ZeroMemory( &OboToken,
  252. sizeof(OboToken) );
  253. OboToken.Type = OBO_USER;
  254. //
  255. // Get component's setup class reference.
  256. //
  257. hr = pnc->QueryNetCfgClass ( pguidClass,
  258. IID_INetCfgClassSetup,
  259. (void**)&pncClassSetup );
  260. if ( hr == S_OK ) {
  261. hr = pncClassSetup->Install( szComponentId,
  262. &OboToken,
  263. 0,
  264. 0, // Upgrade from build number.
  265. NULL, // Answerfile name
  266. NULL, // Answerfile section name
  267. &pncc ); // Reference after the component
  268. if ( S_OK == hr ) { // is installed.
  269. //
  270. // we don't need to use pncc (INetCfgComponent), release it
  271. //
  272. ReleaseRef( pncc );
  273. }
  274. ReleaseRef( pncClassSetup );
  275. }
  276. return hr;
  277. }
  278. //
  279. // Function: HrUninstallNetComponent
  280. //
  281. // Purpose: Uninstall a network component(protocols, clients and services).
  282. //
  283. // Arguments:
  284. // pnc [in] Reference to INetCfg.
  285. // szComponentId [in] PnpID of the network component to uninstall.
  286. //
  287. // Returns: S_OK on sucess, otherwise an error code.
  288. //
  289. // Notes:
  290. //
  291. HRESULT HrUninstallNetComponent(IN INetCfg* pnc,
  292. IN LPCWSTR szComponentId)
  293. {
  294. INetCfgComponent *pncc = NULL;
  295. INetCfgClass *pncClass = NULL;
  296. INetCfgClassSetup *pncClassSetup = NULL;
  297. OBO_TOKEN OboToken;
  298. GUID guidClass;
  299. HRESULT hr = S_OK;
  300. //
  301. // OBO_TOKEN specifies on whose behalf this
  302. // component is being installed.
  303. // Set it to OBO_USER so that szComponentId will be installed
  304. // on behalf of the user.
  305. //
  306. ZeroMemory( &OboToken,
  307. sizeof(OboToken) );
  308. OboToken.Type = OBO_USER;
  309. //
  310. // Get the component's reference.
  311. //
  312. hr = pnc->FindComponent( szComponentId,
  313. &pncc );
  314. if (S_OK == hr) {
  315. //
  316. // Get the component's class GUID.
  317. //
  318. hr = pncc->GetClassGuid( &guidClass );
  319. if ( hr == S_OK ) {
  320. //
  321. // Get component's class reference.
  322. //
  323. hr = pnc->QueryNetCfgClass( &guidClass,
  324. IID_INetCfgClass,
  325. (void**)&pncClass );
  326. if ( hr == S_OK ) {
  327. //
  328. // Get Setup reference.
  329. //
  330. hr = pncClass->QueryInterface( IID_INetCfgClassSetup,
  331. (void**)&pncClassSetup );
  332. if ( hr == S_OK ) {
  333. hr = pncClassSetup->DeInstall( pncc,
  334. &OboToken,
  335. NULL);
  336. if ( hr == S_OK ) {
  337. //
  338. // Apply the changes
  339. //
  340. hr = pnc->Apply();
  341. }
  342. ReleaseRef( pncClassSetup );
  343. }
  344. ReleaseRef( pncClass );
  345. }
  346. }
  347. ReleaseRef( pncc );
  348. }
  349. return hr;
  350. }
  351. //
  352. // Function: HrGetComponentEnum
  353. //
  354. // Purpose: Get network component enumerator reference.
  355. //
  356. // Arguments:
  357. // pnc [in] Reference to INetCfg.
  358. // pguidClass [in] Class GUID of the network component.
  359. // ppencc [out] Enumerator reference.
  360. //
  361. // Returns: S_OK on sucess, otherwise an error code.
  362. //
  363. // Notes:
  364. //
  365. HRESULT HrGetComponentEnum (INetCfg* pnc,
  366. IN const GUID* pguidClass,
  367. OUT IEnumNetCfgComponent **ppencc)
  368. {
  369. INetCfgClass *pncclass;
  370. HRESULT hr;
  371. *ppencc = NULL;
  372. //
  373. // Get the class reference.
  374. //
  375. hr = pnc->QueryNetCfgClass( pguidClass,
  376. IID_INetCfgClass,
  377. (PVOID *)&pncclass );
  378. if ( hr == S_OK ) {
  379. //
  380. // Get the enumerator reference.
  381. //
  382. hr = pncclass->EnumComponents( ppencc );
  383. //
  384. // We don't need the class reference any more.
  385. //
  386. ReleaseRef( pncclass );
  387. }
  388. return hr;
  389. }
  390. //
  391. // Function: HrGetFirstComponent
  392. //
  393. // Purpose: Enumerates the first network component.
  394. //
  395. // Arguments:
  396. // pencc [in] Component enumerator reference.
  397. // ppncc [out] Network component reference.
  398. //
  399. // Returns: S_OK on sucess, otherwise an error code.
  400. //
  401. // Notes:
  402. //
  403. HRESULT HrGetFirstComponent (IN IEnumNetCfgComponent* pencc,
  404. OUT INetCfgComponent **ppncc)
  405. {
  406. HRESULT hr;
  407. ULONG ulCount;
  408. *ppncc = NULL;
  409. pencc->Reset();
  410. hr = pencc->Next( 1,
  411. ppncc,
  412. &ulCount );
  413. return hr;
  414. }
  415. //
  416. // Function: HrGetNextComponent
  417. //
  418. // Purpose: Enumerate the next network component.
  419. //
  420. // Arguments:
  421. // pencc [in] Component enumerator reference.
  422. // ppncc [out] Network component reference.
  423. //
  424. // Returns: S_OK on sucess, otherwise an error code.
  425. //
  426. // Notes: The function behaves just like HrGetFirstComponent if
  427. // it is called right after HrGetComponentEnum.
  428. //
  429. //
  430. HRESULT HrGetNextComponent (IN IEnumNetCfgComponent* pencc,
  431. OUT INetCfgComponent **ppncc)
  432. {
  433. HRESULT hr;
  434. ULONG ulCount;
  435. *ppncc = NULL;
  436. hr = pencc->Next( 1,
  437. ppncc,
  438. &ulCount );
  439. return hr;
  440. }
  441. //
  442. // Function: HrGetBindingPathEnum
  443. //
  444. // Purpose: Get network component's binding path enumerator reference.
  445. //
  446. // Arguments:
  447. // pncc [in] Network component reference.
  448. // dwBindingType [in] EBP_ABOVE or EBP_BELOW.
  449. // ppencbp [out] Enumerator reference.
  450. //
  451. // Returns: S_OK on sucess, otherwise an error code.
  452. //
  453. // Notes:
  454. //
  455. HRESULT HrGetBindingPathEnum (IN INetCfgComponent *pncc,
  456. IN DWORD dwBindingType,
  457. OUT IEnumNetCfgBindingPath **ppencbp)
  458. {
  459. INetCfgComponentBindings *pnccb = NULL;
  460. HRESULT hr;
  461. *ppencbp = NULL;
  462. //
  463. // Get component's binding.
  464. //
  465. hr = pncc->QueryInterface( IID_INetCfgComponentBindings,
  466. (PVOID *)&pnccb );
  467. if ( hr == S_OK ) {
  468. //
  469. // Get binding path enumerator reference.
  470. //
  471. hr = pnccb->EnumBindingPaths( dwBindingType,
  472. ppencbp );
  473. ReleaseRef( pnccb );
  474. }
  475. return hr;
  476. }
  477. //
  478. // Function: HrGetFirstBindingPath
  479. //
  480. // Purpose: Enumerates the first binding path.
  481. //
  482. // Arguments:
  483. // pencc [in] Binding path enumerator reference.
  484. // ppncc [out] Binding path reference.
  485. //
  486. // Returns: S_OK on sucess, otherwise an error code.
  487. //
  488. // Notes:
  489. //
  490. HRESULT HrGetFirstBindingPath (IN IEnumNetCfgBindingPath *pencbp,
  491. OUT INetCfgBindingPath **ppncbp)
  492. {
  493. ULONG ulCount;
  494. HRESULT hr;
  495. *ppncbp = NULL;
  496. pencbp->Reset();
  497. hr = pencbp->Next( 1,
  498. ppncbp,
  499. &ulCount );
  500. return hr;
  501. }
  502. //
  503. // Function: HrGetNextBindingPath
  504. //
  505. // Purpose: Enumerate the next binding path.
  506. //
  507. // Arguments:
  508. // pencbp [in] Binding path enumerator reference.
  509. // ppncbp [out] Binding path reference.
  510. //
  511. // Returns: S_OK on sucess, otherwise an error code.
  512. //
  513. // Notes: The function behaves just like HrGetFirstBindingPath if
  514. // it is called right after HrGetBindingPathEnum.
  515. //
  516. //
  517. HRESULT HrGetNextBindingPath (IN IEnumNetCfgBindingPath *pencbp,
  518. OUT INetCfgBindingPath **ppncbp)
  519. {
  520. ULONG ulCount;
  521. HRESULT hr;
  522. *ppncbp = NULL;
  523. hr = pencbp->Next( 1,
  524. ppncbp,
  525. &ulCount );
  526. return hr;
  527. }
  528. //
  529. // Function: HrGetBindingInterfaceEnum
  530. //
  531. // Purpose: Get binding interface enumerator reference.
  532. //
  533. // Arguments:
  534. // pncbp [in] Binding path reference.
  535. // ppencbp [out] Enumerator reference.
  536. //
  537. // Returns: S_OK on sucess, otherwise an error code.
  538. //
  539. // Notes:
  540. //
  541. HRESULT HrGetBindingInterfaceEnum (IN INetCfgBindingPath *pncbp,
  542. OUT IEnumNetCfgBindingInterface **ppencbi)
  543. {
  544. HRESULT hr;
  545. *ppencbi = NULL;
  546. hr = pncbp->EnumBindingInterfaces( ppencbi );
  547. return hr;
  548. }
  549. //
  550. // Function: HrGetFirstBindingInterface
  551. //
  552. // Purpose: Enumerates the first binding interface.
  553. //
  554. // Arguments:
  555. // pencbi [in] Binding interface enumerator reference.
  556. // ppncbi [out] Binding interface reference.
  557. //
  558. // Returns: S_OK on sucess, otherwise an error code.
  559. //
  560. // Notes:
  561. //
  562. HRESULT HrGetFirstBindingInterface (IN IEnumNetCfgBindingInterface *pencbi,
  563. OUT INetCfgBindingInterface **ppncbi)
  564. {
  565. ULONG ulCount;
  566. HRESULT hr;
  567. *ppncbi = NULL;
  568. pencbi->Reset();
  569. hr = pencbi->Next( 1,
  570. ppncbi,
  571. &ulCount );
  572. return hr;
  573. }
  574. //
  575. // Function: HrGetNextBindingInterface
  576. //
  577. // Purpose: Enumerate the next binding interface.
  578. //
  579. // Arguments:
  580. // pencbi [in] Binding interface enumerator reference.
  581. // ppncbi [out] Binding interface reference.
  582. //
  583. // Returns: S_OK on sucess, otherwise an error code.
  584. //
  585. // Notes: The function behaves just like HrGetFirstBindingInterface if
  586. // it is called right after HrGetBindingInterfaceEnum.
  587. //
  588. //
  589. HRESULT HrGetNextBindingInterface (IN IEnumNetCfgBindingInterface *pencbi,
  590. OUT INetCfgBindingInterface **ppncbi)
  591. {
  592. ULONG ulCount;
  593. HRESULT hr;
  594. *ppncbi = NULL;
  595. hr = pencbi->Next( 1,
  596. ppncbi,
  597. &ulCount );
  598. return hr;
  599. }
  600. //
  601. // Function: ReleaseRef
  602. //
  603. // Purpose: Release reference.
  604. //
  605. // Arguments:
  606. // punk [in] IUnknown reference to release.
  607. //
  608. // Returns: Reference count.
  609. //
  610. // Notes:
  611. //
  612. VOID ReleaseRef (IN IUnknown* punk)
  613. {
  614. if ( punk ) {
  615. punk->Release();
  616. }
  617. return;
  618. }