You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
575 lines
15 KiB
575 lines
15 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: A C B I N D . C P P
|
|
//
|
|
// Contents: Advanced configuration bindings dialog implementation
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: danielwe 18 Nov 1997
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include "acbind.h"
|
|
#include "achelp.h"
|
|
#include "acsheet.h"
|
|
#include "connutil.h"
|
|
#include "lancmn.h"
|
|
#include "ncnetcfg.h"
|
|
#include "ncsetup.h"
|
|
#include "ncui.h"
|
|
#include "netconp.h"
|
|
#include "order.h"
|
|
|
|
|
|
const DWORD g_aHelpIDs_IDD_ADVCFG_Bindings[]=
|
|
{
|
|
LVW_Adapters, IDH_Adapters,
|
|
PSB_Adapter_Up, IDH_Adapter_Up,
|
|
PSB_Adapter_Down, IDH_Adapter_Down,
|
|
TVW_Bindings, IDH_Bindings,
|
|
PSB_Binding_Up, IDH_Binding_Up,
|
|
IDH_Binding_Down, PSB_Binding_Down,
|
|
0,0
|
|
};
|
|
|
|
extern const WCHAR c_szNetCfgHelpFile[];
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBindingsDlg::~CBindingsDlg
|
|
//
|
|
// Purpose: Destructor for the Advanced configuration dialog
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// Author: danielwe 26 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
CBindingsDlg::~CBindingsDlg()
|
|
{
|
|
if (m_hiconUpArrow)
|
|
{
|
|
DeleteObject(m_hiconUpArrow);
|
|
}
|
|
if (m_hiconDownArrow)
|
|
{
|
|
DeleteObject(m_hiconDownArrow);
|
|
}
|
|
|
|
if (m_hilItemIcons)
|
|
{
|
|
ImageList_Destroy(m_hilItemIcons);
|
|
}
|
|
|
|
if (m_hilCheckIcons)
|
|
{
|
|
ImageList_Destroy(m_hilCheckIcons);
|
|
}
|
|
|
|
ReleaseObj(m_pnc);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBindingsDlg::OnInitDialog
|
|
//
|
|
// Purpose: Called when the WM_INITDIALOG is received
|
|
//
|
|
// Arguments:
|
|
// uMsg []
|
|
// wParam []
|
|
// lParam []
|
|
// bHandled []
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: danielwe 19 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
LRESULT CBindingsDlg::OnInitDialog(UINT uMsg, WPARAM wParam,
|
|
LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
INT iaci;
|
|
RECT rc;
|
|
LV_COLUMN lvc = {0};
|
|
SP_CLASSIMAGELIST_DATA cid;
|
|
|
|
m_hwndLV = GetDlgItem(LVW_Adapters);
|
|
m_hwndTV = GetDlgItem(TVW_Bindings);
|
|
|
|
// Make this initially invisible in case we don't have any adapters
|
|
::ShowWindow(GetDlgItem(IDH_TXT_ADVGFG_BINDINGS), SW_HIDE);
|
|
|
|
hr = HrSetupDiGetClassImageList(&cid);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Create small image lists
|
|
m_hilItemIcons = ImageList_Duplicate(cid.ImageList);
|
|
|
|
// Add the LAN connection icon to the image list
|
|
HICON hIcon = LoadIcon(_Module.GetResourceInstance(),
|
|
MAKEINTRESOURCE(IDI_LB_GEN_S_16));
|
|
Assert(hIcon);
|
|
|
|
// Add the icon
|
|
m_nIndexLan = ImageList_AddIcon(m_hilItemIcons, hIcon);
|
|
|
|
ListView_SetImageList(m_hwndLV, m_hilItemIcons, LVSIL_SMALL);
|
|
TreeView_SetImageList(m_hwndTV, m_hilItemIcons, TVSIL_NORMAL);
|
|
|
|
(void) HrSetupDiDestroyClassImageList(&cid);
|
|
}
|
|
|
|
::GetClientRect(m_hwndLV, &rc);
|
|
lvc.mask = LVCF_FMT | LVCF_WIDTH;
|
|
lvc.fmt = LVCFMT_LEFT;
|
|
lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
|
|
ListView_InsertColumn(m_hwndLV, 0, &lvc);
|
|
|
|
if (!m_hiconUpArrow && !m_hiconDownArrow)
|
|
{
|
|
m_hiconUpArrow = (HICON)LoadImage(_Module.GetResourceInstance(),
|
|
MAKEINTRESOURCE(IDI_UP_ARROW),
|
|
IMAGE_ICON, 16, 16, 0);
|
|
m_hiconDownArrow = (HICON)LoadImage(_Module.GetResourceInstance(),
|
|
MAKEINTRESOURCE(IDI_DOWN_ARROW),
|
|
IMAGE_ICON, 16, 16, 0);
|
|
}
|
|
|
|
SendDlgItemMessage(PSB_Adapter_Up, BM_SETIMAGE, IMAGE_ICON,
|
|
reinterpret_cast<LPARAM>(m_hiconUpArrow));
|
|
SendDlgItemMessage(PSB_Adapter_Down, BM_SETIMAGE, IMAGE_ICON,
|
|
reinterpret_cast<LPARAM>(m_hiconDownArrow));
|
|
SendDlgItemMessage(PSB_Binding_Up, BM_SETIMAGE, IMAGE_ICON,
|
|
reinterpret_cast<LPARAM>(m_hiconUpArrow));
|
|
SendDlgItemMessage(PSB_Binding_Down, BM_SETIMAGE, IMAGE_ICON,
|
|
reinterpret_cast<LPARAM>(m_hiconDownArrow));
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = HrBuildAdapterList();
|
|
}
|
|
|
|
// Create state image lists
|
|
m_hilCheckIcons = ImageList_LoadBitmapAndMirror(
|
|
_Module.GetResourceInstance(),
|
|
MAKEINTRESOURCE(IDB_CHECKSTATE),
|
|
16,
|
|
0,
|
|
PALETTEINDEX(6));
|
|
TreeView_SetImageList(m_hwndTV, m_hilCheckIcons, TVSIL_STATE);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
SetWindowLong(DWLP_MSGRESULT, PSNRET_INVALID);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBindingsDlg::OnContextMenu
|
|
//
|
|
// Purpose: Called in response to the WM_CONTEXTMENU message
|
|
//
|
|
// Arguments:
|
|
// uMsg []
|
|
// wParam []
|
|
// lParam []
|
|
// bHandled []
|
|
//
|
|
// Returns: 0 always
|
|
//
|
|
// Author: danielwe 22 Jan 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
LRESULT CBindingsDlg::OnContextMenu(UINT uMsg, WPARAM wParam,
|
|
LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
::WinHelp(m_hWnd,
|
|
c_szNetCfgHelpFile,
|
|
HELP_CONTEXTMENU,
|
|
reinterpret_cast<ULONG_PTR>(g_aHelpIDs_IDD_ADVCFG_Bindings));
|
|
|
|
return 0;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBindingsDlg::OnHelp
|
|
//
|
|
// Purpose: Called in response to the WM_HELP message
|
|
//
|
|
// Arguments:
|
|
// uMsg []
|
|
// wParam []
|
|
// lParam []
|
|
// bHandled []
|
|
//
|
|
// Returns: TRUE
|
|
//
|
|
// Author: danielwe 19 Mar 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
LRESULT CBindingsDlg::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam,
|
|
BOOL& bHandled)
|
|
{
|
|
LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
|
|
|
|
if (HELPINFO_WINDOW == lphi->iContextType)
|
|
{
|
|
::WinHelp(static_cast<HWND>(lphi->hItemHandle),
|
|
c_szNetCfgHelpFile,
|
|
HELP_WM_HELP,
|
|
reinterpret_cast<ULONG_PTR>(g_aHelpIDs_IDD_ADVCFG_Bindings));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBindingsDlg::OnOk
|
|
//
|
|
// Purpose: Called when the OK button is pressed
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: danielwe 19 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
LRESULT CBindingsDlg::OnOk(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
|
|
{
|
|
CWaitCursor wc;
|
|
|
|
HRESULT hr = m_pnc->Apply();
|
|
|
|
if (NETCFG_S_REBOOT == hr)
|
|
{
|
|
// On a reboot, uninitialize NetCfg since we won't be leaving
|
|
// this function.
|
|
//
|
|
(VOID) m_pnc->Uninitialize();
|
|
|
|
(VOID) HrNcQueryUserForReboot(_Module.GetResourceInstance(),
|
|
m_hWnd,
|
|
IDS_ADVCFG_CAPTION,
|
|
IDS_REBOOT_REQUIRED,
|
|
QUFR_PROMPT | QUFR_REBOOT);
|
|
}
|
|
|
|
// Normalize result
|
|
if (S_FALSE == hr)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("CBindingsDlg::OnOk", hr);
|
|
return LresFromHr(hr);
|
|
}
|
|
|
|
//
|
|
// Binding list implementation
|
|
//
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSortableBindPath::operator <
|
|
//
|
|
// Purpose: Provides comparison operator for binding path depth
|
|
//
|
|
// Arguments:
|
|
// refsbp [in] Reference to bind path to compare with
|
|
//
|
|
// Returns: TRUE if given bind path depth is greater than this one
|
|
//
|
|
// Author: danielwe 26 Nov 1997
|
|
//
|
|
// Notes: The comparison is backwards on purpose so that sorting is
|
|
// done is descending order.
|
|
//
|
|
bool CSortableBindPath::operator<(const CSortableBindPath &refsbp) const
|
|
{
|
|
DWORD dwLen1;
|
|
DWORD dwLen2;
|
|
|
|
GetDepth(&dwLen1);
|
|
refsbp.GetDepth(&dwLen2);
|
|
|
|
// yes this is greater than because we want to sort in descending order
|
|
return dwLen1 > dwLen2;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FIsHidden
|
|
//
|
|
// Purpose: Returns TRUE if the given component has the NCF_HIDDEN
|
|
// characterstic.
|
|
//
|
|
// Arguments:
|
|
// pncc [in] Component to be checked
|
|
//
|
|
// Returns: TRUE if component is hidden, FALSE if not
|
|
//
|
|
// Author: danielwe 26 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FIsHidden(INetCfgComponent *pncc)
|
|
{
|
|
DWORD dwFlags;
|
|
|
|
return (SUCCEEDED(pncc->GetCharacteristics(&dwFlags)) &&
|
|
((dwFlags & NCF_HIDE_BINDING) || (dwFlags & NCF_HIDDEN)));
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FDontExposeLower
|
|
//
|
|
// Purpose: Returns TRUE if the given component has the NCF_DONTEXPOSELOWER
|
|
// characterstic.
|
|
//
|
|
// Arguments:
|
|
// pncc [in] Component to be checked
|
|
//
|
|
// Returns: TRUE if component has DONTEXPOSELOWER, FALSE if not
|
|
//
|
|
// Author: danielwe 26 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FDontExposeLower(INetCfgComponent *pncc)
|
|
{
|
|
DWORD dwFlags;
|
|
|
|
return (SUCCEEDED(pncc->GetCharacteristics(&dwFlags)) &&
|
|
(dwFlags & NCF_DONTEXPOSELOWER));
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrCountDontExposeLower
|
|
//
|
|
// Purpose: Counts the number of components in the given binding path
|
|
// that have the NCF_DONTEXPOSELOWER characterstic.
|
|
//
|
|
// Arguments:
|
|
// pncbp [in] Binding path to count
|
|
// pcItems[out] Number of components in the binding path that have the
|
|
// NCF_DONTEXPOSELOWER characterstic.
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error otherwise
|
|
//
|
|
// Author: danielwe 1 Dec 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrCountDontExposeLower(INetCfgBindingPath *pncbp, DWORD *pcItems)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CIterNetCfgBindingInterface ncbiIter(pncbp);
|
|
INetCfgBindingInterface * pncbi;
|
|
DWORD cItems = 0;
|
|
DWORD cIter = 0;
|
|
|
|
Assert(pcItems);
|
|
|
|
*pcItems = 0;
|
|
|
|
while (SUCCEEDED(hr) && S_OK == (hr = ncbiIter.HrNext(&pncbi)))
|
|
{
|
|
INetCfgComponent * pncc;
|
|
|
|
if (!cIter)
|
|
{
|
|
// First iteration. Get upper component first.
|
|
hr = pncbi->GetUpperComponent(&pncc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (FDontExposeLower(pncc))
|
|
{
|
|
cItems++;
|
|
}
|
|
|
|
ReleaseObj(pncc);
|
|
}
|
|
}
|
|
|
|
hr = pncbi->GetLowerComponent(&pncc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (FDontExposeLower(pncc))
|
|
{
|
|
cItems++;
|
|
}
|
|
|
|
ReleaseObj(pncc);
|
|
}
|
|
|
|
ReleaseObj(pncbi);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*pcItems = cItems;
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("HrCountDontExposeLower", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FEqualComponents
|
|
//
|
|
// Purpose: Compares the given 2 components to see if they are the same
|
|
//
|
|
// Arguments:
|
|
// pnccA [in] First component to compare
|
|
// pnccB [in] Second component to compare
|
|
//
|
|
// Returns: TRUE if components are the same, FALSE if not
|
|
//
|
|
// Author: danielwe 1 Dec 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FEqualComponents(INetCfgComponent *pnccA, INetCfgComponent *pnccB)
|
|
{
|
|
GUID guidA;
|
|
GUID guidB;
|
|
|
|
if (SUCCEEDED(pnccA->GetInstanceGuid(&guidA)) &&
|
|
SUCCEEDED(pnccB->GetInstanceGuid(&guidB)))
|
|
{
|
|
return (guidA == guidB);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Debug functions
|
|
//
|
|
|
|
#ifdef ENABLETRACE
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: DbgDumpBindPath
|
|
//
|
|
// Purpose: Dumps the given binding path in an easy to read format
|
|
//
|
|
// Arguments:
|
|
// pncbp [in] Bind path to dump
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// Author: danielwe 26 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID DbgDumpBindPath(INetCfgBindingPath *pncbp)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
tstring strPath;
|
|
INetCfgBindingInterface * pncbi;
|
|
INetCfgComponent * pncc = NULL;
|
|
PWSTR pszwCompId;
|
|
|
|
if ((!pncbp) || IsBadReadPtr((CONST VOID *)pncbp,
|
|
sizeof(INetCfgBindingPath *)))
|
|
{
|
|
TraceTag(ttidAdvCfg, "Bind path is invalid!");
|
|
return;
|
|
}
|
|
|
|
CIterNetCfgBindingInterface ncbiIter(pncbp);
|
|
|
|
while (SUCCEEDED(hr) && S_OK == (hr = ncbiIter.HrNext(&pncbi)))
|
|
{
|
|
if (strPath.empty())
|
|
{
|
|
hr = pncbi->GetUpperComponent(&pncc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pncc->GetId(&pszwCompId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
strPath = pszwCompId;
|
|
CoTaskMemFree(pszwCompId);
|
|
}
|
|
ReleaseObj(pncc);
|
|
pncc = NULL;
|
|
}
|
|
}
|
|
hr = pncbi->GetLowerComponent(&pncc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pncc->GetId(&pszwCompId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
strPath += L" -> ";
|
|
strPath += pszwCompId;
|
|
|
|
CoTaskMemFree(pszwCompId);
|
|
}
|
|
ReleaseObj(pncc);
|
|
}
|
|
ReleaseObj(pncbi);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
TraceTag(ttidAdvCfg, "Address = 0x%08lx, Path is '%S'",
|
|
pncbp, strPath.c_str());
|
|
}
|
|
else
|
|
{
|
|
TraceTag(ttidAdvCfg, "Error dumping binding path.");
|
|
}
|
|
|
|
}
|
|
|
|
VOID DbgDumpTreeViewItem(HWND hwndTV, HTREEITEM hti)
|
|
{
|
|
WCHAR szText[256];
|
|
TV_ITEM tvi;
|
|
|
|
if (hti)
|
|
{
|
|
tvi.hItem = hti;
|
|
tvi.pszText = szText;
|
|
tvi.cchTextMax = celems(szText);
|
|
tvi.mask = TVIF_TEXT;
|
|
TreeView_GetItem(hwndTV, &tvi);
|
|
|
|
TraceTag(ttidAdvCfg, "TreeView item is %S.", szText);
|
|
}
|
|
else
|
|
{
|
|
TraceTag(ttidAdvCfg, "TreeView item is NULL");
|
|
}
|
|
}
|
|
|
|
#endif //ENABLETRACE
|