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.

2241 lines
59 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: B I N D V I E W . C P P
  7. //
  8. // Contents:
  9. //
  10. // Notes:
  11. //
  12. // Author: Alok Sinha 15-Amy-01
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "BindView.h"
  16. //----------------------------------------------------------------------------
  17. // Globals
  18. //
  19. //
  20. // Image list for devices of various setup class.
  21. //
  22. SP_CLASSIMAGELIST_DATA ClassImageListData;
  23. HINSTANCE hInstance;
  24. HMENU hMainMenu;
  25. HMENU hComponentSubMenu;
  26. HMENU hBindingPathSubMenu;
  27. //
  28. // Network components whose bindings are enumerated.
  29. //
  30. LPWSTR lpszNetClass[] = {
  31. L"All Clients",
  32. L"All Services",
  33. L"All Protocols"
  34. };
  35. //
  36. // GUIDs of network components.
  37. //
  38. const GUID *pguidNetClass [] = {
  39. &GUID_DEVCLASS_NETCLIENT,
  40. &GUID_DEVCLASS_NETSERVICE,
  41. &GUID_DEVCLASS_NETTRANS,
  42. &GUID_DEVCLASS_NET
  43. };
  44. //
  45. // Program entry point.
  46. //
  47. int APIENTRY WinMain (HINSTANCE hInst,
  48. HINSTANCE hPrevInstance,
  49. LPSTR lpCmdLine,
  50. int nCmdShow )
  51. {
  52. //
  53. // Make sure common control DLL is loaded.
  54. //
  55. hInstance = hInst;
  56. InitCommonControls();
  57. if ( DialogBoxW(hInst,
  58. MAKEINTRESOURCEW(IDD_MAIN),
  59. NULL,
  60. MainDlgProc) == -1 ) {
  61. ErrMsg( HRESULT_FROM_WIN32(GetLastError()),
  62. L"Failed to create the main dialog box, exiting..." );
  63. }
  64. return 0;
  65. }
  66. //
  67. // WndProc for the main dialog box.
  68. //
  69. INT_PTR CALLBACK MainDlgProc (HWND hwndDlg,
  70. UINT uMsg,
  71. WPARAM wParam,
  72. LPARAM lParam)
  73. {
  74. HWND hwndBindingTree;
  75. HICON hIcon;
  76. switch (uMsg) {
  77. case WM_INITDIALOG:
  78. hIcon = LoadIcon( hInstance,
  79. MAKEINTRESOURCE(IDI_BINDVIEW) );
  80. if ( !hIcon ) {
  81. ErrMsg( HRESULT_FROM_WIN32(GetLastError()),
  82. L"Couldn't load the program icon, exiting..." );
  83. return FALSE;
  84. }
  85. SetClassLongPtr( hwndDlg,
  86. GCLP_HICON,
  87. (LONG_PTR)hIcon );
  88. hMainMenu = LoadMenu( hInstance,
  89. MAKEINTRESOURCE(IDM_OPTIONS) );
  90. if ( !hMainMenu ) {
  91. ErrMsg( HRESULT_FROM_WIN32(GetLastError()),
  92. L"Couldn't load the program menu, exiting..." );
  93. return FALSE;
  94. }
  95. hComponentSubMenu = GetSubMenu( hMainMenu,
  96. 0 );
  97. hBindingPathSubMenu = GetSubMenu( hMainMenu,
  98. 1 );
  99. if ( !hComponentSubMenu || !hBindingPathSubMenu ) {
  100. ErrMsg( HRESULT_FROM_WIN32(GetLastError()),
  101. L"Couldn't load the program menu, exiting..." );
  102. DestroyMenu( hMainMenu );
  103. return FALSE;
  104. }
  105. //
  106. // Add the network components types whose bindings are shown.
  107. //
  108. UpdateComponentTypeList( GetDlgItem(hwndDlg,
  109. IDL_COMPONENT_TYPES) );
  110. //
  111. // Load and associate the image list of all device classes with
  112. // tree.
  113. //
  114. hwndBindingTree = GetDlgItem( hwndDlg,
  115. IDT_BINDINGS );
  116. ZeroMemory( &ClassImageListData, sizeof(SP_CLASSIMAGELIST_DATA) );
  117. ClassImageListData.cbSize = sizeof(SP_CLASSIMAGELIST_DATA);
  118. if ( SetupDiGetClassImageList(&ClassImageListData) == TRUE ) {
  119. TreeView_SetImageList( hwndBindingTree,
  120. ClassImageListData.ImageList,
  121. LVSIL_NORMAL );
  122. }
  123. else {
  124. //
  125. // In case, we failed to load the image list, abort.
  126. //
  127. ErrMsg( HRESULT_FROM_WIN32(GetLastError()),
  128. L"Couldn't load the image list of "
  129. L"device classes, exiting..." );
  130. DestroyMenu( hMainMenu );
  131. return FALSE;
  132. }
  133. //
  134. // Enumerate the bindings of the network component selected by default.
  135. //
  136. EnumNetBindings( hwndBindingTree,
  137. DEFAULT_COMPONENT_SELECTED );
  138. return TRUE; // Tell Windows to continue creating the dialog box.
  139. case WM_COMMAND:
  140. switch( LOWORD(wParam) ) {
  141. case IDL_COMPONENT_TYPES:
  142. if ( HIWORD(wParam) == CBN_SELCHANGE ) {
  143. //
  144. // User has selected a new network component type.
  145. //
  146. RefreshAll( hwndDlg );
  147. }
  148. break;
  149. case IDB_EXPAND_ALL:
  150. case IDB_COLLAPSE_ALL:
  151. if ( HIWORD(wParam) == BN_CLICKED ) {
  152. HTREEITEM hItem;
  153. //
  154. // Expand/Collapse the entire tree.
  155. //
  156. hwndBindingTree = GetDlgItem( hwndDlg,
  157. IDT_BINDINGS );
  158. hItem = TreeView_GetSelection( hwndBindingTree );
  159. ExpandCollapseAll( hwndBindingTree,
  160. TVI_ROOT,
  161. (LOWORD(wParam) == IDB_EXPAND_ALL) ?
  162. TVE_EXPAND : TVE_COLLAPSE );
  163. TreeView_SelectSetFirstVisible( hwndBindingTree,
  164. hItem );
  165. }
  166. break;
  167. case IDB_SAVE:
  168. if ( HIWORD(wParam) == BN_CLICKED ) {
  169. //
  170. // Save the binding information to a file.
  171. //
  172. WCHAR lpszFile[MAX_PATH+1];
  173. if ( GetFileName(hwndDlg,
  174. NULL,
  175. L"Select a file name",
  176. OFN_DONTADDTORECENT | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT,
  177. lpszFile) ) {
  178. DumpBindings( lpszFile );
  179. }
  180. }
  181. break;
  182. case IDB_INSTALL:
  183. if ( HIWORD(wParam) == BN_CLICKED ) {
  184. //
  185. // Install a network component.
  186. //
  187. if ( (BOOL)DialogBoxW(hInstance,
  188. MAKEINTRESOURCEW(IDD_INSTALL),
  189. hwndDlg,
  190. InstallDlg) == TRUE ) {
  191. RefreshAll( hwndDlg );
  192. }
  193. }
  194. break;
  195. case IDB_UNINSTALL:
  196. if ( HIWORD(wParam) == BN_CLICKED ) {
  197. //
  198. // Uninstall a network component.
  199. //
  200. if ( (BOOL)DialogBoxW(hInstance,
  201. MAKEINTRESOURCEW(IDD_UNINSTALL),
  202. hwndDlg,
  203. UninstallDlg) == TRUE ) {
  204. RefreshAll( hwndDlg );
  205. }
  206. }
  207. }
  208. break;
  209. case WM_NOTIFY:
  210. {
  211. LPNMHDR lpnm;
  212. lpnm = (LPNMHDR)lParam;
  213. if ( (lpnm->idFrom == IDT_BINDINGS) &&
  214. (lpnm->code == NM_RCLICK) ) {
  215. //
  216. // A network component or a binding path is selected
  217. // with a righ-click.
  218. //
  219. ProcessRightClick( lpnm );
  220. //
  221. // Tell Windows that the righ-click has been handled
  222. // us.
  223. //
  224. return TRUE;
  225. }
  226. }
  227. break;
  228. case WM_SYSCOMMAND:
  229. if ( (0xFFF0 & wParam) == SC_CLOSE ) {
  230. //
  231. // Before exiting, make sure to delete the image list
  232. // and the buffers associated with each item in the tree.
  233. //
  234. SetupDiDestroyClassImageList( &ClassImageListData );
  235. ReleaseMemory( GetDlgItem(hwndDlg, IDT_BINDINGS),
  236. TVI_ROOT );
  237. DestroyMenu( hMainMenu );
  238. EndDialog( hwndDlg, 0 );
  239. }
  240. }
  241. return FALSE;
  242. }
  243. //
  244. // WndProc of the dialog box for binding/unbinding compoents.
  245. //
  246. INT_PTR CALLBACK BindComponentDlg (HWND hwndDlg,
  247. UINT uMsg,
  248. WPARAM wParam,
  249. LPARAM lParam)
  250. {
  251. LPBIND_UNBIND_INFO lpBindUnbind;
  252. switch (uMsg) {
  253. case WM_INITDIALOG:
  254. {
  255. DWORD dwCount;
  256. //
  257. // Save the lParam which is an index to the selected network
  258. // component.
  259. //
  260. SetWindowLongPtr( hwndDlg,
  261. DWLP_USER,
  262. (LONG_PTR)lParam );
  263. lpBindUnbind = (LPBIND_UNBIND_INFO)lParam;
  264. //
  265. // fBindTo is TRUE when the user wants to bind the selected
  266. // component to other components. So, we list the components
  267. // that are not bound and can bind.
  268. //
  269. //
  270. // fBindTo is FALSE when the user wants to unbind the selected
  271. // component from other components. So, we list the components
  272. // that are bound to it.
  273. //
  274. //
  275. // ListCompToBindUnbind returns number of components added to
  276. // the list. Keep track of it. If it zero then, we don't want to
  277. // show this dialog box.
  278. //
  279. dwCount = ListCompToBindUnbind(
  280. lpBindUnbind->lpszInfId,
  281. ADAPTERS_SELECTED,
  282. GetDlgItem(hwndDlg, IDT_COMPONENT_LIST),
  283. lpBindUnbind->fBindTo == FALSE );
  284. dwCount += ListCompToBindUnbind(
  285. lpBindUnbind->lpszInfId,
  286. CLIENTS_SELECTED,
  287. GetDlgItem(hwndDlg, IDT_COMPONENT_LIST),
  288. lpBindUnbind->fBindTo == FALSE );
  289. dwCount += ListCompToBindUnbind(
  290. lpBindUnbind->lpszInfId,
  291. SERVICES_SELECTED,
  292. GetDlgItem(hwndDlg, IDT_COMPONENT_LIST),
  293. lpBindUnbind->fBindTo == FALSE );
  294. dwCount += ListCompToBindUnbind(
  295. lpBindUnbind->lpszInfId,
  296. PROTOCOLS_SELECTED,
  297. GetDlgItem(hwndDlg, IDT_COMPONENT_LIST),
  298. lpBindUnbind->fBindTo == FALSE );
  299. if ( dwCount > 0 ) {
  300. //
  301. // Since the same dialog box is used for unbind opration,
  302. // we need to update the text on the button to reflect that
  303. // it is a bind operation.
  304. //
  305. if ( lpBindUnbind->fBindTo == FALSE ) {
  306. SetWindowTextW( hwndDlg,
  307. L"Unbind From Network Components" );
  308. SetWindowTextW( GetDlgItem(hwndDlg, IDB_BIND_UNBIND),
  309. L"Unbind" );
  310. SetWindowTextW( GetDlgItem(hwndDlg, IDG_COMPONENT_LIST),
  311. L"Select components to unbind from" );
  312. }
  313. }
  314. else {
  315. if ( lpBindUnbind->fBindTo == TRUE ) {
  316. ErrMsg( 0,
  317. L"There no network components that can "
  318. L"bind to the selected component." );
  319. }
  320. else {
  321. ErrMsg( 0,
  322. L"There no network components that are "
  323. L"bound to the selected component." );
  324. }
  325. PostMessage( hwndDlg, WM_NO_COMPONENTS, 0, 0 );
  326. }
  327. return TRUE;
  328. }
  329. case WM_NO_COMPONENTS:
  330. EndDialog( hwndDlg, 0 );
  331. break;
  332. case WM_COMMAND:
  333. if ( (LOWORD(wParam) == IDB_CLOSE) &&
  334. (HIWORD(wParam) == BN_CLICKED) ) {
  335. //
  336. // Before deleting the list in the tree, free the buffer
  337. // associated with each item. The buffer holds the
  338. // INF Id of network components.
  339. //
  340. ReleaseMemory( GetDlgItem(hwndDlg, IDT_COMPONENT_LIST),
  341. TVI_ROOT );
  342. EndDialog( hwndDlg, 0 );
  343. }
  344. else {
  345. //
  346. // User wants to bind/unbind.
  347. //
  348. if ( (LOWORD(wParam) == IDB_BIND_UNBIND) &&
  349. (HIWORD(wParam) == BN_CLICKED) ) {
  350. lpBindUnbind = (LPBIND_UNBIND_INFO)GetWindowLongPtr( hwndDlg,
  351. DWLP_USER );
  352. if ( BindUnbind(lpBindUnbind->lpszInfId,
  353. GetDlgItem(hwndDlg, IDT_COMPONENT_LIST),
  354. lpBindUnbind->fBindTo) ) {
  355. RefreshBindings( hwndDlg,
  356. lpBindUnbind->lpszInfId );
  357. }
  358. ReleaseMemory( GetDlgItem(hwndDlg, IDT_COMPONENT_LIST),
  359. TVI_ROOT );
  360. EndDialog( hwndDlg, 0 );
  361. }
  362. }
  363. break;
  364. case WM_SYSCOMMAND:
  365. if ( (0xFFF0 & wParam) == SC_CLOSE ) {
  366. //
  367. // Before deleting the list in the tree, free the buffer
  368. // associated with each item. The buffer holds the
  369. // INF Id of network components.
  370. //
  371. ReleaseMemory( GetDlgItem(hwndDlg, IDT_COMPONENT_LIST),
  372. TVI_ROOT );
  373. EndDialog( hwndDlg, 0 );
  374. }
  375. }
  376. return FALSE;
  377. }
  378. //
  379. //WndProc of the dialog box for installing network components.
  380. //
  381. INT_PTR CALLBACK InstallDlg (HWND hwndDlg,
  382. UINT uMsg,
  383. WPARAM wParam,
  384. LPARAM lParam)
  385. {
  386. switch (uMsg) {
  387. case WM_INITDIALOG:
  388. {
  389. HWND hwndTree;
  390. //
  391. // List types of network components e.g. client,
  392. // protocol and service.
  393. //
  394. hwndTree = GetDlgItem( hwndDlg,
  395. IDT_COMPONENT_LIST );
  396. TreeView_SetImageList( hwndTree,
  397. ClassImageListData.ImageList,
  398. LVSIL_NORMAL );
  399. //
  400. // Insert and select client by default.
  401. //
  402. TreeView_Select( hwndTree,
  403. InsertItem(hwndTree,
  404. CLIENTS_SELECTED),
  405. TVGN_CARET );
  406. InsertItem( hwndTree,
  407. SERVICES_SELECTED );
  408. InsertItem( hwndTree,
  409. PROTOCOLS_SELECTED );
  410. //
  411. // Initialize it to FALSE. It will be set to TRUE when
  412. // at least one component is installed.
  413. //
  414. SetWindowLongPtr( hwndDlg,
  415. DWLP_USER,
  416. (LONG_PTR)FALSE );
  417. return TRUE;
  418. }
  419. case WM_COMMAND:
  420. switch( LOWORD(wParam) ) {
  421. case IDB_INSTALL:
  422. //
  423. // Install from Windows system directory.
  424. //
  425. if ( HIWORD(wParam) == BN_CLICKED ) {
  426. InstallSelectedComponentType( hwndDlg, NULL );
  427. }
  428. break;
  429. case IDB_BROWSE:
  430. //
  431. // User wants to specify an INF file for the network
  432. // to install.
  433. //
  434. if ( HIWORD(wParam) == BN_CLICKED ) {
  435. WCHAR lpszInfFile[MAX_PATH+1];
  436. if ( GetFileName(hwndDlg,
  437. L"INF files (*.inf)\0*.inf\0",
  438. L"Select the INF file of the network component to install",
  439. OFN_DONTADDTORECENT | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
  440. lpszInfFile) ) {
  441. InstallSelectedComponentType( hwndDlg,
  442. lpszInfFile );
  443. }
  444. }
  445. break;
  446. case IDB_CLOSE:
  447. if ( HIWORD(wParam) == BN_CLICKED ) {
  448. //
  449. // Return the value of DWLP_USER to indicate whether one or
  450. // more components have been installed. Accordingly, the
  451. // the list will be refreshed.
  452. //
  453. EndDialog( hwndDlg,
  454. GetWindowLongPtr(hwndDlg, DWLP_USER) );
  455. }
  456. }
  457. break;
  458. case WM_NOTIFY:
  459. {
  460. LPNMHDR lpnm;
  461. lpnm = (LPNMHDR)lParam;
  462. if ( (lpnm->idFrom == IDT_COMPONENT_LIST) &&
  463. (lpnm->code == NM_DBLCLK) ) {
  464. //
  465. // On double-click, install from Windows system directory.
  466. //
  467. InstallSelectedComponentType( hwndDlg, NULL );
  468. }
  469. }
  470. break;
  471. case WM_SYSCOMMAND:
  472. if ( (0xFFF0 & wParam) == SC_CLOSE ) {
  473. //
  474. // Return the value of DWLP_USER to indicate whether one or
  475. // more components have been installed. Accordingly, the
  476. // the list will be refreshed.
  477. //
  478. EndDialog( hwndDlg,
  479. GetWindowLongPtr(hwndDlg, DWLP_USER) );
  480. }
  481. }
  482. return FALSE;
  483. }
  484. //
  485. // WndProc of the dialog box for uninstalling a network component.
  486. //
  487. INT_PTR CALLBACK UninstallDlg (HWND hwndDlg,
  488. UINT uMsg,
  489. WPARAM wParam,
  490. LPARAM lParam)
  491. {
  492. HWND hwndTree;
  493. switch (uMsg) {
  494. case WM_INITDIALOG:
  495. hwndTree = GetDlgItem( hwndDlg,
  496. IDT_COMPONENT_LIST );
  497. TreeView_SetImageList( hwndTree,
  498. ClassImageListData.ImageList,
  499. LVSIL_NORMAL );
  500. //
  501. // List all the compoents currently installed.
  502. //
  503. ListInstalledComponents( hwndTree,
  504. &GUID_DEVCLASS_NETCLIENT);
  505. ListInstalledComponents( hwndTree,
  506. &GUID_DEVCLASS_NETSERVICE );
  507. ListInstalledComponents( hwndTree,
  508. &GUID_DEVCLASS_NETTRANS );
  509. //
  510. // Initialize it to FALSE. It will be set to TRUE when
  511. // at least one component is installed.
  512. //
  513. SetWindowLongPtr( hwndDlg,
  514. DWLP_USER,
  515. (LONG_PTR)FALSE );
  516. return TRUE;
  517. case WM_COMMAND:
  518. switch( LOWORD(wParam) ) {
  519. case IDB_REMOVE:
  520. if ( HIWORD(wParam) == BN_CLICKED ) {
  521. //
  522. // Uninstall the selected component.
  523. //
  524. UninstallSelectedComponent( hwndDlg );
  525. }
  526. break;
  527. case IDB_CLOSE:
  528. if ( HIWORD(wParam) == BN_CLICKED ) {
  529. hwndTree = GetDlgItem( hwndDlg,
  530. IDT_COMPONENT_LIST );
  531. ReleaseMemory( hwndTree,
  532. TVI_ROOT );
  533. //
  534. // Return the value of DWLP_USER to indicate whether one or
  535. // more components have been installed. Accordingly, the
  536. // the list will be refreshed.
  537. //
  538. EndDialog( hwndDlg,
  539. GetWindowLongPtr(hwndDlg, DWLP_USER) );
  540. }
  541. }
  542. break;
  543. case WM_NOTIFY:
  544. {
  545. LPNMHDR lpnm;
  546. lpnm = (LPNMHDR)lParam;
  547. if ( (lpnm->idFrom == IDT_COMPONENT_LIST) &&
  548. (lpnm->code == NM_DBLCLK) ) {
  549. UninstallSelectedComponent( hwndDlg );
  550. }
  551. }
  552. break;
  553. case WM_SYSCOMMAND:
  554. if ( (0xFFF0 & wParam) == SC_CLOSE ) {
  555. hwndTree = GetDlgItem( hwndDlg,
  556. IDT_COMPONENT_LIST );
  557. ReleaseMemory( hwndTree,
  558. TVI_ROOT );
  559. //
  560. // Return the value of DWLP_USER to indicate whether one or
  561. // more components have been installed. Accordingly, the
  562. // the list will be refreshed.
  563. //
  564. EndDialog( hwndDlg,
  565. GetWindowLongPtr(hwndDlg, DWLP_USER) );
  566. }
  567. }
  568. return FALSE;
  569. }
  570. //+---------------------------------------------------------------------------
  571. //
  572. // Function: DumpBindings
  573. //
  574. // Purpose: Write the binding information.
  575. //
  576. // Arguments:
  577. // lpszFile [in] Name of the file in which to write.
  578. //
  579. // Returns: None
  580. //
  581. // Notes:
  582. //
  583. VOID DumpBindings (LPWSTR lpszFile)
  584. {
  585. FILE *fp;
  586. fp = _wfopen( lpszFile,
  587. L"w" );
  588. if ( fp == NULL ) {
  589. ErrMsg( 0,
  590. L"Unable to open %s.",
  591. lpszFile );
  592. }
  593. else {
  594. WriteBindings( fp );
  595. fclose( fp );
  596. }
  597. return;
  598. }
  599. //
  600. // Function: InstallSelectedComponentType
  601. //
  602. // Purpose: Install a network component.
  603. //
  604. // Arguments:
  605. // hwndDlg [in] Handle to Install dialog box.
  606. // lpszInfFile [in] Inf file of the network component.
  607. //
  608. // Returns: None
  609. //
  610. // Notes:
  611. // If lpszInfFile is NULL, network components are installed from the
  612. // system directory.
  613. //
  614. VOID InstallSelectedComponentType (HWND hwndDlg,
  615. LPWSTR lpszInfFile)
  616. {
  617. HWND hwndTree;
  618. HTREEITEM hItem;
  619. LPARAM lParam;
  620. HCURSOR hPrevCursor;
  621. HCURSOR hWaitCursor;
  622. HWND hwndFocus;
  623. DWORD dwType;
  624. BOOL fEnable;
  625. HRESULT hr;
  626. hwndTree = GetDlgItem( hwndDlg,
  627. IDT_COMPONENT_LIST );
  628. //
  629. // Find out the type of component selected.
  630. //
  631. hItem = TreeView_GetSelection( hwndTree );
  632. if ( hItem ) {
  633. if ( GetItemInfo( hwndTree,
  634. hItem,
  635. &lParam,
  636. &dwType,
  637. &fEnable) ) {
  638. //
  639. // Disable the install dialog controls.
  640. //
  641. hwndFocus = GetFocus();
  642. EnableWindow( hwndTree, FALSE );
  643. EnableWindow( GetDlgItem(hwndDlg,IDB_OK),
  644. FALSE );
  645. EnableWindow( GetDlgItem(hwndDlg,IDB_CLOSE),
  646. FALSE );
  647. hWaitCursor = LoadCursor( NULL,
  648. IDC_WAIT );
  649. if ( hWaitCursor ) {
  650. hPrevCursor = SetCursor( hWaitCursor );
  651. }
  652. if ( lpszInfFile ) {
  653. LPWSTR lpszPnpID;
  654. //
  655. // Inf file name specified, install the network component
  656. // from this file.
  657. //
  658. hr = GetPnpID( lpszInfFile, &lpszPnpID );
  659. if ( hr == S_OK ) {
  660. hr = InstallSpecifiedComponent( lpszInfFile,
  661. lpszPnpID,
  662. pguidNetClass[(UINT)lParam] );
  663. CoTaskMemFree( lpszPnpID );
  664. }
  665. else {
  666. ErrMsg( hr,
  667. L"Error reading the INF file %s.",
  668. lpszInfFile );
  669. }
  670. }
  671. else {
  672. //
  673. // Install from system directory.
  674. //
  675. hr = InstallComponent( hwndTree,
  676. pguidNetClass[(UINT)lParam] );
  677. }
  678. if ( hWaitCursor ) {
  679. SetCursor( hPrevCursor );
  680. }
  681. switch( hr ) {
  682. case S_OK:
  683. MessageBoxW(
  684. hwndTree,
  685. L"Component installed successfully.",
  686. L"Network Component Installation",
  687. MB_OK | MB_ICONINFORMATION );
  688. SetWindowLongPtr( hwndDlg,
  689. DWLP_USER,
  690. (LONG_PTR)TRUE );
  691. break;
  692. case NETCFG_S_REBOOT:
  693. MessageBoxW(
  694. hwndTree,
  695. L"Component installed successfully: "
  696. L"Reboot required.",
  697. L"Network Component Installation",
  698. MB_OK | MB_ICONINFORMATION );
  699. SetWindowLongPtr( hwndDlg,
  700. DWLP_USER,
  701. (LONG_PTR)TRUE );
  702. }
  703. //
  704. // Enable the install dialog controls.
  705. //
  706. EnableWindow( hwndTree, TRUE );
  707. EnableWindow( GetDlgItem(hwndDlg,IDB_OK),
  708. TRUE );
  709. EnableWindow( GetDlgItem(hwndDlg,IDB_CLOSE),
  710. TRUE );
  711. SetFocus( hwndFocus );
  712. }
  713. }
  714. return;
  715. }
  716. //
  717. // Function: GetPnpID
  718. //
  719. // Purpose: Retrieve PnpID from an inf file.
  720. //
  721. // Arguments:
  722. // lpszInfFile [in] Inf file to search.
  723. // lppszPnpID [out] PnpID found.
  724. //
  725. // Returns: TRUE on success.
  726. //
  727. // Notes:
  728. //
  729. HRESULT GetPnpID (LPWSTR lpszInfFile,
  730. LPWSTR *lppszPnpID)
  731. {
  732. HINF hInf;
  733. LPWSTR lpszModelSection;
  734. HRESULT hr;
  735. *lppszPnpID = NULL;
  736. hInf = SetupOpenInfFileW( lpszInfFile,
  737. NULL,
  738. INF_STYLE_WIN4,
  739. NULL );
  740. if ( hInf == INVALID_HANDLE_VALUE )
  741. {
  742. return HRESULT_FROM_WIN32(GetLastError());
  743. }
  744. //
  745. // Read the Model section name from Manufacturer section.
  746. //
  747. hr = GetKeyValue( hInf,
  748. L"Manufacturer",
  749. NULL,
  750. 1,
  751. &lpszModelSection );
  752. if ( hr == S_OK )
  753. {
  754. //
  755. // Read PnpID from the Model section.
  756. //
  757. hr = GetKeyValue( hInf,
  758. lpszModelSection,
  759. NULL,
  760. 2,
  761. lppszPnpID );
  762. CoTaskMemFree( lpszModelSection );
  763. }
  764. SetupCloseInfFile( hInf );
  765. return hr;
  766. }
  767. //
  768. // Function: GetKeyValue
  769. //
  770. // Purpose: Retrieve the value of a key from the inf file.
  771. //
  772. // Arguments:
  773. // hInf [in] Inf file handle.
  774. // lpszSection [in] Section name.
  775. // lpszKey [in] Key name.
  776. // dwIndex [in] Key index.
  777. // lppszValue [out] Key value.
  778. //
  779. // Returns: S_OK on success, otherwise and error code.
  780. //
  781. // Notes:
  782. //
  783. HRESULT GetKeyValue (HINF hInf,
  784. LPCWSTR lpszSection,
  785. LPCWSTR lpszKey,
  786. DWORD dwIndex,
  787. LPWSTR *lppszValue)
  788. {
  789. INFCONTEXT infCtx;
  790. DWORD dwSizeNeeded;
  791. HRESULT hr;
  792. *lppszValue = NULL;
  793. if ( SetupFindFirstLineW(hInf,
  794. lpszSection,
  795. lpszKey,
  796. &infCtx) == FALSE )
  797. {
  798. return HRESULT_FROM_WIN32(GetLastError());
  799. }
  800. SetupGetStringFieldW( &infCtx,
  801. dwIndex,
  802. NULL,
  803. 0,
  804. &dwSizeNeeded );
  805. *lppszValue = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded );
  806. if ( !*lppszValue )
  807. {
  808. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  809. }
  810. if ( SetupGetStringFieldW(&infCtx,
  811. dwIndex,
  812. *lppszValue,
  813. dwSizeNeeded,
  814. NULL) == FALSE )
  815. {
  816. hr = HRESULT_FROM_WIN32(GetLastError());
  817. CoTaskMemFree( *lppszValue );
  818. *lppszValue = NULL;
  819. }
  820. else
  821. {
  822. hr = S_OK;
  823. }
  824. return hr;
  825. }
  826. //
  827. // Function: UninstallSelectedComponent
  828. //
  829. // Purpose: Uninstall the selected network component.
  830. //
  831. // Arguments:
  832. // hwndDlg [in] Window handle of the uninstall dialog box.
  833. //
  834. // Returns: TRUE on success.
  835. //
  836. // Notes:
  837. //
  838. VOID UninstallSelectedComponent (HWND hwndDlg)
  839. {
  840. HWND hwndTree;
  841. HTREEITEM hItem;
  842. LPARAM lParam;
  843. HCURSOR hPrevCursor;
  844. HCURSOR hWaitCursor;
  845. DWORD dwType;
  846. BOOL fEnable;
  847. HRESULT hr;
  848. hwndTree = GetDlgItem( hwndDlg,
  849. IDT_COMPONENT_LIST );
  850. //
  851. // Get the selected item to get its lParam which is the
  852. // PnpID of the network component.
  853. //
  854. hItem = TreeView_GetSelection( hwndTree );
  855. if ( hItem ) {
  856. if ( GetItemInfo( hwndTree,
  857. hItem,
  858. &lParam,
  859. &dwType,
  860. &fEnable) ) {
  861. hWaitCursor = LoadCursor( NULL,
  862. IDC_WAIT );
  863. if ( hWaitCursor ) {
  864. hPrevCursor = SetCursor( hWaitCursor );
  865. }
  866. //
  867. // Uninstall the selected component.
  868. //
  869. hr = UninstallComponent( (LPWSTR)lParam );
  870. if ( hWaitCursor ) {
  871. SetCursor( hPrevCursor );
  872. }
  873. switch( hr ) {
  874. case S_OK:
  875. MessageBoxW(
  876. hwndTree,
  877. L"Uninstallation successful.",
  878. L"Network Component Uninstallation",
  879. MB_OK | MB_ICONINFORMATION );
  880. CoTaskMemFree( (LPVOID)lParam );
  881. TreeView_DeleteItem( hwndTree,
  882. hItem );
  883. SetWindowLongPtr( hwndDlg,
  884. DWLP_USER,
  885. (LONG_PTR)TRUE );
  886. break;
  887. case NETCFG_S_REBOOT:
  888. MessageBoxW(
  889. hwndTree,
  890. L"Uninstallation successful: "
  891. L"Reboot required.",
  892. L"Network Component Uninstallation",
  893. MB_OK | MB_ICONINFORMATION );
  894. CoTaskMemFree( (LPVOID)lParam );
  895. TreeView_DeleteItem( hwndTree,
  896. hItem );
  897. SetWindowLongPtr( hwndDlg,
  898. DWLP_USER,
  899. (LONG_PTR)TRUE );
  900. }
  901. }
  902. }
  903. return;
  904. }
  905. //
  906. // Function: ExpandCollapseAll
  907. //
  908. // Purpose: Expand or collapse a tree.
  909. //
  910. // Arguments:
  911. // hwndTree [in] Window handle of the tree.
  912. // hTreeItem [in] Handle of root item.
  913. // uiFlag [in] Flag indicating whether to expand or collapse.
  914. //
  915. // Returns: None.
  916. //
  917. // Notes:
  918. //
  919. VOID ExpandCollapseAll (HWND hwndTree,
  920. HTREEITEM hTreeItem,
  921. UINT uiFlag)
  922. {
  923. HTREEITEM hItemChild;
  924. hItemChild = TreeView_GetChild( hwndTree,
  925. hTreeItem );
  926. if ( hItemChild ) {
  927. //
  928. // If the root has one or more children, expand/collapse the root.
  929. //
  930. TreeView_Expand( hwndTree,
  931. hTreeItem,
  932. uiFlag );
  933. }
  934. while ( hItemChild ) {
  935. //
  936. // Expand/collapse all the children.
  937. //
  938. ExpandCollapseAll( hwndTree,
  939. hItemChild,
  940. uiFlag );
  941. //
  942. // Expand/collapse all the siblings.
  943. //
  944. hItemChild = TreeView_GetNextSibling( hwndTree,
  945. hItemChild );
  946. }
  947. return;
  948. }
  949. //
  950. // Function: GetFileName
  951. //
  952. // Purpose: Prompt for a filename.
  953. //
  954. // Arguments:
  955. // hwndDlg [in] Window handle of the parent.
  956. // lpszFilter [in] See documentation for GetOpenFileName.
  957. // lpszTitle [in] See documentation for GetOpenFileName.
  958. // dwFlags [in] See documentation for GetOpenFileName.
  959. // lpszFile [in] See documentation for GetOpenFileName.
  960. //
  961. // Returns: See documentation for GetOpenFileName.
  962. //
  963. // Notes:
  964. //
  965. BOOL GetFileName (HWND hwndDlg,
  966. LPWSTR lpszFilter,
  967. LPWSTR lpszTitle,
  968. DWORD dwFlags,
  969. LPWSTR lpszFile)
  970. {
  971. OPENFILENAMEW ofn;
  972. lpszFile[0] = NULL;
  973. ZeroMemory( &ofn, sizeof(OPENFILENAMEW) );
  974. ofn.lStructSize = sizeof(OPENFILENAMEW);
  975. ofn.hwndOwner = hwndDlg;
  976. ofn.lpstrFilter = lpszFilter;
  977. ofn.lpstrFile = lpszFile;
  978. ofn.nMaxFile = MAX_PATH+1;
  979. ofn.lpstrTitle = lpszTitle;
  980. ofn.Flags = dwFlags;
  981. return GetOpenFileName( &ofn );
  982. }
  983. //
  984. // Function: ProcessRightClick
  985. //
  986. // Purpose: Handle righ mouse button click.
  987. //
  988. // Arguments:
  989. // lpnm [in] LPNMHDR info
  990. //
  991. // Returns: None.
  992. //
  993. // Notes:
  994. //
  995. VOID ProcessRightClick (LPNMHDR lpnm)
  996. {
  997. HTREEITEM hItemSelected;
  998. LPARAM lParam;
  999. DWORD dwItemType;
  1000. BOOL fEnabled;
  1001. //
  1002. // Determine the item on which user clicked the right mouse button.
  1003. //
  1004. hItemSelected = TreeView_GetDropHilight( lpnm->hwndFrom );
  1005. if ( !hItemSelected ) {
  1006. hItemSelected = TreeView_GetSelection( lpnm->hwndFrom );
  1007. }
  1008. else {
  1009. //
  1010. // User has right-clicked an unselected item, make that a selected
  1011. // item.
  1012. //
  1013. TreeView_Select( lpnm->hwndFrom,
  1014. hItemSelected,
  1015. TVGN_CARET );
  1016. }
  1017. if ( hItemSelected ) {
  1018. //
  1019. // Get the lParam of the selected node in the tree which points to inf id or
  1020. // pathtoken name depending on if the node represents a network component or
  1021. // a binding path.
  1022. //
  1023. if ( GetItemInfo(lpnm->hwndFrom,
  1024. hItemSelected,
  1025. &lParam,
  1026. &dwItemType,
  1027. &fEnabled) ) {
  1028. if ( dwItemType & ITEM_NET_COMPONENTS ) {
  1029. //
  1030. // Show the shortcut menu of operations for a network component.
  1031. //
  1032. ShowComponentMenu( lpnm->hwndFrom,
  1033. hItemSelected,
  1034. lParam);
  1035. }
  1036. else {
  1037. if ( dwItemType & ITEM_NET_BINDINGS ) {
  1038. //
  1039. // Show the shortcut menu of operations for a binding path.
  1040. //
  1041. ShowBindingPathMenu( lpnm->hwndFrom,
  1042. hItemSelected,
  1043. lParam,
  1044. fEnabled );
  1045. }
  1046. }
  1047. }
  1048. }
  1049. return;
  1050. }
  1051. //
  1052. // Function: ShowComponentMenu
  1053. //
  1054. // Purpose: Show shortcut menu of options for a network component.
  1055. //
  1056. // Arguments:
  1057. // hwndOwner [in] Owner window.
  1058. // hItem [in] Selected item representing a network component.
  1059. // lParam [in] PnpID of the network component.
  1060. //
  1061. // Returns: None.
  1062. //
  1063. // Notes:
  1064. //
  1065. VOID ShowComponentMenu (HWND hwndOwner,
  1066. HTREEITEM hItem,
  1067. LPARAM lParam)
  1068. {
  1069. ULONG ulSelection;
  1070. POINT pt;
  1071. GetCursorPos( &pt );
  1072. ulSelection = (ULONG)TrackPopupMenu( hComponentSubMenu,
  1073. TPM_RIGHTALIGN | TPM_BOTTOMALIGN |
  1074. TPM_NONOTIFY | TPM_RETURNCMD |
  1075. TPM_RIGHTBUTTON,
  1076. pt.x,
  1077. pt.y,
  1078. 0,
  1079. hwndOwner,
  1080. NULL );
  1081. if ( ulSelection ) {
  1082. //
  1083. // Do the selected action.
  1084. //
  1085. HandleComponentOperation( hwndOwner,
  1086. ulSelection,
  1087. hItem,
  1088. lParam );
  1089. }
  1090. return;
  1091. }
  1092. //
  1093. // Function: ShowBindingPathMenu
  1094. //
  1095. // Purpose: Show shortcut menu of options for a network component.
  1096. //
  1097. // Arguments:
  1098. // hwndOwner [in] Owner window.
  1099. // hItem [in] Selected item representing a binding path.
  1100. // lParam [in] PnpID of the network component.
  1101. // fEnabled [in] TRUE when the path is enabled.
  1102. //
  1103. // Returns: None.
  1104. //
  1105. // Notes:
  1106. //
  1107. VOID ShowBindingPathMenu (HWND hwndOwner,
  1108. HTREEITEM hItem,
  1109. LPARAM lParam,
  1110. BOOL fEnabled)
  1111. {
  1112. MENUITEMINFOW menuItemInfo;
  1113. ULONG ulSelection;
  1114. POINT pt;
  1115. //
  1116. // Build the shortcut menu depending on whether path is
  1117. // disabled or enabled.
  1118. //
  1119. ZeroMemory( &menuItemInfo,
  1120. sizeof(MENUITEMINFOW) );
  1121. menuItemInfo.cbSize = sizeof( MENUITEMINFOW );
  1122. menuItemInfo.fMask = MIIM_TYPE | MIIM_ID;
  1123. menuItemInfo.fType = MFT_STRING;
  1124. menuItemInfo.fState = MFS_ENABLED;
  1125. if ( fEnabled ) {
  1126. menuItemInfo.dwTypeData = MENUITEM_DISABLE;
  1127. menuItemInfo.wID = IDI_DISABLE;
  1128. }
  1129. else {
  1130. menuItemInfo.dwTypeData = MENUITEM_ENABLE;
  1131. menuItemInfo.wID = IDI_ENABLE;
  1132. }
  1133. SetMenuItemInfoW( hBindingPathSubMenu,
  1134. 0,
  1135. TRUE,
  1136. &menuItemInfo );
  1137. GetCursorPos( &pt );
  1138. ulSelection = (ULONG)TrackPopupMenu( hBindingPathSubMenu,
  1139. TPM_RIGHTALIGN | TPM_BOTTOMALIGN |
  1140. TPM_NONOTIFY | TPM_RETURNCMD |
  1141. TPM_RIGHTBUTTON,
  1142. pt.x,
  1143. pt.y,
  1144. 0,
  1145. hwndOwner,
  1146. NULL );
  1147. if ( ulSelection ) {
  1148. //
  1149. // Do the selected action.
  1150. //
  1151. HandleBindingPathOperation( hwndOwner,
  1152. ulSelection,
  1153. hItem,
  1154. lParam );
  1155. }
  1156. return;
  1157. }
  1158. //
  1159. // Function: GetItemInfo
  1160. //
  1161. // Purpose: Returns information about an item.
  1162. //
  1163. // Arguments:
  1164. // hwndTree [in] Window handle of the tree.
  1165. // hItem [in] Item handle.
  1166. // lParam [out] lParam
  1167. // lpdwItemType [out] Type, binding path or network component.
  1168. // fEnabled [out] TRUE if the binding path or component is enabled.
  1169. //
  1170. // Returns: TRUE on sucess.
  1171. //
  1172. // Notes:
  1173. //
  1174. BOOL GetItemInfo (HWND hwndTree,
  1175. HTREEITEM hItem,
  1176. LPARAM *lParam,
  1177. LPDWORD lpdwItemType,
  1178. BOOL *fEnabled)
  1179. {
  1180. TVITEMW tvItem;
  1181. int iImage;
  1182. BOOL fSuccess;
  1183. fSuccess = FALSE;
  1184. //
  1185. // Get item's information.
  1186. //
  1187. ZeroMemory( &tvItem,
  1188. sizeof(TVITEMW) );
  1189. tvItem.hItem = hItem;
  1190. tvItem.mask = TVIF_PARAM | TVIF_IMAGE | TVIF_STATE;
  1191. tvItem.stateMask = TVIS_OVERLAYMASK ;
  1192. if ( TreeView_GetItem(hwndTree,
  1193. &tvItem) ) {
  1194. *lParam = tvItem.lParam;
  1195. if ( SetupDiGetClassImageIndex(&ClassImageListData,
  1196. &GUID_DEVCLASS_SYSTEM,
  1197. &iImage) ) {
  1198. //
  1199. // Is it a binding path?
  1200. //
  1201. if ( tvItem.iImage == iImage ) {
  1202. *lpdwItemType = ITEM_NET_BINDINGS;
  1203. *fEnabled = !(TVIS_OVERLAYMASK & tvItem.state);
  1204. fSuccess = TRUE;
  1205. }
  1206. else {
  1207. //
  1208. // Item is a network component.
  1209. //
  1210. if ( SetupDiGetClassImageIndex(&ClassImageListData,
  1211. &GUID_DEVCLASS_NET,
  1212. &iImage) ) {
  1213. if ( tvItem.iImage == iImage ) {
  1214. *lpdwItemType = ITEM_NET_ADAPTERS;
  1215. }
  1216. else {
  1217. *lpdwItemType = ITEM_NET_COMPONENTS;
  1218. }
  1219. *fEnabled = !(TVIS_OVERLAYMASK & tvItem.state);
  1220. fSuccess = TRUE;
  1221. }
  1222. else {
  1223. ErrMsg( HRESULT_FROM_WIN32(GetLastError()),
  1224. L"Couldn't load the images of network adapters." );
  1225. }
  1226. }
  1227. }
  1228. else {
  1229. ErrMsg( HRESULT_FROM_WIN32(GetLastError()),
  1230. L"Couldn't load the images of system devices." );
  1231. }
  1232. }
  1233. return fSuccess;
  1234. }
  1235. //
  1236. // Function: AddBindNameToTree
  1237. //
  1238. // Purpose: Adds an item representing the binding path.
  1239. //
  1240. // Arguments:
  1241. // pncbp [in] Binding path to add.
  1242. // hwndTree [in] Tree handle.
  1243. // hParent [in] Parent item.
  1244. // ulIndex [in] Index of the binding path.
  1245. //
  1246. // Returns: Handle of the item added on success, otherwise NULL.
  1247. //
  1248. // Notes:
  1249. //
  1250. HTREEITEM AddBindNameToTree (INetCfgBindingPath *pncbp,
  1251. HWND hwndTree,
  1252. HTREEITEM hParent,
  1253. ULONG ulIndex)
  1254. {
  1255. WCHAR lpszBindName[40];
  1256. LPWSTR lpszPathToken;
  1257. HTREEITEM hTreeItem;
  1258. TV_INSERTSTRUCTW tvInsertStruc;
  1259. HRESULT hr;
  1260. hTreeItem = NULL;
  1261. //
  1262. // Store the path token as lParam.
  1263. //
  1264. hr = pncbp->GetPathToken( &lpszPathToken );
  1265. if ( hr == S_OK ) {
  1266. swprintf( lpszBindName, L"Binding Path %d", ulIndex );
  1267. ZeroMemory(
  1268. &tvInsertStruc,
  1269. sizeof(TV_INSERTSTRUCTW) );
  1270. tvInsertStruc.hParent = hParent;
  1271. tvInsertStruc.hInsertAfter = TVI_LAST;
  1272. tvInsertStruc.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE |
  1273. TVIF_SELECTEDIMAGE | TVIF_STATE;
  1274. tvInsertStruc.item.pszText = lpszBindName;
  1275. tvInsertStruc.item.cchTextMax = wcslen( lpszBindName ) + sizeof(WCHAR);
  1276. SetupDiGetClassImageIndex( &ClassImageListData,
  1277. &GUID_DEVCLASS_SYSTEM,
  1278. &tvInsertStruc.item.iImage );
  1279. tvInsertStruc.item.iSelectedImage = tvInsertStruc.item.iImage;
  1280. tvInsertStruc.item.stateMask = TVIS_OVERLAYMASK;
  1281. if ( pncbp->IsEnabled() == S_FALSE ) {
  1282. tvInsertStruc.item.state = INDEXTOOVERLAYMASK(
  1283. IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST + 1);
  1284. }
  1285. tvInsertStruc.item.lParam = (LPARAM)lpszPathToken;
  1286. hTreeItem = TreeView_InsertItem( hwndTree,
  1287. &tvInsertStruc );
  1288. if ( !hTreeItem ) {
  1289. ErrMsg( hr,
  1290. L"Couldn't add the binding path %d to the list."
  1291. L" The binding path will not be shown.", ulIndex );
  1292. CoTaskMemFree( lpszPathToken );
  1293. }
  1294. }
  1295. else {
  1296. ErrMsg( hr,
  1297. L"Couldn't get the PathToken of the binding path %d."
  1298. L" The binding path will not be shown.", ulIndex );
  1299. }
  1300. return hTreeItem;
  1301. }
  1302. //
  1303. // Function: AddToTree
  1304. //
  1305. // Purpose: Adds an item representing the network component.
  1306. //
  1307. // Arguments:
  1308. // hwndTree [in] Tree handle.
  1309. // hParent [in] Parent item.
  1310. // pncc [in] Network component.
  1311. //
  1312. // Returns: Handle of the item added on success, otherwise NULL.
  1313. //
  1314. // Notes:
  1315. //
  1316. HTREEITEM AddToTree (HWND hwndTree,
  1317. HTREEITEM hParent,
  1318. INetCfgComponent *pncc)
  1319. {
  1320. LPWSTR lpszItemName;
  1321. LPWSTR lpszId;
  1322. GUID guidClass;
  1323. BOOL fEnabled;
  1324. ULONG ulStatus;
  1325. HTREEITEM hTreeItem;
  1326. TV_INSERTSTRUCTW tvInsertStruc;
  1327. HRESULT hr;
  1328. hTreeItem = NULL;
  1329. hr = pncc->GetDisplayName( &lpszItemName );
  1330. if ( hr == S_OK ) {
  1331. //
  1332. // Get the inf id of the network component. We store it at lParam
  1333. // and use it later to retrieve its interface pointer.
  1334. //
  1335. hr = pncc->GetId( &lpszId );
  1336. if ( hr == S_OK ) {
  1337. //
  1338. // If it is a network adapter then, find out if it enabled/disabled.
  1339. //
  1340. hr = pncc->GetClassGuid( &guidClass );
  1341. if ( hr == S_OK ) {
  1342. if ( IsEqualGUID(guidClass, GUID_DEVCLASS_NET) ) {
  1343. hr = pncc->GetDeviceStatus( &ulStatus );
  1344. fEnabled = ulStatus == 0;
  1345. }
  1346. else {
  1347. fEnabled = TRUE;
  1348. }
  1349. }
  1350. else {
  1351. //
  1352. // We can't get the status, so assume that it is disabled.
  1353. //
  1354. fEnabled = FALSE;
  1355. }
  1356. ZeroMemory(
  1357. &tvInsertStruc,
  1358. sizeof(TV_INSERTSTRUCTW) );
  1359. tvInsertStruc.hParent = hParent;
  1360. tvInsertStruc.hInsertAfter = TVI_LAST;
  1361. tvInsertStruc.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE |
  1362. TVIF_SELECTEDIMAGE | TVIF_STATE;
  1363. tvInsertStruc.item.pszText = lpszItemName;
  1364. tvInsertStruc.item.cchTextMax = wcslen( lpszItemName ) + sizeof(WCHAR);
  1365. SetupDiGetClassImageIndex( &ClassImageListData,
  1366. &guidClass,
  1367. &tvInsertStruc.item.iImage );
  1368. tvInsertStruc.item.iSelectedImage = tvInsertStruc.item.iImage;
  1369. tvInsertStruc.item.stateMask = TVIS_OVERLAYMASK;
  1370. if ( fEnabled == FALSE ) {
  1371. tvInsertStruc.item.state = INDEXTOOVERLAYMASK(
  1372. IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST + 1);
  1373. }
  1374. tvInsertStruc.item.lParam = (LPARAM)lpszId;
  1375. hTreeItem = TreeView_InsertItem( hwndTree,
  1376. &tvInsertStruc );
  1377. if ( !hTreeItem ) {
  1378. ErrMsg( hr,
  1379. L"Failed to add %s to the list.",
  1380. lpszItemName );
  1381. CoTaskMemFree( lpszId );
  1382. }
  1383. }
  1384. else {
  1385. ErrMsg( hr,
  1386. L"Couldn't get the inf id of %s."
  1387. L" It will not be added to the list.",
  1388. lpszItemName );
  1389. }
  1390. CoTaskMemFree( lpszItemName );
  1391. }
  1392. else {
  1393. ErrMsg( hr,
  1394. L"Couldn't get the display name of a network component."
  1395. L" It will not be added to the list." );
  1396. }
  1397. return hTreeItem;
  1398. }
  1399. //
  1400. // Function: RefreshAll
  1401. //
  1402. // Purpose: Refreshes the main dialog box.
  1403. //
  1404. // Arguments:
  1405. // hwndDlg [in] Dialog box handle.
  1406. //
  1407. // Returns: None.
  1408. //
  1409. // Notes:
  1410. //
  1411. VOID RefreshAll (HWND hwndDlg)
  1412. {
  1413. HWND hwndTypeList;
  1414. INT iSelected;
  1415. //
  1416. // Find the selected network component type.
  1417. //
  1418. hwndTypeList = GetDlgItem( hwndDlg,
  1419. IDL_COMPONENT_TYPES );
  1420. iSelected = (int)SendMessage( hwndTypeList,
  1421. CB_GETCURSEL,
  1422. 0,
  1423. 0 );
  1424. if ( iSelected != CB_ERR ) {
  1425. //
  1426. // Before deleting the list in the tree, free the buffer
  1427. // associated with each item. The buffer holds either the
  1428. // INF Id or the pathtoken depending on whether it is a
  1429. // network component or a binding path.
  1430. //
  1431. ReleaseMemory( GetDlgItem(hwndDlg, IDT_BINDINGS),
  1432. TVI_ROOT );
  1433. TreeView_DeleteItem (
  1434. GetDlgItem(hwndDlg, IDT_BINDINGS),
  1435. TVI_ROOT );
  1436. //
  1437. // Repopulate the tree with the selected network compnent
  1438. // type.
  1439. //
  1440. EnumNetBindings( GetDlgItem(hwndDlg, IDT_BINDINGS),
  1441. (UINT)iSelected );
  1442. }
  1443. return;
  1444. }
  1445. //
  1446. // Function: RefreshItemState
  1447. //
  1448. // Purpose: Refreshes the specified item.
  1449. //
  1450. // Arguments:
  1451. // hwndTree [in] Dialog box handle.
  1452. // hItem [in] Item to refresh.
  1453. // fEnable [in] TRUE if component is enabled.
  1454. //
  1455. // Returns: None.
  1456. //
  1457. // Notes:
  1458. //
  1459. VOID RefreshItemState (HWND hwndTree,
  1460. HTREEITEM hItem,
  1461. BOOL fEnable)
  1462. {
  1463. TVITEMW tvItem;
  1464. ZeroMemory( &tvItem,
  1465. sizeof(TVITEMW) );
  1466. tvItem.hItem = hItem;
  1467. tvItem.mask = TVIF_STATE;
  1468. tvItem.stateMask = TVIS_OVERLAYMASK;
  1469. if ( fEnable )
  1470. tvItem.state = INDEXTOOVERLAYMASK( 0 );
  1471. else
  1472. tvItem.state = INDEXTOOVERLAYMASK(
  1473. IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST + 1);
  1474. TreeView_SetItem( hwndTree,
  1475. &tvItem );
  1476. return;
  1477. }
  1478. //
  1479. // Function: RefreshBindings
  1480. //
  1481. // Purpose: Refreshes bindings of a specific component.
  1482. //
  1483. // Arguments:
  1484. // hwndBindUnBindDlg [in] Dialog box handle.
  1485. // lpszInfId [in] PnpID of the component whose bindings changed.
  1486. //
  1487. // Returns: None.
  1488. //
  1489. // Notes:
  1490. //
  1491. VOID RefreshBindings (HWND hwndBindUnBindDlg,
  1492. LPWSTR lpszInfId)
  1493. {
  1494. INetCfg *pnc;
  1495. INetCfgComponent *pncc;
  1496. HWND hwndParent;
  1497. HWND hwndTree;
  1498. HTREEITEM hItem;
  1499. HRESULT hr;
  1500. hwndParent = GetParent( hwndBindUnBindDlg );
  1501. hwndTree = GetDlgItem( hwndParent,
  1502. IDT_BINDINGS );
  1503. hItem = TreeView_GetSelection( hwndTree );
  1504. hr = HrGetINetCfg( FALSE,
  1505. APP_NAME,
  1506. &pnc,
  1507. NULL );
  1508. if ( hr == S_OK ) {
  1509. hr = pnc->FindComponent( lpszInfId,
  1510. &pncc );
  1511. if ( hr == S_OK ) {
  1512. //
  1513. // Delete all the children.
  1514. //
  1515. ReleaseMemory( hwndTree,
  1516. hItem );
  1517. DeleteChildren( hwndTree,
  1518. hItem );
  1519. ListBindings( pncc,
  1520. hwndTree,
  1521. hItem );
  1522. ReleaseRef( pncc );
  1523. }
  1524. HrReleaseINetCfg( pnc,
  1525. FALSE );
  1526. }
  1527. return;
  1528. }
  1529. //
  1530. // Function: ReleaseMemory
  1531. //
  1532. // Purpose: Free memory associated with each item in the tree.
  1533. //
  1534. // Arguments:
  1535. // hwndTree [in] Tree handle.
  1536. // hTreeItem [in] Root item.
  1537. //
  1538. // Returns: None.
  1539. //
  1540. // Notes:
  1541. //
  1542. // Each node of the tree represents a network component or a binding path.
  1543. // At each node, lParam points to an allocated buffer wherein we store the
  1544. // inf id if it is a network component or pathtoken name if it is a binding
  1545. // path.
  1546. //
  1547. //
  1548. VOID ReleaseMemory (HWND hwndTree,
  1549. HTREEITEM hTreeItem)
  1550. {
  1551. HTREEITEM hItemChild;
  1552. TVITEMW tvItem;
  1553. hItemChild = TreeView_GetChild( hwndTree,
  1554. hTreeItem );
  1555. while ( hItemChild ) {
  1556. ZeroMemory(
  1557. &tvItem,
  1558. sizeof(TVITEMW) );
  1559. tvItem.hItem = hItemChild;
  1560. tvItem.mask = TVIF_PARAM;
  1561. TreeView_GetItem( hwndTree,
  1562. &tvItem );
  1563. //
  1564. // It should never be NULL but just in case...
  1565. //
  1566. if ( tvItem.lParam ) {
  1567. CoTaskMemFree( (LPVOID)tvItem.lParam );
  1568. }
  1569. ReleaseMemory( hwndTree, hItemChild );
  1570. hItemChild = TreeView_GetNextSibling( hwndTree,
  1571. hItemChild );
  1572. }
  1573. return;
  1574. }
  1575. //
  1576. // Function: DeleteChildren
  1577. //
  1578. // Purpose: Delete childen of a specific item.
  1579. //
  1580. // Arguments:
  1581. // hwndTree [in] Tree handle.
  1582. // hTreeItem [in] Parent item.
  1583. //
  1584. // Returns: None.
  1585. //
  1586. // Notes:
  1587. //
  1588. VOID DeleteChildren (HWND hwndTree,
  1589. HTREEITEM hTreeItem)
  1590. {
  1591. HTREEITEM hItemChild;
  1592. HTREEITEM hItemSibling;
  1593. hItemChild = TreeView_GetChild( hwndTree,
  1594. hTreeItem );
  1595. while ( hItemChild ) {
  1596. DeleteChildren( hwndTree,
  1597. hItemChild );
  1598. hItemSibling = TreeView_GetNextSibling( hwndTree,
  1599. hItemChild );
  1600. TreeView_DeleteItem( hwndTree,
  1601. hItemChild );
  1602. hItemChild = hItemSibling;
  1603. }
  1604. return;
  1605. }
  1606. //
  1607. // Function: InsertItem
  1608. //
  1609. // Purpose: Insert text for each network component type.
  1610. //
  1611. // Arguments:
  1612. // hwndTree [in] Tree handle.
  1613. // uiType [in] Item type, protocol, client, service.
  1614. //
  1615. // Returns: Item handle on success, otherwise NULL.
  1616. //
  1617. // Notes:
  1618. //
  1619. HTREEITEM InsertItem (HWND hwndTree,
  1620. UINT uiType)
  1621. {
  1622. TV_INSERTSTRUCTW tvInsertStruc;
  1623. ZeroMemory(
  1624. &tvInsertStruc,
  1625. sizeof(TV_INSERTSTRUCTW) );
  1626. tvInsertStruc.hParent = TVI_ROOT;
  1627. tvInsertStruc.hInsertAfter = TVI_LAST;
  1628. tvInsertStruc.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE |
  1629. TVIF_SELECTEDIMAGE;
  1630. switch( uiType ) {
  1631. case CLIENTS_SELECTED:
  1632. tvInsertStruc.item.pszText = L"Client";
  1633. break;
  1634. case SERVICES_SELECTED:
  1635. tvInsertStruc.item.pszText = L"Service";
  1636. break;
  1637. default:
  1638. tvInsertStruc.item.pszText = L"Protocol";
  1639. break;
  1640. }
  1641. tvInsertStruc.item.cchTextMax = wcslen( tvInsertStruc.item.pszText ) +
  1642. sizeof(WCHAR);
  1643. SetupDiGetClassImageIndex( &ClassImageListData,
  1644. pguidNetClass[uiType],
  1645. &tvInsertStruc.item.iImage );
  1646. tvInsertStruc.item.iSelectedImage = tvInsertStruc.item.iImage;
  1647. tvInsertStruc.item.lParam = (LPARAM)uiType;
  1648. return TreeView_InsertItem( hwndTree,
  1649. &tvInsertStruc );
  1650. }
  1651. //
  1652. // Function: UpdateComponentTypeList
  1653. //
  1654. // Purpose: Insert text for each network component type.
  1655. //
  1656. // Arguments:
  1657. // hwndTypeList [in] ListView handle.
  1658. //
  1659. // Returns: TRUE on success.
  1660. //
  1661. // Notes:
  1662. //
  1663. BOOL UpdateComponentTypeList (HWND hwndTypeList)
  1664. {
  1665. UINT i;
  1666. for (i=0; i < 3; ++i) {
  1667. SendMessage( hwndTypeList,
  1668. CB_ADDSTRING,
  1669. (WPARAM)0,
  1670. (LPARAM)lpszNetClass[i] );
  1671. }
  1672. SendMessage( hwndTypeList,
  1673. CB_SETCURSEL,
  1674. (WPARAM)DEFAULT_COMPONENT_SELECTED,
  1675. (LPARAM)0 );
  1676. return TRUE;
  1677. }
  1678. //
  1679. // Function: ErrMsg
  1680. //
  1681. // Purpose: Insert text for each network component type.
  1682. //
  1683. // Arguments:
  1684. // hr [in] Error code.
  1685. //
  1686. // Returns: None.
  1687. //
  1688. // Notes:
  1689. //
  1690. VOID ErrMsg (HRESULT hr,
  1691. LPCWSTR lpFmt,
  1692. ...)
  1693. {
  1694. LPWSTR lpSysMsg;
  1695. WCHAR buf[400];
  1696. ULONG offset;
  1697. va_list vArgList;
  1698. if ( hr != 0 ) {
  1699. swprintf( buf,
  1700. L"Error %#lx: ",
  1701. hr );
  1702. }
  1703. else {
  1704. buf[0] = 0;
  1705. }
  1706. offset = wcslen( buf );
  1707. va_start( vArgList,
  1708. lpFmt );
  1709. vswprintf( buf+offset,
  1710. lpFmt,
  1711. vArgList );
  1712. va_end( vArgList );
  1713. if ( hr != 0 ) {
  1714. FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1715. FORMAT_MESSAGE_FROM_SYSTEM |
  1716. FORMAT_MESSAGE_IGNORE_INSERTS,
  1717. NULL,
  1718. hr,
  1719. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1720. (LPWSTR)&lpSysMsg,
  1721. 0,
  1722. NULL );
  1723. if ( lpSysMsg ) {
  1724. offset = wcslen( buf );
  1725. swprintf( buf+offset,
  1726. L"\n\nPossible cause:\n\n" );
  1727. offset = wcslen( buf );
  1728. wcscat( buf+offset,
  1729. lpSysMsg );
  1730. LocalFree( (HLOCAL)lpSysMsg );
  1731. }
  1732. MessageBoxW( NULL,
  1733. buf,
  1734. L"Error",
  1735. MB_ICONERROR | MB_OK );
  1736. }
  1737. else {
  1738. MessageBoxW( NULL,
  1739. buf,
  1740. L"BindView",
  1741. MB_ICONINFORMATION | MB_OK );
  1742. }
  1743. return;
  1744. }