|
|
// 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; }
|