|
|
//+---------------------------------------------------------------------------
//
// 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 (HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int 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, NULL, L"Select a file name", OFN_DONTADDTORECENT | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT, lpszFile) ) {
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 righ-click.
//
ProcessRightClick( lpnm );
//
// Tell Windows that the righ-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 compoents.
//
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 opration,
// 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) ) {
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 ); } } 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 compoents 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 ); } } 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 (LPWSTR lpszFile) { FILE *fp;
fp = _wfopen( lpszFile, L"w" );
if ( 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, LPWSTR lpszInfFile) { HWND hwndTree; HTREEITEM hItem; LPARAM lParam; HCURSOR hPrevCursor; HCURSOR hWaitCursor; HWND hwndFocus; 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();
EnableWindow( hwndTree, FALSE ); EnableWindow( GetDlgItem(hwndDlg,IDB_OK), FALSE ); EnableWindow( GetDlgItem(hwndDlg,IDB_CLOSE), FALSE ); hWaitCursor = LoadCursor( NULL, IDC_WAIT ); if ( hWaitCursor ) { hPrevCursor = SetCursor( hWaitCursor ); }
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( hwndTree, 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( hwndTree, 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_OK), 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 (LPWSTR lpszInfFile, 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 ( hr == S_OK ) {
//
// 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, LPCWSTR lpszSection, LPCWSTR lpszKey, DWORD dwIndex, LPWSTR *lppszValue) { INFCONTEXT infCtx; DWORD dwSizeNeeded; HRESULT hr;
*lppszValue = NULL;
if ( SetupFindFirstLineW(hInf, lpszSection, lpszKey, &infCtx) == FALSE ) { return HRESULT_FROM_WIN32(GetLastError()); }
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; }
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; HTREEITEM hItem; LPARAM lParam; HCURSOR hPrevCursor; HCURSOR hWaitCursor; 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 ); }
//
// Uninstall the selected component.
//
hr = UninstallComponent( (LPWSTR)lParam );
if ( hWaitCursor ) { SetCursor( hPrevCursor ); }
switch( hr ) {
case S_OK: MessageBoxW( hwndTree, 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( hwndTree, 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 ); } } }
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 [in] See documentation for GetOpenFileName.
//
// Returns: See documentation for GetOpenFileName.
//
// Notes:
//
BOOL GetFileName (HWND hwndDlg, LPWSTR lpszFilter, LPWSTR lpszTitle, DWORD dwFlags, LPWSTR lpszFile) { OPENFILENAMEW ofn; lpszFile[0] = NULL;
ZeroMemory( &ofn, sizeof(OPENFILENAMEW) ); ofn.lStructSize = sizeof(OPENFILENAMEW); ofn.hwndOwner = hwndDlg; ofn.lpstrFilter = lpszFilter; ofn.lpstrFile = lpszFile; ofn.nMaxFile = MAX_PATH+1; ofn.lpstrTitle = lpszTitle; ofn.Flags = dwFlags;
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 ) {
swprintf( 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;
tvInsertStruc.item.cchTextMax = wcslen( lpszBindName ) + sizeof(WCHAR);
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) { 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 of the network component. We store it at lParam
// and use it later to retrieve its interface pointer.
//
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;
tvInsertStruc.item.cchTextMax = wcslen( lpszItemName ) + sizeof(WCHAR);
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, 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; }
tvInsertStruc.item.cchTextMax = wcslen( tvInsertStruc.item.pszText ) + sizeof(WCHAR);
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; WCHAR buf[400]; ULONG offset; va_list vArgList;
if ( hr != 0 ) { swprintf( buf, L"Error %#lx: ", hr ); } else { buf[0] = 0; }
offset = wcslen( buf ); va_start( vArgList, lpFmt ); vswprintf( 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 );
swprintf( buf+offset, L"\n\nPossible cause:\n\n" );
offset = wcslen( buf );
wcscat( 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; }
|