//+--------------------------------------------------------------------------- // // 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(m_hiconUpArrow)); SendDlgItemMessage(PSB_Adapter_Down, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast(m_hiconDownArrow)); SendDlgItemMessage(PSB_Binding_Up, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast(m_hiconUpArrow)); SendDlgItemMessage(PSB_Binding_Down, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast(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(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(lParam); if (HELPINFO_WINDOW == lphi->iContextType) { ::WinHelp(static_cast(lphi->hItemHandle), c_szNetCfgHelpFile, HELP_WM_HELP, reinterpret_cast(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