mirror of https://github.com/tongzx/nt5src
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.
2251 lines
63 KiB
2251 lines
63 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997-1999.
|
|
//
|
|
// File: U T I L. C P P
|
|
//
|
|
// Contents: Utility functions shared within lanui
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include "resource.h"
|
|
#include "ncreg.h"
|
|
#include "ncnetcon.h"
|
|
#include "ncnetcfg.h"
|
|
#include "ncsetup.h"
|
|
#include "lanui.h"
|
|
#include "util.h"
|
|
#include "chklist.h"
|
|
#include "lanuiobj.h"
|
|
#include "ncui.h"
|
|
#include "ndispnp.h"
|
|
#include "ncperms.h"
|
|
#include "ncmisc.h"
|
|
#include "wzcsapi.h"
|
|
#include <raseapif.h>
|
|
#include <raserror.h>
|
|
#include "connutil.h"
|
|
|
|
#define INITGUID
|
|
#include "ncxclsid.h"
|
|
#undef INITGUID
|
|
|
|
extern const WCHAR c_szBiNdisAtm[];
|
|
extern const WCHAR c_szDevice[];
|
|
extern const WCHAR c_szInfId_MS_TCPIP[];
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: HrInitCheckboxListView
|
|
//
|
|
// Purpose: Initialize the list view for checkboxes.
|
|
//
|
|
// Arguments:
|
|
// hwndList[in]: Handle of the list view
|
|
// philStateIcons[out]: Image list for the list view
|
|
// pcild [in,optional] Image list data, created if necessary
|
|
//
|
|
// Returns: HRESULT, Error code.
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT HrInitCheckboxListView(HWND hwndList, HIMAGELIST* philStateIcons, SP_CLASSIMAGELIST_DATA* pcild)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
RECT rc;
|
|
LVCOLUMN lvc = {0};
|
|
HWND hwndHeader;
|
|
|
|
// Create small image lists
|
|
//
|
|
if(NULL == pcild)
|
|
{
|
|
pcild = new SP_CLASSIMAGELIST_DATA;
|
|
if(pcild)
|
|
{
|
|
hr = HrSetupDiGetClassImageList(pcild);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
AssertSz(pcild->ImageList, "No class image list data!");
|
|
|
|
// Save off image list data for use later
|
|
::SetWindowLongPtr(GetParent(hwndList), GWLP_USERDATA,
|
|
reinterpret_cast<LONG_PTR>(pcild));
|
|
}
|
|
else
|
|
{
|
|
TraceError("HrSetupDiGetClassImageList returns failure", hr);
|
|
hr = S_OK;
|
|
|
|
// delete this if we couldn't get the structure
|
|
delete pcild;
|
|
::SetWindowLongPtr(GetParent(hwndList), GWLP_USERDATA, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
ListView_SetImageList(hwndList, pcild->ImageList, LVSIL_SMALL);
|
|
|
|
// Set the shared image lists bit so the caller can destroy the class
|
|
// image lists itself
|
|
//
|
|
DWORD dwStyle = GetWindowLong(hwndList, GWL_STYLE);
|
|
SetWindowLong(hwndList, GWL_STYLE, (dwStyle | LVS_SHAREIMAGELISTS));
|
|
|
|
// Create state image lists
|
|
*philStateIcons = ImageList_LoadBitmapAndMirror(
|
|
_Module.GetResourceInstance(),
|
|
MAKEINTRESOURCE(IDB_CHECKSTATE),
|
|
16,
|
|
0,
|
|
PALETTEINDEX(6));
|
|
ListView_SetImageList(hwndList, *philStateIcons, LVSIL_STATE);
|
|
|
|
// First determine if we have already added a column before
|
|
// adding one.
|
|
//
|
|
|
|
hwndHeader = ListView_GetHeader( hwndList );
|
|
|
|
Assert( hwndHeader );
|
|
|
|
if ( (!hwndHeader) ||
|
|
(Header_GetItemCount(hwndHeader) == 0) )
|
|
{
|
|
GetClientRect(hwndList, &rc);
|
|
lvc.mask = LVCF_FMT | LVCF_WIDTH;
|
|
lvc.fmt = LVCFMT_LEFT;
|
|
lvc.cx = rc.right;
|
|
|
|
// $REVIEW(tongl 12\22\97): Fix for bug#127472
|
|
// lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
|
|
|
|
ListView_InsertColumn(hwndList, 0, &lvc);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: HrInitListView
|
|
//
|
|
// Purpose: Initialize the list view.
|
|
// Iterate through all installed clients, services and protocols,
|
|
// insert into the list view with the correct binding state with
|
|
// the adapter used in this connection.
|
|
//
|
|
// Arguments:
|
|
// hwndList[in]: Handle of the list view
|
|
// pnc[in]: The writable INetcfg pointer
|
|
// pnccAdapter[in]: The INetcfgComponent pointer to the adapter used in this connection
|
|
//
|
|
// Returns: HRESULT, Error code.
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT HrInitListView(HWND hwndList,
|
|
INetCfg* pnc,
|
|
INetCfgComponent * pnccAdapter,
|
|
ListBPObj * plistBindingPaths,
|
|
HIMAGELIST* philStateIcons)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SP_CLASSIMAGELIST_DATA *pcild;
|
|
|
|
Assert(hwndList);
|
|
Assert(pnc);
|
|
Assert(pnccAdapter);
|
|
Assert(plistBindingPaths);
|
|
Assert(philStateIcons);
|
|
|
|
pcild = (SP_CLASSIMAGELIST_DATA *)::GetWindowLongPtr(::GetParent(hwndList),
|
|
GWLP_USERDATA);
|
|
|
|
HrInitCheckboxListView(hwndList, philStateIcons, pcild);
|
|
|
|
hr = HrRefreshAll(hwndList, pnc, pnccAdapter, plistBindingPaths);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Selete the first item
|
|
ListView_SetItemState(hwndList, 0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
|
|
}
|
|
|
|
TraceError("HrInitListView", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: UninitListView
|
|
//
|
|
// Purpose: Uninitializes the common component list view
|
|
//
|
|
// Arguments:
|
|
// hwndList [in] HWND of listview
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// Author: danielwe 2 Feb 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID UninitListView(HWND hwndList)
|
|
{
|
|
SP_CLASSIMAGELIST_DATA * pcild;
|
|
|
|
Assert(hwndList);
|
|
|
|
// delete existing items in the list view
|
|
ListView_DeleteAllItems( hwndList );
|
|
|
|
pcild = reinterpret_cast<SP_CLASSIMAGELIST_DATA *>(
|
|
::GetWindowLongPtr(GetParent(hwndList), GWLP_USERDATA));
|
|
|
|
if (pcild)
|
|
{
|
|
// Destroy the class image list data
|
|
(VOID) HrSetupDiDestroyClassImageList(pcild);
|
|
delete pcild;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: HrInsertComponent
|
|
//
|
|
// Purpose: Insert all installed, non-hidden and bindable components
|
|
// of a class to the list view
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT, Error code.
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrInsertComponent(
|
|
IN HWND hwndList,
|
|
IN const GUID* pGuidDevClass,
|
|
IN INetCfgComponent *pncc,
|
|
IN INetCfgComponent *pnccAdapter,
|
|
IN DWORD dwFlags,
|
|
IN ListBPObj * plistBindingPaths,
|
|
IN OUT INT* pnPos)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SP_CLASSIMAGELIST_DATA * pcild;
|
|
|
|
Assert(hwndList);
|
|
Assert(pGuidDevClass);
|
|
|
|
pcild = reinterpret_cast<SP_CLASSIMAGELIST_DATA *>
|
|
(::GetWindowLongPtr(GetParent(hwndList), GWLP_USERDATA));
|
|
|
|
// We should only list components that are bindable to the adapter
|
|
// Note: bindable means binding path exists, either enabled or disabled
|
|
|
|
INetCfgComponentBindings * pnccb;
|
|
hr = pncc->QueryInterface(IID_INetCfgComponentBindings, (LPVOID *)&pnccb);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// Do this only for protocols !!
|
|
|
|
// $REVIEW(TongL 3/28/99), I included the 2 reasons on why we only filter
|
|
// non-bindable protocols below, in case someone ask again ..
|
|
|
|
// 1) (Originally per BillBe) The add component dialog filters out non-bindable
|
|
// protocols by matching binding interface names from INF, it can not easily do
|
|
// so for services/clients which could be several layers above the adapter.
|
|
|
|
// The property UI needs to be consistent because it's confusing to users if
|
|
// we allow them to add a component from a connection but don't let that
|
|
// component show up in the same connection's property UI.
|
|
|
|
// 2) (Per ShaunCo) After talking with Bill, we show protocols yet not clients
|
|
// services not to be consistent with the add component dialog, but because
|
|
// you cannot predict based on bindings alone whether a client or service will
|
|
// end up being involved with an adapter. example: i can install a service
|
|
// that doesn't bind and uses winsock to send data. It may be able to be configured
|
|
// differently for each adapter (and hence would need to show up for each adapter's
|
|
// connection) but you can't tell by any means whether its going to be invovled with
|
|
// that adapter or not. -- So you have to show all services and clients.
|
|
// A protocol, on the other hand, binds with adapters by definition. So, we know
|
|
// for the protocol's which will use an adapter and which won't.
|
|
|
|
// Special case: do now show filter components unless it is bindable,
|
|
// Raid 358865
|
|
DWORD dwFlags;
|
|
hr = pncc->GetCharacteristics(&dwFlags);
|
|
|
|
if ((SUCCEEDED(hr) && (dwFlags & NCF_FILTER)) ||
|
|
(GUID_DEVCLASS_NETTRANS == *pGuidDevClass))
|
|
{
|
|
// $REVIEW(ShaunCo 3/26/99)
|
|
// To see if the protocol is involved with the adapter, check the
|
|
// owner of each bindpath and see if its equal to the component
|
|
// we are considering inserting into the list view.
|
|
// Note the special case for ms_nwnb. It won't be involved in a
|
|
// direct binding to the adapter because it has NCF_DONTEXPOSELOWER,
|
|
// so we can't use IsBindableTo.
|
|
|
|
BOOL fProtocolIsInvolved = FALSE;
|
|
ListBPObj_ITER iter;
|
|
|
|
for (iter = plistBindingPaths->begin();
|
|
(iter != plistBindingPaths->end() && !fProtocolIsInvolved);
|
|
iter++)
|
|
{
|
|
INetCfgComponent* pScan;
|
|
hr = (*iter)->m_pncbp->GetOwner(&pScan);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
if (pScan == pncc)
|
|
{
|
|
fProtocolIsInvolved = TRUE;
|
|
}
|
|
ReleaseObj(pScan);
|
|
}
|
|
}
|
|
|
|
if (!fProtocolIsInvolved)
|
|
{
|
|
// Don't insert this protocol because it is not involved
|
|
// in the binding set for the adpater.
|
|
//
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
|
|
if (S_OK == hr) // bindable, add to list
|
|
{
|
|
PWSTR pszwName;
|
|
|
|
hr = pncc->GetDisplayName(&pszwName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
PWSTR pszwDesc;
|
|
|
|
// Special Case:
|
|
// If this is a Domain Controller,
|
|
// disable tcpip removal, Raid 263754
|
|
//
|
|
if (GUID_DEVCLASS_NETTRANS == *pGuidDevClass)
|
|
{
|
|
PWSTR pszwId;
|
|
hr = pncc->GetId (&pszwId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (FEqualComponentId (c_szInfId_MS_TCPIP, pszwId))
|
|
{
|
|
NT_PRODUCT_TYPE pt;
|
|
|
|
RtlGetNtProductType (&pt);
|
|
if (NtProductLanManNt == pt)
|
|
{
|
|
dwFlags |= NCF_NOT_USER_REMOVABLE;
|
|
}
|
|
}
|
|
|
|
CoTaskMemFree (pszwId);
|
|
}
|
|
}
|
|
|
|
hr = pncc->GetHelpText(&pszwDesc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
|
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE |
|
|
LVIF_STATE | LVIF_PARAM;
|
|
|
|
|
|
// Get the component's class image list index
|
|
if (pcild)
|
|
{
|
|
INT nIndex = 0;
|
|
|
|
(VOID) HrSetupDiGetClassImageIndex(pcild,
|
|
pGuidDevClass, &nIndex);
|
|
|
|
lvi.iImage = nIndex;
|
|
}
|
|
|
|
lvi.iItem = *pnPos;
|
|
|
|
NET_ITEM_DATA * pnid = new NET_ITEM_DATA;
|
|
|
|
if (pnid)
|
|
{
|
|
pnid->szwName = SzDupSz(pszwName);
|
|
pnid->szwDesc = SzDupSz(pszwDesc);
|
|
pnid->dwFlags = dwFlags;
|
|
AddRefObj(pnid->pncc = pncc);
|
|
|
|
pnid->pCompObj = new CComponentObj(pncc);
|
|
if (pnid->pCompObj)
|
|
{
|
|
hr = pnid->pCompObj->HrInit(plistBindingPaths);
|
|
if FAILED(hr)
|
|
{
|
|
TraceError("HrInsertComponent: failed to initialize a component object", hr);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
lvi.lParam = reinterpret_cast<LPARAM>(pnid);
|
|
lvi.pszText = pnid->szwName;
|
|
|
|
// We will refresh the state of the whole list in the end
|
|
UINT iChkIndex = SELS_CHECKED;
|
|
lvi.state = INDEXTOSTATEIMAGEMASK( iChkIndex );
|
|
|
|
INT ret;
|
|
ret = ListView_InsertItem(hwndList, &lvi);
|
|
|
|
(*pnPos)++;
|
|
|
|
CoTaskMemFree(pszwDesc);
|
|
}
|
|
}
|
|
|
|
CoTaskMemFree(pszwName);
|
|
}
|
|
}
|
|
|
|
ReleaseObj(pnccb);
|
|
}
|
|
|
|
TraceError("HrInsertComponent", S_FALSE == hr ? S_OK : hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: HrInsertComponents
|
|
//
|
|
// Purpose: Insert installed and non-hidden components
|
|
// of a class to the list view
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT, Error code.
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrInsertComponents(
|
|
IN HWND hwndList,
|
|
IN INetCfg* pnc,
|
|
IN const GUID* pGuidDevClass,
|
|
IN INetCfgComponent* pnccAdapter,
|
|
IN ListBPObj* plistBindingPaths,
|
|
IN OUT INT* pnPos)
|
|
{
|
|
Assert(hwndList);
|
|
|
|
HRESULT hr = S_OK;
|
|
CIterNetCfgComponent iterComp (pnc, pGuidDevClass);
|
|
INetCfgComponent* pncc;
|
|
|
|
while (SUCCEEDED(hr) && S_OK == (hr = iterComp.HrNext(&pncc)))
|
|
{
|
|
DWORD dwFlags;
|
|
|
|
hr = pncc->GetCharacteristics(&dwFlags);
|
|
|
|
// Make sure it's not hidden
|
|
if (SUCCEEDED(hr) && !(dwFlags & NCF_HIDDEN))
|
|
{
|
|
// This will AddRef pncc so the release below can still be
|
|
// there
|
|
hr = HrInsertComponent(
|
|
hwndList, pGuidDevClass, pncc, pnccAdapter,
|
|
dwFlags, plistBindingPaths, pnPos);
|
|
}
|
|
ReleaseObj(pncc);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Get rid of FALSE returns
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("HrInsertComponents", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: HrRefreshListView
|
|
//
|
|
// Purpose: Iterate through all installed clients, services and protocols,
|
|
// insert into the list view with the correct binding state with
|
|
// the adapter used in this connection.
|
|
//
|
|
// Arguments:
|
|
// hwndList[in]: Handle of the list view
|
|
// pnc[in]: The writable INetcfg pointer
|
|
// pnccAdapter[in]: The INetcfgComponent pointer to the adapter used in this connection
|
|
//
|
|
// Returns: HRESULT, Error code.
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrRefreshListView(HWND hwndList,
|
|
INetCfg* pnc,
|
|
INetCfgComponent * pnccAdapter,
|
|
ListBPObj * plistBindingPaths)
|
|
{
|
|
HRESULT hr;
|
|
INT nPos = 0;
|
|
|
|
Assert(hwndList);
|
|
|
|
// Clients
|
|
hr = HrInsertComponents(hwndList, pnc,
|
|
&GUID_DEVCLASS_NETCLIENT, pnccAdapter, plistBindingPaths,
|
|
&nPos);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Services
|
|
hr = HrInsertComponents(hwndList, pnc,
|
|
&GUID_DEVCLASS_NETSERVICE, pnccAdapter, plistBindingPaths,
|
|
&nPos);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Protocols
|
|
hr = HrInsertComponents(hwndList, pnc,
|
|
&GUID_DEVCLASS_NETTRANS, pnccAdapter, plistBindingPaths,
|
|
&nPos);
|
|
}
|
|
|
|
// Now refresh the state of all items
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = HrRefreshCheckListState(hwndList);
|
|
}
|
|
|
|
TraceError("HrRefreshListView", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: HrLvGetSelectedComponent
|
|
//
|
|
// Purpose: Return pointer to the INetCfgComponent of the selected
|
|
// client, service or protocol
|
|
//
|
|
// Returns: S_OK if successful,
|
|
// S_FALSE if list view Macros returns failure
|
|
// (specific error not available).
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrLvGetSelectedComponent(HWND hwndList,
|
|
INetCfgComponent ** ppncc)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
Assert(hwndList);
|
|
|
|
*ppncc = NULL;
|
|
|
|
INT iSelected = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
|
|
|
|
if (iSelected != -1)
|
|
{
|
|
LV_ITEM lvItem = {0};
|
|
|
|
lvItem.mask = LVIF_PARAM;
|
|
lvItem.iItem = iSelected;
|
|
|
|
if (ListView_GetItem(hwndList, &lvItem))
|
|
{
|
|
NET_ITEM_DATA * pnid;
|
|
|
|
pnid = reinterpret_cast<NET_ITEM_DATA *>(lvItem.lParam);
|
|
|
|
if (pnid)
|
|
{
|
|
hr = S_OK;
|
|
pnid->pncc->AddRef();
|
|
*ppncc = pnid->pncc;
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceError("HrLvGetSelectedComponent", S_FALSE == hr ? S_OK : hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: LvDeleteItem
|
|
//
|
|
// Purpose: Handles deletion of the given item from the listview. Should
|
|
// be called in response to the LVN_DELETEITEM notification.
|
|
//
|
|
// Arguments:
|
|
// hwndList [in] Listview handle
|
|
// iItem [in] item that was deleted
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// Author: danielwe 3 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID LvDeleteItem(HWND hwndList, int iItem)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
NET_ITEM_DATA * pnid;
|
|
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = iItem;
|
|
|
|
ListView_GetItem(hwndList, &lvi);
|
|
|
|
pnid = reinterpret_cast<NET_ITEM_DATA*>(lvi.lParam);
|
|
|
|
AssertSz(pnid, "No item data!?!?");
|
|
|
|
ReleaseObj(pnid->pncc);
|
|
delete(pnid->pCompObj);
|
|
delete pnid->szwName;
|
|
delete pnid->szwDesc;
|
|
|
|
delete pnid;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: OnListClick
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Returns:
|
|
//
|
|
INT OnListClick(HWND hwndList,
|
|
HWND hwndParent,
|
|
INetCfg *pnc,
|
|
IUnknown *punk,
|
|
INetCfgComponent *pnccAdapter,
|
|
ListBPObj * plistBindingPaths,
|
|
BOOL fDoubleClk,
|
|
BOOL fReadOnly)
|
|
{
|
|
INT iItem;
|
|
DWORD dwpts;
|
|
LV_HITTESTINFO lvhti;
|
|
|
|
// we have the location
|
|
dwpts = GetMessagePos();
|
|
|
|
lvhti.pt.x = LOWORD( dwpts );
|
|
lvhti.pt.y = HIWORD( dwpts );
|
|
MapWindowPoints(NULL , hwndList , (LPPOINT) &(lvhti.pt) , 1);
|
|
|
|
// get currently selected item
|
|
iItem = ListView_HitTest( hwndList, &lvhti );
|
|
|
|
// if no selection, or click not on state return false
|
|
if (-1 != iItem)
|
|
{
|
|
// set the current selection
|
|
ListView_SetItemState(hwndList, iItem, LVIS_SELECTED, LVIS_SELECTED);
|
|
|
|
if ( fDoubleClk )
|
|
{
|
|
if ((LVHT_ONITEMICON != (LVHT_ONITEMICON & lvhti.flags)) &&
|
|
(LVHT_ONITEMLABEL != (LVHT_ONITEMLABEL & lvhti.flags)) &&
|
|
(LVHT_ONITEMSTATEICON != (LVHT_ONITEMSTATEICON & lvhti.flags)) )
|
|
{
|
|
iItem = -1;
|
|
}
|
|
}
|
|
else // single click
|
|
{
|
|
if (LVHT_ONITEMSTATEICON != (LVHT_ONITEMSTATEICON & lvhti.flags))
|
|
{
|
|
iItem = -1;
|
|
}
|
|
}
|
|
|
|
if (-1 != iItem)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if ((fDoubleClk) &&
|
|
(LVHT_ONITEMSTATEICON != (LVHT_ONITEMSTATEICON & lvhti.flags)))
|
|
{
|
|
// only raise properties if the selected component has UI and
|
|
// is not disabled, and the current user has the permission to
|
|
// change properties.
|
|
|
|
LV_ITEM lvItem;
|
|
lvItem.mask = LVIF_PARAM;
|
|
lvItem.iItem = iItem;
|
|
lvItem.iSubItem = 0;
|
|
|
|
if (ListView_GetItem(hwndList, &lvItem))
|
|
{
|
|
NET_ITEM_DATA * pnid = NULL;
|
|
pnid = reinterpret_cast<NET_ITEM_DATA *>(lvItem.lParam);
|
|
if (pnid)
|
|
{
|
|
// is this component checked ?
|
|
if ((UNCHECKED != (pnid->pCompObj)->GetChkState()) &&
|
|
(pnid->dwFlags & NCF_HAS_UI) &&
|
|
FHasPermission(NCPERM_LanChangeProperties))
|
|
{
|
|
BOOL fShowProperties = TRUE;
|
|
|
|
if (FIsUserNetworkConfigOps())
|
|
{
|
|
LPWSTR pszwId;
|
|
|
|
hr = pnid->pncc->GetId(&pszwId);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (pszwId)
|
|
{
|
|
if (!FEqualComponentId (c_szInfId_MS_TCPIP, pszwId))
|
|
{
|
|
fShowProperties = FALSE;
|
|
}
|
|
else if (FEqualComponentId (c_szInfId_MS_TCPIP, pszwId))
|
|
{
|
|
fShowProperties = TRUE;
|
|
}
|
|
CoTaskMemFree(pszwId);
|
|
}
|
|
else
|
|
{
|
|
fShowProperties = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fShowProperties = FALSE;
|
|
}
|
|
}
|
|
|
|
if (fShowProperties)
|
|
{
|
|
hr = HrLvProperties(hwndList, hwndParent, pnc, punk,
|
|
pnccAdapter, plistBindingPaths, NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!fReadOnly)
|
|
{
|
|
hr = HrToggleLVItemState(hwndList, plistBindingPaths, iItem);
|
|
}
|
|
}
|
|
|
|
if FAILED(hr)
|
|
iItem = -1;
|
|
}
|
|
}
|
|
|
|
return( iItem );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: HrToggleLVItemState
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Returns:
|
|
//
|
|
HRESULT HrToggleLVItemState(HWND hwndList,
|
|
ListBPObj * plistBindingPaths,
|
|
INT iItem)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
LV_ITEM lvItem;
|
|
NET_ITEM_DATA * pnid;
|
|
|
|
// we are interested in is the PARAM
|
|
lvItem.iItem = iItem;
|
|
lvItem.mask = LVIF_PARAM;
|
|
lvItem.iSubItem = 0;
|
|
|
|
ListView_GetItem( hwndList, &lvItem );
|
|
|
|
// get the item
|
|
pnid = (NET_ITEM_DATA *)lvItem.lParam;
|
|
|
|
// If the binding checkbox is available, then allow the toggle.
|
|
//
|
|
if (!(pnid->dwFlags & NCF_FIXED_BINDING) &&
|
|
FHasPermission(NCPERM_ChangeBindState))
|
|
{
|
|
if (pnid->pCompObj->GetChkState() == UNCHECKED) // toggle on
|
|
{
|
|
hr = pnid->pCompObj->HrCheck(plistBindingPaths);
|
|
if SUCCEEDED(hr)
|
|
{
|
|
hr = HrRefreshCheckListState(hwndList);
|
|
}
|
|
|
|
// "Ding" if the state of this item is still unchecked
|
|
if (pnid->pCompObj->GetChkState() == UNCHECKED)
|
|
{
|
|
#ifdef DBG
|
|
TraceTag(ttidLanUi, "Why is this component still disabled ???");
|
|
#endif
|
|
}
|
|
|
|
}
|
|
else // toggle off
|
|
{
|
|
hr = pnid->pCompObj->HrUncheck(plistBindingPaths);
|
|
if SUCCEEDED(hr)
|
|
{
|
|
hr = HrRefreshCheckListState(hwndList);
|
|
}
|
|
|
|
// "Ding" if the state of this item is not unchecked
|
|
if (pnid->pCompObj->GetChkState() != UNCHECKED)
|
|
{
|
|
#ifdef DBG
|
|
TraceTag(ttidLanUi, "Why is this component not disabled ???");
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceError("HrToggleLVItemState", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: OnListKeyDown
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Returns:
|
|
//
|
|
|
|
INT OnListKeyDown(HWND hwndList, ListBPObj * plistBindingPaths, WORD wVKey)
|
|
{
|
|
INT iItem = -1;
|
|
|
|
if ((VK_SPACE == wVKey) && (GetAsyncKeyState(VK_MENU)>=0))
|
|
{
|
|
iItem = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED | LVNI_SELECTED);
|
|
// if no selection
|
|
if (-1 != iItem)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
hr = HrToggleLVItemState(hwndList, plistBindingPaths, iItem);
|
|
|
|
if FAILED(hr)
|
|
iItem = -1;
|
|
}
|
|
}
|
|
|
|
return( iItem );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function Name: LvSetButtons
|
|
//
|
|
// Purpose: Set the correct status of Add, Remove, Property buttons,
|
|
// and the description text
|
|
//
|
|
// Returns:
|
|
//
|
|
VOID LvSetButtons(HWND hwndParent, HANDLES& h, BOOL fReadOnly, IUnknown * punk)
|
|
{
|
|
Assert(IsWindow(h.m_hList));
|
|
Assert(IsWindow(h.m_hAdd));
|
|
Assert(IsWindow(h.m_hRemove));
|
|
Assert(IsWindow(h.m_hProperty));
|
|
|
|
// enable Property button if valid and update description text
|
|
INT iSelected = ListView_GetNextItem(h.m_hList, -1, LVNI_SELECTED);
|
|
if (iSelected == -1) // Nothing selected or list empty
|
|
{
|
|
::EnableWindow(h.m_hAdd, !fReadOnly && FHasPermission(NCPERM_AddRemoveComponents));
|
|
|
|
if (!fReadOnly)
|
|
{
|
|
// if list is empty, set focus to the list view
|
|
if (0 == ListView_GetItemCount(h.m_hList))
|
|
{
|
|
// remove the default on the remove button
|
|
SendMessage(h.m_hRemove, BM_SETSTYLE, (WPARAM)BS_PUSHBUTTON, TRUE );
|
|
|
|
// move focus to the Add button
|
|
::SetFocus(h.m_hAdd);
|
|
}
|
|
}
|
|
|
|
::EnableWindow(h.m_hRemove, FALSE);
|
|
::EnableWindow(h.m_hProperty, FALSE);
|
|
|
|
if(h.m_hDescription)
|
|
{
|
|
::SetWindowText(h.m_hDescription, c_szEmpty);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// enable Add/Remove buttons
|
|
::EnableWindow(h.m_hAdd, !fReadOnly && FHasPermission(NCPERM_AddRemoveComponents));
|
|
|
|
LV_ITEM lvItem;
|
|
lvItem.mask = LVIF_PARAM;
|
|
lvItem.iItem = iSelected;
|
|
lvItem.iSubItem = 0;
|
|
|
|
if (ListView_GetItem(h.m_hList, &lvItem))
|
|
{
|
|
NET_ITEM_DATA * pnid = NULL;
|
|
pnid = reinterpret_cast<NET_ITEM_DATA *>(lvItem.lParam);
|
|
if (pnid)
|
|
{
|
|
if (fReadOnly)
|
|
{
|
|
::EnableWindow(h.m_hProperty, FALSE);
|
|
::EnableWindow(h.m_hRemove, FALSE);
|
|
}
|
|
else
|
|
{
|
|
// is this component checked ?
|
|
if (UNCHECKED != (pnid->pCompObj)->GetChkState())
|
|
{
|
|
BOOL fHasPropertyUi = FALSE;
|
|
|
|
HRESULT hr = S_OK;
|
|
INetCfgComponent * pncc;
|
|
LPWSTR pszwId;
|
|
|
|
hr = HrLvGetSelectedComponent(h.m_hList, &pncc);
|
|
if (S_OK == hr)
|
|
{
|
|
AssertSz(pncc, "No component selected?!?!");
|
|
hr = pncc->RaisePropertyUi(hwndParent, NCRP_QUERY_PROPERTY_UI, punk);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
fHasPropertyUi = TRUE;
|
|
}
|
|
ReleaseObj(pncc);
|
|
}
|
|
|
|
if (FIsUserNetworkConfigOps() && FHasPermission(NCPERM_LanChangeProperties))
|
|
{
|
|
hr = pncc->GetId(&pszwId);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (pszwId && !FEqualComponentId (c_szInfId_MS_TCPIP, pszwId))
|
|
{
|
|
::EnableWindow(h.m_hProperty, FALSE);
|
|
}
|
|
else if (pszwId && FEqualComponentId (c_szInfId_MS_TCPIP, pszwId) && fHasPropertyUi)
|
|
{
|
|
::EnableWindow(h.m_hProperty, TRUE);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
::EnableWindow(h.m_hProperty,
|
|
fHasPropertyUi &&
|
|
FHasPermission(NCPERM_LanChangeProperties));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
::EnableWindow(h.m_hProperty, FALSE);
|
|
}
|
|
|
|
// is this component user removable ?
|
|
::EnableWindow(h.m_hRemove,
|
|
!(pnid->dwFlags & NCF_NOT_USER_REMOVABLE) &&
|
|
FHasPermission(NCPERM_AddRemoveComponents));
|
|
}
|
|
|
|
// set description text
|
|
if(h.m_hDescription)
|
|
{
|
|
::SetWindowText(h.m_hDescription, (PCWSTR)pnid->szwDesc);
|
|
}
|
|
}
|
|
|
|
// Set focus to the list (336050)
|
|
SetFocus(h.m_hList);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrLvRemove
|
|
//
|
|
// Purpose: Handles the pressing of the Remove button. Should be called
|
|
// in responsed to the PSB_Remove message.
|
|
//
|
|
// Arguments:
|
|
// hwndLV [in] Handle of listview
|
|
// hwndParent [in] Handle of parent window
|
|
// pnc [in] INetCfg being used
|
|
// pnccAdapter [in] INetCfgComponent of adapter for the connection
|
|
//
|
|
// Returns: S_OK if success, Win32 or OLE error code otherwise
|
|
//
|
|
// Author: danielwe 3 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrLvRemove(HWND hwndLV, HWND hwndParent,
|
|
INetCfg *pnc, INetCfgComponent *pnccAdapter,
|
|
ListBPObj * plistBindingPaths)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
INetCfgComponent * pncc;
|
|
|
|
hr = HrLvGetSelectedComponent(hwndLV, &pncc);
|
|
if (S_OK == hr)
|
|
{
|
|
hr = HrQueryUserAndRemoveComponent(hwndParent, pnc, pncc);
|
|
if (NETCFG_S_STILL_REFERENCED == hr)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
HRESULT hrTmp = HrRefreshAll(hwndLV, pnc, pnccAdapter, plistBindingPaths);
|
|
if (S_OK != hrTmp)
|
|
hr = hrTmp;
|
|
}
|
|
}
|
|
|
|
ReleaseObj(pncc);
|
|
}
|
|
else
|
|
{
|
|
TraceTag(ttidLanUi, "HrLvGetSelectedComponent did not get a valid selection.");
|
|
}
|
|
|
|
TraceError("HrLvRemove", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrLvAdd
|
|
//
|
|
// Purpose: Handles the pressing of the Add button. Should be called in
|
|
// response to the PSB_Add message.
|
|
//
|
|
// Arguments:
|
|
// hwndLV [in] Handle of listview
|
|
// hwndParent [in] Handle of parent window
|
|
// pnc [in] INetCfg being used
|
|
// pnccAdapter [in] INetCfgComponent of adapter for the connection
|
|
//
|
|
// Returns: S_OK if success, Win32 or OLE error code otherwise
|
|
//
|
|
// Author: danielwe 3 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrLvAdd(HWND hwndLV, HWND hwndParent, INetCfg *pnc,
|
|
INetCfgComponent *pnccAdapter,
|
|
ListBPObj * plistBindingPaths)
|
|
{
|
|
HRESULT hr;
|
|
CI_FILTER_INFO cfi;
|
|
|
|
ZeroMemory(&cfi, sizeof(cfi));
|
|
|
|
if (!pnccAdapter)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
// We want to filter out any irrelvant protocols (i.e. protocols that
|
|
// won't bind to this adapter) so we need to send in a filter info
|
|
// struct with our information.
|
|
cfi.eFilter = FC_LAN; // Apply lan specific filtering
|
|
cfi.pIComp = pnccAdapter; // Filter against this adapter
|
|
|
|
INetCfgComponentBindings* pnccb;
|
|
hr = pnccAdapter->QueryInterface(IID_INetCfgComponentBindings,
|
|
reinterpret_cast<LPVOID *>(&pnccb));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pnccb->SupportsBindingInterface(NCF_UPPER, c_szBiNdisAtm);
|
|
if (S_OK == hr)
|
|
{
|
|
cfi.eFilter = FC_ATM; // Apply lan specific filtering
|
|
}
|
|
ReleaseObj(pnccb);
|
|
}
|
|
|
|
hr = HrDisplayAddComponentDialog(hwndParent, pnc, &cfi);
|
|
if ((S_OK == hr) || (NETCFG_S_REBOOT == hr))
|
|
{
|
|
HRESULT hrSave = hr;
|
|
|
|
// Refresh the list to reflect changes
|
|
hr = HrRefreshAll(hwndLV, pnc, pnccAdapter, plistBindingPaths);
|
|
if (SUCCEEDED(hr))
|
|
hr = hrSave;
|
|
}
|
|
else if (NETCFG_E_ACTIVE_RAS_CONNECTIONS == hr)
|
|
{
|
|
LvReportError(IDS_LANUI_REQUIRE_DISCONNECT_ADD, hwndParent, NULL, NULL);
|
|
}
|
|
else if (NETCFG_E_NEED_REBOOT == hr)
|
|
{
|
|
LvReportError(IDS_LANUI_REQUIRE_REBOOT_ADD, hwndParent, NULL, NULL);
|
|
}
|
|
else if (S_FALSE != hr)
|
|
{
|
|
PWSTR psz = NULL;
|
|
|
|
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
hr,
|
|
LANG_NEUTRAL,
|
|
(PWSTR)&psz,
|
|
0,
|
|
NULL))
|
|
{
|
|
LvReportError(IDS_LANUI_GENERIC_ADD_ERROR, hwndParent, NULL, psz);
|
|
GlobalFree(psz);
|
|
}
|
|
else
|
|
{
|
|
LvReportErrorHr(hr, IDS_LANUI_GENERIC_ADD_ERROR, hwndParent, NULL);
|
|
}
|
|
}
|
|
|
|
TraceError("HrLvAdd", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: LvReportError
|
|
//
|
|
// Purpose: Reports a generic error based on the information passed in
|
|
//
|
|
// Arguments:
|
|
// ids [in] IDS of the string to be used as the text of the
|
|
// message box
|
|
// hwnd [in] Parent HWND
|
|
// szDesc [in] Display name of component
|
|
// szText [in] [Optional] If supplied, provides additional string
|
|
// for replacement. Can be NULL.
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// Author: danielwe 6 Jan 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID LvReportError(INT ids, HWND hwnd, PCWSTR szDesc, PCWSTR szText)
|
|
{
|
|
if (szDesc && szText)
|
|
{
|
|
NcMsgBox(_Module.GetResourceInstance(), hwnd,
|
|
IDS_LANUI_ERROR_CAPTION, ids,
|
|
MB_ICONSTOP | MB_OK, szDesc, szText);
|
|
}
|
|
else if (szDesc)
|
|
{
|
|
NcMsgBox(_Module.GetResourceInstance(), hwnd,
|
|
IDS_LANUI_ERROR_CAPTION, ids,
|
|
MB_ICONSTOP | MB_OK, szDesc);
|
|
}
|
|
else if (szText)
|
|
{
|
|
NcMsgBox(_Module.GetResourceInstance(), hwnd,
|
|
IDS_LANUI_ERROR_CAPTION, ids,
|
|
MB_ICONSTOP | MB_OK, szText);
|
|
}
|
|
else
|
|
{
|
|
NcMsgBox(_Module.GetResourceInstance(), hwnd,
|
|
IDS_LANUI_ERROR_CAPTION, ids,
|
|
MB_ICONSTOP | MB_OK);
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: LvReportErrorHr
|
|
//
|
|
// Purpose: Reports a generic error based on the information passed in
|
|
//
|
|
// Arguments:
|
|
// hr [in] HRESULT error value to use in reporting the error
|
|
// ids [in] IDS of the string to be used as the text of the
|
|
// message box
|
|
// hwnd [in] Parent HWND
|
|
// szDesc [in] Display name of component
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// Author: danielwe 14 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID LvReportErrorHr(HRESULT hr, INT ids, HWND hwnd, PCWSTR szDesc)
|
|
{
|
|
WCHAR szText[32];
|
|
static const WCHAR c_szFmt[] = L"0x%08X";
|
|
|
|
wsprintfW(szText, c_szFmt, hr);
|
|
LvReportError(ids, hwnd, szDesc, szText);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrLvProperties
|
|
//
|
|
// Purpose: Handles the pressing of the Add button. Should be called in
|
|
// response to the PSB_Properties message.
|
|
//
|
|
// Arguments:
|
|
// hwndLV [in] Handle of listview
|
|
// hwndParent [in] Handle of parent window
|
|
// pnc [in] INetCfg being used
|
|
// punk [in] IUnknown for interface to query context information
|
|
// bChanged [out] Boolean indicating if something changed.
|
|
//
|
|
// Returns: S_OK if success, Win32 or OLE error code otherwise
|
|
//
|
|
// Author: danielwe 3 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrLvProperties(HWND hwndLV, HWND hwndParent, INetCfg *pnc,
|
|
IUnknown *punk, INetCfgComponent *pnccAdapter,
|
|
ListBPObj * plistBindingPaths,
|
|
BOOL *bChanged)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
INetCfgComponent * pncc;
|
|
|
|
if ( bChanged )
|
|
{
|
|
|
|
*bChanged = FALSE;
|
|
}
|
|
|
|
hr = HrLvGetSelectedComponent(hwndLV, &pncc);
|
|
if (S_OK == hr)
|
|
{
|
|
AssertSz(pncc, "No component selected?!?!");
|
|
|
|
hr = pncc->RaisePropertyUi(hwndParent, NCRP_SHOW_PROPERTY_UI, punk);
|
|
|
|
// if components have been added or removed, we may need
|
|
// to refresh the whole list
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
TraceTag(ttidLanUi, "Refreshing component list needed because other components are added or removed.");
|
|
hr = HrRefreshAll(hwndLV, pnc, pnccAdapter, plistBindingPaths);
|
|
|
|
if ( bChanged )
|
|
{
|
|
*bChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
ReleaseObj(pncc);
|
|
}
|
|
else
|
|
{
|
|
TraceTag(ttidLanUi, "HrLvGetSelectedComponent did not return a valid selection.");
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Normalize error result
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("HrLvProperties", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrRefreshAll
|
|
//
|
|
// Purpose: Rebuilds the collection of BindingPathObj and the list view
|
|
//
|
|
// Arguments:
|
|
// hwndList [in] Handle of listview
|
|
// pnc [in] INetCfg being used
|
|
// pnccAdapter [in] INetCfgComponent of the adapter in this connection
|
|
// plistBindingPaths [in/out] The collection of BindingPathObj
|
|
//
|
|
// Returns: S_OK if success, Win32 or OLE error code otherwise
|
|
//
|
|
// Author: tongl 23 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT HrRefreshAll(HWND hwndList,
|
|
INetCfg* pnc,
|
|
INetCfgComponent * pnccAdapter,
|
|
ListBPObj * plistBindingPaths)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
ReleaseAll(hwndList, plistBindingPaths);
|
|
|
|
hr = HrRebuildBindingPathObjCollection( pnccAdapter,
|
|
plistBindingPaths);
|
|
if SUCCEEDED(hr)
|
|
{
|
|
// Set the correct state on the BindingPathObject list
|
|
hr = HrRefreshBindingPathObjCollectionState(plistBindingPaths);
|
|
|
|
if SUCCEEDED(hr)
|
|
{
|
|
// Now refresh the list to reflect changes
|
|
hr = HrRefreshListView(hwndList, pnc, pnccAdapter, plistBindingPaths);
|
|
}
|
|
}
|
|
|
|
// $REVIEW(tongl 12\16\97): added so we always have a selection.
|
|
// Caller of this function can reset selection if they need to.
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Selete the first item
|
|
ListView_SetItemState(hwndList, 0, LVIS_SELECTED, LVIS_SELECTED);
|
|
}
|
|
|
|
TraceError("HrRefreshAll", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ReleaseAll
|
|
//
|
|
// Purpose: Releases the INetCfgComponent and INetCfgBindingPath objects
|
|
//
|
|
// Arguments:
|
|
// hwndList [in] Handle of listview
|
|
// plistBindingPaths [in/out] The collection of BindingPathObj
|
|
//
|
|
// Author: tongl 18 Mar, 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID ReleaseAll(HWND hwndList,
|
|
ListBPObj * plistBindingPaths)
|
|
{
|
|
// first, clean up any existing objects in the list
|
|
FreeCollectionAndItem(*plistBindingPaths);
|
|
|
|
// delete existing items in the list view
|
|
ListView_DeleteAllItems( hwndList );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FValidatePageContents
|
|
//
|
|
// Purpose: Check error conditions before LAN property or wizard page
|
|
// exits
|
|
//
|
|
// Arguments:
|
|
// hwndDlg [in] Handle of dialog
|
|
// hwndList [in] Handle of the list view
|
|
// pnc [in] INetCfg
|
|
// pnccAdapter [in] INetCfgComponent
|
|
// plistBindignPaths [in] List of binding paths to this adater
|
|
//
|
|
// Returns: TRUE if there is a possible error and user wants to fix
|
|
// it before leaving the page. FALSE if no error or user
|
|
// chooses to move on.
|
|
//
|
|
// Author: tongl 17 Sept 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FValidatePageContents( HWND hwndDlg,
|
|
HWND hwndList,
|
|
INetCfg * pnc,
|
|
INetCfgComponent * pnccAdapter,
|
|
ListBPObj * plistBindingPaths)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// 1) Check if any protocol is enabled on this adapter
|
|
BOOL fEnabledProtocolExists = FALSE;
|
|
|
|
CIterNetCfgComponent iterProt(pnc, &GUID_DEVCLASS_NETTRANS);
|
|
INetCfgComponent* pnccTrans;
|
|
|
|
while (SUCCEEDED(hr) && !fEnabledProtocolExists &&
|
|
S_OK == (hr = iterProt.HrNext(&pnccTrans)))
|
|
{
|
|
HRESULT hrTmp;
|
|
|
|
INetCfgComponentBindings * pnccb;
|
|
hrTmp = pnccTrans->QueryInterface (
|
|
IID_INetCfgComponentBindings, (LPVOID*)&pnccb);
|
|
|
|
if (S_OK == hrTmp)
|
|
{
|
|
hrTmp = pnccb->IsBindableTo(pnccAdapter);
|
|
|
|
if (S_OK == hrTmp)
|
|
{
|
|
fEnabledProtocolExists = TRUE;
|
|
}
|
|
ReleaseObj(pnccb);
|
|
}
|
|
ReleaseObj(pnccTrans);
|
|
}
|
|
|
|
if (!fEnabledProtocolExists)
|
|
{
|
|
// warn the user
|
|
int nRet = NcMsgBox(
|
|
_Module.GetResourceInstance(),
|
|
hwndDlg,
|
|
IDS_LANUI_NOPROTOCOL_CAPTION,
|
|
IDS_LANUI_NOPROTOCOL,
|
|
MB_APPLMODAL|MB_ICONINFORMATION|MB_YESNO
|
|
);
|
|
|
|
if (nRet == IDYES)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// 2) Check if any component on the display list is in an intent check state
|
|
// If so, it means these components are actually disabled and will not be
|
|
// displayed as checked the next time the UI is refreshed.
|
|
tstring strCompList = c_szEmpty;
|
|
|
|
// for each item in the list view
|
|
int nlvCount = ListView_GetItemCount(hwndList);
|
|
|
|
LV_ITEM lvItem;
|
|
for (int i=0; i< nlvCount; i++)
|
|
{
|
|
lvItem.iItem = i;
|
|
lvItem.iSubItem = 0;
|
|
|
|
lvItem.mask = LVIF_PARAM;
|
|
if (ListView_GetItem(hwndList, &lvItem))
|
|
{
|
|
NET_ITEM_DATA * pnid;
|
|
|
|
pnid = reinterpret_cast<NET_ITEM_DATA *>(lvItem.lParam);
|
|
|
|
if (pnid)
|
|
{
|
|
// get the component object associated with this item
|
|
CComponentObj * pCompObj = pnid->pCompObj;
|
|
|
|
if (pCompObj)
|
|
{
|
|
if (INTENT_CHECKED == pCompObj->m_CheckState)
|
|
{
|
|
PWSTR pszwName;
|
|
hr = pCompObj->m_pncc->GetDisplayName(&pszwName);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (!strCompList.empty())
|
|
strCompList += SzLoadIds(IDS_NEWLINE);
|
|
strCompList += pszwName;
|
|
|
|
delete pszwName;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!strCompList.empty())
|
|
{
|
|
// warn the user
|
|
int nRet = NcMsgBox(
|
|
_Module.GetResourceInstance(),
|
|
hwndDlg,
|
|
IDS_LANUI_ERROR_CAPTION,
|
|
IDS_LANUI_INTENTCHECK,
|
|
MB_APPLMODAL|MB_ICONINFORMATION|MB_YESNO,
|
|
strCompList.c_str());
|
|
if (nRet == IDNO)
|
|
{
|
|
hr = HrRefreshAll(hwndList, pnc, pnccAdapter, plistBindingPaths);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// EAPOL related util functions
|
|
//
|
|
//+---------------------------------------------------------------------------
|
|
|
|
// Location of EAPOL Parameters Service
|
|
static WCHAR cszEapKeyEapolServiceParams[] = L"Software\\Microsoft\\EAPOL\\Parameters\\General" ;
|
|
|
|
static WCHAR cszInterfaceList[] = L"InterfaceList";
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function called to retrieve the connection data for an interface for a
|
|
// specific EAP type and SSID (if any). Data is stored in the HKLM hive
|
|
//
|
|
// Input arguments:
|
|
// pwszGUID - GUID string for the interface
|
|
// dwEapTypeId - EAP type for which connection data is to be stored
|
|
// dwSizeOfSSID - Size of Special identifier if any for the EAP blob
|
|
// pwszSSID - Special identifier if any for the EAP blob
|
|
//
|
|
// Return values:
|
|
// pbConnInfo - pointer to binary EAP connection data blob
|
|
// dwInfoSize - pointer to size of EAP connection blob
|
|
//
|
|
//
|
|
|
|
HRESULT
|
|
HrElGetCustomAuthData (
|
|
IN WCHAR *pwszGUID,
|
|
IN DWORD dwEapTypeId,
|
|
IN DWORD dwSizeOfSSID,
|
|
IN BYTE *pbSSID,
|
|
IN OUT BYTE *pbConnInfo,
|
|
IN OUT DWORD *pdwInfoSize
|
|
)
|
|
{
|
|
DWORD dwRetCode = ERROR_SUCCESS;
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
dwRetCode = WZCEapolGetCustomAuthData (
|
|
NULL,
|
|
pwszGUID,
|
|
dwEapTypeId,
|
|
dwSizeOfSSID,
|
|
pbSSID,
|
|
pbConnInfo,
|
|
pdwInfoSize
|
|
);
|
|
|
|
if (dwRetCode == ERROR_BUFFER_TOO_SMALL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
dwRetCode = ERROR_SUCCESS;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
if (dwRetCode != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwRetCode);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function called to set the connection data for an interface for a specific
|
|
// EAP type and SSID (if any). Data will be stored in the HKLM hive
|
|
//
|
|
// Input arguments:
|
|
// pwszGUID - pinter to GUID string for the interface
|
|
// dwEapTypeId - EAP type for which connection data is to be stored
|
|
// dwSizeOfSSID - Size of Special identifier if any for the EAP blob
|
|
// pwszSSID - Special identifier if any for the EAP blob
|
|
// pbConnInfo - pointer to binary EAP connection data blob
|
|
// dwInfoSize - Size of EAP connection blob
|
|
//
|
|
// Return values:
|
|
//
|
|
|
|
HRESULT
|
|
HrElSetCustomAuthData (
|
|
IN WCHAR *pwszGUID,
|
|
IN DWORD dwEapTypeId,
|
|
IN DWORD dwSizeOfSSID,
|
|
IN BYTE *pbSSID,
|
|
IN PBYTE pbConnInfo,
|
|
IN DWORD dwInfoSize
|
|
)
|
|
{
|
|
DWORD dwRetCode = ERROR_SUCCESS;
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
dwRetCode = WZCEapolSetCustomAuthData (
|
|
NULL,
|
|
pwszGUID,
|
|
dwEapTypeId,
|
|
dwSizeOfSSID,
|
|
pbSSID,
|
|
pbConnInfo,
|
|
dwInfoSize
|
|
);
|
|
|
|
} while (FALSE);
|
|
|
|
if (dwRetCode != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwRetCode);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function called to retrieve the EAPOL parameters for an interface
|
|
//
|
|
// Input arguments:
|
|
// pwszGUID - GUID string for the interface
|
|
//
|
|
// Return values:
|
|
// pdwDefaultEAPType - default EAP type for interface
|
|
// pIntfParams - Interface parameters
|
|
//
|
|
|
|
HRESULT
|
|
HrElGetInterfaceParams (
|
|
IN WCHAR *pwszGUID,
|
|
IN OUT EAPOL_INTF_PARAMS *pIntfParams
|
|
)
|
|
{
|
|
DWORD dwRetCode = ERROR_SUCCESS;
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
dwRetCode = WZCEapolGetInterfaceParams (
|
|
NULL,
|
|
pwszGUID,
|
|
pIntfParams
|
|
);
|
|
|
|
} while (FALSE);
|
|
|
|
if (dwRetCode != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwRetCode);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function called to set the EAPOL parameters for an interface
|
|
//
|
|
// Input arguments:
|
|
// pwszGUID - GUID string for the interface
|
|
// pIntfParams - Interface parameters
|
|
//
|
|
// Return values:
|
|
//
|
|
|
|
HRESULT
|
|
HrElSetInterfaceParams (
|
|
IN WCHAR *pwszGUID,
|
|
IN EAPOL_INTF_PARAMS *pIntfParams
|
|
)
|
|
{
|
|
DWORD dwRetCode = ERROR_SUCCESS;
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
dwRetCode = WZCEapolSetInterfaceParams (
|
|
NULL,
|
|
pwszGUID,
|
|
pIntfParams
|
|
);
|
|
|
|
} while (FALSE);
|
|
|
|
if (dwRetCode != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwRetCode);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Set selection in listbox 'hwndLb' to 'nIndex' and notify parent as if
|
|
// user had clicked the item which Windows doesn't do for some reason.
|
|
//
|
|
|
|
VOID
|
|
ComboBox_SetCurSelNotify (
|
|
IN HWND hwndLb,
|
|
IN INT nIndex
|
|
)
|
|
{
|
|
ComboBox_SetCurSel( hwndLb, nIndex );
|
|
|
|
SendMessage(
|
|
GetParent( hwndLb ),
|
|
WM_COMMAND,
|
|
(WPARAM )MAKELONG(
|
|
(WORD )GetDlgCtrlID( hwndLb ), (WORD )CBN_SELCHANGE ),
|
|
(LPARAM )hwndLb );
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Set the width of the drop-down list 'hwndLb' to the width of the
|
|
// longest item (or the width of the list box if that's wider).
|
|
//
|
|
|
|
VOID
|
|
ComboBox_AutoSizeDroppedWidth (
|
|
IN HWND hwndLb
|
|
)
|
|
{
|
|
HDC hdc;
|
|
HFONT hfont;
|
|
TCHAR* psz;
|
|
SIZE size;
|
|
DWORD cch;
|
|
DWORD dxNew;
|
|
DWORD i;
|
|
|
|
hfont = (HFONT )SendMessage( hwndLb, WM_GETFONT, 0, 0 );
|
|
if (!hfont)
|
|
return;
|
|
|
|
hdc = GetDC( hwndLb );
|
|
if (!hdc)
|
|
return;
|
|
|
|
SelectObject( hdc, hfont );
|
|
|
|
dxNew = 0;
|
|
for (i = 0; psz = ComboBox_GetPsz( hwndLb, i ); ++i)
|
|
{
|
|
cch = lstrlen( psz );
|
|
if (GetTextExtentPoint32( hdc, psz, cch, &size ))
|
|
{
|
|
if (dxNew < (DWORD )size.cx)
|
|
dxNew = (DWORD )size.cx;
|
|
}
|
|
|
|
free ( psz );
|
|
}
|
|
|
|
ReleaseDC( hwndLb, hdc );
|
|
|
|
// Allow for the spacing on left and right added by the control.
|
|
|
|
dxNew += 6;
|
|
|
|
// Figure out if the vertical scrollbar will be displayed and, if so,
|
|
// allow for it's width.
|
|
|
|
{
|
|
RECT rectD;
|
|
RECT rectU;
|
|
DWORD dyItem;
|
|
DWORD cItemsInDrop;
|
|
DWORD cItemsInList;
|
|
|
|
GetWindowRect( hwndLb, &rectU );
|
|
SendMessage( hwndLb, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM )&rectD );
|
|
dyItem = (DWORD)SendMessage( hwndLb, CB_GETITEMHEIGHT, 0, 0 );
|
|
cItemsInDrop = (rectD.bottom - rectU.bottom) / dyItem;
|
|
cItemsInList = ComboBox_GetCount( hwndLb );
|
|
if (cItemsInDrop < cItemsInList)
|
|
dxNew += GetSystemMetrics( SM_CXVSCROLL );
|
|
}
|
|
|
|
SendMessage( hwndLb, CB_SETDROPPEDWIDTH, dxNew, 0 );
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Adds data item 'pItem' with displayed text 'pszText' to listbox
|
|
// 'hwndLb'. The item is added sorted if the listbox has LBS_SORT style,
|
|
// or to the end of the list otherwise. If the listbox has LB_HASSTRINGS
|
|
// style, 'pItem' is a null terminated string, otherwise it is any user
|
|
// defined data.
|
|
//
|
|
// Returns the index of the item in the list or negative if error.
|
|
//
|
|
|
|
INT
|
|
ComboBox_AddItem(
|
|
IN HWND hwndLb,
|
|
IN LPCTSTR pszText,
|
|
IN VOID* pItem
|
|
)
|
|
{
|
|
INT nIndex;
|
|
|
|
nIndex = ComboBox_AddString( hwndLb, pszText );
|
|
if (nIndex >= 0)
|
|
ComboBox_SetItemData( hwndLb, nIndex, pItem );
|
|
return nIndex;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Returns the address of the 'nIndex'th item context in 'hwndLb' or NULL
|
|
// if none.
|
|
//
|
|
|
|
VOID*
|
|
ComboBox_GetItemDataPtr (
|
|
IN HWND hwndLb,
|
|
IN INT nIndex
|
|
)
|
|
{
|
|
LRESULT lResult;
|
|
|
|
if (nIndex < 0)
|
|
return NULL;
|
|
|
|
lResult = ComboBox_GetItemData( hwndLb, nIndex );
|
|
if (lResult < 0)
|
|
return NULL;
|
|
|
|
return (VOID* )lResult;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Returns heap block containing the text contents of the 'nIndex'th item
|
|
// of combo box 'hwnd' or NULL. It is caller's responsibility to Free the
|
|
// returned string.
|
|
//
|
|
|
|
TCHAR*
|
|
ComboBox_GetPsz (
|
|
IN HWND hwnd,
|
|
IN INT nIndex
|
|
)
|
|
{
|
|
INT cch;
|
|
TCHAR* psz;
|
|
|
|
cch = ComboBox_GetLBTextLen( hwnd, nIndex );
|
|
if (cch < 0)
|
|
return NULL;
|
|
|
|
psz = new TCHAR[( cch + 1)];
|
|
|
|
if (psz)
|
|
{
|
|
*psz = TEXT('\0');
|
|
ComboBox_GetLBText( hwnd, nIndex, psz );
|
|
}
|
|
|
|
return psz;
|
|
}
|
|
|
|
|
|
static WCHAR WZCSVC_SERVICE_NAME[] = L"WZCSVC";
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// ElCanEapolRunOnInterface:
|
|
//
|
|
// Function to verify if EAPOL can ever be started on an interface
|
|
//
|
|
// Returns TRUE if:
|
|
// WZCSVC service is running and WZCSVC has bound to the interface
|
|
//
|
|
//
|
|
|
|
BOOL
|
|
ElCanEapolRunOnInterface (
|
|
IN INetConnection *pconn
|
|
)
|
|
{
|
|
SC_HANDLE hServiceCM = NULL;
|
|
SC_HANDLE hWZCSVCService = NULL;
|
|
SERVICE_STATUS WZCSVCServiceStatus;
|
|
WCHAR wszGuid[c_cchGuidWithTerm];
|
|
NETCON_PROPERTIES* pProps = NULL;
|
|
BOOL fIsOK = TRUE;
|
|
DWORD dwType = 0;
|
|
DWORD dwSizeOfList = 0;
|
|
WCHAR *pwszRegInterfaceList = NULL;
|
|
DWORD dwDisposition = 0;
|
|
HKEY hkey = NULL;
|
|
EAPOL_INTF_PARAMS EapolIntfParams;
|
|
LONG lError = ERROR_SUCCESS;
|
|
DWORD dwRetCode = NO_ERROR;
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
|
|
//
|
|
// Query status of WZCSVC service
|
|
// Do not display tab if WZCSVC service is not running
|
|
//
|
|
|
|
if ((hServiceCM = OpenSCManager ( NULL, NULL, GENERIC_READ ))
|
|
== NULL)
|
|
{
|
|
dwRetCode = GetLastError ();
|
|
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: OpenSCManager failed with error %ld",
|
|
dwRetCode);
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
|
|
if ((hWZCSVCService =
|
|
OpenService ( hServiceCM, WZCSVC_SERVICE_NAME, GENERIC_READ ))
|
|
== NULL)
|
|
{
|
|
dwRetCode = GetLastError ();
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: OpenService failed with error %ld",
|
|
dwRetCode);
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (!QueryServiceStatus ( hWZCSVCService, &WZCSVCServiceStatus ))
|
|
{
|
|
dwRetCode = GetLastError ();
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: StartService failed with error %ld",
|
|
dwRetCode);
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
|
|
if ( WZCSVCServiceStatus.dwCurrentState != SERVICE_RUNNING )
|
|
{
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: WZCSVC service not running !!!");
|
|
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: WZCSVC service is indeed running !!!");
|
|
|
|
if (!CloseServiceHandle ( hWZCSVCService ))
|
|
{
|
|
dwRetCode = GetLastError ();
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: CloseService failed with error %ld",
|
|
dwRetCode);
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
hWZCSVCService = NULL;
|
|
|
|
if (!CloseServiceHandle ( hServiceCM ))
|
|
{
|
|
dwRetCode = GetLastError ();
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: CloseService failed with error %ld",
|
|
dwRetCode);
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
hServiceCM = NULL;
|
|
|
|
//
|
|
// Check if NDISUIO is bound to interface
|
|
//
|
|
|
|
hr = pconn->GetProperties (&pProps);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (::StringFromGUID2 (pProps->guidId, wszGuid, c_cchGuidWithTerm)
|
|
== 0)
|
|
{
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: StringFromGUID2 failed");
|
|
fIsOK = FALSE;
|
|
FreeNetconProperties(pProps);
|
|
break;
|
|
}
|
|
FreeNetconProperties(pProps);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Fetch InterfaceList from registry
|
|
// Search for GUID string in registry
|
|
|
|
// Get handle to
|
|
// HKLM\Software\Microsoft\EAPOL\Parameters\Interfaces\General
|
|
|
|
hr = HrRegCreateKeyEx (
|
|
HKEY_LOCAL_MACHINE,
|
|
cszEapKeyEapolServiceParams,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
NULL,
|
|
&hkey,
|
|
&dwDisposition);
|
|
if (!SUCCEEDED (hr))
|
|
{
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: Error in HrRegCreateKeyEx for base key, %ld",
|
|
LresFromHr(hr));
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
|
|
|
|
// Query the value of
|
|
// ...\EAPOL\Parameters\Interfaces\General\InterfaceList key
|
|
|
|
dwSizeOfList = 0;
|
|
|
|
hr = HrRegQueryValueEx (
|
|
hkey,
|
|
cszInterfaceList,
|
|
&dwType,
|
|
NULL,
|
|
&dwSizeOfList);
|
|
if (SUCCEEDED (hr))
|
|
{
|
|
pwszRegInterfaceList = (WCHAR *) new BYTE [dwSizeOfList];
|
|
if (pwszRegInterfaceList == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
|
|
hr = HrRegQueryValueEx (
|
|
hkey,
|
|
cszInterfaceList,
|
|
&dwType,
|
|
(LPBYTE)pwszRegInterfaceList,
|
|
&dwSizeOfList);
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: Error in HrRegQueryValueEx acquiring value for InterfaceList, %ld",
|
|
LresFromHr(hr));
|
|
break;
|
|
}
|
|
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: Query value succeeded = %ws, size=%ld, search GUID = %ws",
|
|
pwszRegInterfaceList, dwSizeOfList, wszGuid);
|
|
}
|
|
else
|
|
{
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: Error in HrRegQueryValueEx size estimation for InterfaceList, %ld",
|
|
LresFromHr(hr));
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (wcsstr (pwszRegInterfaceList, wszGuid))
|
|
{
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface interface found in interface list !!!");
|
|
}
|
|
else
|
|
{
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface interface *not* found in interface list !!!");
|
|
fIsOK = FALSE;
|
|
break;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
if (hkey != NULL)
|
|
{
|
|
RegSafeCloseKey (hkey);
|
|
}
|
|
|
|
if (pwszRegInterfaceList != NULL)
|
|
{
|
|
free (pwszRegInterfaceList);
|
|
}
|
|
|
|
if (hWZCSVCService != NULL)
|
|
{
|
|
if (!CloseServiceHandle ( hWZCSVCService ))
|
|
{
|
|
dwRetCode = GetLastError ();
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: CloseService failed with error %ld",
|
|
dwRetCode);
|
|
}
|
|
}
|
|
|
|
if (hServiceCM != NULL)
|
|
{
|
|
if (!CloseServiceHandle ( hServiceCM ))
|
|
{
|
|
dwRetCode = GetLastError ();
|
|
TraceTag (ttidLanUi, "ElCanEapolRunOnInterface: CloseService failed with error %ld",
|
|
dwRetCode);
|
|
}
|
|
}
|
|
|
|
return fIsOK;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef ENABLETRACE
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: PrintBindingPath
|
|
//
|
|
// Purpose: Prints the binding path ID and a list of component IDs on
|
|
// the path from top down
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: tongl 26 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID PrintBindingPath (
|
|
TRACETAGID ttidToTrace,
|
|
INetCfgBindingPath* pncbp,
|
|
PCSTR pszaExtraText)
|
|
{
|
|
Assert (pncbp);
|
|
|
|
if (!pszaExtraText)
|
|
{
|
|
pszaExtraText = "";
|
|
}
|
|
|
|
const WCHAR c_szSept[] = L"->";
|
|
|
|
tstring strPath;
|
|
INetCfgComponent * pnccNetComponent;
|
|
PWSTR pszwCompId;
|
|
HRESULT hr;
|
|
|
|
// Get the top component
|
|
hr = pncbp->GetOwner(&pnccNetComponent);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pnccNetComponent->GetId(&pszwCompId);
|
|
if SUCCEEDED(hr)
|
|
{
|
|
strPath += pszwCompId;
|
|
CoTaskMemFree(pszwCompId);
|
|
}
|
|
}
|
|
ReleaseObj(pnccNetComponent);
|
|
|
|
// Get Comp ID for other component on the path
|
|
CIterNetCfgBindingInterface ncbiIter(pncbp);
|
|
INetCfgBindingInterface * pncbi;
|
|
|
|
//Go through interfaces of the binding path
|
|
while (SUCCEEDED(hr) && (hr = ncbiIter.HrNext(&pncbi)) == S_OK)
|
|
{
|
|
strPath += c_szSept;
|
|
|
|
// Get the lower component
|
|
hr = pncbi->GetLowerComponent(&pnccNetComponent);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pnccNetComponent->GetId(&pszwCompId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
strPath += pszwCompId;
|
|
CoTaskMemFree(pszwCompId);
|
|
}
|
|
}
|
|
ReleaseObj(pnccNetComponent);
|
|
ReleaseObj(pncbi);
|
|
}
|
|
|
|
if (hr == S_FALSE) // We just got to the end of the loop
|
|
hr = S_OK;
|
|
|
|
BOOL fEnabled = (S_OK == pncbp->IsEnabled());
|
|
|
|
// Now print the path and ID
|
|
char szaBuf[1024];
|
|
wsprintfA (szaBuf, "[%s] %S: %s",
|
|
(fEnabled) ? "x" : " ",
|
|
strPath.c_str(),
|
|
pszaExtraText);
|
|
|
|
TraceTag (ttidToTrace, szaBuf);
|
|
|
|
TraceError ("PrintBindingPath", hr);
|
|
}
|
|
#endif //ENABLETRACE
|
|
|
|
|
|
|