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.
1807 lines
45 KiB
1807 lines
45 KiB
// Copyright (c) 1995, Microsoft Corporation, all rights reserved
|
|
//
|
|
// util.c
|
|
// Remote Access Common Dialog APIs
|
|
// Utility routines
|
|
// Listed alphabetically
|
|
//
|
|
// Steve Cobb 06/20/95
|
|
|
|
|
|
#include "rasdlgp.h" // Our private header
|
|
#include <dlgs.h> // Common dialog resource constants
|
|
#include <lmwksta.h> // NetWkstaGetInfo
|
|
#include <lmapibuf.h> // NetApiBufferFree
|
|
#include <dsrole.h> // machine is a member of a workgroup or domain, etc.
|
|
#include <tchar.h>
|
|
|
|
typedef struct _COUNT_FREE_COM_PORTS_DATA
|
|
{
|
|
DTLLIST* pListPortsInUse;
|
|
DWORD dwCount;
|
|
} COUNT_FREE_COM_PORTS_DATA;
|
|
|
|
const WCHAR c_szCurrentBuildNumber[] = L"CurrentBuildNumber";
|
|
const WCHAR c_szWinVersionPath[] =
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
|
|
const WCHAR c_szNt40BuildNumber[] = L"1381";
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Help maps
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static DWORD g_adwPnHelp[] =
|
|
{
|
|
CID_LE_ST_Item, HID_PN_EB_NewNumber,
|
|
CID_LE_EB_Item, HID_PN_EB_NewNumber,
|
|
CID_LE_PB_Add, HID_PN_PB_Add,
|
|
CID_LE_PB_Replace, HID_PN_PB_Replace,
|
|
CID_LE_ST_List, HID_PN_LB_List,
|
|
CID_LE_LB_List, HID_PN_LB_List,
|
|
CID_LE_PB_Up, HID_PN_PB_Up,
|
|
CID_LE_PB_Down, HID_PN_PB_Down,
|
|
CID_LE_PB_Delete, HID_PN_PB_Delete,
|
|
CID_LE_CB_Promote, HID_PN_CB_Promote,
|
|
0, 0
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Local helper prototypes (alphabetically)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
CountFreeComPorts(
|
|
IN PWCHAR pszPort,
|
|
IN HANDLE hData);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Utility routines (alphabetically)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
AllLinksAreModems(
|
|
IN PBENTRY* pEntry )
|
|
|
|
// Returns true if all links associated with the entry are modem links
|
|
// (MXS or Unimodem), false otherwise.
|
|
//
|
|
{
|
|
DTLNODE* pNode;
|
|
|
|
if (pEntry->pdtllistLinks)
|
|
{
|
|
for (pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
|
|
pNode;
|
|
pNode = DtlGetNextNode( pNode ))
|
|
{
|
|
PBLINK* pLink = (PBLINK* )DtlGetData( pNode );
|
|
|
|
if (pLink->pbport.pbdevicetype != PBDT_Modem)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
AllowDccWizard(
|
|
IN HANDLE hConnection)
|
|
|
|
// Finds out if there are any dcc devices installed on the local
|
|
// machine or if there are any available com ports. If neither
|
|
// condition is satisfied, then we return FALSE, otherwise TRUE.
|
|
{
|
|
DWORD dwErr, dwUsedCount = 0;
|
|
COUNT_FREE_COM_PORTS_DATA CountFreeComPortsData,
|
|
*pCfcpd = &CountFreeComPortsData;
|
|
DTLNODE* pNodeP, *pNodeL, *pNode;
|
|
BOOL bRet = FALSE;
|
|
|
|
// Initialize
|
|
ZeroMemory(pCfcpd, sizeof(COUNT_FREE_COM_PORTS_DATA));
|
|
|
|
do
|
|
{
|
|
// Load ras if it wasn't already loaded
|
|
dwErr = LoadRas( g_hinstDll, NULL );
|
|
if (dwErr != 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Load in all of the ports and count the number of
|
|
// dcc devices
|
|
dwErr = LoadPortsList2(
|
|
hConnection,
|
|
&(pCfcpd->pListPortsInUse),
|
|
FALSE);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
bRet = FALSE;
|
|
break;
|
|
}
|
|
|
|
// Count the dcc devices
|
|
for (pNodeL = DtlGetFirstNode( pCfcpd->pListPortsInUse );
|
|
pNodeL;
|
|
pNodeL = DtlGetNextNode( pNodeL ))
|
|
{
|
|
PBLINK* pLink = (PBLINK* )DtlGetData( pNodeL );
|
|
if (pLink->pbport.dwType == RASET_Direct)
|
|
{
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (bRet == TRUE)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// pmay: 249346
|
|
//
|
|
// Only merge the com ports if the user is an admin since
|
|
// admin privilege is required to install a null modem.
|
|
//
|
|
if (FIsUserAdminOrPowerUser())
|
|
{
|
|
// Count the number of available com ports
|
|
dwErr = MdmEnumComPorts (
|
|
CountFreeComPorts,
|
|
(HANDLE)pCfcpd);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
bRet = FALSE;
|
|
break;
|
|
}
|
|
|
|
bRet = (pCfcpd->dwCount > 0) ? TRUE : FALSE;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
// Cleanup
|
|
{
|
|
if ( pCfcpd->pListPortsInUse )
|
|
{
|
|
DtlDestroyList(pCfcpd->pListPortsInUse, DestroyPortNode);
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
DWORD
|
|
AuthRestrictionsFromTypicalAuth(
|
|
IN DWORD dwTypicalAuth )
|
|
|
|
// Return the AR_F_* flag corresponding to the TA_* value 'dwTypicalAuth',
|
|
// i.e. convert a typical authentication selection to a bitmask of
|
|
// authentication protocols.
|
|
//
|
|
{
|
|
if (dwTypicalAuth == TA_Secure)
|
|
{
|
|
return AR_F_TypicalSecure;
|
|
}
|
|
else if (dwTypicalAuth == TA_CardOrCert)
|
|
{
|
|
return AR_F_TypicalCardOrCert;
|
|
}
|
|
else
|
|
{
|
|
return AR_F_TypicalUnsecure;
|
|
}
|
|
}
|
|
|
|
LONG GetGlobalCallbackActive( )
|
|
{
|
|
LONG ret = 0;
|
|
|
|
__try
|
|
{
|
|
EnterCriticalSection( &g_csCallBacks );
|
|
|
|
ret = g_ulCallbacksActive;
|
|
TRACE1("GlobalActive Calls are:%ld",g_ulCallbacksActive);
|
|
}
|
|
__finally
|
|
{
|
|
LeaveCriticalSection( &g_csCallBacks );
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
LONG IncGlobalCallbackActive( )
|
|
{
|
|
LONG ret = 0;
|
|
|
|
__try
|
|
{
|
|
EnterCriticalSection( &g_csCallBacks );
|
|
|
|
g_ulCallbacksActive++;
|
|
|
|
ret = g_ulCallbacksActive;
|
|
TRACE1("GlobalActive Calls are:%ld",g_ulCallbacksActive);
|
|
}
|
|
__finally
|
|
{
|
|
LeaveCriticalSection( &g_csCallBacks );
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
LONG DecGlobalCallbackActive( )
|
|
{
|
|
LONG ret = 0;
|
|
|
|
__try
|
|
{
|
|
EnterCriticalSection( &g_csCallBacks );
|
|
|
|
if( 0 < g_ulCallbacksActive )
|
|
{
|
|
g_ulCallbacksActive -- ;
|
|
}
|
|
|
|
ret = g_ulCallbacksActive;
|
|
|
|
TRACE1("GlobalActive Calls are:%ld", g_ulCallbacksActive);
|
|
}
|
|
__finally
|
|
{
|
|
LeaveCriticalSection( &g_csCallBacks );
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
ULONG
|
|
CallbacksActive(
|
|
INT nSetTerminateAsap,
|
|
BOOL* pfTerminateAsap )
|
|
|
|
// If 'fSetTerminateAsap' >= 0, sets 'g_fTerminateAsap' flag to 'nSetTerminateAsap'.
|
|
// If non-NULL, caller's '*pfTerminateAsap' is filled with the current value of
|
|
// 'g_fTerminateAsap'.
|
|
//
|
|
// Returns the number of Rasdial callback threads active.
|
|
//
|
|
{
|
|
ULONG ul;
|
|
|
|
TRACE1( "CallbacksActive(%d)", nSetTerminateAsap );
|
|
|
|
ul = 0;
|
|
|
|
//For XPSP2 511810 and .Net 668164
|
|
//
|
|
__try
|
|
{
|
|
EnterCriticalSection( &g_csCallBacks );
|
|
|
|
if (pfTerminateAsap)
|
|
{
|
|
*pfTerminateAsap = g_fTerminateAsap;
|
|
}
|
|
|
|
if (nSetTerminateAsap >= 0)
|
|
{
|
|
g_fTerminateAsap = (BOOL )nSetTerminateAsap;
|
|
}
|
|
|
|
ul = g_ulCallbacksActive;
|
|
|
|
}
|
|
__finally
|
|
|
|
{
|
|
LeaveCriticalSection( &g_csCallBacks );
|
|
}
|
|
|
|
|
|
TRACE1( "CallbacksActive=%d", ul );
|
|
|
|
return ul;
|
|
}
|
|
|
|
|
|
VOID
|
|
ContextHelp(
|
|
IN const DWORD* padwMap,
|
|
IN HWND hwndDlg,
|
|
IN UINT unMsg,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam)
|
|
{
|
|
ContextHelpX( padwMap, hwndDlg, unMsg, wparam, lparam, FALSE );
|
|
}
|
|
|
|
|
|
VOID
|
|
ContextHelpX(
|
|
IN const DWORD* padwMap,
|
|
IN HWND hwndDlg,
|
|
IN UINT unMsg,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam,
|
|
IN BOOL fRouter)
|
|
|
|
// Calls WinHelp to popup context sensitive help. 'PadwMap' is an array
|
|
// of control-ID help-ID pairs terminated with a 0,0 pair. 'UnMsg' is
|
|
// WM_HELP or WM_CONTEXTMENU indicating the message received requesting
|
|
// help. 'Wparam' and 'lparam' are the parameters of the message received
|
|
// requesting help.
|
|
//
|
|
{
|
|
HWND hwnd;
|
|
UINT unType;
|
|
TCHAR* pszHelpFile;
|
|
|
|
ASSERT( unMsg==WM_HELP || unMsg==WM_CONTEXTMENU );
|
|
|
|
// Don't try to do help if it won't work. See common\uiutil\ui.c.
|
|
//
|
|
{
|
|
extern BOOL g_fNoWinHelp;
|
|
if (g_fNoWinHelp)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (unMsg == WM_HELP)
|
|
{
|
|
LPHELPINFO p = (LPHELPINFO )lparam;
|
|
|
|
TRACE3( "ContextHelp(WM_HELP,t=%d,id=%d,h=$%08x)",
|
|
p->iContextType, p->iCtrlId,p->hItemHandle );
|
|
|
|
if (p->iContextType != HELPINFO_WINDOW)
|
|
{
|
|
return;
|
|
}
|
|
|
|
hwnd = p->hItemHandle;
|
|
ASSERT( hwnd );
|
|
unType = HELP_WM_HELP;
|
|
}
|
|
else
|
|
{
|
|
// Standard Win95 method that produces a one-item "What's This?" menu
|
|
// that user must click to get help.
|
|
//
|
|
TRACE1( "ContextHelp(WM_CONTEXTMENU,h=$%08x)", wparam );
|
|
|
|
hwnd = (HWND )wparam;
|
|
unType = HELP_CONTEXTMENU;
|
|
};
|
|
|
|
if (fRouter)
|
|
{
|
|
pszHelpFile = g_pszRouterHelpFile;
|
|
}
|
|
else
|
|
{
|
|
pszHelpFile = g_pszHelpFile;
|
|
}
|
|
|
|
TRACE1( "WinHelp(%s)", pszHelpFile );
|
|
WinHelp( hwnd, pszHelpFile, unType, (ULONG_PTR ) padwMap );
|
|
}
|
|
|
|
|
|
VOID
|
|
CopyLinkPhoneNumberInfo(
|
|
OUT DTLNODE* pDstLinkNode,
|
|
IN DTLNODE* pSrcLinkNode )
|
|
|
|
// Copies the source link's phone number information to the destination
|
|
// link. Any existing destination information is properly destroyed. The
|
|
// arguments are DTLNODEs containing PBLINKs.
|
|
//
|
|
{
|
|
PBLINK* pSrcLink;
|
|
PBLINK* pDstLink;
|
|
DTLLIST* pDstList;
|
|
|
|
pSrcLink = (PBLINK* )DtlGetData( pSrcLinkNode );
|
|
pDstLink = (PBLINK* )DtlGetData( pDstLinkNode );
|
|
|
|
pDstList =
|
|
DtlDuplicateList(
|
|
pSrcLink->pdtllistPhones, DuplicatePhoneNode, DestroyPhoneNode );
|
|
|
|
if (pDstList)
|
|
{
|
|
DtlDestroyList( pDstLink->pdtllistPhones, DestroyPhoneNode );
|
|
pDstLink->pdtllistPhones = pDstList;
|
|
|
|
pDstLink->fPromoteAlternates = pSrcLink->fPromoteAlternates;
|
|
pDstLink->fTryNextAlternateOnFail = pSrcLink->fTryNextAlternateOnFail;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
CopyPszListToPhoneList(
|
|
IN OUT PBLINK* pLink,
|
|
IN DTLLIST* pListPhoneNumbers )
|
|
|
|
// Converts the phone number list of 'pLink' to be list created using the
|
|
// the list of Psz phone numbers 'pListPhoneNumbers' for phone numbers.
|
|
//
|
|
{
|
|
DTLNODE* pNodeP;
|
|
DTLNODE* pNodeZ;
|
|
|
|
// Empty the existing list of PBPHONE nodes.
|
|
//
|
|
while (pNodeP = DtlGetFirstNode( pLink->pdtllistPhones ))
|
|
{
|
|
DtlRemoveNode( pLink->pdtllistPhones, pNodeP );
|
|
DestroyPhoneNode( pNodeP );
|
|
}
|
|
|
|
// Recreate the list of PBPHONE nodes from the list of PSZ nodes.
|
|
//
|
|
for (pNodeZ = DtlGetFirstNode( pListPhoneNumbers );
|
|
pNodeZ;
|
|
pNodeZ = DtlGetNextNode( pNodeZ ))
|
|
{
|
|
PBPHONE* pPhone;
|
|
|
|
pNodeP = CreatePhoneNode();
|
|
if (!pNodeP)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
pPhone = (PBPHONE* )DtlGetData( pNodeP );
|
|
ASSERT( pPhone );
|
|
|
|
Free0( pPhone->pszPhoneNumber );
|
|
pPhone->pszPhoneNumber =
|
|
StrDup( (TCHAR* )DtlGetData( pNodeZ ) );
|
|
|
|
DtlAddNodeLast( pLink->pdtllistPhones, pNodeP );
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
CountFreeComPorts(
|
|
IN PWCHAR pszPort,
|
|
IN HANDLE hData)
|
|
|
|
// Com port enumeration function that counts the list of
|
|
// free com ports. Returns TRUE to stop enumeration (see
|
|
// MdmEnumComPorts)
|
|
{
|
|
COUNT_FREE_COM_PORTS_DATA* pfcpData = (COUNT_FREE_COM_PORTS_DATA*)hData;
|
|
DTLLIST* pListUsed = pfcpData->pListPortsInUse;
|
|
DTLNODE* pNodeP, *pNodeL, *pNode;
|
|
|
|
// If the given port is in the used list, then return
|
|
// so that it is not added to the list of free ports and
|
|
// so that enumeration continues.
|
|
for (pNodeL = DtlGetFirstNode( pListUsed );
|
|
pNodeL;
|
|
pNodeL = DtlGetNextNode( pNodeL ))
|
|
{
|
|
PBLINK* pLink = (PBLINK* )DtlGetData( pNodeL );
|
|
ASSERT( pLink->pbport.pszPort );
|
|
|
|
// The port already appears in a link in the list.
|
|
if (lstrcmp( pLink->pbport.pszPort, pszPort ) == 0)
|
|
return FALSE;
|
|
}
|
|
|
|
// The port is not in use. Increment the count.
|
|
pfcpData->dwCount += 1;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
HWND
|
|
CreateWizardBitmap(
|
|
IN HWND hwndDlg,
|
|
IN BOOL fPage )
|
|
|
|
// Create a static control that displays the RAS wizard bitmap at the
|
|
// standard place on dialog 'hwndDlg'. 'FPage' is set if the bitmap is
|
|
// being placed on a property page, false for the equivalent placement on
|
|
// a dialog.
|
|
//
|
|
// Returns the bitmap window handle or NULL or error.
|
|
//
|
|
{
|
|
HWND hwnd;
|
|
INT x;
|
|
INT y;
|
|
|
|
if (fPage)
|
|
{
|
|
x = y = 0;
|
|
}
|
|
else
|
|
{
|
|
x = y = 10;
|
|
}
|
|
|
|
hwnd =
|
|
CreateWindowEx(
|
|
0,
|
|
TEXT("static"),
|
|
NULL,
|
|
WS_VISIBLE | WS_CHILD | SS_SUNKEN | SS_BITMAP,
|
|
x, y, 80, 140,
|
|
hwndDlg,
|
|
(HMENU )CID_BM_Wizard,
|
|
g_hinstDll,
|
|
NULL );
|
|
|
|
if (hwnd)
|
|
{
|
|
if (!g_hbmWizard)
|
|
{
|
|
g_hbmWizard = LoadBitmap(
|
|
g_hinstDll, MAKEINTRESOURCE( BID_Wizard ) );
|
|
}
|
|
|
|
SendMessage( hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM )g_hbmWizard );
|
|
}
|
|
|
|
return hwnd;
|
|
}
|
|
|
|
TCHAR*
|
|
DisplayPszFromDeviceAndPort(
|
|
IN TCHAR* pszDevice,
|
|
IN TCHAR* pszPort )
|
|
|
|
// Returns address of heap block psz containing the MXS modem list display
|
|
// form, i.e. the device name 'pszDevice' followed by the port name
|
|
// 'pszPort'. It's caller's responsibility to Free the returned string.
|
|
//
|
|
{
|
|
TCHAR* pszResult;
|
|
TCHAR* pszD;
|
|
|
|
if (pszDevice)
|
|
{
|
|
pszD = NULL;
|
|
}
|
|
else
|
|
{
|
|
pszD = pszDevice = PszFromId( g_hinstDll, SID_UnknownDevice );
|
|
}
|
|
|
|
pszResult = PszFromDeviceAndPort( pszDevice, pszPort );
|
|
Free0( pszD );
|
|
|
|
return pszResult;
|
|
}
|
|
|
|
|
|
TCHAR*
|
|
DisplayPszFromPpbport(
|
|
IN PBPORT* pPort,
|
|
OUT DWORD* pdwDeviceIcon )
|
|
|
|
// Returns address of heap block psz containing the device display form of
|
|
// the 'pPort', e.g. "Modem - KTel 28.8 Fax Plus" It's caller's
|
|
// responsibility to Free the returned string. If non-NULL,
|
|
// '*pdwDeviceIcon' is set to the DI_* device icon code corresponding to
|
|
// the device. DI_* codes are used with the RAS ListView extensions to
|
|
// show the correct item icon.
|
|
//
|
|
{
|
|
TCHAR* pszFormat;
|
|
TCHAR* pszD;
|
|
TCHAR* pszDT;
|
|
TCHAR* pszDevice;
|
|
TCHAR* pszDeviceType;
|
|
TCHAR* pszResult;
|
|
DWORD dwDeviceIcon;
|
|
LPCTSTR pszChannel = NULL;
|
|
|
|
// These are set if a resource string is read that must be Freed later.
|
|
//
|
|
pszDT = NULL;
|
|
pszD = NULL;
|
|
|
|
if (pPort->pszDevice)
|
|
{
|
|
pszDevice = pPort->pszDevice;
|
|
}
|
|
else
|
|
{
|
|
pszDevice = PszFromId( g_hinstDll, SID_UnknownDevice );
|
|
|
|
if(NULL == pszDevice)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pszD = pszDevice;
|
|
}
|
|
|
|
// Set default format and device icon, though they may be changed below.
|
|
//
|
|
pszFormat = TEXT("%s - %s (%s)");
|
|
dwDeviceIcon = DI_Adapter;
|
|
|
|
if (pPort->pbdevicetype == PBDT_Modem
|
|
&& !(pPort->dwFlags & PBP_F_NullModem))
|
|
{
|
|
pszDeviceType = PszFromId( g_hinstDll, SID_Modem );
|
|
pszDT = pszDeviceType;
|
|
dwDeviceIcon = DI_Modem;
|
|
}
|
|
else if (pPort->pbdevicetype == PBDT_Isdn)
|
|
{
|
|
pszDeviceType = PszFromId( g_hinstDll, SID_Isdn );
|
|
pszDT = pszDeviceType;
|
|
pszFormat = TEXT("%s %s - %s");
|
|
}
|
|
else if (pPort->pbdevicetype == PBDT_X25)
|
|
{
|
|
pszDeviceType = PszFromId( g_hinstDll, SID_X25 );
|
|
pszDT = pszDeviceType;
|
|
}
|
|
else if (pPort->pbdevicetype == PBDT_Pad)
|
|
{
|
|
pszDeviceType = PszFromId( g_hinstDll, SID_X25Pad );
|
|
pszDT = pszDeviceType;
|
|
}
|
|
else
|
|
{
|
|
// Don't know the device type, so just bag the device descriptive word
|
|
// and let the device name stand alone.
|
|
//
|
|
pszDeviceType = TEXT("");
|
|
pszFormat = TEXT("%s%s (%s)");
|
|
}
|
|
|
|
if(NULL == pszDeviceType)
|
|
{
|
|
pszDeviceType = TEXT("");
|
|
}
|
|
|
|
if(pPort->pbdevicetype != PBDT_Isdn)
|
|
{
|
|
pszResult = Malloc(
|
|
(lstrlen( pszFormat ) + lstrlen( pszDeviceType ) + lstrlen( pszDevice ) + lstrlen( pPort->pszPort ))
|
|
* sizeof(TCHAR) );
|
|
}
|
|
else
|
|
{
|
|
|
|
pszChannel = PszLoadString( g_hinstDll, SID_Channel );
|
|
|
|
if(NULL == pszChannel)
|
|
{
|
|
pszChannel = TEXT("");
|
|
}
|
|
|
|
// For isdn use the following format
|
|
// "Isdn channel - <DeviceName>
|
|
// Talk to steve falcon about this if you have issues
|
|
// with special casing isdn.
|
|
//
|
|
pszResult = Malloc(
|
|
(lstrlen( pszFormat ) + lstrlen( pszDeviceType ) + lstrlen(pszChannel) + lstrlen( pszDevice ))
|
|
* sizeof(TCHAR));
|
|
}
|
|
|
|
|
|
if (pszResult)
|
|
{
|
|
if(pPort->pbdevicetype != PBDT_Isdn)
|
|
{
|
|
wsprintf( pszResult, pszFormat, pszDeviceType, pszDevice, pPort->pszPort);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(NULL != pszChannel);
|
|
wsprintf( pszResult, pszFormat, pszDeviceType, pszChannel, pszDevice);
|
|
}
|
|
}
|
|
|
|
if (pdwDeviceIcon)
|
|
{
|
|
#if 1
|
|
// Per SteveFal. Wants "modem" icon for all if Device-Manager-style
|
|
// physically descriptive icons cannot be used.
|
|
//
|
|
dwDeviceIcon = DI_Modem;
|
|
#endif
|
|
*pdwDeviceIcon = dwDeviceIcon;
|
|
}
|
|
|
|
Free0( pszD );
|
|
Free0( pszDT );
|
|
|
|
return pszResult;
|
|
}
|
|
|
|
|
|
VOID
|
|
EnableCbWithRestore(
|
|
IN HWND hwndCb,
|
|
IN BOOL fEnable,
|
|
IN BOOL fDisabledCheck,
|
|
IN OUT BOOL* pfRestore )
|
|
|
|
// Enable/disable the checkbox 'hwndCb' based on the 'fEnable' flag
|
|
// including stashing and restoring a cached value '*pfRestore' when
|
|
// disabled. When disabling, the check value is set to 'fDisabledCheck'.
|
|
//
|
|
{
|
|
if (fEnable)
|
|
{
|
|
if (!IsWindowEnabled( hwndCb ))
|
|
{
|
|
// Toggling to enabled. Restore the stashed check value.
|
|
//
|
|
Button_SetCheck( hwndCb, *pfRestore );
|
|
EnableWindow( hwndCb, TRUE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (IsWindowEnabled( hwndCb ))
|
|
{
|
|
// Toggling to disabled. Stashed the current check value.
|
|
//
|
|
*pfRestore = Button_GetCheck( hwndCb );
|
|
Button_SetCheck( hwndCb, fDisabledCheck );
|
|
EnableWindow( hwndCb, FALSE );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
EnableLbWithRestore(
|
|
IN HWND hwndLb,
|
|
IN BOOL fEnable,
|
|
IN OUT INT* piRestore )
|
|
|
|
// Enable/disable the combobox 'hwndLb' based on the 'fEnable' flag. If
|
|
// disabling, '*piRestore' is loaded with the stashed selection index and
|
|
// a blank item is added to the front of the list and selected. This is
|
|
// undone if enabling.
|
|
//
|
|
{
|
|
if (fEnable)
|
|
{
|
|
if (!IsWindowEnabled( hwndLb ))
|
|
{
|
|
// Toggling to enabled. Restore the stashed selection.
|
|
//
|
|
ComboBox_DeleteString( hwndLb, 0 );
|
|
ComboBox_SetCurSelNotify( hwndLb, *piRestore );
|
|
EnableWindow( hwndLb, TRUE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (IsWindowEnabled( hwndLb ))
|
|
{
|
|
// Toggling to disabled. Stash the selection index.
|
|
//
|
|
*piRestore = ComboBox_GetCurSel( hwndLb );
|
|
ComboBox_InsertString( hwndLb, 0, TEXT("") );
|
|
ComboBox_SetItemData( hwndLb, 0, NULL );
|
|
ComboBox_SetCurSelNotify( hwndLb, 0 );
|
|
EnableWindow( hwndLb, FALSE );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
FirstPhoneNodeFromPhoneList(
|
|
IN DTLLIST* pListPhones )
|
|
|
|
// Return the first PBPHONE node in list of PBPHONEs 'pListPhones' or a
|
|
// default node if none. Returns NULL if out of memory.
|
|
//
|
|
{
|
|
DTLNODE* pFirstNode;
|
|
DTLNODE* pNode;
|
|
|
|
pFirstNode = DtlGetFirstNode( pListPhones );
|
|
if (pFirstNode)
|
|
{
|
|
pNode = DuplicatePhoneNode( pFirstNode );
|
|
}
|
|
else
|
|
{
|
|
pNode = CreatePhoneNode();
|
|
}
|
|
|
|
return pNode;
|
|
}
|
|
|
|
|
|
VOID
|
|
FirstPhoneNodeToPhoneList(
|
|
IN DTLLIST* pListPhones,
|
|
IN DTLNODE* pNewNode )
|
|
|
|
// Replace the first PBPHONE node in list of PBPHONEs 'pListPhones' with
|
|
// 'pNewNode', deleting any existing first node. Caller's actual
|
|
// 'pNewNode', not a copy, is linked.
|
|
//
|
|
{
|
|
DTLNODE* pFirstNode;
|
|
DTLNODE* pNode;
|
|
|
|
pFirstNode = DtlGetFirstNode( pListPhones );
|
|
if (pFirstNode)
|
|
{
|
|
DtlRemoveNode( pListPhones, pFirstNode );
|
|
DestroyPhoneNode( pFirstNode );
|
|
}
|
|
|
|
DtlAddNodeFirst( pListPhones, pNewNode );
|
|
}
|
|
|
|
|
|
#if 0 //!!!
|
|
TCHAR*
|
|
FirstPhoneNumberFromEntry(
|
|
IN PBENTRY* pEntry )
|
|
|
|
// Returns the first phone number of the first link of entry 'pEntry' or
|
|
// an empty string if none. The returned address is into the list of
|
|
// phone numbers and should be copied if it needs to be stored.
|
|
//
|
|
{
|
|
TCHAR* pszPhoneNumber;
|
|
DTLNODE* pNode;
|
|
PBLINK* pLink;
|
|
|
|
TRACE( "FirstPhoneNumberFromEntry" );
|
|
|
|
ASSERT( pEntry->pdtllistLinks );
|
|
pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
|
|
ASSERT( pNode );
|
|
pLink = (PBLINK* )DtlGetData( pNode );
|
|
ASSERT( pLink );
|
|
|
|
return FirstPszFromList( pLink->pdtllistPhoneNumbers );
|
|
}
|
|
#endif
|
|
|
|
|
|
TCHAR*
|
|
FirstPszFromList(
|
|
IN DTLLIST* pPszList )
|
|
|
|
// Returns the first string from the first node of 'pPszList' or an empty
|
|
// string if none. The returned address is into the list and should be
|
|
// copied if it needs to be stored.
|
|
//
|
|
{
|
|
TCHAR* psz;
|
|
DTLNODE* pNode;
|
|
|
|
TRACE( "FirstPszFromList" );
|
|
|
|
if (DtlGetNodes( pPszList ) > 0)
|
|
{
|
|
pNode = DtlGetFirstNode( pPszList );
|
|
ASSERT( pNode );
|
|
psz = (TCHAR* )DtlGetData( pNode );
|
|
ASSERT( psz );
|
|
}
|
|
else
|
|
{
|
|
psz = TEXT("");
|
|
}
|
|
|
|
return psz;
|
|
}
|
|
|
|
|
|
#if 0 //!!!
|
|
DWORD
|
|
FirstPhoneNumberToEntry(
|
|
IN PBENTRY* pEntry,
|
|
IN TCHAR* pszPhoneNumber )
|
|
|
|
// Sets the first phone number of the first link of entry 'pEntry' to
|
|
// 'pszPhoneNumber'.
|
|
//
|
|
// Returns 0 if successful, or an error code.
|
|
//
|
|
{
|
|
DTLNODE* pNode;
|
|
PBLINK* pLink;
|
|
TCHAR* pszNew;
|
|
|
|
TRACE( "FirstPhoneNumberToEntry" );
|
|
|
|
ASSERT( pEntry->pdtllistLinks );
|
|
pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
|
|
ASSERT( pNode );
|
|
pLink = (PBLINK* )DtlGetData( pNode );
|
|
ASSERT( pLink );
|
|
ASSERT( pLink->pdtllistPhoneNumbers );
|
|
|
|
return FirstPszToList( pLink->pdtllistPhoneNumbers, pszPhoneNumber );
|
|
}
|
|
#endif
|
|
|
|
|
|
DWORD
|
|
FirstPszToList(
|
|
IN DTLLIST* pPszList,
|
|
IN TCHAR* psz )
|
|
|
|
// Sets the string of the first node of the list 'pPszList' to a copy of
|
|
// 'psz'. If 'psz' is "" the first node is deleted.
|
|
//
|
|
// Returns 0 if successful, or an error code.
|
|
//
|
|
{
|
|
DTLNODE* pNode;
|
|
TCHAR* pszNew;
|
|
|
|
ASSERT( pPszList );
|
|
|
|
// Delete the existing first node, if any.
|
|
//
|
|
if (DtlGetNodes( pPszList ) > 0)
|
|
{
|
|
pNode = DtlGetFirstNode( pPszList );
|
|
DtlRemoveNode( pPszList, pNode );
|
|
DestroyPszNode( pNode );
|
|
}
|
|
|
|
// Create a new first node and link it. An empty string is not added.
|
|
//
|
|
if (*psz == TEXT('\0'))
|
|
return 0;
|
|
|
|
pszNew = StrDup( psz );
|
|
pNode = DtlCreateNode( pszNew, 0 );
|
|
if (!pszNew || !pNode)
|
|
{
|
|
Free0( pszNew );
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
DtlAddNodeFirst( pPszList, pNode );
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Function: GetBoldWindowFont
|
|
//
|
|
// Purpose: Generate bold or large bold fonts based on the font of the
|
|
// window specified
|
|
//
|
|
// Parameters: hwnd [IN] - Handle of window to base font on
|
|
// fLargeFont [IN] - If TRUE, generate a 12 point bold font for
|
|
// use in the wizard "welcome" page.
|
|
// pBoldFont [OUT] - The newly generated font, NULL if the
|
|
//
|
|
// Returns: nothing
|
|
//
|
|
VOID
|
|
GetBoldWindowFont(
|
|
IN HWND hwnd,
|
|
IN BOOL fLargeFont,
|
|
OUT HFONT * pBoldFont)
|
|
{
|
|
LOGFONT BoldLogFont;
|
|
HFONT hFont;
|
|
TCHAR FontSizeString[MAX_PATH];
|
|
INT FontSize;
|
|
HDC hdc;
|
|
|
|
*pBoldFont = NULL;
|
|
|
|
// Get the font used by the specified window
|
|
//
|
|
hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
|
|
if (NULL == hFont)
|
|
{
|
|
// If not found then the control is using the system font
|
|
//
|
|
hFont = (HFONT)GetStockObject(SYSTEM_FONT);
|
|
}
|
|
|
|
if (hFont)
|
|
{
|
|
// Get the font info so we can generate the BOLD version
|
|
//
|
|
if (GetObject(hFont, sizeof(BoldLogFont), &BoldLogFont))
|
|
{
|
|
// Create the Bold Font
|
|
//
|
|
BoldLogFont.lfWeight = FW_BOLD;
|
|
|
|
hdc = GetDC(hwnd);
|
|
if (hdc)
|
|
{
|
|
// Large (tall) font is an option
|
|
//
|
|
if (fLargeFont)
|
|
{
|
|
// Load size and name from resources,
|
|
// since these may change
|
|
// from locale to locale based on the
|
|
// size of the system font, etc.
|
|
//
|
|
UINT nLen;
|
|
PWCHAR pszFontName = NULL, pszFontSize = NULL;
|
|
|
|
pszFontName = (PWCHAR)PszLoadString(
|
|
g_hinstDll,
|
|
SID_LargeFontName);
|
|
pszFontSize = (PWCHAR)PszLoadString(
|
|
g_hinstDll,
|
|
SID_LargeFontSize);
|
|
if (pszFontName != NULL)
|
|
{
|
|
lstrcpyn(
|
|
BoldLogFont.lfFaceName,
|
|
pszFontName,
|
|
sizeof(BoldLogFont.lfFaceName) / sizeof(TCHAR));
|
|
}
|
|
|
|
FontSize = 12;
|
|
nLen = lstrlen(pszFontName);
|
|
if (pszFontSize)
|
|
{
|
|
lstrcpyn(
|
|
FontSizeString,
|
|
pszFontSize,
|
|
sizeof(FontSizeString) / sizeof(TCHAR));
|
|
FontSize = wcstoul((const TCHAR*)FontSizeString, NULL, 10);
|
|
}
|
|
|
|
BoldLogFont.lfHeight =
|
|
0 - (GetDeviceCaps(hdc,LOGPIXELSY) * FontSize / 72);
|
|
|
|
//Free0(pszFontName);
|
|
//Free0(pszFontSize);
|
|
}
|
|
|
|
*pBoldFont = CreateFontIndirect(&BoldLogFont);
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
GetDefaultEntryName(
|
|
IN PBFILE* pFile,
|
|
IN DWORD dwType,
|
|
IN BOOL fRouter,
|
|
OUT TCHAR** ppszName )
|
|
|
|
// Loads a default entry name into '*ppszName' that is unique within open
|
|
// phonebook 'pFile', or if NULL, in all default phonebooks. 'FRouter' is
|
|
// set if a router-style name should be chosen rather than a client-style
|
|
// name. It is caller's responsibility to Free the returned string.
|
|
//
|
|
// Returns 0 if successful or an error code.
|
|
//
|
|
{
|
|
DWORD dwErr;
|
|
TCHAR szBuf[ RAS_MaxEntryName + 1 ];
|
|
UINT unSid;
|
|
LPCTSTR pszDefault;
|
|
DWORD dwDefaultLen;
|
|
LONG lNum;
|
|
PBFILE file;
|
|
DTLNODE* pNode;
|
|
|
|
*ppszName = NULL;
|
|
|
|
if (fRouter)
|
|
{
|
|
unSid = SID_DefaultRouterEntryName;
|
|
}
|
|
else
|
|
{
|
|
unSid = SID_DefaultEntryName;
|
|
|
|
if (RASET_Vpn == dwType)
|
|
{
|
|
unSid = SID_DefaultVpnEntryName;
|
|
}
|
|
|
|
else if (RASET_Direct == dwType)
|
|
{
|
|
unSid = SID_DefaultDccEntryName;
|
|
}
|
|
|
|
else if (RASET_Broadband == dwType)
|
|
{
|
|
unSid = SID_DefaultBbEntryName;
|
|
}
|
|
}
|
|
|
|
pszDefault = PszLoadString( g_hinstDll, unSid );
|
|
lstrcpyn( szBuf, pszDefault, sizeof(szBuf) / sizeof(TCHAR) );
|
|
dwDefaultLen = lstrlen( pszDefault ) + 1; // +1 for extra space below
|
|
lNum = 2;
|
|
|
|
for (;;)
|
|
{
|
|
if (pFile)
|
|
{
|
|
if (!EntryNodeFromName( pFile->pdtllistEntries, szBuf ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GetPbkAndEntryName(
|
|
NULL, szBuf, RPBF_NoCreate, &file, &pNode ) == 0)
|
|
{
|
|
ClosePhonebookFile( &file );
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Duplicate entry found so increment the default name and try the
|
|
// next one.
|
|
//
|
|
lstrcpyn( szBuf, pszDefault, sizeof(szBuf) / sizeof(TCHAR) );
|
|
lstrcat( szBuf, TEXT(" "));
|
|
LToT( lNum, szBuf + dwDefaultLen, 10 );
|
|
++lNum;
|
|
}
|
|
|
|
*ppszName = StrDup( szBuf );
|
|
if (!*ppszName)
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
BOOL
|
|
IsLocalPad(
|
|
IN PBENTRY* pEntry )
|
|
|
|
// Returns true if 'pEntry' is a local PAD device, i.e. the first link of
|
|
// the entry has device type "pad", false otherwise.
|
|
//
|
|
{
|
|
PBLINK* pLink;
|
|
DTLNODE* pNode;
|
|
|
|
if (!pEntry)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
ASSERT( pEntry->pdtllistLinks );
|
|
pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
|
|
ASSERT( pNode );
|
|
pLink = (PBLINK* )DtlGetData( pNode );
|
|
ASSERT( pLink );
|
|
|
|
return (pLink->pbport.pbdevicetype == PBDT_Pad);
|
|
}
|
|
|
|
#if 0
|
|
//----------------------------------------------------------------------------
|
|
// Function: IsNt40Machine
|
|
//
|
|
// Returns whether the given machine is running nt40
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD
|
|
IsNt40Machine (
|
|
IN PWCHAR pszServer,
|
|
OUT PBOOL pbIsNt40)
|
|
{
|
|
|
|
DWORD dwErr, dwType = REG_SZ, dwLength;
|
|
HKEY hkMachine, hkVersion;
|
|
WCHAR pszBuildNumber[64];
|
|
PWCHAR pszMachine = NULL;
|
|
|
|
//
|
|
// Validate and initialize
|
|
//
|
|
|
|
if (!pbIsNt40)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
*pbIsNt40 = FALSE;
|
|
|
|
do
|
|
{
|
|
// Format the machine name
|
|
if ( (pszServer) && (wcslen(pszServer) > 0) )
|
|
{
|
|
dwLength = wcslen( pszServer ) + 3;
|
|
pszMachine = (PWCHAR) Malloc ( dwLength * sizeof( WCHAR ) );
|
|
if (pszMachine == NULL)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
if ( *pszMachine == L'\\' )
|
|
{
|
|
wcscpy( pszMachine, pszServer );
|
|
}
|
|
else
|
|
{
|
|
wcscpy( pszMachine, L"\\\\" );
|
|
wcscat( pszMachine, pszServer );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pszMachine = NULL;
|
|
}
|
|
|
|
//
|
|
// Connect to the remote server
|
|
//
|
|
dwErr = RegConnectRegistry(
|
|
pszMachine,
|
|
HKEY_LOCAL_MACHINE,
|
|
&hkMachine);
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Open the windows version key
|
|
//
|
|
|
|
dwErr = RegOpenKeyEx(
|
|
hkMachine,
|
|
c_szWinVersionPath,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hkVersion
|
|
);
|
|
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Read in the current version key
|
|
//
|
|
dwLength = sizeof(pszBuildNumber);
|
|
dwErr = RegQueryValueEx (
|
|
hkVersion,
|
|
c_szCurrentBuildNumber,
|
|
NULL,
|
|
&dwType,
|
|
(BYTE*)pszBuildNumber,
|
|
&dwLength
|
|
);
|
|
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (lstrcmp (pszBuildNumber, c_szNt40BuildNumber) == 0)
|
|
{
|
|
*pbIsNt40 = TRUE;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
// Cleanup
|
|
{
|
|
if ( hkVersion )
|
|
{
|
|
RegCloseKey( hkVersion );
|
|
}
|
|
if ( hkMachine )
|
|
{
|
|
RegCloseKey( hkMachine );
|
|
}
|
|
Free0( pszMachine );
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
#endif
|
|
|
|
BOOL
|
|
PhoneNodeIsBlank(
|
|
IN DTLNODE* pNode )
|
|
|
|
// Returns true if the phone number in PBPHONE node 'pNode' is "blank",
|
|
// i.e. it contains no area code, phone number, or comment strings.
|
|
//
|
|
{
|
|
PBPHONE* pPhone;
|
|
|
|
pPhone = (PBPHONE* )DtlGetData( pNode );
|
|
ASSERT( pPhone );
|
|
|
|
if ((!pPhone->pszAreaCode || IsAllWhite( pPhone->pszAreaCode ))
|
|
&& (!pPhone->pszPhoneNumber || IsAllWhite( pPhone->pszPhoneNumber ))
|
|
&& (!pPhone->pszComment || IsAllWhite( pPhone->pszComment )))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
PhoneNumberDlg(
|
|
IN HWND hwndOwner,
|
|
IN BOOL fRouter,
|
|
IN OUT DTLLIST* pList,
|
|
IN OUT BOOL* pfCheck )
|
|
|
|
// Popup the phone number list dialog. 'HwndOwner' is the owner of the
|
|
// created dialog. 'FRouter' indicates router-style labels should be used
|
|
// rather than client-style. 'PList' is a list of Psz nodes containing
|
|
// the phone numbers. 'PfCheck' is the address that contains the initial
|
|
// "promote number" checkbox setting and which receives the value set by
|
|
// user.
|
|
//
|
|
// Returns true if user presses OK and succeeds, false if he presses
|
|
// Cancel or encounters an error.
|
|
//
|
|
{
|
|
DWORD sidHuntTitle;
|
|
DWORD sidHuntItemLabel;
|
|
DWORD sidHuntListLabel;
|
|
DWORD sidHuntCheckLabel;
|
|
|
|
//For whistler bug 227538
|
|
TCHAR *pszTitle = NULL, *pszItem = NULL, *pszList = NULL, *pszCheck = NULL;
|
|
DWORD dwErr = NO_ERROR;
|
|
|
|
TRACE( "PhoneNumberDlg" );
|
|
|
|
if (fRouter)
|
|
{
|
|
sidHuntTitle = SID_RouterHuntTitle;
|
|
sidHuntItemLabel = SID_RouterHuntItemLabel;
|
|
sidHuntListLabel = SID_RouterHuntListLabel;
|
|
sidHuntCheckLabel = SID_RouterHuntCheckLabel;
|
|
}
|
|
else
|
|
{
|
|
sidHuntTitle = SID_HuntTitle;
|
|
sidHuntItemLabel = SID_HuntItemLabel;
|
|
sidHuntListLabel = SID_HuntListLabel;
|
|
sidHuntCheckLabel = SID_HuntCheckLabel;
|
|
}
|
|
|
|
pszTitle = PszFromId( g_hinstDll, sidHuntTitle );
|
|
pszItem = PszFromId( g_hinstDll, sidHuntItemLabel );
|
|
pszList = PszFromId( g_hinstDll, sidHuntListLabel );
|
|
pszCheck = PszFromId( g_hinstDll, sidHuntCheckLabel );
|
|
|
|
dwErr=ListEditorDlg(
|
|
hwndOwner,
|
|
pList,
|
|
pfCheck,
|
|
RAS_MaxPhoneNumber,
|
|
pszTitle,
|
|
pszItem,
|
|
pszList,
|
|
pszCheck,
|
|
NULL,
|
|
0,
|
|
g_adwPnHelp,
|
|
0,
|
|
NULL );
|
|
|
|
Free0( pszTitle );
|
|
Free0( pszItem );
|
|
Free0( pszList );
|
|
Free0( pszCheck );
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
VOID
|
|
PositionDlg(
|
|
IN HWND hwndDlg,
|
|
IN BOOL fPosition,
|
|
IN LONG xDlg,
|
|
IN LONG yDlg )
|
|
|
|
// Positions the dialog 'hwndDlg' based on caller's API settings, where
|
|
// 'fPosition' is the RASxxFLAG_PositionDlg flag and 'xDlg' and 'yDlg' are
|
|
// the coordinates.
|
|
//
|
|
{
|
|
if (fPosition)
|
|
{
|
|
// Move it to caller's coordinates.
|
|
//
|
|
SetWindowPos( hwndDlg, NULL, xDlg, yDlg, 0, 0,
|
|
SWP_NOZORDER + SWP_NOSIZE );
|
|
UnclipWindow( hwndDlg );
|
|
}
|
|
else
|
|
{
|
|
// Center it on the owner window, or on the screen if none.
|
|
//
|
|
CenterWindow( hwndDlg, GetParent( hwndDlg ) );
|
|
}
|
|
}
|
|
|
|
|
|
LRESULT CALLBACK
|
|
PositionDlgStdCallWndProc(
|
|
int code,
|
|
WPARAM wparam,
|
|
LPARAM lparam )
|
|
|
|
// Standard Win32 CallWndProc hook callback that positions the next dialog
|
|
// to start in this thread at our standard offset relative to owner.
|
|
//
|
|
{
|
|
// Arrive here when any window procedure associated with our thread is
|
|
// called.
|
|
//
|
|
if (!wparam)
|
|
{
|
|
CWPSTRUCT* p = (CWPSTRUCT* )lparam;
|
|
|
|
// The message is from outside our process. Look for the MessageBox
|
|
// dialog initialization message and take that opportunity to position
|
|
// the dialog at the standard place relative to the calling dialog.
|
|
//
|
|
if (p->message == WM_INITDIALOG)
|
|
{
|
|
RECT rect;
|
|
HWND hwndOwner;
|
|
|
|
hwndOwner = GetParent( p->hwnd );
|
|
GetWindowRect( hwndOwner, &rect );
|
|
SetWindowPos( p->hwnd, NULL,
|
|
rect.left + DXSHEET, rect.top + DYSHEET,
|
|
0, 0, SWP_NOZORDER + SWP_NOSIZE );
|
|
UnclipWindow( p->hwnd );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
TCHAR*
|
|
PszFromPhoneNumberList(
|
|
IN DTLLIST* pList )
|
|
|
|
// Returns the phone numbers in phone number list 'pList' in a comma
|
|
// string or NULL on error. It is caller's responsiblity to Free the
|
|
// returned string.
|
|
//
|
|
{
|
|
TCHAR* pszResult, *pszTemp;
|
|
DTLNODE* pNode;
|
|
DWORD cb;
|
|
|
|
const TCHAR* pszSeparator = TEXT(", ");
|
|
|
|
cb = (DtlGetNodes( pList ) *
|
|
(RAS_MaxPhoneNumber + lstrlen( pszSeparator )) + 1)
|
|
* sizeof(TCHAR);
|
|
pszResult = Malloc( cb );
|
|
if (!pszResult)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
*pszResult = TEXT('\0');
|
|
|
|
for (pNode = DtlGetFirstNode( pList );
|
|
pNode;
|
|
pNode = DtlGetNextNode( pNode ))
|
|
{
|
|
TCHAR* psz = (TCHAR* )DtlGetData( pNode );
|
|
ASSERT( psz );
|
|
|
|
if (*pszResult)
|
|
lstrcat( pszResult, pszSeparator );
|
|
lstrcat( pszResult, psz );
|
|
}
|
|
|
|
pszTemp = Realloc( pszResult,
|
|
(lstrlen( pszResult ) + 1) * sizeof(TCHAR) );
|
|
ASSERT( pszTemp );
|
|
if (pszTemp)
|
|
{
|
|
pszResult = pszTemp;
|
|
}
|
|
|
|
return pszResult;
|
|
}
|
|
|
|
|
|
#if 0
|
|
LRESULT CALLBACK
|
|
SelectDesktopCallWndRetProc(
|
|
int code,
|
|
WPARAM wparam,
|
|
LPARAM lparam )
|
|
|
|
// Standard Win32 CallWndRetProc hook callback that makes "Desktop" the
|
|
// initial selection of the FileOpen "Look in" combo-box.
|
|
//
|
|
{
|
|
// Arrive here when any window procedure associated with our thread is
|
|
// called.
|
|
//
|
|
if (!wparam)
|
|
{
|
|
CWPRETSTRUCT* p = (CWPRETSTRUCT* )lparam;
|
|
|
|
// The message is from outside our process. Look for the MessageBox
|
|
// dialog initialization message and take that opportunity to set the
|
|
// "Look in:" combo box to the first item, i.e. "Desktop". FileOpen
|
|
// keys off CBN_CLOSEUP rather than CBN_SELCHANGE to update the
|
|
// "contents" listbox.
|
|
//
|
|
if (p->message == WM_INITDIALOG)
|
|
{
|
|
HWND hwndLbLookIn;
|
|
|
|
hwndLbLookIn = GetDlgItem( p->hwnd, cmb2 );
|
|
ComboBox_SetCurSel( hwndLbLookIn, 0 );
|
|
SendMessage( p->hwnd, WM_COMMAND,
|
|
MAKELONG( cmb2, CBN_CLOSEUP ), (LPARAM )hwndLbLookIn );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
//We want to get rid of the Icon resources from rasdlg, they take too much
|
|
//memory resource. instead, we retrieve them from netman.dll, if failed, we
|
|
//use the default one IID_Broadband gangz
|
|
//Also, for whistler bug 372078 364763 364876
|
|
//
|
|
|
|
HICON
|
|
GetCurrentIconEntryType(
|
|
IN DWORD dwType,
|
|
IN BOOL fSmall)
|
|
{
|
|
HICON hIcon = NULL;
|
|
DWORD dwSize, dwConnectionIcon;
|
|
HRESULT hr = E_FAIL;
|
|
NETCON_MEDIATYPE ncm;
|
|
HMODULE hNetshell = NULL;
|
|
|
|
HRESULT (WINAPI * pHrGetIconFromMediaType) (DWORD ,
|
|
NETCON_MEDIATYPE ,
|
|
NETCON_SUBMEDIATYPE ,
|
|
DWORD ,
|
|
DWORD ,
|
|
HICON *);
|
|
|
|
dwSize = fSmall ? 16 : 32;
|
|
|
|
switch (dwType)
|
|
{
|
|
case RASET_Direct:
|
|
{
|
|
ncm = NCM_DIRECT;
|
|
break;
|
|
}
|
|
|
|
case RASET_Vpn:
|
|
{
|
|
ncm = NCM_TUNNEL;
|
|
break;
|
|
}
|
|
|
|
case RASET_Broadband:
|
|
{
|
|
ncm = NCM_PPPOE;
|
|
break;
|
|
}
|
|
|
|
case RASET_Phone:
|
|
default:
|
|
{
|
|
ncm = NCM_PHONE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
hNetshell = LoadLibrary(TEXT("netshell.dll"));
|
|
|
|
if( hNetshell )
|
|
{
|
|
pHrGetIconFromMediaType =(HRESULT (WINAPI*)(
|
|
DWORD ,
|
|
NETCON_MEDIATYPE ,
|
|
NETCON_SUBMEDIATYPE ,
|
|
DWORD ,
|
|
DWORD ,
|
|
HICON *) )GetProcAddress(
|
|
hNetshell,
|
|
"HrGetIconFromMediaType");
|
|
|
|
if ( NULL != pHrGetIconFromMediaType )
|
|
{
|
|
/*******************************************************************
|
|
** dwConnectionIcon - (This is the little Computer part of the icon):
|
|
** 0 - no connection overlay
|
|
** 4 - Connection Icon with both lights off (Disabled status)
|
|
** 5 - Connection Icon with left light on (Transmitting Data)
|
|
** 6 - Connection Icon with right light on (Receiving Data)
|
|
** 7 - Connection Icon with both lights on (Enabled status)
|
|
*********************************************************************/
|
|
|
|
dwConnectionIcon = 7;
|
|
hr = pHrGetIconFromMediaType(dwSize,
|
|
ncm,
|
|
NCSM_NONE,
|
|
7,
|
|
0,
|
|
&hIcon);
|
|
|
|
}
|
|
FreeLibrary( hNetshell );
|
|
}
|
|
|
|
if ( !SUCCEEDED(hr) || !hIcon)
|
|
{
|
|
ICONINFO iInfo;
|
|
HICON hTemp;
|
|
hTemp = LoadIcon( g_hinstDll, MAKEINTRESOURCE( IID_Broadband ) );
|
|
|
|
if(hTemp)
|
|
{
|
|
if( GetIconInfo(hTemp, &iInfo) )
|
|
{
|
|
hIcon = CreateIconIndirect(&iInfo);
|
|
}
|
|
}
|
|
}
|
|
|
|
return hIcon;
|
|
}
|
|
|
|
|
|
VOID
|
|
SetIconFromEntryType(
|
|
IN HWND hwndIcon,
|
|
IN DWORD dwType,
|
|
IN BOOL fSmall)
|
|
|
|
// Set the icon image of icon control 'dwType' to the image corresponding
|
|
// to the entry type 'dwType'.
|
|
//
|
|
{
|
|
HICON hIcon = NULL;
|
|
|
|
hIcon = GetCurrentIconEntryType( dwType, fSmall );
|
|
|
|
if (hIcon)
|
|
{
|
|
Static_SetIcon( hwndIcon, hIcon );
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
TweakTitleBar(
|
|
IN HWND hwndDlg )
|
|
|
|
// Adjust the title bar to include an icon if unowned and the modal frame
|
|
// if not. 'HwndDlg' is the dialog window.
|
|
//
|
|
{
|
|
if (GetParent( hwndDlg ))
|
|
{
|
|
LONG lStyle;
|
|
LONG lStyleAdd;
|
|
|
|
// Drop the system menu and go for the dialog look.
|
|
//
|
|
lStyleAdd = WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE;
|
|
|
|
lStyle = GetWindowLong( hwndDlg, GWL_EXSTYLE );
|
|
if (lStyle)
|
|
SetWindowLong( hwndDlg, GWL_EXSTYLE, lStyle | lStyleAdd );
|
|
}
|
|
else
|
|
{
|
|
// Stick a DUN1 icon in the upper left of the dialog, and more
|
|
// importantly on the task bar
|
|
//
|
|
// Whistler bug: 343455 RAS: Connection dialogs need to use new icons
|
|
//
|
|
//For whistler bug 381099 372078 gangz
|
|
//
|
|
HICON hIcon = NULL;
|
|
|
|
SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
|
|
(LPARAM )LoadIcon( g_hinstDll, MAKEINTRESOURCE( IID_Dun1 ) ) );
|
|
|
|
/*
|
|
//Use small Icon gangz
|
|
//Icon returned from GetCurrentIconEntryType() has to be destroyed after use
|
|
//In the future, Deonb will return a Icon for IID_Dun1 or dun1.ico for us.
|
|
|
|
hIcon = GetCurrentIconEntryType(RASET_Broadband , TRUE);
|
|
|
|
ASSERT(hIcon);
|
|
if(hIcon)
|
|
{
|
|
SendMessage( hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)(hIcon) );
|
|
SetProp( hwndDlg, TEXT("TweakTitleBar_Icon"), hIcon);
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
int CALLBACK
|
|
UnHelpCallbackFunc(
|
|
IN HWND hwndDlg,
|
|
IN UINT unMsg,
|
|
IN LPARAM lparam )
|
|
|
|
// A standard Win32 commctrl PropSheetProc. See MSDN documentation.
|
|
//
|
|
// Returns 0 always.
|
|
//
|
|
{
|
|
TRACE2( "UnHelpCallbackFunc(m=%d,l=%08x)",unMsg, lparam );
|
|
|
|
if (unMsg == PSCB_PRECREATE)
|
|
{
|
|
extern BOOL g_fNoWinHelp;
|
|
|
|
// Turn off context help button if WinHelp won't work. See
|
|
// common\uiutil\ui.c.
|
|
//
|
|
if (g_fNoWinHelp)
|
|
{
|
|
DLGTEMPLATE* pDlg = (DLGTEMPLATE* )lparam;
|
|
pDlg->style &= ~(DS_CONTEXTHELP);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|