Leaked source code of windows server 2003
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.
 
 
 
 
 
 

6360 lines
181 KiB

// Copyright (c) 1995, Microsoft Corporation, all rights reserved
//
// entryps.c
// Remote Access Common Dialog APIs
// Phonebook Entry property sheet
//
// 06/20/95 Steve Cobb
//
#include "rasdlgp.h"
#include "entryps.h"
#include "uiinfo.h"
#include "inetcfgp.h"
#include "netcon.h"
#include "rassrvrc.h"
#include "shlobjp.h"
#include "shellapi.h"
#include "iphlpapi.h"
#include "prsht.h"
#include "pbkp.h"
// Page definitions.
//
#define PE_GePage 0
#define PE_OePage 1
#define PE_LoPage 2
#define PE_NePage 3
#define PE_SaPage 4
#define PE_PageCount 5
// (Router) Callback context block.
//
#define CRINFO struct tagCRINFO
CRINFO
{
/* Caller's argument to the stub API.
*/
EINFO* pArgs;
/* Dialog and control handles.
*/
HWND hwndDlg;
HWND hwndRbNo;
HWND hwndRbYes;
HWND hwndLvNumbers;
HWND hwndPbEdit;
HWND hwndPbDelete;
};
static TCHAR g_pszFirewallRegKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\HomeNetworking\\PersonalFirewall");
static TCHAR g_pszDisableFirewallWarningValue[] = TEXT("ShowDisableFirewallWarning");
//----------------------------------------------------------------------------
// Help maps
//----------------------------------------------------------------------------
static const DWORD g_adwGeHelp[] =
{
CID_GE_GB_ConnectUsing, HID_GE_LV_Device, //HID_GE_GB_ConnectUsing,
CID_GE_LV_Device, HID_GE_LV_Device,
CID_GE_LV_Devices, HID_GE_LV_Devices,
CID_GE_PB_MoveUp, HID_GE_PB_MoveUp,
CID_GE_PB_MoveDown, HID_GE_PB_MoveDown,
CID_GE_CB_SharedPhoneNumber, HID_GE_CB_SharedPhoneNumber,
CID_GE_PB_Configure, HID_GE_PB_Configure,
CID_GE_ST_AreaCodes, HID_GE_CLB_AreaCodes,
CID_GE_CLB_AreaCodes, HID_GE_CLB_AreaCodes,
CID_GE_ST_PhoneNumber, HID_GE_EB_PhoneNumber,
CID_GE_EB_PhoneNumber, HID_GE_EB_PhoneNumber,
CID_GE_ST_CountryCodes, HID_GE_LB_CountryCodes,
CID_GE_LB_CountryCodes, HID_GE_LB_CountryCodes,
CID_GE_CB_UseDialingRules, HID_GE_CB_UseDialingRules,
CID_GE_PB_Alternates, HID_GE_PB_Alternates,
CID_GE_CB_ShowIcon, HID_GE_CB_ShowIcon,
CID_GE_ST_HostName, HID_GE_EB_HostName,
CID_GE_EB_HostName, HID_GE_EB_HostName,
CID_GE_ST_ServiceName, HID_GE_EB_ServiceName, //Add for whistler bug 343249
CID_GE_EB_ServiceName, HID_GE_EB_ServiceName,
CID_GE_GB_FirstConnect, -1, //HID_GE_GB_FirstConnect,
CID_GE_ST_Explain, HID_GE_GB_FirstConnect,
CID_GE_CB_DialAnotherFirst, HID_GE_CB_DialAnotherFirst,
CID_GE_LB_DialAnotherFirst, HID_GE_LB_DialAnotherFirst,
CID_GE_ST_Devices, HID_GE_LB_Devices,
CID_GE_LB_Devices, HID_GE_LB_Devices,
CID_GE_PB_DialingRules, HID_GE_PB_DialingRules,
CID_GE_GB_PhoneNumber, -1,
0, 0
};
static const DWORD g_adwOeHelp[] =
{
CID_OE_GB_Progress, -1, //commented for bug 15738//HID_OE_GB_Progress,
CID_OE_CB_DisplayProgress, HID_OE_CB_DisplayProgress,
CID_OE_CB_PreviewUserPw, HID_OE_CB_PreviewUserPw,
CID_OE_CB_PreviewDomain, HID_OE_CB_PreviewDomain,
CID_OE_CB_PreviewNumber, HID_OE_CB_PreviewNumber,
CID_OE_GB_Redial, -1, //commented for bug 15738//HID_OE_GB_Redial,
CID_OE_ST_RedialAttempts, HID_OE_EB_RedialAttempts,
CID_OE_EB_RedialAttempts, HID_OE_EB_RedialAttempts,
CID_OE_ST_RedialTimes, HID_OE_LB_RedialTimes,
CID_OE_LB_RedialTimes, HID_OE_LB_RedialTimes,
CID_OE_ST_IdleTimes, HID_OE_LB_IdleTimes,
CID_OE_LB_IdleTimes, HID_OE_LB_IdleTimes,
CID_OE_CB_RedialOnDrop, HID_OE_CB_RedialOnDrop,
CID_OE_GB_MultipleDevices, -1, //commented for bug 15738//HID_OE_GB_MultipleDevices,
CID_OE_LB_MultipleDevices, HID_OE_LB_MultipleDevices,
CID_OE_PB_Configure, HID_OE_PB_Configure,
CID_OE_PB_X25, HID_OE_PB_X25,
CID_OE_PB_Tunnel, HID_OE_PB_Tunnel,
CID_OE_RB_DemandDial, HID_OE_RB_DemandDial,
CID_OE_RB_Persistent, HID_OE_RB_Persistent,
0, 0
};
static const DWORD g_adwOeRouterHelp[] =
{
CID_OE_GB_Progress, -1, //commented for bug 15738//HID_OE_GB_Progress,
CID_OE_CB_DisplayProgress, HID_OE_CB_DisplayProgress,
CID_OE_CB_PreviewUserPw, HID_OE_CB_PreviewUserPw,
CID_OE_CB_PreviewDomain, HID_OE_CB_PreviewDomain,
CID_OE_CB_PreviewNumber, HID_OE_CB_PreviewNumber,
CID_OE_GB_Redial, -1, //commented for bug 15738//HID_OE_GB_Redial,
CID_OE_ST_RedialAttempts, HID_OE_EB_RedialAttempts,
CID_OE_EB_RedialAttempts, HID_OE_EB_RedialAttempts,
CID_OE_ST_RedialTimes, HID_OE_LB_RedialTimes,
CID_OE_LB_RedialTimes, HID_OE_LB_RedialTimes,
CID_OE_ST_IdleTimes, HID_OE_LB_IdleTimesRouter,
CID_OE_LB_IdleTimes, HID_OE_LB_IdleTimesRouter,
CID_OE_CB_RedialOnDrop, HID_OE_CB_RedialOnDrop,
CID_OE_GB_MultipleDevices, -1, //commented for bug 15738//HID_OE_GB_MultipleDevices,
CID_OE_LB_MultipleDevices, HID_OE_LB_MultipleDevices,
CID_OE_PB_Configure, HID_OE_PB_Configure,
CID_OE_PB_X25, HID_OE_PB_X25,
CID_OE_PB_Tunnel, HID_OE_PB_Tunnel,
CID_OE_RB_DemandDial, HID_OE_RB_DemandDial,
CID_OE_RB_Persistent, HID_OE_RB_Persistent,
CID_OE_PB_Callback, HID_OE_PB_Callback,
0, 0
};
//Get rid of the const qualifire for whistler bug#276452
static DWORD g_adwLoHelp[] =
{
CID_LO_GB_SecurityOptions, -1, //commented for bug 15738//HID_LO_GB_SecurityOptions,
CID_LO_RB_TypicalSecurity, HID_LO_RB_TypicalSecurity,
CID_LO_ST_Auths, HID_LO_LB_Auths,
CID_LO_LB_Auths, HID_LO_LB_Auths,
CID_LO_CB_UseWindowsPw, HID_LO_CB_UseWindowsPw,
CID_LO_CB_Encryption, HID_LO_CB_Encryption,
CID_LO_RB_AdvancedSecurity, HID_LO_RB_AdvancedSecurity,
CID_LO_ST_AdvancedText, HID_LO_PB_Advanced,
CID_LO_PB_Advanced, HID_LO_PB_Advanced,
CID_LO_GB_Scripting, -1, //commented for bug 15738//HID_LO_GB_Scripting,
CID_LO_CB_RunScript, HID_LO_CB_RunScript,
CID_LO_CB_Terminal, HID_LO_CB_Terminal,
CID_LO_LB_Scripts, HID_LO_LB_Scripts,
CID_LO_PB_Edit, HID_LO_PB_Edit,
CID_LO_PB_Browse, HID_LO_PB_Browse,
CID_LO_ST_IPSecText, HID_LO_PB_IPSec,
CID_LO_PB_IPSec, HID_LO_PB_IPSec,//On Server, this help ID will be HID_LO_PB_IPSecServer
0, 0
};
static const DWORD g_adwNeHelp[] =
{
CID_NE_ST_ServerType, HID_NE_LB_ServerType,
CID_NE_LB_ServerType, HID_NE_LB_ServerType,
CID_NE_PB_Settings, HID_NE_PB_Settings,
CID_NE_ST_Components, HID_NE_LV_Components,
CID_NE_LV_Components, HID_NE_LV_Components,
CID_NE_PB_Add, HID_NE_PB_Add,
CID_NE_PB_Remove, HID_NE_PB_Remove,
CID_NE_PB_Properties, HID_NE_PB_Properties,
CID_NE_GB_Description, -1, //commented for bug 15738//HID_NE_LB_ComponentDesc,
CID_NE_LB_ComponentDesc, HID_NE_LB_ComponentDesc,
0, 0
};
static const DWORD g_adwPpHelp[] =
{
CID_NE_EnableLcp, HID_NE_EnableLcp,
CID_NE_EnableCompression, HID_NE_EnableCompression,
CID_NE_NegotiateMultilinkAlways,HID_NE_NegotiateMultilinkAlways,
0, 0
};
static DWORD g_adwCrHelp[] =
{
CID_CR_RB_No, HID_CR_RB_No,
CID_CR_RB_Yes, HID_CR_RB_Yes,
CID_CR_PB_Edit, HID_CR_PB_Edit,
CID_CR_PB_Delete, HID_CR_PB_Delete,
CID_CR_LV_Numbers, HID_CR_LV_Numbers,
0, 0
};
static DWORD g_adwSaHelp[] =
{
CID_SA_PB_Shared, HID_SA_PB_Shared,
CID_SA_GB_Shared, -1,
CID_SA_PB_DemandDial, HID_SA_PB_DemandDial,
CID_SA_ST_DemandDial, HID_SA_PB_DemandDial,
CID_SA_PB_Settings, HID_SA_PB_Settings,
CID_SA_GB_PrivateLan, -1,
CID_SA_ST_PrivateLan, HID_SA_LB_PrivateLan,
CID_SA_LB_PrivateLan, HID_SA_LB_PrivateLan,
0, 0
};
//-----------------------------------------------------------------------------
// Local prototypes (alphabetically)
//-----------------------------------------------------------------------------
BOOL
RouterCallbackDlg(
IN HWND hwndOwner,
IN OUT EINFO* pEinfo );
INT_PTR CALLBACK
CrDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
BOOL
CrCommand(
IN CRINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl );
BOOL
CrInit(
IN HWND hwndDlg,
IN EINFO* pArgs );
VOID
CrSave(
IN CRINFO* pInfo );
VOID
CrTerm(
IN HWND hwndDlg );
VOID
CrUpdateLvAndPbState(
IN CRINFO* pInfo );
VOID
GeAlternates(
IN PEINFO* pInfo );
VOID
GeDialingRules(
IN PEINFO* pInfo );
INT_PTR CALLBACK
GeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
INT_PTR CALLBACK
GeDlgProcMultiple(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
INT_PTR CALLBACK
GeDlgProcSingle(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
VOID
GeClearLbDialAnotherFirst(
IN HWND hwndLbDialAnotherFirst );
BOOL
GeCommand(
IN PEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl );
VOID
GeConfigure(
IN PEINFO* pInfo );
VOID
GeDialAnotherFirstSelChange(
IN PEINFO* pInfo );
BOOL
GeFillLbDialAnotherFirst(
IN PEINFO* pInfo,
IN BOOL fAbortIfPrereqNotFound );
VOID
GeGetPhoneFields(
IN PEINFO* pInfo,
OUT DTLNODE* pDstLinkNode );
BOOL
GeInit(
IN HWND hwndPage,
IN OUT EINFO* pArgs );
LVXDRAWINFO*
GeLvDevicesCallbackMultiple(
IN HWND hwndLv,
IN DWORD dwItem );
LVXDRAWINFO*
GeLvDevicesCallbackSingle(
IN HWND hwndLv,
IN DWORD dwItem );
VOID
GeMoveDevice(
IN PEINFO* pInfo,
IN BOOL fUp );
DWORD
GeSaveLvDeviceChecks(
IN PEINFO* pInfo );
VOID
GeUpdateDialAnotherFirstState(
IN PEINFO* pInfo );
VOID
GeSetPhoneFields(
IN PEINFO* pInfo,
IN DTLNODE* pSrcLinkNode,
IN BOOL fDisableAll );
VOID
GeUpdatePhoneNumberFields(
IN PEINFO* pInfo,
IN BOOL fSharedToggle );
VOID
GeUpdatePhoneNumberTitle(
IN PEINFO* pInfo,
IN TCHAR* pszDevice );
VOID
GeUpdateUpDownButtons(
IN PEINFO* pInfo );
BOOL
LoCommand(
IN PEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl );
INT_PTR CALLBACK
LoDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
VOID
LoEnableSecuritySettings(
IN PEINFO* pInfo,
IN BOOL fTypical,
IN BOOL fAdvanced );
VOID
LoFillLbAuths(
IN PEINFO* pInfo );
BOOL
LoInit(
IN HWND hwndPage );
VOID
LoLbAuthsSelChange(
IN PEINFO* pInfo );
VOID
LoRefreshSecuritySettings(
IN PEINFO* pInfo );
VOID
LoSaveTypicalAuthSettings(
IN PEINFO* pInfo );
INT_PTR CALLBACK
NeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
BOOL
NeInit(
IN HWND hwndPage );
void
NeServerTypeSelChange (
IN PEINFO* pInfo);
void
NeAddComponent (
IN PEINFO* pInfo);
void
NeEnsureNetshellLoaded (
IN PEINFO* pInfo);
void
NeRemoveComponent (
IN PEINFO* pInfo);
void
NeLvClick (
IN PEINFO* pInfo,
IN BOOL fDoubleClick);
void
NeLvItemChanged (
IN PEINFO* pInfo);
void
NeSaveBindingChanges (
IN PEINFO* pInfo);
void
NeLvDeleteItem (
IN PEINFO* pInfo,
IN NM_LISTVIEW* pnmlv);
BOOL
OeCommand(
IN PEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl );
INT_PTR CALLBACK
OeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
VOID
OeEnableMultipleDeviceGroup(
IN PEINFO* pInfo,
IN BOOL fEnable );
BOOL
OeInit(
IN HWND hwndPage );
VOID
OeTunnel(
IN PEINFO* pInfo );
VOID
OeUpdateUserPwState(
IN PEINFO* pInfo );
VOID
OeX25(
IN PEINFO* pInfo );
BOOL
PeApply(
IN HWND hwndPage );
PEINFO*
PeContext(
IN HWND hwndPage );
DWORD
PeCountEnabledLinks(
IN PEINFO* pInfo );
VOID
PeExit(
IN PEINFO* pInfo,
IN DWORD dwError );
VOID
PeExitInit(
IN HWND hwndDlg,
IN EINFO* pEinfo,
IN DWORD dwError );
PEINFO*
PeInit(
IN HWND hwndFirstPage,
IN EINFO* pArgs );
VOID
PeTerm(
IN HWND hwndPage );
INT_PTR CALLBACK
PpDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
INT_PTR CALLBACK
RdDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
BOOL
SaCommand(
IN PEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl );
INT_PTR CALLBACK
SaDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
INT_PTR CALLBACK
SaUnavailDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
BOOL
SaInit(
IN HWND hwndDlg );
INT_PTR CALLBACK
SaDisableFirewallWarningDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
BOOL SaIsAdapterDHCPEnabled(
IN IHNetConnection* pConnection);
// wrapper to load homenet page: used in PePropertySheet(...)
HRESULT HrLoadHNetGetFirewallSettingsPage (PROPSHEETPAGEW * ppsp, EINFO* pInfo)
{
PROPSHEETPAGEW psp;
HRESULT hr;
HNET_CONN_PROPERTIES *pProps;
IHNetConnection *pHNetConn = NULL;
IHNetCfgMgr *pHNetCfgMgr = NULL;
// _asm int 3
ZeroMemory (&psp, sizeof(PROPSHEETPAGEW));
psp.dwSize = sizeof(PROPSHEETPAGEW);
*ppsp = psp;
// Make sure COM is initialized on this thread.
//
hr = CoInitializeEx(
NULL,
COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE
);
if (SUCCEEDED(hr))
{
pInfo->fComInitialized = TRUE;
}
else if (RPC_E_CHANGED_MODE == hr)
{
hr = S_OK;
}
if (SUCCEEDED(hr)) {
// pass the Guid to the export from hnetcfg ("HNetGetFirewallSettingsPage").
HINSTANCE hinstDll = LoadLibrary (TEXT("hnetcfg.dll"));
if (hinstDll == NULL)
hr = HRESULT_FROM_WIN32 (GetLastError());
else {
HRESULT (*pfnGetPage) (PROPSHEETPAGEW *, GUID *);
pfnGetPage = (HRESULT (*)(PROPSHEETPAGEW *, GUID *))GetProcAddress (hinstDll, "HNetGetFirewallSettingsPage");
if (!pfnGetPage)
hr = HRESULT_FROM_WIN32 (GetLastError());
else
hr = pfnGetPage (&psp, pInfo->pEntry->pGuid);
FreeLibrary (hinstDll);
}
if (hr == S_OK)
*ppsp = psp;
}
return pInfo->hShowHNetPagesResult = hr;
}
//----------------------------------------------------------------------------
// Phonebook Entry property sheet entrypoint
//----------------------------------------------------------------------------
VOID
PePropertySheet(
IN OUT EINFO* pEinfo )
// Runs the Phonebook entry property sheet. 'PEinfo' is the API caller's
// arguments.
//
{
PROPSHEETPAGE apage[ PE_PageCount ];
PROPSHEETPAGE* ppage;
INT nPages;
INT nPageIndex;
TRACE( "PePropertySheet" );
nPages = PE_PageCount;
ZeroMemory( apage, sizeof(apage) );
// General page.
//
ppage = &apage[ PE_GePage ];
ppage->dwSize = sizeof(PROPSHEETPAGE);
ppage->hInstance = g_hinstDll;
if (pEinfo->pEntry->dwType == RASET_Vpn)
{
ppage->pszTemplate = MAKEINTRESOURCE( PID_GE_GeneralVpn );
ppage->pfnDlgProc = GeDlgProc;
}
else if (pEinfo->pEntry->dwType == RASET_Broadband)
{
ppage->pszTemplate = MAKEINTRESOURCE( PID_GE_GeneralBroadband );
ppage->pfnDlgProc = GeDlgProc;
}
else if (pEinfo->pEntry->dwType == RASET_Phone)
{
if (pEinfo->fMultipleDevices)
{
if (pEinfo->fRouter)
{
ppage->pszTemplate =
MAKEINTRESOURCE( PID_GE_RouterGeneralMultiple );
}
else
{
ppage->pszTemplate =
MAKEINTRESOURCE( PID_GE_GeneralMultiple );
}
ppage->pfnDlgProc = GeDlgProcMultiple;
}
else
{
if (pEinfo->fRouter)
{
ppage->pszTemplate =
MAKEINTRESOURCE( PID_GE_RouterGeneralSingle );
}
else
{
ppage->pszTemplate =
MAKEINTRESOURCE( PID_GE_GeneralSingle );
}
ppage->pfnDlgProc = GeDlgProcSingle;
}
}
else
{
ASSERT( pEinfo->pEntry->dwType == RASET_Direct );
ppage->pszTemplate = MAKEINTRESOURCE( PID_GE_GeneralDirect );
ppage->pfnDlgProc = GeDlgProc;
}
ppage->lParam = (LPARAM )pEinfo;
// Options page.
//
ppage = &apage[ PE_OePage ];
ppage->dwSize = sizeof(PROPSHEETPAGE);
ppage->hInstance = g_hinstDll;
ppage->pszTemplate =
(pEinfo->fRouter)
? MAKEINTRESOURCE( PID_OE_OptionsRouter )
: ((pEinfo->pEntry->dwType == RASET_Phone)
? MAKEINTRESOURCE( PID_OE_Options )
: MAKEINTRESOURCE( PID_OE_OptionsVD ));
ppage->pfnDlgProc = OeDlgProc;
// Security page.
//
ppage = &apage[ PE_LoPage ];
ppage->dwSize = sizeof(PROPSHEETPAGE);
ppage->hInstance = g_hinstDll;
//
//Add new Security Page for bug 193987 PSK
//
if ( pEinfo->pEntry->dwType == RASET_Vpn )
{
ppage->pszTemplate = MAKEINTRESOURCE( PID_LO_SecurityVpn );
}
else
{
ppage->pszTemplate = MAKEINTRESOURCE( PID_LO_Security );
}
ppage->pfnDlgProc = LoDlgProc;
// Network page.
//
ppage = &apage[ PE_NePage ];
ppage->dwSize = sizeof(PROPSHEETPAGE);
ppage->hInstance = g_hinstDll;
ppage->pszTemplate = MAKEINTRESOURCE( PID_NE_Network );
ppage->pfnDlgProc = NeDlgProc;
// Advanced page.
// (AboladeG) The page is shown if the user is admin and
// there is at least one LAN connection, or if this phonebook entry
// is already shared.
//
nPageIndex = PE_SaPage;
if((!pEinfo->fIsUserAdminOrPowerUser) || (pEinfo->fRouter))
{
--nPages;
}
else
{
HRESULT hr;
BOOL fShowAdvancedUi = TRUE;
INetConnectionUiUtilities* pncuu = NULL;
// Check if ZAW is denying access to the Shared Access UI
//
hr = HrCreateNetConnectionUtilities(&pncuu);
if (SUCCEEDED(hr))
{
if(FALSE == INetConnectionUiUtilities_UserHasPermission(pncuu, NCPERM_ShowSharedAccessUi) &&
FALSE == INetConnectionUiUtilities_UserHasPermission(pncuu, NCPERM_PersonalFirewallConfig))
fShowAdvancedUi = FALSE;
INetConnectionUiUtilities_Release(pncuu);
}
if (!fShowAdvancedUi)
{
--nPages;
}
else
{
// Finally, check whether TCP/IP is installed or not.
//
if (!FIsTcpipInstalled())
{
--nPages;
}
else
{
ppage = &apage[ nPageIndex++ ];
ppage->dwSize = sizeof(PROPSHEETPAGE);
ppage->hInstance = g_hinstDll;
{
PROPSHEETPAGEW psp;
hr = HrLoadHNetGetFirewallSettingsPage (&psp, pEinfo);
if (hr == S_OK)
*ppage = psp;
}
if (hr != S_OK)
{
ppage->pszTemplate = MAKEINTRESOURCE( PID_SA_HomenetUnavailable );
ppage->pfnDlgProc = SaUnavailDlgProc;
}
}
}
}
if (pEinfo->pApiArgs->dwFlags & RASEDFLAG_ShellOwned)
{
INT i;
BOOL fStatus;
RASEDSHELLOWNEDR2* pShellOwnedInfo;
pShellOwnedInfo = (RASEDSHELLOWNEDR2*)pEinfo->pApiArgs->reserved2;
// The property sheet is to be invoked by the shell, using the shell
// convention of adding pages via callback.
//
for (i = 0; i < nPages; ++i)
{
HPROPSHEETPAGE h;
h = CreatePropertySheetPage( &apage[ i ] );
if (!h)
{
TRACE( "CreatePage failed" );
break;
}
fStatus = pShellOwnedInfo->pfnAddPage( h, pShellOwnedInfo->lparam );
if (!fStatus)
{
TRACE( "AddPage failed" );
DestroyPropertySheetPage( h );
break;
}
}
if (i < nPages)
{
ErrorDlg( pEinfo->pApiArgs->hwndOwner,
SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
}
}
else
{
PROPSHEETHEADER header;
PWSTR pszBuf = NULL;
PWSTR pszHeader;
DWORD cb;
HICON hIcon = NULL;
DWORD dwDisplayIcon = 0;
int i;
HPROPSHEETPAGE hPages[PE_PageCount];
//For whistler bug 382720 349866 gangz
//to fusionalize well for both rasdlg pages in NCW and
//property pages launched by pressing "Property" button
//besides following the normal fusion steps: we have to
// (1) add _WIN32_WINNT=0x501 in the file sources
// (2) use the phpage member in PROPSHEETHEADER structure, that is
// use CreatePropertySheetPage() to create page handles
for (i = 0; i < nPages; ++i)
{
hPages[i] = CreatePropertySheetPage( &apage[ i ] );
if ( !hPages[i] )
{
TRACE( "CreatePage failed" );
break;
}
}
if (i < nPages)
{
ErrorDlg( pEinfo->pApiArgs->hwndOwner,
SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
}
else
{
// Create the correct properties header
pszHeader = PszFromId(g_hinstDll, SID_PropertiesHeader);
if (pszHeader)
{
cb = lstrlenW(pEinfo->pEntry->pszEntryName) +
1 +
lstrlenW(pszHeader) +
1;
pszBuf = Malloc(cb * sizeof(TCHAR));
if (!pszBuf)
{
TRACE("Properties header allocation failed");
}
else
{
lstrcpyW(pszBuf, pEinfo->pEntry->pszEntryName);
lstrcatW(pszBuf, L" ");
lstrcatW(pszBuf, pszHeader);
}
Free(pszHeader);
}
//For whistler bug 372078 364876 gangz
//
hIcon = GetCurrentIconEntryType(pEinfo->pEntry->dwType,
TRUE); //TRUE means small Icon
if (hIcon)
{
dwDisplayIcon = PSH_USEHICON;
}
// The property sheet is to be invoked directly.
//
ZeroMemory( &header, sizeof(header) );
header.dwSize = sizeof(PROPSHEETHEADER);
// header.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | PSH_USECALLBACK | dwDisplayIcon;
header.dwFlags = PSH_NOAPPLYNOW | PSH_USECALLBACK | dwDisplayIcon;
header.hwndParent = pEinfo->pApiArgs->hwndOwner;
header.hInstance = g_hinstDll;
header.pszCaption = (pszBuf)?(pszBuf):(pEinfo->pEntry->pszEntryName);
header.nPages = nPages;
// header.ppsp = apage;
header.phpage = hPages;
header.hIcon = hIcon;
header.pfnCallback = UnHelpCallbackFunc;
if (PropertySheet( &header ) == -1)
{
TRACE( "PropertySheet failed" );
ErrorDlg( pEinfo->pApiArgs->hwndOwner,
SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
}
Free0(pszBuf);
//For whistler bug 372078
//GetCurrentIconEntryType() loads Icon from netshell where the icon is loaded
//by LoadImage() without LR_SHARED, so I have to destroy it when we are done
//with it
//
if (hIcon)
{
DestroyIcon( hIcon );
}
}
}
}
//----------------------------------------------------------------------------
// Phonebook Entry property sheet
// Listed alphabetically
//----------------------------------------------------------------------------
BOOL
PeApply(
IN HWND hwndPage )
// Saves the contents of the property sheet. 'HwndPage is the handle of a
// property page. Pops up any errors that occur.
//
// Returns true is page can be dismissed, false otherwise.
//
{
DWORD dwErr;
PEINFO* pInfo;
PBENTRY* pEntry;
TRACE( "PeApply" );
pInfo = PeContext( hwndPage );
ASSERT( pInfo );
if (pInfo == NULL)
{
return ERROR_CAN_NOT_COMPLETE;
}
pEntry = pInfo->pArgs->pEntry;
ASSERT( pEntry );
// Save General page fields.
//
ASSERT( pInfo->hwndGe );
{
DTLNODE* pNode;
// Retrieve the lone common control.
//
pEntry->fShowMonitorIconInTaskBar =
Button_GetCheck( pInfo->hwndCbShowIcon );
if (pEntry->dwType == RASET_Phone)
{
DWORD dwCount;
dwCount = GeSaveLvDeviceChecks( pInfo );
// Don't allow the user to deselect all of the
// devices
if ( (pInfo->pArgs->fMultipleDevices) && (dwCount == 0) )
{
MsgDlg( hwndPage, SID_SelectDevice, NULL );
PropSheet_SetCurSel ( pInfo->hwndDlg, pInfo->hwndGe, 0 );
SetFocus ( pInfo->hwndLvDevices );
return FALSE;
}
// Save the "shared phone number" setting. As usual, single
// device mode implies shared mode, allowing things to fall
// through correctly.
//
if (pInfo->pArgs->fMultipleDevices)
{
pEntry->fSharedPhoneNumbers =
Button_GetCheck( pInfo->hwndCbSharedPhoneNumbers );
}
else
{
pEntry->fSharedPhoneNumbers = TRUE;
}
// Set the phone number set for the first phone number of the
// current link (shared or selected) to the contents of the phone
// number controls.
//
GeGetPhoneFields( pInfo, pInfo->pCurLinkNode );
// Swap lists, saving updates to caller's global list of area
// codes. Caller's original list will be destroyed by PeTerm.
//
if (pInfo->pListAreaCodes)
{
DtlSwapLists(
pInfo->pArgs->pUser->pdtllistAreaCodes,
pInfo->pListAreaCodes );
pInfo->pArgs->pUser->fDirty = TRUE;
}
}
else if (pEntry->dwType == RASET_Vpn)
{
// For whistler 522872
DTLNODE* pNodeTmp = NULL;
PBLINK* pLink = NULL;
PBPHONE* pPhone = NULL;
// Save host name, i.e. the VPN phone number.
//
pNodeTmp = DtlGetFirstNode( pEntry->pdtllistLinks );
ASSERT( pNodeTmp );
pLink = (PBLINK* )DtlGetData( pNodeTmp );
pNodeTmp = FirstPhoneNodeFromPhoneList( pLink->pdtllistPhones );
if(NULL == pNodeTmp)
{
return FALSE;
}
pPhone = (PBPHONE* )DtlGetData( pNodeTmp );
Free0( pPhone->pszPhoneNumber );
pPhone->pszPhoneNumber = GetText( pInfo->hwndEbHostName );
FirstPhoneNodeToPhoneList( pLink->pdtllistPhones, pNodeTmp );
// Any prequisite entry selection change has been saved already.
// Just need to toss it if disabled.
//
if (!Button_GetCheck( pInfo->hwndCbDialAnotherFirst ))
{
Free0( pEntry->pszPrerequisiteEntry );
pEntry->pszPrerequisiteEntry = NULL;
Free0( pEntry->pszPrerequisitePbk );
pEntry->pszPrerequisitePbk = NULL;
}
}
else if (pEntry->dwType == RASET_Broadband)
{
DTLNODE* pNodeTmp = NULL;
PBLINK* pLink = NULL;
PBPHONE* pPhone = NULL;
// Save service name, i.e. the broadband phone number.
//
pNodeTmp = DtlGetFirstNode( pEntry->pdtllistLinks );
ASSERT( pNodeTmp );
pLink = (PBLINK* )DtlGetData( pNodeTmp );
pNodeTmp = FirstPhoneNodeFromPhoneList( pLink->pdtllistPhones );
if(NULL == pNodeTmp)
{
return FALSE;
}
pPhone = (PBPHONE* )DtlGetData( pNodeTmp );
Free0( pPhone->pszPhoneNumber );
pPhone->pszPhoneNumber = GetText( pInfo->hwndEbBroadbandService );
FirstPhoneNodeToPhoneList( pLink->pdtllistPhones, pNodeTmp );
}
else if (pEntry->dwType == RASET_Direct)
{
DTLNODE* pNodeTmp = NULL;
PBLINK* pLink = NULL;
// The currently enabled device is the one
// that should be used for the connection. Only
// one device will be enabled (DnUpdateSelectedDevice).
for (pNodeTmp = DtlGetFirstNode( pEntry->pdtllistLinks );
pNodeTmp;
pNodeTmp = DtlGetNextNode( pNodeTmp ))
{
pLink = (PBLINK* )DtlGetData( pNodeTmp );
ASSERT(pLink);
if ( pLink->fEnabled )
break;
}
// If we found a link successfully, deal with it
// now.
if ( pLink && pLink->fEnabled ) {
if (pLink->pbport.pbdevicetype == PBDT_ComPort)
MdmInstallNullModem (pLink->pbport.pszPort);
}
}
}
// Save Options page fields.
//
if (pInfo->hwndOe)
{
UINT unValue;
BOOL f;
INT iSel;
pEntry->fShowDialingProgress =
Button_GetCheck( pInfo->hwndCbDisplayProgress );
// Note: The'fPreviewUserPw', 'fPreviewDomain' fields are updated as
// they are changed.
pEntry->fPreviewPhoneNumber =
Button_GetCheck( pInfo->hwndCbPreviewNumber );
unValue = GetDlgItemInt(
pInfo->hwndOe, CID_OE_EB_RedialAttempts, &f, FALSE );
if (f && unValue <= RAS_MaxRedialCount)
{
pEntry->dwRedialAttempts = unValue;
}
iSel = ComboBox_GetCurSel( pInfo->hwndLbRedialTimes );
pEntry->dwRedialSeconds =
(DWORD )ComboBox_GetItemData( pInfo->hwndLbRedialTimes, iSel );
iSel = ComboBox_GetCurSel( pInfo->hwndLbIdleTimes );
pEntry->lIdleDisconnectSeconds =
(LONG )ComboBox_GetItemData( pInfo->hwndLbIdleTimes, iSel );
if (pInfo->pArgs->fRouter)
{
pEntry->fRedialOnLinkFailure =
Button_GetCheck( pInfo->hwndRbPersistent );
}
else
{
pEntry->fRedialOnLinkFailure =
Button_GetCheck( pInfo->hwndCbRedialOnDrop );
}
// Note: dwDialMode is saved as changed.
// Note: X.25 settings are saved at OK on that dialog.
}
// Save Security page fields.
//
if (pInfo->hwndLo)
{
if (Button_GetCheck( pInfo->hwndRbTypicalSecurity ))
{
LoSaveTypicalAuthSettings( pInfo );
if (pEntry->dwTypicalAuth == TA_CardOrCert)
{
/*
// Toss any existing advanced EAP configuration remnants when
// typical smartcard, per bug 262702 and VBaliga email.
//
Free0( pEntry->pCustomAuthData );
pEntry->pCustomAuthData = NULL;
pEntry->cbCustomAuthData = 0;
*/
(void) DwSetCustomAuthData(
pEntry,
0,
NULL);
TRACE( "RasSetEapUserData" );
ASSERT( g_pRasSetEapUserData );
g_pRasSetEapUserData(
INVALID_HANDLE_VALUE,
pInfo->pArgs->pFile->pszPath,
pEntry->pszEntryName,
NULL,
0 );
TRACE( "RasSetEapUserData done" );
}
}
if (pEntry->dwType == RASET_Phone)
{
Free0( pEntry->pszScriptAfter );
SuGetInfo( &pInfo->suinfo,
&pEntry->fScriptAfter,
&pEntry->fScriptAfterTerminal,
&pEntry->pszScriptAfter );
}
}
// Save Network page fields.
// We won't have anything to do if we never initialized pNetCfg.
//
if (pInfo->pNetCfg)
{
HRESULT hr;
// Update the phone book entry with the enabled state of the components.
// Do this by enumerating the components from the list view item data
// and consulting the check state for each.
//
NeSaveBindingChanges(pInfo);
hr = INetCfg_Apply (pInfo->pNetCfg);
if (((NETCFG_S_REBOOT == hr) || (pInfo->fRebootAlreadyRequested)) &&
pInfo->pNetConUtilities)
{
DWORD dwFlags = QUFR_REBOOT;
if (!pInfo->fRebootAlreadyRequested)
dwFlags |= QUFR_PROMPT;
//$TODO NULL caption?
INetConnectionUiUtilities_QueryUserForReboot (
pInfo->pNetConUtilities, pInfo->hwndDlg, NULL, dwFlags);
}
}
#if 0 //!!!
if ((fLocalPad || iPadSelection != 0)
&& (!pEntry->pszX25Address || IsAllWhite( pEntry->pszX25Address )))
{
// Address field is blank with X.25 dial-up or local PAD chosen.
//
MsgDlg( pInfo->hwndDlg, SID_NoX25Address, NULL );
PropSheet_SetCurSel( pInfo->hwndDlg, NULL, PE_XsPage );
SetFocus( pInfo->hwndEbX25Address );
Edit_SetSel( pInfo->hwndEbX25Address, 0, -1 );
return FALSE;
}
#endif
// Make sure proprietary ISDN options are disabled if more than one link
// is enabled. The proprietary ISDN option is only meaningful when
// calling a down-level server that needs Digiboard channel aggragation
// instead of PPP multi-link.
//
{
DTLNODE* pNode;
DWORD cIsdnLinks;
cIsdnLinks = 0;
for (pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
pNode;
pNode = DtlGetNextNode( pNode ))
{
PBLINK* pLink = (PBLINK* )DtlGetData( pNode );
ASSERT(pLink);
if (pLink->fEnabled && pLink->pbport.pbdevicetype == PBDT_Isdn)
{
++cIsdnLinks;
}
}
if (cIsdnLinks > 1)
{
for (pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
pNode;
pNode = DtlGetNextNode( pNode ))
{
PBLINK* pLink = (PBLINK* )DtlGetData( pNode );
ASSERT(pLink);
if (pLink->fEnabled && pLink->fProprietaryIsdn)
{
pLink->fProprietaryIsdn = FALSE;
}
}
}
}
// Inform user that edits to the connected entry won't take affect until
// the entry is hung up and re-dialed, per PierreS's insistence.
//
if (HrasconnFromEntry( pInfo->pArgs->pFile->pszPath, pEntry->pszEntryName ))
{
MsgDlg( pInfo->hwndDlg, SID_EditConnected, NULL );
}
// It's a valid new/changed entry. Commit the changes to the phonebook
// and preferences. This occurs immediately in "ShellOwned" mode where
// the RasEntryDlg API has already returned, but is otherwise deferred
// until the API is ready to return.
//
if (pInfo->pArgs->pApiArgs->dwFlags & RASEDFLAG_ShellOwned)
{
EuCommit( pInfo->pArgs );
}
else
{
pInfo->pArgs->fCommit = TRUE;
}
return TRUE;
}
PEINFO*
PeContext(
IN HWND hwndPage )
// Retrieve the property sheet context from a property page handle.
//
{
return (PEINFO* )GetProp( GetParent( hwndPage ), g_contextId );
}
DWORD
PeCountEnabledLinks(
IN PEINFO* pInfo )
// Returns the number of enabled links in the entry.
//
{
DWORD c;
DTLNODE* pNode;
c = 0;
for (pNode = DtlGetFirstNode( pInfo->pArgs->pEntry->pdtllistLinks );
pNode;
pNode = DtlGetNextNode( pNode ))
{
PBLINK* pLink = (PBLINK* )DtlGetData( pNode );
if (pLink->fEnabled)
{
++c;
}
}
TRACE1( "PeCountEnabledLinks=%d", c );
return c;
}
VOID
PeExit(
IN PEINFO* pInfo,
IN DWORD dwError )
// Forces an exit from the dialog, reporting 'dwError' to the caller.
// 'PInfo' is the dialog context.
//
// Note: This cannot be called during initialization of the first page.
// See PeExitInit.
//
{
TRACE( "PeExit" );
// In "ShellOwned" mode where the RasEntryDlg API has already returned,
// output arguments are not recorded.
//
if (!(pInfo->pArgs->pApiArgs->dwFlags & RASEDFLAG_ShellOwned))
{
pInfo->pArgs->pApiArgs->dwError = dwError;
}
PropSheet_PressButton( pInfo->hwndDlg, PSBTN_CANCEL );
}
VOID
PeExitInit(
IN HWND hwndDlg,
IN EINFO* pEinfo,
IN DWORD dwError )
// Utility to report errors within PeInit and other first page
// initialization. 'HwndDlg' is the dialog window. 'PEinfo' is the
// common context block, i.e. the PropertySheet argument. 'DwError' is
// the error that occurred.
//
{
// In "ShellOwned" mode where the RasEntryDlg API has already returned,
// output arguments are not recorded.
//
if (!(pEinfo->pApiArgs->dwFlags & RASEDFLAG_ShellOwned))
{
pEinfo->pApiArgs->dwError = dwError;
}
SetOffDesktop( hwndDlg, SOD_MoveOff, NULL );
SetOffDesktop( hwndDlg, SOD_Free, NULL );
PostMessage( hwndDlg, WM_COMMAND,
MAKEWPARAM( IDCANCEL , BN_CLICKED ),
(LPARAM )GetDlgItem( hwndDlg, IDCANCEL ) );
}
PEINFO*
PeInit(
IN HWND hwndFirstPage,
IN EINFO* pArgs )
// Property sheet level initialization. 'HwndPage' is the handle of the
// first page. 'PArgs' is the common entry input argument block.
//
// Returns address of the context block if successful, NULL otherwise. If
// NULL is returned, an appropriate message has been displayed, and the
// property sheet has been cancelled.
//
{
DWORD dwErr;
DWORD dwOp;
PEINFO* pInfo;
HWND hwndDlg;
TRACE( "PeInit" );
hwndDlg = GetParent( hwndFirstPage );
// Allocate the context information block. Initialize it enough so that
// it can be destroyed properly, and associate the context with the
// window.
//
{
pInfo = Malloc( sizeof(*pInfo) );
if (!pInfo)
{
TRACE( "Context NOT allocated" );
ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
PeExitInit( hwndDlg, pArgs, ERROR_NOT_ENOUGH_MEMORY );
return NULL;
}
ZeroMemory( pInfo, sizeof(PEINFO) );
pInfo->pArgs = pArgs;
pInfo->hwndDlg = hwndDlg;
pInfo->hwndFirstPage = hwndFirstPage;
if (!SetProp( hwndDlg, g_contextId, pInfo ))
{
TRACE(" Context NOT set" );
ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
Free( pInfo );
PeExitInit( hwndDlg, pArgs, ERROR_UNKNOWN );
return NULL;
}
TRACE( "Context set" );
}
// Position the dialog per API caller's instructions.
//
//For whislter bug 238459, we center the Property dialog box on its
//parent window rather than shift it as before. gangz
//
PositionDlg( hwndDlg,
0,
pArgs->pApiArgs->xDlg, pArgs->pApiArgs->yDlg );
// Mess with the title bar gadgets.
//
//TweakTitleBar( hwndDlg );
// Indicate no device has yet been selected.
//
pInfo->iDeviceSelected = -1;
// Indicate the "no security settings for SLIP" popup is appropriate for
// the entry and has not been viewed yet during this visit.
//
if (pArgs->pEntry->dwBaseProtocol == BP_Slip)
{
pInfo->fShowSlipPopup = TRUE;
}
// Initialize COM which may be needed by netshell calls.
//
{
HRESULT hr;
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
if (hr == RPC_E_CHANGED_MODE)
{
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
}
if (hr == S_OK || hr == S_FALSE)
{
pInfo->fComInitialized = TRUE;
}
}
#if 0
// Set even fixed tab widths.
//
SetEvenTabWidths( hwndDlg, PE_PageCount );
#endif
return pInfo;
}
VOID
PeTerm(
IN HWND hwndPage )
// Property sheet level termination. Releases the context block.
// 'HwndPage' is the handle of a property page.
//
{
PEINFO* pInfo;
TRACE( "PeTerm" );
pInfo = PeContext( hwndPage );
if (pInfo)
{
if (pInfo->pArgs->pApiArgs->dwFlags & RASEDFLAG_ShellOwned)
{
EuFree(pInfo->pArgs);
pInfo->pArgs = NULL;
}
if (pInfo->hwndLbDialAnotherFirst)
{
GeClearLbDialAnotherFirst( pInfo->hwndLbDialAnotherFirst );
}
if (pInfo->pListAreaCodes)
{
DtlDestroyList( pInfo->pListAreaCodes, DestroyPszNode );
}
#if 0
if (pInfo->pListEapcfgs)
{
DtlDestroyList( pInfo->pListEapcfgs, DestroyEapcfgNode );
}
#endif
if (pInfo->fCuInfoInitialized)
{
CuFree( &pInfo->cuinfo );
}
if (pInfo->fSuInfoInitialized)
{
SuFree( &pInfo->suinfo );
}
// Cleanup networking page context.
//
{
// Release our UI info callback object after revoking its info.
//
if (pInfo->punkUiInfoCallback)
{
RevokePeinfoFromUiInfoCallbackObject (pInfo->punkUiInfoCallback);
ReleaseObj (pInfo->punkUiInfoCallback);
}
//!!! Major hack: Get the list view on the networking page
// to dump its items before the pInfo and pInfo->pNetCfg go away.
// We have to do this here when we dismiss the property sheet
// from the General tab. When this happens, the general page
// is destroyed first (causing us to wind up here in PeTerm)
// before the networking page is destroyed. When the networking
// page is destroyed, its listview will also get destroyed
// causing all of its items to be deleted. If those LVN_ITEMDELETED
// notifications show up after pInfo and pInfo->pNetCfg are long
// gone, badness ensues. We need to solve this by decoupling
// PeTerm from a WM_DESTROY message and hooking it up to some
// later notification (like a page callback).
//
ListView_DeleteAllItems (pInfo->hwndLvComponents);
if (pInfo->pNetConUtilities)
{
INetConnectionUiUtilities_Release(pInfo->pNetConUtilities);
}
if (pInfo->pNetCfg)
{
HrUninitializeAndReleaseINetCfg (pInfo->fInitCom,
pInfo->pNetCfg, pInfo->fNetCfgLock);
}
SetupDiDestroyClassImageList (&pInfo->cild);
}
if (pInfo->fComInitialized)
{
CoUninitialize();
}
Free( pInfo );
TRACE("Context freed");
}
RemoveProp( GetParent( hwndPage ), g_contextId );
}
//----------------------------------------------------------------------------
// General property page (non-VPN)
// Listed alphabetically following dialog proc
//----------------------------------------------------------------------------
INT_PTR CALLBACK
GeDlgProcSingle(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
// DialogProc callback for the General page of the Entry Property sheet
// when in single device mode. Parameters and return value are as
// described for standard windows 'DialogProc's.
//
{
#if 0
TRACE4( "GeDlgProcS(h=$%x,m=$%x,w=$%x,l=$%x)",
(DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
#endif
if (ListView_OwnerHandler(
hwnd, unMsg, wparam, lparam, GeLvDevicesCallbackSingle ))
{
return TRUE;
}
return GeDlgProc( hwnd, unMsg, wparam, lparam );
}
INT_PTR CALLBACK
GeDlgProcMultiple(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
// DialogProc callback for the General page of the Entry Property sheet
// when in multiple device mode. Parameters and return value are as
// described for standard windows 'DialogProc's.
//
{
#if 0
TRACE4( "GeDlgProcS(h=$%x,m=$%x,w=$%x,l=$%x)",
(DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
#endif
if (ListView_OwnerHandler(
hwnd, unMsg, wparam, lparam, GeLvDevicesCallbackMultiple ))
{
return TRUE;
}
return GeDlgProc( hwnd, unMsg, wparam, lparam );
}
INT_PTR CALLBACK
GeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
// DialogProc callback for the General page of the Entry Property sheet.
// Called directly for VPNs or called by one of the two non-VPN stubs so
// 'pInfo' lookup is not required for every messages. Parameters and
// return value are as described for standard windows 'DialogProc's.
//
{
switch (unMsg)
{
case WM_INITDIALOG:
{
return
GeInit( hwnd, (EINFO* )(((PROPSHEETPAGE* )lparam)->lParam) );
}
case WM_HELP:
case WM_CONTEXTMENU:
{
ContextHelp( g_adwGeHelp, hwnd, unMsg, wparam, lparam );
break;
}
case WM_NOTIFY:
{
switch (((NMHDR* )lparam)->code)
{
case PSN_APPLY:
{
BOOL fValid;
TRACE( "GeAPPLY" );
fValid = PeApply( hwnd );
SetWindowLong(
hwnd, DWLP_MSGRESULT,
(fValid)
? PSNRET_NOERROR
: PSNRET_INVALID_NOCHANGEPAGE );
return TRUE;
}
case PSN_RESET:
{
TRACE( "GeRESET" );
SetWindowLong( hwnd, DWLP_MSGRESULT, FALSE );
break;
}
case LVXN_SETCHECK:
{
PEINFO* pInfo;
// An item was just checked or unchecked.
//
pInfo = PeContext( hwnd );
ASSERT( pInfo );
if (pInfo == NULL)
{
break;
}
GeUpdatePhoneNumberFields( pInfo, FALSE );
// For whistler bug 29419 gangz
// We should grey out the "All device call the same number"
// if not all the modems are selected
//
do
{
int i, iCount = 0, iChecked = 0;
BOOL fEnable = TRUE;
iCount = ListView_GetItemCount(
pInfo->hwndLvDevices
);
if ( iCount <= 0 )
{
break;
}
for ( i = 0; i < iCount; i ++ )
{
if ( ListView_GetCheck(
pInfo->hwndLvDevices,
i)
)
{
iChecked ++;
}
if ( 2 <=iChecked )
{
break;
}
}
if ( iChecked < 2 )
{
fEnable = FALSE;
}
if ( pInfo->hwndCbSharedPhoneNumbers )
{
EnableWindow( pInfo->hwndCbSharedPhoneNumbers,
fEnable);
}
}while(FALSE);
break;
}
case LVN_ITEMCHANGED:
{
NM_LISTVIEW* p;
p = (NM_LISTVIEW* )lparam;
if ((p->uNewState & LVIS_SELECTED)
&& !(p->uOldState & LVIS_SELECTED))
{
PEINFO* pInfo;
// This item was just selected.
//
pInfo = PeContext( hwnd );
ASSERT( pInfo );
if (pInfo == NULL)
{
break;
}
GeUpdatePhoneNumberFields( pInfo, FALSE );
GeUpdateUpDownButtons( pInfo );
}
break;
}
}
break;
}
case WM_COMMAND:
{
PEINFO* pInfo = PeContext( hwnd );
ASSERT(pInfo);
if (pInfo == NULL)
{
break;
}
return GeCommand(
pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
}
case WM_DESTROY:
{
PeTerm( hwnd );
break;
}
}
return FALSE;
}
VOID
GeAlternates(
IN PEINFO* pInfo )
// Called when the "Alternates" button is pressed to popup the alternate
// phone number dialog.
//
{
// Pick up any control window changes into the underlying link so the
// dialog will reflect them.
//
GeGetPhoneFields( pInfo, pInfo->pCurLinkNode );
if (pInfo->pArgs->fRouter)
{
PBLINK* pLink;
DTLLIST* pListPsz;
DTLNODE* pNode;
// TAPI modifiers are not offered in the demand dial connection case,
// where user enters only a simple string phone number. The old
// NT4-style Alternates dialog that allows simple string edits only is
// used here. First, must convert the NT5-style list of PBPHONE nodes
// to a list of PSZ nodes that the old dialog expects.
//
pListPsz = DtlCreateList( 0L );
if (!pListPsz)
{
return;
}
pLink = (PBLINK* )DtlGetData( pInfo->pCurLinkNode );
for (pNode = DtlGetFirstNode( pLink->pdtllistPhones );
pNode;
pNode = DtlGetNextNode( pNode ) )
{
PBPHONE* pPhone;
DTLNODE* pNodePsz;
pPhone = (PBPHONE* )DtlGetData( pNode );
ASSERT( pPhone );
if (pPhone->pszPhoneNumber && *(pPhone->pszPhoneNumber))
{
pNodePsz = CreatePszNode( pPhone->pszPhoneNumber );
if (pNodePsz)
{
DtlAddNodeLast( pListPsz, pNodePsz );
}
}
}
// Call the old-sytle Alternates dialog which is shared with the
// demand dial wizard.
//
if (PhoneNumberDlg(
pInfo->hwndGe, TRUE, pListPsz, &pLink->fPromoteAlternates ))
{
// User pressed OK. Convert back to a PBPHONE node list.
//
while (pNode = DtlGetFirstNode( pLink->pdtllistPhones ))
{
DtlRemoveNode( pLink->pdtllistPhones, pNode );
DestroyPhoneNode( pNode );
}
for (pNode = DtlGetFirstNode( pListPsz );
pNode;
pNode = DtlGetNextNode( pNode ) )
{
TCHAR* psz;
DTLNODE* pPhoneNode;
PBPHONE* pPhone;
psz = (TCHAR* )DtlGetData( pNode );
if (!psz)
{
continue;
}
pPhoneNode = CreatePhoneNode();
if (!pPhoneNode)
{
continue;
}
pPhone = (PBPHONE* )DtlGetData( pPhoneNode );
if (!pPhone)
{
continue;
}
pPhone->pszPhoneNumber = psz;
DtlPutData( pNode, NULL );
DtlAddNodeLast( pLink->pdtllistPhones, pPhoneNode );
}
// Refresh the displayed phone number information, since user's
// edits in the dialog may have changed them.
//
GeSetPhoneFields( pInfo, pInfo->pCurLinkNode, FALSE );
}
DtlDestroyList( pListPsz, DestroyPszNode );
}
else
{
// Popup the Alternate Phone Number dialog on the link.
//
if (AlternatePhoneNumbersDlg(
pInfo->hwndDlg, pInfo->pCurLinkNode, pInfo->pListAreaCodes ))
{
// User pressed OK. Refresh the displayed phone number
// information, since user's edits in the dialog may have changed
// them.
//
GeSetPhoneFields( pInfo, pInfo->pCurLinkNode, FALSE );
}
}
}
VOID
GeDialingRules(
IN PEINFO* pInfo )
// Called when the "Rules" button is pressed to popup the tapi
// dialing rules dialog.
//
{
TCHAR pszAreaCode[RAS_MaxPhoneNumber];
TCHAR pszPhoneNumber[RAS_MaxPhoneNumber];
DWORD dwErr, dwCountryCode, dwLineId;
COUNTRY* pCountry = NULL;
INT iSel;
TRACE( "GeDialingRules" );
// Get the current phone number
//
GetWindowText ( pInfo->hwndEbPhoneNumber,
pszPhoneNumber,
sizeof(pszPhoneNumber) / sizeof(TCHAR) );
// Get the current area code
//
GetWindowText ( pInfo->hwndClbAreaCodes,
pszAreaCode,
sizeof(pszAreaCode) / sizeof(TCHAR) );
// Get the current country code
//
iSel = ComboBox_GetCurSel ( pInfo->hwndLbCountryCodes );
if (iSel >= 0)
{
pCountry = (COUNTRY*) ComboBox_GetItemDataPtr (
pInfo->hwndLbCountryCodes, iSel );
}
dwCountryCode = (pCountry) ? pCountry->dwCode : 0;
// Popup TAPI dialing rules dialog.
//
dwErr = TapiLocationDlg(
g_hinstDll,
&(pInfo->cuinfo.hlineapp),
pInfo->hwndDlg,
dwCountryCode,
pszAreaCode,
pszPhoneNumber,
0 );
if (dwErr != 0)
{
ErrorDlg( pInfo->hwndDlg, SID_OP_LoadTapiInfo, dwErr, NULL );
}
}
VOID
GeClearLbDialAnotherFirst(
IN HWND hwndLbDialAnotherFirst )
// Clear prerequisite entry list box. 'hwndLbDialAnotherFirst' is the
// window handle of the listbox control. context.
//
{
PREREQITEM* pItem;
while (pItem = ComboBox_GetItemDataPtr( hwndLbDialAnotherFirst, 0 ))
{
ComboBox_DeleteString( hwndLbDialAnotherFirst, 0 );
Free0( pItem->pszEntry );
Free0( pItem->pszPbk );
Free( pItem );
}
}
BOOL
GeCommand(
IN PEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl )
// Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
// is the notification code of the command. 'wId' is the control/menu
// identifier of the command. 'HwndCtrl' is the control window handle of
// the command.
//
// Returns true if processed message, false otherwise.
//
{
TRACE3( "GeCommand(n=%d,i=%d,c=$%x)",
(DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
switch (wId)
{
case CID_GE_PB_MoveUp:
{
GeMoveDevice( pInfo, TRUE );
return TRUE;
}
case CID_GE_PB_MoveDown:
{
GeMoveDevice( pInfo, FALSE );
return TRUE;
}
case CID_GE_PB_Configure:
{
GeConfigure( pInfo );
return TRUE;
}
case CID_GE_PB_Alternates:
{
GeAlternates( pInfo );
return TRUE;
}
case CID_GE_PB_DialingRules:
{
GeDialingRules( pInfo );
return TRUE;
}
case CID_GE_CB_SharedPhoneNumber:
{
GeUpdatePhoneNumberFields( pInfo, TRUE );
return TRUE;
}
case CID_GE_CB_UseDialingRules:
{
if (CuDialingRulesCbHandler( &pInfo->cuinfo, wNotification ))
{
return TRUE;
}
break;
}
case CID_GE_LB_CountryCodes:
{
if (CuCountryCodeLbHandler( &pInfo->cuinfo, wNotification ))
{
return TRUE;
}
break;
}
case CID_GE_CB_DialAnotherFirst:
{
GeUpdateDialAnotherFirstState( pInfo );
return TRUE;
}
case CID_GE_LB_DialAnotherFirst:
{
if (wNotification == CBN_SELCHANGE)
{
GeDialAnotherFirstSelChange( pInfo );
return TRUE;
}
break;
}
case CID_GE_LB_Devices:
{
if (wNotification == CBN_SELCHANGE)
{
DTLLIST* pList;
DTLNODE* pNode, *pNode2;
PBLINK * pLink;
pList = pInfo->pArgs->pEntry->pdtllistLinks;
// Get node from current selection
pNode = (DTLNODE* )ComboBox_GetItemDataPtr(
pInfo->hwndLbDevices,
ComboBox_GetCurSel( pInfo->hwndLbDevices ) );
if(NULL == pNode)
{
break;
}
// Remove selected item from list of links
// and disable all other links
DtlRemoveNode ( pList, pNode );
for (pNode2 = DtlGetFirstNode (pList);
pNode2;
pNode2 = DtlGetNextNode (pNode2))
{
pLink = (PBLINK* )DtlGetData( pNode2 );
pLink->fEnabled = FALSE;
}
// Enable selected device and Re-add
// in list of links at front
pLink = (PBLINK* )DtlGetData( pNode );
pLink->fEnabled = TRUE;
DtlAddNodeFirst( pList, pNode );
}
break;
}
}
return FALSE;
}
VOID
GeConfigure(
IN PEINFO* pInfo )
// Called when the "Configure" button is pressed to popup the appropriate
// device configuration dialog.
//
{
DTLNODE* pNode;
PBLINK* pLink;
PBENTRY* pEntry;
BOOL fMultilinking = FALSE;
pEntry = pInfo->pArgs->pEntry;
// pmay: 245860
//
// Need to allow config of null modem speed.
//
if ( pEntry->dwType == RASET_Direct )
{
INT iSel;
iSel = ComboBox_GetCurSel( pInfo->hwndLbDevices );
pNode = (DTLNODE*)
ComboBox_GetItemDataPtr ( pInfo->hwndLbDevices, iSel );
}
else
{
pNode = (DTLNODE* )ListView_GetSelectedParamPtr( pInfo->hwndLvDevices );
fMultilinking =
(ListView_GetCheckedCount( pInfo->hwndLvDevices ) > 1
&& pEntry->dwDialMode == RASEDM_DialAll);
}
if (!pNode)
{
return;
}
pLink = (PBLINK* )DtlGetData( pNode );
DeviceConfigureDlg(
pInfo->hwndDlg,
pLink,
pEntry,
!fMultilinking,
pInfo->pArgs->fRouter);
}
VOID
GeDialAnotherFirstSelChange(
IN PEINFO* pInfo )
// Called when the prerequisite entry selection changes. 'PInfo' is the
// property sheet context.
//
{
PBENTRY* pEntry;
PREREQITEM* pItem;
INT iSel;
iSel = ComboBox_GetCurSel( pInfo->hwndLbDialAnotherFirst );
if (iSel < 0)
{
return;
}
pEntry = pInfo->pArgs->pEntry;
Free0( pEntry->pszPrerequisiteEntry );
Free0( pEntry->pszPrerequisitePbk );
pItem = (PREREQITEM* )
ComboBox_GetItemDataPtr( pInfo->hwndLbDialAnotherFirst, iSel );
if(NULL != pItem)
{
pEntry->pszPrerequisiteEntry = StrDup( pItem->pszEntry );
pEntry->pszPrerequisitePbk = StrDup( pItem->pszPbk );
}
pEntry->fDirty = TRUE;
}
BOOL
GeFillLbDialAnotherFirst(
IN PEINFO* pInfo,
IN BOOL fAbortIfPrereqNotFound )
// Fill prerequisite entry list box with all non-VPN entries in the
// phonebook, and select the prerequiste one. 'PInfo' is the property
// sheet context. 'FAbortIfPrereqNotFound' means the list should not be
// filled unless the entry's prerequisite entry is found and selected.
//
// Returns TRUE if a selection was made, FALSE otherwise.
//
{
DWORD i;
INT iThis;
INT iSel;
TCHAR* pszEntry;
TCHAR* pszPrerequisiteEntry = NULL;
RASENTRYNAME* pRens;
RASENTRYNAME* pRen;
DWORD dwRens;
GeClearLbDialAnotherFirst( pInfo->hwndLbDialAnotherFirst );
iSel = -1;
pszEntry = pInfo->pArgs->pEntry->pszEntryName;
//
// Make a dup of this prerequisite entry here. Otherwise
// this leads to accessing freed memory when _SetCurSelNotify
// frees pszPrerequisiteEntry - [raos].
//
if(NULL != pInfo->pArgs->pEntry->pszPrerequisiteEntry)
{
pszPrerequisiteEntry = StrDup(
pInfo->pArgs->pEntry->pszPrerequisiteEntry);
}
if (GetRasEntrynameTable( &pRens, &dwRens ) != 0)
{
return FALSE;
}
for (i = 0, pRen = pRens; i < dwRens; ++i, ++pRen )
{
PREREQITEM* pItem;
if (lstrcmp( pRen->szEntryName, pszEntry ) == 0)
{
continue;
}
pItem = Malloc( sizeof(PREREQITEM) );
if (!pItem)
{
continue;
}
pItem->pszEntry = StrDup( pRen->szEntryName );
pItem->pszPbk = StrDup( pRen->szPhonebookPath );
if (!pItem->pszEntry || !pItem->pszPbk)
{
Free0( pItem->pszEntry );
Free( pItem );
continue;
}
iThis = ComboBox_AddItem(
pInfo->hwndLbDialAnotherFirst, pItem->pszEntry, pItem );
if (pszPrerequisiteEntry && *(pszPrerequisiteEntry)
&& lstrcmp( pItem->pszEntry, pszPrerequisiteEntry ) == 0)
{
iSel = iThis;
ComboBox_SetCurSelNotify( pInfo->hwndLbDialAnotherFirst, iSel );
}
}
Free( pRens );
if (iSel < 0)
{
if (fAbortIfPrereqNotFound)
{
GeClearLbDialAnotherFirst( pInfo->hwndLbDialAnotherFirst );
}
else
{
iSel = 0;
ComboBox_SetCurSelNotify( pInfo->hwndLbDialAnotherFirst, iSel );
}
}
Free0(pszPrerequisiteEntry);
return (iSel >= 0);
}
VOID
GeFillLbDevices(
IN PEINFO* pInfo )
// Populate the already initialized ListBox of devices, selecting the
// currently selected item or if none, the first item. 'PInfo' is the
// property sheet context.
//
{
DTLNODE* pNode;
DTLNODE* pSelNode;
DTLLIST* pListLinks;
INT iItem;
INT iSelItem;
TRACE( "GeFillLbDevices" );
pSelNode = NULL;
iSelItem = -1;
// (Re-)populate the list.
//
pListLinks = pInfo->pArgs->pEntry->pdtllistLinks;
for (pNode = DtlGetFirstNode( pListLinks ), iItem = 0;
pNode;
pNode = DtlGetNextNode( pNode ), ++iItem)
{
PBLINK* pLink;
DWORD dwImage;
TCHAR* pszText;
pLink = (PBLINK* )DtlGetData( pNode );
ASSERT( pLink );
pszText = DisplayPszFromPpbport( &pLink->pbport, &dwImage );
if (pszText)
{
iItem = ComboBox_AddString( pInfo->hwndLbDevices, pszText );
ComboBox_SetItemData ( pInfo->hwndLbDevices, iItem, pNode );
Free (pszText);
}
}
ComboBox_SetCurSelNotify( pInfo->hwndLbDevices, 0 );
}
VOID
GeFillLvDevices(
IN PEINFO* pInfo )
// Populate the already initialized ListView of devices, selecting the
// currently selected item or if none, the first item. 'PInfo' is the
// property sheet context.
//
{
DTLNODE* pNode;
DTLNODE* pSelNode;
DTLLIST* pListLinks;
INT iItem;
INT iSelItem;
BOOL bFirstTime = TRUE;
INT cItems;
TRACE( "GeFillLvDevices" );
pSelNode = NULL;
iSelItem = -1;
if (ListView_GetItemCount( pInfo->hwndLvDevices ) > 0)
{
// ListView has been filled. Lookup the selected link node, if any,
// then save the check state to the links, and delete all items from
// the list.
//
if (pInfo->iDeviceSelected >= 0)
{
pSelNode =
(DTLNODE* )ListView_GetParamPtr(
pInfo->hwndLvDevices, pInfo->iDeviceSelected );
}
GeSaveLvDeviceChecks( pInfo );
ListView_DeleteAllItems( pInfo->hwndLvDevices );
bFirstTime = FALSE;
}
// (Re-)populate the list.
//
pListLinks = pInfo->pArgs->pEntry->pdtllistLinks;
for (pNode = DtlGetFirstNode( pListLinks ), iItem = 0;
pNode;
pNode = DtlGetNextNode( pNode ), ++iItem)
{
PBLINK* pLink;
DWORD dwImage;
TCHAR* pszText;
pLink = (PBLINK* )DtlGetData( pNode );
ASSERT( pLink );
pszText = DisplayPszFromPpbport( &pLink->pbport, &dwImage );
if (pszText)
{
LV_ITEM item;
ZeroMemory( &item, sizeof(item) );
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
item.iItem = iItem;
item.lParam = (LPARAM )pNode;
item.pszText = pszText;
item.cchTextMax = wcslen(pszText) + 1;
item.iImage = dwImage;
iItem = ListView_InsertItem( pInfo->hwndLvDevices, &item );
Free( pszText );
if (pNode == pSelNode)
{
iSelItem = iItem;
pInfo->iDeviceSelected = iItem;
}
/*
if (pInfo->pArgs->fMultipleDevices)
{
ListView_SetCheck(
pInfo->hwndLvDevices, iItem, pLink->fEnabled );
}
*/
}
}
if(pInfo->pArgs->fMultipleDevices)
{
INT i = -1;
while ((i = ListView_GetNextItem(
pInfo->hwndLvDevices, i, LVNI_ALL )) >= 0)
{
DTLNODE* pNodeTmp = NULL;
PBLINK* pLink = NULL;
pNodeTmp = (DTLNODE* )ListView_GetParamPtr( pInfo->hwndLvDevices, i );
ASSERT( pNodeTmp );
if(NULL == pNodeTmp)
{
continue;
}
pLink = (PBLINK* )DtlGetData( pNodeTmp );
ASSERT( pLink );
ListView_SetCheck(
pInfo->hwndLvDevices, i, pLink->fEnabled);
}
}
if (bFirstTime == TRUE)
{
// Add a single column exactly wide enough to fully display
// the widest member of the list.
//
LV_COLUMN col;
ZeroMemory( &col, sizeof(col) );
col.mask = LVCF_FMT;
col.fmt = LVCFMT_LEFT;
ListView_InsertColumn( pInfo->hwndLvDevices, 0, &col );
ListView_SetColumnWidth( pInfo->hwndLvDevices, 0, LVSCW_AUTOSIZE_USEHEADER );
}
// EuInit creates a bogus device if there are none guaranteeing that the
// device list is never empty.
//
ASSERT( iItem > 0 );
// Select the previously selected item, or the first item if none. This
// will trigger an update of the phone number related controls. The
// "previous selection" index is updated to the new index of the same
// item.
//
if (iSelItem >= 0)
{
pInfo->iDeviceSelected = iSelItem;
}
else
{
iSelItem = 0;
}
ListView_SetItemState(
pInfo->hwndLvDevices, iSelItem, LVIS_SELECTED, LVIS_SELECTED );
}
VOID
GeInitLvDevices(
IN PEINFO* pInfo )
// Initialize the ListView of devices.
//
{
BOOL fChecksInstalled;
// Install "listview of checkboxes" handling.
//
if (pInfo->pArgs->fMultipleDevices)
{
fChecksInstalled =
ListView_InstallChecks( pInfo->hwndLvDevices, g_hinstDll );
if (!fChecksInstalled)
return;
}
// Set the modem, adapter, and other device images.
//
ListView_SetDeviceImageList( pInfo->hwndLvDevices, g_hinstDll );
// Add a single column exactly wide enough to fully display the widest
// member of the list.
//
ListView_InsertSingleAutoWidthColumn( pInfo->hwndLvDevices );
}
VOID
GeGetPhoneFields(
IN PEINFO* pInfo,
OUT DTLNODE* pDstLinkNode )
// Load the phone number group box field settings into the phone number
// information of PBLINK node 'pDstLinkNode'. 'PInfo' is the property
// sheet context.
//
{
PBLINK* pLink;
PBPHONE* pPhone;
DTLNODE* pPhoneNode;
TRACE( "GeGetPhoneFields" );
pLink = (PBLINK* )DtlGetData( pDstLinkNode );
ASSERT( pLink );
pPhoneNode = FirstPhoneNodeFromPhoneList( pLink->pdtllistPhones );
if (pPhoneNode)
{
CuGetInfo( &pInfo->cuinfo, pPhoneNode );
FirstPhoneNodeToPhoneList( pLink->pdtllistPhones, pPhoneNode );
}
}
BOOL
GeInit(
IN HWND hwndPage,
IN OUT EINFO* pArgs )
// Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
// page. 'PArgs' is the arguments from the PropertySheet caller.
//
// Return false if focus was set, true otherwise.
//
{
DWORD dwErr;
PEINFO* pInfo;
PBENTRY* pEntry;
TRACE( "GeInit" );
// We're first page, so initialize the property sheet.
//
pInfo = PeInit( hwndPage, pArgs );
if (!pInfo)
{
return TRUE;
}
pEntry = pInfo->pArgs->pEntry;
// Initialize page-specific context information.
//
pInfo->hwndGe = hwndPage;
// Initialize the "show icon in the taskbar" button, the lone piece of consistency among
// the various forms.
//
//for bug 154607 whistler, Enable/Disable Show Icon on taskbar
//check box according to Policy
//
//
{
BOOL fShowStatistics = TRUE;
NeEnsureNetshellLoaded (pInfo);
if ( NULL != pInfo->pNetConUtilities)
{
fShowStatistics =
INetConnectionUiUtilities_UserHasPermission(
pInfo->pNetConUtilities, NCPERM_Statistics);
}
pInfo->hwndCbShowIcon =
GetDlgItem( hwndPage, CID_GE_CB_ShowIcon );
ASSERT( pInfo->hwndCbShowIcon );
if ( pInfo->pArgs->fRouter )
{
Button_SetCheck( pInfo->hwndCbShowIcon, FALSE );
ShowWindow( pInfo->hwndCbShowIcon, SW_HIDE );
}
else
{
Button_SetCheck(
pInfo->hwndCbShowIcon, pEntry->fShowMonitorIconInTaskBar );
if ( !fShowStatistics )
{
EnableWindow( pInfo->hwndCbShowIcon, FALSE );
}
}
}
if (pEntry->dwType == RASET_Vpn)
{
pInfo->hwndEbHostName =
GetDlgItem( hwndPage, CID_GE_EB_HostName );
ASSERT( pInfo->hwndEbHostName );
pInfo->hwndCbDialAnotherFirst =
GetDlgItem( hwndPage, CID_GE_CB_DialAnotherFirst );
ASSERT( pInfo->hwndCbDialAnotherFirst );
pInfo->hwndLbDialAnotherFirst =
GetDlgItem( hwndPage, CID_GE_LB_DialAnotherFirst );
ASSERT( pInfo->hwndLbDialAnotherFirst );
// Initialize host name, i.e. the "phone number".
//
{
DTLNODE* pNode;
PBLINK* pLink;
PBPHONE* pPhone;
Edit_LimitText( pInfo->hwndEbHostName, RAS_MaxPhoneNumber );
pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
ASSERT( pNode );
pLink = (PBLINK* )DtlGetData( pNode );
pNode = FirstPhoneNodeFromPhoneList( pLink->pdtllistPhones );
if(NULL == pNode)
{
return TRUE;
}
pPhone = (PBPHONE* )DtlGetData( pNode );
SetWindowText( pInfo->hwndEbHostName, pPhone->pszPhoneNumber );
DestroyPhoneNode( pNode );
}
// Initialize the "dial connected first" controls.
//
if (pInfo->pArgs->fRouter)
{
Button_SetCheck( pInfo->hwndCbDialAnotherFirst, FALSE );
EnableWindow( pInfo->hwndCbDialAnotherFirst, FALSE );
ShowWindow( pInfo->hwndCbDialAnotherFirst, SW_HIDE );
EnableWindow( pInfo->hwndLbDialAnotherFirst, FALSE );
ShowWindow(pInfo->hwndLbDialAnotherFirst, SW_HIDE );
ShowWindow(
GetDlgItem( hwndPage, CID_GE_GB_FirstConnect ),
SW_HIDE );
ShowWindow(
GetDlgItem( hwndPage, CID_GE_ST_Explain ),
SW_HIDE );
}
else
{
BOOL fEnableLb;
fEnableLb = FALSE;
if (pEntry->pszPrerequisiteEntry
&& *(pEntry->pszPrerequisiteEntry))
{
if (GeFillLbDialAnotherFirst( pInfo, TRUE ))
{
fEnableLb = TRUE;
}
else
{
// Don't enable the listbox if the prerequisite entry
// defined no longer exists. See bug 220420.
//
Free0( pEntry->pszPrerequisiteEntry );
pEntry->pszPrerequisiteEntry = NULL;
Free0( pEntry->pszPrerequisitePbk );
pEntry->pszPrerequisitePbk = NULL;
}
}
Button_SetCheck( pInfo->hwndCbDialAnotherFirst, fEnableLb );
EnableWindow( pInfo->hwndLbDialAnotherFirst, fEnableLb );
if (pArgs->fDisableFirstConnect)
{
EnableWindow( pInfo->hwndCbDialAnotherFirst, FALSE );
EnableWindow( pInfo->hwndLbDialAnotherFirst, FALSE );
}
}
return TRUE;
}
else if (pEntry->dwType == RASET_Broadband)
{
pInfo->hwndEbBroadbandService =
GetDlgItem( hwndPage, CID_GE_EB_ServiceName );
ASSERT( pInfo->hwndEbBroadbandService );
// Initialize host name, i.e. the "phone number".
//
{
DTLNODE* pNode;
PBLINK* pLink;
PBPHONE* pPhone;
Edit_LimitText( pInfo->hwndEbBroadbandService, RAS_MaxPhoneNumber );
pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
ASSERT( pNode );
pLink = (PBLINK* )DtlGetData( pNode );
pNode = FirstPhoneNodeFromPhoneList( pLink->pdtllistPhones );
if(NULL == pNode)
{
return TRUE;
}
pPhone = (PBPHONE* )DtlGetData( pNode );
SetWindowText( pInfo->hwndEbBroadbandService, pPhone->pszPhoneNumber );
DestroyPhoneNode( pNode );
}
return TRUE;
}
else if (pEntry->dwType == RASET_Phone)
{
if (pArgs->fMultipleDevices)
{
pInfo->hwndLvDevices =
GetDlgItem( hwndPage, CID_GE_LV_Devices );
ASSERT( pInfo->hwndLvDevices );
pInfo->hwndPbUp =
GetDlgItem( hwndPage, CID_GE_PB_MoveUp );
ASSERT( pInfo->hwndPbUp );
pInfo->hwndPbDown =
GetDlgItem( hwndPage, CID_GE_PB_MoveDown );
ASSERT( pInfo->hwndPbDown );
pInfo->hwndCbSharedPhoneNumbers =
GetDlgItem( hwndPage, CID_GE_CB_SharedPhoneNumber );
ASSERT( pInfo->hwndCbSharedPhoneNumbers );
}
else
{
// The listview has a different control-ID in single mode so that
// a different help context can be provided.
//
pInfo->hwndLvDevices =
GetDlgItem( hwndPage, CID_GE_LV_Device );
ASSERT( pInfo->hwndLvDevices );
}
pInfo->hwndPbConfigureDevice =
GetDlgItem( hwndPage, CID_GE_PB_Configure );
ASSERT( pInfo->hwndPbConfigureDevice );
if ( pEntry->fGlobalDeviceSettings )
{
// Whislter bug 281306. If the entry is set up to use
// control panel settings, then hide the option that
// allows users to configure the devices per-phonebook.
//
ShowWindow( pInfo->hwndPbConfigureDevice, SW_HIDE );
}
pInfo->hwndStPhoneNumber =
GetDlgItem( hwndPage, CID_GE_ST_PhoneNumber );
ASSERT( pInfo->hwndStPhoneNumber );
pInfo->hwndEbPhoneNumber =
GetDlgItem( hwndPage, CID_GE_EB_PhoneNumber );
ASSERT( pInfo->hwndEbPhoneNumber );
pInfo->hwndPbAlternates =
GetDlgItem( hwndPage, CID_GE_PB_Alternates );
ASSERT( pInfo->hwndPbAlternates );
if (!pInfo->pArgs->fRouter)
{
pInfo->hwndGbPhoneNumber =
GetDlgItem( hwndPage, CID_GE_GB_PhoneNumber );
ASSERT( pInfo->hwndGbPhoneNumber );
pInfo->hwndStAreaCodes =
GetDlgItem( hwndPage, CID_GE_ST_AreaCodes );
ASSERT( pInfo->hwndStAreaCodes );
pInfo->hwndClbAreaCodes =
GetDlgItem( hwndPage, CID_GE_CLB_AreaCodes );
ASSERT( pInfo->hwndClbAreaCodes );
pInfo->hwndStCountryCodes =
GetDlgItem( hwndPage, CID_GE_ST_CountryCodes );
ASSERT( pInfo->hwndStCountryCodes );
pInfo->hwndLbCountryCodes =
GetDlgItem( hwndPage, CID_GE_LB_CountryCodes );
ASSERT( pInfo->hwndLbCountryCodes );
pInfo->hwndCbUseDialingRules =
GetDlgItem( hwndPage, CID_GE_CB_UseDialingRules );
ASSERT( pInfo->hwndCbUseDialingRules );
pInfo->hwndPbDialingRules =
GetDlgItem( hwndPage, CID_GE_PB_DialingRules );
ASSERT( pInfo->hwndPbDialingRules );
}
if (pArgs->fMultipleDevices)
{
// Set the shared phone number checkbox.
//
Button_SetCheck(
pInfo->hwndCbSharedPhoneNumbers, pEntry->fSharedPhoneNumbers );
// Load the icons into the move up and move down buttons. From
// what I can tell tell in MSDN, you don't have to close or
// destroy the icon handle.
//
pInfo->hiconUpArr = LoadImage(
g_hinstDll, MAKEINTRESOURCE( IID_UpArr ), IMAGE_ICON, 0, 0, 0 );
pInfo->hiconDnArr = LoadImage(
g_hinstDll, MAKEINTRESOURCE( IID_DnArr ), IMAGE_ICON, 0, 0, 0 );
pInfo->hiconUpArrDis = LoadImage(
g_hinstDll, MAKEINTRESOURCE( IID_UpArrDis ), IMAGE_ICON, 0, 0, 0 );
pInfo->hiconDnArrDis = LoadImage(
g_hinstDll, MAKEINTRESOURCE( IID_DnArrDis ), IMAGE_ICON, 0, 0, 0 );
}
pInfo->pListAreaCodes = DtlDuplicateList(
pInfo->pArgs->pUser->pdtllistAreaCodes,
DuplicatePszNode, DestroyPszNode );
CuInit( &pInfo->cuinfo,
pInfo->hwndStAreaCodes, pInfo->hwndClbAreaCodes,
pInfo->hwndStPhoneNumber, pInfo->hwndEbPhoneNumber,
pInfo->hwndStCountryCodes, pInfo->hwndLbCountryCodes,
pInfo->hwndCbUseDialingRules, pInfo->hwndPbDialingRules,
pInfo->hwndPbAlternates,
NULL, NULL,
pInfo->pListAreaCodes );
pInfo->fCuInfoInitialized = TRUE;
// Configure and populate the device list, selecting the first item.
//
GeInitLvDevices( pInfo );
GeFillLvDevices( pInfo );
// Set initial focus.
//
if (pArgs->fMultipleDevices)
{
SetFocus( pInfo->hwndLvDevices );
}
else
{
ASSERT( IsWindowEnabled( pInfo->hwndEbPhoneNumber ) );
SetFocus( pInfo->hwndEbPhoneNumber );
Edit_SetSel( pInfo->hwndEbPhoneNumber, 0, -1 );
}
return FALSE;
}
else
{
ASSERT( pEntry->dwType == RASET_Direct );
// The listview has a different control-ID in single mode so that
// a different help context can be provided.
//
pInfo->hwndLbDevices =
GetDlgItem( hwndPage, CID_GE_LB_Devices );
ASSERT( pInfo->hwndLbDevices );
// Configure and populate the device list, selecting the first item.
//
GeFillLbDevices( pInfo );
}
return TRUE;
}
LVXDRAWINFO*
GeLvDevicesCallbackMultiple(
IN HWND hwndLv,
IN DWORD dwItem )
// Enhanced list view callback to report drawing information. 'HwndLv' is
// the handle of the list view control. 'DwItem' is the index of the item
// being drawn.
//
// Returns the address of the draw information.
//
{
// Use "full row select" and other recommended options.
//
// Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
//
static LVXDRAWINFO info = { 1, 0, 0, { 0 } };
return &info;
}
LVXDRAWINFO*
GeLvDevicesCallbackSingle(
IN HWND hwndLv,
IN DWORD dwItem )
// Enhanced list view callback to report drawing information. 'HwndLv' is
// the handle of the list view control. 'DwItem' is the index of the item
// being drawn.
//
// Returns the address of the draw information.
//
{
// Set up to emulate a static text control but with icon on left.
//
// Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
//
static LVXDRAWINFO info = { 1, 0, LVXDI_DxFill, { LVXDIA_Static } };
return &info;
}
VOID
GeMoveDevice(
IN PEINFO* pInfo,
IN BOOL fUp )
// Refill the ListView of devices with the selected item moved up or down
// one position. 'FUp' is set to move up, otherwise moves down. 'PInfo'
// is the property sheeet context.
//
{
DTLNODE* pNode;
DTLNODE* pPrevNode;
DTLNODE* pNextNode;
DTLLIST* pList;
if (pInfo->iDeviceSelected < 0)
{
return;
}
pNode =
(DTLNODE* )ListView_GetParamPtr(
pInfo->hwndLvDevices, pInfo->iDeviceSelected );
ASSERT( pNode );
if(NULL == pNode)
{
return;
}
pList = pInfo->pArgs->pEntry->pdtllistLinks;
if (fUp)
{
pPrevNode = DtlGetPrevNode( pNode );
if (!pPrevNode)
{
return;
}
DtlRemoveNode( pList, pNode );
DtlAddNodeBefore( pList, pPrevNode, pNode );
}
else
{
pNextNode = DtlGetNextNode( pNode );
if (!pNextNode)
{
return;
}
DtlRemoveNode( pList, pNode );
DtlAddNodeAfter( pList, pNextNode, pNode );
}
GeFillLvDevices( pInfo );
}
DWORD
GeSaveLvDeviceChecks(
IN PEINFO* pInfo )
// Mark links enabled/disabled based on it's check box in the ListView of
// devices. Returns the count of enabled devices.
//
{
DWORD dwCount = 0;
if (pInfo->pArgs->fMultipleDevices)
{
INT i;
i = -1;
while ((i = ListView_GetNextItem(
pInfo->hwndLvDevices, i, LVNI_ALL )) >= 0)
{
DTLNODE* pNode;
PBLINK* pLink;
pNode = (DTLNODE* )ListView_GetParamPtr( pInfo->hwndLvDevices, i );
ASSERT( pNode );
if(NULL == pNode)
{
return 0;
}
pLink = (PBLINK* )DtlGetData( pNode );
ASSERT( pLink );
pLink->fEnabled = ListView_GetCheck( pInfo->hwndLvDevices, i );
dwCount += (pLink->fEnabled) ? 1 : 0;
}
}
return dwCount;
}
VOID
GeSetPhoneFields(
IN PEINFO* pInfo,
IN DTLNODE* pSrcLinkNode,
IN BOOL fDisableAll )
// Set the phone number group box fields from the phone information in
// PBLINK node 'pSrcLinkNode'. 'PInfo' is the property sheet context.
//
{
PBLINK* pLink;
DTLNODE* pPhoneNode;
TRACE( "GeSetPhoneFields" );
pLink = (PBLINK* )DtlGetData( pSrcLinkNode );
ASSERT( pLink );
pPhoneNode = FirstPhoneNodeFromPhoneList( pLink->pdtllistPhones );
if (pPhoneNode)
{
CuSetInfo( &pInfo->cuinfo, pPhoneNode, fDisableAll );
DestroyPhoneNode( pPhoneNode );
}
}
VOID
GeUpdateDialAnotherFirstState(
IN PEINFO* pInfo )
// Update the prequisite entry controls. 'PInfo' is the property sheet
// context.
//
{
if (Button_GetCheck( pInfo->hwndCbDialAnotherFirst ))
{
GeFillLbDialAnotherFirst( pInfo, FALSE );
EnableWindow( pInfo->hwndLbDialAnotherFirst, TRUE );
}
else
{
GeClearLbDialAnotherFirst( pInfo->hwndLbDialAnotherFirst );
EnableWindow( pInfo->hwndLbDialAnotherFirst, FALSE );
}
}
VOID
GeUpdatePhoneNumberFields(
IN PEINFO* pInfo,
IN BOOL fSharedToggle )
// Called when anything affecting the Phone Number group of controls
// occurs. 'PInfo' is the property sheet context. 'FSharedToggle' is set
// when the update is due to the toggling of the shared phone number
// checkbox.
//
{
INT i;
BOOL fShared;
DTLNODE* pNode;
PBLINK* pLink;
TRACE( "GeUpdatePhoneNumberFields" );
if (pInfo->pArgs->fMultipleDevices)
{
fShared = Button_GetCheck( pInfo->hwndCbSharedPhoneNumbers );
}
else
{
fShared = TRUE;
ASSERT( !fSharedToggle );
}
if (pInfo->iDeviceSelected >= 0)
{
// A device was previously selected.
//
pNode = (DTLNODE* )ListView_GetParamPtr(
pInfo->hwndLvDevices, pInfo->iDeviceSelected );
ASSERT( pNode );
if(NULL == pNode)
{
return;
}
if (fShared)
{
if (fSharedToggle)
{
// Shared-mode just toggled on. Update the selected node from
// the controls, then copy it's phone settings to the shared
// node.
//
GeGetPhoneFields( pInfo, pNode );
CopyLinkPhoneNumberInfo( pInfo->pArgs->pSharedNode, pNode );
}
else
{
// Update the shared node from the controls.
//
GeGetPhoneFields( pInfo, pInfo->pArgs->pSharedNode );
}
}
else
{
if (fSharedToggle)
{
// Shared-mode just toggled off. Update the shared node from
// the controls, then copy it's phone settings to the selected
// node.
//
GeGetPhoneFields( pInfo, pInfo->pArgs->pSharedNode );
CopyLinkPhoneNumberInfo( pNode, pInfo->pArgs->pSharedNode );
}
else
{
// Update the previously selected node from the controls.
//
GeGetPhoneFields( pInfo, pNode );
}
}
}
// Load the phone number fields and title with the phone number for the
// selected link. Save the selected device index in the context block so
// we'll know where to swap out the phone number when the selection
// changes.
//
i = ListView_GetNextItem( pInfo->hwndLvDevices, -1, LVIS_SELECTED );
pInfo->iDeviceSelected = i;
if (i < 0)
{
// No device is currently selected. This occurs because a new
// selection generates first an "unselect" event, then a separate
// "select" event.
//
return;
}
// Set the phone number fields including group box title, all
// enabling/disabling, and "blanked" handling of area code and country
// code. The entire phone number group is disabled when in separate
// number mode with the selected device unchecked.
//
if (fShared)
{
pInfo->pCurLinkNode = pInfo->pArgs->pSharedNode;
GeUpdatePhoneNumberTitle( pInfo, NULL );
GeSetPhoneFields( pInfo, pInfo->pArgs->pSharedNode, FALSE );
}
else
{
pNode = (DTLNODE* )ListView_GetParamPtr( pInfo->hwndLvDevices, i );
ASSERT( pNode );
if(NULL == pNode)
{
return;
}
pLink = (PBLINK* )DtlGetData( pNode );
ASSERT( pLink );
if(NULL == pLink)
{
return;
}
pInfo->pCurLinkNode = pNode;
GeUpdatePhoneNumberTitle( pInfo, pLink->pbport.pszDevice );
GeSetPhoneFields( pInfo, pNode,
!(ListView_GetCheck( pInfo->hwndLvDevices, i )) );
}
// When the enabled device count falls below 2 the "Multiple Devices"
// group box and contained controls on the Options page are disabled. If
// 2 or above it is enabled.
//
if (pInfo->hwndOe && pInfo->pArgs->fMultipleDevices)
{
DWORD cChecked;
cChecked = ListView_GetCheckedCount( pInfo->hwndLvDevices );
OeEnableMultipleDeviceGroup( pInfo, (cChecked > 1) );
}
}
VOID
GeUpdatePhoneNumberTitle(
IN PEINFO* pInfo,
IN TCHAR* pszDevice )
// Update the Phone Number group box title based on the "share" mode.
// 'PInfo' is the property sheet context. 'PszDevice' is the device name
// string to display in non-shared mode or NULL in shared mode.
//
{
if (!pInfo->hwndGbPhoneNumber)
{
return;
}
if (pszDevice)
{
TCHAR* psz;
TCHAR* pszFormat;
// Set the individual title, e.g. "Phone number for K-Tel 28.8
// Fax/Plus".
//
pszFormat = PszFromId( g_hinstDll, SID_LinkPhoneNumber );
if (pszFormat)
{
psz = Malloc(
(lstrlen( pszFormat ) + lstrlen( pszDevice ))
* sizeof(TCHAR) );
if (psz)
{
wsprintf( psz, pszFormat, pszDevice );
SetWindowText( pInfo->hwndGbPhoneNumber, psz );
Free( psz );
}
Free( pszFormat );
}
}
else
{
TCHAR* psz;
// Set the shared title, e.g. "Phone number".
//
psz = PszFromId( g_hinstDll, SID_SharedPhoneNumber );
if (psz)
{
SetWindowText( pInfo->hwndGbPhoneNumber, psz );
Free( psz );
}
}
}
VOID
GeUpdateUpDownButtons(
IN PEINFO* pInfo )
// Update the enable/disable and corresponding icon for the
// move-up/move-down buttons. Moves focus and default button as
// necessary. 'PInfo' is the property sheet context.
//
{
INT iSel;
INT cItems;
BOOL fSel;
if (!pInfo->pArgs->fMultipleDevices)
{
return;
}
iSel = ListView_GetNextItem( pInfo->hwndLvDevices, -1, LVNI_SELECTED );
fSel = (iSel >= 0);
cItems = ListView_GetItemCount( pInfo->hwndLvDevices );
// "Up" button, enabled if there is an item above.
//
if (iSel > 0)
{
EnableWindow( pInfo->hwndPbUp, TRUE );
SendMessage( pInfo->hwndPbUp, BM_SETIMAGE, IMAGE_ICON,
(LPARAM )pInfo->hiconUpArr );
}
else
{
EnableWindow( pInfo->hwndPbUp, FALSE );
SendMessage( pInfo->hwndPbUp, BM_SETIMAGE, IMAGE_ICON,
(LPARAM )pInfo->hiconUpArrDis );
}
// "Down" button, enabled if there is an item below.
//
if (fSel && (iSel < cItems - 1))
{
EnableWindow( pInfo->hwndPbDown, TRUE );
SendMessage( pInfo->hwndPbDown, BM_SETIMAGE, IMAGE_ICON,
(LPARAM )pInfo->hiconDnArr );
}
else
{
EnableWindow( pInfo->hwndPbDown, FALSE );
SendMessage( pInfo->hwndPbDown, BM_SETIMAGE, IMAGE_ICON,
(LPARAM )pInfo->hiconDnArrDis );
}
// if the focus button is disabled, move focus to the ListView and make OK
// the default button.
//
if (!IsWindowEnabled( GetFocus() ))
{
SetFocus( pInfo->hwndLvDevices );
Button_MakeDefault( pInfo->hwndDlg,
GetDlgItem( pInfo->hwndDlg, IDOK ) );
}
}
//----------------------------------------------------------------------------
// Options property page
// Listed alphabetically following dialog proc
//----------------------------------------------------------------------------
INT_PTR CALLBACK
OeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
// DialogProc callback for the Options page of the Entry property sheet.
// Parameters and return value are as described for standard windows
// 'DialogProc's.
//
{
#if 0
TRACE4( "OeDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
(DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
#endif
switch (unMsg)
{
case WM_INITDIALOG:
{
return OeInit( hwnd );
}
case WM_HELP:
case WM_CONTEXTMENU:
{
PEINFO* pInfo = PeContext( hwnd );
ASSERT(pInfo);
if (pInfo == NULL)
{
break;
}
if (pInfo->pArgs->fRouter)
{
ContextHelp( g_adwOeRouterHelp, hwnd, unMsg, wparam, lparam );
}
else
{
ContextHelp( g_adwOeHelp, hwnd, unMsg, wparam, lparam );
}
break;
}
case WM_COMMAND:
{
PEINFO* pInfo = PeContext( hwnd );
ASSERT(pInfo);
if (pInfo == NULL)
{
break;
}
return OeCommand(
pInfo, HIWORD( wparam ), LOWORD( wparam ),(HWND )lparam );
}
case WM_NOTIFY:
{
PEINFO* pInfo = PeContext( hwnd );
ASSERT(pInfo);
if (pInfo == NULL)
{
break;
}
switch (((NMHDR* )lparam)->code)
{
case PSN_SETACTIVE:
{
// Because of inter-page dependencies on the 'fAutoLogon'
// flag the User/password and subordinate checkbox states
// must be reinitialized at each activation.
//
OeUpdateUserPwState( pInfo );
break;
}
}
break;
}
}
return FALSE;
}
BOOL
OeCommand(
IN PEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl )
// Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
// is the notification code of the command. 'wId' is the control/menu
// identifier of the command. 'HwndCtrl' is the control window handle of
// the command.
//
// Returns true if processed message, false otherwise.
//
{
TRACE3( "OeCommand(n=%d,i=%d,c=$%x)",
(DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
switch (wId)
{
case CID_OE_CB_PreviewUserPw:
{
pInfo->pArgs->pEntry->fPreviewUserPw =
Button_GetCheck( pInfo->hwndCbPreviewUserPw );
OeUpdateUserPwState( pInfo );
return TRUE;
}
case CID_OE_CB_PreviewDomain:
{
pInfo->pArgs->pEntry->fPreviewDomain =
Button_GetCheck( pInfo->hwndCbPreviewDomain );
return TRUE;
}
case CID_OE_PB_Configure:
{
MultiLinkDialingDlg( pInfo->hwndDlg, pInfo->pArgs->pEntry );
return TRUE;
}
case CID_OE_PB_X25:
{
OeX25( pInfo );
return TRUE;
}
case CID_OE_PB_Tunnel:
{
OeTunnel( pInfo );
return TRUE;
}
case CID_OE_LB_MultipleDevices:
{
pInfo->pArgs->pEntry->dwDialMode =
(DWORD)ComboBox_GetItemData( pInfo->hwndLbMultipleDevices,
ComboBox_GetCurSel( pInfo->hwndLbMultipleDevices ) );
EnableWindow( pInfo->hwndPbConfigureDialing,
!!(pInfo->pArgs->pEntry->dwDialMode == RASEDM_DialAsNeeded) );
return TRUE;
}
case CID_OE_RB_Persistent:
{
switch (wNotification)
{
case BN_CLICKED:
{
ComboBox_SetCurSel( pInfo->hwndLbIdleTimes, 0 );
EnableWindow( pInfo->hwndLbIdleTimes, FALSE );
return TRUE;
}
}
break;
}
case CID_OE_RB_DemandDial:
{
switch (wNotification)
{
case BN_CLICKED:
{
EnableWindow( pInfo->hwndLbIdleTimes, TRUE );
return TRUE;
}
}
break;
}
case CID_OE_PB_Callback:
{
RouterCallbackDlg ( pInfo->hwndOe, pInfo->pArgs );
return TRUE;
}
}
return FALSE;
}
VOID
OeEnableMultipleDeviceGroup(
IN PEINFO* pInfo,
IN BOOL fEnable )
// Enable/disable the Multiple Devices groupbox and all controls it
// contains based on 'fEnable'. 'PInfo' is the property sheet context.
//
{
EnableWindow( pInfo->hwndGbMultipleDevices, fEnable );
EnableWindow( pInfo->hwndLbMultipleDevices, fEnable );
EnableWindow( pInfo->hwndPbConfigureDialing,
(fEnable
&& !!(pInfo->pArgs->pEntry->dwDialMode == RASEDM_DialAsNeeded)) );
}
BOOL
OeInit(
IN HWND hwndPage )
// Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
// page.
//
// Return false if focus was set, true otherwise.
//
{
PEINFO* pInfo;
PBENTRY* pEntry;
LBTABLEITEM* pItem;
HWND hwndLb;
INT i;
INT iSel;
HWND hwndUdRedialAttempts;
static LBTABLEITEM aRedialTimes[] =
{
SID_Time1s, 1,
SID_Time3s, 3,
SID_Time5s, 5,
SID_Time10s, 10,
SID_Time30s, 30,
SID_Time1m, 60,
SID_Time2m, 120,
SID_Time5m, 300,
SID_Time10m, RAS_RedialPause10m,
0, 0
};
static LBTABLEITEM aIdleTimes[] =
{
SID_TimeNever, 0,
SID_Time1m, 60,
SID_Time5m, 300,
SID_Time10m, 600,
SID_Time20m, 1200, //Add for whistler bug 307969
SID_Time30m, 1800,
SID_Time1h, 3600,
SID_Time2h, 7200,
SID_Time4h, 14400,
SID_Time8h, 28800,
SID_Time24h, 86400,
0, 0
};
static LBTABLEITEM aMultipleDeviceOptions[] =
{
SID_DialOnlyFirst, 0,
SID_DialAll, RASEDM_DialAll,
SID_DialNeeded, RASEDM_DialAsNeeded,
0, 0
};
TRACE( "OeInit" );
pInfo = PeContext( hwndPage );
if (!pInfo)
{
return TRUE;
}
pEntry = pInfo->pArgs->pEntry;
// Initialize page-specific context information.
//
pInfo->hwndOe = hwndPage;
// Initialize 'Dialing options' group box.
//
if (!pInfo->pArgs->fRouter)
{
pInfo->hwndCbDisplayProgress =
GetDlgItem( hwndPage, CID_OE_CB_DisplayProgress );
ASSERT( pInfo->hwndCbDisplayProgress );
Button_SetCheck(
pInfo->hwndCbDisplayProgress, pEntry->fShowDialingProgress );
pInfo->hwndCbPreviewUserPw =
GetDlgItem( hwndPage, CID_OE_CB_PreviewUserPw );
ASSERT( pInfo->hwndCbPreviewUserPw );
pInfo->fPreviewUserPw = pEntry->fPreviewUserPw;
Button_SetCheck( pInfo->hwndCbPreviewUserPw, pInfo->fPreviewUserPw );
pInfo->hwndCbPreviewDomain =
GetDlgItem( hwndPage, CID_OE_CB_PreviewDomain );
ASSERT( pInfo->hwndCbPreviewDomain );
pInfo->fPreviewDomain = pEntry->fPreviewDomain;
Button_SetCheck( pInfo->hwndCbPreviewDomain, pInfo->fPreviewDomain );
if (pEntry->dwType == RASET_Phone)
{
pInfo->hwndCbPreviewNumber =
GetDlgItem( hwndPage, CID_OE_CB_PreviewNumber );
ASSERT( pInfo->hwndCbPreviewNumber );
Button_SetCheck(
pInfo->hwndCbPreviewNumber, pEntry->fPreviewPhoneNumber );
}
}
// Initialize 'Redialing options' group box. In the 'fRouter' case this
// includes both the 'Dialing policy' and 'Connection type' group boxes.
//
{
pInfo->hwndEbRedialAttempts =
GetDlgItem( hwndPage, CID_OE_EB_RedialAttempts );
ASSERT( pInfo->hwndEbRedialAttempts );
// Redial attempts. Note that the RAS API and phonebook allow redials
// up to RAS_MaxRedialCount (999999999). However, it was decided this
// many redials didn't make sense. Thus we have limited the UI to a max
// of MAX_UI_REDIAL_ATTEMPTS (99) redials even though through the API
// or an upgraded phonebook entry may have more.
//
hwndUdRedialAttempts = CreateUpDownControl(
WS_CHILD + WS_VISIBLE + WS_BORDER + UDS_SETBUDDYINT
+ UDS_ALIGNRIGHT + UDS_NOTHOUSANDS + UDS_ARROWKEYS,
0, 0, 0, 0, hwndPage, 100, g_hinstDll, pInfo->hwndEbRedialAttempts,
MAX_UI_REDIAL_ATTEMPTS, 0, 0 );
ASSERT( hwndUdRedialAttempts );
Edit_LimitText( pInfo->hwndEbRedialAttempts, MAX_UI_REDIAL_CHARS );
SetDlgItemInt( hwndPage, CID_OE_EB_RedialAttempts,
pEntry->dwRedialAttempts, FALSE );
// Redial times.
//
pInfo->hwndLbRedialTimes =
GetDlgItem( hwndPage, CID_OE_LB_RedialTimes );
ASSERT( pInfo->hwndLbRedialTimes );
{
iSel = -1;
for (pItem = aRedialTimes, i = 0;
pItem->sidItem;
++pItem, ++i )
{
ComboBox_AddItemFromId( g_hinstDll, pInfo->hwndLbRedialTimes,
pItem->sidItem, (VOID* )UlongToPtr(pItem->dwData ));
if (iSel < 0
&& pEntry->dwRedialSeconds <= pItem->dwData)
{
iSel = i;
ComboBox_SetCurSel( pInfo->hwndLbRedialTimes, iSel );
}
}
if (iSel < 0)
{
ComboBox_SetCurSel( pInfo->hwndLbRedialTimes, i - 1 );
}
}
// Idle times.
//
pInfo->hwndLbIdleTimes =
GetDlgItem( hwndPage, CID_OE_LB_IdleTimes );
ASSERT( pInfo->hwndLbIdleTimes );
{
if (pEntry->lIdleDisconnectSeconds < 0)
{
pEntry->lIdleDisconnectSeconds = 0;
}
iSel = -1;
for (pItem = aIdleTimes, i = 0;
pItem->sidItem;
++pItem, ++i )
{
ComboBox_AddItemFromId( g_hinstDll, pInfo->hwndLbIdleTimes,
pItem->sidItem, (VOID* )UlongToPtr(pItem->dwData));
if (iSel < 0
&& pEntry->lIdleDisconnectSeconds <= (LONG )pItem->dwData)
{
iSel = i;
ComboBox_SetCurSel( pInfo->hwndLbIdleTimes, iSel );
}
}
if (iSel < 0)
{
ComboBox_SetCurSel( pInfo->hwndLbIdleTimes, i - 1 );
}
}
if (pInfo->pArgs->fRouter)
{
HWND hwndRb;
//for whistler bug 294271, initialize the window handlers for
//multiple device group gangz
//
pInfo->hwndGbMultipleDevices =
GetDlgItem( hwndPage, CID_OE_GB_MultipleDevices );
ASSERT( pInfo->hwndGbMultipleDevices );
pInfo->hwndLbMultipleDevices =
GetDlgItem( hwndPage, CID_OE_LB_MultipleDevices );
ASSERT( pInfo->hwndLbMultipleDevices );
pInfo->hwndPbConfigureDialing =
GetDlgItem( hwndPage, CID_OE_PB_Configure );
ASSERT( pInfo->hwndPbConfigureDialing );
// Connection type radio buttons.
//
pInfo->hwndRbDemandDial =
GetDlgItem( hwndPage, CID_OE_RB_DemandDial );
ASSERT( pInfo->hwndRbDemandDial );
pInfo->hwndRbPersistent =
GetDlgItem( hwndPage, CID_OE_RB_Persistent );
ASSERT( pInfo->hwndRbPersistent );
hwndRb =
(pEntry->fRedialOnLinkFailure)
? pInfo->hwndRbPersistent
: pInfo->hwndRbDemandDial;
SendMessage( hwndRb, BM_CLICK, 0, 0 );
}
else
{
// Redial on link failure
//
pInfo->hwndCbRedialOnDrop =
GetDlgItem( hwndPage, CID_OE_CB_RedialOnDrop );
ASSERT( pInfo->hwndCbRedialOnDrop );
Button_SetCheck(
pInfo->hwndCbRedialOnDrop, pEntry->fRedialOnLinkFailure );
}
}
// Initialize 'Multiple devices' group box.
//
if (pEntry->dwType == RASET_Phone)
{
pInfo->hwndGbMultipleDevices =
GetDlgItem( hwndPage, CID_OE_GB_MultipleDevices );
ASSERT( pInfo->hwndGbMultipleDevices );
pInfo->hwndLbMultipleDevices =
GetDlgItem( hwndPage, CID_OE_LB_MultipleDevices );
ASSERT( pInfo->hwndLbMultipleDevices );
pInfo->hwndPbConfigureDialing =
GetDlgItem( hwndPage, CID_OE_PB_Configure );
ASSERT( pInfo->hwndPbConfigureDialing );
{
iSel = -1;
for (pItem = aMultipleDeviceOptions, i = 0;
pItem->sidItem;
++pItem, ++i )
{
ComboBox_AddItemFromId(
g_hinstDll, pInfo->hwndLbMultipleDevices,
pItem->sidItem, (VOID* )UlongToPtr(pItem->dwData));
if (pEntry->dwDialMode == pItem->dwData)
{
iSel = i;
ComboBox_SetCurSel( pInfo->hwndLbMultipleDevices, iSel );
}
}
if (iSel < 0)
{
ComboBox_SetCurSel( pInfo->hwndLbMultipleDevices, 0 );
}
}
if (pInfo->pArgs->fMultipleDevices)
{
DWORD cChecked;
// When the enabled device count falls below 2 the "Multiple
// Devices" group box and contained controls are disabled. If 2
// or above it is enabled.
//
if (pInfo->hwndLvDevices)
{
cChecked = ListView_GetCheckedCount( pInfo->hwndLvDevices );
OeEnableMultipleDeviceGroup( pInfo, (cChecked > 1) );
}
}
else
{
ShowWindow( pInfo->hwndGbMultipleDevices, SW_HIDE );
ShowWindow( pInfo->hwndLbMultipleDevices, SW_HIDE );
ShowWindow( pInfo->hwndPbConfigureDialing, SW_HIDE );
}
}
else if (pInfo->pArgs->fRouter && pEntry->dwType == RASET_Vpn)
{
// Make sure that a VPN demand dial interface can't be configured for
// multilink.
//
ComboBox_SetCurSel( pInfo->hwndLbMultipleDevices, 0 );
ShowWindow( pInfo->hwndGbMultipleDevices, SW_HIDE );
ShowWindow( pInfo->hwndLbMultipleDevices, SW_HIDE );
ShowWindow( pInfo->hwndPbConfigureDialing, SW_HIDE );
}
else if (pEntry->dwType == RASET_Broadband)
{
// Make sure that broadband connections can't be multilinked since
// it is not possible to select multiple ports.
//
ComboBox_SetCurSel( pInfo->hwndLbMultipleDevices, 0 );
ShowWindow( pInfo->hwndGbMultipleDevices, SW_HIDE );
ShowWindow( pInfo->hwndLbMultipleDevices, SW_HIDE );
ShowWindow( pInfo->hwndPbConfigureDialing, SW_HIDE );
}
else if ( pEntry->dwType == RASET_Direct )
{
//for whistler bug 294271, initialize the window handlers for
//multiple device group gangz
//
ShowWindow( pInfo->hwndGbMultipleDevices, SW_HIDE );
ShowWindow( pInfo->hwndLbMultipleDevices, SW_HIDE );
ShowWindow( pInfo->hwndPbConfigureDialing, SW_HIDE );
}
// Bug 261692: Don't show X.25 button unless "phone" type entry.
//
if (pInfo->pArgs->fRouter && pEntry->dwType != RASET_Phone)
{
pInfo->hwndPbX25 = GetDlgItem( hwndPage, CID_OE_PB_X25 );
ASSERT( pInfo->hwndPbX25 );
ShowWindow( pInfo->hwndPbX25, SW_HIDE );
EnableWindow( pInfo->hwndPbX25, FALSE );
}
return TRUE;
}
VOID
OeTunnel(
IN PEINFO* pInfo )
// Called when the "Virtual (tunnel) connection" button is pressed to
// chain the VPN add entry wizard.
//
{
//!!!
}
VOID
OeUpdateUserPwState(
IN PEINFO* pInfo )
// Called to update the enabled/disabled save/restore state of the
// User/password and Domain checkboxes.
//
{
PBENTRY* pEntry;
pEntry = pInfo->pArgs->pEntry;
EnableCbWithRestore(
pInfo->hwndCbPreviewUserPw,
!pEntry->fAutoLogon,
FALSE,
&pInfo->fPreviewUserPw );
EnableCbWithRestore(
pInfo->hwndCbPreviewDomain,
!pEntry->fAutoLogon,
FALSE,
&pInfo->fPreviewDomain );
}
VOID
OeX25(
IN PEINFO* pInfo )
// Called when the X.25 button is pressed to popup the X.25 settings
// dialog.
//
{
DTLNODE* pNode;
PBLINK* pLink;
BOOL fLocalPad;
INT iSel;
// Figure out if the selected device is a local PAD device.
//
fLocalPad = FALSE;
iSel = ListView_GetNextItem( pInfo->hwndLvDevices, -1, LVNI_SELECTED );
if (iSel >= 0)
{
pNode = (DTLNODE* )ListView_GetParamPtr( pInfo->hwndLvDevices, iSel );
ASSERT( pNode );
if(NULL == pNode)
{
return;
}
pLink = (PBLINK* )DtlGetData( pNode );
ASSERT( pLink );
if (pLink->pbport.pbdevicetype == PBDT_Pad)
{
fLocalPad = TRUE;
}
}
// Popup the X.25 dialog which saves directly to the common context
// 'pEntry' if user makes changes.
//
X25LogonSettingsDlg( pInfo->hwndDlg, fLocalPad, pInfo->pArgs->pEntry );
}
//----------------------------------------------------------------------------
// Security property page
// Listed alphabetically following dialog proc
//----------------------------------------------------------------------------
INT_PTR CALLBACK
LoDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
// DialogProc callback for the Security page of the Entry property sheet
// "Lo" is for Logon, the original name of this page. Parameters and
// return value are as described for standard windows 'DialogProc's.
//
{
#if 0
TRACE4( "LoDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
(DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
#endif
switch (unMsg)
{
case WM_INITDIALOG:
{
return LoInit( hwnd );
}
case WM_HELP:
case WM_CONTEXTMENU:
{
ContextHelp( g_adwLoHelp, hwnd, unMsg, wparam, lparam );
break;
}
case WM_COMMAND:
{
PEINFO* pInfo = PeContext( hwnd );
ASSERT(pInfo);
if (pInfo == NULL)
{
break;
}
return LoCommand(
pInfo, HIWORD( wparam ), LOWORD( wparam ),(HWND )lparam );
}
case WM_NOTIFY:
{
PEINFO* pInfo = PeContext( hwnd );
ASSERT(pInfo);
if (pInfo == NULL)
{
break;
}
switch (((NMHDR* )lparam)->code)
{
case PSN_SETACTIVE:
{
// Because of inter-page dependencies on the framing type,
// the typical and advanced sections must be reinitialized
// at each activation.
//
BOOL fEnabled;
//This is for pre-shared key bug
//
fEnabled = ( VS_PptpOnly != pInfo->pArgs->pEntry->dwVpnStrategy );
EnableWindow( pInfo->hwndPbIPSec, fEnabled );
pInfo->fAuthRbInitialized = FALSE;
LoRefreshSecuritySettings( pInfo );
break;
}
}
break;
}
}
return FALSE;
}
BOOL
LoCommand(
IN PEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl )
// Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
// is the notification code of the command. 'wId' is the control/menu
// identifier of the command. 'HwndCtrl' is the control window handle of
// the command.
//
// Returns true if processed message, false otherwise.
//
{
TRACE3( "LoCommand(n=%d,i=%d,c=$%x)",
(DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
switch (wId)
{
case CID_LO_LB_Auths:
{
switch (wNotification)
{
case CBN_SELCHANGE:
{
LoLbAuthsSelChange( pInfo );
return TRUE;
}
}
break;
}
case CID_LO_CB_UseWindowsPw:
{
switch (wNotification)
{
case BN_CLICKED:
{
// Necessary to save 'fAutoLogon' setting immediately as
// there is an inter-page dependency with the Option page
// 'fPreviewUserPw' and subordinate controls.
//
LoSaveTypicalAuthSettings( pInfo );
return TRUE;
}
}
break;
}
case CID_LO_RB_TypicalSecurity:
{
switch (wNotification)
{
case BN_CLICKED:
{
if (!pInfo->fAuthRbInitialized)
{
pInfo->fAuthRbInitialized = TRUE;
}
pInfo->pArgs->pEntry->dwAuthRestrictions
&= ~(AR_F_AuthCustom);
LoEnableSecuritySettings( pInfo, TRUE, FALSE );
return TRUE;
}
}
break;
}
case CID_LO_RB_AdvancedSecurity:
{
switch (wNotification)
{
case BN_CLICKED:
{
if (!pInfo->fAuthRbInitialized)
{
pInfo->fAuthRbInitialized = TRUE;
}
else
{
// Save the "typical" settings as they will be used as
// defaults should user decide to invoke the advanced
// security dialog.
//
LoSaveTypicalAuthSettings( pInfo );
}
pInfo->pArgs->pEntry->dwAuthRestrictions
|= AR_F_AuthCustom;
LoEnableSecuritySettings( pInfo, FALSE, TRUE );
return TRUE;
}
}
break;
}
case CID_LO_PB_Advanced:
{
switch (wNotification)
{
case BN_CLICKED:
{
// At this point, the 'pEntry' authentication settings
// match the current "typical" settings, which the
// advanced dialog uses as defaults.
//
AdvancedSecurityDlg( pInfo->hwndDlg, pInfo->pArgs );
return TRUE;
}
}
break;
}
case CID_LO_PB_IPSec:
{
switch (wNotification)
{
case BN_CLICKED:
{
IPSecPolicyDlg( pInfo->hwndDlg, pInfo->pArgs );
return TRUE;
}
}
break;
}
case CID_LO_CB_RunScript:
{
if (SuScriptsCbHandler( &pInfo->suinfo, wNotification ))
{
return TRUE;
}
break;
}
case CID_LO_PB_Edit:
{
if (SuEditPbHandler( &pInfo->suinfo, wNotification ))
{
return TRUE;
}
break;
}
case CID_LO_PB_Browse:
{
if (SuBrowsePbHandler( &pInfo->suinfo, wNotification ))
{
return TRUE;
}
break;
}
}
return FALSE;
}
VOID
LoEnableSecuritySettings(
IN PEINFO* pInfo,
IN BOOL fTypical,
IN BOOL fAdvanced )
// Enables/disables the typical or advanced security settings based on
// caller's 'fTypical' and 'fAdvanced' flags. If neither flag is set all
// controls including the frames and radio buttons are disabled. Both
// flags may not be set. 'PInfo' is the property sheet context.
//
{
BOOL fEither;
ASSERT( !(fTypical && fAdvanced) );
fEither = (fTypical || fAdvanced);
EnableWindow( pInfo->hwndGbSecurityOptions, fEither );
EnableWindow( pInfo->hwndRbTypicalSecurity, fEither );
EnableWindow( pInfo->hwndStAuths, fTypical );
EnableLbWithRestore( pInfo->hwndLbAuths, fTypical, &pInfo->iLbAuths );
// Note: "Use Windows password" and "require encryption" checkbox updates
// are triggered by the EnableLbWithRestore above.
EnableWindow( pInfo->hwndRbAdvancedSecurity, fEither );
EnableWindow( pInfo->hwndStAdvancedText, fAdvanced );
EnableWindow( pInfo->hwndPbAdvanced, fAdvanced );
}
VOID
LoFillLbAuths(
IN PEINFO* pInfo )
// Fill the authentication list box and set the selection based on the
// setting in the phonebook entry. 'PInfo' is the property sheet context.
// This routine should be called only once.
//
{
INT i;
LBTABLEITEM* pItem;
LBTABLEITEM* pItems;
PBENTRY* pEntry;
LBTABLEITEM aItemsPhone[] =
{
SID_AuthUnsecured, TA_Unsecure,
SID_AuthSecured, TA_Secure,
SID_AuthCardOrCert, TA_CardOrCert,
0, 0
};
LBTABLEITEM aItemsVpn[] =
{
SID_AuthSecured, TA_Secure,
SID_AuthCardOrCert, TA_CardOrCert,
0, 0
};
LBTABLEITEM aItemsPhoneRouter[] =
{
SID_AuthUnsecured, TA_Unsecure,
SID_AuthSecured, TA_Secure,
0, 0
};
LBTABLEITEM aItemsVpnRouter[] =
{
SID_AuthSecured, TA_Secure,
0, 0
};
pEntry = pInfo->pArgs->pEntry;
if (pEntry->dwType == RASET_Vpn)
{
pItems = (pInfo->pArgs->fRouter) ? aItemsVpnRouter : aItemsVpn;
}
else
{
pItems = (pInfo->pArgs->fRouter) ? aItemsPhoneRouter : aItemsPhone;
}
for (pItem = pItems; pItem->sidItem; ++pItem)
{
i = ComboBox_AddItemFromId(
g_hinstDll, pInfo->hwndLbAuths,
pItem->sidItem, (VOID* )UlongToPtr(pItem->dwData));
if (pEntry->dwTypicalAuth == pItem->dwData)
{
ComboBox_SetCurSelNotify( pInfo->hwndLbAuths, i );
}
}
if (ComboBox_GetCurSel( pInfo->hwndLbAuths ) < 0)
{
ComboBox_SetCurSelNotify( pInfo->hwndLbAuths, 0 );
}
}
BOOL
LoInit(
IN HWND hwndPage )
// Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
// page.
//
// Return false if focus was set, true otherwise.
//
{
PEINFO* pInfo;
PBENTRY* pEntry;
TRACE( "LoInit" );
pInfo = PeContext( hwndPage );
if (!pInfo)
{
return TRUE;
}
pEntry = pInfo->pArgs->pEntry;
// Initialize page-specific context information.
//
pInfo->hwndLo = hwndPage;
pInfo->hwndGbSecurityOptions =
GetDlgItem( hwndPage, CID_LO_GB_SecurityOptions );
ASSERT( pInfo->hwndGbSecurityOptions );
pInfo->hwndRbTypicalSecurity =
GetDlgItem( hwndPage, CID_LO_RB_TypicalSecurity );
ASSERT( pInfo->hwndRbTypicalSecurity );
pInfo->hwndStAuths = GetDlgItem( hwndPage, CID_LO_ST_Auths );
ASSERT( pInfo->hwndStAuths );
pInfo->hwndLbAuths = GetDlgItem( hwndPage, CID_LO_LB_Auths );
ASSERT( pInfo->hwndLbAuths );
pInfo->hwndCbUseWindowsPw = GetDlgItem( hwndPage, CID_LO_CB_UseWindowsPw );
ASSERT( pInfo->hwndCbUseWindowsPw );
pInfo->hwndCbEncryption = GetDlgItem( hwndPage, CID_LO_CB_Encryption );
ASSERT( pInfo->hwndCbEncryption );
pInfo->hwndRbAdvancedSecurity =
GetDlgItem( hwndPage, CID_LO_RB_AdvancedSecurity );
ASSERT( pInfo->hwndRbAdvancedSecurity );
pInfo->hwndStAdvancedText = GetDlgItem( hwndPage, CID_LO_ST_AdvancedText );
ASSERT( pInfo->hwndStAdvancedText );
pInfo->hwndPbAdvanced = GetDlgItem( hwndPage, CID_LO_PB_Advanced );
ASSERT( pInfo->hwndPbAdvanced );
//
//for VPN's security page show IPSec Policy
// for whistler bug 193987
//
if ( pInfo->pArgs->pEntry->dwType == RASET_Vpn )
{
BOOL fEnabled;
pInfo->hwndPbIPSec = GetDlgItem( hwndPage, CID_LO_PB_IPSec );
ASSERT( pInfo->hwndPbIPSec );
// gangz
//If it is for a remote Win2k server's Demand Dialer
//dont show the IPSec Policy stuff, because W2k didnt
//implement this.
//
if ( pInfo->pArgs->fW2kRouter )
{
ShowWindow( pInfo->hwndPbIPSec, FALSE );
}
else
{
fEnabled = ( VS_PptpOnly != pInfo->pArgs->pEntry->dwVpnStrategy );
EnableWindow( pInfo->hwndPbIPSec, fEnabled );
}
//for the IPSec Policy dialog, fPSKCached = TRUE means the user already
//go to the IPSec Policy dialog and saved a PSK gangz
//
pInfo->pArgs->fPSKCached = FALSE;
//gangz: for bug# 276452
//On a Server OS, the help message for this IPSec pushbutton
//should be different from that for a Non-server OS,
//so change its help ID when neeeded.
//
if ( IsServerOS() )
{
DWORD * p = (DWORD *)g_adwLoHelp;
while( p )
{
if ( (p[0] == 0) && ( p[1] == 0 ) )
{
break;
}
if ( (p[0] == CID_LO_PB_IPSec) &&
(p[1] == HID_LO_PB_IPSec) )
{
p[1] = HID_LO_PB_IPSecServer;
break;
}
p+=2;
}
}
}
else
{
pInfo->hwndGbScripting = GetDlgItem( hwndPage, CID_LO_GB_Scripting );
ASSERT( pInfo->hwndGbScripting );
pInfo->hwndCbRunScript = GetDlgItem( hwndPage, CID_LO_CB_RunScript );
ASSERT( pInfo->hwndCbRunScript );
pInfo->hwndCbTerminal = GetDlgItem( hwndPage, CID_LO_CB_Terminal );
ASSERT( pInfo->hwndCbTerminal );
pInfo->hwndLbScripts = GetDlgItem( hwndPage, CID_LO_LB_Scripts );
ASSERT( pInfo->hwndLbScripts );
pInfo->hwndPbEdit = GetDlgItem( hwndPage, CID_LO_PB_Edit );
ASSERT( pInfo->hwndPbEdit );
pInfo->hwndPbBrowse = GetDlgItem( hwndPage, CID_LO_PB_Browse );
ASSERT( pInfo->hwndPbBrowse );
}
// Initialize the page controls. Note that the page activation event
// immediately after this initialization triggers the final security
// setting enabling/disabling and does any "restore caching". While this
// initialization sets the check values and list selection to bootstrap
// the "restore caching", these settings may be adjusted by the activation
// refresh.
//
if (pInfo->pArgs->fRouter)
{
// The "Use Windows credentials" option is removed in the demand-dial
// case.
//
pInfo->fUseWindowsPw = FALSE;
Button_SetCheck( pInfo->hwndCbUseWindowsPw, FALSE );
EnableWindow ( pInfo->hwndCbUseWindowsPw, FALSE );
ShowWindow (pInfo->hwndCbUseWindowsPw, SW_HIDE );
}
else
{
pInfo->fUseWindowsPw = pEntry->fAutoLogon;
Button_SetCheck( pInfo->hwndCbUseWindowsPw, pInfo->fUseWindowsPw );
}
pInfo->fEncryption =
(pEntry->dwDataEncryption != DE_None
&& pEntry->dwDataEncryption != DE_IfPossible);
Button_SetCheck( pInfo->hwndCbEncryption, pInfo->fEncryption );
// Fill authentiction list and set selection, which triggers all
// appropriate enabling/disabling.
//
LoFillLbAuths( pInfo );
if ((pInfo->pArgs->pEntry->dwType != RASET_Vpn)
&& (pInfo->pArgs->pEntry->dwType != RASET_Direct)
&& (pInfo->pArgs->pEntry->dwType != RASET_Broadband))
//&& !pInfo->pArgs->fRouter)
{
// Set up the after-dial scripting controls.
//
SuInit( &pInfo->suinfo,
pInfo->hwndCbRunScript,
pInfo->hwndCbTerminal,
pInfo->hwndLbScripts,
pInfo->hwndPbEdit,
pInfo->hwndPbBrowse,
pInfo->pArgs->fRouter ? SU_F_DisableTerminal : 0);
pInfo->fSuInfoInitialized = TRUE;
SuSetInfo( &pInfo->suinfo,
pEntry->fScriptAfter,
pEntry->fScriptAfterTerminal,
pEntry->pszScriptAfter );
}
else
{
// Disable/hide the after-dial scripting controls.
// for VPN there is no need to do this Disable/hide operation
//
if (pInfo->pArgs->pEntry->dwType != RASET_Vpn)
{
EnableWindow( pInfo->hwndGbScripting, FALSE );
ShowWindow( pInfo->hwndGbScripting, SW_HIDE );
EnableWindow( pInfo->hwndCbRunScript, FALSE );
ShowWindow( pInfo->hwndCbRunScript, SW_HIDE );
EnableWindow( pInfo->hwndCbTerminal, FALSE );
ShowWindow( pInfo->hwndCbTerminal, SW_HIDE );
EnableWindow( pInfo->hwndLbScripts, FALSE );
ShowWindow( pInfo->hwndLbScripts, SW_HIDE );
EnableWindow( pInfo->hwndPbEdit, FALSE );
ShowWindow( pInfo->hwndPbEdit, SW_HIDE );
EnableWindow( pInfo->hwndPbBrowse, FALSE );
ShowWindow( pInfo->hwndPbBrowse, SW_HIDE );
}
}
if (pInfo->pArgs->fRouter)
{
EnableWindow( pInfo->hwndCbTerminal, FALSE );
ShowWindow( pInfo->hwndCbTerminal, SW_HIDE );
}
return TRUE;
}
VOID
LoLbAuthsSelChange(
IN PEINFO* pInfo )
// Called when the selection in the authentication drop list is changed.
//
{
INT iSel;
DWORD dwTaCode;
// Retrieve the bitmask of authentication protocols associated with the
// selected authentication level.
//
iSel = ComboBox_GetCurSel( pInfo->hwndLbAuths );
if (iSel < 0)
{
dwTaCode = 0;
}
else
{
dwTaCode = (DWORD )ComboBox_GetItemData( pInfo->hwndLbAuths, iSel );
}
if (!pInfo->pArgs->fRouter)
{
// Update the "Use Windows NT credentials" checkbox. Per the spec, it
// is enabled only for "require secure password", though the real
// requirement is that MSCHAP (provides NT-style credentials) gets
// negotiated.
//
EnableCbWithRestore(
pInfo->hwndCbUseWindowsPw,
(dwTaCode == TA_Secure),
FALSE,
&pInfo->fUseWindowsPw );
}
// Update the "Require data encryption" checkbox. Per the spec, it is
// enabled unless "allow unsecured password" is selected, though the real
// requirement is that all authentication protocols in the set provide
// MPPE encryption keys.
//
EnableCbWithRestore(
pInfo->hwndCbEncryption,
(dwTaCode != 0 && dwTaCode != TA_Unsecure),
FALSE,
&pInfo->fEncryption );
}
VOID
LoRefreshSecuritySettings(
IN PEINFO* pInfo )
// Sets the contents and state of all typical and advanced security
// setting fields.
//
{
if (pInfo->pArgs->pEntry->dwBaseProtocol & BP_Slip)
{
// For SLIP framing, all the typical and advanced controls are
// disabled and the radio buttons show no selection.
//
Button_SetCheck( pInfo->hwndRbTypicalSecurity, FALSE );
Button_SetCheck( pInfo->hwndRbAdvancedSecurity, FALSE );
LoEnableSecuritySettings( pInfo, FALSE, FALSE );
if (pInfo->fShowSlipPopup)
{
// Time to show the one-shot informational about SLIP not doing
// any in-protocol authentication or encryption.
//
MsgDlg( pInfo->hwndDlg, SID_NoAuthForSlip, NULL );
pInfo->fShowSlipPopup = FALSE;
}
}
else
{
HWND hwndRb;
// For PPP framing, select the appropriate security setting radio
// button which triggers additional enabling/disabling of the framed
// controls.
//
if (pInfo->pArgs->pEntry->dwAuthRestrictions & AR_F_AuthCustom)
{
hwndRb = pInfo->hwndRbAdvancedSecurity;
}
else
{
hwndRb = pInfo->hwndRbTypicalSecurity;
}
SendMessage( hwndRb, BM_CLICK, 0, 0 );
}
}
VOID
LoSaveTypicalAuthSettings(
IN PEINFO* pInfo )
// Save the values in the "typical" authentication controls to the
// phonebook entry. 'PInfo' is the property sheet context.
//
{
PBENTRY* pEntry;
INT iSel;
pEntry = pInfo->pArgs->pEntry;
iSel = ComboBox_GetCurSel( pInfo->hwndLbAuths );
if (iSel >= 0)
{
pEntry->dwTypicalAuth =
(DWORD) ComboBox_GetItemData( pInfo->hwndLbAuths, iSel );
pEntry->dwAuthRestrictions =
AuthRestrictionsFromTypicalAuth( pEntry->dwTypicalAuth );
// Set the default custom authentication key value for smart
// cards. RasDial API should assume this default anyway, but we
// need it before then in DialerDlgEap.
//
if (pEntry->dwTypicalAuth == TA_CardOrCert)
{
pEntry->dwCustomAuthKey = EAPCFG_DefaultKey;
}
else
{
pEntry->dwCustomAuthKey = (DWORD )-1;
}
}
if (IsWindowEnabled( pInfo->hwndCbUseWindowsPw ))
{
pEntry->fAutoLogon =
Button_GetCheck( pInfo->hwndCbUseWindowsPw );
}
else
{
pEntry->fAutoLogon = FALSE;
}
if (IsWindowEnabled( pInfo->hwndCbEncryption ))
{
pEntry->dwDataEncryption =
(Button_GetCheck( pInfo->hwndCbEncryption ))
? DE_Require : DE_IfPossible;
}
else
{
pEntry->dwDataEncryption = DE_IfPossible;
}
if (pEntry->dwDataEncryption == DE_Require
&& !(pEntry->dwType == RASET_Vpn
&& pEntry->dwVpnStrategy == VS_L2tpOnly))
{
// Encryption is required and MPPE will be the encryption method
// so eliminate authentication protocols that don't support it.
//
pEntry->dwAuthRestrictions &= ~(AR_F_AuthNoMPPE);
}
}
//----------------------------------------------------------------------------
// Networking property page
// Listed alphabetically following dialog proc
//----------------------------------------------------------------------------
LVXDRAWINFO*
NeLvComponentsCallback(
IN HWND hwndLv,
IN DWORD dwItem )
// Enhanced list view callback to report drawing information. 'HwndLv' is
// the handle of the list view control. 'DwItem' is the index of the item
// being drawn.
//
// Returns the address of the draw information.
//
{
// Use "full row select" and other recommended options.
//
// Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
//
static LVXDRAWINFO info = { 1, 0, LVXDI_DxFill, { 0 } };
return &info;
}
INT_PTR CALLBACK
NeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
// DialogProc callback for the Network page of the Entry property sheet.
// Parameters and return value are as described for standard windows
// 'DialogProc's.
//
{
// Filter the customized list view messages
if (ListView_OwnerHandler(hwnd, unMsg, wparam, lparam, NeLvComponentsCallback))
return TRUE;
switch (unMsg)
{
case WM_INITDIALOG:
{
return NeInit( hwnd );
}
case WM_HELP:
case WM_CONTEXTMENU:
{
ContextHelp( g_adwNeHelp, hwnd, unMsg, wparam, lparam );
break;
}
case WM_COMMAND:
{
PEINFO* pInfo = PeContext (hwnd);
ASSERT (pInfo);
switch (LOWORD(wparam))
{
case CID_NE_LB_ServerType:
if (CBN_SELCHANGE == HIWORD(wparam))
{
NeServerTypeSelChange (pInfo);
}
break;
case CID_NE_PB_Settings:
DialogBoxParam (g_hinstDll,
MAKEINTRESOURCE(DID_NE_PppSettings),
hwnd, PpDlgProc, (LPARAM)pInfo);
break;
case CID_NE_PB_Add:
NeAddComponent (pInfo);
break;
case CID_NE_PB_Properties:
NeShowComponentProperties (pInfo);
break;
case CID_NE_PB_Remove:
NeRemoveComponent (pInfo);
break;
}
break;
}
case WM_NOTIFY:
{
PEINFO* pInfo = PeContext(hwnd);
//!!! Hack related to PeTerm in WM_DESTROY. We still get
// WM_NOTIFYs after PeTerm is called. So we commented out the
// following assert and moved it into each message handler below.
//ASSERT (pInfo);
switch (((NMHDR*)lparam)->code)
{
// !!! See if base lvx.c code can handle inversion of check state on double
// click.
#if 0
case NM_CLICK:
ASSERT (pInfo);
if (CID_NE_LV_Components == ((NMHDR*)lparam)->idFrom)
{
NeLvClick (pInfo, FALSE);
}
break;
#endif
case NM_DBLCLK:
ASSERT (pInfo);
if (CID_NE_LV_Components == ((NMHDR*)lparam)->idFrom)
{
NeLvClick (pInfo, TRUE);
}
break;
case LVN_ITEMCHANGED:
ASSERT (pInfo);
NeLvItemChanged (pInfo);
break;
case LVN_DELETEITEM:
ASSERT (pInfo);
NeLvDeleteItem (pInfo, (NM_LISTVIEW*)lparam);
break;
case PSN_SETACTIVE:
ASSERT (pInfo);
// If we couldn't get INetCfg, we can't show this page.
//
if (!pInfo->pNetCfg)
{
MsgDlg( pInfo->hwndDlg, ERR_CANT_SHOW_NETTAB_INETCFG, NULL );
SetWindowLong( hwnd, DWLP_MSGRESULT, -1 );
return TRUE;
}
break;
}
break;
}
}
return FALSE;
}
void
NeEnsureNetshellLoaded (
IN PEINFO* pInfo)
{
// Load the netshell utilities interface. The interface is freed in PeTerm.
//
if (!pInfo->pNetConUtilities)
{
// Initialize the NetConnectionsUiUtilities
//
HRESULT hr = HrCreateNetConnectionUtilities(&pInfo->pNetConUtilities);
}
}
BOOL
NeInit(
IN HWND hwndPage )
// Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
// page.
//
// Return false if focus was set, true otherwise.
//
{
PEINFO* pInfo;
PBENTRY* pEntry;
pInfo = PeContext( hwndPage );
if (!pInfo)
{
return TRUE;
}
// Initialize page-specific context information.
//
pInfo->hwndLbServerType =
GetDlgItem( hwndPage, CID_NE_LB_ServerType );
ASSERT( pInfo->hwndLbServerType );
pInfo->hwndPbSettings =
GetDlgItem( hwndPage, CID_NE_PB_Settings );
ASSERT( pInfo->hwndPbSettings );
pInfo->hwndLvComponents =
GetDlgItem( hwndPage, CID_NE_LV_Components );
ASSERT( pInfo->hwndLvComponents );
pInfo->hwndPbAdd =
GetDlgItem( hwndPage, CID_NE_PB_Add );
ASSERT( pInfo->hwndPbAdd );
pInfo->hwndPbRemove =
GetDlgItem( hwndPage, CID_NE_PB_Remove );
ASSERT( pInfo->hwndPbRemove );
pInfo->hwndPbProperties =
GetDlgItem( hwndPage, CID_NE_PB_Properties );
ASSERT( pInfo->hwndPbProperties );
pInfo->hwndDescription =
GetDlgItem( hwndPage, CID_NE_LB_ComponentDesc );
ASSERT( pInfo->hwndDescription );
// Initialize page.
//
pEntry = pInfo->pArgs->pEntry;
// Initialize the server type combo box with the strings and the selection.
//
if (pEntry->dwType == RASET_Vpn)
{
INT i;
LBTABLEITEM* pItem;
// Whistler bug 312921 CM/RAS should default to PPTP instead of L2TP
//
LBTABLEITEM aItems[] =
{
SID_ST_VpnAuto, VS_PptpFirst,
SID_ST_VpnPptp, VS_PptpOnly,
SID_ST_VpnL2tp, VS_L2tpOnly,
0, 0
};
for (pItem = aItems; pItem->sidItem != 0; ++pItem)
{
i = ComboBox_AddItemFromId(
g_hinstDll, pInfo->hwndLbServerType,
pItem->sidItem, (VOID* )UlongToPtr(pItem->dwData));
if (pItem->dwData == pEntry->dwVpnStrategy)
{
ComboBox_SetCurSel( pInfo->hwndLbServerType, i );
}
}
// If nothing was selected, then the strategy must have been one of the
// VS_xxxxFirst values. Set the current selection to automatic.
if ( ComboBox_GetCurSel ( pInfo->hwndLbServerType ) < 0 )
ComboBox_SetCurSel( pInfo->hwndLbServerType, 0 );
// Change the label to be VPN-specific per bug 307526.
//
{
TCHAR* psz;
psz = PszFromId( g_hinstDll, SID_NE_VpnServerLabel );
if (psz)
{
SetWindowText(
GetDlgItem( hwndPage, CID_NE_ST_ServerType ), psz );
Free( psz );
}
}
}
else if (pEntry->dwType == RASET_Broadband)
{
INT i;
LBTABLEITEM* pItem;
LBTABLEITEM aItems[] =
{
SID_ST_BbPppoe, BP_Ppp,
0, 0
};
for (pItem = aItems; pItem->sidItem != 0; ++pItem)
{
i = ComboBox_AddItemFromId(
g_hinstDll, pInfo->hwndLbServerType,
pItem->sidItem, (VOID* )UlongToPtr(pItem->dwData));
}
ComboBox_SetCurSel( pInfo->hwndLbServerType, 0 );
// Change the label to be broadband-specific
//
{
TCHAR* psz;
psz = PszFromId( g_hinstDll, SID_NE_BbServerLabel );
if (psz)
{
SetWindowText(
GetDlgItem( hwndPage, CID_NE_ST_ServerType ), psz );
Free( psz );
}
}
}
else
{
ComboBox_AddItemFromId (g_hinstDll, pInfo->hwndLbServerType,
SID_ST_Ppp, (VOID*)BP_Ppp );
if (!pInfo->pArgs->fRouter)
{
ComboBox_AddItemFromId (g_hinstDll, pInfo->hwndLbServerType,
SID_ST_Slip, (VOID*)BP_Slip );
}
if (pEntry->dwBaseProtocol == BP_Ppp)
{
ComboBox_SetCurSel(pInfo->hwndLbServerType, 0 );
}
else
{
ComboBox_SetCurSel( pInfo->hwndLbServerType, 1 );
EnableWindow( pInfo->hwndPbSettings, FALSE );
}
}
// Set the image list for the state of the check boxes.
//
ListView_InstallChecks( pInfo->hwndLvComponents, g_hinstDll );
ListView_InsertSingleAutoWidthColumn( pInfo->hwndLvComponents );
// Set the image list for the component bitmaps. Unfortunately we have to
// duplicate it (as opposed to share) because the image list for the state
// icons is not shared. (If we set the shared style, all image lists would
// have to be deleted manually.
//
{
ZeroMemory (&pInfo->cild, sizeof(pInfo->cild));
pInfo->cild.cbSize = sizeof(pInfo->cild);
if (SetupDiGetClassImageList (&pInfo->cild))
{
HIMAGELIST himlSmall = ImageList_Duplicate (pInfo->cild.ImageList);
ListView_SetImageList (pInfo->hwndLvComponents, himlSmall, LVSIL_SMALL);
}
}
// Get the interface used to change network configuration and lock it.
// The description of who has the lock (us) comes from the title of our
// parent dialog. This is done so that when other applications try to obtain
// the lock (and fail) they get an indication of who has it locked. They
// can then direct the user to close our window to release the lock.
//
{
BOOL fEnableAdd = TRUE;
HRESULT hr;
TCHAR pszParentCaption [MAX_PATH] = {0};
GetWindowText (GetParent(hwndPage), pszParentCaption, MAX_PATH);
pInfo->fInitCom = TRUE;
hr = HrCreateAndInitializeINetCfg (&pInfo->fInitCom, &pInfo->pNetCfg,
TRUE, 0, pszParentCaption, NULL);
if (S_OK == hr)
{
// Refresh the list view.
//
hr = HrNeRefreshListView (pInfo);
// Reset the state of the buttons as if something changed.
//
NeLvItemChanged (pInfo);
pInfo->fNetCfgLock = TRUE;
}
else
{
DWORD dwMsg = SID_NE_ReadOnly;
//For whistler bug 311566
//
if (NETCFG_E_NO_WRITE_LOCK == hr)
{
pInfo->fReadOnly = TRUE;
}
if (NETCFG_E_NEED_REBOOT == hr)
{
dwMsg = SID_NE_Reboot;
}
else if (E_ACCESSDENIED == hr)
{
pInfo->fNonAdmin = TRUE;
dwMsg = SID_NE_AccessDenied;
}
// Uh.. ok let's try that again in read-only mode
hr = HrCreateAndInitializeINetCfg (&pInfo->fInitCom,
&pInfo->pNetCfg,FALSE, 0,
pszParentCaption, NULL);
if (S_OK == hr)
{
// Refresh the list view.
//
hr = HrNeRefreshListView (pInfo);
// Reset the state of the buttons as if something changed.
//
NeLvItemChanged (pInfo);
MsgDlg( pInfo->hwndDlg, dwMsg, NULL );
}
}
// Get the interface so we can check our access rights to the UI
//
NeEnsureNetshellLoaded (pInfo);
if (NULL != pInfo->pNetConUtilities)
{
fEnableAdd = INetConnectionUiUtilities_UserHasPermission(
pInfo->pNetConUtilities,
NCPERM_AddRemoveComponents);
}
// Disable some buttons if user does not have privilege
//
if (pInfo->fReadOnly || (NULL == pInfo->pNetConUtilities))
{
EnableWindow(pInfo->hwndPbAdd, FALSE);
EnableWindow(pInfo->hwndPbRemove, FALSE);
EnableWindow(pInfo->hwndPbProperties, FALSE);
}
// Disable some buttons if running in non-admin mode
else if (pInfo->fNonAdmin)
{
EnableWindow(pInfo->hwndPbAdd, FALSE);
EnableWindow(pInfo->hwndPbRemove, FALSE);
}
else
{
EnableWindow(pInfo->hwndPbAdd, fEnableAdd);
// Other buttons enabled via NeLvItemChanged
}
// pmay: 348623
//
// Hide some buttons if we're remote admining
//
if (pInfo->pArgs->fRemote)
{
ShowWindow(pInfo->hwndPbAdd, SW_HIDE);
ShowWindow(pInfo->hwndPbRemove, SW_HIDE);
}
}
return TRUE;
}
void
NeServerTypeSelChange (
IN PEINFO* pInfo)
{
PBENTRY* pEntry;
int iSel;
DWORD dwValue;
pEntry = pInfo->pArgs->pEntry;
iSel = ComboBox_GetCurSel (pInfo->hwndLbServerType);
ASSERT (CB_ERR != iSel);
dwValue = (DWORD) ComboBox_GetItemData (pInfo->hwndLbServerType, iSel);
// Regular connections choose between slip and ppp
//
if (pEntry->dwType != RASET_Vpn)
{
pEntry->dwBaseProtocol = dwValue;
// When SLIP is selected, turn off all protocols but IP and indicate
// the SLIP security page informational popup should appear.
//
if (BP_Slip == dwValue)
{
// No need to exclude the protocols. We lose this config state if
// we remove this and its of no use anyway. PPP won't be done
// if slip is selected -- [raos].
//
// pEntry->dwfExcludedProtocols = ~NP_Ip;
pInfo->fShowSlipPopup = TRUE;
}
HrNeRefreshListView (pInfo);
}
// Vpn connections select a strategy. When automatic is selected,
// we need to make sure the authentication and encryption is
// compatible
//
else
{
pEntry->dwVpnStrategy = dwValue;
// Whistler bug 312921 CM/RAS should default to PPTP instead of L2TP
//
if (dwValue == VS_PptpFirst)
{
pEntry->dwDataEncryption = DE_Require;
if( !(pEntry->dwAuthRestrictions & AR_F_AuthEAP ) )
{
pEntry->dwAuthRestrictions = AR_F_TypicalSecure;
}
pEntry->dwTypicalAuth = TA_Secure;
}
}
EnableWindow (pInfo->hwndPbSettings, !!(BP_Ppp == pEntry->dwBaseProtocol));
}
BOOL
NeRequestReboot (
IN PEINFO* pInfo)
{
NeEnsureNetshellLoaded (pInfo);
if (pInfo->pNetConUtilities)
{
HRESULT hr;
// A reboot is required. Ask the user if it is ok to reboot now
//
//$TODO NULL caption?
hr = INetConnectionUiUtilities_QueryUserForReboot(
pInfo->pNetConUtilities, pInfo->hwndDlg,
NULL, QUFR_PROMPT);
if (S_OK == hr)
{
// User requested a reboot, note this for processing in OnApply
// which is triggered by the message posted below
//
pInfo->fRebootAlreadyRequested = TRUE;
// Press the cancel button (changes have already been applied)
// so the appropriate cleanup occurs.
//
PostMessage(pInfo->hwndDlg, PSM_PRESSBUTTON,
(WPARAM)PSBTN_OK, 0);
}
else if (S_FALSE == hr)
{
// User denied to request to reboot
//
return FALSE;
}
}
return TRUE;
}
void
NeSaveBindingChanges(IN PEINFO* pInfo)
{
// Won't have changes to keep unless we have a writable INetCfg
if (pInfo->pNetCfg)
{
int iItem;
INetCfgComponent* pComponent;
BOOL fEnabled;
HRESULT hr;
// Update the phone book entry with the enabled state of the components.
// Do this by enumerating the components from the list view item data
// and consulting the check state for each.
//
iItem = -1;
while (-1 != (iItem = ListView_GetNextItem (pInfo->hwndLvComponents,
iItem, LVNI_ALL)))
{
pComponent = PComponentFromItemIndex (pInfo->hwndLvComponents, iItem);
ASSERT (pComponent);
fEnabled = ListView_GetCheck (pInfo->hwndLvComponents, iItem);
if(pComponent)
{
NeEnableComponent (pInfo, pComponent, fEnabled);
}
}
}
}
void
NeAddComponent (
IN PEINFO* pInfo)
{
NeEnsureNetshellLoaded (pInfo);
// If we have our pointer to the interface used to bring up the add
// component dialog (obtained above only once), call it.
//
if (pInfo->pNetConUtilities)
{
HRESULT hr;
// We want to filter out protocols that RAS does not care about
// We do this by sending in a CI_FILTER_INFO structure indicating
// we want non-RAS protocols filtered out
//
CI_FILTER_INFO cfi = {0};
cfi.eFilter = FC_RASCLI;
ASSERT (pInfo->pNetCfg);
hr = INetConnectionUiUtilities_DisplayAddComponentDialog(
pInfo->pNetConUtilities, pInfo->hwndDlg,
pInfo->pNetCfg, &cfi);
// If the user didn't cancel, refresh the list view.
//
if (S_FALSE != hr)
{
if (SUCCEEDED(hr))
{
// Change the Cancel Button to CLOSE (because we committed changes)
//
PropSheet_CancelToClose(pInfo->hwndDlg);
}
// commit binding changes made (Raid #297216)
NeSaveBindingChanges(pInfo);
HrNeRefreshListView (pInfo);
// Reset the state of the buttons as if something changed.
//
NeLvItemChanged (pInfo);
// If reboot is needed request approval for this from the user
//
if (NETCFG_S_REBOOT == hr)
{
NeRequestReboot (pInfo);
}
}
}
}
void
NeRemoveComponent (
IN PEINFO* pInfo)
{
NeEnsureNetshellLoaded (pInfo);
// If we have our pointer to the function used to bring up the remove
// component dialog (obtained above only once), call it.
//
if (pInfo->pNetConUtilities)
{
HRESULT hr;
INetCfgComponent* pComponent;
pComponent = PComponentFromCurSel (pInfo->hwndLvComponents, NULL);
ASSERT (pComponent);
ASSERT (pInfo->pNetCfg);
hr = INetConnectionUiUtilities_QueryUserAndRemoveComponent(
pInfo->pNetConUtilities, pInfo->hwndDlg,
pInfo->pNetCfg, pComponent);
// If the user didn't cancel, refresh the list view.
//
if (S_FALSE != hr)
{
if (SUCCEEDED(hr))
{
// Change the Cancel Button to CLOSE (because we committed changes)
//
PropSheet_CancelToClose(pInfo->hwndDlg);
}
NeSaveBindingChanges(pInfo);
HrNeRefreshListView(pInfo);
// Reset the state of the buttons as if something changed.
//
NeLvItemChanged (pInfo);
// If reboot is needed request approval for this from the user
//
if (NETCFG_S_REBOOT == hr)
{
NeRequestReboot (pInfo);
}
}
}
}
void
NeLvClick (
IN PEINFO* pInfo,
IN BOOL fDoubleClick)
{
//Add the IsWindowEnabled for whistler bug #204976
//Not to pop up the property dialog box if it is a router
//and the selected List View item is IPX
//
if (fDoubleClick && IsWindowEnabled(pInfo->hwndPbProperties))
{
INetCfgComponent* pComponent;
int iItem;
pComponent = PComponentFromCurSel (pInfo->hwndLvComponents, &iItem);
if (pComponent)
{
HRESULT hr;
if ( ListView_GetCheck (pInfo->hwndLvComponents, iItem))
{
// Check if the component has property UI
//
// 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);
}
// Check if the component has property UI
hr = INetCfgComponent_RaisePropertyUi ( pComponent,
pInfo->hwndDlg,
NCRP_QUERY_PROPERTY_UI,
pInfo->punkUiInfoCallback);
if (S_OK == hr)
{
NeEnsureNetshellLoaded (pInfo);
if ((NULL != pInfo->pNetConUtilities) &&
INetConnectionUiUtilities_UserHasPermission(
pInfo->pNetConUtilities,
NCPERM_RasChangeProperties))
{
NeShowComponentProperties (pInfo);
}
}
}
}
}
}
void
NeLvItemChanged (
IN PEINFO* pInfo)
{
LPWSTR pszwDescription = NULL;
BOOL fEnableRemove = FALSE;
BOOL fEnableProperties = FALSE;
INetCfgComponent* pComponent;
int iItem;
// Get the current selection if it exists.
//
pComponent = PComponentFromCurSel (pInfo->hwndLvComponents, &iItem);
if (pComponent)
{
NeEnsureNetshellLoaded (pInfo);
// Determine if removal is allowed
//
if (NULL != pInfo->pNetConUtilities)
{
DWORD dwFlags = 0;
HRESULT hr;
fEnableRemove = INetConnectionUiUtilities_UserHasPermission(
pInfo->pNetConUtilities,
NCPERM_AddRemoveComponents);
//Now disable the user ability to uninstall TCP stack
//for whistler bug 322846 gangz
//
hr = INetCfgComponent_GetCharacteristics(pComponent, &dwFlags );
if( SUCCEEDED(hr) && (NCF_NOT_USER_REMOVABLE & dwFlags) )
{
fEnableRemove = FALSE;
}
}
// See if the properties UI should be allowed. Only allow it for
// enabled items that have UI to display.
//
{
HRESULT hr = S_OK;
if (ListView_GetCheck (pInfo->hwndLvComponents, iItem))
{
// Check if the component has property UI
//
INetCfgComponent* pComponentTmp = PComponentFromCurSel (pInfo->hwndLvComponents, NULL);
ASSERT (pComponentTmp);
// 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);
}
if(pComponentTmp)
{
// Check if the component has property UI
hr = INetCfgComponent_RaisePropertyUi ( pComponentTmp,
pInfo->hwndDlg,
NCRP_QUERY_PROPERTY_UI,
pInfo->punkUiInfoCallback);
if ((S_OK == hr) && (NULL != pInfo->pNetConUtilities))
{
fEnableProperties = INetConnectionUiUtilities_UserHasPermission(
pInfo->pNetConUtilities,
NCPERM_RasChangeProperties);
}
}
}
}
// Bug #221837 (danielwe): Set member vars based on whether they
// are checked in the UI
//
{
PBENTRY * pEntry;
BOOL fIsChecked;
LPWSTR pszwId = NULL;
pEntry = pInfo->pArgs->pEntry;
fIsChecked = ListView_GetCheck(pInfo->hwndLvComponents, iItem);
if (SUCCEEDED(INetCfgComponent_GetId(pComponent, &pszwId)))
{
// For whistler 522872
//
if( CSTR_EQUAL == CompareStringW(
LOCALE_INVARIANT,
NORM_IGNORECASE,
NETCFG_CLIENT_CID_MS_MSClient,
-1,
pszwId,
-1
)
)
{
pEntry->fBindMsNetClient = fIsChecked;
}
else if( CSTR_EQUAL == CompareStringW(
LOCALE_INVARIANT,
NORM_IGNORECASE,
NETCFG_SERVICE_CID_MS_SERVER,
-1,
pszwId,
-1
)
)
{
pEntry->fShareMsFilePrint = fIsChecked;
}
// pmay 406630
//
// Disable the properties of all components but tcpip if we
// are running in non-admin mode
//
else if ( CSTR_EQUAL == CompareStringW(
LOCALE_INVARIANT,
NORM_IGNORECASE,
NETCFG_TRANS_CID_MS_TCPIP,
-1,
pszwId,
-1)
)
{
if (pInfo->fNonAdmin)
{
fEnableProperties = FALSE;
}
}
CoTaskMemFree(pszwId);
}
}
// Bug #348623 (pmay):
//
// Ipx is hardcoded to disable properties when remote admining
// a router.
//
if (pInfo->pArgs->fRouter ) //commented for bug #204976 //&& pInfo->pArgs->fRemote)
{
LPWSTR pszwId = NULL;
if (SUCCEEDED(INetCfgComponent_GetId(pComponent, &pszwId)))
{
if ( CSTR_EQUAL== CompareStringW(
LOCALE_INVARIANT,
NORM_IGNORECASE,
NETCFG_TRANS_CID_MS_NWIPX,
-1,
pszwId,
-1)
)
{
fEnableProperties = FALSE;
}
CoTaskMemFree(pszwId);
}
}
// Get the description text. Failure is okay here. It just means
// we'll display nothing.
//
INetCfgComponent_GetHelpText (pComponent, &pszwDescription);
}
// Update the UI with its new state.
//
if (!pInfo->fReadOnly)
{
EnableWindow (pInfo->hwndPbRemove, fEnableRemove);
EnableWindow (pInfo->hwndPbProperties, fEnableProperties);
}
if(NULL != pszwDescription)
{
SetWindowText (pInfo->hwndDescription, pszwDescription);
CoTaskMemFree (pszwDescription);
}
}
void
NeLvDeleteItem (
IN PEINFO* pInfo,
IN NM_LISTVIEW* pnmlv)
{
// Release our component object stored as the lParam of the list view
// item.
//
INetCfgComponent* pComponent;
pComponent = PComponentFromItemIndex (pInfo->hwndLvComponents,
pnmlv->iItem);
ReleaseObj (pComponent);
}
//----------------------------------------------------------------------------
// Networking property page PPP Settings dialog
//----------------------------------------------------------------------------
INT_PTR CALLBACK
PpDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
{
PEINFO* pInfo;
PBENTRY* pEntry;
switch (unMsg)
{
case WM_INITDIALOG:
{
pInfo = (PEINFO*)lparam;
ASSERT (pInfo);
pEntry = pInfo->pArgs->pEntry;
CheckDlgButton (hwnd, CID_NE_EnableLcp,
(pEntry->fLcpExtensions)
? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton (hwnd, CID_NE_EnableCompression,
(pEntry->fSwCompression)
? BST_CHECKED : BST_UNCHECKED);
//Cut Negotiate multi-link for whistler bug 385842
//
CheckDlgButton (hwnd, CID_NE_NegotiateMultilinkAlways,
(pEntry->fNegotiateMultilinkAlways)
? BST_CHECKED : BST_UNCHECKED);
SetWindowLongPtr (hwnd, DWLP_USER, (ULONG_PTR )lparam);
// Center dialog on the owner window.
//
CenterWindow(hwnd, GetParent(hwnd));
// Add context help button to title bar.
//
AddContextHelpButton(hwnd);
return TRUE;
}
case WM_HELP:
case WM_CONTEXTMENU:
{
ContextHelp( g_adwPpHelp, hwnd, unMsg, wparam, lparam );
break;
}
case WM_COMMAND:
{
if ((IDOK == LOWORD(wparam)) &&
(BN_CLICKED == HIWORD(wparam)))
{
pInfo = (PEINFO*)GetWindowLongPtr (hwnd, DWLP_USER);
ASSERT (pInfo);
pEntry = pInfo->pArgs->pEntry;
pEntry->fLcpExtensions = (BST_CHECKED ==
IsDlgButtonChecked (hwnd, CID_NE_EnableLcp));
pEntry->fSwCompression = (BST_CHECKED ==
IsDlgButtonChecked (hwnd, CID_NE_EnableCompression));
//Cut Negotiate multi-link for whistler bug 385842
//
pEntry->fNegotiateMultilinkAlways = (BST_CHECKED ==
IsDlgButtonChecked (hwnd, CID_NE_NegotiateMultilinkAlways));
/*
pEntry->fNegotiateMultilinkAlways = FALSE;
*/
EndDialog (hwnd, TRUE);
return TRUE;
}
else if ((IDCANCEL == LOWORD(wparam)) &&
(BN_CLICKED == HIWORD(wparam)))
{
EndDialog (hwnd, FALSE);
return TRUE;
}
break;
}
}
return FALSE;
}
INT_PTR CALLBACK
SaUnavailDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
// DialogProc callback for the Shared Access Unavailable page of the Entry property
// sheet.
// Parameters and return value are as described for standard windows
// 'DialogProc's.
//
{
#if 0
TRACE4( "SaUnavailDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
(DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
#endif
switch (unMsg)
{
case WM_INITDIALOG:
{
LPWSTR pszError;
PEINFO* pInfo = PeContext( hwnd );
ASSERT(pInfo);
if (pInfo == NULL)
{
break;
}
pszError = PszFromId(g_hinstDll, pInfo->pArgs->hShowHNetPagesResult == HRESULT_FROM_WIN32(ERROR_SERVICE_DISABLED) ? SID_SA_NoWMIError : SID_SA_StoreError);
if(NULL != pszError)
{
SetDlgItemText(hwnd, CID_SA_ST_ErrorText, pszError);
Free(pszError);
}
}
case WM_HELP:
case WM_CONTEXTMENU:
{
// ContextHelp( g_adwSaHelp, hwnd, unMsg, wparam, lparam );
break;
}
}
return FALSE;
}
//----------------------------------------------------------------------------
// Routing property page (PLACEHOLDER only)
// Listed alphabetically following dialog proc
//----------------------------------------------------------------------------
INT_PTR CALLBACK
RdDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
// DialogProc callback for the Routing page of the Entry property sheet.
// Parameters and return value are as described for standard windows
// 'DialogProc's.
//
{
return FALSE;
}
/*----------------------------------------------------------------------------
** (Router) Callback dialog
** Listed alphabetically following dialog proc
**----------------------------------------------------------------------------
*/
BOOL
RouterCallbackDlg(
IN HWND hwndOwner,
IN OUT EINFO* pEinfo )
/* Pops-up the (Router) Callback dialog. Initial settings are read from
** the working entry (no/yes choice) and router user preferences (number
** list) in common entry context 'pEinfo' and the result of user's edits
** written there on "OK" exit. 'HwndOwner' is the window owning the
** dialog.
**
** Returns true if user pressed OK and succeeded, false if he pressed
** Cancel or encountered an error.
*/
{
INT_PTR nStatus;
TRACE("RouterCallbackDlg");
nStatus =
DialogBoxParam(
g_hinstDll,
MAKEINTRESOURCE( DID_CR_CallbackRouter ),
hwndOwner,
CrDlgProc,
(LPARAM )pEinfo );
if (nStatus == -1)
{
ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
nStatus = FALSE;
}
return (nStatus) ? TRUE : FALSE;
}
INT_PTR CALLBACK
CrDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
/* DialogProc callback for the (Router) Callback dialog. Parameters and
** return value are as described for standard windows 'DialogProc's.
*/
{
#if 0
TRACE4("CrDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
(DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
#endif
if (ListView_OwnerHandler(
hwnd, unMsg, wparam, lparam, CbutilLvNumbersCallback ))
{
return TRUE;
}
switch (unMsg)
{
case WM_INITDIALOG:
return CrInit( hwnd, (EINFO* )lparam );
case WM_HELP:
case WM_CONTEXTMENU:
ContextHelp( g_adwCrHelp, hwnd, unMsg, wparam, lparam );
break;
case WM_NOTIFY:
{
switch (((NMHDR* )lparam)->code)
{
case NM_DBLCLK:
{
CRINFO* pInfo = (CRINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
ASSERT(pInfo);
SendMessage( pInfo->hwndPbEdit, BM_CLICK, 0, 0 );
return TRUE;
}
case LVN_ITEMCHANGED:
{
CRINFO* pInfo = (CRINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
ASSERT(pInfo);
CrUpdateLvAndPbState( pInfo );
return TRUE;
}
}
break;
}
case WM_COMMAND:
{
CRINFO* pInfo = (CRINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
ASSERT(pInfo);
return CrCommand(
pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
}
case WM_DESTROY:
{
CrTerm( hwnd );
break;
}
}
return FALSE;
}
BOOL
CrCommand(
IN CRINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl )
/* Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
** is the notification code of the command. 'wId' is the control/menu
** identifier of the command. 'HwndCtrl' is the control window handle of
** the command.
**
** Returns true if processed message, false otherwise.
*/
{
TRACE3("CrCommand(n=%d,i=%d,c=$%x)",
(DWORD)wNotification,(DWORD)wId,(ULONG_PTR )hwndCtrl);
switch (wId)
{
case CID_CR_RB_No:
case CID_CR_RB_Yes:
{
if (wNotification == BN_CLICKED)
{
CrUpdateLvAndPbState( pInfo );
if (wId == CID_CR_RB_Yes
&& ListView_GetSelectedCount( pInfo->hwndLvNumbers ) == 0)
{
/* Nothing's selected, so select the first item, if any.
*/
ListView_SetItemState( pInfo->hwndLvNumbers, 0,
LVIS_SELECTED, LVIS_SELECTED );
}
}
break;
}
case CID_CR_PB_Edit:
{
if (wNotification == BN_CLICKED)
CbutilEdit( pInfo->hwndDlg, pInfo->hwndLvNumbers );
break;
}
case CID_CR_PB_Delete:
{
if (wNotification == BN_CLICKED)
CbutilDelete( pInfo->hwndDlg, pInfo->hwndLvNumbers );
break;
}
case IDOK:
{
TRACE("OK pressed");
CrSave( pInfo );
EndDialog( pInfo->hwndDlg, TRUE );
return TRUE;
}
case IDCANCEL:
{
TRACE("Cancel pressed");
EndDialog( pInfo->hwndDlg, FALSE );
return TRUE;
}
}
return FALSE;
}
BOOL
CrInit(
IN HWND hwndDlg,
IN EINFO* pArgs )
/* Called on WM_INITDIALOG. 'hwndDlg' is the handle of the phonebook
** dialog window. 'pArgs' is caller's argument to the stub API.
**
** Return false if focus was set, true otherwise, i.e. as defined for
** WM_INITDIALOG.
*/
{
DWORD dwErr;
CRINFO* pInfo;
TRACE("CrInit");
/* Allocate the dialog context block. Initialize minimally for proper
** cleanup, then attach to the dialog window.
*/
{
pInfo = Malloc( sizeof(*pInfo) );
if (!pInfo)
{
ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
EndDialog( hwndDlg, FALSE );
return TRUE;
}
ZeroMemory( pInfo, sizeof(*pInfo) );
pInfo->pArgs = pArgs;
pInfo->hwndDlg = hwndDlg;
SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
TRACE("Context set");
}
/* Initialize page-specific context information.
*/
pInfo->hwndRbNo = GetDlgItem( hwndDlg, CID_CR_RB_No );
ASSERT(pInfo->hwndRbNo);
pInfo->hwndRbYes = GetDlgItem( hwndDlg, CID_CR_RB_Yes );
ASSERT(pInfo->hwndRbYes);
pInfo->hwndLvNumbers = GetDlgItem( hwndDlg, CID_CR_LV_Numbers );
ASSERT(pInfo->hwndLvNumbers);
pInfo->hwndPbEdit = GetDlgItem( hwndDlg, CID_CR_PB_Edit );
ASSERT(pInfo->hwndPbEdit);
pInfo->hwndPbDelete = GetDlgItem( hwndDlg, CID_CR_PB_Delete );
ASSERT(pInfo->hwndPbDelete);
/* Initialize the listview.
*/
CbutilFillLvNumbers(
pInfo->hwndDlg, pInfo->hwndLvNumbers,
pArgs->pUser->pdtllistCallback, pArgs->fRouter );
/* Set the radio button selection, which triggers appropriate
** enabling/disabling.
*/
{
HWND hwndRb;
if (pArgs->pEntry->dwCallbackMode == CBM_No)
hwndRb = pInfo->hwndRbNo;
else
{
ASSERT(pArgs->pEntry->dwCallbackMode==CBM_Yes);
hwndRb = pInfo->hwndRbYes;
}
SendMessage( hwndRb, BM_CLICK, 0, 0 );
}
/* Center dialog on the owner window.
*/
CenterWindow( hwndDlg, GetParent( hwndDlg ) );
// Add context help button to title bar.
//
AddContextHelpButton( hwndDlg );
return TRUE;
}
VOID
CrSave(
IN CRINFO* pInfo )
/* Saves dialog settings in the entry. 'PInfo' is the dialog context.
*/
{
PBENTRY* pEntry;
TRACE("CrSave");
pEntry = pInfo->pArgs->pEntry;
ASSERT(pEntry);
if (IsDlgButtonChecked( pInfo->hwndDlg, CID_CR_RB_No ))
pEntry->dwCallbackMode = CBM_No;
else
pEntry->dwCallbackMode = CBM_Yes;
pEntry->dwfOverridePref |= RASOR_CallbackMode;
pEntry->fDirty = TRUE;
pInfo->pArgs->pUser->fDirty = TRUE;
CbutilSaveLv(
pInfo->hwndLvNumbers, pInfo->pArgs->pUser->pdtllistCallback );
}
VOID
CrTerm(
IN HWND hwndDlg )
/* Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
*/
{
CRINFO* pInfo = (CRINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
TRACE("CrTerm");
// pmay: 213060
//
// Cleanup the numbers
//
if ( pInfo->hwndLvNumbers )
{
CbutilLvNumbersCleanup( pInfo->hwndLvNumbers );
}
if (pInfo)
{
Free( pInfo );
}
}
VOID
CrUpdateLvAndPbState(
IN CRINFO* pInfo )
/* Enables/disables the list view and associated buttons. ListView is
** gray unless auto-callback is selected. Buttons gray unless
** auto-callback selected and there is an item selected.
*/
{
BOOL fEnableList;
BOOL fEnableButton;
fEnableList = Button_GetCheck( pInfo->hwndRbYes );
if (fEnableList)
{
fEnableButton =
ListView_GetSelectedCount( pInfo->hwndLvNumbers );
}
else
fEnableButton = FALSE;
EnableWindow( pInfo->hwndLvNumbers, fEnableList );
EnableWindow( pInfo->hwndPbEdit, fEnableButton );
EnableWindow( pInfo->hwndPbDelete, fEnableButton );
}
INT_PTR CALLBACK
SaDisableFirewallWarningDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
{
switch(unMsg)
{
case WM_COMMAND:
{
switch(LOWORD(wparam))
{
case IDYES:
case IDNO:
if(BST_CHECKED == IsDlgButtonChecked(hwnd, CID_SA_PB_DisableFirewallWarning))
{
HKEY hFirewallKey;
if(ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, g_pszFirewallRegKey, 0, NULL, 0, KEY_SET_VALUE, NULL, &hFirewallKey, NULL))
{
DWORD dwValue = TRUE;
RegSetValueEx(hFirewallKey, g_pszDisableFirewallWarningValue, 0, REG_DWORD, (CONST BYTE*)&dwValue, sizeof(dwValue));
RegCloseKey(hFirewallKey);
}
}
// fallthru
case IDCANCEL:
EndDialog(hwnd, LOWORD(wparam));
break;
}
break;
}
}
return FALSE;
}
BOOL SaIsAdapterDHCPEnabled(IHNetConnection* pConnection)
{
HRESULT hr;
BOOL fDHCP = FALSE;
GUID* pAdapterGuid;
hr = IHNetConnection_GetGuid(pConnection, &pAdapterGuid);
if(SUCCEEDED(hr))
{
LPOLESTR pAdapterName;
hr = StringFromCLSID(pAdapterGuid, &pAdapterName);
if(SUCCEEDED(hr))
{
SIZE_T Length = wcslen(pAdapterName);
LPSTR pszAnsiAdapterName = Malloc(Length + 1);
if(NULL != pszAnsiAdapterName)
{
if(0 != WideCharToMultiByte(CP_ACP, 0, pAdapterName, (int)(Length + 1), pszAnsiAdapterName, (int)(Length + 1), NULL, NULL))
{
HMODULE hIpHelper;
hIpHelper = LoadLibrary(L"iphlpapi");
if(NULL != hIpHelper)
{
DWORD (WINAPI *pGetAdaptersInfo)(PIP_ADAPTER_INFO, PULONG);
pGetAdaptersInfo = (DWORD (WINAPI*)(PIP_ADAPTER_INFO, PULONG)) GetProcAddress(hIpHelper, "GetAdaptersInfo");
if(NULL != pGetAdaptersInfo)
{
ULONG ulSize = 0;
if(ERROR_BUFFER_OVERFLOW == pGetAdaptersInfo(NULL, &ulSize))
{
PIP_ADAPTER_INFO pInfo = Malloc(ulSize);
if(NULL != pInfo)
{
if(ERROR_SUCCESS == pGetAdaptersInfo(pInfo, &ulSize))
{
PIP_ADAPTER_INFO pAdapterInfo = pInfo;
do
{
if(0 == lstrcmpA(pszAnsiAdapterName, pAdapterInfo->AdapterName))
{
fDHCP = !!pAdapterInfo->DhcpEnabled;
break;
}
} while(NULL != (pAdapterInfo = pAdapterInfo->Next));
}
Free(pInfo);
}
}
}
FreeLibrary(hIpHelper);
}
}
Free(pszAnsiAdapterName);
}
CoTaskMemFree(pAdapterName);
}
CoTaskMemFree(pAdapterGuid);
}
return fDHCP;
}