1437 lines
36 KiB
C
1437 lines
36 KiB
C
/* Copyright (c) 1995, Microsoft Corporation, all rights reserved
|
|
**
|
|
** pbk.c
|
|
** Remote Access phonebook library
|
|
** General routines
|
|
** Listed alphabetically
|
|
**
|
|
** 06/20/95 Steve Cobb
|
|
*/
|
|
|
|
#include "pbkp.h"
|
|
#include <search.h> // Qsort
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
** Local prototypes
|
|
**----------------------------------------------------------------------------
|
|
*/
|
|
|
|
DWORD
|
|
AppendPbportToList(
|
|
IN DTLLIST* pdtllist,
|
|
IN RASMAN_PORT* pPort );
|
|
|
|
DWORD
|
|
AppendStringToList(
|
|
IN DTLLIST* pdtllist,
|
|
IN TCHAR* psz );
|
|
|
|
int __cdecl
|
|
CompareDevices(
|
|
const void* pDevice1,
|
|
const void* pDevice2 );
|
|
|
|
int __cdecl
|
|
ComparePorts(
|
|
const void* pPort1,
|
|
const void* pPort2 );
|
|
|
|
CHAR*
|
|
PbMedia(
|
|
IN PBDEVICETYPE pbdt,
|
|
IN CHAR* pszMedia );
|
|
|
|
/*----------------------------------------------------------------------------
|
|
** Routines
|
|
**----------------------------------------------------------------------------
|
|
*/
|
|
|
|
DWORD
|
|
AppendPbportToList(
|
|
IN DTLLIST* pdtllist,
|
|
IN RASMAN_PORT* pPort )
|
|
|
|
/* Append a PBPORT onto the list 'pdtllist' which has the characteristics
|
|
** of RAS Manager port 'pPort'.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-zero error code.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
DTLNODE* pdtlnode;
|
|
PBPORT* ppbport;
|
|
|
|
dwErr = 0;
|
|
|
|
pdtlnode = CreatePortNode();
|
|
if (!pdtlnode)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
ppbport = (PBPORT* )DtlGetData( pdtlnode );
|
|
|
|
ppbport->pszDevice = StrDupTFromA( pPort->P_DeviceName );
|
|
ppbport->pszPort = StrDupTFromA( pPort->P_PortName );
|
|
ppbport->pbdevicetype = PbdevicetypeFromPszTypeA( pPort->P_DeviceType );
|
|
ppbport->pszMedia = StrDupTFromA(
|
|
PbMedia( ppbport->pbdevicetype, pPort->P_MediaName ) );
|
|
|
|
if (!ppbport->pszPort || !ppbport->pszDevice || !ppbport->pszMedia)
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
else if (ppbport->pbdevicetype == PBDT_Modem)
|
|
{
|
|
if (pPort->P_LineDeviceId == 0xFFFFFFFF)
|
|
{
|
|
/* MXS modem port.
|
|
*/
|
|
ppbport->fMxsModemPort = TRUE;
|
|
|
|
GetRasPortMaxBps( pPort->P_Handle,
|
|
&ppbport->dwMaxConnectBps, &ppbport->dwMaxCarrierBps );
|
|
|
|
GetRasPortModemSettings( pPort->P_Handle, &ppbport->fHwFlowDefault,
|
|
&ppbport->fEcDefault, &ppbport->fEccDefault );
|
|
}
|
|
else
|
|
{
|
|
/* Unimodem port.
|
|
*/
|
|
UNIMODEMINFO info;
|
|
|
|
GetRasUnimodemInfo( pPort->P_Handle, pPort->P_DeviceType, &info );
|
|
|
|
TRACE6("Port=%s,fHw=%d,fEc=%d,fEcc=%d,bps=%d,fSp=%d",
|
|
pPort->P_PortName,info.fHwFlow,info.fEc,info.fEcc,
|
|
info.dwBps,info.fSpeaker);
|
|
|
|
ppbport->fHwFlowDefault = info.fHwFlow;
|
|
ppbport->fEcDefault = info.fEc;
|
|
ppbport->fEccDefault = info.fEcc;
|
|
ppbport->dwBpsDefault = info.dwBps;
|
|
ppbport->fSpeakerDefault = info.fSpeaker;
|
|
}
|
|
}
|
|
|
|
if (dwErr == 0)
|
|
DtlAddNodeLast( pdtllist, pdtlnode );
|
|
else
|
|
{
|
|
Free0( ppbport->pszDevice );
|
|
Free0( ppbport->pszMedia );
|
|
Free0( ppbport->pszPort );
|
|
DtlDestroyNode( pdtlnode );
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD
|
|
AppendStringToList(
|
|
IN DTLLIST* pdtllist,
|
|
IN TCHAR* psz )
|
|
|
|
/* Appends a copy of 'psz' to the end of list 'pdtllist'.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-zero error code.
|
|
** ERROR_NOT_ENOUGH_MEMORY is returned if 'psz' is NULL.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
TCHAR* pszDup;
|
|
|
|
if (!psz)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
pszDup = StrDup( psz );
|
|
if (!pszDup)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
pdtlnode = DtlCreateNode( pszDup, 0L );
|
|
if (!pdtlnode )
|
|
{
|
|
Free( pszDup );
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
DtlAddNodeLast( pdtllist, pdtlnode );
|
|
return 0;
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
CloneEntryNode(
|
|
DTLNODE* pdtlnodeSrc )
|
|
|
|
/* Duplicates entry node 'pdtlnodeSrc' with fields that cannot be cloned
|
|
** set to "like new" settings.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
|
|
pdtlnode = DuplicateEntryNode( pdtlnodeSrc );
|
|
if (pdtlnode)
|
|
{
|
|
PBENTRY* ppbentry = (PBENTRY* )DtlGetData( pdtlnode );
|
|
ASSERT(ppbentry);
|
|
|
|
ppbentry->fSkipDownLevelDialog = FALSE;
|
|
ppbentry->fSkipNwcWarning = FALSE;
|
|
ppbentry->dwDialParamsUID = GetTickCount();
|
|
ppbentry->fUsePwForNetwork = FALSE;
|
|
ppbentry->fDirty = FALSE;
|
|
}
|
|
|
|
return pdtlnode;
|
|
}
|
|
|
|
|
|
int __cdecl
|
|
CompareDevices(
|
|
const void* pDevice1,
|
|
const void* pDevice2 )
|
|
|
|
/* Qsort compare function for RASMAN_DEVICEs.
|
|
*/
|
|
{
|
|
return
|
|
lstrcmpiA( ((RASMAN_DEVICE* )pDevice1)->D_Name,
|
|
((RASMAN_DEVICE* )pDevice2)->D_Name );
|
|
}
|
|
|
|
|
|
int __cdecl
|
|
ComparePorts(
|
|
const void* pPort1,
|
|
const void* pPort2 )
|
|
|
|
/* Qsort compare function for RASMAN_PORTs.
|
|
*/
|
|
{
|
|
return
|
|
lstrcmpiA( ((RASMAN_PORT* )pPort1)->P_PortName,
|
|
((RASMAN_PORT* )pPort2)->P_PortName );
|
|
}
|
|
|
|
|
|
DWORD
|
|
CopyToPbport(
|
|
IN PBPORT* ppbportDst,
|
|
IN PBPORT* ppbportSrc )
|
|
|
|
/* Make a duplicate of 'ppbportSrc' in 'ppbportDst'. If 'ppbportSrc' is
|
|
** NULL it sets 'ppbportDst' to defaults.
|
|
**
|
|
** Returns 0 if successful or an error code.
|
|
*/
|
|
{
|
|
Free0( ppbportDst->pszDevice );
|
|
Free0( ppbportDst->pszMedia );
|
|
Free0( ppbportDst->pszPort );
|
|
|
|
if (!ppbportSrc)
|
|
{
|
|
ppbportDst->pszPort = NULL;
|
|
ppbportDst->fConfigured = TRUE;
|
|
ppbportDst->pszDevice = NULL;
|
|
ppbportDst->pszMedia = NULL;
|
|
ppbportDst->pbdevicetype = PBDT_None;
|
|
ppbportDst->fMxsModemPort = FALSE;
|
|
ppbportDst->dwMaxConnectBps = 0;
|
|
ppbportDst->dwMaxCarrierBps = 0;
|
|
ppbportDst->fHwFlowDefault = FALSE;
|
|
ppbportDst->fEcDefault = FALSE;
|
|
ppbportDst->fEccDefault = FALSE;
|
|
ppbportDst->dwBpsDefault = 0;
|
|
ppbportDst->fSpeakerDefault = TRUE;
|
|
return 0;
|
|
}
|
|
|
|
CopyMemory( ppbportDst, ppbportSrc, sizeof(*ppbportDst) );
|
|
ppbportDst->pszDevice = StrDup( ppbportSrc->pszDevice );
|
|
ppbportDst->pszMedia = StrDup( ppbportSrc->pszMedia );
|
|
ppbportDst->pszPort = StrDup( ppbportSrc->pszPort );
|
|
|
|
if ((ppbportSrc->pszDevice && !ppbportDst->pszDevice)
|
|
|| (ppbportSrc->pszMedia && !ppbportDst->pszMedia)
|
|
|| (ppbportSrc->pszPort && !ppbportDst->pszPort))
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
CreateEntryNode(
|
|
BOOL fCreateLink )
|
|
|
|
/* Allocates a sized phonebook entry node and fills it with default
|
|
** values. If 'fCreateLink' is true a default node is added the list of
|
|
** links. Otherwise, the list of links is empty.
|
|
**
|
|
** Returns the address of the allocated node if successful, NULL
|
|
** otherwise.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
PBENTRY* ppbentry;
|
|
|
|
TRACE("CreateEntryNode");
|
|
|
|
pdtlnode = DtlCreateSizedNode( sizeof(PBENTRY), 0L );
|
|
if (!pdtlnode)
|
|
return NULL;
|
|
|
|
ppbentry = (PBENTRY* )DtlGetData( pdtlnode );
|
|
ASSERT(ppbentry);
|
|
|
|
/* Basic page fields.
|
|
*/
|
|
ppbentry->pszEntryName = NULL;
|
|
ppbentry->pszDescription = NULL;
|
|
ppbentry->pszAreaCode = NULL;
|
|
ppbentry->dwCountryCode = 1;
|
|
ppbentry->dwCountryID = 1;
|
|
ppbentry->fUseCountryAndAreaCode = FALSE;
|
|
|
|
/* The list of links is created but left empty.
|
|
*/
|
|
ppbentry->pdtllistLinks = DtlCreateList( 0 );
|
|
if (!ppbentry->pdtllistLinks)
|
|
{
|
|
DestroyEntryNode( pdtlnode );
|
|
return NULL;
|
|
}
|
|
|
|
if (fCreateLink)
|
|
{
|
|
DTLNODE* pLinkNode;
|
|
|
|
pLinkNode = CreateLinkNode();
|
|
if (!pLinkNode)
|
|
{
|
|
DestroyEntryNode( pdtlnode );
|
|
return NULL;
|
|
}
|
|
|
|
DtlAddNodeLast( ppbentry->pdtllistLinks, pLinkNode );
|
|
}
|
|
|
|
ppbentry->dwDialMode = RASEDM_DialAll;
|
|
ppbentry->dwDialPercent = 90;
|
|
ppbentry->dwDialSeconds = 120;
|
|
ppbentry->dwHangUpPercent = 50;
|
|
ppbentry->dwHangUpSeconds = 120;
|
|
|
|
/* Server page fields.
|
|
*/
|
|
ppbentry->dwBaseProtocol = BP_Ppp;
|
|
ppbentry->dwfExcludedProtocols = 0;
|
|
ppbentry->fLcpExtensions = TRUE;
|
|
ppbentry->dwAuthentication = (DWORD )AS_Default;
|
|
ppbentry->fSkipNwcWarning = FALSE;
|
|
ppbentry->fSkipDownLevelDialog = FALSE;
|
|
ppbentry->fSwCompression = TRUE;
|
|
|
|
/* TCPIP Settings dialog.
|
|
*/
|
|
ppbentry->fIpPrioritizeRemote = TRUE;
|
|
ppbentry->fIpHeaderCompression = TRUE;
|
|
ppbentry->pszIpAddress = NULL;
|
|
ppbentry->pszIpDnsAddress = NULL;
|
|
ppbentry->pszIpDns2Address = NULL;
|
|
ppbentry->pszIpWinsAddress = NULL;
|
|
ppbentry->pszIpWins2Address = NULL;
|
|
ppbentry->dwIpAddressSource = ASRC_ServerAssigned;
|
|
ppbentry->dwIpNameSource = ASRC_ServerAssigned;
|
|
ppbentry->dwFrameSize = 1006;
|
|
|
|
/* Script settings.
|
|
*/
|
|
ppbentry->dwScriptModeBefore = SM_None;
|
|
ppbentry->pszScriptBefore = NULL;
|
|
ppbentry->dwScriptModeAfter = SM_None;
|
|
ppbentry->pszScriptAfter = NULL;
|
|
|
|
/* Security page fields.
|
|
*/
|
|
ppbentry->dwAuthRestrictions = AR_AuthAny;
|
|
ppbentry->dwDataEncryption = DE_None;
|
|
ppbentry->fAutoLogon = FALSE;
|
|
ppbentry->fSecureLocalFiles = FALSE;
|
|
ppbentry->fAuthenticateServer = FALSE;
|
|
|
|
/* X.25 page fields.
|
|
*/
|
|
ppbentry->pszX25Network = NULL;
|
|
ppbentry->pszX25Address = NULL;
|
|
ppbentry->pszX25UserData = NULL;
|
|
ppbentry->pszX25Facilities = NULL;
|
|
|
|
/* (Router) Dialing page fields.
|
|
*/
|
|
ppbentry->dwfOverridePref = 0;
|
|
ppbentry->dwIdleDisconnectSeconds = 0;
|
|
ppbentry->dwRedialAttempts = 3;
|
|
ppbentry->dwRedialSeconds = 60;
|
|
ppbentry->fRedialOnLinkFailure = FALSE;
|
|
ppbentry->fPopupOnTopWhenRedialing = TRUE;
|
|
ppbentry->dwCallbackMode = CBM_No;
|
|
|
|
/* Other fields not shown in UI.
|
|
*/
|
|
ppbentry->pszCustomDialDll = NULL;
|
|
ppbentry->pszCustomDialFunc = NULL;
|
|
|
|
/* Authentication dialog fields.
|
|
*/
|
|
ppbentry->dwDialParamsUID = GetTickCount();
|
|
ppbentry->fUsePwForNetwork = FALSE;
|
|
ppbentry->pszOldUser = NULL;
|
|
ppbentry->pszOldDomain = NULL;
|
|
|
|
/* Status flags. 'fDirty' is set when the entry has changed so as to
|
|
** differ from the phonebook file on disk. 'fCustom' is set when the
|
|
** entry contains at least one MEDIA and DEVICE (so RASAPI is able to read
|
|
** it) but was not created by us. When 'fCustom' is set only 'pszEntry'
|
|
** is guaranteed valid and the entry cannot be edited.
|
|
*/
|
|
ppbentry->fDirty = FALSE;
|
|
ppbentry->fCustom = FALSE;
|
|
|
|
return pdtlnode;
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
CreateLinkNode(
|
|
void )
|
|
|
|
/* Allocates a sized phonebook entry link node and fills it with default
|
|
** values.
|
|
**
|
|
** Returns the address of the allocated node if successful, NULL
|
|
** otherwise. It's the caller's responsibility to free the block.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
PBLINK* ppblink;
|
|
|
|
TRACE("CreateLinkNode");
|
|
|
|
pdtlnode = DtlCreateSizedNode( sizeof(PBLINK), 0L );
|
|
if (!pdtlnode)
|
|
return NULL;
|
|
|
|
ppblink = (PBLINK* )DtlGetData( pdtlnode );
|
|
ASSERT(ppblink);
|
|
|
|
CopyToPbport( &ppblink->pbport, NULL );
|
|
ppblink->fOtherPortOk = TRUE;
|
|
|
|
ppblink->dwBps = 0;
|
|
ppblink->fHwFlow = TRUE;
|
|
ppblink->fEc = TRUE;
|
|
ppblink->fEcc = TRUE;
|
|
ppblink->fManualDial = FALSE;
|
|
ppblink->fSpeaker = TRUE;
|
|
|
|
ppblink->fProprietaryIsdn = FALSE;
|
|
ppblink->lLineType = 0;
|
|
ppblink->fFallback = TRUE;
|
|
ppblink->fCompression = TRUE;
|
|
ppblink->lChannels = 1;
|
|
|
|
ppblink->pTapiBlob = NULL;
|
|
ppblink->cbTapiBlob = 0;
|
|
ppblink->fPromoteHuntNumbers = TRUE;
|
|
|
|
ppblink->fEnabled = TRUE;
|
|
|
|
/* The list of phone numbers is created but left empty.
|
|
*/
|
|
ppblink->pdtllistPhoneNumbers = DtlCreateList( 0 );
|
|
if (!ppblink->pdtllistPhoneNumbers)
|
|
{
|
|
Free( ppblink );
|
|
return NULL;
|
|
}
|
|
|
|
return pdtlnode;
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
CreatePortNode(
|
|
void )
|
|
|
|
/* Allocates a sized port node and fills it with default values.
|
|
**
|
|
** Returns the address of the allocated node if successful, NULL
|
|
** otherwise. It's the caller's responsibility to free the block.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
PBPORT* ppbport;
|
|
|
|
TRACE("CreatePortNode");
|
|
|
|
pdtlnode = DtlCreateSizedNode( sizeof(PBPORT), 0L );
|
|
if (!pdtlnode)
|
|
return NULL;
|
|
|
|
ppbport = (PBPORT* )DtlGetData( pdtlnode );
|
|
ASSERT(ppbport);
|
|
|
|
CopyToPbport( ppbport, NULL );
|
|
|
|
return pdtlnode;
|
|
}
|
|
|
|
|
|
VOID
|
|
DestroyEntryNode(
|
|
IN DTLNODE* pdtlnode )
|
|
|
|
/* Release all memory associated with phonebook entry node 'pdtlnode'.
|
|
** See DtlDestroyList.
|
|
*/
|
|
{
|
|
PBENTRY* ppbentry;
|
|
|
|
TRACE("DestroyEntryNode");
|
|
|
|
ASSERT(pdtlnode);
|
|
ppbentry = (PBENTRY* )DtlGetData( pdtlnode );
|
|
ASSERT(ppbentry);
|
|
|
|
Free0( ppbentry->pszEntryName );
|
|
Free0( ppbentry->pszDescription );
|
|
Free0( ppbentry->pszAreaCode );
|
|
Free0( ppbentry->pszIpAddress );
|
|
Free0( ppbentry->pszIpDnsAddress );
|
|
Free0( ppbentry->pszIpDns2Address );
|
|
Free0( ppbentry->pszIpWinsAddress );
|
|
Free0( ppbentry->pszIpWins2Address );
|
|
Free0( ppbentry->pszScriptBefore );
|
|
Free0( ppbentry->pszScriptAfter );
|
|
Free0( ppbentry->pszX25Network );
|
|
Free0( ppbentry->pszX25Address );
|
|
Free0( ppbentry->pszX25UserData );
|
|
Free0( ppbentry->pszX25Facilities );
|
|
Free0( ppbentry->pszCustomDialDll );
|
|
Free0( ppbentry->pszCustomDialFunc );
|
|
Free0( ppbentry->pszOldUser );
|
|
Free0( ppbentry->pszOldDomain );
|
|
DtlDestroyList( ppbentry->pdtllistLinks, DestroyLinkNode );
|
|
|
|
DtlDestroyNode( pdtlnode );
|
|
}
|
|
|
|
|
|
VOID
|
|
DestroyLinkNode(
|
|
IN DTLNODE* pdtlnode )
|
|
|
|
/* Release all memory associated with phonebook entry link node
|
|
** 'pdtlnode'. See DtlDestroyList.
|
|
*/
|
|
{
|
|
PBLINK* ppblink;
|
|
|
|
TRACE("DestroyLinkNode");
|
|
|
|
ASSERT(pdtlnode);
|
|
ppblink = (PBLINK* )DtlGetData( pdtlnode );
|
|
ASSERT(ppblink);
|
|
|
|
Free( ppblink->pbport.pszDevice );
|
|
Free( ppblink->pbport.pszMedia );
|
|
Free0( ppblink->pbport.pszPort );
|
|
Free0( ppblink->pTapiBlob );
|
|
DtlDestroyList( ppblink->pdtllistPhoneNumbers, DestroyPszNode );
|
|
|
|
DtlDestroyNode( pdtlnode );
|
|
}
|
|
|
|
|
|
VOID
|
|
DestroyPortNode(
|
|
IN DTLNODE* pdtlnode )
|
|
|
|
/* Release memory associated with PBPORT node 'pdtlnode'. See
|
|
** DtlDestroyList.
|
|
*/
|
|
{
|
|
PBPORT* pPort;
|
|
|
|
TRACE("DestroyPortNode");
|
|
|
|
ASSERT(pdtlnode);
|
|
pPort = (PBPORT* )DtlGetData( pdtlnode );
|
|
ASSERT(pPort);
|
|
|
|
Free0( pPort->pszDevice );
|
|
Free0( pPort->pszMedia );
|
|
Free0( pPort->pszPort );
|
|
|
|
DtlDestroyNode( pdtlnode );
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
DuplicateEntryNode(
|
|
DTLNODE* pdtlnodeSrc )
|
|
|
|
/* Duplicates phonebook entry node 'pdtlnodeSrc'. See CloneEntryNode and
|
|
** DtlDuplicateList.
|
|
**
|
|
** Returns the address of the allocated node if successful, NULL
|
|
** otherwise. It's the caller's responsibility to free the block.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnodeDst;
|
|
PBENTRY* ppbentrySrc;
|
|
PBENTRY* ppbentryDst;
|
|
BOOL fDone;
|
|
|
|
TRACE("DuplicateEntryNode");
|
|
|
|
pdtlnodeDst = DtlCreateSizedNode( sizeof(PBENTRY), 0L );
|
|
if (!pdtlnodeDst)
|
|
return NULL;
|
|
|
|
ppbentrySrc = (PBENTRY* )DtlGetData( pdtlnodeSrc );
|
|
ppbentryDst = (PBENTRY* )DtlGetData( pdtlnodeDst );
|
|
fDone = FALSE;
|
|
|
|
CopyMemory( ppbentryDst, ppbentrySrc, sizeof(PBENTRY) );
|
|
|
|
ppbentryDst->pszEntryName = NULL;
|
|
ppbentryDst->pszDescription = NULL;
|
|
ppbentryDst->pszAreaCode = NULL;
|
|
ppbentryDst->pszIpAddress = NULL;
|
|
ppbentryDst->pszIpDnsAddress = NULL;
|
|
ppbentryDst->pszIpDns2Address = NULL;
|
|
ppbentryDst->pszIpWinsAddress = NULL;
|
|
ppbentryDst->pszIpWins2Address = NULL;
|
|
ppbentryDst->pszScriptBefore = NULL;
|
|
ppbentryDst->pszScriptAfter = NULL;
|
|
ppbentryDst->pszX25Network = NULL;
|
|
ppbentryDst->pszX25Address = NULL;
|
|
ppbentryDst->pszX25UserData = NULL;
|
|
ppbentryDst->pszX25Facilities = NULL;
|
|
ppbentryDst->pszCustomDialDll = NULL;
|
|
ppbentryDst->pszCustomDialFunc = NULL;
|
|
ppbentryDst->pszOldUser = NULL;
|
|
ppbentryDst->pszOldDomain = NULL;
|
|
ppbentryDst->pdtllistLinks = NULL;
|
|
|
|
do
|
|
{
|
|
/* Duplicate strings.
|
|
*/
|
|
if (ppbentrySrc->pszEntryName
|
|
&& (!(ppbentryDst->pszEntryName =
|
|
StrDup( ppbentrySrc->pszEntryName ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszDescription
|
|
&& (!(ppbentryDst->pszDescription =
|
|
StrDup( ppbentrySrc->pszDescription ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszAreaCode
|
|
&& (!(ppbentryDst->pszAreaCode =
|
|
StrDup( ppbentrySrc->pszAreaCode ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszIpAddress
|
|
&& (!(ppbentryDst->pszIpAddress =
|
|
StrDup( ppbentrySrc->pszIpAddress ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszIpDnsAddress
|
|
&& (!(ppbentryDst->pszIpDnsAddress =
|
|
StrDup( ppbentrySrc->pszIpDnsAddress ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszIpDns2Address
|
|
&& (!(ppbentryDst->pszIpDns2Address =
|
|
StrDup( ppbentrySrc->pszIpDns2Address ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszIpWinsAddress
|
|
&& (!(ppbentryDst->pszIpWinsAddress =
|
|
StrDup( ppbentrySrc->pszIpWinsAddress ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszIpWins2Address
|
|
&& (!(ppbentryDst->pszIpWins2Address =
|
|
StrDup( ppbentrySrc->pszIpWins2Address ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszScriptBefore
|
|
&& (!(ppbentryDst->pszScriptBefore =
|
|
StrDup( ppbentrySrc->pszScriptBefore ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszScriptAfter
|
|
&& (!(ppbentryDst->pszScriptAfter =
|
|
StrDup( ppbentrySrc->pszScriptAfter ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszX25Network
|
|
&& (!(ppbentryDst->pszX25Network =
|
|
StrDup( ppbentrySrc->pszX25Network ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszX25Address
|
|
&& (!(ppbentryDst->pszX25Address =
|
|
StrDup( ppbentrySrc->pszX25Address ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszX25UserData
|
|
&& (!(ppbentryDst->pszX25UserData =
|
|
StrDup( ppbentrySrc->pszX25UserData ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszX25Facilities
|
|
&& (!(ppbentryDst->pszX25Facilities =
|
|
StrDup( ppbentrySrc->pszX25Facilities ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszCustomDialDll
|
|
&& (!(ppbentryDst->pszCustomDialDll =
|
|
StrDup( ppbentrySrc->pszCustomDialDll ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszCustomDialFunc
|
|
&& (!(ppbentryDst->pszCustomDialFunc =
|
|
StrDup( ppbentrySrc->pszCustomDialFunc ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszOldUser
|
|
&& (!(ppbentryDst->pszOldUser =
|
|
StrDup( ppbentrySrc->pszOldUser ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppbentrySrc->pszOldDomain
|
|
&& (!(ppbentryDst->pszOldDomain =
|
|
StrDup( ppbentrySrc->pszOldDomain ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
/* Duplicate list of link information.
|
|
*/
|
|
if (ppbentrySrc->pdtllistLinks
|
|
&& (!(ppbentryDst->pdtllistLinks =
|
|
DtlDuplicateList(
|
|
ppbentrySrc->pdtllistLinks,
|
|
DuplicateLinkNode,
|
|
DestroyLinkNode ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
fDone = TRUE;
|
|
}
|
|
while (FALSE);
|
|
|
|
if (!fDone)
|
|
{
|
|
DestroyEntryNode( pdtlnodeDst );
|
|
return NULL;
|
|
}
|
|
|
|
/* Since the copy is "new" it is inherently dirty relative to the
|
|
** phonebook file.
|
|
*/
|
|
ppbentryDst->fDirty = TRUE;
|
|
|
|
return pdtlnodeDst;
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
DuplicateLinkNode(
|
|
IN DTLNODE* pdtlnodeSrc )
|
|
|
|
/* Duplicates phonebook entry link node 'pdtlnodeSrc'. See
|
|
** DtlDuplicateList.
|
|
**
|
|
** Returns the address of the allocated node if successful, NULL
|
|
** otherwise. It's the caller's responsibility to free the block.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnodeDst;
|
|
PBLINK* ppblinkSrc;
|
|
PBLINK* ppblinkDst;
|
|
BOOL fDone;
|
|
|
|
TRACE("DuplicateLinkNode");
|
|
|
|
pdtlnodeDst = DtlCreateSizedNode( sizeof(PBLINK), 0L );
|
|
if (!pdtlnodeDst)
|
|
return NULL;
|
|
|
|
ppblinkSrc = (PBLINK* )DtlGetData( pdtlnodeSrc );
|
|
ppblinkDst = (PBLINK* )DtlGetData( pdtlnodeDst );
|
|
fDone = FALSE;
|
|
|
|
CopyMemory( ppblinkDst, ppblinkSrc, sizeof(PBLINK) );
|
|
|
|
ppblinkDst->pbport.pszDevice = NULL;
|
|
ppblinkDst->pbport.pszMedia = NULL;
|
|
ppblinkDst->pbport.pszPort = NULL;
|
|
ppblinkDst->pTapiBlob = NULL;
|
|
ppblinkDst->pdtllistPhoneNumbers = NULL;
|
|
|
|
do
|
|
{
|
|
/* Duplicate strings.
|
|
*/
|
|
if (ppblinkSrc->pbport.pszDevice
|
|
&& (!(ppblinkDst->pbport.pszDevice =
|
|
StrDup( ppblinkSrc->pbport.pszDevice ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ppblinkSrc->pbport.pszMedia
|
|
&& (!(ppblinkDst->pbport.pszMedia =
|
|
StrDup( ppblinkSrc->pbport.pszMedia ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
|
|
if (ppblinkSrc->pbport.pszPort
|
|
&& (!(ppblinkDst->pbport.pszPort =
|
|
StrDup( ppblinkSrc->pbport.pszPort ))))
|
|
{
|
|
break;
|
|
}
|
|
/* Duplicate TAPI blob.
|
|
*/
|
|
if (ppblinkSrc->pTapiBlob)
|
|
{
|
|
VOID* pTapiBlobDst;
|
|
|
|
ppblinkDst->pTapiBlob = (VOID* )Malloc( ppblinkSrc->cbTapiBlob );
|
|
if (!ppblinkDst->pTapiBlob)
|
|
break;
|
|
|
|
CopyMemory( ppblinkDst->pTapiBlob, ppblinkSrc->pTapiBlob,
|
|
ppblinkSrc->cbTapiBlob );
|
|
}
|
|
|
|
/* Duplicate list of phone numbers.
|
|
*/
|
|
if (ppblinkSrc->pdtllistPhoneNumbers
|
|
&& (!(ppblinkDst->pdtllistPhoneNumbers =
|
|
DtlDuplicateList(
|
|
ppblinkSrc->pdtllistPhoneNumbers,
|
|
DuplicatePszNode,
|
|
DestroyPszNode ))))
|
|
{
|
|
break;
|
|
}
|
|
|
|
fDone = TRUE;
|
|
}
|
|
while (FALSE);
|
|
|
|
if (!fDone)
|
|
{
|
|
DestroyLinkNode( pdtlnodeDst );
|
|
return NULL;
|
|
}
|
|
|
|
return pdtlnodeDst;
|
|
}
|
|
|
|
|
|
DTLNODE*
|
|
EntryNodeFromName(
|
|
IN DTLLIST* pdtllistEntries,
|
|
IN TCHAR* pszName )
|
|
|
|
/* Returns the address of the node in the global phonebook entries list
|
|
** whose Entry Name matches 'pszName' or NULL if none.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
|
|
for (pdtlnode = DtlGetFirstNode( pdtllistEntries );
|
|
pdtlnode;
|
|
pdtlnode = DtlGetNextNode( pdtlnode ))
|
|
{
|
|
PBENTRY* ppbentry = (PBENTRY* )DtlGetData( pdtlnode );
|
|
|
|
if (lstrcmpi( ppbentry->pszEntryName, pszName ) == 0)
|
|
return pdtlnode;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
#if 0
|
|
INT
|
|
IndexFromName(
|
|
IN DTLLIST* pdtllist,
|
|
IN TCHAR* pszName )
|
|
|
|
/* Returns the 0-based index of the first node that matches 'pszName' in
|
|
** the linked list of strings, 'pdtllist', or -1 if not found.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
INT i;
|
|
|
|
for (pdtlnode = DtlGetFirstNode( pdtllist ), i = 0;
|
|
pdtlnode;
|
|
pdtlnode = DtlGetNextNode( pdtlnode ), ++i)
|
|
{
|
|
if (lstrcmp( pszName, (TCHAR* )DtlGetData( pdtlnode ) ) == 0)
|
|
break;
|
|
}
|
|
|
|
return (pdtlnode) ? i : -1;
|
|
}
|
|
#endif
|
|
|
|
|
|
#if 0
|
|
INT
|
|
IndexFromDeviceName(
|
|
IN DTLLIST* pdtllist,
|
|
IN TCHAR* pszDeviceName )
|
|
|
|
/* Returns the 0-based index of the first node that matches
|
|
** 'pszDeviceName' in the linked list of PBPORTs, 'pdtllist', or -1 if not
|
|
** found.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
INT i;
|
|
|
|
for (pdtlnode = DtlGetFirstNode( pdtllist ), i = 0;
|
|
pdtlnode;
|
|
pdtlnode = DtlGetNextNode( pdtlnode ), ++i)
|
|
{
|
|
PBPORT* pPort = (PBPORT* )DtlGetData( pdtlnode );
|
|
|
|
if (lstrcmp( pszDeviceName, pPort->pszDevice ) == 0)
|
|
break;
|
|
}
|
|
|
|
return (pdtlnode) ? i : -1;
|
|
}
|
|
#endif
|
|
|
|
|
|
DWORD
|
|
LoadPadsList(
|
|
OUT DTLLIST** ppdtllistPads )
|
|
|
|
/* Build a list of all X.25 PAD devices in '*ppdtllistPads'.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-zero error code. It is
|
|
** caller's responsibility to DtlDestroyList the list when done.
|
|
*/
|
|
{
|
|
INT i;
|
|
DWORD dwErr;
|
|
RASMAN_DEVICE* pDevices;
|
|
WORD wDevices;
|
|
|
|
TRACE("LoadPadsList");
|
|
|
|
*ppdtllistPads = NULL;
|
|
|
|
dwErr = GetRasPads( &pDevices, &wDevices );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
|
|
*ppdtllistPads = DtlCreateList( 0L );
|
|
if (!*ppdtllistPads)
|
|
{
|
|
Free( pDevices );
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
qsort( (VOID* )pDevices, (size_t )wDevices, sizeof(RASMAN_DEVICE),
|
|
CompareDevices );
|
|
|
|
for (i = 0; i < (INT )wDevices; ++i)
|
|
{
|
|
TCHAR* pszDup;
|
|
|
|
pszDup = StrDupTFromA( pDevices[ i ].D_Name );
|
|
dwErr = AppendStringToList( *ppdtllistPads, pszDup );
|
|
Free0( pszDup );
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
Free( pDevices );
|
|
DtlDestroyList( *ppdtllistPads, NULL );
|
|
*ppdtllistPads = NULL;
|
|
return dwErr;
|
|
}
|
|
}
|
|
|
|
Free( pDevices );
|
|
|
|
TRACE("LoadPadsList=0");
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
LoadPortsList(
|
|
OUT DTLLIST** ppdtllistPorts )
|
|
|
|
/* Build a sorted list of all RAS ports in '*ppdtllistPorts'.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-zero error code. It is
|
|
** caller's responsibility to DtlDestroyList the list when done.
|
|
*/
|
|
{
|
|
return LoadPortsList2( ppdtllistPorts, FALSE );
|
|
}
|
|
|
|
|
|
DWORD
|
|
LoadPortsList2(
|
|
OUT DTLLIST** ppdtllistPorts,
|
|
OUT BOOL fRouter )
|
|
|
|
/* Build a sorted list of all RAS ports in '*ppdtllistPorts'. 'FRouter'
|
|
** indicates only ports with "router" usage should be returned.
|
|
** Otherwise, only dialout ports are returned.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-zero error code. It is
|
|
** caller's responsibility to DtlDestroyList the list when done.
|
|
*/
|
|
{
|
|
INT i;
|
|
DWORD dwErr;
|
|
RASMAN_PORT* pPorts;
|
|
RASMAN_PORT* pPort;
|
|
WORD wPorts;
|
|
|
|
TRACE("LoadPortsList2");
|
|
|
|
*ppdtllistPorts = NULL;
|
|
|
|
dwErr = GetRasPorts( &pPorts, &wPorts );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
|
|
*ppdtllistPorts = DtlCreateList( 0L );
|
|
if (!*ppdtllistPorts)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
qsort( (VOID* )pPorts, (size_t )wPorts, sizeof(RASMAN_PORT),
|
|
ComparePorts );
|
|
|
|
for (i = 0, pPort = pPorts; i < (INT )wPorts; ++i, ++pPort)
|
|
{
|
|
if (fRouter)
|
|
{
|
|
/* We're only interested in router ports.
|
|
*/
|
|
if (!(pPort->P_ConfiguredUsage & CALL_ROUTER))
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
/* We're only interested in ports you can dial-out on.
|
|
*/
|
|
if (!(pPort->P_ConfiguredUsage & CALL_OUT))
|
|
continue;
|
|
}
|
|
|
|
dwErr = AppendPbportToList( *ppdtllistPorts, pPort );
|
|
if (dwErr != 0)
|
|
{
|
|
Free( pPorts );
|
|
DtlDestroyList( *ppdtllistPorts, NULL );
|
|
*ppdtllistPorts = NULL;
|
|
return dwErr;
|
|
}
|
|
}
|
|
|
|
Free( pPorts );
|
|
|
|
TRACE("LoadPortsList=0");
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
LoadScriptsList(
|
|
OUT DTLLIST** ppdtllistScripts )
|
|
|
|
/* Build a sorted list of all RAS switch devices in '*ppdtllistPorts'.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-zero error code. It is
|
|
** caller's responsibility to DtlDestroyList the list when done.
|
|
*/
|
|
{
|
|
INT i;
|
|
DWORD dwErr;
|
|
RASMAN_DEVICE* pDevices;
|
|
WORD wDevices;
|
|
|
|
TRACE("LoadScriptsList");
|
|
|
|
*ppdtllistScripts = NULL;
|
|
|
|
dwErr = GetRasSwitches( &pDevices, &wDevices );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
|
|
*ppdtllistScripts = DtlCreateList( 0L );
|
|
if (!*ppdtllistScripts)
|
|
{
|
|
Free( pDevices );
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
qsort( (VOID* )pDevices, (size_t )wDevices, sizeof(RASMAN_DEVICE),
|
|
CompareDevices );
|
|
|
|
for (i = 0; i < (INT )wDevices; ++i)
|
|
{
|
|
TCHAR* pszDup;
|
|
|
|
pszDup = StrDupTFromA( pDevices[ i ].D_Name );
|
|
dwErr = AppendStringToList( *ppdtllistScripts, pszDup );
|
|
Free( pszDup );
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
Free( pDevices );
|
|
DtlDestroyList( *ppdtllistScripts, NULL );
|
|
*ppdtllistScripts = NULL;
|
|
return dwErr;
|
|
}
|
|
}
|
|
|
|
Free( pDevices );
|
|
|
|
TRACE("LoadScriptsList=0");
|
|
return 0;
|
|
}
|
|
|
|
|
|
#if 0
|
|
TCHAR*
|
|
NameFromIndex(
|
|
IN DTLLIST* pdtllist,
|
|
IN INT iToFind )
|
|
|
|
/* Returns the name associated with 0-based index 'iToFind' in the linked
|
|
** list of strings, 'pdtllist', or NULL if not found.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
|
|
if (!pdtllist)
|
|
return NULL;
|
|
|
|
pdtlnode = DtlGetFirstNode( pdtllist );
|
|
|
|
if (iToFind < 0)
|
|
return NULL;
|
|
|
|
while (pdtlnode && iToFind--)
|
|
pdtlnode = DtlGetNextNode( pdtlnode );
|
|
|
|
return (pdtlnode) ? (TCHAR* )DtlGetData( pdtlnode ) : NULL;
|
|
}
|
|
#endif
|
|
|
|
|
|
PBDEVICETYPE
|
|
PbdevicetypeFromPszType(
|
|
IN TCHAR* pszDeviceType )
|
|
|
|
/* Returns the device type corresponding to the device type string,
|
|
** 'pszDeviceType'.
|
|
*/
|
|
{
|
|
CHAR* pszA;
|
|
PBDEVICETYPE pbdt;
|
|
|
|
pbdt = PBDT_None;
|
|
pszA = StrDupAFromT( pszDeviceType );
|
|
if (pszA)
|
|
{
|
|
pbdt = PbdevicetypeFromPszTypeA( pszA );
|
|
Free( pszA );
|
|
}
|
|
return pbdt;
|
|
}
|
|
|
|
|
|
PBDEVICETYPE
|
|
PbdevicetypeFromPszTypeA(
|
|
IN CHAR* pszDeviceType )
|
|
|
|
/* Returns the device type corresponding to the ANSI device type string,
|
|
** 'pszDeviceType'.
|
|
*/
|
|
{
|
|
if (*pszDeviceType == '\0')
|
|
return PBDT_None;
|
|
else if (lstrcmpiA( pszDeviceType, MXS_MODEM_TXT ) == 0)
|
|
return PBDT_Modem;
|
|
else if (lstrcmpiA( pszDeviceType, MXS_NULL_TXT ) == 0)
|
|
return PBDT_Null;
|
|
else if (lstrcmpiA( pszDeviceType, MXS_PAD_TXT ) == 0)
|
|
return PBDT_Pad;
|
|
else if (lstrcmpiA( pszDeviceType, MXS_SWITCH_TXT ) == 0)
|
|
return PBDT_Switch;
|
|
else if (lstrcmpiA( pszDeviceType, ISDN_TXT ) == 0)
|
|
return PBDT_Isdn;
|
|
else if (lstrcmpiA( pszDeviceType, X25_TXT ) == 0)
|
|
return PBDT_X25;
|
|
else
|
|
return PBDT_Other;
|
|
}
|
|
|
|
|
|
CHAR*
|
|
PbMedia(
|
|
IN PBDEVICETYPE pbdt,
|
|
IN CHAR* pszMedia )
|
|
|
|
/* The media names stored in the phonebook are not exactly the same as
|
|
** those returned by RASMAN. This translates a RASMAN media name to
|
|
** equivalent phonebook media names given the device type. The reason for
|
|
** this is historical and obscure.
|
|
*/
|
|
{
|
|
if (pbdt == PBDT_Isdn)
|
|
return ISDN_TXT;
|
|
else if (pbdt == PBDT_X25)
|
|
return X25_TXT;
|
|
else if (pbdt == PBDT_Other)
|
|
return pszMedia;
|
|
else
|
|
return SERIAL_TXT;
|
|
}
|
|
|
|
|
|
PBPORT*
|
|
PpbportFromPortName(
|
|
IN DTLLIST* pdtllistPorts,
|
|
IN TCHAR* pszPort )
|
|
|
|
/* Return port with name 'pszPort' in list of ports 'pdtllistPorts' or
|
|
** NULL if not found. 'PszPort' may be an old-style name such as
|
|
** PcImacISDN1, in which case it will match ISDN1.
|
|
*/
|
|
{
|
|
DTLNODE* pdtlnode;
|
|
|
|
if (!pszPort)
|
|
return NULL;
|
|
|
|
for (pdtlnode = DtlGetFirstNode( pdtllistPorts );
|
|
pdtlnode;
|
|
pdtlnode = DtlGetNextNode( pdtlnode ))
|
|
{
|
|
PBPORT* ppbport = (PBPORT* )DtlGetData( pdtlnode );
|
|
|
|
if (ppbport->pszPort && lstrcmp( ppbport->pszPort, pszPort ) == 0)
|
|
return ppbport;
|
|
}
|
|
|
|
/* No match. Look for the old port name format.
|
|
*/
|
|
for (pdtlnode = DtlGetFirstNode( pdtllistPorts );
|
|
pdtlnode;
|
|
pdtlnode = DtlGetNextNode( pdtlnode ))
|
|
{
|
|
TCHAR szBuf[ MAX_DEVICE_NAME + MAX_DEVICETYPE_NAME + 10 + 1 ];
|
|
PBPORT* ppbport;
|
|
|
|
ppbport = (PBPORT* )DtlGetData( pdtlnode );
|
|
|
|
/* Skip modems (COM ports) and unconfigured ports, since they do not
|
|
** follow the same port name formatting rules as other ports.
|
|
*/
|
|
if (!ppbport->pszDevice || ppbport->pbdevicetype == PBDT_Modem)
|
|
continue;
|
|
|
|
lstrcpy( szBuf, ppbport->pszDevice );
|
|
lstrcat( szBuf, ppbport->pszPort );
|
|
|
|
if (lstrcmp( szBuf, pszPort ) == 0)
|
|
return ppbport;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
BOOL
|
|
SetDefaultModemSettings(
|
|
IN PBLINK* pLink )
|
|
|
|
/* Set the MXS modem settings for link 'pLink' to the defaults.
|
|
**
|
|
** Returns true if something changed, false otherwise.
|
|
*/
|
|
{
|
|
BOOL fChange;
|
|
DWORD dwBps;
|
|
|
|
fChange = FALSE;
|
|
|
|
if (pLink->fHwFlow != pLink->pbport.fHwFlowDefault)
|
|
{
|
|
fChange = TRUE;
|
|
pLink->fHwFlow = pLink->pbport.fHwFlowDefault;
|
|
}
|
|
|
|
if (pLink->fEc != pLink->pbport.fEcDefault)
|
|
{
|
|
fChange = TRUE;
|
|
pLink->fEc = pLink->pbport.fEcDefault;
|
|
}
|
|
|
|
if (pLink->fEcc != pLink->pbport.fEccDefault)
|
|
{
|
|
fChange = TRUE;
|
|
pLink->fEcc = pLink->pbport.fEccDefault;
|
|
}
|
|
|
|
if (pLink->fManualDial)
|
|
{
|
|
fChange = TRUE;
|
|
pLink->fManualDial = FALSE;
|
|
}
|
|
|
|
if (!pLink->pbport.fMxsModemPort)
|
|
{
|
|
if (pLink->fSpeaker != pLink->pbport.fSpeakerDefault)
|
|
{
|
|
fChange = TRUE;
|
|
pLink->fSpeaker = pLink->pbport.fSpeakerDefault;
|
|
}
|
|
}
|
|
|
|
if (pLink->pbport.fMxsModemPort)
|
|
{
|
|
dwBps = (pLink->fHwFlow)
|
|
? pLink->pbport.dwMaxConnectBps
|
|
: pLink->pbport.dwMaxCarrierBps;
|
|
}
|
|
else
|
|
dwBps = pLink->pbport.dwBpsDefault;
|
|
|
|
if (pLink->dwBps != dwBps)
|
|
{
|
|
fChange = TRUE;
|
|
pLink->dwBps = dwBps;
|
|
}
|
|
|
|
TRACE2("SetDefaultModemSettings(bps=%d)=%d",pLink->dwBps,fChange);
|
|
return fChange;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ValidateAreaCode(
|
|
IN OUT TCHAR* pszAreaCode )
|
|
|
|
/* Checks that area code consists of decimal digits only. If the area
|
|
** code is all white characters it is reduced to empty string. Returns
|
|
** true if 'pszAreaCode' is a valid area code, false if not.
|
|
*/
|
|
{
|
|
if (IsAllWhite( pszAreaCode ))
|
|
{
|
|
*pszAreaCode = TEXT('\0');
|
|
return TRUE;
|
|
}
|
|
|
|
if (lstrlen( pszAreaCode ) > RAS_MaxAreaCode)
|
|
return FALSE;
|
|
|
|
while (*pszAreaCode != TEXT('\0'))
|
|
{
|
|
if (*pszAreaCode < TEXT('0') || *pszAreaCode > TEXT('9'))
|
|
return FALSE;
|
|
|
|
++pszAreaCode;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ValidateEntryName(
|
|
IN TCHAR* pszEntry )
|
|
|
|
/* Returns true if 'pszEntry' is a valid phonebook entry name, false if
|
|
** not.
|
|
*/
|
|
{
|
|
INT nLen = lstrlen( pszEntry );
|
|
|
|
if (nLen <= 0
|
|
|| nLen > RAS_MaxEntryName
|
|
|| IsAllWhite( pszEntry )
|
|
|| pszEntry[ 0 ] == TEXT('.'))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|