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.
1462 lines
47 KiB
1462 lines
47 KiB
// ############################################################################
|
|
// Phone book APIs
|
|
#include "pch.hpp"
|
|
#ifdef WIN16
|
|
#include <win16def.h>
|
|
#include <win32fn.h>
|
|
#include <rasc.h>
|
|
#include <raserr.h>
|
|
#include <ietapi.h>
|
|
extern "C" {
|
|
#include "bmp.h"
|
|
}
|
|
#endif
|
|
|
|
#include "phbk.h"
|
|
#include "misc.h"
|
|
#include "phbkrc.h"
|
|
#include "suapi.h"
|
|
|
|
//#define ReadVerifyPhoneBookDW(x) AssertMsg(ReadPhoneBookDW(&(x),pcCSVFile),"Invalid DWORD in phone book");
|
|
#define ReadVerifyPhoneBookDW(x) if (!ReadPhoneBookDW(&(x),pcCSVFile)) \
|
|
{ AssertMsg(0,"Invalid DWORD in phone book"); \
|
|
goto ReadError; }
|
|
#define ReadVerifyPhoneBookW(x) if (!ReadPhoneBookW(&(x),pcCSVFile)) \
|
|
{ AssertMsg(0,"Invalid DWORD in phone book"); \
|
|
goto ReadError; }
|
|
#define ReadVerifyPhoneBookB(x) if (!ReadPhoneBookB(&(x),pcCSVFile)) \
|
|
{ AssertMsg(0,"Invalid DWORD in phone book"); \
|
|
goto ReadError; }
|
|
#define ReadVerifyPhoneBookSZ(x,y) if (!ReadPhoneBookSZ(&x[0],y+sizeof('\0'),pcCSVFile)) \
|
|
{ AssertMsg(0,"Invalid DWORD in phone book"); \
|
|
goto ReadError; }
|
|
|
|
#define CHANGE_BUFFER_SIZE 50
|
|
|
|
#define TEMP_PHONE_BOOK_PREFIX TEXT("PBH")
|
|
|
|
#define ERROR_USERBACK 32766
|
|
#define ERROR_USERCANCEL 32767
|
|
|
|
TCHAR szTempBuffer[TEMP_BUFFER_LENGTH];
|
|
TCHAR szTempFileName[MAX_PATH];
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
HWND g_hWndMain;
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#if !defined(WIN16)
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function IsMSDUN12Installed
|
|
//
|
|
// Synopsis Check if MSDUN 1.2 or higher is installed
|
|
//
|
|
// Arguments none
|
|
//
|
|
// Returns TRUE - MSDUN 1.2 is installed
|
|
//
|
|
// History 5/28/97 ChrisK created for Olympus Bug 4392
|
|
// 8/7/97 ChrisK lifted from isign32
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
#define DUN_12_Version ((double)1.2)
|
|
BOOL IsMSDUN12Installed()
|
|
{
|
|
TCHAR szBuffer[MAX_PATH] = {TEXT("\0")};
|
|
HKEY hkey = NULL;
|
|
BOOL bRC = FALSE;
|
|
DWORD dwType = 0;
|
|
DWORD dwSize = sizeof(szBuffer);
|
|
FLOAT flVersion = 0e0f;
|
|
|
|
if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
|
|
TEXT("System\\CurrentControlSet\\Services\\RemoteAccess"),
|
|
&hkey))
|
|
{
|
|
goto IsMSDUN12InstalledExit;
|
|
}
|
|
|
|
if (ERROR_SUCCESS != RegQueryValueEx(hkey,
|
|
TEXT("Version"),
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szBuffer,
|
|
&dwSize))
|
|
{
|
|
goto IsMSDUN12InstalledExit;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
CHAR szTmp[MAX_PATH];
|
|
wcstombs(szTmp, szBuffer, MAX_PATH);
|
|
szTmp[MAX_PATH - 1] = '\0';
|
|
bRC = DUN_12_Version <= atof(szTmp);
|
|
#else
|
|
bRC = DUN_12_Version <= atof(szBuffer);
|
|
#endif
|
|
IsMSDUN12InstalledExit:
|
|
if (hkey != NULL)
|
|
{
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
}
|
|
return bRC;
|
|
}
|
|
#endif
|
|
|
|
// ############################################################################
|
|
CPhoneBook::CPhoneBook()
|
|
{
|
|
HINSTANCE hInst = NULL;
|
|
LONG lrc;
|
|
#if !defined(WIN16)
|
|
HKEY hkey;
|
|
#endif
|
|
DWORD dwType;
|
|
DWORD dwSize;
|
|
TCHAR szData[MAX_PATH+1];
|
|
|
|
m_rgPhoneBookEntry = NULL;
|
|
m_hPhoneBookEntry = NULL;
|
|
m_cPhoneBookEntries =0;
|
|
m_rgLineCountryEntry=NULL;
|
|
m_rgState=NULL;
|
|
m_cStates=0;
|
|
m_rgIDLookUp = NULL;
|
|
m_rgNameLookUp = NULL;
|
|
m_pLineCountryList = NULL;
|
|
|
|
ZeroMemory(&m_szINFFile[0],MAX_PATH);
|
|
ZeroMemory(&m_szINFCode[0],MAX_INFCODE);
|
|
ZeroMemory(&m_szPhoneBook[0],MAX_PATH);
|
|
|
|
#if !defined(WIN16)
|
|
if (VER_PLATFORM_WIN32_NT == DWGetWin32Platform())
|
|
{
|
|
m_bScriptingAvailable = TRUE;
|
|
}
|
|
else if (IsMSDUN12Installed())
|
|
{
|
|
//
|
|
// ChrisK 8/7/97 Olympus1 11814
|
|
// Display scripted phone numbers on system with DUN 1.2 installed
|
|
//
|
|
m_bScriptingAvailable = TRUE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Verify scripting by checking for smmscrpt.dll in RemoteAccess registry key
|
|
//
|
|
if (1111 <= DWGetWin32BuildNumber())
|
|
{
|
|
m_bScriptingAvailable = TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_bScriptingAvailable = FALSE;
|
|
hkey = NULL;
|
|
lrc=RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\Authentication\\SMM_FILES\\PPP"),&hkey);
|
|
if (ERROR_SUCCESS == lrc)
|
|
{
|
|
dwSize = sizeof(TCHAR)*MAX_PATH;
|
|
lrc = RegQueryValueEx(hkey,TEXT("Path"),0,&dwType,(LPBYTE)szData,&dwSize);
|
|
if (ERROR_SUCCESS == lrc)
|
|
{
|
|
if (0 == lstrcmpi(szData,TEXT("smmscrpt.dll")))
|
|
m_bScriptingAvailable = TRUE;
|
|
}
|
|
}
|
|
if (hkey)
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
}
|
|
|
|
//
|
|
// Verify that the DLL can be loaded
|
|
//
|
|
if (m_bScriptingAvailable)
|
|
{
|
|
hInst = LoadLibrary(TEXT("smmscrpt.dll"));
|
|
if (hInst)
|
|
FreeLibrary(hInst);
|
|
else
|
|
m_bScriptingAvailable = FALSE;
|
|
hInst = NULL;
|
|
}
|
|
}
|
|
#endif // WIN16
|
|
}
|
|
|
|
// ############################################################################
|
|
CPhoneBook::~CPhoneBook()
|
|
{
|
|
#ifdef WIN16
|
|
if (m_rgPhoneBookEntry)
|
|
GlobalFree(m_rgPhoneBookEntry);
|
|
#else
|
|
if (m_hPhoneBookEntry)
|
|
GlobalUnlock(m_hPhoneBookEntry);
|
|
|
|
if (m_hPhoneBookEntry)
|
|
GlobalFree(m_hPhoneBookEntry);
|
|
#endif
|
|
|
|
if (m_pLineCountryList)
|
|
GlobalFree(m_pLineCountryList);
|
|
|
|
if (m_rgIDLookUp)
|
|
GlobalFree(m_rgIDLookUp);
|
|
|
|
if (m_rgNameLookUp)
|
|
GlobalFree(m_rgNameLookUp);
|
|
|
|
if (m_rgState)
|
|
GlobalFree(m_rgState);
|
|
}
|
|
|
|
// ############################################################################
|
|
BOOL CPhoneBook::ReadPhoneBookDW(DWORD far *pdw, CCSVFile far *pcCSVFile)
|
|
{
|
|
if (!pcCSVFile->ReadToken(szTempBuffer,TEMP_BUFFER_LENGTH))
|
|
return FALSE;
|
|
return (FSz2Dw(szTempBuffer,pdw));
|
|
}
|
|
|
|
// ############################################################################
|
|
BOOL CPhoneBook::ReadPhoneBookW(WORD far *pw, CCSVFile far *pcCSVFile)
|
|
{
|
|
if (!pcCSVFile->ReadToken(szTempBuffer,TEMP_BUFFER_LENGTH))
|
|
return FALSE;
|
|
return (FSz2W(szTempBuffer,pw));
|
|
}
|
|
|
|
// ############################################################################
|
|
BOOL CPhoneBook::ReadPhoneBookB(BYTE far *pb, CCSVFile far *pcCSVFile)
|
|
{
|
|
if (!pcCSVFile->ReadToken(szTempBuffer,TEMP_BUFFER_LENGTH))
|
|
return FALSE;
|
|
return (FSz2B(szTempBuffer,pb));
|
|
}
|
|
|
|
// ############################################################################
|
|
BOOL CPhoneBook::ReadPhoneBookSZ(LPTSTR psz, DWORD dwSize, CCSVFile far *pcCSVFile)
|
|
{
|
|
if (!pcCSVFile->ReadToken(psz,dwSize))
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
// ############################################################################
|
|
BOOL CPhoneBook::FixUpFromRealloc(PACCESSENTRY paeOld, PACCESSENTRY paeNew)
|
|
{
|
|
BOOL bRC = FALSE;
|
|
LONG_PTR lDiff = 0;
|
|
DWORD idx = 0;
|
|
|
|
//
|
|
// No starting value or no move, therefore no fix-ups needed
|
|
//
|
|
if ((0 == paeOld) || (paeNew == paeOld))
|
|
{
|
|
bRC = TRUE;
|
|
goto FixUpFromReallocExit;
|
|
}
|
|
|
|
Assert(paeNew);
|
|
Assert(((LONG)paeOld) > 0); // if these address look like negative numbers
|
|
Assert(((LONG)paeNew) > 0); // I'm not sure the code would handle them
|
|
|
|
lDiff = (LONG_PTR)paeOld - (LONG_PTR)paeNew;
|
|
|
|
//
|
|
// fix up STATES
|
|
//
|
|
for (idx = 0; idx < m_cStates; idx++)
|
|
{
|
|
if (m_rgState[idx].paeFirst)
|
|
m_rgState[idx].paeFirst = (PACCESSENTRY )((LONG_PTR)m_rgState[idx].paeFirst - lDiff);
|
|
}
|
|
|
|
//
|
|
// fix up ID look up array
|
|
//
|
|
for (idx = 0; idx < m_pLineCountryList->dwNumCountries ; idx++)
|
|
{
|
|
if (m_rgIDLookUp[idx].pFirstAE)
|
|
m_rgIDLookUp[idx].pFirstAE = (PACCESSENTRY )((LONG_PTR)m_rgIDLookUp[idx].pFirstAE - lDiff);
|
|
}
|
|
|
|
bRC = TRUE;
|
|
FixUpFromReallocExit:
|
|
return bRC;
|
|
}
|
|
|
|
// ############################################################################
|
|
HRESULT CPhoneBook::Init(LPCTSTR pszISPCode)
|
|
{
|
|
LPLINECOUNTRYLIST pLineCountryTemp = NULL;
|
|
HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
DWORD dwLastState = 0;
|
|
DWORD dwLastCountry = 0;
|
|
DWORD dwSizeAllocated;
|
|
PACCESSENTRY pCurAccessEntry;
|
|
PACCESSENTRY pAETemp;
|
|
LPLINECOUNTRYENTRY pLCETemp;
|
|
DWORD idx;
|
|
LPTSTR pszTemp;
|
|
CCSVFile far *pcCSVFile=NULL;
|
|
LPSTATE ps,psLast; //faster to use pointers.
|
|
HGLOBAL hTemp = NULL;
|
|
|
|
|
|
/*#ifdef WIN16
|
|
|
|
m_pLineCountryList = (LPLINECOUNTRYLIST)GlobalAlloc(GPTR, sizeof(LINECOUNTRYLIST) + sizeof(LINECOUNTRYENTRY) + 10);
|
|
if (!m_pLineCountryList)
|
|
goto InitExit;
|
|
|
|
m_pLineCountryList->dwTotalSize = sizeof(LINECOUNTRYLIST) + sizeof(LINECOUNTRYENTRY) + 3;
|
|
m_pLineCountryList->dwNeededSize = m_pLineCountryList->dwUsedSize = m_pLineCountryList->dwTotalSize;
|
|
m_pLineCountryList->dwNumCountries = 1;
|
|
m_pLineCountryList->dwCountryListSize = sizeof(LINECOUNTRYENTRY);
|
|
m_pLineCountryList->dwCountryListOffset = sizeof(LINECOUNTRYLIST);
|
|
|
|
pLCETemp = (LPLINECOUNTRYENTRY)((DWORD) m_pLineCountryList + m_pLineCountryList->dwCountryListOffset);
|
|
pLCETemp->dwCountryID = 1;
|
|
pLCETemp->dwCountryCode = 1;
|
|
pLCETemp->dwNextCountryID = 0;
|
|
pLCETemp->dwCountryNameSize = 3;
|
|
pLCETemp->dwCountryNameOffset = sizeof(LINECOUNTRYLIST) + sizeof(LINECOUNTRYENTRY);
|
|
pLCETemp->dwSameAreaRuleSize = 0;
|
|
pLCETemp->dwSameAreaRuleOffset = 0;
|
|
pLCETemp->dwLongDistanceRuleSize = 0;
|
|
pLCETemp->dwLongDistanceRuleOffset = 0;
|
|
pLCETemp->dwInternationalRuleSize = 0;
|
|
pLCETemp->dwInternationalRuleOffset = 0;
|
|
lstrcpy ((LPTSTR)((DWORD)m_pLineCountryList + pLCETemp->dwCountryNameOffset), TEXT("USA"));
|
|
pszTemp = (LPTSTR)((DWORD)m_pLineCountryList + pLCETemp->dwCountryNameOffset);
|
|
|
|
#else // WIN16 */
|
|
|
|
// Get TAPI country list
|
|
m_pLineCountryList = (LPLINECOUNTRYLIST)GlobalAlloc(GPTR,sizeof(LINECOUNTRYLIST));
|
|
if (!m_pLineCountryList)
|
|
goto InitExit;
|
|
|
|
m_pLineCountryList->dwTotalSize = sizeof(LINECOUNTRYLIST);
|
|
|
|
#if defined(WIN16)
|
|
idx = (DWORD) IETapiGetCountry(0, m_pLineCountryList);
|
|
#else
|
|
idx = lineGetCountry(0,0x10003,m_pLineCountryList);
|
|
#endif
|
|
if (idx && idx != LINEERR_STRUCTURETOOSMALL)
|
|
goto InitExit;
|
|
|
|
Assert(m_pLineCountryList->dwNeededSize);
|
|
|
|
pLineCountryTemp = (LPLINECOUNTRYLIST)GlobalAlloc(GPTR,
|
|
(size_t)m_pLineCountryList->dwNeededSize);
|
|
if (!pLineCountryTemp)
|
|
goto InitExit;
|
|
|
|
pLineCountryTemp->dwTotalSize = m_pLineCountryList->dwNeededSize;
|
|
GlobalFree(m_pLineCountryList);
|
|
|
|
m_pLineCountryList = pLineCountryTemp;
|
|
pLineCountryTemp = NULL;
|
|
|
|
#if defined(WIN16)
|
|
if (IETapiGetCountry(0, m_pLineCountryList))
|
|
#else
|
|
if (lineGetCountry(0,0x10003,m_pLineCountryList))
|
|
#endif
|
|
goto InitExit;
|
|
|
|
//#endif // WIN16
|
|
|
|
// Load Look Up arrays
|
|
#ifdef DEBUG
|
|
m_rgIDLookUp = (LPIDLOOKUPELEMENT)GlobalAlloc(GPTR,
|
|
(int)(sizeof(IDLOOKUPELEMENT)*m_pLineCountryList->dwNumCountries+5));
|
|
#else
|
|
m_rgIDLookUp = (LPIDLOOKUPELEMENT)GlobalAlloc(GPTR,
|
|
(int)(sizeof(IDLOOKUPELEMENT)*m_pLineCountryList->dwNumCountries));
|
|
#endif
|
|
if (!m_rgIDLookUp) goto InitExit;
|
|
|
|
pLCETemp = (LPLINECOUNTRYENTRY)((DWORD_PTR)m_pLineCountryList +
|
|
m_pLineCountryList->dwCountryListOffset);
|
|
|
|
for (idx=0;idx<m_pLineCountryList->dwNumCountries;idx++)
|
|
{
|
|
m_rgIDLookUp[idx].dwID = pLCETemp[idx].dwCountryID;
|
|
m_rgIDLookUp[idx].pLCE = &pLCETemp[idx];
|
|
}
|
|
|
|
qsort(m_rgIDLookUp,(int)m_pLineCountryList->dwNumCountries,sizeof(IDLOOKUPELEMENT),
|
|
CompareIDLookUpElements);
|
|
|
|
m_rgNameLookUp = (LPCNTRYNAMELOOKUPELEMENT)GlobalAlloc(GPTR,
|
|
(int)(sizeof(CNTRYNAMELOOKUPELEMENT) * m_pLineCountryList->dwNumCountries));
|
|
|
|
if (!m_rgNameLookUp) goto InitExit;
|
|
|
|
for (idx=0;idx<m_pLineCountryList->dwNumCountries;idx++)
|
|
{
|
|
m_rgNameLookUp[idx].psCountryName = (LPTSTR)((LPBYTE)m_pLineCountryList + (DWORD)pLCETemp[idx].dwCountryNameOffset);
|
|
m_rgNameLookUp[idx].dwNameSize = pLCETemp[idx].dwCountryNameSize;
|
|
m_rgNameLookUp[idx].pLCE = &pLCETemp[idx];
|
|
}
|
|
|
|
qsort(m_rgNameLookUp,(int)m_pLineCountryList->dwNumCountries,sizeof(CNTRYNAMELOOKUPELEMENT),
|
|
CompareCntryNameLookUpElements);
|
|
|
|
// Load States
|
|
if (!SearchPath(NULL,STATE_FILENAME,NULL,TEMP_BUFFER_LENGTH,szTempBuffer,&pszTemp))
|
|
{
|
|
AssertMsg(0,"STATE.ICW not found");
|
|
hr = ERROR_FILE_NOT_FOUND;
|
|
goto InitExit;
|
|
}
|
|
|
|
pcCSVFile = new CCSVFile;
|
|
if (!pcCSVFile) goto InitExit;
|
|
|
|
if (!pcCSVFile->Open(szTempBuffer))
|
|
{
|
|
AssertMsg(0,"Can not open STATE.ICW");
|
|
delete pcCSVFile;
|
|
pcCSVFile = NULL;
|
|
goto InitExit;
|
|
}
|
|
|
|
// first token in state file is the number of states
|
|
if (!pcCSVFile->ReadToken(szTempBuffer,TEMP_BUFFER_LENGTH))
|
|
goto InitExit;
|
|
|
|
if (!FSz2Dw(szTempBuffer,&m_cStates))
|
|
{
|
|
AssertMsg(0,"STATE.ICW count is invalid");
|
|
goto InitExit;
|
|
}
|
|
|
|
m_rgState = (LPSTATE)GlobalAlloc(GPTR,(int)(sizeof(STATE)*m_cStates));
|
|
if (!m_rgState)
|
|
goto InitExit;
|
|
|
|
for (ps = m_rgState, psLast = &m_rgState[m_cStates - 1]; ps <= psLast;++ps)
|
|
{
|
|
pcCSVFile->ReadToken(ps->szStateName,cbStateName);
|
|
}
|
|
|
|
pcCSVFile->Close();
|
|
|
|
// Locate ISP's INF file
|
|
if (!SearchPath(NULL,(LPCTSTR) pszISPCode,INF_SUFFIX,MAX_PATH,
|
|
m_szINFFile,&pszTemp))
|
|
{
|
|
wsprintf(szTempBuffer,TEXT("Can not find:%s%s (%d)"),pszISPCode,INF_SUFFIX,GetLastError());
|
|
AssertMsg(0,szTempBuffer);
|
|
hr = ERROR_FILE_NOT_FOUND;
|
|
goto InitExit;
|
|
}
|
|
|
|
//Load Phone Book
|
|
if (!GetPrivateProfileString(INF_APP_NAME,INF_PHONE_BOOK,INF_DEFAULT,
|
|
szTempBuffer,TEMP_BUFFER_LENGTH,m_szINFFile))
|
|
{
|
|
AssertMsg(0,"PhoneBookFile not specified in INF file");
|
|
hr = ERROR_FILE_NOT_FOUND;
|
|
goto InitExit;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (!lstrcmp(szTempBuffer,INF_DEFAULT))
|
|
{
|
|
wsprintf(szTempBuffer, TEXT("%s value not found in ISP file"), INF_PHONE_BOOK);
|
|
AssertMsg(0,szTempBuffer);
|
|
}
|
|
#endif
|
|
|
|
|
|
if (!SearchPath(NULL,szTempBuffer,NULL,MAX_PATH,m_szPhoneBook,&pszTemp))
|
|
{
|
|
AssertMsg(0,"ISP phone book not found");
|
|
hr = ERROR_FILE_NOT_FOUND;
|
|
goto InitExit;
|
|
}
|
|
|
|
if (!pcCSVFile->Open(m_szPhoneBook))
|
|
{
|
|
AssertMsg(0,"Can not open phone book");
|
|
hr = GetLastError();
|
|
goto InitExit;
|
|
}
|
|
|
|
dwSizeAllocated = 0;
|
|
do {
|
|
Assert (dwSizeAllocated >= m_cPhoneBookEntries);
|
|
// check that sufficient memory is allocated
|
|
if (m_rgPhoneBookEntry)
|
|
{
|
|
if (dwSizeAllocated == m_cPhoneBookEntries)
|
|
{
|
|
//
|
|
// we need more memory
|
|
//
|
|
// AssertMsg(0,"Out of memory originally allocated for phone book.\r\n");
|
|
// goto InitExit;
|
|
|
|
pAETemp = m_rgPhoneBookEntry;
|
|
#ifdef WIN16
|
|
dwSizeAllocated += PHONE_ENTRY_ALLOC_SIZE;
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)GlobalReAlloc(m_rgPhoneBookEntry,
|
|
(int)(dwSizeAllocated * sizeof(ACCESSENTRY)),GHND);
|
|
if (NULL == m_rgPhoneBookEntry)
|
|
goto InitExit;
|
|
#else
|
|
|
|
// UNLOCK
|
|
Assert(m_hPhoneBookEntry);
|
|
if (FALSE == GlobalUnlock(m_hPhoneBookEntry))
|
|
{
|
|
if (NO_ERROR != GetLastError())
|
|
goto InitExit;
|
|
}
|
|
|
|
// REALLOC
|
|
dwSizeAllocated += PHONE_ENTRY_ALLOC_SIZE;
|
|
hTemp = m_hPhoneBookEntry;
|
|
m_hPhoneBookEntry = GlobalReAlloc(hTemp,
|
|
(int)(dwSizeAllocated * sizeof(ACCESSENTRY)),GHND);
|
|
if (NULL == m_hPhoneBookEntry)
|
|
{
|
|
GlobalFree(hTemp);
|
|
goto InitExit;
|
|
}
|
|
else
|
|
{
|
|
hTemp = NULL;
|
|
}
|
|
|
|
// LOCK
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
|
|
if (NULL == m_rgPhoneBookEntry)
|
|
goto InitExit;
|
|
|
|
#endif
|
|
FixUpFromRealloc(pAETemp, m_rgPhoneBookEntry);
|
|
TraceMsg(TF_GENERAL, "Grow phone book to %d entries\n",dwSizeAllocated);
|
|
pCurAccessEntry = (PACCESSENTRY)((LONG_PTR)pCurAccessEntry -
|
|
((LONG_PTR)pAETemp - (LONG_PTR)(m_rgPhoneBookEntry)));
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Initialization for the first time through
|
|
//
|
|
|
|
// ALLOC
|
|
#ifdef WIN16
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)GlobalAlloc(GHND,sizeof(ACCESSENTRY) * PHONE_ENTRY_ALLOC_SIZE);
|
|
if(NULL == m_rgPhoneBookEntry)
|
|
goto InitExit;
|
|
#else
|
|
m_hPhoneBookEntry = GlobalAlloc(GHND,sizeof(ACCESSENTRY) * PHONE_ENTRY_ALLOC_SIZE);
|
|
if(NULL == m_hPhoneBookEntry)
|
|
goto InitExit;
|
|
|
|
// LOCK
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
|
|
if(NULL == m_rgPhoneBookEntry)
|
|
goto InitExit;
|
|
#endif
|
|
dwSizeAllocated = PHONE_ENTRY_ALLOC_SIZE;
|
|
pCurAccessEntry = m_rgPhoneBookEntry;
|
|
}
|
|
|
|
// Read a line from the phonebook
|
|
hr = ReadOneLine(pCurAccessEntry,pcCSVFile);
|
|
if (hr == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
break;
|
|
}
|
|
else if (hr != ERROR_SUCCESS)
|
|
{
|
|
goto InitExit;
|
|
}
|
|
|
|
hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
// Check to see if this is the first phone number for a given country
|
|
if (pCurAccessEntry->dwCountryID != dwLastCountry)
|
|
{
|
|
LPIDLOOKUPELEMENT lpIDLookupElement;
|
|
// NOTE: Not sure about the first parameter here.
|
|
lpIDLookupElement = (LPIDLOOKUPELEMENT)bsearch(&pCurAccessEntry->dwCountryID,
|
|
m_rgIDLookUp,(int)m_pLineCountryList->dwNumCountries,sizeof(IDLOOKUPELEMENT),
|
|
CompareIDLookUpElements);
|
|
if (!lpIDLookupElement)
|
|
{
|
|
// bad country ID, but we can't assert here
|
|
TraceMsg(TF_GENERAL,"Bad country ID in phone book %d\n",pCurAccessEntry->dwCountryID);
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
// for a given country ID this is the first phone number
|
|
lpIDLookupElement->pFirstAE = pCurAccessEntry;
|
|
dwLastCountry = pCurAccessEntry->dwCountryID;
|
|
}
|
|
}
|
|
|
|
// Check to see if this is the first phone number for a given state
|
|
if (pCurAccessEntry->wStateID && (pCurAccessEntry->wStateID != dwLastState))
|
|
{
|
|
idx = pCurAccessEntry->wStateID - 1;
|
|
m_rgState[idx].dwCountryID = pCurAccessEntry->dwCountryID;
|
|
m_rgState[idx].paeFirst = pCurAccessEntry;
|
|
dwLastState = pCurAccessEntry->wStateID;
|
|
}
|
|
|
|
pCurAccessEntry++;
|
|
m_cPhoneBookEntries++;
|
|
} while (TRUE);
|
|
|
|
// Trim the phone book for unused memory
|
|
Assert(m_rgPhoneBookEntry && m_cPhoneBookEntries);
|
|
|
|
pAETemp = m_rgPhoneBookEntry;
|
|
|
|
#ifdef WIN16
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)GlobalReAlloc(m_rgPhoneBookEntry,(int)(m_cPhoneBookEntries * sizeof(ACCESSENTRY)),GHND);
|
|
if (!m_rgPhoneBookEntry) goto InitExit;
|
|
#else
|
|
|
|
// UNLOCK
|
|
Assert(m_hPhoneBookEntry);
|
|
if (FALSE != GlobalUnlock(m_hPhoneBookEntry))
|
|
{
|
|
if (NO_ERROR != GetLastError())
|
|
goto InitExit;
|
|
}
|
|
|
|
// REALLOC
|
|
hTemp = m_hPhoneBookEntry;
|
|
m_hPhoneBookEntry = GlobalReAlloc(hTemp,(int)(m_cPhoneBookEntries * sizeof(ACCESSENTRY)),GHND);
|
|
if (NULL == m_hPhoneBookEntry)
|
|
{
|
|
GlobalFree(hTemp);
|
|
goto InitExit;
|
|
}
|
|
else
|
|
{
|
|
hTemp = NULL;
|
|
}
|
|
|
|
// LOCK
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
|
|
if (NULL == m_rgPhoneBookEntry)
|
|
goto InitExit;
|
|
#endif
|
|
FixUpFromRealloc(pAETemp, m_rgPhoneBookEntry);
|
|
|
|
hr = ERROR_SUCCESS;
|
|
InitExit:
|
|
// If something failed release everything
|
|
if (hr != ERROR_SUCCESS)
|
|
{
|
|
#ifdef WIN16
|
|
GlobalFree(m_rgPhoneBookEntry);
|
|
#else
|
|
GlobalUnlock(m_hPhoneBookEntry);
|
|
GlobalFree(m_hPhoneBookEntry);
|
|
#endif
|
|
GlobalFree(m_pLineCountryList);
|
|
GlobalFree(m_rgIDLookUp);
|
|
GlobalFree(m_rgNameLookUp);
|
|
GlobalFree(m_rgState);
|
|
|
|
m_cPhoneBookEntries = 0 ;
|
|
m_cStates = 0;
|
|
|
|
m_pLineCountryList = NULL;
|
|
m_rgPhoneBookEntry = NULL;
|
|
m_hPhoneBookEntry = NULL;
|
|
m_rgIDLookUp=NULL;
|
|
m_rgNameLookUp=NULL;
|
|
m_rgState=NULL;
|
|
}
|
|
|
|
if (pcCSVFile)
|
|
{
|
|
pcCSVFile->Close();
|
|
delete pcCSVFile;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// ############################################################################
|
|
HRESULT CPhoneBook::Merge(LPCTSTR pszChangeFile)
|
|
{
|
|
CCSVFile far *pcCSVFile;
|
|
ACCESSENTRY aeChange;
|
|
LPIDXLOOKUPELEMENT rgIdxLookUp;
|
|
LPIDXLOOKUPELEMENT pCurIdxLookUp;
|
|
DWORD dwAllocated;
|
|
DWORD dwUsed;
|
|
DWORD dwOriginalSize;
|
|
HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
DWORD dwIdx;
|
|
#if !defined(WIN16)
|
|
HANDLE hTemp;
|
|
HANDLE hIdxLookUp;
|
|
#else
|
|
// Normandy 11746
|
|
LPVOID rgTemp; // 16-bit only
|
|
#endif
|
|
DWORD cch, cchWritten;
|
|
HANDLE hFile;
|
|
|
|
// Pad the phonebook for new entries.
|
|
dwAllocated = m_cPhoneBookEntries + CHANGE_BUFFER_SIZE;
|
|
#ifdef WIN16
|
|
Assert(m_rgPhoneBookEntry);
|
|
rgTemp = GlobalReAlloc(m_rgPhoneBookEntry, (int)(sizeof(ACCESSENTRY) * dwAllocated),GHND);
|
|
Assert(rgTemp);
|
|
if (!rgTemp) goto MergeExit;
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)rgTemp;
|
|
#else
|
|
Assert(m_hPhoneBookEntry);
|
|
GlobalUnlock(m_hPhoneBookEntry);
|
|
hTemp = (HANDLE)GlobalReAlloc(m_hPhoneBookEntry, sizeof(ACCESSENTRY) * dwAllocated,GHND);
|
|
Assert(hTemp);
|
|
if (!hTemp)
|
|
goto MergeExit;
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
|
|
if (!m_rgPhoneBookEntry)
|
|
goto MergeExit;
|
|
#endif
|
|
|
|
// Create index to loaded phone book, sorted by index
|
|
#ifdef WIN16
|
|
rgIdxLookUp = (LPIDXLOOKUPELEMENT)GlobalAlloc(GHND,(int)(sizeof(IDXLOOKUPELEMENT) * dwAllocated));
|
|
#else
|
|
hIdxLookUp = (HANDLE)GlobalAlloc(GHND,sizeof(IDXLOOKUPELEMENT) * dwAllocated);
|
|
rgIdxLookUp = (LPIDXLOOKUPELEMENT)GlobalLock(hIdxLookUp);
|
|
#endif
|
|
Assert(rgIdxLookUp);
|
|
if (!rgIdxLookUp)
|
|
goto MergeExit;
|
|
|
|
for (dwIdx = 0; dwIdx < m_cPhoneBookEntries; dwIdx++)
|
|
{
|
|
rgIdxLookUp[dwIdx].dwIndex = rgIdxLookUp[dwIdx].pAE->dwIndex;
|
|
rgIdxLookUp[dwIdx].pAE = &m_rgPhoneBookEntry[dwIdx];
|
|
}
|
|
dwUsed = m_cPhoneBookEntries;
|
|
dwOriginalSize = m_cPhoneBookEntries;
|
|
|
|
qsort(rgIdxLookUp,(int)dwOriginalSize,sizeof(IDXLOOKUPELEMENT),CompareIdxLookUpElements);
|
|
|
|
// Load changes to phone book
|
|
pcCSVFile = new CCSVFile;
|
|
Assert(pcCSVFile);
|
|
if (!pcCSVFile)
|
|
goto MergeExit;
|
|
if (!pcCSVFile->Open(pszChangeFile))
|
|
goto MergeExit;
|
|
|
|
do {
|
|
|
|
// Read a change record
|
|
ZeroMemory(&aeChange,sizeof(ACCESSENTRY));
|
|
hr = ReadOneLine(&aeChange, pcCSVFile);
|
|
|
|
if(hr == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
break; // no more enteries
|
|
}
|
|
else if (hr != ERROR_SUCCESS)
|
|
{
|
|
goto MergeExit;
|
|
}
|
|
|
|
hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
/* if (!ReadPhoneBookDW(&aeChange.dwIndex,pcCSVFile))
|
|
break; // no more enteries
|
|
ReadVerifyPhoneBookDW(aeChange.dwCountryID);
|
|
ReadVerifyPhoneBookW(aeChange.wStateID);
|
|
ReadVerifyPhoneBookSZ(aeChange.szCity,cbCity);
|
|
ReadVerifyPhoneBookSZ(aeChange.szAreaCode,cbAreaCode);
|
|
// NOTE: 0 is a valid area code and ,, is a valid entry for an area code
|
|
if (!FSz2Dw(aeChange.szAreaCode,&aeChange.dwAreaCode))
|
|
aeChange.dwAreaCode = NO_AREA_CODE;
|
|
ReadVerifyPhoneBookSZ(aeChange.szAccessNumber,cbAccessNumber);
|
|
ReadVerifyPhoneBookDW(aeChange.dwConnectSpeedMin);
|
|
ReadVerifyPhoneBookDW(aeChange.dwConnectSpeedMax);
|
|
ReadVerifyPhoneBookB(aeChange.bFlipFactor);
|
|
ReadVerifyPhoneBookB(aeChange.fType);
|
|
ReadVerifyPhoneBookSZ(aeChange.szDataCenter,cbDataCenter);
|
|
*/
|
|
|
|
// Determine if this is a delete or add record
|
|
if (aeChange.szAccessNumber[0] == '0' && aeChange.szAccessNumber[1] == '\0')
|
|
{
|
|
// This is a delete record, find matching record
|
|
// NOTE: we only search the numbers that existed before the change file,
|
|
// because they are the only ones that are sorted.
|
|
pCurIdxLookUp = (LPIDXLOOKUPELEMENT)bsearch(&aeChange,rgIdxLookUp,(int)dwOriginalSize,
|
|
sizeof(IDXLOOKUPELEMENT),CompareIdxLookUpElements);
|
|
AssertMsg(pCurIdxLookUp,"Attempting to delete a record that does not exist. The change file and phone book versions do not match.");
|
|
if (pCurIdxLookUp)
|
|
pCurIdxLookUp->pAE = NULL; //Create a dead entry in the look up table
|
|
m_cPhoneBookEntries--;
|
|
}
|
|
else
|
|
{
|
|
// This is an add entry
|
|
m_cPhoneBookEntries++;
|
|
dwUsed++;
|
|
// Make sure we have enough room
|
|
if (m_cPhoneBookEntries > dwAllocated)
|
|
{
|
|
// Grow phone book
|
|
dwAllocated += CHANGE_BUFFER_SIZE;
|
|
#ifdef WIN16
|
|
Assert(m_rgPhoneBookEntry);
|
|
rgTemp = GlobalReAlloc(m_rgPhoneBookEntry,(int)(sizeof(ACCESSENTRY)*dwAllocated),GHND);
|
|
Assert(rgTemp);
|
|
if (!rgTemp)
|
|
goto MergeExit;
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)rgTemp;
|
|
|
|
// Grow look up index
|
|
Assert(rgIdxLookUp);
|
|
rgTemp = GlobalReAlloc(rgIdxLookUp,(int)(sizeof(IDXLOOKUPELEMENT)*dwAllocated),GHND);
|
|
Assert(rgTemp);
|
|
if (!rgTemp)
|
|
goto MergeExit;
|
|
rgIdxLookUp = (LPIDXLOOKUPELEMENT)rgTemp;
|
|
#else
|
|
Assert(m_hPhoneBookEntry);
|
|
GlobalUnlock(m_hPhoneBookEntry);
|
|
hTemp = (HANDLE)GlobalReAlloc(m_hPhoneBookEntry,sizeof(ACCESSENTRY)*dwAllocated,GHND);
|
|
Assert(hTemp);
|
|
if (!hTemp)
|
|
goto MergeExit;
|
|
m_hPhoneBookEntry = hTemp;
|
|
m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
|
|
Assert(m_rgPhoneBookEntry);
|
|
if (!m_rgPhoneBookEntry)
|
|
goto MergeExit;
|
|
|
|
// Grow look up index
|
|
Assert(hIdxLookUp);
|
|
GlobalUnlock(hIdxLookUp);
|
|
hTemp = (HANDLE)GlobalReAlloc(hIdxLookUp,sizeof(IDXLOOKUPELEMENT)*dwAllocated,GHND);
|
|
Assert(hTemp);
|
|
if (!hTemp)
|
|
goto MergeExit;
|
|
hIdxLookUp = hTemp;
|
|
rgIdxLookUp = (LPIDXLOOKUPELEMENT)GlobalLock(hIdxLookUp);
|
|
Assert(rgIdxLookUp);
|
|
if (!rgIdxLookUp)
|
|
goto MergeExit;
|
|
#endif
|
|
}
|
|
|
|
//Add entry to the end of the phonebook and to end of look up index
|
|
CopyMemory(&m_rgPhoneBookEntry[m_cPhoneBookEntries],&aeChange,sizeof(ACCESSENTRY));
|
|
rgIdxLookUp[m_cPhoneBookEntries].dwIndex = m_rgPhoneBookEntry[m_cPhoneBookEntries].dwIndex;
|
|
rgIdxLookUp[m_cPhoneBookEntries].pAE = &m_rgPhoneBookEntry[m_cPhoneBookEntries];
|
|
// NOTE: because the entry is added to the end of the list, we can't add
|
|
// and delete entries in the same change file.
|
|
}
|
|
} while (TRUE);
|
|
|
|
// resort the IDXLookUp index to reflect the correct order of enteries
|
|
// for the phonebook file, including all of the entries to be deleted.
|
|
qsort(rgIdxLookUp,(int)dwUsed,sizeof(IDXLOOKUPELEMENT),CompareIdxLookUpElementsFileOrder);
|
|
|
|
// Build a new phonebook file
|
|
#ifdef WIN16
|
|
GetTempFileName(0, TEMP_PHONE_BOOK_PREFIX, 0, szTempFileName);
|
|
#else
|
|
if (!GetTempPath(TEMP_BUFFER_LENGTH,szTempBuffer))
|
|
goto MergeExit;
|
|
if (!GetTempFileName(szTempBuffer,TEMP_PHONE_BOOK_PREFIX,0,szTempFileName))
|
|
goto MergeExit;
|
|
#endif
|
|
hFile = CreateFile(szTempFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
|
|
FILE_FLAG_WRITE_THROUGH,0);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
goto MergeExit;
|
|
|
|
for (dwIdx = 0; dwIdx < m_cPhoneBookEntries; dwIdx++)
|
|
{
|
|
cch = wsprintf(szTempBuffer, TEXT("%lu,%lu,%lu,%s,%s,%s,%lu,%lu,%lu,%lu,%s\r\n"),
|
|
rgIdxLookUp[dwIdx].pAE->dwIndex,
|
|
rgIdxLookUp[dwIdx].pAE->dwCountryID,
|
|
DWORD(rgIdxLookUp[dwIdx].pAE->wStateID),
|
|
rgIdxLookUp[dwIdx].pAE->szCity,
|
|
rgIdxLookUp[dwIdx].pAE->szAreaCode,
|
|
rgIdxLookUp[dwIdx].pAE->szAccessNumber,
|
|
rgIdxLookUp[dwIdx].pAE->dwConnectSpeedMin,
|
|
rgIdxLookUp[dwIdx].pAE->dwConnectSpeedMax,
|
|
DWORD(rgIdxLookUp[dwIdx].pAE->bFlipFactor),
|
|
DWORD(rgIdxLookUp[dwIdx].pAE->fType),
|
|
rgIdxLookUp[dwIdx].pAE->szDataCenter);
|
|
|
|
if (!WriteFile(hFile,szTempBuffer,cch,&cchWritten,NULL))
|
|
{
|
|
// something went wrong, get rid of the temporary file
|
|
CloseHandle(hFile);
|
|
DeleteFile(szTempFileName);
|
|
hr = GetLastError();
|
|
goto MergeExit;
|
|
}
|
|
|
|
Assert(cch == cchWritten);
|
|
}
|
|
CloseHandle(hFile);
|
|
hFile = NULL;
|
|
|
|
// Move new phone book over old
|
|
if (!MoveFileEx(szTempFileName,m_szPhoneBook,MOVEFILE_REPLACE_EXISTING))
|
|
{
|
|
hr = GetLastError();
|
|
goto MergeExit;
|
|
}
|
|
|
|
// discard the phonebook in memory
|
|
#ifndef WIN16
|
|
Assert(m_hPhoneBookEntry);
|
|
GlobalUnlock(m_hPhoneBookEntry);
|
|
#endif
|
|
m_rgPhoneBookEntry = NULL;
|
|
m_cPhoneBookEntries = 0;
|
|
GlobalFree(m_pLineCountryList);
|
|
GlobalFree(m_rgIDLookUp);
|
|
GlobalFree(m_rgNameLookUp);
|
|
GlobalFree(m_rgState);
|
|
m_cStates = 0;
|
|
|
|
lstrcpy(szTempBuffer,m_szINFCode);
|
|
m_szINFFile[0] = '\0';
|
|
m_szPhoneBook[0] = '\0';
|
|
m_szINFCode[0] = '\0';
|
|
|
|
// Reload it (and rebuild look up arrays)
|
|
hr = Init(szTempBuffer);
|
|
|
|
MergeExit:
|
|
if (hr != ERROR_SUCCESS)
|
|
{
|
|
GlobalFree(rgIdxLookUp);
|
|
if (pcCSVFile) delete pcCSVFile;
|
|
CloseHandle(hFile);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// ############################################################################
|
|
HRESULT CPhoneBook::ReadOneLine(PACCESSENTRY lpAccessEntry, CCSVFile far *pcCSVFile)
|
|
{
|
|
HRESULT hr = ERROR_SUCCESS;
|
|
|
|
#if !defined(WIN16)
|
|
ReadOneLineStart:
|
|
#endif //WIN16
|
|
if (!ReadPhoneBookDW(&lpAccessEntry->dwIndex,pcCSVFile))
|
|
{
|
|
hr = ERROR_NO_MORE_ITEMS; // no more enteries
|
|
goto ReadExit;
|
|
}
|
|
ReadVerifyPhoneBookDW(lpAccessEntry->dwCountryID);
|
|
ReadVerifyPhoneBookW(lpAccessEntry->wStateID);
|
|
ReadVerifyPhoneBookSZ(lpAccessEntry->szCity,cbCity);
|
|
ReadVerifyPhoneBookSZ(lpAccessEntry->szAreaCode,cbAreaCode);
|
|
// NOTE: 0 is a valid area code and ,, is a valid entry for an area code
|
|
if (!FSz2Dw(lpAccessEntry->szAreaCode,&lpAccessEntry->dwAreaCode))
|
|
lpAccessEntry->dwAreaCode = NO_AREA_CODE;
|
|
ReadVerifyPhoneBookSZ(lpAccessEntry->szAccessNumber,cbAccessNumber);
|
|
ReadVerifyPhoneBookDW(lpAccessEntry->dwConnectSpeedMin);
|
|
ReadVerifyPhoneBookDW(lpAccessEntry->dwConnectSpeedMax);
|
|
ReadVerifyPhoneBookB(lpAccessEntry->bFlipFactor);
|
|
ReadVerifyPhoneBookDW(lpAccessEntry->fType);
|
|
ReadVerifyPhoneBookSZ(lpAccessEntry->szDataCenter,cbDataCenter);
|
|
|
|
switch (lpAccessEntry->bFlipFactor)
|
|
{
|
|
case BOTH_ISDN_ANALOG:
|
|
// This phone number supports both ISDN or Analog, return true
|
|
// We want analog numbers, check the FlipFactor for zero
|
|
lpAccessEntry->fType |= MASK_ISDN_BIT | MASK_ANALOG_BIT;
|
|
break;
|
|
case ANALOG_TYPE:
|
|
// Analog only
|
|
lpAccessEntry->fType |= MASK_ANALOG_BIT;
|
|
break;
|
|
case ISDN_TYPE:
|
|
// We only want ISDN numbers
|
|
lpAccessEntry->fType |= MASK_ISDN_BIT;
|
|
break;
|
|
}
|
|
#if !defined(WIN16)
|
|
//
|
|
// If scripting is not available and the phonebook entry has a dun file other than
|
|
// icwip.dun, then ignore the entry and read the one after that.
|
|
//
|
|
if (!m_bScriptingAvailable)
|
|
{
|
|
if (0 != lstrcmpi(lpAccessEntry->szDataCenter,TEXT("icwip.dun")))
|
|
{
|
|
ZeroMemory(lpAccessEntry,sizeof(ACCESSENTRY));
|
|
goto ReadOneLineStart;
|
|
}
|
|
}
|
|
#endif //WIN16
|
|
|
|
ReadExit:
|
|
return hr;
|
|
ReadError:
|
|
hr = ERROR_INVALID_DATA;
|
|
goto ReadExit;
|
|
}
|
|
|
|
// ############################################################################
|
|
HRESULT CPhoneBook::Suggest(PSUGGESTINFO pSuggest)
|
|
{
|
|
WORD wNumFound = 0;
|
|
HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
// char szFileName[MAX_PATH];
|
|
// char *pszTemp;
|
|
// HANDLE hFile=NULL;
|
|
// HANDLE hMap=NULL;
|
|
// DWORD dwSize;
|
|
// LPNPABLOCK rg950Data = NULL;
|
|
// NPABLOCK *p950Data;
|
|
|
|
|
|
// Validate parameters
|
|
Assert(pSuggest);
|
|
Assert(pSuggest->wNumber);
|
|
|
|
if (wNumFound == pSuggest->wNumber)
|
|
goto SuggestExit;
|
|
|
|
LPIDLOOKUPELEMENT pCurLookUp;
|
|
PACCESSENTRY lpAccessEntry;
|
|
|
|
//REVIEW: double check this
|
|
pCurLookUp = (LPIDLOOKUPELEMENT)bsearch(&pSuggest->dwCountryID,m_rgIDLookUp,
|
|
(int)m_pLineCountryList->dwNumCountries,sizeof(IDLOOKUPELEMENT),
|
|
CompareIDLookUpElements);
|
|
|
|
// Check for invalid country
|
|
if (!pCurLookUp)
|
|
goto SuggestExit;
|
|
|
|
// Check if there are any phone numbers for this country
|
|
if (!pCurLookUp->pFirstAE) goto SuggestExit;
|
|
|
|
lpAccessEntry = pCurLookUp->pFirstAE;
|
|
do {
|
|
// check for the right area code
|
|
if (lpAccessEntry->dwAreaCode == pSuggest->wAreaCode)
|
|
{
|
|
// check for the right type of number
|
|
if ((lpAccessEntry->fType & pSuggest->bMask) == pSuggest->fType)
|
|
{
|
|
pSuggest->rgpAccessEntry[wNumFound] = lpAccessEntry;
|
|
wNumFound++;
|
|
}
|
|
}
|
|
lpAccessEntry++;
|
|
} while ((lpAccessEntry <= &m_rgPhoneBookEntry[m_cPhoneBookEntries-1]) &&
|
|
(wNumFound < pSuggest->wNumber) &&
|
|
(lpAccessEntry->dwCountryID == pSuggest->dwCountryID));
|
|
|
|
|
|
|
|
//
|
|
// MKarki - Bug 340 no need to list more numbers if one already found
|
|
// in Area Code specified by user
|
|
//
|
|
// 5/24/97 jmazner Olympus #340 and #71
|
|
// nope, this is wrong. We always want to return as many applicable
|
|
// phone numbers as we find. Just because the area code matches
|
|
// doesn't mean that we've found an ideal phone number.
|
|
//if (wNumFound == 0)
|
|
//{
|
|
//
|
|
|
|
// if we couldn't find enough numnbers, try something else
|
|
//
|
|
|
|
// 10/15/96 jmazner ported fixes below from core\client\phbk
|
|
|
|
//
|
|
// Do this only if area code is not 0 - Bug #9349 (VetriV)
|
|
// if ((pSuggest->wAreaCode != 0) && (wNumFound < pSuggest->wNumber))
|
|
//
|
|
// No, there are some places (Finland? ChrisK knows) where 0 is a legit area code -- jmazner
|
|
|
|
if (wNumFound < pSuggest->wNumber)
|
|
{
|
|
lpAccessEntry = pCurLookUp->pFirstAE;
|
|
|
|
// Note: we are now only looking for Nationwide phone numbers (state = 0)
|
|
|
|
// 8/13/96 jmazner MOS Normandy #4597
|
|
// We want nationwide toll-free numbers to display last, so for this pass,
|
|
// only consider numbers that are _not_ toll free (fType bit #1 = 0)
|
|
//
|
|
// 5/24/97 jmazner Olympus #71
|
|
// As per GeoffR's spec, the search passes should not be based on
|
|
// the tollfree bit at all
|
|
//
|
|
// 5/28/97 jmazner Olympus #71
|
|
// ahem...as per GeoffR's new spec, we _should_ consider the tollfree
|
|
// bit and in this query only bring up toll free numbers.
|
|
//
|
|
// so, we will only return numbers whose area code match, or which are
|
|
// tollfree
|
|
//
|
|
|
|
//
|
|
// Tweak pSuggest->bMask to let through the toll/charge bit
|
|
//
|
|
pSuggest->bMask |= MASK_TOLLFREE_BIT;
|
|
|
|
// //Tweak pSuggest->ftype to be charge
|
|
//pSuggest->fType &= TYPE_SET_TOLL;
|
|
//
|
|
// make that tollfree!
|
|
pSuggest->fType |= TYPE_SET_TOLLFREE;
|
|
|
|
do {
|
|
|
|
// 8/13/96 jmazner MOS Normandy #4598
|
|
// If this entry's area code matches pSuggest->wAreaCode, then we already
|
|
// have included it in the previous pass, so don't duplicate it again here.
|
|
if ((lpAccessEntry->fType & pSuggest->bMask) == pSuggest->fType &&
|
|
lpAccessEntry->wStateID == 0 &&
|
|
lpAccessEntry->dwAreaCode != pSuggest->wAreaCode)
|
|
{
|
|
pSuggest->rgpAccessEntry[wNumFound] = lpAccessEntry;
|
|
wNumFound++;
|
|
}
|
|
lpAccessEntry++;
|
|
} while ((lpAccessEntry <= &m_rgPhoneBookEntry[m_cPhoneBookEntries-1]) &&
|
|
(wNumFound < pSuggest->wNumber) &&
|
|
(lpAccessEntry->dwCountryID == pSuggest->dwCountryID) &&
|
|
(lpAccessEntry->wStateID == 0) );
|
|
}
|
|
|
|
|
|
// 8/13/96 jmazner MOS Normandy #4597
|
|
// if we STILL couldn't find enough numnbers, widen the search to include tollfree #s
|
|
//
|
|
// 5/24/97 jmazner Olympus #71
|
|
// no need for this pass at all. See earlier comments.
|
|
|
|
/****
|
|
if (wNumFound < pSuggest->wNumber)
|
|
{
|
|
lpAccessEntry = pCurLookUp->pFirstAE;
|
|
|
|
// Tweak pSuggest->bMask to let through the toll/charge bit
|
|
// REDUNDANT? If we made it to this point, we _should_ have done this above...
|
|
// Better safe than sorry!
|
|
Assert(pSuggest->bMask & MASK_TOLLFREE_BIT);
|
|
pSuggest->bMask |= MASK_TOLLFREE_BIT;
|
|
|
|
// Tweak pSuggest->ftype to be tollfree
|
|
pSuggest->fType |= TYPE_SET_TOLLFREE;
|
|
|
|
do {
|
|
|
|
// 8/13/96 jmazner MOS Normandy #4598
|
|
// If this entry's area code matches pSuggest->wAreaCode, then we already
|
|
// have included it in the first pass, so don't include it here.
|
|
// Any entry that made it in in the 2nd pass will definitely not make it in here
|
|
// (because of tollfree bit), so no need to worry about dups from there.
|
|
if ((lpAccessEntry->fType & pSuggest->bMask) == pSuggest->fType &&
|
|
lpAccessEntry->wStateID == 0 &&
|
|
lpAccessEntry->dwAreaCode != pSuggest->wAreaCode)
|
|
{
|
|
pSuggest->rgpAccessEntry[wNumFound] = lpAccessEntry;
|
|
wNumFound++;
|
|
}
|
|
lpAccessEntry++;
|
|
} while ((lpAccessEntry <= &m_rgPhoneBookEntry[m_cPhoneBookEntries-1]) &&
|
|
(wNumFound < pSuggest->wNumber) &&
|
|
(lpAccessEntry->dwCountryID == pSuggest->dwCountryID) &&
|
|
(lpAccessEntry->wStateID == 0) );
|
|
}
|
|
****/
|
|
//} // End of If for Bug - 340 - MKarki
|
|
|
|
/*
|
|
// Flip factoring
|
|
if (wNumFound == 2)
|
|
{
|
|
SYSTEMTIME st;
|
|
GetSystemTime(&st);
|
|
srand((UINT)st.wMilliseconds);
|
|
if ((rand() % 10) > pSuggest->rgLPACCESSENTRY[0]->bFlipFactor)
|
|
{
|
|
lpAccessEntry = pSuggest->rgLPACCESSENTRY[0];
|
|
pSuggest->rgpAccessEntry[0] = pSuggest->rgpAccessEntry[1];
|
|
pSuggest->rgpAccessEntry[1] = lpAccessEntry;
|
|
}
|
|
}
|
|
*/
|
|
|
|
hr = ERROR_SUCCESS;
|
|
SuggestExit:
|
|
pSuggest->wNumber = wNumFound;
|
|
return hr;
|
|
}
|
|
|
|
// ############################################################################
|
|
HRESULT CPhoneBook::GetCanonical (PACCESSENTRY pAE, LPTSTR psOut)
|
|
{
|
|
HRESULT hr = ERROR_SUCCESS;
|
|
LPIDLOOKUPELEMENT pIDLookUp;
|
|
|
|
pIDLookUp = (LPIDLOOKUPELEMENT)bsearch(&pAE->dwCountryID,m_rgIDLookUp,
|
|
(int)m_pLineCountryList->dwNumCountries,sizeof(IDLOOKUPELEMENT),CompareIdxLookUpElements);
|
|
|
|
if (!pIDLookUp)
|
|
{
|
|
hr = ERROR_INVALID_PARAMETER;
|
|
} else {
|
|
SzCanonicalFromAE (psOut, pAE, pIDLookUp->pLCE);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ############################################################################
|
|
DllExportH PhoneBookLoad(LPCTSTR pszISPCode, DWORD_PTR far *pdwPhoneID)
|
|
{
|
|
HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
CPhoneBook far *pcPhoneBook;
|
|
|
|
if (!g_hInstDll)
|
|
g_hInstDll = GetModuleHandle(NULL);
|
|
|
|
// validate parameters
|
|
Assert(pszISPCode && *pszISPCode && pdwPhoneID);
|
|
*pdwPhoneID = NULL;
|
|
|
|
// allocate phone book
|
|
pcPhoneBook = new CPhoneBook;
|
|
|
|
// initialize phone book
|
|
if (pcPhoneBook)
|
|
hr = pcPhoneBook->Init(pszISPCode);
|
|
|
|
// in case of failure
|
|
if (hr && pcPhoneBook)
|
|
{
|
|
delete pcPhoneBook;
|
|
} else {
|
|
*pdwPhoneID = (DWORD_PTR)pcPhoneBook;
|
|
}
|
|
|
|
#if defined(WIN16)
|
|
if (!hr)
|
|
BMP_RegisterClass(g_hInstDll);
|
|
#endif
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ############################################################################
|
|
DllExportH PhoneBookUnload(DWORD_PTR dwPhoneID)
|
|
{
|
|
Assert(dwPhoneID);
|
|
|
|
if (dwPhoneID)
|
|
{
|
|
#if defined(WIN16)
|
|
BMP_DestroyClass(g_hInstDll);
|
|
#endif
|
|
// Release contents
|
|
delete (CPhoneBook far*)dwPhoneID;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
// ############################################################################
|
|
DllExportH PhoneBookMergeChanges(DWORD_PTR dwPhoneID, LPCTSTR pszChangeFile)
|
|
{
|
|
return ((CPhoneBook far*)dwPhoneID)->Merge(pszChangeFile);
|
|
}
|
|
|
|
// ############################################################################
|
|
DllExportH PhoneBookSuggestNumbers(DWORD_PTR dwPhoneID, PSUGGESTINFO lpSuggestInfo)
|
|
{
|
|
HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
// get suggested numbers
|
|
lpSuggestInfo->rgpAccessEntry = (PACCESSENTRY *)GlobalAlloc(GPTR,sizeof(PACCESSENTRY) * lpSuggestInfo->wNumber);
|
|
if (lpSuggestInfo->rgpAccessEntry)
|
|
{
|
|
hr = ((CPhoneBook far *)dwPhoneID)->Suggest(lpSuggestInfo);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ############################################################################
|
|
DllExportH PhoneBookGetCanonical (DWORD_PTR dwPhoneID, PACCESSENTRY pAE, LPTSTR psOut)
|
|
{
|
|
return ((CPhoneBook far*)dwPhoneID)->GetCanonical(pAE,psOut);
|
|
}
|
|
|
|
// ############################################################################
|
|
DllExportH PhoneBookDisplaySignUpNumbers (DWORD_PTR dwPhoneID,
|
|
LPTSTR far *ppszPhoneNumbers,
|
|
LPTSTR far *ppszDunFiles,
|
|
WORD far *pwPhoneNumbers,
|
|
DWORD far *pdwCountry,
|
|
WORD far *pwRegion,
|
|
BYTE fType,
|
|
BYTE bMask,
|
|
HWND hwndParent,
|
|
DWORD dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
AssertMsg(ppszPhoneNumbers && pwPhoneNumbers && pdwCountry &&pwRegion,"invalid parameters");
|
|
|
|
|
|
//CAccessNumDlg *pcDlg;
|
|
CSelectNumDlg far *pcDlg;
|
|
pcDlg = new CSelectNumDlg;
|
|
if (!pcDlg)
|
|
{
|
|
hr = GetLastError();
|
|
goto DisplayExit;
|
|
}
|
|
|
|
// Initialize information for dialog
|
|
//
|
|
|
|
pcDlg->m_dwPhoneBook = dwPhoneID;
|
|
pcDlg->m_dwCountryID = *pdwCountry;
|
|
pcDlg->m_wRegion = *pwRegion;
|
|
pcDlg->m_fType = fType;
|
|
pcDlg->m_bMask = bMask;
|
|
pcDlg->m_dwFlags = dwFlags;
|
|
|
|
// invoke the dialog
|
|
//
|
|
// BUG: NOT THREAD SAFE!!
|
|
g_hWndMain = hwndParent;
|
|
hr = (HRESULT)DialogBoxParam(g_hInstDll,MAKEINTRESOURCE(IDD_SELECTNUMBER),
|
|
g_hWndMain, PhbkGenericDlgProc,(LPARAM)pcDlg);
|
|
g_hWndMain = NULL;
|
|
|
|
if (hr == IDC_CMDNEXT)
|
|
{
|
|
*pwRegion = pcDlg->m_wRegion;
|
|
*pdwCountry = pcDlg->m_dwCountryID;
|
|
|
|
Assert (ppszPhoneNumbers[0] && ppszDunFiles[0]);
|
|
lstrcpy(ppszPhoneNumbers[0],&pcDlg->m_szPhoneNumber[0]);
|
|
lstrcpy(ppszDunFiles[0],&pcDlg->m_szDunFile[0]);
|
|
|
|
hr = ERROR_SUCCESS;
|
|
}
|
|
else if (hr == IDC_CMDBACK)
|
|
hr = ERROR_USERBACK;
|
|
else
|
|
hr = ERROR_USERCANCEL;
|
|
|
|
// hr == -1;
|
|
DisplayExit:
|
|
if (pcDlg) delete pcDlg;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//DllExportH TestBar()
|
|
//{
|
|
// LPCSTR pszISPCode;
|
|
// LPDWORD pdwPhoneID;
|
|
//
|
|
// HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
|
|
// CPhoneBook FAR *pcPhoneBook;
|
|
//
|
|
// if (!g_hInstDll)
|
|
// g_hInstDll = GetModuleHandle(NULL);
|
|
//
|
|
// // validate parameters
|
|
////1 Assert(pszISPCode && *pszISPCode && pdwPhoneID);
|
|
////1 *pdwPhoneID = NULL;
|
|
//
|
|
// // allocate phone book
|
|
////1 pcPhoneBook = new CPhoneBook;
|
|
//
|
|
// // initialize phone book
|
|
// if (pcPhoneBook)
|
|
// hr = pcPhoneBook->Init(pszISPCode);
|
|
//
|
|
// // in case of failure
|
|
// if (hr && pcPhoneBook)
|
|
// {
|
|
// delete pcPhoneBook;
|
|
// } else {
|
|
// *pdwPhoneID = (DWORD)pcPhoneBook;
|
|
// }
|
|
//
|
|
////2#if defined(WIN16)
|
|
////2 if (!hr)
|
|
////2 BMP_RegisterClass(g_hInstDll);
|
|
////2#endif
|
|
//
|
|
// return hr;
|
|
//}
|
|
//
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// API : GetSupportNumbers
|
|
//
|
|
// Synopsis: This is the API used to get the support
|
|
// numbers
|
|
//
|
|
// Returns: HRESULT - success or error info
|
|
//
|
|
// Arguments: [OUT] PSUPPORTNUM - array of SUPPORTNUM structs
|
|
// [IN/OUT] PDWORD - mem for buffersize
|
|
//
|
|
// Called By: by the EXE using the ICWPHBK.DLL
|
|
//
|
|
// History: MKarki Created 5/8/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
DllExportH GetSupportNumbers (
|
|
PSUPPORTNUM pBuffer,
|
|
PDWORD pBufferSize
|
|
)
|
|
{
|
|
return (GetSupportNumsFromFile (pBuffer, pBufferSize));
|
|
|
|
} // end of GetSupportNumbers API call
|