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.

962 lines
25 KiB

  1. /* Copyright (c) 1995-1996, Microsoft Corporation, all rights reserved
  2. **
  3. ** tapi.c
  4. ** TAPI utility routines
  5. ** Listed alphabetically
  6. **
  7. ** 10/20/95 Steve Cobb
  8. */
  9. #include <windows.h> // Win32 root
  10. #include <debug.h> // Trace/Assert library
  11. #include <nouiutil.h> // Heap macros
  12. #include <tapiutil.h> // Our public header
  13. #define TAPIVERSION 0x00010004
  14. TCHAR g_szTapiDevClass[] = TEXT("tapi/line");
  15. /*----------------------------------------------------------------------------
  16. ** Private TAPI entrypoint prototypes
  17. **----------------------------------------------------------------------------
  18. */
  19. DWORD APIENTRY
  20. internalNewLocationW(
  21. IN WCHAR* pszName );
  22. DWORD APIENTRY
  23. internalRemoveLocation(
  24. IN DWORD dwID );
  25. DWORD APIENTRY
  26. internalRenameLocationW(
  27. IN WCHAR* pszOldName,
  28. IN WCHAR* pszNewName );
  29. /*----------------------------------------------------------------------------
  30. ** Local prototypes
  31. **----------------------------------------------------------------------------
  32. */
  33. TCHAR*
  34. GetCanonPhoneNumber(
  35. IN DWORD dwCountryCode,
  36. IN TCHAR* pszAreaCode,
  37. IN TCHAR* pszPhoneNumber );
  38. DWORD
  39. GetDefaultDeviceBlob(
  40. IN DWORD dwDeviceId,
  41. OUT VARSTRING** ppVs,
  42. OUT BYTE** ppBlob,
  43. OUT DWORD* pcbBlob );
  44. void
  45. TapiLineCallback(
  46. IN DWORD hDevice,
  47. IN DWORD dwMessage,
  48. IN DWORD dwInstance,
  49. IN DWORD dwParam1,
  50. IN DWORD dwParam2,
  51. IN DWORD dwParam3 );
  52. /*----------------------------------------------------------------------------
  53. ** Routines
  54. **----------------------------------------------------------------------------
  55. */
  56. VOID
  57. FreeCountryInfo(
  58. IN COUNTRY* pCountries,
  59. IN DWORD cCountries )
  60. /* Frees the 'pCountries' buffer of 'cCountries' elements as returned by
  61. ** GetCountryInfo.
  62. */
  63. {
  64. if (cCountries)
  65. {
  66. Free( *((VOID** )(pCountries + cCountries)) );
  67. Free( pCountries );
  68. }
  69. }
  70. VOID
  71. FreeLocationInfo(
  72. IN LOCATION* pLocations,
  73. IN DWORD cLocations )
  74. /* Frees the 'pLocations' buffer of 'cLocations' elements as returned by
  75. ** GetLocationInfo.
  76. */
  77. {
  78. if (cLocations)
  79. {
  80. Free( *((VOID** )(pLocations + cLocations)) );
  81. Free( pLocations );
  82. }
  83. }
  84. TCHAR*
  85. GetCanonPhoneNumber(
  86. IN DWORD dwCountryCode,
  87. IN TCHAR* pszAreaCode,
  88. IN TCHAR* pszPhoneNumber )
  89. /* Returns a TAPI canonical phone number from constituent parts or NULL on
  90. ** error or when 'pszPhoneNumber' is NULL. It is caller's responsibility
  91. ** to Free the returned string.
  92. */
  93. {
  94. TCHAR szBuf[ 512 ];
  95. TRACE("GetCanonPhoneNumber");
  96. if (!pszPhoneNumber)
  97. return NULL;
  98. if (pszAreaCode && *pszAreaCode)
  99. {
  100. wsprintf( szBuf, TEXT("+%d (%s) %s"),
  101. dwCountryCode, pszAreaCode, pszPhoneNumber );
  102. }
  103. else
  104. {
  105. wsprintf( szBuf, TEXT("+%d %s"),
  106. dwCountryCode, pszPhoneNumber );
  107. }
  108. return StrDup( szBuf );
  109. }
  110. DWORD
  111. GetCountryInfo(
  112. OUT COUNTRY** ppCountries,
  113. OUT DWORD* pcCountries,
  114. IN DWORD dwCountryID )
  115. /* Sets '*ppCountries' to a heap block containing an array of TAPI country
  116. ** information. '*pcCountries' is set to the number of elements in the
  117. ** array. If 'dwCountryID' is 0, all countries are loaded. Otherwise,
  118. ** only the specific country is loaded.
  119. **
  120. ** Returns 0 if successful, or an error code. If successful, it is
  121. ** caller's responsibility to call FreeLocationInfo on *ppLocations.
  122. */
  123. {
  124. DWORD dwErr;
  125. LINECOUNTRYLIST list;
  126. LINECOUNTRYLIST* pList;
  127. LINECOUNTRYENTRY* pEntry;
  128. COUNTRY* pCountry;
  129. DWORD cb;
  130. DWORD i;
  131. TRACE("GetCountryInfo");
  132. *ppCountries = NULL;
  133. *pcCountries = 0;
  134. /* Get the buffer size needed.
  135. */
  136. ZeroMemory( &list, sizeof(list) );
  137. list.dwTotalSize = sizeof(list);
  138. TRACE("lineGetCountryW");
  139. dwErr = lineGetCountryW( dwCountryID, TAPIVERSION, &list );
  140. TRACE1("lineGetCountryW=$%X",dwErr);
  141. if (dwErr != 0)
  142. return dwErr;
  143. /* Allocate the buffer.
  144. */
  145. pList = (LINECOUNTRYLIST* )Malloc( list.dwNeededSize );
  146. if (!pList)
  147. return ERROR_NOT_ENOUGH_MEMORY;
  148. /* Fill the buffer with TAPI country info.
  149. */
  150. ZeroMemory( pList, list.dwNeededSize );
  151. pList->dwTotalSize = list.dwNeededSize;
  152. TRACE("lineGetCountryW");
  153. dwErr = lineGetCountryW( dwCountryID, TAPIVERSION, pList );
  154. TRACE1("lineGetCountryW=$%X",dwErr);
  155. if (dwErr != 0)
  156. {
  157. Free( pList );
  158. return dwErr;
  159. }
  160. /* Allocate array returned to caller.
  161. */
  162. *pcCountries = pList->dwNumCountries;
  163. TRACE1("countries=%d",*pcCountries);
  164. cb = (sizeof(COUNTRY) * *pcCountries) + sizeof(LINECOUNTRYLIST*);
  165. *ppCountries = Malloc( cb );
  166. if (!*ppCountries)
  167. {
  168. *pcCountries = 0;
  169. Free( pList );
  170. return ERROR_NOT_ENOUGH_MEMORY;
  171. }
  172. /* Fill buffer returned to caller with information from TAPI location
  173. ** buffer. References to the CAPS buffer are included, so the address
  174. ** of the CAPS buffer is tacked on the end for freeing later.
  175. */
  176. pEntry = (LINECOUNTRYENTRY* )
  177. (((BYTE* )pList) + pList->dwCountryListOffset);
  178. pCountry = *ppCountries;
  179. ZeroMemory( pCountry, cb );
  180. for (i = 0; i < *pcCountries; ++i)
  181. {
  182. pCountry->dwId = pEntry->dwCountryID;
  183. pCountry->dwCode = pEntry->dwCountryCode;
  184. pCountry->pszName =
  185. (TCHAR* )(((BYTE* )pList) + pEntry->dwCountryNameOffset);
  186. ++pEntry;
  187. ++pCountry;
  188. }
  189. *((LINECOUNTRYLIST** )pCountry) = pList;
  190. return 0;
  191. }
  192. DWORD
  193. GetCurrentLocation(
  194. IN HINSTANCE hInst,
  195. IN OUT HLINEAPP* pHlineapp )
  196. /* Returns the ID of the current TAPI location, or the default 0 if there
  197. ** is none. 'HInst' is the module instance handle. '*PHlineapp' is the
  198. ** TAPI handle returned from a previous TAPI call or NULL if none.
  199. */
  200. {
  201. DWORD dwErr;
  202. LINETRANSLATECAPS caps;
  203. DWORD dwId;
  204. dwId = 0;
  205. #if 0
  206. dwErr = TapiInit( hInst, pHlineapp, NULL );
  207. if (dwErr == 0)
  208. #endif
  209. {
  210. ZeroMemory( &caps, sizeof(caps) );
  211. caps.dwTotalSize = sizeof(caps);
  212. TRACE("lineGetTranslateCapsW");
  213. dwErr = lineGetTranslateCapsW( *pHlineapp, TAPIVERSION, &caps );
  214. TRACE1("lineGetTranslateCapsW=$%X",dwErr);
  215. if (dwErr == 0)
  216. dwId = caps.dwCurrentLocationID;
  217. }
  218. TRACE1("GetCurrentLocation=%d",dwId);
  219. return dwId;
  220. }
  221. DWORD
  222. GetDefaultDeviceBlob(
  223. IN DWORD dwDeviceId,
  224. OUT VARSTRING** ppVs,
  225. OUT BYTE** ppBlob,
  226. OUT DWORD* pcbBlob )
  227. /* Returns the default device blob for device 'dwDeviceId' in caller's
  228. ** '*ppBlob'. '*pcbBlob' is set to the size of the blob.
  229. **
  230. ** Returns 0 if successful or an error code. If succussful, it is
  231. ** caller's responsibility to Free the returned '*ppVs', which is a buffer
  232. ** containing the returned blob.
  233. */
  234. {
  235. DWORD dwErr;
  236. VARSTRING vs;
  237. VARSTRING* pVs;
  238. *ppVs = NULL;
  239. *ppBlob = NULL;
  240. *pcbBlob = 0;
  241. /* Get the buffer size needed.
  242. */
  243. ZeroMemory( &vs, sizeof(vs) );
  244. vs.dwTotalSize = sizeof(vs);
  245. TRACE("lineGetDevConfigW");
  246. dwErr = lineGetDevConfigW( dwDeviceId, &vs, g_szTapiDevClass );
  247. TRACE1("lineGetDevConfigW=$%X",dwErr);
  248. if (dwErr != LINEERR_STRUCTURETOOSMALL && dwErr != 0)
  249. return dwErr;
  250. /* Allocate the buffer.
  251. */
  252. pVs = (VARSTRING* )Malloc( vs.dwNeededSize );
  253. if (!pVs)
  254. return ERROR_NOT_ENOUGH_MEMORY;
  255. /* Fill buffer with TAPI VARSTRING containing blob information.
  256. */
  257. ZeroMemory( pVs, vs.dwNeededSize );
  258. pVs->dwTotalSize = vs.dwNeededSize;
  259. TRACE("lineGetDevConfigW");
  260. dwErr = lineGetDevConfigW( dwDeviceId, pVs, g_szTapiDevClass );
  261. TRACE1("lineGetDevConfigW=$%X",dwErr);
  262. if (dwErr != 0)
  263. {
  264. Free( pVs );
  265. return dwErr;
  266. }
  267. *ppVs = pVs;
  268. *ppBlob = ((BYTE* )pVs) + pVs->dwStringOffset;
  269. *pcbBlob = pVs->dwStringSize;
  270. TRACE1("GetDefaultDeviceBlob=0,cb=%d",*pcbBlob);
  271. return 0;
  272. }
  273. DWORD
  274. GetLocationInfo(
  275. IN HINSTANCE hInst,
  276. IN OUT HLINEAPP* pHlineapp,
  277. OUT LOCATION** ppLocations,
  278. OUT DWORD* pcLocations,
  279. OUT DWORD* pdwCurLocation )
  280. /* Sets '*ppLocations' to a heap block containing TAPI location
  281. ** information. '*PcLocations' is set to the number of elements in the
  282. ** array. '*pdwLocation' is set to the TAPI ID of the currently selected
  283. ** location. '*PHlineapp' is the TAPI handle returned from a previous
  284. ** TAPI call or NULL if none. 'HInst' is the module instance handle.
  285. **
  286. ** Returns 0 if successful, or an error code. If successful, it is
  287. ** caller's responsibility to call FreeLocationInfo on *ppLocations.
  288. */
  289. {
  290. DWORD dwErr;
  291. LINETRANSLATECAPS caps;
  292. LINETRANSLATECAPS* pCaps;
  293. LINELOCATIONENTRY* pEntry;
  294. LOCATION* pLocation;
  295. DWORD cb;
  296. DWORD i;
  297. TRACE("GetLocationInfo");
  298. *ppLocations = NULL;
  299. *pcLocations = 0;
  300. *pdwCurLocation = 0;
  301. #if 0
  302. dwErr = TapiInit( hInst, pHlineapp, NULL );
  303. if (dwErr != 0)
  304. return dwErr;
  305. #endif
  306. /* Get the buffer size needed.
  307. */
  308. ZeroMemory( &caps, sizeof(caps) );
  309. caps.dwTotalSize = sizeof(caps);
  310. TRACE("lineGetTranslateCapsW");
  311. dwErr = lineGetTranslateCapsW( *pHlineapp, TAPIVERSION, &caps );
  312. TRACE1("lineGetTranslateCapsW=$%X",dwErr);
  313. if (dwErr != 0)
  314. {
  315. if (dwErr == (DWORD )LINEERR_INIFILECORRUPT)
  316. {
  317. /* Means the TAPI registry is uninitialized. Return no locations
  318. ** and "default" current location.
  319. */
  320. dwErr = 0;
  321. }
  322. return dwErr;
  323. }
  324. /* Allocate the buffer.
  325. */
  326. pCaps = (LINETRANSLATECAPS* )Malloc( caps.dwNeededSize );
  327. if (!pCaps)
  328. return ERROR_NOT_ENOUGH_MEMORY;
  329. /* Fill buffer with TAPI location data.
  330. */
  331. ZeroMemory( pCaps, caps.dwNeededSize );
  332. pCaps->dwTotalSize = caps.dwNeededSize;
  333. TRACE("lineGetTranslateCapsW");
  334. dwErr = lineGetTranslateCapsW( *pHlineapp, TAPIVERSION, pCaps );
  335. TRACE1("lineGetTranslateCapsW=$%X",dwErr);
  336. if (dwErr != 0)
  337. {
  338. Free( pCaps );
  339. return dwErr;
  340. }
  341. /* Allocate array returned to caller.
  342. */
  343. *pcLocations = pCaps->dwNumLocations;
  344. *pdwCurLocation = pCaps->dwCurrentLocationID;
  345. TRACE2("locs=%d,cur=%d",*pcLocations,*pdwCurLocation);
  346. cb = (sizeof(LOCATION) * *pcLocations) + sizeof(LINETRANSLATECAPS*);
  347. *ppLocations = Malloc( cb );
  348. if (!*ppLocations)
  349. {
  350. *pcLocations = 0;
  351. Free( pCaps );
  352. return ERROR_NOT_ENOUGH_MEMORY;
  353. }
  354. /* Fill buffer returned to caller with information from TAPI location
  355. ** buffer. References to the CAPS buffer are included, so the address
  356. ** of the CAPS buffer is tacked on the end for freeing later.
  357. */
  358. pEntry = (LINELOCATIONENTRY* )
  359. (((BYTE* )pCaps) + pCaps->dwLocationListOffset);
  360. pLocation = *ppLocations;
  361. ZeroMemory( pLocation, cb );
  362. for (i = 0; i < *pcLocations; ++i)
  363. {
  364. pLocation->dwId = pEntry->dwPermanentLocationID;
  365. pLocation->pszName =
  366. (TCHAR* )(((BYTE* )pCaps) + pEntry->dwLocationNameOffset);
  367. ++pEntry;
  368. ++pLocation;
  369. }
  370. *((LINETRANSLATECAPS** )pLocation) = pCaps;
  371. return 0;
  372. }
  373. DWORD
  374. SetCurrentLocation(
  375. IN HINSTANCE hInst,
  376. IN OUT HLINEAPP* pHlineapp,
  377. IN DWORD dwLocationId )
  378. /* Sets the current TAPI location to 'dwLocationId'. '*PHlineapp' is the
  379. ** TAPI handle returned from a previous TAPI call or NULL if none.
  380. ** 'HInst' is the module instance handle.
  381. **
  382. ** Returns 0 if successful, or an error code.
  383. */
  384. {
  385. DWORD dwErr;
  386. HLINEAPP hlineapp;
  387. TRACE1("SetCurrentLocation(id=%d)",dwLocationId);
  388. #if 0
  389. dwErr = TapiInit( hInst, pHlineapp, NULL );
  390. if (dwErr != 0)
  391. return dwErr;
  392. #endif
  393. TRACE("lineSetCurrentLocation");
  394. dwErr = lineSetCurrentLocation( *pHlineapp, dwLocationId );
  395. TRACE1("lineSetCurrentLocation=$%X",dwErr);
  396. if (dwErr == (DWORD )LINEERR_INIFILECORRUPT && dwLocationId == 0)
  397. {
  398. /* Means the TAPI registry is uninitialized. If caller is setting the
  399. ** default location, this is OK.
  400. */
  401. return 0;
  402. }
  403. return dwErr;
  404. }
  405. #if 0
  406. DWORD
  407. TapiConfigureDlg(
  408. IN HWND hwndOwner,
  409. IN DWORD dwDeviceId,
  410. IN OUT BYTE** ppBlob,
  411. IN OUT DWORD* pcbBlob )
  412. /* Popup the TAPI dialog to edit device 'dwDeviceId, with input blob
  413. ** '*ppBlob' of size '*pcBlob'. '*ppBlob' can be NULL causing the current
  414. ** system defaults for the device to be used as input. 'HwndOwner' is the
  415. ** window owning the modal dialog.
  416. */
  417. {
  418. DWORD dwErr;
  419. VARSTRING vs;
  420. VARSTRING* pVs;
  421. VARSTRING* pVsDefault;
  422. BYTE* pIn;
  423. BYTE* pOut;
  424. DWORD cbIn;
  425. DWORD cbOut;
  426. TRACE("TapiConfigureDlg");
  427. pVs = NULL;
  428. if (*ppBlob)
  429. {
  430. /* Caller provided input blob.
  431. */
  432. pIn = *ppBlob;
  433. cbIn = *pcbBlob;
  434. }
  435. else
  436. {
  437. /* Caller did not provide input blob, so look up the default for this
  438. ** device.
  439. */
  440. dwErr = GetDefaultDeviceBlob( dwDeviceId, &pVsDefault, &pIn, &cbIn );
  441. if (dwErr != 0)
  442. return dwErr;
  443. }
  444. /* Get the buffer size needed.
  445. */
  446. ZeroMemory( &vs, sizeof(vs) );
  447. vs.dwTotalSize = sizeof(vs);
  448. TRACE("lineConfigDialogEditW");
  449. dwErr = lineConfigDialogEditW(
  450. dwDeviceId, hwndOwner, g_szTapiDevClass, pIn, cbIn, &vs );
  451. TRACE1("lineConfigDialogEditW=$%X",dwErr);
  452. if (dwErr != LINEERR_STRUCTURETOOSMALL && dwErr != 0)
  453. goto TapiConfigureDlg_Error;
  454. /* Allocate the buffer.
  455. */
  456. pVs = (VARSTRING* )Malloc( vs.dwNeededSize );
  457. if (!pVs)
  458. {
  459. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  460. goto TapiConfigureDlg_Error;
  461. }
  462. /* Popup the dialog which edits the information in the buffer.
  463. */
  464. ZeroMemory( pVs, vs.dwNeededSize );
  465. pVs->dwTotalSize = vs.dwNeededSize;
  466. TRACE("lineConfigDialogEditW");
  467. dwErr = lineConfigDialogEditW(
  468. dwDeviceId, hwndOwner, g_szTapiDevClass, pIn, cbIn, pVs );
  469. TRACE1("lineConfigDialogEditW=$%X",dwErr);
  470. if (dwErr != 0)
  471. goto TapiConfigureDlg_Error;
  472. /* Allocate a new "blob" buffer and fill it with the "blob" subset of the
  473. ** larger VARSTRING buffer. Can't avoid this copy without introducing
  474. ** Freeing complexity for caller.
  475. */
  476. cbOut = pVs->dwStringSize;
  477. pOut = Malloc( cbOut );
  478. if (!pOut)
  479. {
  480. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  481. goto TapiConfigureDlg_Error;
  482. }
  483. CopyMemory( pOut, ((BYTE* )pVs) + pVs->dwStringOffset, cbOut );
  484. Free( pVs );
  485. if (pIn == *ppBlob)
  486. Free( pIn );
  487. else
  488. Free( pVsDefault );
  489. *ppBlob = pOut;
  490. *pcbBlob = cbOut;
  491. TRACE1("TapiConfigureDlg=0,cbBlob=%d",cbOut);
  492. return 0;
  493. TapiConfigureDlg_Error:
  494. Free0( pVs );
  495. if (pIn != *ppBlob)
  496. Free( pVsDefault );
  497. TRACE1("TapiConfigureDlg=$%X",dwErr);
  498. return dwErr;
  499. }
  500. #endif
  501. #if 0
  502. DWORD
  503. TapiInit(
  504. IN HINSTANCE hInst,
  505. IN OUT HLINEAPP* pHlineapp,
  506. OUT DWORD* pcDevices )
  507. /* Initialize TAPI and return the app handle and device count. Does
  508. ** nothing if '*pHlineapp' is non-NULL. 'PcDevices' may be NULL if caller
  509. ** is not interested in the device count. 'HInst' is the module instance.
  510. **
  511. ** According to BernieM, the hlineapp passed to the TAPI location,
  512. ** country, and line translation APIs (the ones we use in the UI) is not
  513. ** currently used. Therefore, since, lineInitialize can take several
  514. ** seconds to complete we optimize for speed by stubbing it out in these
  515. ** wrappers.
  516. */
  517. {
  518. DWORD dwErr;
  519. HLINEAPP hlineapp;
  520. DWORD cDevices;
  521. ASSERT(pHlineapp);
  522. TRACE1("TapiInit(h=$%x)",*pHlineapp);
  523. dwErr = 0;
  524. if (!*pHlineapp)
  525. {
  526. hlineapp = NULL;
  527. cDevices = 0;
  528. TRACE("lineInitializeW");
  529. dwErr = lineInitializeW(
  530. &hlineapp, hInst, TapiLineCallback, NULL, &cDevices );
  531. TRACE1("lineInitializeW=$%X",dwErr);
  532. if (dwErr == 0)
  533. {
  534. *pHlineapp = hlineapp;
  535. if (pcDevices)
  536. *pcDevices = cDevices;
  537. }
  538. }
  539. return dwErr;
  540. }
  541. #endif
  542. void
  543. TapiLineCallback(
  544. IN DWORD hDevice,
  545. IN DWORD dwMessage,
  546. IN DWORD dwInstance,
  547. IN DWORD dwParam1,
  548. IN DWORD dwParam2,
  549. IN DWORD dwParam3 )
  550. /* Dummy TAPI callback required by lineInitialize.
  551. */
  552. {
  553. TRACE3("TapiLineCallback(h=$%x,m=$%x,i=$%x...",hDevice,dwMessage,dwInstance);
  554. TRACE3(" p1=$%x,p2=$%x,p3=$%x)",dwParam1,dwParam2,dwParam3);
  555. }
  556. DWORD
  557. TapiLocationDlg(
  558. IN HINSTANCE hInst,
  559. IN OUT HLINEAPP* pHlineapp,
  560. IN HWND hwndOwner,
  561. IN DWORD dwCountryCode,
  562. IN TCHAR* pszAreaCode,
  563. IN TCHAR* pszPhoneNumber,
  564. IN DWORD dwDeviceId )
  565. /* Displays the TAPI location property sheet owned by 'hwndOwner'.
  566. ** '*PHlineapp' is the TAPI handle returned from a previous TAPI call or
  567. ** NULL if none. 'DwCountryCode', 'pszAreaCode', and 'pszPhoneNumber' are
  568. ** the components of the TAPI canonical phone number. 'DwDeviceId'
  569. ** specified the device to which the dialog applies, or 0 for a generic
  570. ** device. 'HInst' is the module instance handle.
  571. */
  572. {
  573. DWORD dwErr;
  574. DWORD cDevices;
  575. TCHAR* pszCanon;
  576. TRACE("TapiLocationDlg");
  577. #if 0
  578. dwErr = TapiInit( hInst, pHlineapp, NULL );
  579. if (dwErr != 0)
  580. return dwErr;
  581. #endif
  582. pszCanon = GetCanonPhoneNumber(
  583. dwCountryCode, pszAreaCode, pszPhoneNumber );
  584. TRACEW1("lineTranslateDialogW(\"%s\")",(pszCanon)?pszCanon:TEXT(""));
  585. dwErr = lineTranslateDialogW(
  586. *pHlineapp, dwDeviceId, TAPIVERSION, hwndOwner, pszCanon );
  587. if (dwErr == LINEERR_INUSE)
  588. {
  589. // This error means the dialog is already up and hence our request was
  590. // ignored. From our point of view, this is success, e.g. we don't
  591. // need to do an error popup, so map accordingly. See bug 216683.
  592. //
  593. dwErr = 0;
  594. }
  595. TRACE1("lineTranslateDialogW=$%X",dwErr);
  596. Free0( pszCanon );
  597. return dwErr;
  598. }
  599. DWORD APIENTRY
  600. TapiNewLocation(
  601. IN TCHAR* pszName )
  602. /* Clone current location giving name 'pszName'.
  603. **
  604. ** Returns 0 if successful, or an error code.
  605. */
  606. {
  607. TRACEW1("TapiNewLocation(%s)",pszName);
  608. #ifdef UNICODE
  609. return internalNewLocationW( pszName );
  610. #else
  611. {
  612. DWORD dwErr;
  613. WCHAR* pszNameW;
  614. pszNameW = StrDupWFromA( pszName );
  615. dwErr = internalNewLocation( pszNameW );
  616. Free0( pszNameW );
  617. return dwErr;
  618. }
  619. #endif
  620. }
  621. DWORD
  622. TapiNoLocationDlg(
  623. IN HINSTANCE hInst,
  624. IN HLINEAPP* pHlineapp,
  625. IN HWND hwndOwner )
  626. /* Gives TAPI a chance to initialize the first location, if necessary.
  627. ** Call this before any other TAPI calls. 'HInst' is the module instance
  628. ** handle. '*pHlineapp' is the handle returned from a previous TAPI call
  629. ** or NULL if none (typical in this case). 'HwndOwner' is the window to
  630. ** own the TAPI dialog, if it appears.
  631. **
  632. ** Returns 0 if successful, or an error code.
  633. */
  634. {
  635. DWORD dwErr;
  636. LINETRANSLATECAPS caps;
  637. TRACE("TapiNoLocationDlg");
  638. #if 0
  639. dwErr = TapiInit( hInst, pHlineapp, NULL );
  640. if (dwErr != 0)
  641. return dwErr;
  642. #endif
  643. /* Make an arbitrary TAPI call to see if the TAPI registry has been
  644. ** initialized.
  645. */
  646. ZeroMemory( &caps, sizeof(caps) );
  647. caps.dwTotalSize = sizeof(caps);
  648. TRACE("lineGetTranslateCapsW");
  649. dwErr = lineGetTranslateCapsW( *pHlineapp, TAPIVERSION, &caps );
  650. TRACE1("lineGetTranslateCapsW=$%X",dwErr);
  651. if (dwErr == (DWORD )LINEERR_INIFILECORRUPT)
  652. {
  653. /* This semi-private TAPI API allows the "first location" wizard page
  654. ** to appear without the following "TAPI Dialing Properties" sheet.
  655. */
  656. extern LOpenDialAsst(
  657. IN HWND hwnd,
  658. IN LPCTSTR lpszAddressIn,
  659. IN BOOL fSimple,
  660. IN BOOL fSilentInstall );
  661. dwErr = LOpenDialAsst( hwndOwner, NULL, TRUE, TRUE );
  662. }
  663. return dwErr;
  664. }
  665. DWORD APIENTRY
  666. TapiRemoveLocation(
  667. IN DWORD dwID )
  668. /* Remove TAPI location 'dwID'.
  669. **
  670. ** Returns 0 if successful, or an error code.
  671. */
  672. {
  673. TRACE("TapiRemoveLocation");
  674. return internalRemoveLocation( dwID );
  675. }
  676. DWORD APIENTRY
  677. TapiRenameLocation(
  678. IN WCHAR* pszOldName,
  679. IN WCHAR* pszNewName )
  680. /* Renames TAPI location 'pszOldName' to 'pszNewName'.
  681. **
  682. ** Returns 0 if successful, or an error code.
  683. */
  684. {
  685. TRACEW1("TapiRenameLocation(o=%s...",pszOldName);
  686. TRACEW1("...n=%s)",pszNewName);
  687. #ifdef UNICODE
  688. return internalRenameLocationW( pszOldName, pszNewName );
  689. #else
  690. {
  691. WCHAR* pszOldNameW;
  692. WCHAR* pszNewNameW;
  693. pszOldNameW = StrDupWFromA( pszOldName );
  694. pszNewNameW = StrDupWFromA( pszNewName );
  695. dwErr = internalNewLocation( pszOldNameW, pszNewNameW );
  696. Free0( pszOldNameW );
  697. Free0( pszNewNameW );
  698. return dwErr;
  699. }
  700. #endif
  701. }
  702. DWORD
  703. TapiShutdown(
  704. IN HLINEAPP hlineapp )
  705. /* Terminate the TAPI session 'hlineapp', or do nothing if 'hlineapp' is
  706. ** NULL.
  707. */
  708. {
  709. #if 0
  710. DWORD dwErr = 0;
  711. TRACE1("TapiShutdown(h=$%x)",hlineapp);
  712. if (hlineapp)
  713. {
  714. TRACE("lineShutdown");
  715. dwErr = lineShutdown( hlineapp );
  716. TRACE1("lineShutdown=$%X",dwErr);
  717. }
  718. return dwErr;
  719. #else
  720. /* See TapiInit.
  721. */
  722. ASSERT(!hlineapp);
  723. return 0;
  724. #endif
  725. }
  726. DWORD
  727. TapiTranslateAddress(
  728. IN HINSTANCE hInst,
  729. IN OUT HLINEAPP* pHlineapp,
  730. IN DWORD dwCountryCode,
  731. IN TCHAR* pszAreaCode,
  732. IN TCHAR* pszPhoneNumber,
  733. IN DWORD dwDeviceId,
  734. IN BOOL fDialable,
  735. OUT TCHAR** ppszResult )
  736. /* Returns '*pszResult', a heap string containing the TAPI location
  737. ** transformed dialable phone number built from the component phone number
  738. ** parts. '*PHlineapp' is the TAPI handle returned from a previous TAPI
  739. ** call or NULL if none. parts. 'dwDeviceId' is the device to which the
  740. ** number is to be applied or 0 for generic treatment. 'HInst' is the
  741. ** module instance handle. 'FDialable' indicates the dialable, as opposed
  742. ** to the displayable string should be returned.
  743. **
  744. ** Returns 0 if successful, or an error code.
  745. */
  746. {
  747. DWORD dwErr;
  748. TCHAR* pszCanon;
  749. LINETRANSLATEOUTPUT output;
  750. LINETRANSLATEOUTPUT* pOutput;
  751. TRACE("TapiTranslateAddress");
  752. pOutput = NULL;
  753. pszCanon = NULL;
  754. *ppszResult = NULL;
  755. #if 0
  756. dwErr = TapiInit( hInst, pHlineapp, NULL );
  757. if (dwErr != 0)
  758. return dwErr;
  759. #endif
  760. pszCanon = GetCanonPhoneNumber(
  761. dwCountryCode, pszAreaCode, pszPhoneNumber );
  762. ZeroMemory( &output, sizeof(output) );
  763. output.dwTotalSize = sizeof(output);
  764. TRACE("lineTranslateAddressW");
  765. dwErr = lineTranslateAddressW(
  766. *pHlineapp, dwDeviceId, TAPIVERSION, pszCanon, 0,
  767. LINETRANSLATEOPTION_CANCELCALLWAITING, &output );
  768. TRACE1("lineTranslateAddressW=$%X",dwErr);
  769. if (dwErr != 0)
  770. goto TapiTranslateAddress_Error;
  771. pOutput = (LINETRANSLATEOUTPUT* )Malloc( output.dwNeededSize );
  772. if (!pOutput)
  773. {
  774. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  775. goto TapiTranslateAddress_Error;
  776. }
  777. ZeroMemory( pOutput, output.dwNeededSize );
  778. pOutput->dwTotalSize = output.dwNeededSize;
  779. TRACE("lineTranslateAddressW");
  780. dwErr = lineTranslateAddressW(
  781. *pHlineapp, dwDeviceId, TAPIVERSION, pszCanon, 0,
  782. LINETRANSLATEOPTION_CANCELCALLWAITING, pOutput );
  783. TRACE1("lineTranslateAddressW=$%X",dwErr);
  784. if (dwErr != 0)
  785. goto TapiTranslateAddress_Error;
  786. if (fDialable)
  787. {
  788. *ppszResult = StrDup(
  789. (TCHAR* )(((BYTE* )pOutput) + pOutput->dwDialableStringOffset) );
  790. }
  791. else
  792. {
  793. *ppszResult = StrDup(
  794. (TCHAR* )(((BYTE* )pOutput) + pOutput->dwDisplayableStringOffset) );
  795. }
  796. if (!*ppszResult)
  797. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  798. TapiTranslateAddress_Error:
  799. Free0( pszCanon );
  800. Free0( pOutput );
  801. return dwErr;
  802. }