Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

521 lines
14 KiB

// Copyright (c) 1996, Microsoft Corporation, all rights reserved
//
// phonenum.c
// Phone number helper library
// Listed alphabetically
//
// 03/06/96 Steve Cobb
#include <windows.h> // Win32 root
#include <nouiutil.h> // No-HWND utilities
#include <tapiutil.h> // TAPI wrappers
#include <phonenum.h> // Our public header
#include <debug.h> // Trace/Assert library
TCHAR*
LinkPhoneNumberFromParts(
IN HINSTANCE hInst,
IN OUT HLINEAPP* pHlineapp,
IN PBUSER* pUser,
IN PBENTRY* pEntry,
IN PBLINK* pLink,
IN DWORD iPhoneNumber,
IN TCHAR* pszOverrideNumber,
IN BOOL fDialable )
// Like PhoneNumberFromParts but takes a link and hunt group index as
// input instead of a base number, and handles not modifying the number
// associated with non-modem/ISDN links. If 'pszOverrideNumber' is
// non-NULL and non-"" it is used instead of the derived number.
//
{
DTLNODE* pNode;
TCHAR* pszBaseNumber;
PBPHONE* pPhone;
if (pszOverrideNumber && *pszOverrideNumber)
{
// So, this is useful? RaoS?
//
return StrDup( pszOverrideNumber );
}
pNode = DtlNodeFromIndex( pLink->pdtllistPhones, iPhoneNumber );
if (!pNode)
{
ASSERT( FALSE );
return NULL;
}
pPhone = (PBPHONE *) DtlGetData(pNode);
ASSERT( pPhone );
if (pLink->pbport.pbdevicetype == PBDT_Modem
|| pLink->pbport.pbdevicetype == PBDT_Isdn)
{
BOOL fDownLevelIsdn;
fDownLevelIsdn =
(pLink->pbport.pbdevicetype == PBDT_Isdn
&& pLink->fProprietaryIsdn);
return PhoneNumberFromParts(
hInst, pHlineapp, pUser, pPhone, fDownLevelIsdn, fDialable );
}
else
{
return StrDup( pPhone->pszPhoneNumber );
}
}
TCHAR*
PhoneNumberFromParts(
IN HINSTANCE hInst,
IN OUT HLINEAPP* pHlineapp,
IN PBUSER* pUser,
IN PBPHONE* pPhone,
IN BOOL fDownLevelIsdn,
IN BOOL fDialable )
// Returns a heap block containing the composite phone number using the
// rules of 'pPhone' and 'pUser'. 'HInst' is the module handle.
// 'PHlineapp' is the TAPI context. 'FDialable' indicates the dialable
// string, instead of the displayable string, should be returned.
//
// It is caller's responsibility to Free the returned string.
//
{
TCHAR* pszResult;
TCHAR* pszBaseNumber;
TRACE( "PhoneNumberFromParts" );
pszBaseNumber = pPhone->pszPhoneNumber;
if (!pszBaseNumber)
{
pszBaseNumber = TEXT("");
}
if (pPhone->fUseDialingRules)
{
pszResult =
PhoneNumberFromTapiPartsEx( hInst, pszBaseNumber,
pPhone->pszAreaCode, pPhone->dwCountryCode, fDownLevelIsdn,
pHlineapp, fDialable );
}
else
{
TCHAR* pszPrefix;
TCHAR* pszSuffix;
PrefixSuffixFromLocationId( pUser,
GetCurrentLocation( hInst, pHlineapp ),
&pszPrefix, &pszSuffix );
pszResult =
PhoneNumberFromPrefixSuffixEx(
pszBaseNumber, pszPrefix, pszSuffix, fDownLevelIsdn );
Free0( pszPrefix );
Free0( pszSuffix );
}
if (!pszResult)
{
TRACE( "!Phone#" );
pszResult = StrDup( pszBaseNumber );
}
return pszResult;
}
TCHAR*
PhoneNumberFromPrefixSuffix(
IN TCHAR* pszBaseNumber,
IN TCHAR* pszPrefix,
IN TCHAR* pszSuffix )
// Returns a heap block containing the composite phone number comprised of
// prefix 'pszPrefix', base phone number 'pszBaseNumber', and suffix
// 'pszSuffix', or NULL if the composite number is too long or on a memory
// error.
//
// It is caller's responsibility to Free the returned string.
//
{
TCHAR* pszResult;
DWORD cch;
TRACE( "PhoneNumberFromPrefixSuffix" );
pszResult = NULL;
if (!pszBaseNumber)
{
pszBaseNumber = TEXT("");
}
if (!pszPrefix)
{
pszPrefix = TEXT("");
}
if (!pszSuffix)
{
pszSuffix = TEXT("");
}
cch = lstrlen( pszPrefix ) + lstrlen( pszBaseNumber ) + lstrlen( pszSuffix );
if (cch > RAS_MaxPhoneNumber)
{
return NULL;
}
pszResult = Malloc( (cch + 1) * sizeof(TCHAR) );
if (pszResult)
{
*pszResult = TEXT('\0');
lstrcat( pszResult, pszPrefix );
lstrcat( pszResult, pszBaseNumber );
lstrcat( pszResult, pszSuffix );
}
return pszResult;
}
TCHAR*
PhoneNumberFromPrefixSuffixEx(
IN TCHAR* pszBaseNumber,
IN TCHAR* pszPrefix,
IN TCHAR* pszSuffix,
IN BOOL fDownLevelIsdn )
// Returns a heap block containing the composite phone number comprised of
// prefix 'pszPrefix', base phone number 'pszBaseNumber', and suffix
// 'pszSuffix', or NULL if the composite number is too long or on a memory
// error.
//
// If 'fDownLevelIsdn' is set colons are recognized as separaters with
// each colon separated token built treated separately.
//
// It is caller's responsibility to Free the returned string.
//
{
TCHAR* psz;
TCHAR* pszResult;
INT cchResult;
TRACE( "PhoneNumberFromPrefixSuffixEx" );
if (fDownLevelIsdn)
{
TCHAR* pszNum;
TCHAR* pszS;
TCHAR* pszE;
pszResult = StrDup( TEXT("") );
for (pszS = pszE = pszBaseNumber;
*pszE != TEXT('\0');
pszE = CharNext( pszE ))
{
if (*pszE == TEXT(':'))
{
*pszE = TEXT('\0');
pszNum =
PhoneNumberFromPrefixSuffix(
pszS, pszPrefix, pszSuffix );
*pszE = TEXT(':');
if (pszNum)
{
if (pszResult)
cchResult = lstrlen( pszResult );
psz = Realloc( pszResult,
(cchResult + lstrlen( pszNum ) + 2) * sizeof(TCHAR) );
if (!psz)
{
Free0( pszResult );
Free( pszNum );
return NULL;
}
pszResult = psz;
lstrcat( pszResult, pszNum );
lstrcat( pszResult, TEXT(":") );
Free( pszNum );
}
pszS = CharNext( pszE );
}
}
{
pszNum =
PhoneNumberFromPrefixSuffix(
pszS, pszPrefix, pszSuffix );
if (pszNum)
{
if (pszResult)
cchResult = lstrlen( pszResult );
psz = Realloc( pszResult,
(cchResult + lstrlen( pszNum ) + 1) * sizeof(TCHAR) );
if (!psz)
{
Free0( pszResult );
Free( pszNum );
return NULL;
}
pszResult = psz;
lstrcat( pszResult, pszNum );
Free( pszNum );
}
}
}
else
{
pszResult =
PhoneNumberFromPrefixSuffix(
pszBaseNumber, pszPrefix, pszSuffix );
}
if (pszResult && (lstrlen( pszResult ) > RAS_MaxPhoneNumber ))
{
Free( pszResult );
return NULL;
}
return pszResult;
}
TCHAR*
PhoneNumberFromTapiParts(
IN HINSTANCE hInst,
IN TCHAR* pszBaseNumber,
IN TCHAR* pszAreaCode,
IN DWORD dwCountryCode,
IN OUT HLINEAPP* pHlineapp,
IN BOOL fDialable )
// Returns a heap block containing the composite phone number comprised of
// base phone number 'pszBaseNumber', area code 'pszAreaCode', and country
// code 'dwCountryCode, or NULL if the composite number is too long or on
// a memory error. 'HInst' is the module instance handle. '*PHlineapp'
// is the address of the TAPI context. 'FDialable' indicates the dialable
// string, as opposed to the displayable string, should be returned.
//
// It is caller's responsibility to Free the returned string.
//
{
TCHAR* pszResult;
TRACE( "PhoneNumberFromTapiParts" );
pszResult = NULL;
TapiTranslateAddress(
hInst, pHlineapp, dwCountryCode, pszAreaCode, pszBaseNumber,
0, fDialable, &pszResult );
return pszResult;
}
TCHAR*
PhoneNumberFromTapiPartsEx(
IN HINSTANCE hInst,
IN TCHAR* pszBaseNumber,
IN TCHAR* pszAreaCode,
IN DWORD dwCountryCode,
IN BOOL fDownLevelIsdn,
IN OUT HLINEAPP* pHlineapp,
IN BOOL fDialable )
// Returns heap block containing the composite phone number comprised of
// base phone number 'pszBaseNumber', area code 'pszAreaCode', and country
// code 'dwCountryCode or NULL if the composite number is too long or on a
// memory error. 'HInst' is the module instance handle. '*PHlineapp' is
// the address of the TAPI context. 'FDialable' indicates the dialable
// string, as opposed to the displayable string, should be returned.
//
// If 'fDownLevelIsdn' is set colons are recognized as separaters with
// each colon separated token built treated separately.
//
// It is caller's responsibility to Free the returned string.
//
{
TCHAR* psz;
TCHAR* pszResult;
INT cchResult;
TRACE( "PhoneNumberFromTapiPartsEx" );
if (fDownLevelIsdn)
{
TCHAR* pszNum;
TCHAR* pszS;
TCHAR* pszE;
pszResult = StrDup( TEXT("") );
for (pszS = pszE = pszBaseNumber;
*pszE != TEXT('\0');
pszE = CharNext( pszE ))
{
if (*pszE == TEXT(':'))
{
*pszE = TEXT('\0');
pszNum = PhoneNumberFromTapiParts(
hInst, pszS, pszAreaCode, dwCountryCode, pHlineapp, fDialable );
*pszE = TEXT(':');
if (pszNum)
{
if (pszResult)
{
cchResult = lstrlen( pszResult );
}
psz = Realloc( pszResult,
(cchResult + lstrlen( pszNum ) + 2) * sizeof(TCHAR) );
if (!psz)
{
Free0( pszResult );
Free( pszNum );
return NULL;
}
pszResult = psz;
lstrcat( pszResult, pszNum );
lstrcat( pszResult, TEXT(":") );
Free( pszNum );
}
pszS = CharNext( pszE );
}
}
{
pszNum = PhoneNumberFromTapiParts(
hInst, pszS, pszAreaCode, dwCountryCode, pHlineapp, fDialable );
if (pszNum)
{
if (pszResult)
{
cchResult = lstrlen( pszResult );
}
psz = Realloc( pszResult,
(cchResult + lstrlen( pszNum ) + 1) * sizeof(TCHAR) );
if (!psz)
{
Free0( pszResult );
Free( pszNum );
return NULL;
}
pszResult = psz;
lstrcat( pszResult, pszNum );
Free( pszNum );
}
}
}
else
{
pszResult = PhoneNumberFromTapiParts(
hInst, pszBaseNumber, pszAreaCode, dwCountryCode, pHlineapp,
fDialable );
}
if (pszResult && (lstrlen( pszResult ) > RAS_MaxPhoneNumber ))
{
Free( pszResult );
return NULL;
}
return pszResult;
}
VOID
PrefixSuffixFromLocationId(
IN PBUSER* pUser,
IN DWORD dwLocationId,
OUT TCHAR** ppszPrefix,
OUT TCHAR** ppszSuffix )
// Retrieve the prefix and suffix strings, '*ppszPrefix' and '*ppszSuffix'
// associated with TAPI location 'dwLocationId'. 'PUser' is the user
// preferences from which to retrieve.
//
// It is caller's responsibility to Free the returned strings.
//
{
#if 0 // NT4-style
DTLNODE* pNode;
INT iPrefix;
INT iSuffix;
TRACE( "PrefixSuffixFromLocationId" );
iPrefix = iSuffix = 0;
for (pNode = DtlGetFirstNode( pUser->pdtllistLocations );
pNode;
pNode = DtlGetNextNode( pNode ))
{
LOCATIONINFO* p = (LOCATIONINFO* )DtlGetData( pNode );
ASSERT( p );
if (p->dwLocationId == dwLocationId)
{
iPrefix = p->iPrefix;
iSuffix = p->iSuffix;
break;
}
}
*ppszPrefix = NULL;
if (iPrefix != 0)
{
pNode = DtlNodeFromIndex( pUser->pdtllistPrefixes, iPrefix - 1 );
if (pNode)
{
*ppszPrefix = StrDup( (TCHAR* )DtlGetData( pNode ) );
}
}
*ppszSuffix = NULL;
if (iSuffix != 0)
{
pNode = DtlNodeFromIndex( pUser->pdtllistSuffixes, iSuffix - 1 );
if (pNode)
{
*ppszSuffix = StrDup( (TCHAR* )DtlGetData( pNode ) );
}
}
#else // Stubbed in NT5/Connections
*ppszPrefix = StrDup( TEXT("") );
*ppszSuffix = StrDup( TEXT("") );
#endif
}