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.

851 lines
23 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: C O M P O N E N T . C P P
  7. //
  8. // Contents: Functions to illustrate
  9. // o How to enumerate network components.
  10. // o How to install protocols, clients and services.
  11. // o How to uninstall protocols, clients and services.
  12. // o How to bind/unbind network components.
  13. //
  14. // Notes:
  15. //
  16. // Author: Alok Sinha 15-May-01
  17. //
  18. //----------------------------------------------------------------------------
  19. #include "bindview.h"
  20. //
  21. // Function: HandleComponentOperation
  22. //
  23. // Purpose: Do component specific functions.
  24. //
  25. // Arguments:
  26. // hwndOwner [in] Owner window.
  27. // ulSelection [in] Option selected.
  28. // hItem [in] Item selected.
  29. // lParam [in] lParam of the item.
  30. //
  31. // Returns: None.
  32. //
  33. // Notes:
  34. //
  35. VOID HandleComponentOperation (HWND hwndOwner,
  36. ULONG ulSelection,
  37. HTREEITEM hItem,
  38. LPARAM lParam)
  39. {
  40. switch( ulSelection ) {
  41. case IDI_BIND_TO:
  42. case IDI_UNBIND_FROM:
  43. //
  44. // Bind/unbind components.
  45. //
  46. BindUnbindComponents( hwndOwner,
  47. hItem,
  48. (LPWSTR)lParam,
  49. ulSelection == IDI_BIND_TO );
  50. }
  51. return;
  52. }
  53. //
  54. // Function: BindUnbindComponents
  55. //
  56. // Purpose: Bind/unbind a network component.
  57. //
  58. // Arguments:
  59. // hwndOwner [in] Owner window.
  60. // hItem [in] Item handle of the network component.
  61. // lpszInfId [in] PnpID of the network component.
  62. // fBindTo [in] if TRUE, bind, otherwise unbind.
  63. //
  64. // Returns: None.
  65. //
  66. // Notes:
  67. //
  68. VOID BindUnbindComponents( HWND hwndOwner,
  69. HTREEITEM hItem,
  70. LPWSTR lpszInfId,
  71. BOOL fBindTo)
  72. {
  73. BIND_UNBIND_INFO BindUnbind;
  74. BindUnbind.lpszInfId = lpszInfId;
  75. BindUnbind.fBindTo = fBindTo;
  76. DialogBoxParam( hInstance,
  77. MAKEINTRESOURCE(IDD_BIND_UNBIND),
  78. hwndOwner,
  79. BindComponentDlg,
  80. (LPARAM)&BindUnbind );
  81. return;
  82. }
  83. //
  84. // Function: InstallComponent
  85. //
  86. // Purpose: Install a network component.
  87. //
  88. // Arguments:
  89. // hwndDlg [in] Owner window.
  90. // pguidClass [in] Class GUID of type of network component to install.
  91. //
  92. // Returns: S_OK on success, otherwise and error code.
  93. //
  94. // Notes:
  95. //
  96. HRESULT InstallComponent (HWND hwndDlg,
  97. const GUID *pguidClass)
  98. {
  99. INetCfg *pnc;
  100. INetCfgClass *pncClass;
  101. INetCfgClassSetup *pncClassSetup;
  102. LPWSTR lpszApp;
  103. OBO_TOKEN obo;
  104. HRESULT hr;
  105. //
  106. // Get INetCfg reference.
  107. //
  108. hr = HrGetINetCfg( TRUE,
  109. APP_NAME,
  110. &pnc,
  111. &lpszApp );
  112. if ( hr == S_OK ) {
  113. //
  114. // Get network component's class reference.
  115. //
  116. hr = pnc->QueryNetCfgClass( pguidClass,
  117. IID_INetCfgClass,
  118. (PVOID *)&pncClass );
  119. if ( hr == S_OK ) {
  120. //
  121. // Get Setup class reference.
  122. //
  123. hr = pncClass->QueryInterface( IID_INetCfgClassSetup,
  124. (LPVOID *)&pncClassSetup );
  125. if ( hr == S_OK ) {
  126. ZeroMemory( &obo,
  127. sizeof(OBO_TOKEN) );
  128. obo.Type = OBO_USER;
  129. //
  130. // Let the network class installer prompt the user to select
  131. // a network component to install.
  132. //
  133. hr = pncClassSetup->SelectAndInstall( hwndDlg,
  134. &obo,
  135. NULL );
  136. if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) {
  137. hr = pnc->Apply();
  138. }
  139. else {
  140. if ( hr != HRESULT_FROM_WIN32(ERROR_CANCELLED) ) {
  141. ErrMsg( hr,
  142. L"Couldn't install the network component." );
  143. }
  144. }
  145. ReleaseRef( pncClassSetup );
  146. }
  147. else {
  148. ErrMsg( hr,
  149. L"Couldn't get an interface to setup class." );
  150. }
  151. ReleaseRef( pncClass );
  152. }
  153. else {
  154. ErrMsg( hr,
  155. L"Couldn't get a pointer to class interface." );
  156. }
  157. HrReleaseINetCfg( pnc,
  158. TRUE );
  159. }
  160. else {
  161. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  162. ErrMsg( hr,
  163. L"%s currently holds the lock, try later.",
  164. lpszApp );
  165. CoTaskMemFree( lpszApp );
  166. }
  167. else {
  168. ErrMsg( hr,
  169. L"Couldn't the get notify object interface." );
  170. }
  171. }
  172. return hr;
  173. }
  174. //
  175. // Function: InstallSpecifiedComponent
  176. //
  177. // Purpose: Install a network component from an INF file.
  178. //
  179. // Arguments:
  180. // lpszInfFile [in] INF file.
  181. // lpszPnpID [in] PnpID of the network component to install.
  182. // pguidClass [in] Class GUID of the network component.
  183. //
  184. // Returns: None.
  185. //
  186. // Notes:
  187. //
  188. HRESULT InstallSpecifiedComponent (LPWSTR lpszInfFile,
  189. LPWSTR lpszPnpID,
  190. const GUID *pguidClass)
  191. {
  192. INetCfg *pnc;
  193. LPWSTR lpszApp;
  194. HRESULT hr;
  195. hr = HrGetINetCfg( TRUE,
  196. APP_NAME,
  197. &pnc,
  198. &lpszApp );
  199. if ( hr == S_OK ) {
  200. //
  201. // Install the network component.
  202. //
  203. hr = HrInstallNetComponent( pnc,
  204. lpszPnpID,
  205. pguidClass,
  206. lpszInfFile );
  207. if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) {
  208. hr = pnc->Apply();
  209. }
  210. else {
  211. if ( hr != HRESULT_FROM_WIN32(ERROR_CANCELLED) ) {
  212. ErrMsg( hr,
  213. L"Couldn't install the network component." );
  214. }
  215. }
  216. HrReleaseINetCfg( pnc,
  217. TRUE );
  218. }
  219. else {
  220. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  221. ErrMsg( hr,
  222. L"%s currently holds the lock, try later.",
  223. lpszApp );
  224. CoTaskMemFree( lpszApp );
  225. }
  226. else {
  227. ErrMsg( hr,
  228. L"Couldn't the get notify object interface." );
  229. }
  230. }
  231. return hr;
  232. }
  233. //
  234. // Function: ListCompToBindUnbind
  235. //
  236. // Purpose: List all the components that are bound or bindable.
  237. //
  238. // Arguments:
  239. // lpszInfId [in] PnpID of the network component.
  240. // uiType [in] Type of network component.
  241. // hwndTree [in] Tree handle in which to list.
  242. // fBound [in] if TRUE, list components that are bound.
  243. //
  244. // Returns: Number of components listed.
  245. //
  246. // Notes:
  247. //
  248. DWORD ListCompToBindUnbind (LPWSTR lpszInfId,
  249. UINT uiType,
  250. HWND hwndTree,
  251. BOOL fBound)
  252. {
  253. INetCfg *pnc;
  254. INetCfgComponent *pncc;
  255. IEnumNetCfgComponent *pencc;
  256. INetCfgComponentBindings *pnccb;
  257. INetCfgComponent *pnccToBindUnbind;
  258. LPWSTR lpszApp;
  259. DWORD dwCount;
  260. HRESULT hr;
  261. dwCount = 0;
  262. hr = HrGetINetCfg( TRUE,
  263. APP_NAME,
  264. &pnc,
  265. &lpszApp );
  266. if ( hr == S_OK ) {
  267. //
  268. // Get a reference to the network component selected.
  269. //
  270. hr = pnc->FindComponent( lpszInfId,
  271. &pncc );
  272. if ( hr == S_OK ) {
  273. //
  274. // Get Component Enumerator Interface.
  275. //
  276. hr = HrGetComponentEnum( pnc,
  277. pguidNetClass[uiType],
  278. &pencc );
  279. if ( hr == S_OK ) {
  280. hr = pncc->QueryInterface( IID_INetCfgComponentBindings,
  281. (PVOID *)&pnccb );
  282. if ( hr == S_OK ) {
  283. hr = HrGetFirstComponent( pencc, &pnccToBindUnbind );
  284. while( hr == S_OK ) {
  285. hr = pnccb->IsBoundTo( pnccToBindUnbind );
  286. //
  287. // fBound = TRUE ==> Want to list components that are
  288. // bound.
  289. //
  290. if ( fBound ) {
  291. if ( hr == S_OK ) {
  292. AddToTree( hwndTree,
  293. TVI_ROOT,
  294. pnccToBindUnbind );
  295. dwCount++;
  296. }
  297. }
  298. else {
  299. //
  300. // fBound = FALSE ==> Want to list components that
  301. // are not bound but are bindable.
  302. //
  303. if ( hr == S_FALSE ) {
  304. hr = pnccb->IsBindableTo( pnccToBindUnbind );
  305. if ( hr == S_OK ) {
  306. AddToTree( hwndTree,
  307. TVI_ROOT,
  308. pnccToBindUnbind );
  309. dwCount++;
  310. }
  311. }
  312. }
  313. ReleaseRef( pnccToBindUnbind );
  314. hr = HrGetNextComponent( pencc, &pnccToBindUnbind );
  315. }
  316. ReleaseRef( pnccb );
  317. }
  318. else {
  319. ErrMsg( hr,
  320. L"Couldn't get the component binding interface "
  321. L"of %s.",
  322. lpszInfId );
  323. }
  324. ReleaseRef( pencc );
  325. }
  326. else {
  327. ErrMsg( hr,
  328. L"Couldn't get the network component enumerator "
  329. L"interface." );
  330. }
  331. ReleaseRef( pncc );
  332. }
  333. else {
  334. ErrMsg( hr,
  335. L"Couldn't get an interface pointer to %s.",
  336. lpszInfId );
  337. }
  338. HrReleaseINetCfg( pnc,
  339. TRUE );
  340. }
  341. else {
  342. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  343. ErrMsg( hr,
  344. L"%s currently holds the lock, try later.",
  345. lpszApp );
  346. CoTaskMemFree( lpszApp );
  347. }
  348. else {
  349. ErrMsg( hr,
  350. L"Couldn't get the notify object interface." );
  351. }
  352. }
  353. return dwCount;
  354. }
  355. //
  356. // Function: BindUnbind
  357. //
  358. // Purpose: Bind/unbind a network component.
  359. //
  360. // Arguments:
  361. // lpszInfId [in] PnpID of the network component to bind/unbind.
  362. // hwndTree [in] Tree handle.
  363. // fBind [in] if TRUE, bind, otherwise unbind.
  364. //
  365. // Returns: TRUE on success.
  366. //
  367. // Notes:
  368. //
  369. BOOL BindUnbind (LPWSTR lpszInfId,
  370. HWND hwndTree,
  371. BOOL fBind)
  372. {
  373. INetCfg *pnc;
  374. INetCfgComponent *pncc;
  375. INetCfgComponentBindings *pnccb;
  376. INetCfgComponent *pnccToBindUnbind;
  377. LPWSTR lpszApp;
  378. HTREEITEM hTreeItem;
  379. TVITEMW tvItem;
  380. HRESULT hr;
  381. BOOL fChange;
  382. hr = HrGetINetCfg( TRUE,
  383. APP_NAME,
  384. &pnc,
  385. &lpszApp );
  386. fChange = FALSE;
  387. if ( hr == S_OK ) {
  388. //
  389. // Get a reference to the network component.
  390. //
  391. hr = pnc->FindComponent( lpszInfId,
  392. &pncc );
  393. if ( hr == S_OK ) {
  394. //
  395. // Get a reference to the component's binding.
  396. //
  397. hr = pncc->QueryInterface( IID_INetCfgComponentBindings,
  398. (PVOID *)&pnccb );
  399. if ( hr == S_OK ) {
  400. //
  401. // Start with the root item.
  402. //
  403. hTreeItem = TreeView_GetRoot( hwndTree );
  404. //
  405. // Bind/unbind the network component with every component
  406. // that is checked.
  407. //
  408. while ( hTreeItem ) {
  409. ZeroMemory( &tvItem,
  410. sizeof(TVITEMW) );
  411. tvItem.hItem = hTreeItem;
  412. tvItem.mask = TVIF_PARAM | TVIF_STATE;
  413. tvItem.stateMask = TVIS_STATEIMAGEMASK;
  414. if ( TreeView_GetItem(hwndTree,
  415. &tvItem) ) {
  416. //
  417. // Is the network component selected?
  418. //
  419. if ( (tvItem.state >> 12) == 2 ) {
  420. //
  421. // Get a reference to the selected component.
  422. //
  423. hr = pnc->FindComponent( (LPWSTR)tvItem.lParam,
  424. &pnccToBindUnbind );
  425. if ( hr == S_OK ) {
  426. if ( fBind ) {
  427. //
  428. // Bind the component to the selected component.
  429. //
  430. hr = pnccb->BindTo( pnccToBindUnbind );
  431. if ( !fChange ) {
  432. fChange = hr == S_OK;
  433. }
  434. if ( hr != S_OK ) {
  435. ErrMsg( hr,
  436. L"%s couldn't be bound to %s.",
  437. lpszInfId, (LPWSTR)tvItem.lParam );
  438. }
  439. }
  440. else {
  441. //
  442. // Unbind the component from the selected component.
  443. //
  444. hr = pnccb->UnbindFrom( pnccToBindUnbind );
  445. if ( !fChange ) {
  446. fChange = hr == S_OK;
  447. }
  448. if ( hr != S_OK ) {
  449. ErrMsg( hr,
  450. L"%s couldn't be unbound from %s.",
  451. lpszInfId, (LPWSTR)tvItem.lParam );
  452. }
  453. }
  454. ReleaseRef( pnccToBindUnbind );
  455. }
  456. else {
  457. ErrMsg( hr,
  458. L"Couldn't get an interface pointer to %s. "
  459. L"%s will not be bound to it.",
  460. (LPWSTR)tvItem.lParam,
  461. lpszInfId );
  462. }
  463. }
  464. }
  465. //
  466. // Get the next item.
  467. //
  468. hTreeItem = TreeView_GetNextSibling( hwndTree,
  469. hTreeItem );
  470. }
  471. ReleaseRef( pnccb );
  472. }
  473. else {
  474. ErrMsg( hr,
  475. L"Couldn't get a binding interface of %s.",
  476. lpszInfId );
  477. }
  478. ReleaseRef( pncc );
  479. }
  480. else {
  481. ErrMsg( hr,
  482. L"Couldn't get an interface pointer to %s.",
  483. lpszInfId );
  484. }
  485. //
  486. // If one or more network components have been bound/unbound,
  487. // apply the changes.
  488. //
  489. if ( fChange ) {
  490. hr = pnc->Apply();
  491. fChange = hr == S_OK;
  492. }
  493. HrReleaseINetCfg( pnc,
  494. TRUE );
  495. }
  496. else {
  497. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  498. ErrMsg( hr,
  499. L"%s currently holds the lock, try later.",
  500. lpszApp );
  501. CoTaskMemFree( lpszApp );
  502. }
  503. else {
  504. ErrMsg( hr,
  505. L"Couldn't get the notify object interface." );
  506. }
  507. }
  508. return fChange;
  509. }
  510. //
  511. // Function: ListInstalledComponents
  512. //
  513. // Purpose: List installed network components of specific class.
  514. //
  515. // Arguments:
  516. // hwndTree [in] Tree handle in which to list.
  517. // pguidClass [in] Class GUID of the network compoent class.
  518. //
  519. // Returns: None.
  520. //
  521. // Notes:
  522. //
  523. VOID ListInstalledComponents (HWND hwndTree,
  524. const GUID *pguidClass)
  525. {
  526. INetCfg *pnc;
  527. IEnumNetCfgComponent *pencc;
  528. INetCfgComponent *pncc;
  529. LPWSTR lpszApp;
  530. HTREEITEM hTreeItem;
  531. HRESULT hr;
  532. hr = HrGetINetCfg( FALSE,
  533. APP_NAME,
  534. &pnc,
  535. &lpszApp );
  536. if ( hr == S_OK ) {
  537. //
  538. // Get Component Enumerator Interface.
  539. //
  540. hr = HrGetComponentEnum( pnc,
  541. pguidClass,
  542. &pencc );
  543. if ( hr == S_OK ) {
  544. hr = HrGetFirstComponent( pencc, &pncc );
  545. while( hr == S_OK ) {
  546. //
  547. // Add an item to the tree for the network component.
  548. //
  549. hTreeItem = AddToTree( hwndTree,
  550. TVI_ROOT,
  551. pncc );
  552. ReleaseRef( pncc );
  553. hr = HrGetNextComponent( pencc, &pncc );
  554. }
  555. ReleaseRef( pencc );
  556. }
  557. else {
  558. ErrMsg( hr,
  559. L"Failed to get the network component enumerator." );
  560. }
  561. HrReleaseINetCfg( pnc, FALSE );
  562. }
  563. else {
  564. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  565. ErrMsg( hr,
  566. L"%s currently holds the lock, try later.",
  567. lpszApp );
  568. CoTaskMemFree( lpszApp );
  569. }
  570. else {
  571. ErrMsg( hr,
  572. L"Couldn't get the notify object interface." );
  573. }
  574. }
  575. return;
  576. }
  577. //
  578. // Function: UninstallComponent
  579. //
  580. // Purpose: Uninstall a network component.
  581. //
  582. // Arguments:
  583. // lpszInfId [in] PnpID of the network component to uninstall.
  584. //
  585. // Returns: S_OK on success, otherwise an error code.
  586. //
  587. // Notes:
  588. //
  589. HRESULT UninstallComponent (LPWSTR lpszInfId)
  590. {
  591. INetCfg *pnc;
  592. INetCfgComponent *pncc;
  593. INetCfgClass *pncClass;
  594. INetCfgClassSetup *pncClassSetup;
  595. LPWSTR lpszApp;
  596. GUID guidClass;
  597. OBO_TOKEN obo;
  598. HRESULT hr;
  599. hr = HrGetINetCfg( TRUE,
  600. APP_NAME,
  601. &pnc,
  602. &lpszApp );
  603. if ( hr == S_OK ) {
  604. //
  605. // Get a reference to the network component to uninstall.
  606. //
  607. hr = pnc->FindComponent( lpszInfId,
  608. &pncc );
  609. if ( hr == S_OK ) {
  610. //
  611. // Get the class GUID.
  612. //
  613. hr = pncc->GetClassGuid( &guidClass );
  614. if ( hr == S_OK ) {
  615. //
  616. // Get a reference to component's class.
  617. //
  618. hr = pnc->QueryNetCfgClass( &guidClass,
  619. IID_INetCfgClass,
  620. (PVOID *)&pncClass );
  621. if ( hr == S_OK ) {
  622. //
  623. // Get the setup interface.
  624. //
  625. hr = pncClass->QueryInterface( IID_INetCfgClassSetup,
  626. (LPVOID *)&pncClassSetup );
  627. if ( hr == S_OK ) {
  628. //
  629. // Uninstall the component.
  630. //
  631. ZeroMemory( &obo,
  632. sizeof(OBO_TOKEN) );
  633. obo.Type = OBO_USER;
  634. hr = pncClassSetup->DeInstall( pncc,
  635. &obo,
  636. NULL );
  637. if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) {
  638. hr = pnc->Apply();
  639. if ( (hr != S_OK) && (hr != NETCFG_S_REBOOT) ) {
  640. ErrMsg( hr,
  641. L"Couldn't apply the changes after"
  642. L" uninstalling %s.",
  643. lpszInfId );
  644. }
  645. }
  646. else {
  647. ErrMsg( hr,
  648. L"Failed to uninstall %s.",
  649. lpszInfId );
  650. }
  651. ReleaseRef( pncClassSetup );
  652. }
  653. else {
  654. ErrMsg( hr,
  655. L"Couldn't get an interface to setup class." );
  656. }
  657. ReleaseRef( pncClass );
  658. }
  659. else {
  660. ErrMsg( hr,
  661. L"Couldn't get a pointer to class interface "
  662. L"of %s.",
  663. lpszInfId );
  664. }
  665. }
  666. else {
  667. ErrMsg( hr,
  668. L"Couldn't get the class guid of %s.",
  669. lpszInfId );
  670. }
  671. ReleaseRef( pncc );
  672. }
  673. else {
  674. ErrMsg( hr,
  675. L"Couldn't get an interface pointer to %s.",
  676. lpszInfId );
  677. }
  678. HrReleaseINetCfg( pnc,
  679. TRUE );
  680. }
  681. else {
  682. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  683. ErrMsg( hr,
  684. L"%s currently holds the lock, try later.",
  685. lpszApp );
  686. CoTaskMemFree( lpszApp );
  687. }
  688. else {
  689. ErrMsg( hr,
  690. L"Couldn't get the notify object interface." );
  691. }
  692. }
  693. return hr;
  694. }