Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

859 lines
24 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. if ( (hr != S_OK) && (hr != NETCFG_S_REBOOT) ) {
  139. ErrMsg( hr,
  140. L"Couldn't apply the changes after"
  141. L" installing the network component." );
  142. }
  143. }
  144. else {
  145. if ( hr != HRESULT_FROM_WIN32(ERROR_CANCELLED) ) {
  146. ErrMsg( hr,
  147. L"Couldn't install the network component." );
  148. }
  149. }
  150. ReleaseRef( pncClassSetup );
  151. }
  152. else {
  153. ErrMsg( hr,
  154. L"Couldn't get an interface to setup class." );
  155. }
  156. ReleaseRef( pncClass );
  157. }
  158. else {
  159. ErrMsg( hr,
  160. L"Couldn't get a pointer to class interface." );
  161. }
  162. HrReleaseINetCfg( pnc,
  163. TRUE );
  164. }
  165. else {
  166. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  167. ErrMsg( hr,
  168. L"%s currently holds the lock, try later.",
  169. lpszApp );
  170. CoTaskMemFree( lpszApp );
  171. }
  172. else {
  173. ErrMsg( hr,
  174. L"Couldn't the get notify object interface." );
  175. }
  176. }
  177. return hr;
  178. }
  179. //
  180. // Function: InstallSpecifiedComponent
  181. //
  182. // Purpose: Install a network component from an INF file.
  183. //
  184. // Arguments:
  185. // lpszInfFile [in] INF file.
  186. // lpszPnpID [in] PnpID of the network component to install.
  187. // pguidClass [in] Class GUID of the network component.
  188. //
  189. // Returns: None.
  190. //
  191. // Notes:
  192. //
  193. HRESULT InstallSpecifiedComponent (LPWSTR lpszInfFile,
  194. LPWSTR lpszPnpID,
  195. const GUID *pguidClass)
  196. {
  197. INetCfg *pnc;
  198. LPWSTR lpszApp;
  199. HRESULT hr;
  200. hr = HrGetINetCfg( TRUE,
  201. APP_NAME,
  202. &pnc,
  203. &lpszApp );
  204. if ( hr == S_OK ) {
  205. //
  206. // Install the network component.
  207. //
  208. hr = HrInstallNetComponent( pnc,
  209. lpszPnpID,
  210. pguidClass,
  211. lpszInfFile );
  212. if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) {
  213. hr = pnc->Apply();
  214. }
  215. else {
  216. if ( hr != HRESULT_FROM_WIN32(ERROR_CANCELLED) ) {
  217. ErrMsg( hr,
  218. L"Couldn't install the network component." );
  219. }
  220. }
  221. HrReleaseINetCfg( pnc,
  222. TRUE );
  223. }
  224. else {
  225. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  226. ErrMsg( hr,
  227. L"%s currently holds the lock, try later.",
  228. lpszApp );
  229. CoTaskMemFree( lpszApp );
  230. }
  231. else {
  232. ErrMsg( hr,
  233. L"Couldn't the get notify object interface." );
  234. }
  235. }
  236. return hr;
  237. }
  238. //
  239. // Function: ListCompToBindUnbind
  240. //
  241. // Purpose: List all the components that are bound or bindable.
  242. //
  243. // Arguments:
  244. // lpszInfId [in] PnpID of the network component.
  245. // uiType [in] Type of network component.
  246. // hwndTree [in] Tree handle in which to list.
  247. // fBound [in] if TRUE, list components that are bound.
  248. //
  249. // Returns: Number of components listed.
  250. //
  251. // Notes:
  252. //
  253. DWORD ListCompToBindUnbind (LPWSTR lpszInfId,
  254. UINT uiType,
  255. HWND hwndTree,
  256. BOOL fBound)
  257. {
  258. INetCfg *pnc;
  259. INetCfgComponent *pncc;
  260. IEnumNetCfgComponent *pencc;
  261. INetCfgComponentBindings *pnccb;
  262. INetCfgComponent *pnccToBindUnbind;
  263. LPWSTR lpszApp;
  264. DWORD dwCount;
  265. HRESULT hr;
  266. dwCount = 0;
  267. hr = HrGetINetCfg( TRUE,
  268. APP_NAME,
  269. &pnc,
  270. &lpszApp );
  271. if ( hr == S_OK ) {
  272. //
  273. // Get a reference to the network component selected.
  274. //
  275. hr = pnc->FindComponent( lpszInfId,
  276. &pncc );
  277. if ( hr == S_OK ) {
  278. //
  279. // Get Component Enumerator Interface.
  280. //
  281. hr = HrGetComponentEnum( pnc,
  282. pguidNetClass[uiType],
  283. &pencc );
  284. if ( hr == S_OK ) {
  285. hr = pncc->QueryInterface( IID_INetCfgComponentBindings,
  286. (PVOID *)&pnccb );
  287. if ( hr == S_OK ) {
  288. hr = HrGetFirstComponent( pencc, &pnccToBindUnbind );
  289. while( hr == S_OK ) {
  290. hr = pnccb->IsBoundTo( pnccToBindUnbind );
  291. //
  292. // fBound = TRUE ==> Want to list components that are
  293. // bound.
  294. //
  295. if ( fBound ) {
  296. if ( hr == S_OK ) {
  297. AddToTree( hwndTree,
  298. TVI_ROOT,
  299. pnccToBindUnbind );
  300. dwCount++;
  301. }
  302. }
  303. else {
  304. //
  305. // fBound = FALSE ==> Want to list components that
  306. // are not bound but are bindable.
  307. //
  308. if ( hr == S_FALSE ) {
  309. hr = pnccb->IsBindableTo( pnccToBindUnbind );
  310. if ( hr == S_OK ) {
  311. AddToTree( hwndTree,
  312. TVI_ROOT,
  313. pnccToBindUnbind );
  314. dwCount++;
  315. }
  316. }
  317. }
  318. ReleaseRef( pnccToBindUnbind );
  319. hr = HrGetNextComponent( pencc, &pnccToBindUnbind );
  320. }
  321. ReleaseRef( pnccb );
  322. }
  323. else {
  324. ErrMsg( hr,
  325. L"Couldn't get the component binding interface "
  326. L"of %s.",
  327. lpszInfId );
  328. }
  329. ReleaseRef( pencc );
  330. }
  331. else {
  332. ErrMsg( hr,
  333. L"Couldn't get the network component enumerator "
  334. L"interface." );
  335. }
  336. ReleaseRef( pncc );
  337. }
  338. else {
  339. ErrMsg( hr,
  340. L"Couldn't get an interface pointer to %s.",
  341. lpszInfId );
  342. }
  343. HrReleaseINetCfg( pnc,
  344. TRUE );
  345. }
  346. else {
  347. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  348. ErrMsg( hr,
  349. L"%s currently holds the lock, try later.",
  350. lpszApp );
  351. CoTaskMemFree( lpszApp );
  352. }
  353. else {
  354. ErrMsg( hr,
  355. L"Couldn't get the notify object interface." );
  356. }
  357. }
  358. return dwCount;
  359. }
  360. //
  361. // Function: BindUnbind
  362. //
  363. // Purpose: Bind/unbind a network component.
  364. //
  365. // Arguments:
  366. // lpszInfId [in] PnpID of the network component to bind/unbind.
  367. // hwndTree [in] Tree handle.
  368. // fBind [in] if TRUE, bind, otherwise unbind.
  369. //
  370. // Returns: TRUE on success.
  371. //
  372. // Notes:
  373. //
  374. BOOL BindUnbind (LPWSTR lpszInfId,
  375. HWND hwndTree,
  376. BOOL fBind)
  377. {
  378. INetCfg *pnc;
  379. INetCfgComponent *pncc;
  380. INetCfgComponentBindings *pnccb;
  381. INetCfgComponent *pnccToBindUnbind;
  382. LPWSTR lpszApp;
  383. HTREEITEM hTreeItem;
  384. TVITEMW tvItem;
  385. HRESULT hr;
  386. BOOL fChange;
  387. hr = HrGetINetCfg( TRUE,
  388. APP_NAME,
  389. &pnc,
  390. &lpszApp );
  391. fChange = FALSE;
  392. if ( hr == S_OK ) {
  393. //
  394. // Get a reference to the network component.
  395. //
  396. hr = pnc->FindComponent( lpszInfId,
  397. &pncc );
  398. if ( hr == S_OK ) {
  399. //
  400. // Get a reference to the component's binding.
  401. //
  402. hr = pncc->QueryInterface( IID_INetCfgComponentBindings,
  403. (PVOID *)&pnccb );
  404. if ( hr == S_OK ) {
  405. //
  406. // Start with the root item.
  407. //
  408. hTreeItem = TreeView_GetRoot( hwndTree );
  409. //
  410. // Bind/unbind the network component with every component
  411. // that is checked.
  412. //
  413. while ( hTreeItem ) {
  414. ZeroMemory( &tvItem,
  415. sizeof(TVITEMW) );
  416. tvItem.hItem = hTreeItem;
  417. tvItem.mask = TVIF_PARAM | TVIF_STATE;
  418. tvItem.stateMask = TVIS_STATEIMAGEMASK;
  419. if ( TreeView_GetItem(hwndTree,
  420. &tvItem) ) {
  421. //
  422. // Is the network component selected?
  423. //
  424. if ( (tvItem.state >> 12) == 2 ) {
  425. //
  426. // Get a reference to the selected component.
  427. //
  428. hr = pnc->FindComponent( (LPWSTR)tvItem.lParam,
  429. &pnccToBindUnbind );
  430. if ( hr == S_OK ) {
  431. if ( fBind ) {
  432. //
  433. // Bind the component to the selected component.
  434. //
  435. hr = pnccb->BindTo( pnccToBindUnbind );
  436. if ( !fChange ) {
  437. fChange = hr == S_OK;
  438. }
  439. if ( hr != S_OK ) {
  440. ErrMsg( hr,
  441. L"%s couldn't be bound to %s.",
  442. lpszInfId, (LPWSTR)tvItem.lParam );
  443. }
  444. }
  445. else {
  446. //
  447. // Unbind the component from the selected component.
  448. //
  449. hr = pnccb->UnbindFrom( pnccToBindUnbind );
  450. if ( !fChange ) {
  451. fChange = hr == S_OK;
  452. }
  453. if ( hr != S_OK ) {
  454. ErrMsg( hr,
  455. L"%s couldn't be unbound from %s.",
  456. lpszInfId, (LPWSTR)tvItem.lParam );
  457. }
  458. }
  459. ReleaseRef( pnccToBindUnbind );
  460. }
  461. else {
  462. ErrMsg( hr,
  463. L"Couldn't get an interface pointer to %s. "
  464. L"%s will not be bound to it.",
  465. (LPWSTR)tvItem.lParam,
  466. lpszInfId );
  467. }
  468. }
  469. }
  470. //
  471. // Get the next item.
  472. //
  473. hTreeItem = TreeView_GetNextSibling( hwndTree,
  474. hTreeItem );
  475. }
  476. ReleaseRef( pnccb );
  477. }
  478. else {
  479. ErrMsg( hr,
  480. L"Couldn't get a binding interface of %s.",
  481. lpszInfId );
  482. }
  483. ReleaseRef( pncc );
  484. }
  485. else {
  486. ErrMsg( hr,
  487. L"Couldn't get an interface pointer to %s.",
  488. lpszInfId );
  489. }
  490. //
  491. // If one or more network components have been bound/unbound,
  492. // apply the changes.
  493. //
  494. if ( fChange ) {
  495. hr = pnc->Apply();
  496. fChange = hr == S_OK;
  497. }
  498. HrReleaseINetCfg( pnc,
  499. TRUE );
  500. }
  501. else {
  502. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  503. ErrMsg( hr,
  504. L"%s currently holds the lock, try later.",
  505. lpszApp );
  506. CoTaskMemFree( lpszApp );
  507. }
  508. else {
  509. ErrMsg( hr,
  510. L"Couldn't get the notify object interface." );
  511. }
  512. }
  513. return fChange;
  514. }
  515. //
  516. // Function: ListInstalledComponents
  517. //
  518. // Purpose: List installed network components of specific class.
  519. //
  520. // Arguments:
  521. // hwndTree [in] Tree handle in which to list.
  522. // pguidClass [in] Class GUID of the network compoent class.
  523. //
  524. // Returns: None.
  525. //
  526. // Notes:
  527. //
  528. VOID ListInstalledComponents (HWND hwndTree,
  529. const GUID *pguidClass)
  530. {
  531. INetCfg *pnc;
  532. IEnumNetCfgComponent *pencc;
  533. INetCfgComponent *pncc;
  534. LPWSTR lpszApp;
  535. HTREEITEM hTreeItem;
  536. HRESULT hr;
  537. hr = HrGetINetCfg( FALSE,
  538. APP_NAME,
  539. &pnc,
  540. &lpszApp );
  541. if ( hr == S_OK ) {
  542. //
  543. // Get Component Enumerator Interface.
  544. //
  545. hr = HrGetComponentEnum( pnc,
  546. pguidClass,
  547. &pencc );
  548. if ( hr == S_OK ) {
  549. hr = HrGetFirstComponent( pencc, &pncc );
  550. while( hr == S_OK ) {
  551. //
  552. // Add an item to the tree for the network component.
  553. //
  554. hTreeItem = AddToTree( hwndTree,
  555. TVI_ROOT,
  556. pncc );
  557. ReleaseRef( pncc );
  558. hr = HrGetNextComponent( pencc, &pncc );
  559. }
  560. ReleaseRef( pencc );
  561. }
  562. else {
  563. ErrMsg( hr,
  564. L"Failed to get the network component enumerator." );
  565. }
  566. HrReleaseINetCfg( pnc, FALSE );
  567. }
  568. else {
  569. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  570. ErrMsg( hr,
  571. L"%s currently holds the lock, try later.",
  572. lpszApp );
  573. CoTaskMemFree( lpszApp );
  574. }
  575. else {
  576. ErrMsg( hr,
  577. L"Couldn't get the notify object interface." );
  578. }
  579. }
  580. return;
  581. }
  582. //
  583. // Function: UninstallComponent
  584. //
  585. // Purpose: Uninstall a network component.
  586. //
  587. // Arguments:
  588. // lpszInfId [in] PnpID of the network component to uninstall.
  589. //
  590. // Returns: S_OK on success, otherwise an error code.
  591. //
  592. // Notes:
  593. //
  594. HRESULT UninstallComponent (LPWSTR lpszInfId)
  595. {
  596. INetCfg *pnc;
  597. INetCfgComponent *pncc;
  598. INetCfgClass *pncClass;
  599. INetCfgClassSetup *pncClassSetup;
  600. LPWSTR lpszApp;
  601. GUID guidClass;
  602. OBO_TOKEN obo;
  603. HRESULT hr;
  604. hr = HrGetINetCfg( TRUE,
  605. APP_NAME,
  606. &pnc,
  607. &lpszApp );
  608. if ( hr == S_OK ) {
  609. //
  610. // Get a reference to the network component to uninstall.
  611. //
  612. hr = pnc->FindComponent( lpszInfId,
  613. &pncc );
  614. if ( hr == S_OK ) {
  615. //
  616. // Get the class GUID.
  617. //
  618. hr = pncc->GetClassGuid( &guidClass );
  619. if ( hr == S_OK ) {
  620. //
  621. // Get a reference to component's class.
  622. //
  623. hr = pnc->QueryNetCfgClass( &guidClass,
  624. IID_INetCfgClass,
  625. (PVOID *)&pncClass );
  626. if ( hr == S_OK ) {
  627. //
  628. // Get the setup interface.
  629. //
  630. hr = pncClass->QueryInterface( IID_INetCfgClassSetup,
  631. (LPVOID *)&pncClassSetup );
  632. if ( hr == S_OK ) {
  633. //
  634. // Uninstall the component.
  635. //
  636. ZeroMemory( &obo,
  637. sizeof(OBO_TOKEN) );
  638. obo.Type = OBO_USER;
  639. hr = pncClassSetup->DeInstall( pncc,
  640. &obo,
  641. NULL );
  642. if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) {
  643. hr = pnc->Apply();
  644. if ( (hr != S_OK) && (hr != NETCFG_S_REBOOT) ) {
  645. ErrMsg( hr,
  646. L"Couldn't apply the changes after"
  647. L" uninstalling %s.",
  648. lpszInfId );
  649. }
  650. }
  651. else {
  652. ErrMsg( hr,
  653. L"Failed to uninstall %s.",
  654. lpszInfId );
  655. }
  656. ReleaseRef( pncClassSetup );
  657. }
  658. else {
  659. ErrMsg( hr,
  660. L"Couldn't get an interface to setup class." );
  661. }
  662. ReleaseRef( pncClass );
  663. }
  664. else {
  665. ErrMsg( hr,
  666. L"Couldn't get a pointer to class interface "
  667. L"of %s.",
  668. lpszInfId );
  669. }
  670. }
  671. else {
  672. ErrMsg( hr,
  673. L"Couldn't get the class guid of %s.",
  674. lpszInfId );
  675. }
  676. ReleaseRef( pncc );
  677. }
  678. else {
  679. ErrMsg( hr,
  680. L"Couldn't get an interface pointer to %s.",
  681. lpszInfId );
  682. }
  683. HrReleaseINetCfg( pnc,
  684. TRUE );
  685. }
  686. else {
  687. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  688. ErrMsg( hr,
  689. L"%s currently holds the lock, try later.",
  690. lpszApp );
  691. CoTaskMemFree( lpszApp );
  692. }
  693. else {
  694. ErrMsg( hr,
  695. L"Couldn't get the notify object interface." );
  696. }
  697. }
  698. return hr;
  699. }