2242 lines
59 KiB
C++
2242 lines
59 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// 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;
|
||
|
}
|