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.

1462 lines
47 KiB

  1. // ############################################################################
  2. // Phone book APIs
  3. #include "pch.hpp"
  4. #ifdef WIN16
  5. #include <win16def.h>
  6. #include <win32fn.h>
  7. #include <rasc.h>
  8. #include <raserr.h>
  9. #include <ietapi.h>
  10. extern "C" {
  11. #include "bmp.h"
  12. }
  13. #endif
  14. #include "phbk.h"
  15. #include "misc.h"
  16. #include "phbkrc.h"
  17. #include "suapi.h"
  18. //#define ReadVerifyPhoneBookDW(x) AssertMsg(ReadPhoneBookDW(&(x),pcCSVFile),"Invalid DWORD in phone book");
  19. #define ReadVerifyPhoneBookDW(x) if (!ReadPhoneBookDW(&(x),pcCSVFile)) \
  20. { AssertMsg(0,"Invalid DWORD in phone book"); \
  21. goto ReadError; }
  22. #define ReadVerifyPhoneBookW(x) if (!ReadPhoneBookW(&(x),pcCSVFile)) \
  23. { AssertMsg(0,"Invalid DWORD in phone book"); \
  24. goto ReadError; }
  25. #define ReadVerifyPhoneBookB(x) if (!ReadPhoneBookB(&(x),pcCSVFile)) \
  26. { AssertMsg(0,"Invalid DWORD in phone book"); \
  27. goto ReadError; }
  28. #define ReadVerifyPhoneBookSZ(x,y) if (!ReadPhoneBookSZ(&x[0],y+sizeof('\0'),pcCSVFile)) \
  29. { AssertMsg(0,"Invalid DWORD in phone book"); \
  30. goto ReadError; }
  31. #define CHANGE_BUFFER_SIZE 50
  32. #define TEMP_PHONE_BOOK_PREFIX TEXT("PBH")
  33. #define ERROR_USERBACK 32766
  34. #define ERROR_USERCANCEL 32767
  35. TCHAR szTempBuffer[TEMP_BUFFER_LENGTH];
  36. TCHAR szTempFileName[MAX_PATH];
  37. #ifdef __cplusplus
  38. extern "C" {
  39. #endif
  40. HWND g_hWndMain;
  41. #ifdef __cplusplus
  42. }
  43. #endif
  44. #if !defined(WIN16)
  45. //+----------------------------------------------------------------------------
  46. //
  47. // Function IsMSDUN12Installed
  48. //
  49. // Synopsis Check if MSDUN 1.2 or higher is installed
  50. //
  51. // Arguments none
  52. //
  53. // Returns TRUE - MSDUN 1.2 is installed
  54. //
  55. // History 5/28/97 ChrisK created for Olympus Bug 4392
  56. // 8/7/97 ChrisK lifted from isign32
  57. //
  58. //-----------------------------------------------------------------------------
  59. #define DUN_12_Version ((double)1.2)
  60. BOOL IsMSDUN12Installed()
  61. {
  62. TCHAR szBuffer[MAX_PATH] = {TEXT("\0")};
  63. HKEY hkey = NULL;
  64. BOOL bRC = FALSE;
  65. DWORD dwType = 0;
  66. DWORD dwSize = sizeof(szBuffer);
  67. FLOAT flVersion = 0e0f;
  68. if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
  69. TEXT("System\\CurrentControlSet\\Services\\RemoteAccess"),
  70. &hkey))
  71. {
  72. goto IsMSDUN12InstalledExit;
  73. }
  74. if (ERROR_SUCCESS != RegQueryValueEx(hkey,
  75. TEXT("Version"),
  76. NULL,
  77. &dwType,
  78. (LPBYTE)szBuffer,
  79. &dwSize))
  80. {
  81. goto IsMSDUN12InstalledExit;
  82. }
  83. #ifdef UNICODE
  84. CHAR szTmp[MAX_PATH];
  85. wcstombs(szTmp, szBuffer, MAX_PATH);
  86. szTmp[MAX_PATH - 1] = '\0';
  87. bRC = DUN_12_Version <= atof(szTmp);
  88. #else
  89. bRC = DUN_12_Version <= atof(szBuffer);
  90. #endif
  91. IsMSDUN12InstalledExit:
  92. if (hkey != NULL)
  93. {
  94. RegCloseKey(hkey);
  95. hkey = NULL;
  96. }
  97. return bRC;
  98. }
  99. #endif
  100. // ############################################################################
  101. CPhoneBook::CPhoneBook()
  102. {
  103. HINSTANCE hInst = NULL;
  104. LONG lrc;
  105. #if !defined(WIN16)
  106. HKEY hkey;
  107. #endif
  108. DWORD dwType;
  109. DWORD dwSize;
  110. TCHAR szData[MAX_PATH+1];
  111. m_rgPhoneBookEntry = NULL;
  112. m_hPhoneBookEntry = NULL;
  113. m_cPhoneBookEntries =0;
  114. m_rgLineCountryEntry=NULL;
  115. m_rgState=NULL;
  116. m_cStates=0;
  117. m_rgIDLookUp = NULL;
  118. m_rgNameLookUp = NULL;
  119. m_pLineCountryList = NULL;
  120. ZeroMemory(&m_szINFFile[0],MAX_PATH);
  121. ZeroMemory(&m_szINFCode[0],MAX_INFCODE);
  122. ZeroMemory(&m_szPhoneBook[0],MAX_PATH);
  123. #if !defined(WIN16)
  124. if (VER_PLATFORM_WIN32_NT == DWGetWin32Platform())
  125. {
  126. m_bScriptingAvailable = TRUE;
  127. }
  128. else if (IsMSDUN12Installed())
  129. {
  130. //
  131. // ChrisK 8/7/97 Olympus1 11814
  132. // Display scripted phone numbers on system with DUN 1.2 installed
  133. //
  134. m_bScriptingAvailable = TRUE;
  135. }
  136. else
  137. {
  138. //
  139. // Verify scripting by checking for smmscrpt.dll in RemoteAccess registry key
  140. //
  141. if (1111 <= DWGetWin32BuildNumber())
  142. {
  143. m_bScriptingAvailable = TRUE;
  144. }
  145. else
  146. {
  147. m_bScriptingAvailable = FALSE;
  148. hkey = NULL;
  149. lrc=RegOpenKey(HKEY_LOCAL_MACHINE,TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\Authentication\\SMM_FILES\\PPP"),&hkey);
  150. if (ERROR_SUCCESS == lrc)
  151. {
  152. dwSize = sizeof(TCHAR)*MAX_PATH;
  153. lrc = RegQueryValueEx(hkey,TEXT("Path"),0,&dwType,(LPBYTE)szData,&dwSize);
  154. if (ERROR_SUCCESS == lrc)
  155. {
  156. if (0 == lstrcmpi(szData,TEXT("smmscrpt.dll")))
  157. m_bScriptingAvailable = TRUE;
  158. }
  159. }
  160. if (hkey)
  161. RegCloseKey(hkey);
  162. hkey = NULL;
  163. }
  164. //
  165. // Verify that the DLL can be loaded
  166. //
  167. if (m_bScriptingAvailable)
  168. {
  169. hInst = LoadLibrary(TEXT("smmscrpt.dll"));
  170. if (hInst)
  171. FreeLibrary(hInst);
  172. else
  173. m_bScriptingAvailable = FALSE;
  174. hInst = NULL;
  175. }
  176. }
  177. #endif // WIN16
  178. }
  179. // ############################################################################
  180. CPhoneBook::~CPhoneBook()
  181. {
  182. #ifdef WIN16
  183. if (m_rgPhoneBookEntry)
  184. GlobalFree(m_rgPhoneBookEntry);
  185. #else
  186. if (m_hPhoneBookEntry)
  187. GlobalUnlock(m_hPhoneBookEntry);
  188. if (m_hPhoneBookEntry)
  189. GlobalFree(m_hPhoneBookEntry);
  190. #endif
  191. if (m_pLineCountryList)
  192. GlobalFree(m_pLineCountryList);
  193. if (m_rgIDLookUp)
  194. GlobalFree(m_rgIDLookUp);
  195. if (m_rgNameLookUp)
  196. GlobalFree(m_rgNameLookUp);
  197. if (m_rgState)
  198. GlobalFree(m_rgState);
  199. }
  200. // ############################################################################
  201. BOOL CPhoneBook::ReadPhoneBookDW(DWORD far *pdw, CCSVFile far *pcCSVFile)
  202. {
  203. if (!pcCSVFile->ReadToken(szTempBuffer,TEMP_BUFFER_LENGTH))
  204. return FALSE;
  205. return (FSz2Dw(szTempBuffer,pdw));
  206. }
  207. // ############################################################################
  208. BOOL CPhoneBook::ReadPhoneBookW(WORD far *pw, CCSVFile far *pcCSVFile)
  209. {
  210. if (!pcCSVFile->ReadToken(szTempBuffer,TEMP_BUFFER_LENGTH))
  211. return FALSE;
  212. return (FSz2W(szTempBuffer,pw));
  213. }
  214. // ############################################################################
  215. BOOL CPhoneBook::ReadPhoneBookB(BYTE far *pb, CCSVFile far *pcCSVFile)
  216. {
  217. if (!pcCSVFile->ReadToken(szTempBuffer,TEMP_BUFFER_LENGTH))
  218. return FALSE;
  219. return (FSz2B(szTempBuffer,pb));
  220. }
  221. // ############################################################################
  222. BOOL CPhoneBook::ReadPhoneBookSZ(LPTSTR psz, DWORD dwSize, CCSVFile far *pcCSVFile)
  223. {
  224. if (!pcCSVFile->ReadToken(psz,dwSize))
  225. return FALSE;
  226. return TRUE;
  227. }
  228. // ############################################################################
  229. BOOL CPhoneBook::FixUpFromRealloc(PACCESSENTRY paeOld, PACCESSENTRY paeNew)
  230. {
  231. BOOL bRC = FALSE;
  232. LONG_PTR lDiff = 0;
  233. DWORD idx = 0;
  234. //
  235. // No starting value or no move, therefore no fix-ups needed
  236. //
  237. if ((0 == paeOld) || (paeNew == paeOld))
  238. {
  239. bRC = TRUE;
  240. goto FixUpFromReallocExit;
  241. }
  242. Assert(paeNew);
  243. Assert(((LONG)paeOld) > 0); // if these address look like negative numbers
  244. Assert(((LONG)paeNew) > 0); // I'm not sure the code would handle them
  245. lDiff = (LONG_PTR)paeOld - (LONG_PTR)paeNew;
  246. //
  247. // fix up STATES
  248. //
  249. for (idx = 0; idx < m_cStates; idx++)
  250. {
  251. if (m_rgState[idx].paeFirst)
  252. m_rgState[idx].paeFirst = (PACCESSENTRY )((LONG_PTR)m_rgState[idx].paeFirst - lDiff);
  253. }
  254. //
  255. // fix up ID look up array
  256. //
  257. for (idx = 0; idx < m_pLineCountryList->dwNumCountries ; idx++)
  258. {
  259. if (m_rgIDLookUp[idx].pFirstAE)
  260. m_rgIDLookUp[idx].pFirstAE = (PACCESSENTRY )((LONG_PTR)m_rgIDLookUp[idx].pFirstAE - lDiff);
  261. }
  262. bRC = TRUE;
  263. FixUpFromReallocExit:
  264. return bRC;
  265. }
  266. // ############################################################################
  267. HRESULT CPhoneBook::Init(LPCTSTR pszISPCode)
  268. {
  269. LPLINECOUNTRYLIST pLineCountryTemp = NULL;
  270. HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
  271. DWORD dwLastState = 0;
  272. DWORD dwLastCountry = 0;
  273. DWORD dwSizeAllocated;
  274. PACCESSENTRY pCurAccessEntry;
  275. PACCESSENTRY pAETemp;
  276. LPLINECOUNTRYENTRY pLCETemp;
  277. DWORD idx;
  278. LPTSTR pszTemp;
  279. CCSVFile far *pcCSVFile=NULL;
  280. LPSTATE ps,psLast; //faster to use pointers.
  281. HGLOBAL hTemp = NULL;
  282. /*#ifdef WIN16
  283. m_pLineCountryList = (LPLINECOUNTRYLIST)GlobalAlloc(GPTR, sizeof(LINECOUNTRYLIST) + sizeof(LINECOUNTRYENTRY) + 10);
  284. if (!m_pLineCountryList)
  285. goto InitExit;
  286. m_pLineCountryList->dwTotalSize = sizeof(LINECOUNTRYLIST) + sizeof(LINECOUNTRYENTRY) + 3;
  287. m_pLineCountryList->dwNeededSize = m_pLineCountryList->dwUsedSize = m_pLineCountryList->dwTotalSize;
  288. m_pLineCountryList->dwNumCountries = 1;
  289. m_pLineCountryList->dwCountryListSize = sizeof(LINECOUNTRYENTRY);
  290. m_pLineCountryList->dwCountryListOffset = sizeof(LINECOUNTRYLIST);
  291. pLCETemp = (LPLINECOUNTRYENTRY)((DWORD) m_pLineCountryList + m_pLineCountryList->dwCountryListOffset);
  292. pLCETemp->dwCountryID = 1;
  293. pLCETemp->dwCountryCode = 1;
  294. pLCETemp->dwNextCountryID = 0;
  295. pLCETemp->dwCountryNameSize = 3;
  296. pLCETemp->dwCountryNameOffset = sizeof(LINECOUNTRYLIST) + sizeof(LINECOUNTRYENTRY);
  297. pLCETemp->dwSameAreaRuleSize = 0;
  298. pLCETemp->dwSameAreaRuleOffset = 0;
  299. pLCETemp->dwLongDistanceRuleSize = 0;
  300. pLCETemp->dwLongDistanceRuleOffset = 0;
  301. pLCETemp->dwInternationalRuleSize = 0;
  302. pLCETemp->dwInternationalRuleOffset = 0;
  303. lstrcpy ((LPTSTR)((DWORD)m_pLineCountryList + pLCETemp->dwCountryNameOffset), TEXT("USA"));
  304. pszTemp = (LPTSTR)((DWORD)m_pLineCountryList + pLCETemp->dwCountryNameOffset);
  305. #else // WIN16 */
  306. // Get TAPI country list
  307. m_pLineCountryList = (LPLINECOUNTRYLIST)GlobalAlloc(GPTR,sizeof(LINECOUNTRYLIST));
  308. if (!m_pLineCountryList)
  309. goto InitExit;
  310. m_pLineCountryList->dwTotalSize = sizeof(LINECOUNTRYLIST);
  311. #if defined(WIN16)
  312. idx = (DWORD) IETapiGetCountry(0, m_pLineCountryList);
  313. #else
  314. idx = lineGetCountry(0,0x10003,m_pLineCountryList);
  315. #endif
  316. if (idx && idx != LINEERR_STRUCTURETOOSMALL)
  317. goto InitExit;
  318. Assert(m_pLineCountryList->dwNeededSize);
  319. pLineCountryTemp = (LPLINECOUNTRYLIST)GlobalAlloc(GPTR,
  320. (size_t)m_pLineCountryList->dwNeededSize);
  321. if (!pLineCountryTemp)
  322. goto InitExit;
  323. pLineCountryTemp->dwTotalSize = m_pLineCountryList->dwNeededSize;
  324. GlobalFree(m_pLineCountryList);
  325. m_pLineCountryList = pLineCountryTemp;
  326. pLineCountryTemp = NULL;
  327. #if defined(WIN16)
  328. if (IETapiGetCountry(0, m_pLineCountryList))
  329. #else
  330. if (lineGetCountry(0,0x10003,m_pLineCountryList))
  331. #endif
  332. goto InitExit;
  333. //#endif // WIN16
  334. // Load Look Up arrays
  335. #ifdef DEBUG
  336. m_rgIDLookUp = (LPIDLOOKUPELEMENT)GlobalAlloc(GPTR,
  337. (int)(sizeof(IDLOOKUPELEMENT)*m_pLineCountryList->dwNumCountries+5));
  338. #else
  339. m_rgIDLookUp = (LPIDLOOKUPELEMENT)GlobalAlloc(GPTR,
  340. (int)(sizeof(IDLOOKUPELEMENT)*m_pLineCountryList->dwNumCountries));
  341. #endif
  342. if (!m_rgIDLookUp) goto InitExit;
  343. pLCETemp = (LPLINECOUNTRYENTRY)((DWORD_PTR)m_pLineCountryList +
  344. m_pLineCountryList->dwCountryListOffset);
  345. for (idx=0;idx<m_pLineCountryList->dwNumCountries;idx++)
  346. {
  347. m_rgIDLookUp[idx].dwID = pLCETemp[idx].dwCountryID;
  348. m_rgIDLookUp[idx].pLCE = &pLCETemp[idx];
  349. }
  350. qsort(m_rgIDLookUp,(int)m_pLineCountryList->dwNumCountries,sizeof(IDLOOKUPELEMENT),
  351. CompareIDLookUpElements);
  352. m_rgNameLookUp = (LPCNTRYNAMELOOKUPELEMENT)GlobalAlloc(GPTR,
  353. (int)(sizeof(CNTRYNAMELOOKUPELEMENT) * m_pLineCountryList->dwNumCountries));
  354. if (!m_rgNameLookUp) goto InitExit;
  355. for (idx=0;idx<m_pLineCountryList->dwNumCountries;idx++)
  356. {
  357. m_rgNameLookUp[idx].psCountryName = (LPTSTR)((LPBYTE)m_pLineCountryList + (DWORD)pLCETemp[idx].dwCountryNameOffset);
  358. m_rgNameLookUp[idx].dwNameSize = pLCETemp[idx].dwCountryNameSize;
  359. m_rgNameLookUp[idx].pLCE = &pLCETemp[idx];
  360. }
  361. qsort(m_rgNameLookUp,(int)m_pLineCountryList->dwNumCountries,sizeof(CNTRYNAMELOOKUPELEMENT),
  362. CompareCntryNameLookUpElements);
  363. // Load States
  364. if (!SearchPath(NULL,STATE_FILENAME,NULL,TEMP_BUFFER_LENGTH,szTempBuffer,&pszTemp))
  365. {
  366. AssertMsg(0,"STATE.ICW not found");
  367. hr = ERROR_FILE_NOT_FOUND;
  368. goto InitExit;
  369. }
  370. pcCSVFile = new CCSVFile;
  371. if (!pcCSVFile) goto InitExit;
  372. if (!pcCSVFile->Open(szTempBuffer))
  373. {
  374. AssertMsg(0,"Can not open STATE.ICW");
  375. delete pcCSVFile;
  376. pcCSVFile = NULL;
  377. goto InitExit;
  378. }
  379. // first token in state file is the number of states
  380. if (!pcCSVFile->ReadToken(szTempBuffer,TEMP_BUFFER_LENGTH))
  381. goto InitExit;
  382. if (!FSz2Dw(szTempBuffer,&m_cStates))
  383. {
  384. AssertMsg(0,"STATE.ICW count is invalid");
  385. goto InitExit;
  386. }
  387. m_rgState = (LPSTATE)GlobalAlloc(GPTR,(int)(sizeof(STATE)*m_cStates));
  388. if (!m_rgState)
  389. goto InitExit;
  390. for (ps = m_rgState, psLast = &m_rgState[m_cStates - 1]; ps <= psLast;++ps)
  391. {
  392. pcCSVFile->ReadToken(ps->szStateName,cbStateName);
  393. }
  394. pcCSVFile->Close();
  395. // Locate ISP's INF file
  396. if (!SearchPath(NULL,(LPCTSTR) pszISPCode,INF_SUFFIX,MAX_PATH,
  397. m_szINFFile,&pszTemp))
  398. {
  399. wsprintf(szTempBuffer,TEXT("Can not find:%s%s (%d)"),pszISPCode,INF_SUFFIX,GetLastError());
  400. AssertMsg(0,szTempBuffer);
  401. hr = ERROR_FILE_NOT_FOUND;
  402. goto InitExit;
  403. }
  404. //Load Phone Book
  405. if (!GetPrivateProfileString(INF_APP_NAME,INF_PHONE_BOOK,INF_DEFAULT,
  406. szTempBuffer,TEMP_BUFFER_LENGTH,m_szINFFile))
  407. {
  408. AssertMsg(0,"PhoneBookFile not specified in INF file");
  409. hr = ERROR_FILE_NOT_FOUND;
  410. goto InitExit;
  411. }
  412. #ifdef DEBUG
  413. if (!lstrcmp(szTempBuffer,INF_DEFAULT))
  414. {
  415. wsprintf(szTempBuffer, TEXT("%s value not found in ISP file"), INF_PHONE_BOOK);
  416. AssertMsg(0,szTempBuffer);
  417. }
  418. #endif
  419. if (!SearchPath(NULL,szTempBuffer,NULL,MAX_PATH,m_szPhoneBook,&pszTemp))
  420. {
  421. AssertMsg(0,"ISP phone book not found");
  422. hr = ERROR_FILE_NOT_FOUND;
  423. goto InitExit;
  424. }
  425. if (!pcCSVFile->Open(m_szPhoneBook))
  426. {
  427. AssertMsg(0,"Can not open phone book");
  428. hr = GetLastError();
  429. goto InitExit;
  430. }
  431. dwSizeAllocated = 0;
  432. do {
  433. Assert (dwSizeAllocated >= m_cPhoneBookEntries);
  434. // check that sufficient memory is allocated
  435. if (m_rgPhoneBookEntry)
  436. {
  437. if (dwSizeAllocated == m_cPhoneBookEntries)
  438. {
  439. //
  440. // we need more memory
  441. //
  442. // AssertMsg(0,"Out of memory originally allocated for phone book.\r\n");
  443. // goto InitExit;
  444. pAETemp = m_rgPhoneBookEntry;
  445. #ifdef WIN16
  446. dwSizeAllocated += PHONE_ENTRY_ALLOC_SIZE;
  447. m_rgPhoneBookEntry = (PACCESSENTRY)GlobalReAlloc(m_rgPhoneBookEntry,
  448. (int)(dwSizeAllocated * sizeof(ACCESSENTRY)),GHND);
  449. if (NULL == m_rgPhoneBookEntry)
  450. goto InitExit;
  451. #else
  452. // UNLOCK
  453. Assert(m_hPhoneBookEntry);
  454. if (FALSE == GlobalUnlock(m_hPhoneBookEntry))
  455. {
  456. if (NO_ERROR != GetLastError())
  457. goto InitExit;
  458. }
  459. // REALLOC
  460. dwSizeAllocated += PHONE_ENTRY_ALLOC_SIZE;
  461. hTemp = m_hPhoneBookEntry;
  462. m_hPhoneBookEntry = GlobalReAlloc(hTemp,
  463. (int)(dwSizeAllocated * sizeof(ACCESSENTRY)),GHND);
  464. if (NULL == m_hPhoneBookEntry)
  465. {
  466. GlobalFree(hTemp);
  467. goto InitExit;
  468. }
  469. else
  470. {
  471. hTemp = NULL;
  472. }
  473. // LOCK
  474. m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
  475. if (NULL == m_rgPhoneBookEntry)
  476. goto InitExit;
  477. #endif
  478. FixUpFromRealloc(pAETemp, m_rgPhoneBookEntry);
  479. TraceMsg(TF_GENERAL, "Grow phone book to %d entries\n",dwSizeAllocated);
  480. pCurAccessEntry = (PACCESSENTRY)((LONG_PTR)pCurAccessEntry -
  481. ((LONG_PTR)pAETemp - (LONG_PTR)(m_rgPhoneBookEntry)));
  482. }
  483. }
  484. else
  485. {
  486. //
  487. // Initialization for the first time through
  488. //
  489. // ALLOC
  490. #ifdef WIN16
  491. m_rgPhoneBookEntry = (PACCESSENTRY)GlobalAlloc(GHND,sizeof(ACCESSENTRY) * PHONE_ENTRY_ALLOC_SIZE);
  492. if(NULL == m_rgPhoneBookEntry)
  493. goto InitExit;
  494. #else
  495. m_hPhoneBookEntry = GlobalAlloc(GHND,sizeof(ACCESSENTRY) * PHONE_ENTRY_ALLOC_SIZE);
  496. if(NULL == m_hPhoneBookEntry)
  497. goto InitExit;
  498. // LOCK
  499. m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
  500. if(NULL == m_rgPhoneBookEntry)
  501. goto InitExit;
  502. #endif
  503. dwSizeAllocated = PHONE_ENTRY_ALLOC_SIZE;
  504. pCurAccessEntry = m_rgPhoneBookEntry;
  505. }
  506. // Read a line from the phonebook
  507. hr = ReadOneLine(pCurAccessEntry,pcCSVFile);
  508. if (hr == ERROR_NO_MORE_ITEMS)
  509. {
  510. break;
  511. }
  512. else if (hr != ERROR_SUCCESS)
  513. {
  514. goto InitExit;
  515. }
  516. hr = ERROR_NOT_ENOUGH_MEMORY;
  517. // Check to see if this is the first phone number for a given country
  518. if (pCurAccessEntry->dwCountryID != dwLastCountry)
  519. {
  520. LPIDLOOKUPELEMENT lpIDLookupElement;
  521. // NOTE: Not sure about the first parameter here.
  522. lpIDLookupElement = (LPIDLOOKUPELEMENT)bsearch(&pCurAccessEntry->dwCountryID,
  523. m_rgIDLookUp,(int)m_pLineCountryList->dwNumCountries,sizeof(IDLOOKUPELEMENT),
  524. CompareIDLookUpElements);
  525. if (!lpIDLookupElement)
  526. {
  527. // bad country ID, but we can't assert here
  528. TraceMsg(TF_GENERAL,"Bad country ID in phone book %d\n",pCurAccessEntry->dwCountryID);
  529. continue;
  530. }
  531. else
  532. {
  533. // for a given country ID this is the first phone number
  534. lpIDLookupElement->pFirstAE = pCurAccessEntry;
  535. dwLastCountry = pCurAccessEntry->dwCountryID;
  536. }
  537. }
  538. // Check to see if this is the first phone number for a given state
  539. if (pCurAccessEntry->wStateID && (pCurAccessEntry->wStateID != dwLastState))
  540. {
  541. idx = pCurAccessEntry->wStateID - 1;
  542. m_rgState[idx].dwCountryID = pCurAccessEntry->dwCountryID;
  543. m_rgState[idx].paeFirst = pCurAccessEntry;
  544. dwLastState = pCurAccessEntry->wStateID;
  545. }
  546. pCurAccessEntry++;
  547. m_cPhoneBookEntries++;
  548. } while (TRUE);
  549. // Trim the phone book for unused memory
  550. Assert(m_rgPhoneBookEntry && m_cPhoneBookEntries);
  551. pAETemp = m_rgPhoneBookEntry;
  552. #ifdef WIN16
  553. m_rgPhoneBookEntry = (PACCESSENTRY)GlobalReAlloc(m_rgPhoneBookEntry,(int)(m_cPhoneBookEntries * sizeof(ACCESSENTRY)),GHND);
  554. if (!m_rgPhoneBookEntry) goto InitExit;
  555. #else
  556. // UNLOCK
  557. Assert(m_hPhoneBookEntry);
  558. if (FALSE != GlobalUnlock(m_hPhoneBookEntry))
  559. {
  560. if (NO_ERROR != GetLastError())
  561. goto InitExit;
  562. }
  563. // REALLOC
  564. hTemp = m_hPhoneBookEntry;
  565. m_hPhoneBookEntry = GlobalReAlloc(hTemp,(int)(m_cPhoneBookEntries * sizeof(ACCESSENTRY)),GHND);
  566. if (NULL == m_hPhoneBookEntry)
  567. {
  568. GlobalFree(hTemp);
  569. goto InitExit;
  570. }
  571. else
  572. {
  573. hTemp = NULL;
  574. }
  575. // LOCK
  576. m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
  577. if (NULL == m_rgPhoneBookEntry)
  578. goto InitExit;
  579. #endif
  580. FixUpFromRealloc(pAETemp, m_rgPhoneBookEntry);
  581. hr = ERROR_SUCCESS;
  582. InitExit:
  583. // If something failed release everything
  584. if (hr != ERROR_SUCCESS)
  585. {
  586. #ifdef WIN16
  587. GlobalFree(m_rgPhoneBookEntry);
  588. #else
  589. GlobalUnlock(m_hPhoneBookEntry);
  590. GlobalFree(m_hPhoneBookEntry);
  591. #endif
  592. GlobalFree(m_pLineCountryList);
  593. GlobalFree(m_rgIDLookUp);
  594. GlobalFree(m_rgNameLookUp);
  595. GlobalFree(m_rgState);
  596. m_cPhoneBookEntries = 0 ;
  597. m_cStates = 0;
  598. m_pLineCountryList = NULL;
  599. m_rgPhoneBookEntry = NULL;
  600. m_hPhoneBookEntry = NULL;
  601. m_rgIDLookUp=NULL;
  602. m_rgNameLookUp=NULL;
  603. m_rgState=NULL;
  604. }
  605. if (pcCSVFile)
  606. {
  607. pcCSVFile->Close();
  608. delete pcCSVFile;
  609. }
  610. return hr;
  611. }
  612. // ############################################################################
  613. HRESULT CPhoneBook::Merge(LPCTSTR pszChangeFile)
  614. {
  615. CCSVFile far *pcCSVFile;
  616. ACCESSENTRY aeChange;
  617. LPIDXLOOKUPELEMENT rgIdxLookUp;
  618. LPIDXLOOKUPELEMENT pCurIdxLookUp;
  619. DWORD dwAllocated;
  620. DWORD dwUsed;
  621. DWORD dwOriginalSize;
  622. HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
  623. DWORD dwIdx;
  624. #if !defined(WIN16)
  625. HANDLE hTemp;
  626. HANDLE hIdxLookUp;
  627. #else
  628. // Normandy 11746
  629. LPVOID rgTemp; // 16-bit only
  630. #endif
  631. DWORD cch, cchWritten;
  632. HANDLE hFile;
  633. // Pad the phonebook for new entries.
  634. dwAllocated = m_cPhoneBookEntries + CHANGE_BUFFER_SIZE;
  635. #ifdef WIN16
  636. Assert(m_rgPhoneBookEntry);
  637. rgTemp = GlobalReAlloc(m_rgPhoneBookEntry, (int)(sizeof(ACCESSENTRY) * dwAllocated),GHND);
  638. Assert(rgTemp);
  639. if (!rgTemp) goto MergeExit;
  640. m_rgPhoneBookEntry = (PACCESSENTRY)rgTemp;
  641. #else
  642. Assert(m_hPhoneBookEntry);
  643. GlobalUnlock(m_hPhoneBookEntry);
  644. hTemp = (HANDLE)GlobalReAlloc(m_hPhoneBookEntry, sizeof(ACCESSENTRY) * dwAllocated,GHND);
  645. Assert(hTemp);
  646. if (!hTemp)
  647. goto MergeExit;
  648. m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
  649. if (!m_rgPhoneBookEntry)
  650. goto MergeExit;
  651. #endif
  652. // Create index to loaded phone book, sorted by index
  653. #ifdef WIN16
  654. rgIdxLookUp = (LPIDXLOOKUPELEMENT)GlobalAlloc(GHND,(int)(sizeof(IDXLOOKUPELEMENT) * dwAllocated));
  655. #else
  656. hIdxLookUp = (HANDLE)GlobalAlloc(GHND,sizeof(IDXLOOKUPELEMENT) * dwAllocated);
  657. rgIdxLookUp = (LPIDXLOOKUPELEMENT)GlobalLock(hIdxLookUp);
  658. #endif
  659. Assert(rgIdxLookUp);
  660. if (!rgIdxLookUp)
  661. goto MergeExit;
  662. for (dwIdx = 0; dwIdx < m_cPhoneBookEntries; dwIdx++)
  663. {
  664. rgIdxLookUp[dwIdx].dwIndex = rgIdxLookUp[dwIdx].pAE->dwIndex;
  665. rgIdxLookUp[dwIdx].pAE = &m_rgPhoneBookEntry[dwIdx];
  666. }
  667. dwUsed = m_cPhoneBookEntries;
  668. dwOriginalSize = m_cPhoneBookEntries;
  669. qsort(rgIdxLookUp,(int)dwOriginalSize,sizeof(IDXLOOKUPELEMENT),CompareIdxLookUpElements);
  670. // Load changes to phone book
  671. pcCSVFile = new CCSVFile;
  672. Assert(pcCSVFile);
  673. if (!pcCSVFile)
  674. goto MergeExit;
  675. if (!pcCSVFile->Open(pszChangeFile))
  676. goto MergeExit;
  677. do {
  678. // Read a change record
  679. ZeroMemory(&aeChange,sizeof(ACCESSENTRY));
  680. hr = ReadOneLine(&aeChange, pcCSVFile);
  681. if(hr == ERROR_NO_MORE_ITEMS)
  682. {
  683. break; // no more enteries
  684. }
  685. else if (hr != ERROR_SUCCESS)
  686. {
  687. goto MergeExit;
  688. }
  689. hr = ERROR_NOT_ENOUGH_MEMORY;
  690. /* if (!ReadPhoneBookDW(&aeChange.dwIndex,pcCSVFile))
  691. break; // no more enteries
  692. ReadVerifyPhoneBookDW(aeChange.dwCountryID);
  693. ReadVerifyPhoneBookW(aeChange.wStateID);
  694. ReadVerifyPhoneBookSZ(aeChange.szCity,cbCity);
  695. ReadVerifyPhoneBookSZ(aeChange.szAreaCode,cbAreaCode);
  696. // NOTE: 0 is a valid area code and ,, is a valid entry for an area code
  697. if (!FSz2Dw(aeChange.szAreaCode,&aeChange.dwAreaCode))
  698. aeChange.dwAreaCode = NO_AREA_CODE;
  699. ReadVerifyPhoneBookSZ(aeChange.szAccessNumber,cbAccessNumber);
  700. ReadVerifyPhoneBookDW(aeChange.dwConnectSpeedMin);
  701. ReadVerifyPhoneBookDW(aeChange.dwConnectSpeedMax);
  702. ReadVerifyPhoneBookB(aeChange.bFlipFactor);
  703. ReadVerifyPhoneBookB(aeChange.fType);
  704. ReadVerifyPhoneBookSZ(aeChange.szDataCenter,cbDataCenter);
  705. */
  706. // Determine if this is a delete or add record
  707. if (aeChange.szAccessNumber[0] == '0' && aeChange.szAccessNumber[1] == '\0')
  708. {
  709. // This is a delete record, find matching record
  710. // NOTE: we only search the numbers that existed before the change file,
  711. // because they are the only ones that are sorted.
  712. pCurIdxLookUp = (LPIDXLOOKUPELEMENT)bsearch(&aeChange,rgIdxLookUp,(int)dwOriginalSize,
  713. sizeof(IDXLOOKUPELEMENT),CompareIdxLookUpElements);
  714. AssertMsg(pCurIdxLookUp,"Attempting to delete a record that does not exist. The change file and phone book versions do not match.");
  715. if (pCurIdxLookUp)
  716. pCurIdxLookUp->pAE = NULL; //Create a dead entry in the look up table
  717. m_cPhoneBookEntries--;
  718. }
  719. else
  720. {
  721. // This is an add entry
  722. m_cPhoneBookEntries++;
  723. dwUsed++;
  724. // Make sure we have enough room
  725. if (m_cPhoneBookEntries > dwAllocated)
  726. {
  727. // Grow phone book
  728. dwAllocated += CHANGE_BUFFER_SIZE;
  729. #ifdef WIN16
  730. Assert(m_rgPhoneBookEntry);
  731. rgTemp = GlobalReAlloc(m_rgPhoneBookEntry,(int)(sizeof(ACCESSENTRY)*dwAllocated),GHND);
  732. Assert(rgTemp);
  733. if (!rgTemp)
  734. goto MergeExit;
  735. m_rgPhoneBookEntry = (PACCESSENTRY)rgTemp;
  736. // Grow look up index
  737. Assert(rgIdxLookUp);
  738. rgTemp = GlobalReAlloc(rgIdxLookUp,(int)(sizeof(IDXLOOKUPELEMENT)*dwAllocated),GHND);
  739. Assert(rgTemp);
  740. if (!rgTemp)
  741. goto MergeExit;
  742. rgIdxLookUp = (LPIDXLOOKUPELEMENT)rgTemp;
  743. #else
  744. Assert(m_hPhoneBookEntry);
  745. GlobalUnlock(m_hPhoneBookEntry);
  746. hTemp = (HANDLE)GlobalReAlloc(m_hPhoneBookEntry,sizeof(ACCESSENTRY)*dwAllocated,GHND);
  747. Assert(hTemp);
  748. if (!hTemp)
  749. goto MergeExit;
  750. m_hPhoneBookEntry = hTemp;
  751. m_rgPhoneBookEntry = (PACCESSENTRY)GlobalLock(m_hPhoneBookEntry);
  752. Assert(m_rgPhoneBookEntry);
  753. if (!m_rgPhoneBookEntry)
  754. goto MergeExit;
  755. // Grow look up index
  756. Assert(hIdxLookUp);
  757. GlobalUnlock(hIdxLookUp);
  758. hTemp = (HANDLE)GlobalReAlloc(hIdxLookUp,sizeof(IDXLOOKUPELEMENT)*dwAllocated,GHND);
  759. Assert(hTemp);
  760. if (!hTemp)
  761. goto MergeExit;
  762. hIdxLookUp = hTemp;
  763. rgIdxLookUp = (LPIDXLOOKUPELEMENT)GlobalLock(hIdxLookUp);
  764. Assert(rgIdxLookUp);
  765. if (!rgIdxLookUp)
  766. goto MergeExit;
  767. #endif
  768. }
  769. //Add entry to the end of the phonebook and to end of look up index
  770. CopyMemory(&m_rgPhoneBookEntry[m_cPhoneBookEntries],&aeChange,sizeof(ACCESSENTRY));
  771. rgIdxLookUp[m_cPhoneBookEntries].dwIndex = m_rgPhoneBookEntry[m_cPhoneBookEntries].dwIndex;
  772. rgIdxLookUp[m_cPhoneBookEntries].pAE = &m_rgPhoneBookEntry[m_cPhoneBookEntries];
  773. // NOTE: because the entry is added to the end of the list, we can't add
  774. // and delete entries in the same change file.
  775. }
  776. } while (TRUE);
  777. // resort the IDXLookUp index to reflect the correct order of enteries
  778. // for the phonebook file, including all of the entries to be deleted.
  779. qsort(rgIdxLookUp,(int)dwUsed,sizeof(IDXLOOKUPELEMENT),CompareIdxLookUpElementsFileOrder);
  780. // Build a new phonebook file
  781. #ifdef WIN16
  782. GetTempFileName(0, TEMP_PHONE_BOOK_PREFIX, 0, szTempFileName);
  783. #else
  784. if (!GetTempPath(TEMP_BUFFER_LENGTH,szTempBuffer))
  785. goto MergeExit;
  786. if (!GetTempFileName(szTempBuffer,TEMP_PHONE_BOOK_PREFIX,0,szTempFileName))
  787. goto MergeExit;
  788. #endif
  789. hFile = CreateFile(szTempFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
  790. FILE_FLAG_WRITE_THROUGH,0);
  791. if (hFile == INVALID_HANDLE_VALUE)
  792. goto MergeExit;
  793. for (dwIdx = 0; dwIdx < m_cPhoneBookEntries; dwIdx++)
  794. {
  795. cch = wsprintf(szTempBuffer, TEXT("%lu,%lu,%lu,%s,%s,%s,%lu,%lu,%lu,%lu,%s\r\n"),
  796. rgIdxLookUp[dwIdx].pAE->dwIndex,
  797. rgIdxLookUp[dwIdx].pAE->dwCountryID,
  798. DWORD(rgIdxLookUp[dwIdx].pAE->wStateID),
  799. rgIdxLookUp[dwIdx].pAE->szCity,
  800. rgIdxLookUp[dwIdx].pAE->szAreaCode,
  801. rgIdxLookUp[dwIdx].pAE->szAccessNumber,
  802. rgIdxLookUp[dwIdx].pAE->dwConnectSpeedMin,
  803. rgIdxLookUp[dwIdx].pAE->dwConnectSpeedMax,
  804. DWORD(rgIdxLookUp[dwIdx].pAE->bFlipFactor),
  805. DWORD(rgIdxLookUp[dwIdx].pAE->fType),
  806. rgIdxLookUp[dwIdx].pAE->szDataCenter);
  807. if (!WriteFile(hFile,szTempBuffer,cch,&cchWritten,NULL))
  808. {
  809. // something went wrong, get rid of the temporary file
  810. CloseHandle(hFile);
  811. DeleteFile(szTempFileName);
  812. hr = GetLastError();
  813. goto MergeExit;
  814. }
  815. Assert(cch == cchWritten);
  816. }
  817. CloseHandle(hFile);
  818. hFile = NULL;
  819. // Move new phone book over old
  820. if (!MoveFileEx(szTempFileName,m_szPhoneBook,MOVEFILE_REPLACE_EXISTING))
  821. {
  822. hr = GetLastError();
  823. goto MergeExit;
  824. }
  825. // discard the phonebook in memory
  826. #ifndef WIN16
  827. Assert(m_hPhoneBookEntry);
  828. GlobalUnlock(m_hPhoneBookEntry);
  829. #endif
  830. m_rgPhoneBookEntry = NULL;
  831. m_cPhoneBookEntries = 0;
  832. GlobalFree(m_pLineCountryList);
  833. GlobalFree(m_rgIDLookUp);
  834. GlobalFree(m_rgNameLookUp);
  835. GlobalFree(m_rgState);
  836. m_cStates = 0;
  837. lstrcpy(szTempBuffer,m_szINFCode);
  838. m_szINFFile[0] = '\0';
  839. m_szPhoneBook[0] = '\0';
  840. m_szINFCode[0] = '\0';
  841. // Reload it (and rebuild look up arrays)
  842. hr = Init(szTempBuffer);
  843. MergeExit:
  844. if (hr != ERROR_SUCCESS)
  845. {
  846. GlobalFree(rgIdxLookUp);
  847. if (pcCSVFile) delete pcCSVFile;
  848. CloseHandle(hFile);
  849. }
  850. return hr;
  851. }
  852. // ############################################################################
  853. HRESULT CPhoneBook::ReadOneLine(PACCESSENTRY lpAccessEntry, CCSVFile far *pcCSVFile)
  854. {
  855. HRESULT hr = ERROR_SUCCESS;
  856. #if !defined(WIN16)
  857. ReadOneLineStart:
  858. #endif //WIN16
  859. if (!ReadPhoneBookDW(&lpAccessEntry->dwIndex,pcCSVFile))
  860. {
  861. hr = ERROR_NO_MORE_ITEMS; // no more enteries
  862. goto ReadExit;
  863. }
  864. ReadVerifyPhoneBookDW(lpAccessEntry->dwCountryID);
  865. ReadVerifyPhoneBookW(lpAccessEntry->wStateID);
  866. ReadVerifyPhoneBookSZ(lpAccessEntry->szCity,cbCity);
  867. ReadVerifyPhoneBookSZ(lpAccessEntry->szAreaCode,cbAreaCode);
  868. // NOTE: 0 is a valid area code and ,, is a valid entry for an area code
  869. if (!FSz2Dw(lpAccessEntry->szAreaCode,&lpAccessEntry->dwAreaCode))
  870. lpAccessEntry->dwAreaCode = NO_AREA_CODE;
  871. ReadVerifyPhoneBookSZ(lpAccessEntry->szAccessNumber,cbAccessNumber);
  872. ReadVerifyPhoneBookDW(lpAccessEntry->dwConnectSpeedMin);
  873. ReadVerifyPhoneBookDW(lpAccessEntry->dwConnectSpeedMax);
  874. ReadVerifyPhoneBookB(lpAccessEntry->bFlipFactor);
  875. ReadVerifyPhoneBookDW(lpAccessEntry->fType);
  876. ReadVerifyPhoneBookSZ(lpAccessEntry->szDataCenter,cbDataCenter);
  877. switch (lpAccessEntry->bFlipFactor)
  878. {
  879. case BOTH_ISDN_ANALOG:
  880. // This phone number supports both ISDN or Analog, return true
  881. // We want analog numbers, check the FlipFactor for zero
  882. lpAccessEntry->fType |= MASK_ISDN_BIT | MASK_ANALOG_BIT;
  883. break;
  884. case ANALOG_TYPE:
  885. // Analog only
  886. lpAccessEntry->fType |= MASK_ANALOG_BIT;
  887. break;
  888. case ISDN_TYPE:
  889. // We only want ISDN numbers
  890. lpAccessEntry->fType |= MASK_ISDN_BIT;
  891. break;
  892. }
  893. #if !defined(WIN16)
  894. //
  895. // If scripting is not available and the phonebook entry has a dun file other than
  896. // icwip.dun, then ignore the entry and read the one after that.
  897. //
  898. if (!m_bScriptingAvailable)
  899. {
  900. if (0 != lstrcmpi(lpAccessEntry->szDataCenter,TEXT("icwip.dun")))
  901. {
  902. ZeroMemory(lpAccessEntry,sizeof(ACCESSENTRY));
  903. goto ReadOneLineStart;
  904. }
  905. }
  906. #endif //WIN16
  907. ReadExit:
  908. return hr;
  909. ReadError:
  910. hr = ERROR_INVALID_DATA;
  911. goto ReadExit;
  912. }
  913. // ############################################################################
  914. HRESULT CPhoneBook::Suggest(PSUGGESTINFO pSuggest)
  915. {
  916. WORD wNumFound = 0;
  917. HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
  918. // char szFileName[MAX_PATH];
  919. // char *pszTemp;
  920. // HANDLE hFile=NULL;
  921. // HANDLE hMap=NULL;
  922. // DWORD dwSize;
  923. // LPNPABLOCK rg950Data = NULL;
  924. // NPABLOCK *p950Data;
  925. // Validate parameters
  926. Assert(pSuggest);
  927. Assert(pSuggest->wNumber);
  928. if (wNumFound == pSuggest->wNumber)
  929. goto SuggestExit;
  930. LPIDLOOKUPELEMENT pCurLookUp;
  931. PACCESSENTRY lpAccessEntry;
  932. //REVIEW: double check this
  933. pCurLookUp = (LPIDLOOKUPELEMENT)bsearch(&pSuggest->dwCountryID,m_rgIDLookUp,
  934. (int)m_pLineCountryList->dwNumCountries,sizeof(IDLOOKUPELEMENT),
  935. CompareIDLookUpElements);
  936. // Check for invalid country
  937. if (!pCurLookUp)
  938. goto SuggestExit;
  939. // Check if there are any phone numbers for this country
  940. if (!pCurLookUp->pFirstAE) goto SuggestExit;
  941. lpAccessEntry = pCurLookUp->pFirstAE;
  942. do {
  943. // check for the right area code
  944. if (lpAccessEntry->dwAreaCode == pSuggest->wAreaCode)
  945. {
  946. // check for the right type of number
  947. if ((lpAccessEntry->fType & pSuggest->bMask) == pSuggest->fType)
  948. {
  949. pSuggest->rgpAccessEntry[wNumFound] = lpAccessEntry;
  950. wNumFound++;
  951. }
  952. }
  953. lpAccessEntry++;
  954. } while ((lpAccessEntry <= &m_rgPhoneBookEntry[m_cPhoneBookEntries-1]) &&
  955. (wNumFound < pSuggest->wNumber) &&
  956. (lpAccessEntry->dwCountryID == pSuggest->dwCountryID));
  957. //
  958. // MKarki - Bug 340 no need to list more numbers if one already found
  959. // in Area Code specified by user
  960. //
  961. // 5/24/97 jmazner Olympus #340 and #71
  962. // nope, this is wrong. We always want to return as many applicable
  963. // phone numbers as we find. Just because the area code matches
  964. // doesn't mean that we've found an ideal phone number.
  965. //if (wNumFound == 0)
  966. //{
  967. //
  968. // if we couldn't find enough numnbers, try something else
  969. //
  970. // 10/15/96 jmazner ported fixes below from core\client\phbk
  971. //
  972. // Do this only if area code is not 0 - Bug #9349 (VetriV)
  973. // if ((pSuggest->wAreaCode != 0) && (wNumFound < pSuggest->wNumber))
  974. //
  975. // No, there are some places (Finland? ChrisK knows) where 0 is a legit area code -- jmazner
  976. if (wNumFound < pSuggest->wNumber)
  977. {
  978. lpAccessEntry = pCurLookUp->pFirstAE;
  979. // Note: we are now only looking for Nationwide phone numbers (state = 0)
  980. // 8/13/96 jmazner MOS Normandy #4597
  981. // We want nationwide toll-free numbers to display last, so for this pass,
  982. // only consider numbers that are _not_ toll free (fType bit #1 = 0)
  983. //
  984. // 5/24/97 jmazner Olympus #71
  985. // As per GeoffR's spec, the search passes should not be based on
  986. // the tollfree bit at all
  987. //
  988. // 5/28/97 jmazner Olympus #71
  989. // ahem...as per GeoffR's new spec, we _should_ consider the tollfree
  990. // bit and in this query only bring up toll free numbers.
  991. //
  992. // so, we will only return numbers whose area code match, or which are
  993. // tollfree
  994. //
  995. //
  996. // Tweak pSuggest->bMask to let through the toll/charge bit
  997. //
  998. pSuggest->bMask |= MASK_TOLLFREE_BIT;
  999. // //Tweak pSuggest->ftype to be charge
  1000. //pSuggest->fType &= TYPE_SET_TOLL;
  1001. //
  1002. // make that tollfree!
  1003. pSuggest->fType |= TYPE_SET_TOLLFREE;
  1004. do {
  1005. // 8/13/96 jmazner MOS Normandy #4598
  1006. // If this entry's area code matches pSuggest->wAreaCode, then we already
  1007. // have included it in the previous pass, so don't duplicate it again here.
  1008. if ((lpAccessEntry->fType & pSuggest->bMask) == pSuggest->fType &&
  1009. lpAccessEntry->wStateID == 0 &&
  1010. lpAccessEntry->dwAreaCode != pSuggest->wAreaCode)
  1011. {
  1012. pSuggest->rgpAccessEntry[wNumFound] = lpAccessEntry;
  1013. wNumFound++;
  1014. }
  1015. lpAccessEntry++;
  1016. } while ((lpAccessEntry <= &m_rgPhoneBookEntry[m_cPhoneBookEntries-1]) &&
  1017. (wNumFound < pSuggest->wNumber) &&
  1018. (lpAccessEntry->dwCountryID == pSuggest->dwCountryID) &&
  1019. (lpAccessEntry->wStateID == 0) );
  1020. }
  1021. // 8/13/96 jmazner MOS Normandy #4597
  1022. // if we STILL couldn't find enough numnbers, widen the search to include tollfree #s
  1023. //
  1024. // 5/24/97 jmazner Olympus #71
  1025. // no need for this pass at all. See earlier comments.
  1026. /****
  1027. if (wNumFound < pSuggest->wNumber)
  1028. {
  1029. lpAccessEntry = pCurLookUp->pFirstAE;
  1030. // Tweak pSuggest->bMask to let through the toll/charge bit
  1031. // REDUNDANT? If we made it to this point, we _should_ have done this above...
  1032. // Better safe than sorry!
  1033. Assert(pSuggest->bMask & MASK_TOLLFREE_BIT);
  1034. pSuggest->bMask |= MASK_TOLLFREE_BIT;
  1035. // Tweak pSuggest->ftype to be tollfree
  1036. pSuggest->fType |= TYPE_SET_TOLLFREE;
  1037. do {
  1038. // 8/13/96 jmazner MOS Normandy #4598
  1039. // If this entry's area code matches pSuggest->wAreaCode, then we already
  1040. // have included it in the first pass, so don't include it here.
  1041. // Any entry that made it in in the 2nd pass will definitely not make it in here
  1042. // (because of tollfree bit), so no need to worry about dups from there.
  1043. if ((lpAccessEntry->fType & pSuggest->bMask) == pSuggest->fType &&
  1044. lpAccessEntry->wStateID == 0 &&
  1045. lpAccessEntry->dwAreaCode != pSuggest->wAreaCode)
  1046. {
  1047. pSuggest->rgpAccessEntry[wNumFound] = lpAccessEntry;
  1048. wNumFound++;
  1049. }
  1050. lpAccessEntry++;
  1051. } while ((lpAccessEntry <= &m_rgPhoneBookEntry[m_cPhoneBookEntries-1]) &&
  1052. (wNumFound < pSuggest->wNumber) &&
  1053. (lpAccessEntry->dwCountryID == pSuggest->dwCountryID) &&
  1054. (lpAccessEntry->wStateID == 0) );
  1055. }
  1056. ****/
  1057. //} // End of If for Bug - 340 - MKarki
  1058. /*
  1059. // Flip factoring
  1060. if (wNumFound == 2)
  1061. {
  1062. SYSTEMTIME st;
  1063. GetSystemTime(&st);
  1064. srand((UINT)st.wMilliseconds);
  1065. if ((rand() % 10) > pSuggest->rgLPACCESSENTRY[0]->bFlipFactor)
  1066. {
  1067. lpAccessEntry = pSuggest->rgLPACCESSENTRY[0];
  1068. pSuggest->rgpAccessEntry[0] = pSuggest->rgpAccessEntry[1];
  1069. pSuggest->rgpAccessEntry[1] = lpAccessEntry;
  1070. }
  1071. }
  1072. */
  1073. hr = ERROR_SUCCESS;
  1074. SuggestExit:
  1075. pSuggest->wNumber = wNumFound;
  1076. return hr;
  1077. }
  1078. // ############################################################################
  1079. HRESULT CPhoneBook::GetCanonical (PACCESSENTRY pAE, LPTSTR psOut)
  1080. {
  1081. HRESULT hr = ERROR_SUCCESS;
  1082. LPIDLOOKUPELEMENT pIDLookUp;
  1083. pIDLookUp = (LPIDLOOKUPELEMENT)bsearch(&pAE->dwCountryID,m_rgIDLookUp,
  1084. (int)m_pLineCountryList->dwNumCountries,sizeof(IDLOOKUPELEMENT),CompareIdxLookUpElements);
  1085. if (!pIDLookUp)
  1086. {
  1087. hr = ERROR_INVALID_PARAMETER;
  1088. } else {
  1089. SzCanonicalFromAE (psOut, pAE, pIDLookUp->pLCE);
  1090. }
  1091. return hr;
  1092. }
  1093. // ############################################################################
  1094. DllExportH PhoneBookLoad(LPCTSTR pszISPCode, DWORD_PTR far *pdwPhoneID)
  1095. {
  1096. HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
  1097. CPhoneBook far *pcPhoneBook;
  1098. if (!g_hInstDll)
  1099. g_hInstDll = GetModuleHandle(NULL);
  1100. // validate parameters
  1101. Assert(pszISPCode && *pszISPCode && pdwPhoneID);
  1102. *pdwPhoneID = NULL;
  1103. // allocate phone book
  1104. pcPhoneBook = new CPhoneBook;
  1105. // initialize phone book
  1106. if (pcPhoneBook)
  1107. hr = pcPhoneBook->Init(pszISPCode);
  1108. // in case of failure
  1109. if (hr && pcPhoneBook)
  1110. {
  1111. delete pcPhoneBook;
  1112. } else {
  1113. *pdwPhoneID = (DWORD_PTR)pcPhoneBook;
  1114. }
  1115. #if defined(WIN16)
  1116. if (!hr)
  1117. BMP_RegisterClass(g_hInstDll);
  1118. #endif
  1119. return hr;
  1120. }
  1121. // ############################################################################
  1122. DllExportH PhoneBookUnload(DWORD_PTR dwPhoneID)
  1123. {
  1124. Assert(dwPhoneID);
  1125. if (dwPhoneID)
  1126. {
  1127. #if defined(WIN16)
  1128. BMP_DestroyClass(g_hInstDll);
  1129. #endif
  1130. // Release contents
  1131. delete (CPhoneBook far*)dwPhoneID;
  1132. }
  1133. return ERROR_SUCCESS;
  1134. }
  1135. // ############################################################################
  1136. DllExportH PhoneBookMergeChanges(DWORD_PTR dwPhoneID, LPCTSTR pszChangeFile)
  1137. {
  1138. return ((CPhoneBook far*)dwPhoneID)->Merge(pszChangeFile);
  1139. }
  1140. // ############################################################################
  1141. DllExportH PhoneBookSuggestNumbers(DWORD_PTR dwPhoneID, PSUGGESTINFO lpSuggestInfo)
  1142. {
  1143. HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
  1144. // get suggested numbers
  1145. lpSuggestInfo->rgpAccessEntry = (PACCESSENTRY *)GlobalAlloc(GPTR,sizeof(PACCESSENTRY) * lpSuggestInfo->wNumber);
  1146. if (lpSuggestInfo->rgpAccessEntry)
  1147. {
  1148. hr = ((CPhoneBook far *)dwPhoneID)->Suggest(lpSuggestInfo);
  1149. }
  1150. return hr;
  1151. }
  1152. // ############################################################################
  1153. DllExportH PhoneBookGetCanonical (DWORD_PTR dwPhoneID, PACCESSENTRY pAE, LPTSTR psOut)
  1154. {
  1155. return ((CPhoneBook far*)dwPhoneID)->GetCanonical(pAE,psOut);
  1156. }
  1157. // ############################################################################
  1158. DllExportH PhoneBookDisplaySignUpNumbers (DWORD_PTR dwPhoneID,
  1159. LPTSTR far *ppszPhoneNumbers,
  1160. LPTSTR far *ppszDunFiles,
  1161. WORD far *pwPhoneNumbers,
  1162. DWORD far *pdwCountry,
  1163. WORD far *pwRegion,
  1164. BYTE fType,
  1165. BYTE bMask,
  1166. HWND hwndParent,
  1167. DWORD dwFlags)
  1168. {
  1169. HRESULT hr;
  1170. AssertMsg(ppszPhoneNumbers && pwPhoneNumbers && pdwCountry &&pwRegion,"invalid parameters");
  1171. //CAccessNumDlg *pcDlg;
  1172. CSelectNumDlg far *pcDlg;
  1173. pcDlg = new CSelectNumDlg;
  1174. if (!pcDlg)
  1175. {
  1176. hr = GetLastError();
  1177. goto DisplayExit;
  1178. }
  1179. // Initialize information for dialog
  1180. //
  1181. pcDlg->m_dwPhoneBook = dwPhoneID;
  1182. pcDlg->m_dwCountryID = *pdwCountry;
  1183. pcDlg->m_wRegion = *pwRegion;
  1184. pcDlg->m_fType = fType;
  1185. pcDlg->m_bMask = bMask;
  1186. pcDlg->m_dwFlags = dwFlags;
  1187. // invoke the dialog
  1188. //
  1189. // BUG: NOT THREAD SAFE!!
  1190. g_hWndMain = hwndParent;
  1191. hr = (HRESULT)DialogBoxParam(g_hInstDll,MAKEINTRESOURCE(IDD_SELECTNUMBER),
  1192. g_hWndMain, PhbkGenericDlgProc,(LPARAM)pcDlg);
  1193. g_hWndMain = NULL;
  1194. if (hr == IDC_CMDNEXT)
  1195. {
  1196. *pwRegion = pcDlg->m_wRegion;
  1197. *pdwCountry = pcDlg->m_dwCountryID;
  1198. Assert (ppszPhoneNumbers[0] && ppszDunFiles[0]);
  1199. lstrcpy(ppszPhoneNumbers[0],&pcDlg->m_szPhoneNumber[0]);
  1200. lstrcpy(ppszDunFiles[0],&pcDlg->m_szDunFile[0]);
  1201. hr = ERROR_SUCCESS;
  1202. }
  1203. else if (hr == IDC_CMDBACK)
  1204. hr = ERROR_USERBACK;
  1205. else
  1206. hr = ERROR_USERCANCEL;
  1207. // hr == -1;
  1208. DisplayExit:
  1209. if (pcDlg) delete pcDlg;
  1210. return hr;
  1211. }
  1212. //DllExportH TestBar()
  1213. //{
  1214. // LPCSTR pszISPCode;
  1215. // LPDWORD pdwPhoneID;
  1216. //
  1217. // HRESULT hr = ERROR_NOT_ENOUGH_MEMORY;
  1218. // CPhoneBook FAR *pcPhoneBook;
  1219. //
  1220. // if (!g_hInstDll)
  1221. // g_hInstDll = GetModuleHandle(NULL);
  1222. //
  1223. // // validate parameters
  1224. ////1 Assert(pszISPCode && *pszISPCode && pdwPhoneID);
  1225. ////1 *pdwPhoneID = NULL;
  1226. //
  1227. // // allocate phone book
  1228. ////1 pcPhoneBook = new CPhoneBook;
  1229. //
  1230. // // initialize phone book
  1231. // if (pcPhoneBook)
  1232. // hr = pcPhoneBook->Init(pszISPCode);
  1233. //
  1234. // // in case of failure
  1235. // if (hr && pcPhoneBook)
  1236. // {
  1237. // delete pcPhoneBook;
  1238. // } else {
  1239. // *pdwPhoneID = (DWORD)pcPhoneBook;
  1240. // }
  1241. //
  1242. ////2#if defined(WIN16)
  1243. ////2 if (!hr)
  1244. ////2 BMP_RegisterClass(g_hInstDll);
  1245. ////2#endif
  1246. //
  1247. // return hr;
  1248. //}
  1249. //
  1250. //++--------------------------------------------------------------
  1251. //
  1252. // API : GetSupportNumbers
  1253. //
  1254. // Synopsis: This is the API used to get the support
  1255. // numbers
  1256. //
  1257. // Returns: HRESULT - success or error info
  1258. //
  1259. // Arguments: [OUT] PSUPPORTNUM - array of SUPPORTNUM structs
  1260. // [IN/OUT] PDWORD - mem for buffersize
  1261. //
  1262. // Called By: by the EXE using the ICWPHBK.DLL
  1263. //
  1264. // History: MKarki Created 5/8/97
  1265. //
  1266. //----------------------------------------------------------------
  1267. DllExportH GetSupportNumbers (
  1268. PSUPPORTNUM pBuffer,
  1269. PDWORD pBufferSize
  1270. )
  1271. {
  1272. return (GetSupportNumsFromFile (pBuffer, pBufferSize));
  1273. } // end of GetSupportNumbers API call