diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /network/config/bindview/BINDVIEW.CPP | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'network/config/bindview/BINDVIEW.CPP')
| -rw-r--r-- | network/config/bindview/BINDVIEW.CPP | 2336 |
1 files changed, 2336 insertions, 0 deletions
diff --git a/network/config/bindview/BINDVIEW.CPP b/network/config/bindview/BINDVIEW.CPP new file mode 100644 index 00000000..4231f7c4 --- /dev/null +++ b/network/config/bindview/BINDVIEW.CPP @@ -0,0 +1,2336 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 2001. +// +// File: B I N D V I E W . C P P +// +// Contents: +// +// Notes: +// +// Author: Alok Sinha 15-Amy-01 +// +//---------------------------------------------------------------------------- + + +#include "BindView.h" + +//---------------------------------------------------------------------------- +// Globals +// + +// +// Image list for devices of various setup class. +// + +SP_CLASSIMAGELIST_DATA ClassImageListData; + +HINSTANCE hInstance; +HMENU hMainMenu; +HMENU hComponentSubMenu; +HMENU hBindingPathSubMenu; + +// +// Network components whose bindings are enumerated. +// + +LPWSTR lpszNetClass[] = { + L"All Clients", + L"All Services", + L"All Protocols" + }; + +// +// GUIDs of network components. +// + +const GUID *pguidNetClass [] = { + &GUID_DEVCLASS_NETCLIENT, + &GUID_DEVCLASS_NETSERVICE, + &GUID_DEVCLASS_NETTRANS, + &GUID_DEVCLASS_NET + }; + +// +// Program entry point. +// + +int APIENTRY +WinMain ( + _In_ HINSTANCE hInst, + _In_opt_ HINSTANCE hPrevInstance, + _In_ LPSTR lpCmdLine, + _In_ int nCmdShow ) +{ + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + UNREFERENCED_PARAMETER(nCmdShow); + + // + // Make sure common control DLL is loaded. + // + + hInstance = hInst; + + InitCommonControls(); + + if ( DialogBoxW(hInst, + MAKEINTRESOURCEW(IDD_MAIN), + NULL, + MainDlgProc) == -1 ) { + + ErrMsg( HRESULT_FROM_WIN32(GetLastError()), + L"Failed to create the main dialog box, exiting..." ); + } + + return 0; +} + +// +// WndProc for the main dialog box. +// + +INT_PTR CALLBACK MainDlgProc (HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + HWND hwndBindingTree; + HICON hIcon; + + switch (uMsg) { + + case WM_INITDIALOG: + + hIcon = LoadIcon( hInstance, + MAKEINTRESOURCE(IDI_BINDVIEW) ); + + if ( !hIcon ) { + ErrMsg( HRESULT_FROM_WIN32(GetLastError()), + L"Couldn't load the program icon, exiting..." ); + + return FALSE; + } + + SetClassLongPtr( hwndDlg, + GCLP_HICON, + (LONG_PTR)hIcon ); + + hMainMenu = LoadMenu( hInstance, + MAKEINTRESOURCE(IDM_OPTIONS) ); + + if ( !hMainMenu ) { + + ErrMsg( HRESULT_FROM_WIN32(GetLastError()), + L"Couldn't load the program menu, exiting..." ); + + return FALSE; + } + + hComponentSubMenu = GetSubMenu( hMainMenu, + 0 ); + + hBindingPathSubMenu = GetSubMenu( hMainMenu, + 1 ); + + if ( !hComponentSubMenu || !hBindingPathSubMenu ) { + + ErrMsg( HRESULT_FROM_WIN32(GetLastError()), + L"Couldn't load the program menu, exiting..." ); + + DestroyMenu( hMainMenu ); + return FALSE; + } + + // + // Add the network components types whose bindings are shown. + // + + UpdateComponentTypeList( GetDlgItem(hwndDlg, + IDL_COMPONENT_TYPES) ); + + // + // Load and associate the image list of all device classes with + // tree. + // + + hwndBindingTree = GetDlgItem( hwndDlg, + IDT_BINDINGS ); + + ZeroMemory( &ClassImageListData, sizeof(SP_CLASSIMAGELIST_DATA) ); + ClassImageListData.cbSize = sizeof(SP_CLASSIMAGELIST_DATA); + + if ( SetupDiGetClassImageList(&ClassImageListData) == TRUE ) { + + TreeView_SetImageList( hwndBindingTree, + ClassImageListData.ImageList, + LVSIL_NORMAL ); + } + else { + + // + // In case, we failed to load the image list, abort. + // + + ErrMsg( HRESULT_FROM_WIN32(GetLastError()), + L"Couldn't load the image list of " + L"device classes, exiting..." ); + + DestroyMenu( hMainMenu ); + return FALSE; + } + + // + // Enumerate the bindings of the network component selected by default. + // + + EnumNetBindings( hwndBindingTree, + DEFAULT_COMPONENT_SELECTED ); + + return TRUE; // Tell Windows to continue creating the dialog box. + + case WM_COMMAND: + + switch( LOWORD(wParam) ) { + + case IDL_COMPONENT_TYPES: + + if ( HIWORD(wParam) == CBN_SELCHANGE ) { + + // + // User has selected a new network component type. + // + + RefreshAll( hwndDlg ); + } + + break; + + case IDB_EXPAND_ALL: + case IDB_COLLAPSE_ALL: + + if ( HIWORD(wParam) == BN_CLICKED ) { + + HTREEITEM hItem; + // + // Expand/Collapse the entire tree. + // + + hwndBindingTree = GetDlgItem( hwndDlg, + IDT_BINDINGS ); + + hItem = TreeView_GetSelection( hwndBindingTree ); + + ExpandCollapseAll( hwndBindingTree, + TVI_ROOT, + (LOWORD(wParam) == IDB_EXPAND_ALL) ? + TVE_EXPAND : TVE_COLLAPSE ); + + TreeView_SelectSetFirstVisible( hwndBindingTree, + hItem ); + } + + break; + + case IDB_SAVE: + + if ( HIWORD(wParam) == BN_CLICKED ) { + + // + // Save the binding information to a file. + // + + WCHAR lpszFile[MAX_PATH+1]; + + if ( GetFileName(hwndDlg, + L"Text files (*.txt)\0*.txt\0", + L"Select a file name", + OFN_DONTADDTORECENT | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT, + lpszFile, + L"txt", + TRUE) ) { + + DumpBindings( lpszFile ); + } + } + + break; + + case IDB_INSTALL: + + if ( HIWORD(wParam) == BN_CLICKED ) { + + // + // Install a network component. + // + + if ( (BOOL)DialogBoxW(hInstance, + MAKEINTRESOURCEW(IDD_INSTALL), + hwndDlg, + InstallDlg) == TRUE ) { + + RefreshAll( hwndDlg ); + } + } + + break; + + case IDB_UNINSTALL: + + if ( HIWORD(wParam) == BN_CLICKED ) { + + // + // Uninstall a network component. + // + + if ( (BOOL)DialogBoxW(hInstance, + MAKEINTRESOURCEW(IDD_UNINSTALL), + hwndDlg, + UninstallDlg) == TRUE ) { + + RefreshAll( hwndDlg ); + } + } + } + + break; + + case WM_NOTIFY: + { + LPNMHDR lpnm; + + lpnm = (LPNMHDR)lParam; + + if ( (lpnm->idFrom == IDT_BINDINGS) && + (lpnm->code == NM_RCLICK) ) { + + // + // A network component or a binding path is selected + // with a right-click. + // + + ProcessRightClick( lpnm ); + + // + // Tell Windows that the right-click has been handled + // us. + // + + return TRUE; + } + } + break; + + case WM_SYSCOMMAND: + + if ( (0xFFF0 & wParam) == SC_CLOSE ) { + + // + // Before exiting, make sure to delete the image list + // and the buffers associated with each item in the tree. + // + + SetupDiDestroyClassImageList( &ClassImageListData ); + + ReleaseMemory( GetDlgItem(hwndDlg, IDT_BINDINGS), + TVI_ROOT ); + + DestroyMenu( hMainMenu ); + EndDialog( hwndDlg, 0 ); + } + } + + return FALSE; +} + +// +// WndProc of the dialog box for binding/unbinding components. +// + +INT_PTR CALLBACK BindComponentDlg (HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + LPBIND_UNBIND_INFO lpBindUnbind; + + switch (uMsg) { + + case WM_INITDIALOG: + { + DWORD dwCount; + + // + // Save the lParam which is an index to the selected network + // component. + // + + SetWindowLongPtr( hwndDlg, + DWLP_USER, + (LONG_PTR)lParam ); + + lpBindUnbind = (LPBIND_UNBIND_INFO)lParam; + + // + // fBindTo is TRUE when the user wants to bind the selected + // component to other components. So, we list the components + // that are not bound and can bind. + // + // + // fBindTo is FALSE when the user wants to unbind the selected + // component from other components. So, we list the components + // that are bound to it. + // + // + // ListCompToBindUnbind returns number of components added to + // the list. Keep track of it. If it zero then, we don't want to + // show this dialog box. + // + + dwCount = ListCompToBindUnbind( + lpBindUnbind->lpszInfId, + ADAPTERS_SELECTED, + GetDlgItem(hwndDlg, IDT_COMPONENT_LIST), + lpBindUnbind->fBindTo == FALSE ); + + dwCount += ListCompToBindUnbind( + lpBindUnbind->lpszInfId, + CLIENTS_SELECTED, + GetDlgItem(hwndDlg, IDT_COMPONENT_LIST), + lpBindUnbind->fBindTo == FALSE ); + + dwCount += ListCompToBindUnbind( + lpBindUnbind->lpszInfId, + SERVICES_SELECTED, + GetDlgItem(hwndDlg, IDT_COMPONENT_LIST), + lpBindUnbind->fBindTo == FALSE ); + + dwCount += ListCompToBindUnbind( + lpBindUnbind->lpszInfId, + PROTOCOLS_SELECTED, + GetDlgItem(hwndDlg, IDT_COMPONENT_LIST), + lpBindUnbind->fBindTo == FALSE ); + + if ( dwCount > 0 ) { + + // + // Since the same dialog box is used for unbind operation, + // we need to update the text on the button to reflect that + // it is a bind operation. + // + + if ( lpBindUnbind->fBindTo == FALSE ) { + + SetWindowTextW( hwndDlg, + L"Unbind From Network Components" ); + + SetWindowTextW( GetDlgItem(hwndDlg, IDB_BIND_UNBIND), + L"Unbind" ); + + SetWindowTextW( GetDlgItem(hwndDlg, IDG_COMPONENT_LIST), + L"Select components to unbind from" ); + } + } + else { + if ( lpBindUnbind->fBindTo == TRUE ) { + ErrMsg( 0, + L"There no network components that can " + L"bind to the selected component." ); + } + else { + ErrMsg( 0, + L"There no network components that are " + L"bound to the selected component." ); + } + + PostMessage( hwndDlg, WM_NO_COMPONENTS, 0, 0 ); + } + + return TRUE; + } + + case WM_NO_COMPONENTS: + EndDialog( hwndDlg, 0 ); + break; + + case WM_COMMAND: + + if ( (LOWORD(wParam) == IDB_CLOSE) && + (HIWORD(wParam) == BN_CLICKED) ) { + + // + // Before deleting the list in the tree, free the buffer + // associated with each item. The buffer holds the + // INF Id of network components. + // + + ReleaseMemory( GetDlgItem(hwndDlg, IDT_COMPONENT_LIST), + TVI_ROOT ); + + EndDialog( hwndDlg, 0 ); + } + else { + + // + // User wants to bind/unbind. + // + + if ( (LOWORD(wParam) == IDB_BIND_UNBIND) && + (HIWORD(wParam) == BN_CLICKED) ) { + + + + lpBindUnbind = (LPBIND_UNBIND_INFO)GetWindowLongPtr( hwndDlg, + DWLP_USER ); + + if ( BindUnbind(lpBindUnbind->lpszInfId, + GetDlgItem(hwndDlg, IDT_COMPONENT_LIST), + lpBindUnbind->fBindTo) ) { + + RefreshBindings( hwndDlg, + lpBindUnbind->lpszInfId ); + } + + ReleaseMemory( GetDlgItem(hwndDlg, IDT_COMPONENT_LIST), + TVI_ROOT ); + EndDialog( hwndDlg, 0 ); + } + } + break; + + case WM_SYSCOMMAND: + + if ( (0xFFF0 & wParam) == SC_CLOSE ) { + + // + // Before deleting the list in the tree, free the buffer + // associated with each item. The buffer holds the + // INF Id of network components. + // + + ReleaseMemory( GetDlgItem(hwndDlg, IDT_COMPONENT_LIST), + TVI_ROOT ); + + EndDialog( hwndDlg, 0 ); + } + } + + return FALSE; +} + +// +//WndProc of the dialog box for installing network components. +// + +INT_PTR CALLBACK InstallDlg (HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) { + + case WM_INITDIALOG: + { + HWND hwndTree; + + // + // List types of network components e.g. client, + // protocol and service. + // + + hwndTree = GetDlgItem( hwndDlg, + IDT_COMPONENT_LIST ); + + TreeView_SetImageList( hwndTree, + ClassImageListData.ImageList, + LVSIL_NORMAL ); + + // + // Insert and select client by default. + // + + TreeView_Select( hwndTree, + InsertItem(hwndTree, + CLIENTS_SELECTED), + TVGN_CARET ); + + InsertItem( hwndTree, + SERVICES_SELECTED ); + + InsertItem( hwndTree, + PROTOCOLS_SELECTED ); + + // + // Initialize it to FALSE. It will be set to TRUE when + // at least one component is installed. + // + + SetWindowLongPtr( hwndDlg, + DWLP_USER, + (LONG_PTR)FALSE ); + return TRUE; + } + + case WM_COMMAND: + + switch( LOWORD(wParam) ) { + + case IDB_INSTALL: + + // + // Install from Windows system directory. + // + + if ( HIWORD(wParam) == BN_CLICKED ) { + + InstallSelectedComponentType( hwndDlg, NULL ); + } + break; + + case IDB_BROWSE: + + // + // User wants to specify an INF file for the network + // to install. + // + if ( HIWORD(wParam) == BN_CLICKED ) { + + WCHAR lpszInfFile[MAX_PATH+1]; + + if ( GetFileName(hwndDlg, + L"INF files (*.inf)\0*.inf\0", + L"Select the INF file of the network component to install", + OFN_DONTADDTORECENT | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST, + lpszInfFile, + NULL, + FALSE) ) { + + InstallSelectedComponentType( hwndDlg, + lpszInfFile ); + } + } + break; + + case IDB_CLOSE: + + if ( HIWORD(wParam) == BN_CLICKED ) { + + // + // Return the value of DWLP_USER to indicate whether one or + // more components have been installed. Accordingly, the + // the list will be refreshed. + // + + EndDialog( hwndDlg, + GetWindowLongPtr(hwndDlg, DWLP_USER) ); + } + } + break; + + case WM_NOTIFY: + { + LPNMHDR lpnm; + + lpnm = (LPNMHDR)lParam; + + if ( (lpnm->idFrom == IDT_COMPONENT_LIST) && + (lpnm->code == NM_DBLCLK) ) { + + // + // On double-click, install from Windows system directory. + // + + InstallSelectedComponentType( hwndDlg, NULL ); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); + return TRUE; + } + } + break; + + case WM_SYSCOMMAND: + + if ( (0xFFF0 & wParam) == SC_CLOSE ) { + + // + // Return the value of DWLP_USER to indicate whether one or + // more components have been installed. Accordingly, the + // the list will be refreshed. + // + + EndDialog( hwndDlg, + GetWindowLongPtr(hwndDlg, DWLP_USER) ); + } + } + + return FALSE; +} + +// +// WndProc of the dialog box for uninstalling a network component. +// + +INT_PTR CALLBACK UninstallDlg (HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + HWND hwndTree; + + switch (uMsg) { + + case WM_INITDIALOG: + + hwndTree = GetDlgItem( hwndDlg, + IDT_COMPONENT_LIST ); + TreeView_SetImageList( hwndTree, + ClassImageListData.ImageList, + LVSIL_NORMAL ); + + // + // List all the components currently installed. + // + + ListInstalledComponents( hwndTree, + &GUID_DEVCLASS_NETCLIENT); + ListInstalledComponents( hwndTree, + &GUID_DEVCLASS_NETSERVICE ); + ListInstalledComponents( hwndTree, + &GUID_DEVCLASS_NETTRANS ); + + // + // Initialize it to FALSE. It will be set to TRUE when + // at least one component is installed. + // + + SetWindowLongPtr( hwndDlg, + DWLP_USER, + (LONG_PTR)FALSE ); + return TRUE; + + case WM_COMMAND: + + switch( LOWORD(wParam) ) { + + case IDB_REMOVE: + + if ( HIWORD(wParam) == BN_CLICKED ) { + + // + // Uninstall the selected component. + // + + UninstallSelectedComponent( hwndDlg ); + + } + break; + + case IDB_CLOSE: + + if ( HIWORD(wParam) == BN_CLICKED ) { + + hwndTree = GetDlgItem( hwndDlg, + IDT_COMPONENT_LIST ); + ReleaseMemory( hwndTree, + TVI_ROOT ); + + // + // Return the value of DWLP_USER to indicate whether one or + // more components have been installed. Accordingly, the + // the list will be refreshed. + // + + EndDialog( hwndDlg, + GetWindowLongPtr(hwndDlg, DWLP_USER) ); + } + } + + break; + + case WM_NOTIFY: + { + LPNMHDR lpnm; + + lpnm = (LPNMHDR)lParam; + + if ( (lpnm->idFrom == IDT_COMPONENT_LIST) && + (lpnm->code == NM_DBLCLK) ) { + + UninstallSelectedComponent( hwndDlg ); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); + return TRUE; + } + } + break; + + case WM_SYSCOMMAND: + + if ( (0xFFF0 & wParam) == SC_CLOSE ) { + + hwndTree = GetDlgItem( hwndDlg, + IDT_COMPONENT_LIST ); + ReleaseMemory( hwndTree, + TVI_ROOT ); + + // + // Return the value of DWLP_USER to indicate whether one or + // more components have been installed. Accordingly, the + // the list will be refreshed. + // + + EndDialog( hwndDlg, + GetWindowLongPtr(hwndDlg, DWLP_USER) ); + } + } + + return FALSE; +} + +//+--------------------------------------------------------------------------- +// +// Function: DumpBindings +// +// Purpose: Write the binding information. +// +// Arguments: +// lpszFile [in] Name of the file in which to write. +// +// Returns: None +// +// Notes: +// + +VOID +DumpBindings ( + _In_ LPWSTR lpszFile) +{ + FILE *fp; + errno_t err; + + err = _wfopen_s( &fp, + lpszFile, + L"w" ); + + if ( err != 0 || fp == NULL ) { + + ErrMsg( 0, + L"Unable to open %s.", + lpszFile ); + } + else { + WriteBindings( fp ); + + fclose( fp ); + } + + return; +} + +// +// Function: InstallSelectedComponentType +// +// Purpose: Install a network component. +// +// Arguments: +// hwndDlg [in] Handle to Install dialog box. +// lpszInfFile [in] Inf file of the network component. +// +// Returns: None +// +// Notes: +// If lpszInfFile is NULL, network components are installed from the +// system directory. +// + +VOID +InstallSelectedComponentType ( + HWND hwndDlg, + _In_opt_ LPWSTR lpszInfFile) +{ + HWND hwndTree = NULL; + HTREEITEM hItem = NULL; + LPARAM lParam; + HCURSOR hPrevCursor = NULL; + HCURSOR hWaitCursor = NULL; + HWND hwndFocus = NULL; + DWORD dwType; + BOOL fEnable; + HRESULT hr; + + hwndTree = GetDlgItem( hwndDlg, + IDT_COMPONENT_LIST ); + + // + // Find out the type of component selected. + // + + hItem = TreeView_GetSelection( hwndTree ); + + if ( hItem ) { + if ( GetItemInfo( hwndTree, + hItem, + &lParam, + &dwType, + &fEnable) ) { + + // + // Disable the install dialog controls. + // + + hwndFocus = GetFocus(); + + hWaitCursor = LoadCursor( NULL, + IDC_WAIT ); + if ( hWaitCursor ) { + hPrevCursor = SetCursor( hWaitCursor ); + } + + EnableWindow( hwndTree, FALSE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_INSTALL), + FALSE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_BROWSE), + FALSE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_CLOSE), + FALSE ); + + if ( lpszInfFile ) { + + LPWSTR lpszPnpID; + + // + // Inf file name specified, install the network component + // from this file. + // + + hr = GetPnpID( lpszInfFile, &lpszPnpID ); + + if ( hr == S_OK ) { + + hr = InstallSpecifiedComponent( lpszInfFile, + lpszPnpID, + pguidNetClass[(UINT)lParam] ); + + CoTaskMemFree( lpszPnpID ); + } + else { + ErrMsg( hr, + L"Error reading the INF file %s.", + lpszInfFile ); + } + } + else { + + // + // Install from system directory. + // + + hr = InstallComponent( hwndTree, + pguidNetClass[(UINT)lParam] ); + } + + if ( hWaitCursor ) { + SetCursor( hPrevCursor ); + } + + switch( hr ) { + + case S_OK: + MessageBoxW( + hwndDlg, + L"Component installed successfully.", + L"Network Component Installation", + MB_OK | MB_ICONINFORMATION ); + SetWindowLongPtr( hwndDlg, + DWLP_USER, + (LONG_PTR)TRUE ); + break; + + case NETCFG_S_REBOOT: + MessageBoxW( + hwndDlg, + L"Component installed successfully: " + L"Reboot required.", + L"Network Component Installation", + MB_OK | MB_ICONINFORMATION ); + SetWindowLongPtr( hwndDlg, + DWLP_USER, + (LONG_PTR)TRUE ); + + } + + // + // Enable the install dialog controls. + // + + EnableWindow( hwndTree, TRUE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_INSTALL), + TRUE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_BROWSE), + TRUE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_CLOSE), + TRUE ); + + SetFocus( hwndFocus ); + } + } + + return; +} + +// +// Function: GetPnpID +// +// Purpose: Retrieve PnpID from an inf file. +// +// Arguments: +// lpszInfFile [in] Inf file to search. +// lppszPnpID [out] PnpID found. +// +// Returns: TRUE on success. +// +// Notes: +// + +HRESULT +GetPnpID ( + _In_ LPWSTR lpszInfFile, + _Outptr_ LPWSTR *lppszPnpID) +{ + HINF hInf; + LPWSTR lpszModelSection; + HRESULT hr; + + *lppszPnpID = NULL; + + hInf = SetupOpenInfFileW( lpszInfFile, + NULL, + INF_STYLE_WIN4, + NULL ); + + if ( hInf == INVALID_HANDLE_VALUE ) + { + + return HRESULT_FROM_WIN32(GetLastError()); + } + + // + // Read the Model section name from Manufacturer section. + // + + hr = GetKeyValue( hInf, + L"Manufacturer", + NULL, + 1, + &lpszModelSection ); + + if ( SUCCEEDED(hr) ) + { + + // + // Read PnpID from the Model section. + // + + hr = GetKeyValue( hInf, + lpszModelSection, + NULL, + 2, + lppszPnpID ); + + CoTaskMemFree( lpszModelSection ); + } + + SetupCloseInfFile( hInf ); + + return hr; +} + +// +// Function: GetKeyValue +// +// Purpose: Retrieve the value of a key from the inf file. +// +// Arguments: +// hInf [in] Inf file handle. +// lpszSection [in] Section name. +// lpszKey [in] Key name. +// dwIndex [in] Key index. +// lppszValue [out] Key value. +// +// Returns: S_OK on success, otherwise and error code. +// +// Notes: +// + +HRESULT +GetKeyValue ( + HINF hInf, + _In_ LPCWSTR lpszSection, + _In_opt_ LPCWSTR lpszKey, + DWORD dwIndex, + _Outptr_ LPWSTR *lppszValue) +{ + INFCONTEXT infCtx; + __range(0, 512) DWORD dwSizeNeeded; + HRESULT hr; + + *lppszValue = NULL; + + if ( SetupFindFirstLineW(hInf, + lpszSection, + lpszKey, + &infCtx) == FALSE ) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + if ( SetupGetStringFieldW(&infCtx, + dwIndex, + NULL, + 0, + &dwSizeNeeded) ) + { + *lppszValue = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded ); + + if ( !*lppszValue ) + { + return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + + if ( SetupGetStringFieldW(&infCtx, + dwIndex, + *lppszValue, + dwSizeNeeded, + NULL) == FALSE ) + { + + hr = HRESULT_FROM_WIN32(GetLastError()); + + CoTaskMemFree( *lppszValue ); + *lppszValue = NULL; + } + else + { + hr = S_OK; + } + } + else + { + DWORD dwErr = GetLastError(); + hr = HRESULT_FROM_WIN32(dwErr); + } + + return hr; +} + +// +// Function: UninstallSelectedComponent +// +// Purpose: Uninstall the selected network component. +// +// Arguments: +// hwndDlg [in] Window handle of the uninstall dialog box. +// +// Returns: TRUE on success. +// +// Notes: +// + +VOID UninstallSelectedComponent (HWND hwndDlg) +{ + HWND hwndTree = NULL; + HTREEITEM hItem = NULL; + LPARAM lParam; + HCURSOR hPrevCursor = NULL; + HCURSOR hWaitCursor = NULL; + DWORD dwType; + BOOL fEnable; + HRESULT hr; + + hwndTree = GetDlgItem( hwndDlg, + IDT_COMPONENT_LIST ); + + // + // Get the selected item to get its lParam which is the + // PnpID of the network component. + // + + hItem = TreeView_GetSelection( hwndTree ); + + if ( hItem ) { + if ( GetItemInfo( hwndTree, + hItem, + &lParam, + &dwType, + &fEnable) ) { + + hWaitCursor = LoadCursor( NULL, + IDC_WAIT ); + if ( hWaitCursor ) { + hPrevCursor = SetCursor( hWaitCursor ); + } + + EnableWindow( hwndTree, FALSE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_REMOVE), + FALSE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_CLOSE), + FALSE ); + + // + // Uninstall the selected component. + // + + hr = UninstallComponent( (LPWSTR)lParam ); + + + if ( hWaitCursor ) { + SetCursor( hPrevCursor ); + } + + switch( hr ) { + + case S_OK: + MessageBoxW( + hwndDlg, + L"Uninstallation successful.", + L"Network Component Uninstallation", + MB_OK | MB_ICONINFORMATION ); + + CoTaskMemFree( (LPVOID)lParam ); + TreeView_DeleteItem( hwndTree, + hItem ); + + SetWindowLongPtr( hwndDlg, + DWLP_USER, + (LONG_PTR)TRUE ); + break; + + case NETCFG_S_REBOOT: + MessageBoxW( + hwndDlg, + L"Uninstallation successful: " + L"Reboot required.", + L"Network Component Uninstallation", + MB_OK | MB_ICONINFORMATION ); + + CoTaskMemFree( (LPVOID)lParam ); + TreeView_DeleteItem( hwndTree, + hItem ); + + SetWindowLongPtr( hwndDlg, + DWLP_USER, + (LONG_PTR)TRUE ); + } + + EnableWindow( hwndTree, TRUE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_REMOVE), + TRUE ); + EnableWindow( GetDlgItem(hwndDlg,IDB_CLOSE), + TRUE ); + } + } + + return; +} + +// +// Function: ExpandCollapseAll +// +// Purpose: Expand or collapse a tree. +// +// Arguments: +// hwndTree [in] Window handle of the tree. +// hTreeItem [in] Handle of root item. +// uiFlag [in] Flag indicating whether to expand or collapse. +// +// Returns: None. +// +// Notes: +// + +VOID ExpandCollapseAll (HWND hwndTree, + HTREEITEM hTreeItem, + UINT uiFlag) +{ + HTREEITEM hItemChild; + + hItemChild = TreeView_GetChild( hwndTree, + hTreeItem ); + + if ( hItemChild ) { + + // + // If the root has one or more children, expand/collapse the root. + // + + TreeView_Expand( hwndTree, + hTreeItem, + uiFlag ); + } + + while ( hItemChild ) { + + // + // Expand/collapse all the children. + // + + ExpandCollapseAll( hwndTree, + hItemChild, + uiFlag ); + + // + // Expand/collapse all the siblings. + // + + hItemChild = TreeView_GetNextSibling( hwndTree, + hItemChild ); + } + + return; +} + +// +// Function: GetFileName +// +// Purpose: Prompt for a filename. +// +// Arguments: +// hwndDlg [in] Window handle of the parent. +// lpszFilter [in] See documentation for GetOpenFileName. +// lpszTitle [in] See documentation for GetOpenFileName. +// dwFlags [in] See documentation for GetOpenFileName. +// lpszFile [out] See documentation for GetOpenFileName. +// Supplied buffer must be at least MAX_PATH+1 WCHARS +// +// Returns: See documentation for GetOpenFileName. +// +// Notes: +// + +BOOL +GetFileName ( + HWND hwndDlg, + _In_opt_ LPWSTR lpszFilter, + _In_ LPWSTR lpszTitle, + DWORD dwFlags, + _Out_writes_(MAX_PATH+1) LPWSTR lpszFile, + _In_opt_ LPWSTR lpszDefExt, + BOOL fSave) +{ + OPENFILENAMEW ofn; + + lpszFile[0] = NULL; + + ZeroMemory( &ofn, sizeof(OPENFILENAMEW) ); + ofn.lStructSize = sizeof(OPENFILENAMEW); + ofn.hwndOwner = hwndDlg; + ofn.lpstrFilter = lpszFilter; + ofn.lpstrFile = lpszFile; + ofn.lpstrDefExt = lpszDefExt; + ofn.nMaxFile = MAX_PATH+1; + ofn.lpstrTitle = lpszTitle; + ofn.Flags = dwFlags; + + if ( fSave ) + { + return GetSaveFileName( &ofn ); + } + else + { + return GetOpenFileName( &ofn ); + } +} + +// +// Function: ProcessRightClick +// +// Purpose: Handle righ mouse button click. +// +// Arguments: +// lpnm [in] LPNMHDR info +// +// Returns: None. +// +// Notes: +// + +VOID ProcessRightClick (LPNMHDR lpnm) +{ + HTREEITEM hItemSelected; + LPARAM lParam; + DWORD dwItemType; + BOOL fEnabled; + + // + // Determine the item on which user clicked the right mouse button. + // + + hItemSelected = TreeView_GetDropHilight( lpnm->hwndFrom ); + + if ( !hItemSelected ) { + hItemSelected = TreeView_GetSelection( lpnm->hwndFrom ); + } + else { + + // + // User has right-clicked an unselected item, make that a selected + // item. + // + + TreeView_Select( lpnm->hwndFrom, + hItemSelected, + TVGN_CARET ); + } + + if ( hItemSelected ) { + + // + // Get the lParam of the selected node in the tree which points to inf id or + // pathtoken name depending on if the node represents a network component or + // a binding path. + // + + if ( GetItemInfo(lpnm->hwndFrom, + hItemSelected, + &lParam, + &dwItemType, + &fEnabled) ) { + + if ( dwItemType & ITEM_NET_COMPONENTS ) { + + // + // Show the shortcut menu of operations for a network component. + // + + ShowComponentMenu( lpnm->hwndFrom, + hItemSelected, + lParam); + } + else { + if ( dwItemType & ITEM_NET_BINDINGS ) { + + // + // Show the shortcut menu of operations for a binding path. + // + + ShowBindingPathMenu( lpnm->hwndFrom, + hItemSelected, + lParam, + fEnabled ); + } + } + } + } + + return; +} + +// +// Function: ShowComponentMenu +// +// Purpose: Show shortcut menu of options for a network component. +// +// Arguments: +// hwndOwner [in] Owner window. +// hItem [in] Selected item representing a network component. +// lParam [in] PnpID of the network component. +// +// Returns: None. +// +// Notes: +// + +VOID ShowComponentMenu (HWND hwndOwner, + HTREEITEM hItem, + LPARAM lParam) +{ + ULONG ulSelection; + POINT pt; + + GetCursorPos( &pt ); + ulSelection = (ULONG)TrackPopupMenu( hComponentSubMenu, + TPM_RIGHTALIGN | TPM_BOTTOMALIGN | + TPM_NONOTIFY | TPM_RETURNCMD | + TPM_RIGHTBUTTON, + pt.x, + pt.y, + 0, + hwndOwner, + NULL ); + + if ( ulSelection ) { + + // + // Do the selected action. + // + + HandleComponentOperation( hwndOwner, + ulSelection, + hItem, + lParam ); + } + + return; +} + +// +// Function: ShowBindingPathMenu +// +// Purpose: Show shortcut menu of options for a network component. +// +// Arguments: +// hwndOwner [in] Owner window. +// hItem [in] Selected item representing a binding path. +// lParam [in] PnpID of the network component. +// fEnabled [in] TRUE when the path is enabled. +// +// Returns: None. +// +// Notes: +// + + +VOID ShowBindingPathMenu (HWND hwndOwner, + HTREEITEM hItem, + LPARAM lParam, + BOOL fEnabled) +{ + MENUITEMINFOW menuItemInfo; + ULONG ulSelection; + POINT pt; + + // + // Build the shortcut menu depending on whether path is + // disabled or enabled. + // + + ZeroMemory( &menuItemInfo, + sizeof(MENUITEMINFOW) ); + + menuItemInfo.cbSize = sizeof( MENUITEMINFOW ); + menuItemInfo.fMask = MIIM_TYPE | MIIM_ID; + menuItemInfo.fType = MFT_STRING; + menuItemInfo.fState = MFS_ENABLED; + + if ( fEnabled ) { + menuItemInfo.dwTypeData = MENUITEM_DISABLE; + menuItemInfo.wID = IDI_DISABLE; + } + else { + menuItemInfo.dwTypeData = MENUITEM_ENABLE; + menuItemInfo.wID = IDI_ENABLE; + } + + SetMenuItemInfoW( hBindingPathSubMenu, + 0, + TRUE, + &menuItemInfo ); + + GetCursorPos( &pt ); + ulSelection = (ULONG)TrackPopupMenu( hBindingPathSubMenu, + TPM_RIGHTALIGN | TPM_BOTTOMALIGN | + TPM_NONOTIFY | TPM_RETURNCMD | + TPM_RIGHTBUTTON, + pt.x, + pt.y, + 0, + hwndOwner, + NULL ); + + if ( ulSelection ) { + + // + // Do the selected action. + // + + HandleBindingPathOperation( hwndOwner, + ulSelection, + hItem, + lParam ); + } + + return; +} + +// +// Function: GetItemInfo +// +// Purpose: Returns information about an item. +// +// Arguments: +// hwndTree [in] Window handle of the tree. +// hItem [in] Item handle. +// lParam [out] lParam +// lpdwItemType [out] Type, binding path or network component. +// fEnabled [out] TRUE if the binding path or component is enabled. +// +// Returns: TRUE on sucess. +// +// Notes: +// + +BOOL GetItemInfo (HWND hwndTree, + HTREEITEM hItem, + LPARAM *lParam, + LPDWORD lpdwItemType, + BOOL *fEnabled) +{ + TVITEMW tvItem; + int iImage; + BOOL fSuccess; + + + fSuccess = FALSE; + + // + // Get item's information. + // + + ZeroMemory( &tvItem, + sizeof(TVITEMW) ); + tvItem.hItem = hItem; + tvItem.mask = TVIF_PARAM | TVIF_IMAGE | TVIF_STATE; + tvItem.stateMask = TVIS_OVERLAYMASK ; + + if ( TreeView_GetItem(hwndTree, + &tvItem) ) { + + *lParam = tvItem.lParam; + + if ( SetupDiGetClassImageIndex(&ClassImageListData, + &GUID_DEVCLASS_SYSTEM, + &iImage) ) { + + // + // Is it a binding path? + // + + if ( tvItem.iImage == iImage ) { + *lpdwItemType = ITEM_NET_BINDINGS; + + *fEnabled = !(TVIS_OVERLAYMASK & tvItem.state); + + fSuccess = TRUE; + } + else { + + // + // Item is a network component. + // + + if ( SetupDiGetClassImageIndex(&ClassImageListData, + &GUID_DEVCLASS_NET, + &iImage) ) { + + if ( tvItem.iImage == iImage ) { + *lpdwItemType = ITEM_NET_ADAPTERS; + } + else { + *lpdwItemType = ITEM_NET_COMPONENTS; + } + + *fEnabled = !(TVIS_OVERLAYMASK & tvItem.state); + + fSuccess = TRUE; + } + else { + ErrMsg( HRESULT_FROM_WIN32(GetLastError()), + L"Couldn't load the images of network adapters." ); + } + } + } + else { + ErrMsg( HRESULT_FROM_WIN32(GetLastError()), + L"Couldn't load the images of system devices." ); + } + } + + return fSuccess; +} + +// +// Function: AddBindNameToTree +// +// Purpose: Adds an item representing the binding path. +// +// Arguments: +// pncbp [in] Binding path to add. +// hwndTree [in] Tree handle. +// hParent [in] Parent item. +// ulIndex [in] Index of the binding path. +// +// Returns: Handle of the item added on success, otherwise NULL. +// +// Notes: +// + +HTREEITEM AddBindNameToTree (INetCfgBindingPath *pncbp, + HWND hwndTree, + HTREEITEM hParent, + ULONG ulIndex) +{ + WCHAR lpszBindName[40]; + LPWSTR lpszPathToken; + HTREEITEM hTreeItem; + TV_INSERTSTRUCTW tvInsertStruc; + HRESULT hr; + + hTreeItem = NULL; + + // + // Store the path token as lParam. + // + + hr = pncbp->GetPathToken( &lpszPathToken ); + + if ( hr == S_OK ) { + + StringCchPrintfW (lpszBindName, + celems(lpszBindName), + L"Binding Path %d", + ulIndex ); + + ZeroMemory( + &tvInsertStruc, + sizeof(TV_INSERTSTRUCTW) ); + + tvInsertStruc.hParent = hParent; + + tvInsertStruc.hInsertAfter = TVI_LAST; + + tvInsertStruc.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | + TVIF_SELECTEDIMAGE | TVIF_STATE; + + tvInsertStruc.item.pszText = lpszBindName; + + SetupDiGetClassImageIndex( &ClassImageListData, + &GUID_DEVCLASS_SYSTEM, + &tvInsertStruc.item.iImage ); + + tvInsertStruc.item.iSelectedImage = tvInsertStruc.item.iImage; + + tvInsertStruc.item.stateMask = TVIS_OVERLAYMASK; + + if ( pncbp->IsEnabled() == S_FALSE ) { + tvInsertStruc.item.state = INDEXTOOVERLAYMASK( + IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST + 1); + } + + tvInsertStruc.item.lParam = (LPARAM)lpszPathToken; + + hTreeItem = TreeView_InsertItem( hwndTree, + &tvInsertStruc ); + + if ( !hTreeItem ) { + ErrMsg( hr, + L"Couldn't add the binding path %d to the list." + L" The binding path will not be shown.", ulIndex ); + + CoTaskMemFree( lpszPathToken ); + } + } + else { + ErrMsg( hr, + L"Couldn't get the PathToken of the binding path %d." + L" The binding path will not be shown.", ulIndex ); + } + + return hTreeItem; +} + +// +// Function: AddToTree +// +// Purpose: Adds an item representing the network component. +// +// Arguments: +// hwndTree [in] Tree handle. +// hParent [in] Parent item. +// pncc [in] Network component. +// +// Returns: Handle of the item added on success, otherwise NULL. +// +// Notes: +// + +HTREEITEM AddToTree (HWND hwndTree, + HTREEITEM hParent, + INetCfgComponent *pncc) +{ + return AddToTreeEx( hwndTree, + hParent, + pncc, + FALSE ); +} + +// +// Function: AddToTree +// +// Purpose: Adds an item representing the network component. +// +// Arguments: +// hwndTree [in] Tree handle. +// hParent [in] Parent item. +// pncc [in] Network component. +// fUsePnpId [in] if TRUE, pnp device instance id is used to indentify the component, otherwise inf id. +// +// Returns: Handle of the item added on success, otherwise NULL. +// +// Notes: +// + +HTREEITEM AddToTreeEx (HWND hwndTree, + HTREEITEM hParent, + INetCfgComponent *pncc, + BOOL fUsePnpId) +{ + LPWSTR lpszItemName; + LPWSTR lpszId; + GUID guidClass; + BOOL fEnabled; + ULONG ulStatus; + HTREEITEM hTreeItem; + TV_INSERTSTRUCTW tvInsertStruc; + HRESULT hr; + + hTreeItem = NULL; + + hr = pncc->GetDisplayName( &lpszItemName ); + + if ( hr == S_OK ) { + + // + // Get the inf id or pnp instance id of the network component. We store it at lParam + // and use it later to retrieve its interface pointer. + // + + if ( fUsePnpId ) + { + hr = pncc->GetPnpDevNodeId( &lpszId ); + } + else + { + hr = pncc->GetId( &lpszId ); + } + + if ( hr == S_OK ) { + + // + // If it is a network adapter then, find out if it enabled/disabled. + // + + hr = pncc->GetClassGuid( &guidClass ); + + if ( hr == S_OK ) { + if ( IsEqualGUID(guidClass, GUID_DEVCLASS_NET) ) { + hr = pncc->GetDeviceStatus( &ulStatus ); + fEnabled = ulStatus == 0; + } + else { + fEnabled = TRUE; + } + } + else { + + // + // We can't get the status, so assume that it is disabled. + // + + fEnabled = FALSE; + } + + ZeroMemory( + &tvInsertStruc, + sizeof(TV_INSERTSTRUCTW) ); + + tvInsertStruc.hParent = hParent; + + tvInsertStruc.hInsertAfter = TVI_LAST; + + tvInsertStruc.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | + TVIF_SELECTEDIMAGE | TVIF_STATE; + + tvInsertStruc.item.pszText = lpszItemName; + + SetupDiGetClassImageIndex( &ClassImageListData, + &guidClass, + &tvInsertStruc.item.iImage ); + + tvInsertStruc.item.iSelectedImage = tvInsertStruc.item.iImage; + + tvInsertStruc.item.stateMask = TVIS_OVERLAYMASK; + + if ( fEnabled == FALSE ) { + tvInsertStruc.item.state = INDEXTOOVERLAYMASK( + IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST + 1); + } + + tvInsertStruc.item.lParam = (LPARAM)lpszId; + + hTreeItem = TreeView_InsertItem( hwndTree, + &tvInsertStruc ); + if ( !hTreeItem ) { + ErrMsg( hr, + L"Failed to add %s to the list.", + lpszItemName ); + + CoTaskMemFree( lpszId ); + } + } + else { + ErrMsg( hr, + L"Couldn't get the inf id of %s." + L" It will not be added to the list.", + lpszItemName ); + } + + CoTaskMemFree( lpszItemName ); + } + else { + ErrMsg( hr, + L"Couldn't get the display name of a network component." + L" It will not be added to the list." ); + } + + return hTreeItem; +} + +// +// Function: RefreshAll +// +// Purpose: Refreshes the main dialog box. +// +// Arguments: +// hwndDlg [in] Dialog box handle. +// +// Returns: None. +// +// Notes: +// + +VOID RefreshAll (HWND hwndDlg) +{ + HWND hwndTypeList; + INT iSelected; + + // + // Find the selected network component type. + // + + hwndTypeList = GetDlgItem( hwndDlg, + IDL_COMPONENT_TYPES ); + + iSelected = (int)SendMessage( hwndTypeList, + CB_GETCURSEL, + 0, + 0 ); + + if ( iSelected != CB_ERR ) { + + // + // Before deleting the list in the tree, free the buffer + // associated with each item. The buffer holds either the + // INF Id or the pathtoken depending on whether it is a + // network component or a binding path. + // + + ReleaseMemory( GetDlgItem(hwndDlg, IDT_BINDINGS), + TVI_ROOT ); + + TreeView_DeleteItem ( + GetDlgItem(hwndDlg, IDT_BINDINGS), + TVI_ROOT ); + + // + // Repopulate the tree with the selected network compnent + // type. + // + + EnumNetBindings( GetDlgItem(hwndDlg, IDT_BINDINGS), + (UINT)iSelected ); + + } + + return; +} + +// +// Function: RefreshItemState +// +// Purpose: Refreshes the specified item. +// +// Arguments: +// hwndTree [in] Dialog box handle. +// hItem [in] Item to refresh. +// fEnable [in] TRUE if component is enabled. +// +// Returns: None. +// +// Notes: +// + +VOID RefreshItemState (HWND hwndTree, + HTREEITEM hItem, + BOOL fEnable) +{ + TVITEMW tvItem; + + ZeroMemory( &tvItem, + sizeof(TVITEMW) ); + + tvItem.hItem = hItem; + tvItem.mask = TVIF_STATE; + tvItem.stateMask = TVIS_OVERLAYMASK; + + if ( fEnable ) + tvItem.state = INDEXTOOVERLAYMASK( 0 ); + else + tvItem.state = INDEXTOOVERLAYMASK( + IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST + 1); + TreeView_SetItem( hwndTree, + &tvItem ); + return; +} + +// +// Function: RefreshBindings +// +// Purpose: Refreshes bindings of a specific component. +// +// Arguments: +// hwndBindUnBindDlg [in] Dialog box handle. +// lpszInfId [in] PnpID of the component whose bindings changed. +// +// Returns: None. +// +// Notes: +// + +VOID +RefreshBindings ( + HWND hwndBindUnBindDlg, + _In_ LPWSTR lpszInfId) +{ + INetCfg *pnc; + INetCfgComponent *pncc; + HWND hwndParent; + HWND hwndTree; + HTREEITEM hItem; + HRESULT hr; + + + hwndParent = GetParent( hwndBindUnBindDlg ); + hwndTree = GetDlgItem( hwndParent, + IDT_BINDINGS ); + + hItem = TreeView_GetSelection( hwndTree ); + + hr = HrGetINetCfg( FALSE, + APP_NAME, + &pnc, + NULL ); + + if ( hr == S_OK ) { + + hr = pnc->FindComponent( lpszInfId, + &pncc ); + + if ( hr == S_OK ) { + + // + // Delete all the children. + // + + ReleaseMemory( hwndTree, + hItem ); + + DeleteChildren( hwndTree, + hItem ); + + ListBindings( pncc, + hwndTree, + hItem ); + + ReleaseRef( pncc ); + } + + HrReleaseINetCfg( pnc, + FALSE ); + } + + return; +} + +// +// Function: ReleaseMemory +// +// Purpose: Free memory associated with each item in the tree. +// +// Arguments: +// hwndTree [in] Tree handle. +// hTreeItem [in] Root item. +// +// Returns: None. +// +// Notes: +// +// Each node of the tree represents a network component or a binding path. +// At each node, lParam points to an allocated buffer wherein we store the +// inf id if it is a network component or pathtoken name if it is a binding +// path. +// +// + +VOID ReleaseMemory (HWND hwndTree, + HTREEITEM hTreeItem) +{ + HTREEITEM hItemChild; + TVITEMW tvItem; + + hItemChild = TreeView_GetChild( hwndTree, + hTreeItem ); + + while ( hItemChild ) { + + ZeroMemory( + &tvItem, + sizeof(TVITEMW) ); + + tvItem.hItem = hItemChild; + tvItem.mask = TVIF_PARAM; + + TreeView_GetItem( hwndTree, + &tvItem ); + + // + // It should never be NULL but just in case... + // + + if ( tvItem.lParam ) { + CoTaskMemFree( (LPVOID)tvItem.lParam ); + + } + + ReleaseMemory( hwndTree, hItemChild ); + + hItemChild = TreeView_GetNextSibling( hwndTree, + hItemChild ); + } + + return; +} + +// +// Function: DeleteChildren +// +// Purpose: Delete childen of a specific item. +// +// Arguments: +// hwndTree [in] Tree handle. +// hTreeItem [in] Parent item. +// +// Returns: None. +// +// Notes: +// + +VOID DeleteChildren (HWND hwndTree, + HTREEITEM hTreeItem) +{ + HTREEITEM hItemChild; + HTREEITEM hItemSibling; + + hItemChild = TreeView_GetChild( hwndTree, + hTreeItem ); + + while ( hItemChild ) { + + DeleteChildren( hwndTree, + hItemChild ); + + hItemSibling = TreeView_GetNextSibling( hwndTree, + hItemChild ); + TreeView_DeleteItem( hwndTree, + hItemChild ); + + hItemChild = hItemSibling; + } + + return; +} + +// +// Function: InsertItem +// +// Purpose: Insert text for each network component type. +// +// Arguments: +// hwndTree [in] Tree handle. +// uiType [in] Item type, protocol, client, service. +// +// Returns: Item handle on success, otherwise NULL. +// +// Notes: +// + +HTREEITEM InsertItem (HWND hwndTree, + UINT uiType) +{ + TV_INSERTSTRUCTW tvInsertStruc; + + ZeroMemory( + &tvInsertStruc, + sizeof(TV_INSERTSTRUCTW) ); + + tvInsertStruc.hParent = TVI_ROOT; + + tvInsertStruc.hInsertAfter = TVI_LAST; + + tvInsertStruc.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | + TVIF_SELECTEDIMAGE; + + + switch( uiType ) { + + case CLIENTS_SELECTED: + tvInsertStruc.item.pszText = L"Client"; + break; + + case SERVICES_SELECTED: + tvInsertStruc.item.pszText = L"Service"; + break; + + default: + tvInsertStruc.item.pszText = L"Protocol"; + break; + } + + SetupDiGetClassImageIndex( &ClassImageListData, + pguidNetClass[uiType], + &tvInsertStruc.item.iImage ); + + tvInsertStruc.item.iSelectedImage = tvInsertStruc.item.iImage; + + tvInsertStruc.item.lParam = (LPARAM)uiType; + + return TreeView_InsertItem( hwndTree, + &tvInsertStruc ); + +} + +// +// Function: UpdateComponentTypeList +// +// Purpose: Insert text for each network component type. +// +// Arguments: +// hwndTypeList [in] ListView handle. +// +// Returns: TRUE on success. +// +// Notes: +// + +BOOL UpdateComponentTypeList (HWND hwndTypeList) +{ + UINT i; + + for (i=0; i < 3; ++i) { + SendMessage( hwndTypeList, + CB_ADDSTRING, + (WPARAM)0, + (LPARAM)lpszNetClass[i] ); + } + + SendMessage( hwndTypeList, + CB_SETCURSEL, + (WPARAM)DEFAULT_COMPONENT_SELECTED, + (LPARAM)0 ); + return TRUE; +} + +// +// Function: ErrMsg +// +// Purpose: Insert text for each network component type. +// +// Arguments: +// hr [in] Error code. +// +// Returns: None. +// +// Notes: +// + +VOID ErrMsg (HRESULT hr, + LPCWSTR lpFmt, + ...) +{ + + LPWSTR lpSysMsg = NULL; + WCHAR buf[400]; + size_t offset; + va_list vArgList; + + + if ( hr != 0 ) { + StringCchPrintfW ( buf, + celems(buf), + L"Error %#lx: ", + hr ); + } + else { + buf[0] = 0; + } + + offset = wcslen( buf ); + + va_start( vArgList, + lpFmt ); + StringCchVPrintfW ( buf+offset, + celems(buf) - offset, + lpFmt, + vArgList ); + + va_end( vArgList ); + + if ( hr != 0 ) { + FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + hr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&lpSysMsg, + 0, + NULL ); + if ( lpSysMsg ) { + + offset = wcslen( buf ); + + StringCchPrintfW ( buf+offset, + celems(buf) - offset, + L"\n\nPossible cause:\n\n" ); + + offset = wcslen( buf ); + + StringCchCatW ( buf+offset, + celems(buf) - offset, + lpSysMsg ); + + LocalFree( (HLOCAL)lpSysMsg ); + } + + MessageBoxW( NULL, + buf, + L"Error", + MB_ICONERROR | MB_OK ); + } + else { + MessageBoxW( NULL, + buf, + L"BindView", + MB_ICONINFORMATION | MB_OK ); + } + + return; +} |
