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.

822 lines
20 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: B I N D I N G . C P P
  7. //
  8. // Contents: Functions to illustrate
  9. // o How to enumerate binding paths.
  10. // o How to enumerate binding interfaces.
  11. // o How to enable/disable bindings.
  12. //
  13. // Notes:
  14. //
  15. // Author: Alok Sinha 15-May-01
  16. //
  17. //----------------------------------------------------------------------------
  18. #include "bindview.h"
  19. //
  20. // Function: WriteBindings
  21. //
  22. // Purpose: Write bindings to specified file.
  23. //
  24. // Arguments:
  25. // fp [in] File handle.
  26. //
  27. // Returns: None.
  28. //
  29. // Notes:
  30. //
  31. VOID WriteBindings (FILE *fp)
  32. {
  33. INetCfg *pnc;
  34. IEnumNetCfgComponent *pencc;
  35. INetCfgComponent *pncc;
  36. LPWSTR lpszApp;
  37. HRESULT hr;
  38. UINT i;
  39. hr = HrGetINetCfg( FALSE,
  40. APP_NAME,
  41. &pnc,
  42. &lpszApp );
  43. if ( hr == S_OK ) {
  44. for (i=CLIENTS_SELECTED; i <= PROTOCOLS_SELECTED; ++i) {
  45. fwprintf( fp, L"--- Bindings of %s ---\n", lpszNetClass[i] );
  46. //
  47. // Get Component Enumerator Interface.
  48. //
  49. hr = HrGetComponentEnum( pnc,
  50. pguidNetClass[i],
  51. &pencc );
  52. if ( hr == S_OK ) {
  53. hr = HrGetFirstComponent( pencc, &pncc );
  54. while( hr == S_OK ) {
  55. //
  56. // Write bindings of the component.
  57. //
  58. WriteBindingPath( fp,
  59. pncc );
  60. ReleaseRef( pncc );
  61. fwprintf( fp, L"\n" );
  62. hr = HrGetNextComponent( pencc, &pncc );
  63. }
  64. fwprintf( fp, L"\n" );
  65. //
  66. // S_FALSE merely indicates that there are no more components.
  67. //
  68. if ( hr == S_FALSE ) {
  69. hr = S_OK;
  70. }
  71. ReleaseRef( pencc );
  72. }
  73. else {
  74. ErrMsg( hr,
  75. L"Couldn't get the component enumerator interface." );
  76. }
  77. }
  78. HrReleaseINetCfg( pnc, FALSE );
  79. }
  80. else {
  81. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  82. ErrMsg( hr,
  83. L"%s currently holds the lock, try later.",
  84. lpszApp );
  85. CoTaskMemFree( lpszApp );
  86. }
  87. else {
  88. ErrMsg( hr,
  89. L"Couldn't get the notify object interface." );
  90. }
  91. }
  92. return;
  93. }
  94. //
  95. // Function: WriteBindingPath
  96. //
  97. // Purpose: Write binding paths of a component.
  98. //
  99. // Arguments:
  100. // fp [in] File handle.
  101. // pncc [in] Network component.
  102. //
  103. // Returns: None.
  104. //
  105. // Notes:
  106. //
  107. VOID WriteBindingPath (FILE *fp,
  108. INetCfgComponent *pncc)
  109. {
  110. IEnumNetCfgBindingPath *pencbp;
  111. INetCfgBindingPath *pncbp;
  112. LPWSTR lpszName;
  113. HRESULT hr;
  114. //
  115. // Write the first component's name.
  116. //
  117. hr = pncc->GetDisplayName( &lpszName );
  118. if ( hr == S_OK ) {
  119. fwprintf( fp, L"\n%s", lpszName );
  120. }
  121. else {
  122. ErrMsg( hr,
  123. L"Unable to get the display name of a component, "
  124. L" some binding paths will not be written." );
  125. return;
  126. }
  127. //
  128. // Get binding path enumerator.
  129. //
  130. hr = HrGetBindingPathEnum( pncc,
  131. EBP_BELOW,
  132. &pencbp );
  133. if ( hr == S_OK ) {
  134. hr = HrGetFirstBindingPath( pencbp,
  135. &pncbp );
  136. while( hr == S_OK ) {
  137. //
  138. // Write interfaces of the binding path.
  139. //
  140. WriteInterfaces( fp,
  141. pncbp );
  142. ReleaseRef( pncbp );
  143. hr = HrGetNextBindingPath( pencbp,
  144. &pncbp );
  145. if ( hr == S_OK ) {
  146. fwprintf( fp, L"\n%s", lpszName );
  147. }
  148. }
  149. ReleaseRef( pencbp );
  150. }
  151. else {
  152. ErrMsg( hr,
  153. L"Couldn't get the binding path enumerator of %s. "
  154. L"Its binding paths will not be written.",
  155. lpszName );
  156. }
  157. CoTaskMemFree( lpszName );
  158. return;
  159. }
  160. //
  161. // Function: WriteInterfaces
  162. //
  163. // Purpose: Write bindings to specified file.
  164. //
  165. // Arguments:
  166. // fp [in] File handle.
  167. // pncbp [in] Binding path.
  168. //
  169. // Returns: None.
  170. //
  171. // Notes:
  172. //
  173. VOID WriteInterfaces (FILE *fp,
  174. INetCfgBindingPath *pncbp)
  175. {
  176. IEnumNetCfgBindingInterface *pencbi;
  177. INetCfgBindingInterface *pncbi;
  178. INetCfgComponent *pnccLower;
  179. LPWSTR lpszName;
  180. HRESULT hr;
  181. hr = HrGetBindingInterfaceEnum( pncbp,
  182. &pencbi );
  183. if ( hr == S_OK ) {
  184. hr = HrGetFirstBindingInterface( pencbi,
  185. &pncbi );
  186. //
  187. // Write lower component of each interface.
  188. //
  189. while( hr == S_OK ) {
  190. hr = pncbi->GetLowerComponent ( &pnccLower );
  191. if ( hr == S_OK ) {
  192. hr = pnccLower->GetDisplayName( &lpszName );
  193. if ( hr == S_OK ) {
  194. fwprintf( fp, L"-->%s", lpszName );
  195. CoTaskMemFree( lpszName );
  196. }
  197. }
  198. ReleaseRef( pnccLower );
  199. ReleaseRef( pncbi );
  200. hr = HrGetNextBindingInterface( pencbi,
  201. &pncbi );
  202. }
  203. ReleaseRef( pencbi );
  204. }
  205. else {
  206. ErrMsg( hr,
  207. L"Couldn't get the binding interface enumerator."
  208. L"The binding interfaces will not be shown." );
  209. }
  210. return;
  211. }
  212. //
  213. // Function: EnumNetBindings
  214. //
  215. // Purpose: Enumerate components and their bindings.
  216. //
  217. // Arguments:
  218. // hwndTree [in] Tree handle.
  219. // uiTypeSelected [in] Type of network component selected.
  220. //
  221. // Returns: TRUE on success.
  222. //
  223. // Notes:
  224. //
  225. BOOL EnumNetBindings (HWND hwndTree,
  226. UINT uiTypeSelected)
  227. {
  228. INetCfg *pnc;
  229. IEnumNetCfgComponent *pencc;
  230. INetCfgComponent *pncc;
  231. LPWSTR lpszApp;
  232. HTREEITEM hTreeItem;
  233. HRESULT hr;
  234. hr = HrGetINetCfg( FALSE,
  235. APP_NAME,
  236. &pnc,
  237. &lpszApp );
  238. if ( hr == S_OK ) {
  239. //
  240. // Get Component Enumerator Interface.
  241. //
  242. hr = HrGetComponentEnum( pnc,
  243. pguidNetClass[uiTypeSelected],
  244. &pencc );
  245. if ( hr == S_OK ) {
  246. hr = HrGetFirstComponent( pencc, &pncc );
  247. while( hr == S_OK ) {
  248. //
  249. // Add the component's name to the tree.
  250. //
  251. hTreeItem = AddToTree( hwndTree,
  252. TVI_ROOT,
  253. pncc );
  254. if ( hTreeItem ) {
  255. //
  256. // Enumerate bindings.
  257. //
  258. ListBindings( pncc,
  259. hwndTree,
  260. hTreeItem );
  261. }
  262. ReleaseRef( pncc );
  263. hr = HrGetNextComponent( pencc, &pncc );
  264. }
  265. //
  266. // S_FALSE merely indicates that there are no more components.
  267. //
  268. if ( hr == S_FALSE ) {
  269. hr = S_OK;
  270. }
  271. ReleaseRef( pencc );
  272. }
  273. else {
  274. ErrMsg( hr,
  275. L"Couldn't get the component enumerator interface." );
  276. }
  277. HrReleaseINetCfg( pnc, FALSE );
  278. }
  279. else {
  280. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  281. ErrMsg( hr,
  282. L"%s currently holds the lock, try later.",
  283. lpszApp );
  284. CoTaskMemFree( lpszApp );
  285. }
  286. else {
  287. ErrMsg( hr,
  288. L"Couldn't get the notify object interface." );
  289. }
  290. }
  291. return hr == S_OK;
  292. }
  293. //
  294. // Function: ListBindings
  295. //
  296. // Purpose: Enumerate bindings of network components.
  297. //
  298. // Arguments:
  299. // pncc [in] Network component.
  300. // hwndTree [in] Tree handle.
  301. // hTreeItemRoot [in] Parent item.
  302. //
  303. // Returns: None.
  304. //
  305. // Notes:
  306. //
  307. VOID ListBindings (INetCfgComponent *pncc,
  308. HWND hwndTree,
  309. HTREEITEM hTreeItemRoot)
  310. {
  311. IEnumNetCfgBindingPath *pencbp;
  312. INetCfgBindingPath *pncbp;
  313. HTREEITEM hTreeItem;
  314. ULONG ulIndex;
  315. HRESULT hr;
  316. hr = HrGetBindingPathEnum( pncc,
  317. EBP_BELOW,
  318. &pencbp );
  319. if ( hr == S_OK ) {
  320. hr = HrGetFirstBindingPath( pencbp,
  321. &pncbp );
  322. ulIndex = 1;
  323. while( hr == S_OK ) {
  324. //
  325. // Add an item for the binding path.
  326. //
  327. hTreeItem = AddBindNameToTree( pncbp,
  328. hwndTree,
  329. hTreeItemRoot,
  330. ulIndex );
  331. if ( hTreeItem ) {
  332. //
  333. // Enumerate interfaces.
  334. //
  335. ListInterfaces( pncbp,
  336. hwndTree,
  337. hTreeItem );
  338. }
  339. ReleaseRef( pncbp );
  340. hr = HrGetNextBindingPath( pencbp,
  341. &pncbp );
  342. ulIndex++;
  343. }
  344. ReleaseRef( pencbp );
  345. }
  346. else {
  347. LPWSTR lpszName;
  348. if ( pncc->GetDisplayName(&lpszName) == S_OK ) {
  349. ErrMsg( hr,
  350. L"Couldn't get the binding path enumerator of %s. "
  351. L"Its binding paths will not be shown.",
  352. lpszName );
  353. CoTaskMemFree( lpszName );
  354. }
  355. else {
  356. ErrMsg( hr,
  357. L"Couldn't get the binding path enumerator of a "
  358. L"network component. The binding paths will not "
  359. L"be shown." );
  360. }
  361. }
  362. return;
  363. }
  364. //
  365. // Function: ListInterfaces
  366. //
  367. // Purpose: Enumerate interfaces of a binding path.
  368. //
  369. // Arguments:
  370. // pncbp [in] Binding path.
  371. // hwndTree [in] Tree handle.
  372. // hTreeItemRoot [in] Parent item.
  373. //
  374. // Returns: None.
  375. //
  376. // Notes:
  377. //
  378. VOID ListInterfaces (INetCfgBindingPath *pncbp,
  379. HWND hwndTree,
  380. HTREEITEM hTreeItemRoot)
  381. {
  382. IEnumNetCfgBindingInterface *pencbi;
  383. INetCfgBindingInterface *pncbi;
  384. INetCfgComponent *pnccBound;
  385. HTREEITEM hTreeItem;
  386. HRESULT hr;
  387. hr = HrGetBindingInterfaceEnum( pncbp,
  388. &pencbi );
  389. if ( hr == S_OK ) {
  390. hr = HrGetFirstBindingInterface( pencbi,
  391. &pncbi );
  392. hTreeItem = hTreeItemRoot;
  393. while( (hr == S_OK) && hTreeItem ) {
  394. //
  395. // Add lower component of every interface to the tree.
  396. //
  397. hr = pncbi->GetLowerComponent( &pnccBound );
  398. hTreeItem = AddToTree( hwndTree,
  399. hTreeItem,
  400. pnccBound );
  401. ReleaseRef( pnccBound );
  402. ReleaseRef( pncbi );
  403. hr = HrGetNextBindingInterface( pencbi,
  404. &pncbi );
  405. }
  406. //
  407. // If hr is S_OK then, the loop terminated due to error in adding
  408. // the binding path to the tree and pncbi has a reference to an
  409. // interface.
  410. //
  411. if ( hr == S_OK ) {
  412. ReleaseRef( pncbi );
  413. }
  414. ReleaseRef( pencbi );
  415. }
  416. else {
  417. ErrMsg( hr,
  418. L"Couldn't get the binding interface enumerator."
  419. L"The binding interfaces will not be shown." );
  420. }
  421. return;
  422. }
  423. //
  424. // Function: HandleBindingPathOperation
  425. //
  426. // Purpose:
  427. //
  428. // Arguments:
  429. // hwndOwner [in] Owner window.
  430. // ulSelection [in] Option selected.
  431. // hItem [in] Item selected.
  432. // lParam [in] lParam of the item.
  433. //
  434. // Returns: None.
  435. //
  436. // Notes:
  437. //
  438. VOID HandleBindingPathOperation (HWND hwndOwner,
  439. ULONG ulSelection,
  440. HTREEITEM hItem,
  441. LPARAM lParam)
  442. {
  443. switch( ulSelection ) {
  444. case IDI_ENABLE:
  445. case IDI_DISABLE:
  446. //
  447. // Enable/disable binding path.
  448. //
  449. EnableBindingPath( hwndOwner,
  450. hItem,
  451. (LPWSTR)lParam,
  452. ulSelection == IDI_ENABLE );
  453. }
  454. return;
  455. }
  456. //
  457. // Function: EnableBindingPath
  458. //
  459. // Purpose: Enable/disable binding path.
  460. //
  461. // Arguments:
  462. // hwndOwner [in] Owner window.
  463. // hItem [in] Item handle of the binding path.
  464. // lpszPathToken [in] Path token of the binding path.
  465. // fEnable [in] if TRUE, enable, otherwise disable.
  466. //
  467. // Returns: None.
  468. //
  469. // Notes:
  470. //
  471. VOID EnableBindingPath (HWND hwndOwner,
  472. HTREEITEM hItem,
  473. LPWSTR lpszPathToken,
  474. BOOL fEnable)
  475. {
  476. INetCfg *pnc;
  477. INetCfgBindingPath *pncbp;
  478. LPWSTR lpszInfId;
  479. LPWSTR lpszApp;
  480. HRESULT hr;
  481. //
  482. // Get PnpID of the owner component.
  483. //
  484. lpszInfId = GetComponentId( hwndOwner,
  485. hItem );
  486. if ( lpszInfId ) {
  487. hr = HrGetINetCfg( TRUE,
  488. APP_NAME,
  489. &pnc,
  490. &lpszApp );
  491. if ( hr == S_OK ) {
  492. //
  493. // Find the binding path reference.
  494. //
  495. pncbp = FindBindingPath( pnc,
  496. lpszInfId,
  497. lpszPathToken );
  498. if ( pncbp ) {
  499. //
  500. // Enable/disable.
  501. //
  502. hr = pncbp->Enable( fEnable );
  503. if ( hr == S_OK ) {
  504. hr = pnc->Apply();
  505. if ( hr == S_OK ) {
  506. //
  507. // Refreshe the state of the item representing the
  508. // binding path.
  509. //
  510. RefreshItemState( hwndOwner,
  511. hItem,
  512. fEnable );
  513. }
  514. else {
  515. ErrMsg( hr,
  516. L"Failed to apply changes to the binding path." );
  517. }
  518. }
  519. else {
  520. if ( fEnable ) {
  521. ErrMsg( hr,
  522. L"Failed to enable the binding path." );
  523. }
  524. else {
  525. ErrMsg( hr,
  526. L"Failed to disable the binding path." );
  527. }
  528. }
  529. ReleaseRef( pncbp );
  530. }
  531. HrReleaseINetCfg( pnc,
  532. TRUE );
  533. }
  534. else {
  535. if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) {
  536. ErrMsg( hr,
  537. L"%s currently holds the lock, try later.",
  538. lpszApp );
  539. CoTaskMemFree( lpszApp );
  540. }
  541. else {
  542. ErrMsg( hr,
  543. L"Couldn't get the notify object interface." );
  544. }
  545. }
  546. }
  547. else {
  548. ErrMsg( HRESULT_FROM_WIN32(GetLastError()),
  549. L"Couldn't determine the owner of the binding path." );
  550. }
  551. return;
  552. }
  553. //
  554. // Function: GetComponentId
  555. //
  556. // Purpose: Find the PnpID of a network component.
  557. //
  558. // Arguments:
  559. // hwndTree [in] Tree handle.
  560. // hItem [in] Item handle of the binding path.
  561. //
  562. // Returns: PnpID of the network component.
  563. //
  564. // Notes:
  565. //
  566. LPWSTR GetComponentId (HWND hwndTree,
  567. HTREEITEM hItem)
  568. {
  569. LPWSTR lpszInfId;
  570. HTREEITEM hTreeItemParent;
  571. TVITEMW tvItem;
  572. lpszInfId = NULL;
  573. //
  574. // Get the item handle of the owner component.
  575. //
  576. hTreeItemParent = TreeView_GetParent( hwndTree,
  577. hItem );
  578. if ( hTreeItemParent ) {
  579. //
  580. // Get lParam of the owner component. lParam is the PnpID.
  581. //
  582. ZeroMemory( &tvItem,
  583. sizeof(TVITEMW) );
  584. tvItem.hItem = hTreeItemParent;
  585. tvItem.mask = TVIF_PARAM;
  586. if ( TreeView_GetItem(hwndTree,
  587. &tvItem) ) {
  588. lpszInfId = (LPWSTR)tvItem.lParam;
  589. }
  590. }
  591. return lpszInfId;
  592. }
  593. //
  594. // Function: WriteBindings
  595. //
  596. // Purpose: Find the binding path with a give path token.
  597. //
  598. // Arguments:
  599. // pnc [in] INetCfg reference.
  600. // lpszInfId [in] PnpID of the network component.
  601. // lpszPathTokenSelected [in] Path token of the binding path to search.
  602. //
  603. // Returns: Reference to the binding path on success, otherwise NULL.
  604. //
  605. // Notes:
  606. //
  607. INetCfgBindingPath *FindBindingPath (INetCfg *pnc,
  608. LPWSTR lpszInfId,
  609. LPWSTR lpszPathTokenSelected)
  610. {
  611. INetCfgComponent *pncc;
  612. IEnumNetCfgBindingPath *pencbp;
  613. INetCfgBindingPath *pncbp;
  614. LPWSTR lpszPathToken;
  615. HRESULT hr;
  616. BOOL fFound;
  617. fFound = FALSE;
  618. //
  619. // Get the component reference.
  620. //
  621. hr = pnc->FindComponent( lpszInfId,
  622. &pncc );
  623. if ( hr == S_OK ) {
  624. hr = HrGetBindingPathEnum( pncc,
  625. EBP_BELOW,
  626. &pencbp );
  627. if ( hr == S_OK ) {
  628. hr = HrGetFirstBindingPath( pencbp,
  629. &pncbp );
  630. // Enumerate each binding path and find the one
  631. // whose path token matches the specified one.
  632. //
  633. while ( !fFound && (hr == S_OK) ) {
  634. hr = pncbp->GetPathToken( &lpszPathToken );
  635. if ( hr == S_OK ) {
  636. fFound = !wcscmp( lpszPathToken,
  637. lpszPathTokenSelected );
  638. CoTaskMemFree( lpszPathToken );
  639. }
  640. if ( !fFound ) {
  641. ReleaseRef( pncbp );
  642. hr = HrGetNextBindingPath( pencbp,
  643. &pncbp );
  644. }
  645. }
  646. ReleaseRef( pencbp );
  647. }
  648. else {
  649. ErrMsg( hr,
  650. L"Couldn't get the binding path enumerator interface." );
  651. }
  652. }
  653. else {
  654. ErrMsg( hr,
  655. L"Couldn't get an interface pointer to %s.",
  656. lpszInfId );
  657. }
  658. return (fFound) ? pncbp : NULL;
  659. }