|
|
// Copyright (c) 1995, Microsoft Corporation, all rights reserved
//
// penettab.c
// Remote Access Common Dialog APIs
// Phonebook Entry property sheet (Networking tab)
//
// 12/10/97 Shaun Cox
//
#include "rasdlgp.h"
#include "entryps.h"
#include "inetcfgp.h"
#include "initguid.h"
#include "netcfgp.h"
#include "netconp.h"
#include "devguid.h"
#include "uiinfo.h"
typedef struct _MAP_SZ_DWORD { LPCTSTR pszValue; DWORD dwValue; } MAP_SZ_DWORD;
//For whistler bug#194394
//For 64bit, IPX wont show up
//For 32/64 bit, NETBEUI wont show up
//
#ifdef _WIN64
static const MAP_SZ_DWORD c_mapProtocols [] = { { NETCFG_TRANS_CID_MS_TCPIP, NP_Ip }, { NETCFG_TRANS_CID_MS_NETMON, NP_Netmon }, }; #else
static const MAP_SZ_DWORD c_mapProtocols [] = { { NETCFG_TRANS_CID_MS_TCPIP, NP_Ip }, { NETCFG_TRANS_CID_MS_NWIPX, NP_Ipx }, { NETCFG_TRANS_CID_MS_NETMON, NP_Netmon }, }; #endif
//+---------------------------------------------------------------------------
//
// Function: DwProtocolFromComponentId
//
// Purpose: Return the DWORD value of the protocol corresponding to
// the string value in c_mapProtocols.
//
// Arguments:
// pszComponentId [in] Component id to find.
//
// Returns: NP_xxx value
//
// Author: shaunco 13 Dec 1997
//
// Notes: The input argument must exist in c_mapProtocols.
//
DWORD DwProtocolFromComponentId ( LPCTSTR pszComponentId) { int i; for (i = 0; i < sizeof(c_mapProtocols) / sizeof(c_mapProtocols[0]); i++) { if (0 == lstrcmpi (pszComponentId, c_mapProtocols[i].pszValue)) { return c_mapProtocols[i].dwValue; } } // Should never get here as we should never pass a protocol that is not
// in c_mapProtocols.
//
ASSERT (FALSE); return 0; }
//+---------------------------------------------------------------------------
//
// Function: GetComponentImageIndex
//
// Purpose: Returns the index into pcild corresponding to the class of
// pComponent.
//
// Arguments:
// pComponent [in] Component who's class should be used.
// pcild [in] Returned from SetupDiGetClassImageList
//
// Returns: A valid index or zero (which may also be valid).
//
// Author: shaunco 12 Dec 1997
//
// Notes:
//
int GetComponentImageIndex ( INetCfgComponent* pComponent, SP_CLASSIMAGELIST_DATA* pcild) { int iImage = 0;
GUID guidClass; HRESULT hr = INetCfgComponent_GetClassGuid (pComponent, &guidClass); if (SUCCEEDED(hr)) { SetupDiGetClassImageIndex (pcild, &guidClass, &iImage); }
return iImage; }
//+---------------------------------------------------------------------------
//
// Function: HrEnumComponentsForListView
//
// Purpose: Return an array of INetCfgComponents that are candidates
// for adding to our list view. This is composed of all
// clients and servcies, and a few select protocols. (No
// net adapters.) Hidden components could be returned and
// should be checked before adding to the list view.
//
// Arguments:
// pNetCfg [in]
// celt [in]
// rgelt [out]
// pceltFetched [out]
//
// Returns: S_OK or an error.
//
// Author: shaunco 12 Dec 1997
//
// Notes:
//
HRESULT HrEnumComponentsForListView ( INetCfg* pNetCfg, ULONG celt, INetCfgComponent** rgelt, ULONG* pceltFetched) { static const GUID* c_apguidClasses [] = { &GUID_DEVCLASS_NETCLIENT, &GUID_DEVCLASS_NETSERVICE, };
HRESULT hr; int i; ULONG celtFetched = 0;
// Initialize the output parameters.
//
ZeroMemory (rgelt, celt * sizeof (*rgelt)); *pceltFetched = 0;
// Enumerate the clients and services.
//
hr = HrEnumComponentsInClasses (pNetCfg, sizeof(c_apguidClasses) / sizeof(c_apguidClasses[0]), (GUID**)c_apguidClasses, celt, rgelt, &celtFetched);
// Find the protocols if they are installed.
//
for (i = 0; i < sizeof(c_mapProtocols) / sizeof(c_mapProtocols[0]); i++) { INetCfgComponent* pComponent; hr = INetCfg_FindComponent (pNetCfg, c_mapProtocols[i].pszValue, &pComponent); if (S_OK == hr) { rgelt [celtFetched++] = pComponent; } }
*pceltFetched = celtFetched; return S_OK; }
//+---------------------------------------------------------------------------
//
// Function: HrNeRefreshListView
//
// Purpose: Clear and re-add all of the items that belong in the list
// view.
//
// Arguments:
// pInfo [in]
//
// Returns: S_OK or an error code.
//
// Author: shaunco 12 Dec 1997
//
// Notes:
//
HRESULT HrNeRefreshListView ( PEINFO* pInfo) { HRESULT hr = S_OK; INetCfgComponent* aComponents [256]; ULONG cComponents; HIMAGELIST himlSmall; PBENTRY* pEntry = pInfo->pArgs->pEntry; PBFILE* pFile = pInfo->pArgs->pFile;
// Delete all existing items. The LVN_DELETEITEM handler is expected to
// release the objects we have attached prior.
//
ListView_DeleteAllItems (pInfo->hwndLvComponents);
hr = HrEnumComponentsForListView (pInfo->pNetCfg, sizeof(aComponents)/sizeof(aComponents[0]), aComponents, &cComponents); if (SUCCEEDED(hr)) { BOOL fHasPermission = TRUE; ULONG i;
// check if user has any permission to change the bindings
INetConnectionUiUtilities * pncuu = NULL;
hr = HrCreateNetConnectionUtilities(&pncuu); if (SUCCEEDED(hr)) { fHasPermission = INetConnectionUiUtilities_UserHasPermission( pncuu, NCPERM_ChangeBindState);
INetConnectionUiUtilities_Release(pncuu); }
for (i = 0; i < cComponents; i++) { INetCfgComponent* pComponent = aComponents [i]; DWORD dwCharacter; LPWSTR pszwName = NULL; LPWSTR pszwId = NULL; int iItem; LV_ITEM item = {0}; BOOL fCheck, fForceCheck = FALSE; GUID guid; BOOL fDisableCheckbox = FALSE;
// We'll release it if inserting it failed or we decided to
// skip it. By not releasing it, we pass ownership to the
// list view.
//
BOOL fReleaseComponent = TRUE;
// Don't add hidden components. Silently skip components
// that we fail to get the class GUID or display name for.
// (After all, what could we have the user do to fix the error?
// Might as well show them what we can.)
//
if ( FAILED(INetCfgComponent_GetCharacteristics (pComponent, &dwCharacter)) || (dwCharacter & NCF_HIDDEN) || FAILED(INetCfgComponent_GetDisplayName (pComponent, &pszwName))) { goto skip_component; } if (SUCCEEDED(INetCfgComponent_GetId(pComponent, &pszwId))) { WCHAR * pszwTmpId = NULL;
//for whistler bug 29356 filter out Network Load Balancing
//
pszwTmpId = StrDupWFromT(NETCFG_SERVICE_CID_MS_WLBS);
if(pszwTmpId) { if ( 0 == lstrcmpW(pszwId, pszwTmpId)) { Free0(pszwTmpId); CoTaskMemFree (pszwId); goto skip_component; } Free0(pszwTmpId); }
//
//for .Net 605988 filter out IPX for x86 router case
// IPX is already filtered our for 64 bit case
//
if( pInfo->pArgs->fRouter ) { pszwTmpId = StrDupWFromT(NETCFG_TRANS_CID_MS_NWIPX); if(pszwTmpId) { if ( 0 == lstrcmpW(pszwId, pszwTmpId)) { Free0(pszwTmpId); CoTaskMemFree (pszwId); goto skip_component; } Free0(pszwTmpId); }
pszwTmpId = StrDupWFromT( TEXT("ms_nwnb") ); if(pszwTmpId) { if ( 0 == lstrcmpW(pszwId, pszwTmpId)) { Free0(pszwTmpId); CoTaskMemFree(pszwId); return FALSE; } Free0(pszwTmpId); } } CoTaskMemFree (pszwId); }
// Disable the checkbox on components whose bindings are not user adjustable
// or user has no permission to adjust binding
if (NCF_FIXED_BINDING & dwCharacter) { fDisableCheckbox = TRUE; }
// Bug #157213: Don't add any protocols other than IP if SLIP
// is enabled
//
// Bug #294401: Also filter out CSNW when server type is SLIP
if (pInfo->pArgs->pEntry->dwBaseProtocol == BP_Slip) { if (SUCCEEDED(INetCfgComponent_GetClassGuid(pComponent, &guid))) { BOOL fSkip = FALSE;
if (IsEqualGUID(&guid, &GUID_DEVCLASS_NETTRANS)) { if (SUCCEEDED(INetCfgComponent_GetId(pComponent, &pszwId))) { if (DwProtocolFromComponentId(pszwId) == NP_Ip) { // This item is IP. We should disable the check
// box so the user can't disable TCP/IP in SLIP
// mode. This is done after the item is inserted.
//
fDisableCheckbox = TRUE;
// 122024
//
// We should also force the ui to show ip as enabled
// since IP is always used with SLIP.
//
fForceCheck = TRUE; } else { fSkip = TRUE; }
CoTaskMemFree (pszwId); } } else if (IsEqualGUID(&guid, &GUID_DEVCLASS_NETCLIENT)) { if (SUCCEEDED(INetCfgComponent_GetId(pComponent, &pszwId))) { // For whistler 522872
if ( CSTR_EQUAL == CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, L"MS_NWCLIENT", -1, pszwId, -1 ) ) { fSkip = TRUE; } CoTaskMemFree (pszwId); } }
if (fSkip) { goto skip_component; } } }
// pmay: 348623
//
// If we are remote admining a router, only allow tcpip and
// ipx to be displayed.
//
if (pInfo->pArgs->fRouter && pInfo->pArgs->fRemote) { if (SUCCEEDED(INetCfgComponent_GetClassGuid(pComponent, &guid))) { BOOL fSkip = TRUE; DWORD dwId;
if (IsEqualGUID(&guid, &GUID_DEVCLASS_NETTRANS)) { if (SUCCEEDED(INetCfgComponent_GetId(pComponent, &pszwId))) { dwId = DwProtocolFromComponentId(pszwId); if ((dwId == NP_Ip) || (dwId == NP_Ipx)) { fSkip = FALSE; } CoTaskMemFree (pszwId); } } if (fSkip) { goto skip_component; } } }
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; item.pszText = pszwName; item.iImage = GetComponentImageIndex (pComponent, &pInfo->cild); item.lParam = (LPARAM)pComponent;
// Add the item.
//
iItem = ListView_InsertItem (pInfo->hwndLvComponents, &item); if (-1 != iItem) { // List view now has it. We can't release it.
//
fReleaseComponent = FALSE;
// Set its check state.
//
if (! fForceCheck) { fCheck = NeIsComponentEnabled (pInfo, pComponent); } else { fCheck = TRUE; } ListView_SetCheck (pInfo->hwndLvComponents, iItem, fCheck);
// Disable the checkbox if this is psched. We don't allow
// users to change check state of psched from ras connections.
// bug 255749 [raos].
//
if(SUCCEEDED(INetCfgComponent_GetId(pComponent, &pszwId))) { // Check to see if this is psched.
//
if( (0 == _wcsicmp(pszwId, L"ms_psched")) || (0 == _wcsicmp(pszwId, L"ms_NetMon"))) { fDisableCheckbox = TRUE; } }
if (fDisableCheckbox) { ListView_DisableCheck(pInfo->hwndLvComponents, iItem); } }
skip_component:
if (fReleaseComponent) { ReleaseObj (pComponent); }
CoTaskMemFree (pszwName); }
// Select first item
ListView_SetItemState(pInfo->hwndLvComponents, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); }
return hr; }
//+---------------------------------------------------------------------------
//
// Function: PComponentFromItemIndex
//
// Purpose: Return the INetCfgComponent associated with the specified
// list view item.
//
// Arguments:
// hwndLv [in]
// iItem [in]
//
// Returns: A (non-AddRef'd) copy of the INetCfgComponent pointer
// associated with the item.
//
// Author: shaunco 14 Dec 1997
//
// Notes: The returned value is NOT AddRef'd.
//
INetCfgComponent* PComponentFromItemIndex ( HWND hwndLv, int iItem) { INetCfgComponent* pComponent = NULL; LV_ITEM item = {0};
item.mask = LVIF_PARAM; item.iItem = iItem; if (ListView_GetItem (hwndLv, &item)) { pComponent = (INetCfgComponent*)item.lParam; ASSERT (pComponent); } return pComponent; }
//+---------------------------------------------------------------------------
//
// Function: PComponentFromCurSel
//
// Purpose:
//
// Arguments:
// hwndLv [in] Window handle of list view
// piItem [out] Optional address of integer to receive selected item.
//
// Returns:
//
// Author: shaunco 30 Dec 1997
//
// Notes:
//
INetCfgComponent* PComponentFromCurSel ( HWND hwndLv, int* piItem) { INetCfgComponent* pComponent = NULL;
// Get the current selection if it exists.
//
int iItem = ListView_GetNextItem (hwndLv, -1, LVNI_SELECTED); if (-1 != iItem) { // Get the component associated with the current selection. It must
// exist.
//
pComponent = PComponentFromItemIndex (hwndLv, iItem); ASSERT (pComponent); }
// Return the index of the item if requested.
//
if (piItem) { *piItem = iItem; }
return pComponent; }
//+---------------------------------------------------------------------------
//
// Function: PeQueryOrChangeComponentEnabled
//
// Purpose:
//
// Arguments:
// pInfo []
// pComponent []
// fChange []
// fNewValue []
//
// Returns:
//
// Author: shaunco 14 Dec 1997
//
// Notes:
//
BOOL NeQueryOrChangeComponentEnabled ( PEINFO* pInfo, INetCfgComponent* pComponent, BOOL fChange, BOOL fValue) { BOOL fOldValue; GUID guidClass; HRESULT hr;
hr = INetCfgComponent_GetClassGuid (pComponent, &guidClass); if (SUCCEEDED(hr)) { LPWSTR pszwId; hr = INetCfgComponent_GetId (pComponent, &pszwId); if (SUCCEEDED(hr)) { // We handle protocols in a hard-coded (er, well known) fashion.
//
if (IsEqualGUID (&guidClass, &GUID_DEVCLASS_NETTRANS)) { DWORD* pdwValue = &pInfo->pArgs->pEntry->dwfExcludedProtocols;
// Check if the protocol is exluded.
//
DWORD dwProtocol = DwProtocolFromComponentId (pszwId);
if (fChange) { if (fValue) { // Include the protocol. (By not explicitly excluding
// it.
//
*pdwValue &= ~dwProtocol; } else { // Exclude the protocol. (Remember, its a list of
// excluded protocols.
//
*pdwValue |= dwProtocol; } } else { fValue = !(dwProtocol & *pdwValue); } } else { if (fChange) { EnableOrDisableNetComponent (pInfo->pArgs->pEntry, pszwId, fValue); } else { // Default to enabled for the case whenthe value isn't
// found in the entry. This will be the case for pre-NT5
// entries and entries that have not yet been to the
// Networking tab for edits.
//
BOOL fEnabled; fValue = TRUE; if (FIsNetComponentListed(pInfo->pArgs->pEntry, pszwId, &fEnabled, NULL)) { fValue = fEnabled; } } }
CoTaskMemFree (pszwId); } } return fValue; }
VOID NeEnableComponent ( PEINFO* pInfo, INetCfgComponent* pComponent, BOOL fEnable) { NeQueryOrChangeComponentEnabled (pInfo, pComponent, TRUE, fEnable); }
BOOL NeIsComponentEnabled ( PEINFO* pInfo, INetCfgComponent* pComponent) { return NeQueryOrChangeComponentEnabled (pInfo, pComponent, FALSE, FALSE); }
VOID NeShowComponentProperties ( IN PEINFO* pInfo) { HRESULT hr;
// Get the component for the current selection.
//
INetCfgComponent* pComponent; pComponent = PComponentFromCurSel (pInfo->hwndLvComponents, NULL); ASSERT (pComponent);
if(NULL == pComponent) { return; }
// Create the UI info callback object if we haven't done so yet.
// If this fails, we can still show properties. TCP/IP just might
// not know which UI-variant to show.
//
if (!pInfo->punkUiInfoCallback) { HrCreateUiInfoCallbackObject (pInfo, &pInfo->punkUiInfoCallback); }
// Show the component's property UI. If S_OK is returned, it means
// something changed.
//
hr = INetCfgComponent_RaisePropertyUi (pComponent, pInfo->hwndDlg, NCRP_SHOW_PROPERTY_UI, pInfo->punkUiInfoCallback);
if (S_OK == hr) { // Get the INetCfgComponentPrivate interface so we can query the
// notify object directly.
//
INetCfgComponentPrivate* pPrivate; hr = INetCfgComponent_QueryInterface (pComponent, &IID_INetCfgComponentPrivate, (VOID**)&pPrivate); if (SUCCEEDED(hr)) { // Get the INetRasConnectionIpUiInfo interface from the notify
// object.
//
INetRasConnectionIpUiInfo* pIpUiInfo; hr = INetCfgComponentPrivate_QueryNotifyObject (pPrivate, &IID_INetRasConnectionIpUiInfo, (VOID**)&pIpUiInfo); if (SUCCEEDED(hr)) { // Get the UI info from TCP/IP.
//
RASCON_IPUI info; hr = INetRasConnectionIpUiInfo_GetUiInfo (pIpUiInfo, &info); if (SUCCEEDED(hr)) { PBENTRY* pEntry = pInfo->pArgs->pEntry;
// Get rid of our current data before we copy the new
// data.
//
pEntry->dwIpAddressSource = ASRC_ServerAssigned; pEntry->dwIpNameSource = ASRC_ServerAssigned;
Free0 (pEntry->pszIpAddress); pEntry->pszIpAddress = NULL;
Free0 (pEntry->pszIpDnsAddress); pEntry->pszIpDnsAddress = NULL;
Free0 (pEntry->pszIpDns2Address); pEntry->pszIpDns2Address = NULL;
Free0 (pEntry->pszIpWinsAddress); pEntry->pszIpWinsAddress = NULL;
Free0 (pEntry->pszIpWins2Address); pEntry->pszIpWins2Address = NULL;
Free0 (pEntry->pszIpDnsSuffix); pEntry->pszIpDnsSuffix = StrDup (info.pszwDnsSuffix);
if ((info.dwFlags & RCUIF_USE_IP_ADDR) && *info.pszwIpAddr) { pEntry->dwIpAddressSource = ASRC_RequireSpecific; pEntry->pszIpAddress = StrDup (info.pszwIpAddr); } else { pEntry->dwIpAddressSource = ASRC_ServerAssigned; Free0 (pEntry->pszIpAddress); pEntry->pszIpAddress = NULL; }
if (info.dwFlags & RCUIF_USE_NAME_SERVERS) { if (*info.pszwDnsAddr) { pEntry->dwIpNameSource = ASRC_RequireSpecific; pEntry->pszIpDnsAddress = StrDup (info.pszwDnsAddr); } if (*info.pszwDns2Addr) { pEntry->dwIpNameSource = ASRC_RequireSpecific; pEntry->pszIpDns2Address = StrDup (info.pszwDns2Addr); } if (*info.pszwWinsAddr) { pEntry->dwIpNameSource = ASRC_RequireSpecific; pEntry->pszIpWinsAddress = StrDup (info.pszwWinsAddr); } if (*info.pszwWins2Addr) { pEntry->dwIpNameSource = ASRC_RequireSpecific; pEntry->pszIpWins2Address = StrDup (info.pszwWins2Addr); } }
// pmay: 389632
//
// Use this convoluted logic to store something reasonable
// about the registration process.
//
if (info.dwFlags & RCUIF_USE_DISABLE_REGISTER_DNS) { pEntry->dwIpDnsFlags = 0; } else { BOOL bSuffix = ((pEntry->pszIpDnsSuffix) && (*(pEntry->pszIpDnsSuffix))); pEntry->dwIpDnsFlags = DNS_RegPrimary; if (info.dwFlags & RCUIF_USE_PRIVATE_DNS_SUFFIX) { if (bSuffix) { pEntry->dwIpDnsFlags |= DNS_RegPerConnection; } else { pEntry->dwIpDnsFlags |= DNS_RegDhcpInform; } } }
// 277478
// Enable the NBT over IP controls
//
if (info.dwFlags & RCUIF_ENABLE_NBT) { pEntry->dwIpNbtFlags = PBK_ENTRY_IP_NBT_Enable; } else { pEntry->dwIpNbtFlags = 0; } if (pInfo->pArgs->fRouter) { pEntry->fIpPrioritizeRemote = FALSE; } else { pEntry->fIpPrioritizeRemote = info.dwFlags & RCUIF_USE_REMOTE_GATEWAY; } pEntry->fIpHeaderCompression = info.dwFlags & RCUIF_USE_HEADER_COMPRESSION; pEntry->dwFrameSize = info.dwFrameSize; } ReleaseObj (pIpUiInfo); }
ReleaseObj (pPrivate); }
} }
|