Source code of Windows XP (NT5)
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.

1240 lines
36 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: cm_phbk.cpp
  4. //
  5. // Module: CMPBK32.DLL
  6. //
  7. // Synopsis: Implementation of the Private CM Phone book API.
  8. //
  9. // Copyright (c) 1998-1999 Microsoft Corporation
  10. //
  11. // Author: quintinb created header 08/17/99
  12. //
  13. //+----------------------------------------------------------------------------
  14. // ############################################################################
  15. // INCLUDES
  16. #include "cmmaster.h"
  17. #include <stddef.h>
  18. #include <limits.h>
  19. //#define DllImport extern "C" __declspec(dllimport)
  20. #define MIN_TAPI_VERSION 0x10004
  21. #define MAX_TAPI_VERSION 0x10004
  22. const TCHAR* const c_pszCmEntryIspFilterMask = TEXT("Mask&");
  23. const TCHAR* const c_pszCmEntryIspFilterMatch = TEXT("Match&");
  24. const TCHAR* const c_pszCmSectionServiceTypes = TEXT("Service Types");
  25. const TCHAR* const c_pszBps = TEXT("bps");
  26. #ifndef UNICODE
  27. CM_PHBK_DllExportP PhoneBookCopyFilter(PPBFS pFilterIn)
  28. {
  29. PPBFS pRes;
  30. DWORD dwSize;
  31. if (!pFilterIn)
  32. {
  33. SetLastError(ERROR_INVALID_PARAMETER);
  34. return NULL;
  35. }
  36. // Undocumented feature (used internally): always allocates room for one additional pair.
  37. dwSize = offsetof(PhoneBookFilterStruct,aData) + sizeof(pRes->aData) * (pFilterIn->dwCnt + 1);
  38. pRes = (PPBFS) CmMalloc((size_t) dwSize);
  39. if (pRes)
  40. {
  41. CopyMemory(pRes,pFilterIn,(size_t) dwSize - sizeof(pRes->aData));
  42. }
  43. return pRes;
  44. }
  45. CM_PHBK_DllExportV PhoneBookFreeFilter(PPBFS pFilter)
  46. {
  47. CmFree(pFilter);
  48. }
  49. CM_PHBK_DllExportB PhoneBookMatchFilter(PPBFS pFilter, DWORD dwValue)
  50. {
  51. DWORD dwIdx;
  52. if (!pFilter)
  53. {
  54. return FALSE;
  55. }
  56. for (dwIdx = 0; dwIdx < pFilter->dwCnt; dwIdx++)
  57. {
  58. if ((dwValue & pFilter->aData[dwIdx].dwMask) == pFilter->aData[dwIdx].dwMatch)
  59. {
  60. return TRUE;
  61. }
  62. }
  63. return FALSE;
  64. }
  65. static PPBFS GetFilterFromFile(LPCTSTR pszFile, LPCTSTR pszFilter)
  66. {
  67. LPTSTR pszFilterTmp;
  68. LPTSTR pszTmp;
  69. static PhoneBookFilterStruct sInit = {0,{{0,0}}};
  70. PPBFS pRes;
  71. CIni iniTmp(g_hInst,pszFile);
  72. pRes = PhoneBookCopyFilter(&sInit);
  73. if (!pRes)
  74. {
  75. return NULL;
  76. }
  77. pszFilterTmp = CmStrCpyAlloc(pszFilter);
  78. pszTmp = CmStrtok(pszFilterTmp,TEXT(" \t,"));
  79. while (pszTmp)
  80. {
  81. iniTmp.SetEntry(pszTmp);
  82. pRes->aData[pRes->dwCnt].dwMask = iniTmp.GPPI(c_pszCmSectionIsp,c_pszCmEntryIspFilterMask,0x00000000);
  83. pRes->aData[pRes->dwCnt].dwMatch = iniTmp.GPPI(c_pszCmSectionIsp,c_pszCmEntryIspFilterMatch,0xffffffff);
  84. pRes->dwCnt++;
  85. pszTmp = CmStrtok(NULL,TEXT(" \t,"));
  86. if (pszTmp)
  87. {
  88. PPBFS pResTmp;
  89. pResTmp = PhoneBookCopyFilter(pRes);
  90. PhoneBookFreeFilter(pRes);
  91. pRes = pResTmp;
  92. if (!pRes)
  93. {
  94. CmFree(pszFilterTmp);
  95. return NULL;
  96. }
  97. }
  98. }
  99. CmFree(pszFilterTmp);
  100. return pRes;
  101. }
  102. CM_PHBK_DllExportB PhoneBookParseInfoA(LPCSTR pszFile, PhoneBookParseInfoStructA *pInfo)
  103. {
  104. CIni iniFile(g_hInst,(LPCTSTR) pszFile);
  105. LPTSTR pszTmp;
  106. if (!pszFile || !pInfo || pInfo->dwSize != sizeof(*pInfo))
  107. {
  108. SetLastError(ERROR_INVALID_PARAMETER);
  109. return FALSE;
  110. }
  111. pszTmp = iniFile.GPPS(c_pszCmSectionIsp,c_pszCmEntryIspUrl);
  112. if (pInfo->pszURL && ((DWORD) lstrlen(pszTmp) >= pInfo->dwURL))
  113. {
  114. pInfo->dwURL = lstrlen(pszTmp) + 1;
  115. CmFree(pszTmp);
  116. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  117. return FALSE;
  118. }
  119. pInfo->dwURL = lstrlen(pszTmp) + 1;
  120. if (pInfo->pszURL)
  121. {
  122. lstrcpy(pInfo->pszURL,pszTmp);
  123. }
  124. CmFree(pszTmp);
  125. pszTmp = iniFile.GPPS(c_pszCmSectionIsp,c_pszCmEntryIspFilterA);
  126. pInfo->pFilterA = GetFilterFromFile((LPCTSTR) pszFile,pszTmp);
  127. CmFree(pszTmp);
  128. pszTmp = iniFile.GPPS(c_pszCmSectionIsp,c_pszCmEntryIspFilterB);
  129. pInfo->pFilterB = GetFilterFromFile((LPCTSTR) pszFile,pszTmp);
  130. CmFree(pszTmp);
  131. if (pInfo->pfnSvc)
  132. {
  133. LPTSTR pszSvc;
  134. pszTmp = iniFile.GPPS(c_pszCmSectionServiceTypes,(LPTSTR) NULL);
  135. pszSvc = pszTmp;
  136. while (*pszSvc)
  137. {
  138. LPTSTR pszFilter;
  139. PPBFS pFilter;
  140. pszFilter = iniFile.GPPS(c_pszCmSectionServiceTypes,pszSvc);
  141. pFilter = GetFilterFromFile((LPCTSTR) pszFile,pszFilter);
  142. CmFree(pszFilter);
  143. if (!pInfo->pfnSvc(pszSvc,pFilter,pInfo->dwSvcParam))
  144. {
  145. break;
  146. }
  147. pszSvc += lstrlen(pszSvc) + 1;
  148. }
  149. CmFree(pszTmp);
  150. }
  151. if (pInfo->pfnRef)
  152. {
  153. LPTSTR pszRef,pszNext;
  154. CIni iniRef(g_hInst);
  155. pszTmp = iniFile.GPPS(c_pszCmSectionIsp, c_pszCmEntryIspReferences);
  156. pszRef = NULL;
  157. pszNext = pszTmp;
  158. while (1)
  159. {
  160. LPTSTR pszURL;
  161. LPTSTR pszRefTmp;
  162. PPBFS pFilterA;
  163. PPBFS pFilterB;
  164. //
  165. // Parse out reference list
  166. //
  167. pszRef = CmStrtok(pszNext,TEXT(" \t,"));
  168. if (pszRef)
  169. {
  170. pszNext = pszRef + lstrlen(pszRef)+1; // CHECK FOR MBCS COMPATIBLITY
  171. }
  172. if (!pszRef)
  173. {
  174. break;
  175. }
  176. //
  177. // Setup ini file and paths for this reference
  178. //
  179. iniFile.SetEntry(pszRef);
  180. LPTSTR pszRefFile = (LPTSTR) CmMalloc(MAX_PATH+1);
  181. LPTSTR pszBasePath = GetBaseDirFromCms(pszFile);
  182. LPTSTR pszPhoneFile = (LPTSTR) CmMalloc(MAX_PATH+1);
  183. pszRefTmp = iniFile.GPPS(c_pszCmSectionIsp,c_pszCmEntryIspCmsFile);
  184. //
  185. // Make sure we have a full path to the .CMS
  186. //
  187. if (pszRefTmp && *pszRefTmp && pszRefFile && pszPhoneFile && pszBasePath)
  188. {
  189. LPTSTR pszTemp = NULL;
  190. if (SearchPath(pszBasePath, pszRefTmp, NULL, MAX_PATH, pszRefFile, &pszTemp))
  191. {
  192. iniRef.SetFile(pszRefFile);
  193. }
  194. CmFree(pszRefTmp);
  195. //
  196. // Verify that phone books for this reference exists.
  197. //
  198. pszRefTmp = iniRef.GPPS(c_pszCmSectionIsp, c_pszCmEntryIspPbFile);
  199. //
  200. // If there is a phonebook file name in the .CMS, use
  201. // it to construct a full path to the PhoneBook file.
  202. //
  203. if (*pszRefTmp)
  204. {
  205. lstrcpy(pszPhoneFile, pszBasePath);
  206. lstrcat(pszPhoneFile, TEXT("\\"));
  207. lstrcat(pszPhoneFile, pszRefTmp);
  208. }
  209. else
  210. {
  211. *pszPhoneFile = 0;
  212. }
  213. CmFree(pszRefTmp);
  214. //
  215. // If we have a name, see if the file exists
  216. //
  217. if (*pszPhoneFile)
  218. {
  219. HANDLE hFile = CreateFile(pszPhoneFile, 0,
  220. FILE_SHARE_READ | FILE_SHARE_WRITE,
  221. NULL, OPEN_EXISTING,
  222. FILE_ATTRIBUTE_NORMAL, NULL);
  223. //
  224. // If the file does not exist, we create an empty one
  225. //
  226. if (INVALID_HANDLE_VALUE == hFile)
  227. {
  228. hFile = CreateFile(pszPhoneFile,
  229. GENERIC_READ|GENERIC_WRITE, 0,
  230. (LPSECURITY_ATTRIBUTES)NULL,
  231. CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
  232. NULL);
  233. if (INVALID_HANDLE_VALUE == hFile)
  234. {
  235. //
  236. // If for some reason we failed to create the file,
  237. // we skip this reference pbk.
  238. //
  239. CmFree(pszBasePath);
  240. CmFree(pszPhoneFile);
  241. CmFree(pszRefFile);
  242. continue;
  243. }
  244. CloseHandle(hFile);
  245. }
  246. else
  247. {
  248. CloseHandle(hFile);
  249. }
  250. }
  251. //
  252. // We have a file, get the URL and the filters
  253. //
  254. pszRefTmp = iniFile.GPPS(c_pszCmSectionIsp,c_pszCmEntryIspUrl);
  255. pszURL = iniRef.GPPS(c_pszCmSectionIsp,c_pszCmEntryIspUrl,pszRefTmp);
  256. CmFree(pszRefTmp);
  257. pszRefTmp = iniFile.GPPS(c_pszCmSectionIsp,c_pszCmEntryIspFilterA);
  258. pFilterA = GetFilterFromFile(iniFile.GetFile(),pszRefTmp);
  259. CmFree(pszRefTmp);
  260. pszRefTmp = iniFile.GPPS(c_pszCmSectionIsp,c_pszCmEntryIspFilterB);
  261. pFilterB = GetFilterFromFile(iniFile.GetFile(),pszRefTmp);
  262. CmFree(pszRefTmp);
  263. pszRefTmp = NULL;
  264. pInfo->pfnRef(pszRefFile,pszURL,pFilterA,pFilterB,pInfo->dwRefParam);
  265. PhoneBookFreeFilter(pFilterA);
  266. PhoneBookFreeFilter(pFilterB);
  267. CmFree(pszURL);
  268. }
  269. //
  270. // Cleanup
  271. //
  272. CmFree(pszRefTmp);
  273. CmFree(pszRefFile);
  274. CmFree(pszPhoneFile);
  275. CmFree(pszBasePath);
  276. }
  277. CmFree(pszTmp);
  278. }
  279. return TRUE;
  280. }
  281. CM_PHBK_DllExportV PhoneBookEnumCountries(DWORD_PTR dwPB,
  282. PhoneBookCallBack pfnCountry,
  283. PPBFS pFilter,
  284. DWORD_PTR dwParam)
  285. {
  286. ((CPhoneBook *) dwPB)->EnumCountries(pFilter,pfnCountry,dwParam);
  287. }
  288. //
  289. // Note: this function and its mirror function PhoneBookGetStringW must stay in sync
  290. //
  291. static BOOL PhoneBookGetStringA(LPCSTR pszSrc, LPSTR pszDest, DWORD *pdwDest)
  292. {
  293. DWORD dwTmp = lstrlen(pszSrc);
  294. if (dwTmp > *pdwDest)
  295. {
  296. *pdwDest = dwTmp;
  297. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  298. return FALSE;
  299. }
  300. lstrcpy(pszDest,pszSrc);
  301. *pdwDest = dwTmp;
  302. return TRUE;
  303. }
  304. //
  305. // Note: this function and its mirror function PhoneBookGetStringA must stay in sync
  306. //
  307. static BOOL PhoneBookGetStringW(LPCWSTR pszSrc, LPWSTR pszDest, DWORD *pdwDest)
  308. {
  309. DWORD dwTmp = lstrlenW(pszSrc);
  310. if (dwTmp > *pdwDest)
  311. {
  312. *pdwDest = dwTmp;
  313. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  314. return FALSE;
  315. }
  316. lstrcpyW(pszDest,pszSrc);
  317. *pdwDest = dwTmp;
  318. return TRUE;
  319. }
  320. CM_PHBK_DllExportB PhoneBookGetCountryNameA(DWORD_PTR dwPB, unsigned int nIdx, LPSTR pszCountryName, DWORD *pdwCountryName)
  321. {
  322. return (PhoneBookGetStringA(((CPhoneBook *) dwPB)->GetCountryNameByIdx(nIdx),pszCountryName,pdwCountryName));
  323. }
  324. CM_PHBK_DllExportB PhoneBookGetCountryNameW(DWORD_PTR dwPB, unsigned int nIdx, LPWSTR pszCountryName, DWORD *pdwCountryName)
  325. {
  326. return (PhoneBookGetStringW(((CPhoneBook *) dwPB)->GetCountryNameByIdxW(nIdx),pszCountryName,pdwCountryName));
  327. }
  328. CM_PHBK_DllExportD PhoneBookGetCountryId(DWORD_PTR dwPB, unsigned int nIdx)
  329. {
  330. return (((CPhoneBook *) dwPB)->GetCountryIDByIdx(nIdx));
  331. }
  332. CM_PHBK_DllExportB PhoneBookHasPhoneType(DWORD_PTR dwPB, PPBFS pFilter)
  333. {
  334. return ((CPhoneBook *) dwPB)->FHasPhoneType(pFilter);
  335. }
  336. CM_PHBK_DllExportV PhoneBookEnumRegions(DWORD_PTR dwPB,
  337. PhoneBookCallBack pfnRegion,
  338. DWORD dwCountryID,
  339. PPBFS pFilter,
  340. DWORD_PTR dwParam)
  341. {
  342. ((CPhoneBook *) dwPB)->EnumRegions(dwCountryID,pFilter,pfnRegion,dwParam);
  343. }
  344. CM_PHBK_DllExportB PhoneBookGetRegionNameA(DWORD_PTR dwPB,
  345. unsigned int nIdx,
  346. LPSTR pszRegionName,
  347. DWORD *pdwRegionName)
  348. {
  349. return (PhoneBookGetStringA(((CPhoneBook *) dwPB)->GetRegionNameByIdx(nIdx),pszRegionName,pdwRegionName));
  350. }
  351. CM_PHBK_DllExportB PhoneBookGetPhoneCanonicalA(DWORD_PTR dwPB, DWORD dwIdx, LPSTR pszPhoneNumber, DWORD *pdwPhoneNumber)
  352. {
  353. char szTmp[64];
  354. ((CPhoneBook *) dwPB)->GetCanonical(dwIdx,szTmp);
  355. return (PhoneBookGetStringA(szTmp,pszPhoneNumber,pdwPhoneNumber));
  356. }
  357. CM_PHBK_DllExportB PhoneBookGetPhoneNonCanonicalA(DWORD_PTR dwPB, DWORD dwIdx, LPSTR pszPhoneNumber, DWORD *pdwPhoneNumber)
  358. {
  359. char szTmp[64];
  360. ((CPhoneBook *) dwPB)->GetNonCanonical(dwIdx,szTmp);
  361. return (PhoneBookGetStringA(szTmp,pszPhoneNumber,pdwPhoneNumber));
  362. }
  363. CM_PHBK_DllExportD PhoneBookGetPhoneType(DWORD_PTR dwPB, unsigned int nIdx)
  364. {
  365. return (((CPhoneBook *) dwPB)->GetPhoneTypeByIdx(nIdx));
  366. }
  367. CM_PHBK_DllExportV PhoneBookEnumNumbers(DWORD_PTR dwPB,
  368. PhoneBookCallBack pfnNumber,
  369. DWORD dwCountryID,
  370. unsigned int nRegion,
  371. PPBFS pFilter,
  372. DWORD_PTR dwParam)
  373. {
  374. if (nRegion != UINT_MAX)
  375. {
  376. ((CPhoneBook *) dwPB)->EnumNumbersByRegion(nRegion,dwCountryID,pFilter,pfnNumber,dwParam);
  377. }
  378. else
  379. {
  380. ((CPhoneBook *) dwPB)->EnumNumbersByCountry(dwCountryID,pFilter,pfnNumber,dwParam);
  381. }
  382. }
  383. CM_PHBK_DllExportV PhoneBookEnumNumbersWithRegionsZero(DWORD_PTR dwPB,
  384. PhoneBookCallBack pfnNumber,
  385. DWORD dwCountryID,
  386. PPBFS pFilter,
  387. DWORD_PTR dwParam)
  388. {
  389. ((CPhoneBook *) dwPB)->EnumNumbersByRegion(UINT_MAX,
  390. dwCountryID,
  391. pFilter,
  392. pfnNumber,
  393. dwParam);
  394. }
  395. //+---------------------------------------------------------------------------
  396. //
  397. // Function static GetPhoneBaudDesc()
  398. //
  399. // Description:
  400. // Get the phone baudrate discription in " (BaudMin - BaudMax bps)" format
  401. //
  402. // Arguments:
  403. // IN CPhoneBook* pPB: Pointer to phone book
  404. // DWORD dwIdx: Index for PhoneBook.m_rgPhoneBookEntry[]
  405. // OUT LPTSTR pszBaudDisp: Hold output text, should have enough space to hold the output
  406. //
  407. //+---------------------------------------------------------------------------
  408. static void GetPhoneBaudDesc(IN CPhoneBook* pPB, DWORD dwIdx, OUT LPTSTR pszBaudDisp)
  409. {
  410. MYDBGASSERT(pPB != NULL);
  411. MYDBGASSERT(pszBaudDisp != NULL);
  412. DWORD dwMinBaud = pPB->GetMinBaudByIdx(dwIdx);
  413. DWORD dwMaxBaud = pPB->GetMaxBaudByIdx(dwIdx);
  414. if (dwMinBaud == 0 && dwMaxBaud == 0)
  415. {
  416. //
  417. // If both dwMinBaud and dwMaxBaud are 0, we are done
  418. //
  419. pszBaudDisp[0] = 0;
  420. }
  421. else
  422. {
  423. //
  424. // If the min/max baud are identical
  425. // don't bother displaying as a range, just display the number 400: (400 bps)
  426. //
  427. if (dwMinBaud == dwMaxBaud)
  428. wsprintf(pszBaudDisp, " (%lu %s)", dwMaxBaud, c_pszBps); // " (Baud bps)"
  429. else if (dwMinBaud == 0)
  430. wsprintf(pszBaudDisp, " (1-%lu %s)", dwMaxBaud, c_pszBps); // " (1-dwMaxBaud bps)"
  431. else if (dwMaxBaud == 0)
  432. wsprintf(pszBaudDisp, " (%lu+ %s)", dwMinBaud, c_pszBps); // " (dwMinBaud+ bps)"
  433. else
  434. wsprintf(pszBaudDisp, " (%lu-%lu %s)", dwMinBaud, dwMaxBaud, c_pszBps); // " (dwMinBaud-dwMaxBaud bps)"
  435. }
  436. }
  437. //+---------------------------------------------------------------------------
  438. //
  439. // Function PhoneBookGetPhoneDispA()
  440. //
  441. // Description:
  442. // Format the phone discription text form phonebook dwPB and index dwIndx
  443. // "City (AreaCode) AccessNumber (MinBaud-MaxBaud bps)"
  444. //
  445. // Arguments:
  446. // DWORD_PTR dwPB: Pointer to phone book
  447. // DWORD dwIdx: Index for PhoneBook.m_rgPhoneBookEntry[]
  448. // LPTSTR pszDisp: ???
  449. // DWORD *pdwDisp: ???
  450. //
  451. // Return: ???
  452. //
  453. //+---------------------------------------------------------------------------
  454. CM_PHBK_DllExportB PhoneBookGetPhoneDispA(DWORD_PTR dwPB, DWORD dwIdx, LPTSTR pszDisp, DWORD *pdwDisp)
  455. {
  456. CPhoneBook *pPB = (CPhoneBook *) dwPB;
  457. TCHAR szTmp[256];
  458. MYDBGASSERT(pPB != NULL);
  459. //
  460. // If AreaCode is not empty then format is "City (AreaCode) AccessNumber" ...
  461. //
  462. if (pPB->GetAreaCodeByIdx(dwIdx)[0] != '\0')
  463. {
  464. wsprintf(szTmp,
  465. "%s (%s) %s",
  466. pPB->GetCityNameByIdx(dwIdx),
  467. pPB->GetAreaCodeByIdx(dwIdx),
  468. pPB->GetAccessNumberByIdx(dwIdx));
  469. }
  470. else
  471. {
  472. //
  473. // Otherwise, AreaCode is empty, format is "City AccessNumber" ...
  474. //
  475. wsprintf(szTmp,
  476. "%s %s",
  477. pPB->GetCityNameByIdx(dwIdx),
  478. pPB->GetAccessNumberByIdx(dwIdx));
  479. }
  480. //
  481. // Get the "(BaudMin-BaudMax bps)" text
  482. //
  483. TCHAR szBaudStr[64];
  484. GetPhoneBaudDesc(pPB, dwIdx, szBaudStr);
  485. lstrcat(szTmp, szBaudStr);
  486. return (PhoneBookGetStringA(szTmp,pszDisp,pdwDisp));
  487. }
  488. //+---------------------------------------------------------------------------
  489. //
  490. // PhoneBookGetPhoneDescA()
  491. //
  492. // Description:
  493. // Format part of the phone discription text form phonebook dwPB and index dwIndx
  494. // "City (MinBaud-MaxBaud bps)"
  495. //
  496. // Arguments:
  497. // DWORD_PTR dwPB: Pointer to phone book
  498. // DWORD dwIdx: Index for PhoneBook.m_rgPhoneBookEntry[]
  499. // LPTSTR pszDisp: ???
  500. // DWORD *pdwDisp: ???
  501. //
  502. // Return: ???
  503. //
  504. //+---------------------------------------------------------------------------
  505. CM_PHBK_DllExportB PhoneBookGetPhoneDescA(DWORD_PTR dwPB, DWORD dwIdx, LPTSTR pszDesc, DWORD *pdwDesc)
  506. {
  507. CPhoneBook *pPB = (CPhoneBook *) dwPB;
  508. TCHAR szTmp[256];
  509. lstrcpy(szTmp, pPB->GetCityNameByIdx(dwIdx));
  510. //
  511. // Get the "(BaudMin-BaudMax bps)" text
  512. //
  513. TCHAR szBaudStr[64];
  514. GetPhoneBaudDesc(pPB, dwIdx, szBaudStr);
  515. lstrcat(szTmp, szBaudStr);
  516. return (PhoneBookGetStringA(szTmp,pszDesc,pdwDesc));
  517. }
  518. VOID FAR PASCAL CMPB_LineCallback(DWORD hDevice,
  519. DWORD dwMsg,
  520. DWORD dwCallbackInstance,
  521. DWORD dwParam1,
  522. DWORD dwParam2,
  523. DWORD dwParam3)
  524. {
  525. // nothing
  526. }
  527. static LPVOID GetTapiPfn(HINSTANCE *phInst, LPCTSTR pszFn)
  528. {
  529. LPVOID pvRes = NULL;
  530. *phInst = LoadLibrary(TEXT("tapi32"));
  531. if (*phInst)
  532. {
  533. pvRes = GetProcAddress(*phInst,pszFn);
  534. if (pvRes)
  535. {
  536. return pvRes;
  537. }
  538. FreeLibrary(*phInst);
  539. }
  540. return NULL;
  541. }
  542. static LONG PBlineInitialize(LPHLINEAPP lphLineApp,
  543. HINSTANCE hInstance,
  544. LINECALLBACK lpfnCallback,
  545. LPCSTR lpszAppName,
  546. LPDWORD lpdwNumDevs)
  547. {
  548. HINSTANCE hInst;
  549. LONG (WINAPI *pfn)(LPHLINEAPP,HINSTANCE,LINECALLBACK,LPCSTR,LPDWORD);
  550. LONG lRes;
  551. pfn = (LONG (WINAPI *)(LPHLINEAPP,HINSTANCE,LINECALLBACK,LPCSTR,LPDWORD)) GetTapiPfn(&hInst,"lineInitialize");
  552. if (!pfn)
  553. {
  554. return LINEERR_NOMEM;
  555. }
  556. lRes = pfn(lphLineApp,hInstance,lpfnCallback,lpszAppName,lpdwNumDevs);
  557. FreeLibrary(hInst);
  558. return lRes;
  559. }
  560. static LONG PBlineNegotiateAPIVersion(HLINEAPP hLineApp,
  561. DWORD dwDeviceID,
  562. DWORD dwAPILowVersion,
  563. DWORD dwAPIHighVersion,
  564. LPDWORD lpdwAPIVersion,
  565. LPLINEEXTENSIONID lpExtensionID)
  566. {
  567. HINSTANCE hInst;
  568. LONG (WINAPI *pfn)(HLINEAPP,DWORD,DWORD,DWORD,LPDWORD,LPLINEEXTENSIONID);
  569. LONG lRes;
  570. pfn = (LONG (WINAPI *)(HLINEAPP,DWORD,DWORD,DWORD,LPDWORD,LPLINEEXTENSIONID)) GetTapiPfn(&hInst,"lineNegotiateAPIVersion");
  571. if (!pfn)
  572. {
  573. return LINEERR_NOMEM;
  574. }
  575. lRes = pfn(hLineApp,dwDeviceID,dwAPILowVersion,dwAPIHighVersion,lpdwAPIVersion,lpExtensionID);
  576. FreeLibrary(hInst);
  577. return lRes;
  578. }
  579. static LONG PBlineGetTranslateCaps(HLINEAPP hLineApp, DWORD dwAPIVersion, LPLINETRANSLATECAPS lpTranslateCaps)
  580. {
  581. HINSTANCE hInst;
  582. LONG (WINAPI *pfn)(HLINEAPP,DWORD,LPLINETRANSLATECAPS);
  583. LONG lRes;
  584. pfn = (LONG (WINAPI *)(HLINEAPP,DWORD,LPLINETRANSLATECAPS)) GetTapiPfn(&hInst,"lineGetTranslateCaps");
  585. if (!pfn)
  586. {
  587. return LINEERR_NOMEM;
  588. }
  589. lRes = pfn(hLineApp,dwAPIVersion,lpTranslateCaps);
  590. FreeLibrary(hInst);
  591. return lRes;
  592. }
  593. static LONG PBlineShutdown(HLINEAPP hLineApp)
  594. {
  595. HINSTANCE hInst;
  596. LONG (WINAPI *pfn)(HLINEAPP);
  597. LONG lRes;
  598. pfn = (LONG (WINAPI *)(HLINEAPP)) GetTapiPfn(&hInst,"lineShutdown");
  599. if (!pfn)
  600. {
  601. return LINEERR_NOMEM;
  602. }
  603. lRes = pfn(hLineApp);
  604. FreeLibrary(hInst);
  605. return lRes;
  606. }
  607. static DWORD PhoneBookGetCurrentCountryIdAndCode(LPDWORD pdwCountryCode)
  608. {
  609. HLINEAPP hLine = NULL;
  610. DWORD dwCountry = 1;
  611. DWORD dwCountryCode = 1;
  612. DWORD dwDevices;
  613. LPLINETRANSLATECAPS pTC = NULL;
  614. LPLINELOCATIONENTRY plle;
  615. DWORD dwAPI;
  616. PBlineInitialize(&hLine,g_hInst,CMPB_LineCallback,NULL,&dwDevices);
  617. if (!hLine)
  618. {
  619. goto done;
  620. }
  621. while (dwDevices)
  622. {
  623. LINEEXTENSIONID leid;
  624. if (PBlineNegotiateAPIVersion(hLine,dwDevices-1,0x00010004,0x00010004,&dwAPI,&leid) == ERROR_SUCCESS)
  625. {
  626. break;
  627. }
  628. dwDevices--;
  629. }
  630. if (!dwDevices)
  631. {
  632. goto done;
  633. }
  634. dwDevices--;
  635. pTC = (LPLINETRANSLATECAPS) CmMalloc(sizeof(LINETRANSLATECAPS));
  636. if (NULL == pTC)
  637. {
  638. goto done;
  639. }
  640. pTC->dwTotalSize = sizeof(LINETRANSLATECAPS);
  641. if (PBlineGetTranslateCaps(hLine,dwAPI,pTC) != ERROR_SUCCESS)
  642. {
  643. goto done;
  644. }
  645. dwCountry = pTC->dwNeededSize;
  646. CmFree(pTC);
  647. pTC = (LPLINETRANSLATECAPS) CmMalloc((size_t) dwCountry);
  648. if (NULL == pTC)
  649. {
  650. goto done;
  651. }
  652. pTC->dwTotalSize = dwCountry;
  653. dwCountry = 1;
  654. if (PBlineGetTranslateCaps(hLine,dwAPI,pTC) != ERROR_SUCCESS)
  655. {
  656. goto done;
  657. }
  658. plle = (LPLINELOCATIONENTRY) (((LPBYTE) pTC) + pTC->dwLocationListOffset);
  659. for (dwDevices=0;dwDevices<pTC->dwNumLocations;dwDevices++,plle++)
  660. {
  661. if (pTC->dwCurrentLocationID == plle->dwPermanentLocationID)
  662. {
  663. dwCountry = plle->dwCountryID;
  664. dwCountryCode = plle->dwCountryCode;
  665. break;
  666. }
  667. }
  668. done:
  669. if (hLine)
  670. {
  671. PBlineShutdown(hLine);
  672. }
  673. CmFree(pTC);
  674. if (pdwCountryCode)
  675. {
  676. *pdwCountryCode = dwCountryCode;
  677. }
  678. return dwCountry;
  679. }
  680. CM_PHBK_DllExportD PhoneBookGetCurrentCountryId()
  681. {
  682. return (PhoneBookGetCurrentCountryIdAndCode(NULL));
  683. }
  684. CM_PHBK_DllExportB PhoneBookGetPhoneDUNA(DWORD_PTR dwPB, DWORD dwIdx, LPSTR pszDUN, DWORD *pdwDUN)
  685. {
  686. return (PhoneBookGetStringA(((CPhoneBook *) dwPB)->GetDataCenterByIdx(dwIdx),pszDUN,pdwDUN));
  687. }
  688. #else // The following routines only exist for UNICODE versions.
  689. // UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE
  690. // UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE
  691. // UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE UNICODE
  692. // Helpers
  693. static LPSTR wc2mb(UINT nCP, LPCWSTR pszStr)
  694. {
  695. int iLen;
  696. LPSTR pszTmp;
  697. iLen = WideCharToMultiByte(nCP,0,pszStr,-1,NULL,0,NULL,NULL);
  698. pszTmp = (LPSTR) CmMalloc(iLen*sizeof(*pszTmp));
  699. if (pszTmp)
  700. {
  701. iLen = WideCharToMultiByte(nCP,0,pszStr,-1,pszTmp,iLen,NULL,NULL);
  702. if (!iLen)
  703. {
  704. CmFree(pszTmp);
  705. return NULL;
  706. }
  707. }
  708. return pszTmp;
  709. }
  710. static LPWSTR mb2wc(UINT nCP, LPCSTR pszStr)
  711. {
  712. int iLen;
  713. LPWSTR pszTmp;
  714. iLen = MultiByteToWideChar(nCP,0,pszStr,-1,NULL,0);
  715. pszTmp = (LPWSTR) CmMalloc(iLen*sizeof(*pszTmp));
  716. if (pszTmp)
  717. {
  718. iLen = MultiByteToWideChar(nCP,0,pszStr,-1,pszTmp,iLen);
  719. if (!iLen)
  720. {
  721. CmFree(pszTmp);
  722. return NULL;
  723. }
  724. }
  725. return pszTmp;
  726. }
  727. static void strcpy_wc2mb(UINT nCP, LPSTR pszDest, LPCWSTR pszSrc)
  728. {
  729. LPSTR pszTmp;
  730. pszTmp = wc2mb(nCP,pszSrc);
  731. _mbscpy((unsigned char *) pszDest,(unsigned char *) pszTmp);
  732. CmFree(pszTmp);
  733. }
  734. static void strcpy_mb2wc(UINT nCP, LPWSTR pszDest, LPCSTR pszSrc)
  735. {
  736. LPWSTR pszTmp;
  737. pszTmp = mb2wc(nCP,pszSrc);
  738. wcscpy(pszDest,pszTmp);
  739. CmFree(pszTmp);
  740. }
  741. static void reW2A(const RASENTRYW *pIn, RASENTRYA *pOut)
  742. {
  743. pOut->dwSize = sizeof(*pOut);
  744. pOut->dwfOptions = pIn->dwfOptions;
  745. pOut->dwCountryID = pIn->dwCountryID;
  746. pOut->dwCountryCode = pIn->dwCountryCode;
  747. strcpy_wc2mb(CP_OEMCP,pOut->szAreaCode,pIn->szAreaCode);
  748. strcpy_wc2mb(CP_OEMCP,pOut->szLocalPhoneNumber,pIn->szLocalPhoneNumber);
  749. pOut->dwAlternateOffset = pIn->dwAlternateOffset + sizeof(*pOut) - sizeof(*pIn);
  750. CopyMemory(&pOut->ipaddr,&pIn->ipaddr,sizeof(pIn->ipaddr));
  751. CopyMemory(&pOut->ipaddrDns,&pIn->ipaddrDns,sizeof(pIn->ipaddrDns));
  752. CopyMemory(&pOut->ipaddrDnsAlt,&pIn->ipaddrDnsAlt,sizeof(pIn->ipaddrDnsAlt));
  753. CopyMemory(&pOut->ipaddrWins,&pIn->ipaddrWins,sizeof(pIn->ipaddrWins));
  754. CopyMemory(&pOut->ipaddrWinsAlt,&pIn->ipaddrWinsAlt,sizeof(pIn->ipaddrWinsAlt));
  755. pOut->dwFrameSize = pIn->dwFrameSize;
  756. pOut->dwfNetProtocols = pIn->dwfNetProtocols;
  757. pOut->dwFramingProtocol = pIn->dwFramingProtocol;
  758. strcpy_wc2mb(CP_OEMCP,pOut->szScript,pIn->szScript);
  759. strcpy_wc2mb(CP_OEMCP,pOut->szAutodialDll,pIn->szAutodialDll);
  760. strcpy_wc2mb(CP_OEMCP,pOut->szAutodialFunc,pIn->szAutodialFunc);
  761. strcpy_wc2mb(CP_OEMCP,pOut->szDeviceType,pIn->szDeviceType);
  762. strcpy_wc2mb(CP_OEMCP,pOut->szDeviceName,pIn->szDeviceName);
  763. strcpy_wc2mb(CP_OEMCP,pOut->szX25PadType,pIn->szX25PadType);
  764. strcpy_wc2mb(CP_OEMCP,pOut->szX25Address,pIn->szX25Address);
  765. strcpy_wc2mb(CP_OEMCP,pOut->szX25Facilities,pIn->szX25Facilities);
  766. strcpy_wc2mb(CP_OEMCP,pOut->szX25UserData,pIn->szX25UserData);
  767. pOut->dwChannels = pIn->dwChannels;
  768. if (pIn->dwAlternateOffset)
  769. {
  770. LPWSTR pszIn = (LPWSTR) (((LPBYTE) pIn) + pIn->dwAlternateOffset);
  771. LPSTR pszOut = (LPSTR) (((LPBYTE) pOut) + pOut->dwAlternateOffset);
  772. while (*pszIn)
  773. {
  774. strcpy_wc2mb(CP_OEMCP,pszOut,pszIn);
  775. pszIn += wcslen(pszIn) + 1;
  776. pszOut += _mbslen((unsigned char *) pszOut) + 1;
  777. }
  778. }
  779. }
  780. static void reA2W(const RASENTRYA *pIn, RASENTRYW *pOut)
  781. {
  782. pOut->dwSize = sizeof(*pOut);
  783. pOut->dwfOptions = pIn->dwfOptions;
  784. pOut->dwCountryID = pIn->dwCountryID;
  785. pOut->dwCountryCode = pIn->dwCountryCode;
  786. strcpy_mb2wc(CP_OEMCP,pOut->szAreaCode,pIn->szAreaCode);
  787. strcpy_mb2wc(CP_OEMCP,pOut->szLocalPhoneNumber,pIn->szLocalPhoneNumber);
  788. pOut->dwAlternateOffset = pIn->dwAlternateOffset + sizeof(*pOut) - sizeof(*pIn);
  789. CopyMemory(&pOut->ipaddr,&pIn->ipaddr,sizeof(pIn->ipaddr));
  790. CopyMemory(&pOut->ipaddrDns,&pIn->ipaddrDns,sizeof(pIn->ipaddrDns));
  791. CopyMemory(&pOut->ipaddrDnsAlt,&pIn->ipaddrDnsAlt,sizeof(pIn->ipaddrDnsAlt));
  792. CopyMemory(&pOut->ipaddrWins,&pIn->ipaddrWins,sizeof(pIn->ipaddrWins));
  793. CopyMemory(&pOut->ipaddrWinsAlt,&pIn->ipaddrWinsAlt,sizeof(pIn->ipaddrWinsAlt));
  794. pOut->dwFrameSize = pIn->dwFrameSize;
  795. pOut->dwfNetProtocols = pIn->dwfNetProtocols;
  796. pOut->dwFramingProtocol = pIn->dwFramingProtocol;
  797. strcpy_mb2wc(CP_OEMCP,pOut->szScript,pIn->szScript);
  798. strcpy_mb2wc(CP_OEMCP,pOut->szAutodialDll,pIn->szAutodialDll);
  799. strcpy_mb2wc(CP_OEMCP,pOut->szAutodialFunc,pIn->szAutodialFunc);
  800. strcpy_mb2wc(CP_OEMCP,pOut->szDeviceType,pIn->szDeviceType);
  801. strcpy_mb2wc(CP_OEMCP,pOut->szDeviceName,pIn->szDeviceName);
  802. strcpy_mb2wc(CP_OEMCP,pOut->szX25PadType,pIn->szX25PadType);
  803. strcpy_mb2wc(CP_OEMCP,pOut->szX25Address,pIn->szX25Address);
  804. strcpy_mb2wc(CP_OEMCP,pOut->szX25Facilities,pIn->szX25Facilities);
  805. strcpy_mb2wc(CP_OEMCP,pOut->szX25UserData,pIn->szX25UserData);
  806. pOut->dwChannels = pIn->dwChannels;
  807. if (pIn->dwAlternateOffset)
  808. {
  809. LPSTR pszIn = (LPSTR) (((LPBYTE) pIn) + pIn->dwAlternateOffset);
  810. LPWSTR pszOut = (LPWSTR) (((LPBYTE) pOut) + pOut->dwAlternateOffset);
  811. while (*pszIn)
  812. {
  813. strcpy_mb2wc(CP_OEMCP,pszOut,pszIn);
  814. pszIn += _mbslen((unsigned char *) pszIn) + 1;
  815. pszOut += wcslen(pszOut) + 1;
  816. }
  817. }
  818. }
  819. // Wide versions of current APIs
  820. static BOOL PhoneBookGetStringW(LPCSTR pszSrc, LPWSTR pszDest, DWORD *pdwDest)
  821. {
  822. DWORD dwTmp;
  823. dwTmp = MultiByteToWideChar(GetACP(),0,pszSrc,-1,NULL,0);
  824. if (dwTmp > *pdwDest)
  825. {
  826. *pdwDest = dwTmp;
  827. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  828. return FALSE;
  829. }
  830. dwTmp = MultiByteToWideChar(GetACP(),0,pszSrc,-1,pszDest,*pdwDest);
  831. *pdwDest = dwTmp;
  832. return TRUE;
  833. }
  834. static BOOL WINAPI PhoneBookParseInfoWSvcThunk(LPCSTR pszSvc,
  835. PPBFS pFilter,
  836. DWORD_PTR dwParam)
  837. {
  838. PhoneBookParseInfoStructW *pParam = (PhoneBookParseInfoStructW *) dwParam;
  839. LPWSTR pszTmpSvc;
  840. BOOL bRes;
  841. DWORD dwErr;
  842. pszTmpSvc = mb2wc(GetACP(),pszSvc);
  843. if (!pszTmpSvc) {
  844. return FALSE;
  845. }
  846. bRes = pParam->pfnSvc(pszTmpSvc,pFilter,pParam->dwSvcParam);
  847. if (!bRes) {
  848. dwErr = GetLastError();
  849. }
  850. CmFree(pszTmpSvc);
  851. if (!bRes) {
  852. SetLastError(dwErr);
  853. }
  854. return (bRes);
  855. }
  856. static BOOL WINAPI PhoneBookParseInfoWRefThunk(LPCSTR pszFile,
  857. LPCSTR pszURL,
  858. PPBFS pFilterA,
  859. PPBFS pFilterB,
  860. DWORD_PTR dwParam)
  861. {
  862. PhoneBookParseInfoStructW *pParam = (PhoneBookParseInfoStructW *) dwParam;
  863. LPWSTR pszTmpFile;
  864. LPWSTR pszTmpURL;
  865. DWORD dwErr;
  866. BOOL bRes;
  867. pszTmpFile = mb2wc(CP_OEMCP,pszFile);
  868. if (!pszTmpFile)
  869. {
  870. return FALSE;
  871. }
  872. pszTmpURL = mb2wc(CP_OEMCP,pszURL);
  873. if (!pszTmpURL)
  874. {
  875. dwErr = GetLastError();
  876. CmFree(pszTmpFile);
  877. SetLastError(dwErr);
  878. return FALSE;
  879. }
  880. bRes = pParam->pfnRef(pszTmpFile,pszTmpURL,pFilterA,pFilterB,pParam->dwRefParam);
  881. if (!bRes)
  882. {
  883. dwErr = GetLastError();
  884. }
  885. CmFree(pszTmpFile);
  886. CmFree(pszTmpURL);
  887. if (!bRes)
  888. {
  889. SetLastError(dwErr);
  890. }
  891. return bRes;
  892. }
  893. CM_PHBK_DllExportB PhoneBookGetCountryNameW(DWORD_PTR dwPB, unsigned int nIdx, LPWSTR pszCountryName, DWORD *pdwCountryName)
  894. {
  895. return (PhoneBookGetStringW(((CPhoneBook *) dwPB)->GetCountryNameByIdx(nIdx),pszCountryName,pdwCountryName));
  896. }
  897. CM_PHBK_DllExportB PhoneBookGetRegionNameW(DWORD_PTR dwPB, unsigned int nIdx, LPWSTR pszRegionName, DWORD *pdwRegionName)
  898. {
  899. return (PhoneBookGetStringW(((CPhoneBook *) dwPB)->GetRegionNameByIdx(nIdx),pszRegionName,pdwRegionName));
  900. }
  901. CM_PHBK_DllExportB PhoneBookGetPhoneCanonicalW(DWORD_PTR dwPB, DWORD dwIdx, LPWSTR pszPhoneNumber, DWORD *pdwPhoneNumber)
  902. {
  903. char szTmp[64];
  904. ((CPhoneBook *) dwPB)->GetCanonical(dwIdx,szTmp);
  905. return (PhoneBookGetStringW(szTmp,pszPhoneNumber,pdwPhoneNumber));
  906. }
  907. CM_PHBK_DllExportB PhoneBookGetPhoneNonCanonicalW(DWORD_PTR dwPB, DWORD dwIdx, LPWSTR pszPhoneNumber, DWORD *pdwPhoneNumber)
  908. {
  909. char szTmp[64];
  910. ((CPhoneBook *) dwPB)->GetNonCanonical(dwIdx,szTmp);
  911. return (PhoneBookGetStringW(szTmp,pszPhoneNumber,pdwPhoneNumber));
  912. }
  913. CM_PHBK_DllExportB PhoneBookParseInfoW(LPCWSTR pszFile, PhoneBookParseInfoStructW *pInfo)
  914. {
  915. LPSTR pszTmpFile;
  916. PhoneBookParseInfoStructA iInfo;
  917. BOOL bRes;
  918. DWORD dwErr;
  919. LPWSTR pszTmpURL;
  920. if (!pszFile || !pInfo || pInfo->dwSize != sizeof(*pInfo))
  921. {
  922. SetLastError(ERROR_INVALID_PARAMETER);
  923. return FALSE;
  924. }
  925. pszTmpFile = wc2mb(CP_OEMCP,pszFile);
  926. if (!pszTmpFile)
  927. {
  928. return FALSE;
  929. }
  930. ZeroMemory(&iInfo,sizeof(iInfo));
  931. iInfo.dwSize = sizeof(iInfo);
  932. iInfo.dwURL = MAX_PATH * 3 / 2;
  933. while (1)
  934. {
  935. iInfo.pszURL = (LPSTR) CmMalloc(iInfo.dwURL * sizeof(*iInfo.pszURL));
  936. if (NULL == iInfo.pszURL)
  937. {
  938. CmFree(pszTmpFile);
  939. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  940. return FALSE;
  941. }
  942. bRes = PhoneBookParseInfoA(pszTmpFile,&iInfo);
  943. if (bRes)
  944. {
  945. break;
  946. }
  947. dwErr = GetLastError();
  948. if (dwErr != ERROR_INSUFFICIENT_BUFFER)
  949. {
  950. CmFree(iInfo.pszURL);
  951. CmFree(pszTmpFile);
  952. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  953. return FALSE;
  954. }
  955. CmFree(iInfo.pszURL);
  956. }
  957. pszTmpURL = mb2wc(CP_OEMCP,iInfo.pszURL);
  958. if (!pszTmpURL)
  959. {
  960. dwErr = GetLastError();
  961. CmFree(pszTmpFile);
  962. CmFree(iInfo.pszURL);
  963. SetLastError(dwErr);
  964. return FALSE;
  965. }
  966. if (pInfo->pszURL && (wcslen(pszTmpURL) >= pInfo->dwURL))
  967. {
  968. pInfo->dwURL = wcslen(pszTmpURL) + 1;
  969. CmFree(pszTmpFile);
  970. CmFree(iInfo.pszURL);
  971. CmFree(pszTmpURL);
  972. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  973. return FALSE;
  974. }
  975. pInfo->dwURL = wcslen(pszTmpURL) + 1;
  976. if (pInfo->pszURL)
  977. {
  978. wcscpy(pInfo->pszURL,pszTmpURL);
  979. }
  980. CmFree(iInfo.pszURL);
  981. CmFree(pszTmpURL);
  982. pInfo->pFilterA = iInfo.pFilterA;
  983. pInfo->pFilterB = iInfo.pFilterB;
  984. if (!pInfo->pfnSvc && !pInfo->pfnRef)
  985. {
  986. CmFree(pszTmpFile);
  987. return TRUE;
  988. }
  989. iInfo.pszURL = NULL;
  990. if (pInfo->pfnSvc)
  991. {
  992. iInfo.pfnSvc = PhoneBookParseInfoWSvcThunk;
  993. iInfo.dwSvcParam = (DWORD_PTR) pInfo;
  994. }
  995. if (pInfo->pfnRef)
  996. {
  997. iInfo.pfnRef = PhoneBookParseInfoWRefThunk;
  998. iInfo.dwRefParam = (DWORD_PTR) pInfo;
  999. }
  1000. bRes = PhoneBookParseInfoA(pszTmpFile,&iInfo);
  1001. if (!bRes)
  1002. {
  1003. dwErr = GetLastError();
  1004. }
  1005. CmFree(pszTmpFile);
  1006. if (!bRes)
  1007. {
  1008. SetLastError(dwErr);
  1009. }
  1010. return bRes;
  1011. }
  1012. CM_PHBK_DllExportB PhoneBookGetPhoneDispW(DWORD_PTR dwPB, DWORD dwIdx, LPWSTR pszDisp, DWORD *pdwDisp)
  1013. {
  1014. CPhoneBook *pPB = (CPhoneBook *) dwPB;
  1015. char szTmp[256];
  1016. wsprintf(szTmp,
  1017. "%s (%s) %s (%u-%u %s)",
  1018. pPB->GetCityNameByIdx(dwIdx),
  1019. pPB->GetAreaCodeByIdx(dwIdx),
  1020. pPB->GetAccessNumberByIdx(dwIdx),
  1021. pPB->GetMinBaudByIdx(dwIdx),
  1022. pPB->GetMaxBaudByIdx(dwIdx),
  1023. c_pszBps);
  1024. return (PhoneBookGetStringW(szTmp,pszDisp,pdwDisp));
  1025. }
  1026. CM_PHBK_DllExportB PhoneBookGetPhoneDescW(DWORD_PTR dwPB, DWORD dwIdx, LPWSTR pszDesc, DWORD *pdwDesc)
  1027. {
  1028. CPhoneBook *pPB = (CPhoneBook *) dwPB;
  1029. char szTmp[256];
  1030. wsprintf(szTmp,
  1031. "%s (%u-%u %s)",
  1032. pPB->GetCityNameByIdx(dwIdx),
  1033. pPB->GetMinBaudByIdx(dwIdx),
  1034. pPB->GetMaxBaudByIdx(dwIdx),
  1035. c_pszBps);
  1036. return (PhoneBookGetStringW(szTmp,pszDesc,pdwDesc));
  1037. }
  1038. CM_PHBK_DllExportB PhoneBookGetPhoneDUNW(DWORD_PTR dwPB, DWORD dwIdx, LPWSTR pszDUN, DWORD *pdwDUN)
  1039. {
  1040. return (PhoneBookGetStringW(((CPhoneBook *) dwPB)->GetDataCenterByIdx(dwIdx),pszDUN,pdwDUN));
  1041. }
  1042. #endif // ndef UNICODE