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

521 lines
14 KiB

  1. // Copyright (c) 1996, Microsoft Corporation, all rights reserved
  2. //
  3. // phonenum.c
  4. // Phone number helper library
  5. // Listed alphabetically
  6. //
  7. // 03/06/96 Steve Cobb
  8. #include <windows.h> // Win32 root
  9. #include <nouiutil.h> // No-HWND utilities
  10. #include <tapiutil.h> // TAPI wrappers
  11. #include <phonenum.h> // Our public header
  12. #include <debug.h> // Trace/Assert library
  13. TCHAR*
  14. LinkPhoneNumberFromParts(
  15. IN HINSTANCE hInst,
  16. IN OUT HLINEAPP* pHlineapp,
  17. IN PBUSER* pUser,
  18. IN PBENTRY* pEntry,
  19. IN PBLINK* pLink,
  20. IN DWORD iPhoneNumber,
  21. IN TCHAR* pszOverrideNumber,
  22. IN BOOL fDialable )
  23. // Like PhoneNumberFromParts but takes a link and hunt group index as
  24. // input instead of a base number, and handles not modifying the number
  25. // associated with non-modem/ISDN links. If 'pszOverrideNumber' is
  26. // non-NULL and non-"" it is used instead of the derived number.
  27. //
  28. {
  29. DTLNODE* pNode;
  30. TCHAR* pszBaseNumber;
  31. PBPHONE* pPhone;
  32. if (pszOverrideNumber && *pszOverrideNumber)
  33. {
  34. // So, this is useful? RaoS?
  35. //
  36. return StrDup( pszOverrideNumber );
  37. }
  38. pNode = DtlNodeFromIndex( pLink->pdtllistPhones, iPhoneNumber );
  39. if (!pNode)
  40. {
  41. ASSERT( FALSE );
  42. return NULL;
  43. }
  44. pPhone = (PBPHONE *) DtlGetData(pNode);
  45. ASSERT( pPhone );
  46. if (pLink->pbport.pbdevicetype == PBDT_Modem
  47. || pLink->pbport.pbdevicetype == PBDT_Isdn)
  48. {
  49. BOOL fDownLevelIsdn;
  50. fDownLevelIsdn =
  51. (pLink->pbport.pbdevicetype == PBDT_Isdn
  52. && pLink->fProprietaryIsdn);
  53. return PhoneNumberFromParts(
  54. hInst, pHlineapp, pUser, pPhone, fDownLevelIsdn, fDialable );
  55. }
  56. else
  57. {
  58. return StrDup( pPhone->pszPhoneNumber );
  59. }
  60. }
  61. TCHAR*
  62. PhoneNumberFromParts(
  63. IN HINSTANCE hInst,
  64. IN OUT HLINEAPP* pHlineapp,
  65. IN PBUSER* pUser,
  66. IN PBPHONE* pPhone,
  67. IN BOOL fDownLevelIsdn,
  68. IN BOOL fDialable )
  69. // Returns a heap block containing the composite phone number using the
  70. // rules of 'pPhone' and 'pUser'. 'HInst' is the module handle.
  71. // 'PHlineapp' is the TAPI context. 'FDialable' indicates the dialable
  72. // string, instead of the displayable string, should be returned.
  73. //
  74. // It is caller's responsibility to Free the returned string.
  75. //
  76. {
  77. TCHAR* pszResult;
  78. TCHAR* pszBaseNumber;
  79. TRACE( "PhoneNumberFromParts" );
  80. pszBaseNumber = pPhone->pszPhoneNumber;
  81. if (!pszBaseNumber)
  82. {
  83. pszBaseNumber = TEXT("");
  84. }
  85. if (pPhone->fUseDialingRules)
  86. {
  87. pszResult =
  88. PhoneNumberFromTapiPartsEx( hInst, pszBaseNumber,
  89. pPhone->pszAreaCode, pPhone->dwCountryCode, fDownLevelIsdn,
  90. pHlineapp, fDialable );
  91. }
  92. else
  93. {
  94. TCHAR* pszPrefix;
  95. TCHAR* pszSuffix;
  96. PrefixSuffixFromLocationId( pUser,
  97. GetCurrentLocation( hInst, pHlineapp ),
  98. &pszPrefix, &pszSuffix );
  99. pszResult =
  100. PhoneNumberFromPrefixSuffixEx(
  101. pszBaseNumber, pszPrefix, pszSuffix, fDownLevelIsdn );
  102. Free0( pszPrefix );
  103. Free0( pszSuffix );
  104. }
  105. if (!pszResult)
  106. {
  107. TRACE( "!Phone#" );
  108. pszResult = StrDup( pszBaseNumber );
  109. }
  110. return pszResult;
  111. }
  112. TCHAR*
  113. PhoneNumberFromPrefixSuffix(
  114. IN TCHAR* pszBaseNumber,
  115. IN TCHAR* pszPrefix,
  116. IN TCHAR* pszSuffix )
  117. // Returns a heap block containing the composite phone number comprised of
  118. // prefix 'pszPrefix', base phone number 'pszBaseNumber', and suffix
  119. // 'pszSuffix', or NULL if the composite number is too long or on a memory
  120. // error.
  121. //
  122. // It is caller's responsibility to Free the returned string.
  123. //
  124. {
  125. TCHAR* pszResult;
  126. DWORD cch;
  127. TRACE( "PhoneNumberFromPrefixSuffix" );
  128. pszResult = NULL;
  129. if (!pszBaseNumber)
  130. {
  131. pszBaseNumber = TEXT("");
  132. }
  133. if (!pszPrefix)
  134. {
  135. pszPrefix = TEXT("");
  136. }
  137. if (!pszSuffix)
  138. {
  139. pszSuffix = TEXT("");
  140. }
  141. cch = lstrlen( pszPrefix ) + lstrlen( pszBaseNumber ) + lstrlen( pszSuffix );
  142. if (cch > RAS_MaxPhoneNumber)
  143. {
  144. return NULL;
  145. }
  146. pszResult = Malloc( (cch + 1) * sizeof(TCHAR) );
  147. if (pszResult)
  148. {
  149. *pszResult = TEXT('\0');
  150. lstrcat( pszResult, pszPrefix );
  151. lstrcat( pszResult, pszBaseNumber );
  152. lstrcat( pszResult, pszSuffix );
  153. }
  154. return pszResult;
  155. }
  156. TCHAR*
  157. PhoneNumberFromPrefixSuffixEx(
  158. IN TCHAR* pszBaseNumber,
  159. IN TCHAR* pszPrefix,
  160. IN TCHAR* pszSuffix,
  161. IN BOOL fDownLevelIsdn )
  162. // Returns a heap block containing the composite phone number comprised of
  163. // prefix 'pszPrefix', base phone number 'pszBaseNumber', and suffix
  164. // 'pszSuffix', or NULL if the composite number is too long or on a memory
  165. // error.
  166. //
  167. // If 'fDownLevelIsdn' is set colons are recognized as separaters with
  168. // each colon separated token built treated separately.
  169. //
  170. // It is caller's responsibility to Free the returned string.
  171. //
  172. {
  173. TCHAR* psz;
  174. TCHAR* pszResult;
  175. INT cchResult;
  176. TRACE( "PhoneNumberFromPrefixSuffixEx" );
  177. if (fDownLevelIsdn)
  178. {
  179. TCHAR* pszNum;
  180. TCHAR* pszS;
  181. TCHAR* pszE;
  182. pszResult = StrDup( TEXT("") );
  183. for (pszS = pszE = pszBaseNumber;
  184. *pszE != TEXT('\0');
  185. pszE = CharNext( pszE ))
  186. {
  187. if (*pszE == TEXT(':'))
  188. {
  189. *pszE = TEXT('\0');
  190. pszNum =
  191. PhoneNumberFromPrefixSuffix(
  192. pszS, pszPrefix, pszSuffix );
  193. *pszE = TEXT(':');
  194. if (pszNum)
  195. {
  196. if (pszResult)
  197. cchResult = lstrlen( pszResult );
  198. psz = Realloc( pszResult,
  199. (cchResult + lstrlen( pszNum ) + 2) * sizeof(TCHAR) );
  200. if (!psz)
  201. {
  202. Free0( pszResult );
  203. Free( pszNum );
  204. return NULL;
  205. }
  206. pszResult = psz;
  207. lstrcat( pszResult, pszNum );
  208. lstrcat( pszResult, TEXT(":") );
  209. Free( pszNum );
  210. }
  211. pszS = CharNext( pszE );
  212. }
  213. }
  214. {
  215. pszNum =
  216. PhoneNumberFromPrefixSuffix(
  217. pszS, pszPrefix, pszSuffix );
  218. if (pszNum)
  219. {
  220. if (pszResult)
  221. cchResult = lstrlen( pszResult );
  222. psz = Realloc( pszResult,
  223. (cchResult + lstrlen( pszNum ) + 1) * sizeof(TCHAR) );
  224. if (!psz)
  225. {
  226. Free0( pszResult );
  227. Free( pszNum );
  228. return NULL;
  229. }
  230. pszResult = psz;
  231. lstrcat( pszResult, pszNum );
  232. Free( pszNum );
  233. }
  234. }
  235. }
  236. else
  237. {
  238. pszResult =
  239. PhoneNumberFromPrefixSuffix(
  240. pszBaseNumber, pszPrefix, pszSuffix );
  241. }
  242. if (pszResult && (lstrlen( pszResult ) > RAS_MaxPhoneNumber ))
  243. {
  244. Free( pszResult );
  245. return NULL;
  246. }
  247. return pszResult;
  248. }
  249. TCHAR*
  250. PhoneNumberFromTapiParts(
  251. IN HINSTANCE hInst,
  252. IN TCHAR* pszBaseNumber,
  253. IN TCHAR* pszAreaCode,
  254. IN DWORD dwCountryCode,
  255. IN OUT HLINEAPP* pHlineapp,
  256. IN BOOL fDialable )
  257. // Returns a heap block containing the composite phone number comprised of
  258. // base phone number 'pszBaseNumber', area code 'pszAreaCode', and country
  259. // code 'dwCountryCode, or NULL if the composite number is too long or on
  260. // a memory error. 'HInst' is the module instance handle. '*PHlineapp'
  261. // is the address of the TAPI context. 'FDialable' indicates the dialable
  262. // string, as opposed to the displayable string, should be returned.
  263. //
  264. // It is caller's responsibility to Free the returned string.
  265. //
  266. {
  267. TCHAR* pszResult;
  268. TRACE( "PhoneNumberFromTapiParts" );
  269. pszResult = NULL;
  270. TapiTranslateAddress(
  271. hInst, pHlineapp, dwCountryCode, pszAreaCode, pszBaseNumber,
  272. 0, fDialable, &pszResult );
  273. return pszResult;
  274. }
  275. TCHAR*
  276. PhoneNumberFromTapiPartsEx(
  277. IN HINSTANCE hInst,
  278. IN TCHAR* pszBaseNumber,
  279. IN TCHAR* pszAreaCode,
  280. IN DWORD dwCountryCode,
  281. IN BOOL fDownLevelIsdn,
  282. IN OUT HLINEAPP* pHlineapp,
  283. IN BOOL fDialable )
  284. // Returns heap block containing the composite phone number comprised of
  285. // base phone number 'pszBaseNumber', area code 'pszAreaCode', and country
  286. // code 'dwCountryCode or NULL if the composite number is too long or on a
  287. // memory error. 'HInst' is the module instance handle. '*PHlineapp' is
  288. // the address of the TAPI context. 'FDialable' indicates the dialable
  289. // string, as opposed to the displayable string, should be returned.
  290. //
  291. // If 'fDownLevelIsdn' is set colons are recognized as separaters with
  292. // each colon separated token built treated separately.
  293. //
  294. // It is caller's responsibility to Free the returned string.
  295. //
  296. {
  297. TCHAR* psz;
  298. TCHAR* pszResult;
  299. INT cchResult;
  300. TRACE( "PhoneNumberFromTapiPartsEx" );
  301. if (fDownLevelIsdn)
  302. {
  303. TCHAR* pszNum;
  304. TCHAR* pszS;
  305. TCHAR* pszE;
  306. pszResult = StrDup( TEXT("") );
  307. for (pszS = pszE = pszBaseNumber;
  308. *pszE != TEXT('\0');
  309. pszE = CharNext( pszE ))
  310. {
  311. if (*pszE == TEXT(':'))
  312. {
  313. *pszE = TEXT('\0');
  314. pszNum = PhoneNumberFromTapiParts(
  315. hInst, pszS, pszAreaCode, dwCountryCode, pHlineapp, fDialable );
  316. *pszE = TEXT(':');
  317. if (pszNum)
  318. {
  319. if (pszResult)
  320. {
  321. cchResult = lstrlen( pszResult );
  322. }
  323. psz = Realloc( pszResult,
  324. (cchResult + lstrlen( pszNum ) + 2) * sizeof(TCHAR) );
  325. if (!psz)
  326. {
  327. Free0( pszResult );
  328. Free( pszNum );
  329. return NULL;
  330. }
  331. pszResult = psz;
  332. lstrcat( pszResult, pszNum );
  333. lstrcat( pszResult, TEXT(":") );
  334. Free( pszNum );
  335. }
  336. pszS = CharNext( pszE );
  337. }
  338. }
  339. {
  340. pszNum = PhoneNumberFromTapiParts(
  341. hInst, pszS, pszAreaCode, dwCountryCode, pHlineapp, fDialable );
  342. if (pszNum)
  343. {
  344. if (pszResult)
  345. {
  346. cchResult = lstrlen( pszResult );
  347. }
  348. psz = Realloc( pszResult,
  349. (cchResult + lstrlen( pszNum ) + 1) * sizeof(TCHAR) );
  350. if (!psz)
  351. {
  352. Free0( pszResult );
  353. Free( pszNum );
  354. return NULL;
  355. }
  356. pszResult = psz;
  357. lstrcat( pszResult, pszNum );
  358. Free( pszNum );
  359. }
  360. }
  361. }
  362. else
  363. {
  364. pszResult = PhoneNumberFromTapiParts(
  365. hInst, pszBaseNumber, pszAreaCode, dwCountryCode, pHlineapp,
  366. fDialable );
  367. }
  368. if (pszResult && (lstrlen( pszResult ) > RAS_MaxPhoneNumber ))
  369. {
  370. Free( pszResult );
  371. return NULL;
  372. }
  373. return pszResult;
  374. }
  375. VOID
  376. PrefixSuffixFromLocationId(
  377. IN PBUSER* pUser,
  378. IN DWORD dwLocationId,
  379. OUT TCHAR** ppszPrefix,
  380. OUT TCHAR** ppszSuffix )
  381. // Retrieve the prefix and suffix strings, '*ppszPrefix' and '*ppszSuffix'
  382. // associated with TAPI location 'dwLocationId'. 'PUser' is the user
  383. // preferences from which to retrieve.
  384. //
  385. // It is caller's responsibility to Free the returned strings.
  386. //
  387. {
  388. #if 0 // NT4-style
  389. DTLNODE* pNode;
  390. INT iPrefix;
  391. INT iSuffix;
  392. TRACE( "PrefixSuffixFromLocationId" );
  393. iPrefix = iSuffix = 0;
  394. for (pNode = DtlGetFirstNode( pUser->pdtllistLocations );
  395. pNode;
  396. pNode = DtlGetNextNode( pNode ))
  397. {
  398. LOCATIONINFO* p = (LOCATIONINFO* )DtlGetData( pNode );
  399. ASSERT( p );
  400. if (p->dwLocationId == dwLocationId)
  401. {
  402. iPrefix = p->iPrefix;
  403. iSuffix = p->iSuffix;
  404. break;
  405. }
  406. }
  407. *ppszPrefix = NULL;
  408. if (iPrefix != 0)
  409. {
  410. pNode = DtlNodeFromIndex( pUser->pdtllistPrefixes, iPrefix - 1 );
  411. if (pNode)
  412. {
  413. *ppszPrefix = StrDup( (TCHAR* )DtlGetData( pNode ) );
  414. }
  415. }
  416. *ppszSuffix = NULL;
  417. if (iSuffix != 0)
  418. {
  419. pNode = DtlNodeFromIndex( pUser->pdtllistSuffixes, iSuffix - 1 );
  420. if (pNode)
  421. {
  422. *ppszSuffix = StrDup( (TCHAR* )DtlGetData( pNode ) );
  423. }
  424. }
  425. #else // Stubbed in NT5/Connections
  426. *ppszPrefix = StrDup( TEXT("") );
  427. *ppszSuffix = StrDup( TEXT("") );
  428. #endif
  429. }