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.

1587 lines
44 KiB

  1. /* File: D:\WACKER\cncttapi\enum.c (Created: 23-Mar-1994)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 29 $
  7. * $Date: 7/02/02 8:27a $
  8. */
  9. #define TAPI_CURRENT_VERSION 0x00010004 // cab:11/14/96 - required!
  10. #undef MODEM_NEGOTIATED_DCE_RATE
  11. #include <tapi.h>
  12. #include <unimodem.h>
  13. #include <limits.h>
  14. #pragma hdrstop
  15. #include <time.h>
  16. #include <string.h>
  17. #include <tdll\stdtyp.h>
  18. #include <tdll\session.h>
  19. #include <tdll\tdll.h>
  20. #include <tdll\mc.h>
  21. #include <tdll\assert.h>
  22. #include <tdll\errorbox.h>
  23. #include <tdll\cnct.h>
  24. #include <tdll\hlptable.h>
  25. #include <tdll\globals.h>
  26. #include <tdll\com.h>
  27. #include <term\res.h>
  28. #include <tdll\htchar.h>
  29. #include <tdll\misc.h>
  30. #include "cncttapi.hh"
  31. #include "cncttapi.h"
  32. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  33. * FUNCTION:
  34. * EnumerateTapiLocations
  35. *
  36. * DESCRIPTION:
  37. * Enumerates tapi locations and puts them in the given combo box.
  38. *
  39. * ARGUMENTS:
  40. * hhDriver - private driver handle
  41. * hwndCB - window handle of combo box
  42. * hwndTB - calling card text window
  43. *
  44. * RETURNS:
  45. * 0 on success, else error
  46. *
  47. */
  48. int EnumerateTapiLocations(const HHDRIVER hhDriver, const HWND hwndCB,
  49. const HWND hwndTB)
  50. {
  51. DWORD i, dwSize;
  52. LRESULT lr;
  53. TCHAR *pach = NULL;
  54. TCHAR ach[256];
  55. DWORD dwPreferredCardID = (DWORD)-1;
  56. DWORD dwCountryID = 1;
  57. LINETRANSLATECAPS *pLnTransCap = NULL;
  58. LINELOCATIONENTRY *pLnLocEntry = NULL;
  59. LINECARDENTRY *pLnCardEntry = NULL;
  60. /* --- Enumerate locations --- */
  61. if (hhDriver == 0)
  62. {
  63. return -1;
  64. }
  65. if ((pLnTransCap = malloc(sizeof(LINETRANSLATECAPS))) == 0)
  66. {
  67. assert(FALSE);
  68. return -2;
  69. }
  70. dwSize = 0; // used in this loop to call the dialog only once.
  71. do {
  72. memset(pLnTransCap, 0, sizeof(LINETRANSLATECAPS)); //* temp
  73. pLnTransCap->dwTotalSize = sizeof(LINETRANSLATECAPS); //* temp
  74. if ((i = TRAP(lineGetTranslateCaps(hhDriver->hLineApp, TAPI_VER,
  75. pLnTransCap))) != 0)
  76. {
  77. if ( i == LINEERR_INIFILECORRUPT )
  78. {
  79. // Unfortunately, lineTranslateDialog does not return
  80. // a failure code if the user clicks cancel. So if
  81. // we fail the second time on lineGetTranslateCaps()
  82. // don't bother to do anything else.
  83. //
  84. if (dwSize == 0)
  85. {
  86. LoadString(glblQueryDllHinst(), IDS_ER_TAPI_NEEDS_INFO,
  87. ach, sizeof(ach) / sizeof(TCHAR));
  88. TimedMessageBox(sessQueryHwnd(hhDriver->hSession), ach,
  89. NULL, MB_OK | MB_ICONINFORMATION, 0);
  90. free(pLnTransCap);
  91. pLnTransCap = NULL;
  92. return -3;
  93. }
  94. if (TRAP(lineTranslateDialog(hhDriver->hLineApp, 0,
  95. TAPI_VER, sessQueryHwnd(hhDriver->hSession), 0))
  96. == 0)
  97. {
  98. dwSize = 1;
  99. continue;
  100. }
  101. }
  102. free(pLnTransCap);
  103. pLnTransCap = NULL;
  104. return -4;
  105. }
  106. }
  107. while (i); // end of do.
  108. if (pLnTransCap->dwNeededSize > pLnTransCap->dwTotalSize)
  109. {
  110. dwSize = pLnTransCap->dwNeededSize;
  111. free(pLnTransCap);
  112. pLnTransCap = NULL;
  113. if ((pLnTransCap = malloc(dwSize)) == 0)
  114. {
  115. assert(FALSE);
  116. return -5;
  117. }
  118. pLnTransCap->dwTotalSize = dwSize;
  119. if (TRAP(lineGetTranslateCaps(hhDriver->hLineApp, TAPI_VER,
  120. pLnTransCap)) != 0)
  121. {
  122. free(pLnTransCap);
  123. pLnTransCap = NULL;
  124. return -6;
  125. }
  126. }
  127. /* --- Clear combo box --- */
  128. if (IsWindow(hwndCB))
  129. SendMessage(hwndCB, CB_RESETCONTENT, 0, 0);
  130. /* --- Setup pointer to entry structure and enumerate --- */
  131. pLnLocEntry = (LINELOCATIONENTRY *)
  132. ((LPSTR)pLnTransCap + pLnTransCap->dwLocationListOffset);
  133. for (i = 0 ; i < pLnTransCap->dwNumLocations ; ++i)
  134. {
  135. if (pLnLocEntry->dwLocationNameSize == 0)
  136. continue;
  137. pach = (LPSTR)pLnTransCap + pLnLocEntry->dwLocationNameOffset;
  138. if (pLnLocEntry->dwLocationNameSize)
  139. MemCopy(ach, pach, pLnLocEntry->dwLocationNameSize);
  140. ach[pLnLocEntry->dwLocationNameSize] = TEXT('\0');
  141. if (IsWindow(hwndCB))
  142. {
  143. lr = SendMessage(hwndCB, CB_ADDSTRING, 0, (LPARAM)ach);
  144. if (lr != CB_ERR)
  145. {
  146. SendMessage(hwndCB, CB_SETITEMDATA, (WPARAM)lr,
  147. (LPARAM)pLnLocEntry->dwPermanentLocationID);
  148. }
  149. else
  150. {
  151. assert(FALSE);
  152. }
  153. }
  154. // Make sure we have a default by setting the first valid entry
  155. // we ecounter to the default. Later in the enumeration, if we
  156. // encounter another ID as the default, we can reset it.
  157. if (pLnLocEntry->dwPermanentLocationID ==
  158. pLnTransCap->dwCurrentLocationID
  159. || dwPreferredCardID == (DWORD)-1)
  160. {
  161. dwPreferredCardID = pLnLocEntry->dwPreferredCardID;
  162. if (hhDriver->dwCountryID == (DWORD)-1)
  163. dwCountryID = pLnLocEntry->dwCountryID;
  164. /* --- Get default location area code if not specified --- */
  165. if (pLnLocEntry->dwCityCodeSize)
  166. {
  167. pach = (LPSTR)pLnTransCap +
  168. pLnLocEntry->dwCityCodeOffset;
  169. if (pLnLocEntry->dwCityCodeSize)
  170. MemCopy(hhDriver->achDefaultAreaCode, pach, pLnLocEntry->dwCityCodeSize);
  171. hhDriver->achDefaultAreaCode[pLnLocEntry->dwCityCodeSize] =
  172. TEXT('\0');
  173. }
  174. }
  175. pLnLocEntry += 1;
  176. }
  177. // If we don't have a country code loaded for this session, then
  178. // use the country code of the current location.
  179. //
  180. if (hhDriver->dwCountryID == (DWORD)-1)
  181. hhDriver->dwCountryID = dwCountryID;
  182. /* --- Select the default location --- */
  183. if (IsWindow(hwndCB))
  184. {
  185. // mrw,2/13/95 - changed so that selection is made by quering
  186. // the combo box rather than saving the index which proved
  187. // unreliable.
  188. //
  189. for (i = 0 ; i < pLnTransCap->dwNumLocations ; ++i)
  190. {
  191. lr = SendMessage(hwndCB, CB_GETITEMDATA, (WPARAM)i, 0);
  192. if (lr != CB_ERR)
  193. {
  194. if ((DWORD)lr == pLnTransCap->dwCurrentLocationID)
  195. SendMessage(hwndCB, CB_SETCURSEL, i, 0);
  196. }
  197. }
  198. }
  199. /* --- Now find the card entry --- */
  200. if (dwPreferredCardID != (DWORD)-1)
  201. {
  202. pLnCardEntry = (LINECARDENTRY *)
  203. ((LPSTR)pLnTransCap + pLnTransCap->dwCardListOffset);
  204. for (i = 0 ; i < pLnTransCap->dwNumCards ; ++i)
  205. {
  206. if (pLnCardEntry->dwPermanentCardID == dwPreferredCardID)
  207. {
  208. if (pLnCardEntry->dwCardNameSize == 0)
  209. break;
  210. pach = (LPSTR)pLnTransCap + pLnCardEntry->dwCardNameOffset;
  211. if (pLnCardEntry->dwCardNameSize)
  212. MemCopy(ach, pach, pLnCardEntry->dwCardNameSize);
  213. ach[pLnCardEntry->dwCardNameSize] = TEXT('\0');
  214. if (IsWindow(hwndTB))
  215. SetWindowText(hwndTB, ach);
  216. break;
  217. }
  218. pLnCardEntry += 1;
  219. }
  220. }
  221. free(pLnTransCap);
  222. pLnTransCap = NULL;
  223. return 0;
  224. }
  225. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  226. * FUNCTION:
  227. * EnumerateCountryCodes
  228. *
  229. * DESCRIPTION:
  230. * Enumerates available country codes.
  231. *
  232. * ARGUMENTS:
  233. * hhDriver - private driver handle
  234. * hwndCB - combobox to fill
  235. *
  236. * RETURNS:
  237. * 0=success, else error code.
  238. *
  239. */
  240. int EnumerateCountryCodes(const HHDRIVER hhDriver, const HWND hwndCB)
  241. {
  242. int iIdx;
  243. DWORD dw;
  244. DWORD dwID;
  245. DWORD dwSize;
  246. TCHAR ach[100];
  247. LPLINECOUNTRYLIST pcl = NULL;
  248. LPLINECOUNTRYENTRY pce;
  249. if (hhDriver == 0)
  250. goto ERROR_EXIT;
  251. /* --- Usual junk to make a TAPI call --- */
  252. if ((pcl = (LPLINECOUNTRYLIST)malloc(sizeof(LINECOUNTRYLIST))) == 0)
  253. {
  254. assert(0);
  255. goto ERROR_EXIT;
  256. }
  257. memset( pcl, 0, sizeof(LINECOUNTRYLIST) );
  258. pcl->dwTotalSize = sizeof(LINECOUNTRYLIST);
  259. // Get the country list all at once.
  260. //
  261. if (lineGetCountry(0, TAPI_VER, pcl) != 0)
  262. {
  263. assert(0);
  264. goto ERROR_EXIT;
  265. }
  266. if (pcl->dwNeededSize > pcl->dwTotalSize)
  267. {
  268. dwSize = pcl->dwNeededSize;
  269. free(pcl);
  270. pcl = NULL;
  271. if ((pcl = (LPLINECOUNTRYLIST)malloc(dwSize)) == 0)
  272. {
  273. assert(0);
  274. goto ERROR_EXIT;
  275. }
  276. memset( pcl, 0, dwSize );
  277. pcl->dwTotalSize = dwSize;
  278. if (lineGetCountry(0, TAPI_VER, pcl) != 0)
  279. {
  280. assert(0);
  281. goto ERROR_EXIT;
  282. }
  283. }
  284. // Empty contents of combo box.
  285. //
  286. if (hwndCB)
  287. SendMessage(hwndCB, CB_RESETCONTENT, 0, 0);
  288. // Country List array starts here...
  289. //
  290. pce = (LPLINECOUNTRYENTRY)((BYTE *)pcl + pcl->dwCountryListOffset);
  291. // Loop thru list of countries and insert into combo box.
  292. //
  293. for (dw = 0 ; dw < pcl->dwNumCountries ; ++dw, ++pce)
  294. {
  295. // Format so country name is first.
  296. //
  297. wsprintf(ach, "%s (%d)", (BYTE *)pcl + pce->dwCountryNameOffset,
  298. pce->dwCountryCode);
  299. // Add to combo box
  300. //
  301. iIdx = (int)SendMessage(hwndCB, CB_ADDSTRING, 0, (LPARAM)ach);
  302. if (iIdx != CB_ERR)
  303. {
  304. SendMessage(hwndCB, CB_SETITEMDATA, (WPARAM)iIdx,
  305. (LPARAM)pce->dwCountryID);
  306. }
  307. }
  308. // Find the current ID and select it.
  309. //
  310. for (dw = 0 ; dw < pcl->dwNumCountries ; ++dw)
  311. {
  312. dwID = (DWORD)SendMessage(hwndCB, CB_GETITEMDATA, (WPARAM)dw, 0);
  313. if (dwID == hhDriver->dwCountryID)
  314. {
  315. SendMessage(hwndCB, CB_SETCURSEL, (WPARAM)dw, 0);
  316. break;
  317. }
  318. }
  319. // Clean up and exit
  320. //
  321. free(pcl);
  322. pcl = NULL;
  323. return 0;
  324. /*==========*/
  325. ERROR_EXIT:
  326. /*==========*/
  327. if (pcl)
  328. {
  329. free(pcl);
  330. pcl = NULL;
  331. }
  332. return -1;
  333. }
  334. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  335. * FUNCTION:
  336. * EnumerateAreaCodes
  337. *
  338. * DESCRIPTION:
  339. * Lists last 10 area codes used.
  340. *
  341. * ARGUMENTS:
  342. * hhDriver - private driver handle
  343. * hwndCB - combobox to fill
  344. *
  345. * RETURNS:
  346. * 0=success, else error.
  347. *
  348. */
  349. int EnumerateAreaCodes(const HHDRIVER hhDriver, const HWND hwndCB)
  350. {
  351. if (hhDriver == 0)
  352. {
  353. assert(FALSE);
  354. return -1;
  355. }
  356. if (hhDriver->achAreaCode[0] == TEXT('\0'))
  357. {
  358. StrCharCopyN(hhDriver->achAreaCode, hhDriver->achDefaultAreaCode,
  359. sizeof(hhDriver->achAreaCode) / sizeof(TCHAR));
  360. }
  361. SetWindowText(hwndCB, hhDriver->achAreaCode);
  362. return 0;
  363. }
  364. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  365. * FUNCTION:
  366. * EnumerateLines
  367. *
  368. * DESCRIPTION:
  369. * Enumerates available lines. If hwndCB is non-zero, loads names.
  370. *
  371. * ARGUMENTS:
  372. * hhDriver - private driver handle
  373. * hwndCB - combo box
  374. *
  375. * RETURNS:
  376. * 0=success, -1=error
  377. *
  378. */
  379. int EnumerateLines(const HHDRIVER hhDriver, const HWND hwndCB)
  380. {
  381. int fHotPhone;
  382. int fRet;
  383. DWORD i;
  384. DWORD dwSize;
  385. DWORD dwAPIVersion;
  386. LINEEXTENSIONID LnExtId;
  387. LPLINEDEVCAPS pLnDevCaps = NULL;
  388. PSTLINEIDS pstLineIds = NULL;
  389. TCHAR * pachLine;
  390. TCHAR achLine[256];
  391. TCHAR ach[256];
  392. LRESULT lr;
  393. if (hhDriver == 0)
  394. {
  395. return -1;
  396. }
  397. // This call knows to free the itemdata associated with this combo.
  398. //
  399. mscResetComboBox(hwndCB);
  400. /* --- Initialize stuff --- */
  401. pLnDevCaps = 0;
  402. hhDriver->dwLine = (DWORD)-1;
  403. hhDriver->fMatchedPermanentLineID = FALSE;
  404. /* --- Enumerate the devices --- */
  405. for (i = 0 ; i < hhDriver->dwLineCnt ; ++i)
  406. {
  407. if (lineNegotiateAPIVersion(hhDriver->hLineApp, i, TAPI_VER,
  408. TAPI_VER, &dwAPIVersion, &LnExtId) != 0)
  409. {
  410. // Could be a 1.3 driver, we continue.
  411. continue;
  412. }
  413. fRet = CheckHotPhone(hhDriver, i, &fHotPhone);
  414. if (fRet < 0)
  415. {
  416. assert(0);
  417. continue;
  418. }
  419. else if (fRet == 0 && fHotPhone)
  420. {
  421. continue;
  422. }
  423. if ((pLnDevCaps = malloc(sizeof(LINEDEVCAPS))) == 0)
  424. {
  425. assert(0);
  426. continue;
  427. }
  428. // TAPI says its too small if we just allocate sizeof(LINEDEVCAPS)
  429. //
  430. memset( pLnDevCaps, 0, sizeof(LINEDEVCAPS) );
  431. pLnDevCaps->dwTotalSize = sizeof(LINEDEVCAPS);
  432. /* --- Make call to find out how much we need for this device --- */
  433. if (TRAP(lineGetDevCaps(hhDriver->hLineApp, i, dwAPIVersion, 0,
  434. pLnDevCaps)) != 0)
  435. {
  436. assert(0);
  437. continue;
  438. }
  439. /* --- Find out how big structure really needs to be --- */
  440. if (pLnDevCaps->dwNeededSize > pLnDevCaps->dwTotalSize)
  441. {
  442. dwSize = pLnDevCaps->dwNeededSize;
  443. free(pLnDevCaps);
  444. pLnDevCaps = NULL;
  445. pLnDevCaps = malloc(dwSize);
  446. if (pLnDevCaps == 0)
  447. {
  448. assert(FALSE);
  449. continue;
  450. }
  451. pLnDevCaps->dwTotalSize = dwSize;
  452. /* --- Try again --- */
  453. if (lineGetDevCaps(hhDriver->hLineApp, i, dwAPIVersion, 0,
  454. pLnDevCaps) != 0)
  455. {
  456. assert(FALSE);
  457. free(pLnDevCaps);
  458. pLnDevCaps = NULL;
  459. continue;
  460. }
  461. }
  462. /* --- Check the information we're interested in --- */
  463. //mpt:03-19-98 added a MaxRate check to eliminate the MS VPN adapter
  464. // from the list of available devices.
  465. //mpt 06-23-98 added a MaxNumActiveCalls check to eliminate the
  466. // H323 and Line0 devices from showing up in our list
  467. if (pLnDevCaps->dwLineNameSize == 0 ||
  468. (pLnDevCaps->dwMaxRate == 0 || pLnDevCaps->dwMaxRate >= 1048576) ||
  469. (pLnDevCaps->dwMaxNumActiveCalls > 1 && pLnDevCaps->dwMaxNumActiveCalls != 32768) )
  470. {
  471. free(pLnDevCaps);
  472. pLnDevCaps = NULL;
  473. continue;
  474. }
  475. pachLine = (BYTE *)pLnDevCaps + pLnDevCaps->dwLineNameOffset;
  476. if (pLnDevCaps->dwLineNameSize)
  477. MemCopy(achLine, pachLine, pLnDevCaps->dwLineNameSize);
  478. achLine[pLnDevCaps->dwLineNameSize] = TEXT('\0');
  479. /* --- Put name in combo box if given one --- */
  480. if (IsWindow(hwndCB))
  481. {
  482. // I need to associate two pieces of data with each
  483. // item (permanent line id and relative line id). Both
  484. // are double words and CB_SETITEMDATA only stores a
  485. // a double word. So malloc a structure to hold both
  486. // ids and store a pointer to the memory in the combobox.
  487. // Call the mscResetComboBox() defined in the file to reset
  488. // the contents of the combobox and free the associated
  489. // memory. mscResetComboBox() is also called in the dialog
  490. // destroy.
  491. //
  492. pstLineIds = malloc(sizeof(*pstLineIds));
  493. if (pstLineIds == 0)
  494. {
  495. assert(FALSE);
  496. free(pLnDevCaps);
  497. pLnDevCaps = NULL;
  498. continue;
  499. }
  500. pstLineIds->dwLineId = i;
  501. pstLineIds->dwPermanentLineId = pLnDevCaps->dwPermanentLineID;
  502. // Add the name to the combobox. Since names are sorted,
  503. // the index of the item is returned from SendMessage and
  504. // stored in lr. Save this index for use below.
  505. //
  506. lr = SendMessage(hwndCB, CB_ADDSTRING, 0, (LPARAM)achLine);
  507. if (lr != CB_ERR)
  508. {
  509. // Note: lr was set above CB_ADDSTRING call.
  510. //
  511. if (SendMessage(hwndCB, CB_SETITEMDATA, (WPARAM)lr,
  512. (LPARAM)pstLineIds) == CB_ERR)
  513. {
  514. assert(FALSE);
  515. free(pstLineIds);
  516. free(pLnDevCaps);
  517. pstLineIds = NULL;
  518. pLnDevCaps = NULL;
  519. continue;
  520. }
  521. }
  522. else
  523. {
  524. free(pstLineIds);
  525. free(pLnDevCaps);
  526. pstLineIds = NULL;
  527. pLnDevCaps = NULL;
  528. continue;
  529. }
  530. }
  531. //
  532. // Only set the Modem as a match if the line device's
  533. // dwPermanentLineID is the same as the drivers dwPermanentLineId.
  534. //
  535. // NOTE: We will set the default in the property page if a match
  536. // is not found in this function. REV: 11/5/2001
  537. //
  538. if (pLnDevCaps->dwPermanentLineID == hhDriver->dwPermanentLineId) //||
  539. //hhDriver->dwLine == (DWORD)-1)
  540. {
  541. hhDriver->dwLine = i;
  542. hhDriver->dwAPIVersion = dwAPIVersion;
  543. StrCharCopyN(hhDriver->achLineName, achLine,
  544. sizeof(hhDriver->achLineName) / sizeof(TCHAR));
  545. if (IsWindow(hwndCB))
  546. {
  547. // Note: lr was set above CB_ADDSTRING call.
  548. //
  549. SendMessage(hwndCB, CB_SETCURSEL, (WPARAM)lr, 0);
  550. }
  551. if (pLnDevCaps->dwPermanentLineID == hhDriver->dwPermanentLineId)
  552. {
  553. hhDriver->fMatchedPermanentLineID = TRUE;
  554. }
  555. }
  556. /* --- Free allocated space --- */
  557. free(pLnDevCaps);
  558. pLnDevCaps = NULL;
  559. }
  560. // Load the direct to com port stuff first
  561. if (LoadString(glblQueryDllHinst(), IDS_CNCT_DIRECTCOM, achLine,
  562. sizeof(achLine) / sizeof(TCHAR)) == 0)
  563. {
  564. assert(FALSE);
  565. // The loading of the string has failed from the resource, so
  566. // add the non-localized string here (I don't believe this string
  567. // is ever translated). REV 8/13/99
  568. //
  569. StrCharCopyN(achLine, TEXT("Direct to Com%d"), sizeof(achLine) / sizeof(TCHAR));
  570. //return -1;
  571. }
  572. // Another nasty bug, DIRECT_COM4 is defined as 0x5A2175d4, which
  573. // makes this one heck of a loop. I think we only want to do this
  574. // four times (as opposed to 1.5 billion). - cab:11/14/96
  575. //
  576. // for (i = 0 ; i < DIRECT_COM4 ; ++i)
  577. //
  578. for( i = 0; i < 4; i++ )
  579. {
  580. wsprintf(ach, achLine, i+1);
  581. if (IsWindow(hwndCB))
  582. {
  583. lr = SendMessage(hwndCB, CB_INSERTSTRING, (WPARAM)-1,
  584. (LPARAM)ach);
  585. pstLineIds = malloc(sizeof(*pstLineIds));
  586. if (pstLineIds == 0)
  587. {
  588. assert(FALSE);
  589. continue;
  590. }
  591. // We don't use a line id here, only a permanent line id.
  592. //
  593. pstLineIds->dwPermanentLineId = DIRECT_COM1+i;
  594. // Note: lr was set above CB_INSERTSTRING call.
  595. //
  596. if (SendMessage(hwndCB, CB_SETITEMDATA, (WPARAM)lr,
  597. (LPARAM)pstLineIds) == CB_ERR)
  598. {
  599. assert(FALSE);
  600. free(pstLineIds);
  601. pstLineIds = NULL;
  602. continue;
  603. }
  604. }
  605. // If this is what was saved in the data file, then set
  606. // the line ids.
  607. //
  608. // Only set the serial port as a match if the drivers
  609. // dwPermanentLineId is equal to DIRECT_COM1+i.
  610. //
  611. // Since dwPermanentLineId is unique on Win9.x so we don't need to
  612. // set the driver's name to the serial port's name. REV: 4/15/2002
  613. //
  614. // NOTE: We will set the default in the property page if a match
  615. // is not found in this function. REV: 11/5/2001
  616. //
  617. if ((DIRECT_COM1+i) == hhDriver->dwPermanentLineId) //||
  618. //hhDriver->dwLine == (DWORD)-1)
  619. {
  620. hhDriver->dwLine = 0;
  621. StrCharCopyN(hhDriver->achLineName, ach,
  622. sizeof(hhDriver->achLineName) / sizeof(TCHAR));
  623. if (IsWindow(hwndCB))
  624. {
  625. // Note: lr was set above CB_ADDSTRING call.
  626. //
  627. SendMessage(hwndCB, CB_SETCURSEL, (WPARAM)lr, 0);
  628. }
  629. hhDriver->fMatchedPermanentLineID = TRUE;
  630. }
  631. }
  632. #if defined(INCL_WINSOCK)
  633. // This is causing a syntax error, so I am fixing it. Why nobody
  634. // found this sooner, I have no idea. - cab:11/14/96
  635. //
  636. //if (LoadString(glblQueryDllHinst(), IDS_WINSOCK_SETTINGS_STR, ach,
  637. // sizeof(ach));
  638. //
  639. if (LoadString(glblQueryDllHinst(), IDS_WINSOCK_SETTINGS_STR, ach,
  640. sizeof(ach) / sizeof(TCHAR)) == 0)
  641. {
  642. assert(FALSE);
  643. // The loading of the string has failed from the resource, so
  644. // add the non-localized string here (I don't believe this string
  645. // is ever translated). REV 8/13/99
  646. //
  647. StrCharCopyN(ach, TEXT("TCP/IP (Winsock)"), sizeof(ach) / sizeof(TCHAR));
  648. //return -1;
  649. }
  650. if (IsWindow(hwndCB))
  651. {
  652. lr = SendMessage(hwndCB, CB_INSERTSTRING, (WPARAM)-1,
  653. (LPARAM)ach);
  654. pstLineIds = malloc(sizeof(*pstLineIds));
  655. if (pstLineIds == 0)
  656. {
  657. assert(FALSE);
  658. free(pstLineIds);
  659. pstLineIds = NULL;
  660. return 0;
  661. }
  662. // We don't use a line id here, only a permanent line id.
  663. //
  664. pstLineIds->dwPermanentLineId = DIRECT_COMWINSOCK;
  665. // Note: lr was set above CB_INSERTSTRING call.
  666. //
  667. if (SendMessage(hwndCB, CB_SETITEMDATA, (WPARAM)lr,
  668. (LPARAM)pstLineIds) == CB_ERR)
  669. {
  670. assert(FALSE);
  671. }
  672. }
  673. // Check to see if the current connection is winsock. - cab:11/15/96
  674. //
  675. // Only set the Winsock(TCP/IP) as a match if the drivers
  676. // dwPermanentLineId is DIRECT_COMWSOCK.
  677. //
  678. // NOTE: We will set the default in the property page if a match
  679. // is not found in this function. REV: 11/5/2001
  680. //
  681. if (DIRECT_COMWINSOCK == hhDriver->dwPermanentLineId) //||
  682. //hhDriver->dwLine == (DWORD)-1)
  683. {
  684. hhDriver->dwLine = 0;
  685. StrCharCopyN(hhDriver->achLineName, ach, sizeof(hhDriver->achLineName) / sizeof(TCHAR));
  686. if (IsWindow(hwndCB))
  687. {
  688. // Note: lr was set above CB_INSERTSTRING call.
  689. //
  690. SendMessage(hwndCB, CB_SETCURSEL, (WPARAM)lr, 0);
  691. }
  692. if (DIRECT_COMWINSOCK == hhDriver->dwPermanentLineId)
  693. {
  694. hhDriver->fMatchedPermanentLineID = TRUE;
  695. }
  696. // Don't free the pstLineIds since it will be freed in the
  697. // mscResetComboBox() function. We were previously freeing the
  698. // memory twice causing a crash with the MSVC 6.0 runtime DLL's.
  699. // I'm suprised this did not present itself earlier. REV 8/17/98
  700. //
  701. //free(pstLineIds);
  702. }
  703. #endif
  704. return 0;
  705. }
  706. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  707. * FUNCTION:
  708. * EnumerateLinesNT
  709. *
  710. * DESCRIPTION:
  711. * Enumerates available lines. This function is similar to EnumerateLines, but
  712. * we use different methods to enumerate the ports under Windows NT.
  713. *
  714. * ARGUMENTS:
  715. * hhDriver - private driver handle
  716. * hwndCB - combo box
  717. *
  718. * RETURNS:
  719. * 0=success, -1=error
  720. *
  721. */
  722. int EnumerateLinesNT(const HHDRIVER hhDriver, const HWND hwndCB)
  723. {
  724. int fHotPhone;
  725. int fRet;
  726. DWORD i;
  727. DWORD dwSize;
  728. DWORD dwAPIVersion;
  729. LINEEXTENSIONID LnExtId;
  730. LPLINEDEVCAPS pLnDevCaps = NULL;
  731. PSTLINEIDS pstLineIds = NULL;
  732. TCHAR * pachLine;
  733. TCHAR achLine[256];
  734. TCHAR ach[256];
  735. TCHAR ab[256];
  736. LRESULT lr;
  737. LRESULT nNumberItemInList = 0;
  738. HKEY hKey;
  739. LONG retval;
  740. DWORD dwType;
  741. DWORD dwSizeBuf;
  742. DWORD iMaxComPortEnum = SHRT_MAX; // Make sure we have a
  743. // limit on the number of
  744. // ports we enumerate so
  745. // that we don't get into
  746. // an endless loop. SHRT_MAX
  747. // is the scroll bar maximum
  748. // used in the combo box
  749. // dropdown list.
  750. // REV: 11/14/2000.
  751. if (hhDriver == 0)
  752. {
  753. return -1;
  754. }
  755. // This call knows to free the itemdata associated with this combo.
  756. //
  757. mscResetComboBox(hwndCB);
  758. /* --- Initialize stuff --- */
  759. pLnDevCaps = 0;
  760. if ( StrCharCmp(hhDriver->achLineName, "") == 0 )
  761. {
  762. hhDriver->dwLine = (DWORD)-1;
  763. }
  764. else
  765. {
  766. hhDriver->dwLine = 0;
  767. }
  768. hhDriver->fMatchedPermanentLineID = FALSE;
  769. /* --- Enumerate the devices --- */
  770. for (i = 0 ; i < hhDriver->dwLineCnt ; ++i)
  771. {
  772. if (retval = lineNegotiateAPIVersion(hhDriver->hLineApp, i, TAPI_VER,
  773. TAPI_VER, &dwAPIVersion, &LnExtId) != 0)
  774. {
  775. // Could be a 1.3 driver, we continue.
  776. continue;
  777. }
  778. fRet = CheckHotPhone(hhDriver, i, &fHotPhone);
  779. if (fRet < 0)
  780. {
  781. assert(0);
  782. continue;
  783. }
  784. else if (fRet == 0 && fHotPhone)
  785. {
  786. continue;
  787. }
  788. if ((pLnDevCaps = malloc(sizeof(LINEDEVCAPS))) == 0)
  789. {
  790. assert(0);
  791. continue;
  792. }
  793. if (hhDriver->hLineApp == 0)
  794. {
  795. assert(FALSE);
  796. continue;
  797. }
  798. // TAPI says its too small if we just allocate sizeof(LINEDEVCAPS)
  799. //
  800. pLnDevCaps->dwTotalSize = sizeof(LINEDEVCAPS);
  801. /* --- Make call to find out how much we need for this device --- */
  802. if (TRAP(lineGetDevCaps(hhDriver->hLineApp, i, dwAPIVersion, 0,
  803. pLnDevCaps)) != 0)
  804. {
  805. assert(0);
  806. continue;
  807. }
  808. /* --- Find out how big structure really needs to be --- */
  809. if (pLnDevCaps->dwNeededSize > pLnDevCaps->dwTotalSize)
  810. {
  811. dwSize = pLnDevCaps->dwNeededSize;
  812. free(pLnDevCaps);
  813. pLnDevCaps = NULL;
  814. pLnDevCaps = malloc(dwSize);
  815. if (pLnDevCaps == 0)
  816. {
  817. assert(FALSE);
  818. continue;
  819. }
  820. pLnDevCaps->dwTotalSize = dwSize;
  821. /* --- Try again --- */
  822. if (lineGetDevCaps(hhDriver->hLineApp, i, dwAPIVersion, 0,
  823. pLnDevCaps) != 0)
  824. {
  825. assert(FALSE);
  826. continue;
  827. }
  828. }
  829. /* --- Check the information we're interested in --- */
  830. //mpt:03-19-98 added a MaxRate check to eliminate the MS VPN adapter
  831. // from the list of available devices.
  832. //mpt 06-23-98 added a MaxNumActiveCalls check to eliminate the
  833. // H323 and Line0 devices from showing up in our list
  834. if (pLnDevCaps->dwLineNameSize == 0 ||
  835. (pLnDevCaps->dwMaxRate == 0 || pLnDevCaps->dwMaxRate >= 1048576) ||
  836. (pLnDevCaps->dwMaxNumActiveCalls > 1 && pLnDevCaps->dwMaxNumActiveCalls != 32768) )
  837. {
  838. free(pLnDevCaps);
  839. pLnDevCaps = NULL;
  840. continue;
  841. }
  842. pachLine = (BYTE *)pLnDevCaps + pLnDevCaps->dwLineNameOffset;
  843. if (pLnDevCaps->dwLineNameSize)
  844. MemCopy(achLine, pachLine, pLnDevCaps->dwLineNameSize);
  845. achLine[pLnDevCaps->dwLineNameSize] = TEXT('\0');
  846. /* --- Put name in combo box if given one --- */
  847. if (IsWindow(hwndCB))
  848. {
  849. // I need to associate two pieces of data with each
  850. // item (permanent line id and relative line id). Both
  851. // are double words and CB_SETITEMDATA only stores a
  852. // a double word. So malloc a structure to hold both
  853. // ids and store a pointer to the memory in the combobox.
  854. // Call the mscResetComboBox() defined in the file to reset
  855. // the contents of the combobox and free the associated
  856. // memory. mscResetComboBox() is also called in the dialog
  857. // destroy.
  858. //
  859. pstLineIds = malloc(sizeof(*pstLineIds));
  860. if (pstLineIds == 0)
  861. {
  862. assert(FALSE);
  863. free(pLnDevCaps);
  864. pLnDevCaps = NULL;
  865. continue;
  866. }
  867. pstLineIds->dwLineId = i;
  868. pstLineIds->dwPermanentLineId = pLnDevCaps->dwPermanentLineID;
  869. // Add the name to the combobox. Since names are sorted,
  870. // the index of the item is returned from SendMessage and
  871. // stored in lr. Save this index for use below.
  872. //
  873. lr = SendMessage(hwndCB, CB_ADDSTRING, 0, (LPARAM)achLine);
  874. if (lr != CB_ERR && lr != CB_ERRSPACE)
  875. {
  876. nNumberItemInList++;
  877. // Note: lr was set above CB_ADDSTRING call.
  878. //
  879. if (SendMessage(hwndCB, CB_SETITEMDATA, (WPARAM)lr,
  880. (LPARAM)pstLineIds) == CB_ERR)
  881. {
  882. assert(FALSE);
  883. free(pstLineIds);
  884. free(pLnDevCaps);
  885. pstLineIds = NULL;
  886. pLnDevCaps = NULL;
  887. continue;
  888. }
  889. }
  890. else
  891. {
  892. free(pstLineIds);
  893. free(pLnDevCaps);
  894. pstLineIds = NULL;
  895. pLnDevCaps = NULL;
  896. continue;
  897. }
  898. }
  899. //
  900. // Only set the Modem as a match if the line device's
  901. // dwPermanentLineID is the same as the drivers dwPermanentLineId.
  902. //
  903. // NOTE: We will set the default in the property page if a match
  904. // is not found in this function. REV: 11/5/2001
  905. //
  906. if (pLnDevCaps->dwPermanentLineID == hhDriver->dwPermanentLineId) //||
  907. //hhDriver->dwLine == (DWORD)-1)
  908. {
  909. hhDriver->dwLine = i;
  910. hhDriver->dwAPIVersion = dwAPIVersion;
  911. StrCharCopyN(hhDriver->achLineName, achLine,
  912. sizeof(hhDriver->achLineName) / sizeof(TCHAR));
  913. if (IsWindow(hwndCB))
  914. {
  915. // Note: lr was set above CB_ADDSTRING call.
  916. //
  917. SendMessage(hwndCB, CB_SETCURSEL, (WPARAM)lr, 0);
  918. }
  919. if (pLnDevCaps->dwPermanentLineID == hhDriver->dwPermanentLineId)
  920. hhDriver->fMatchedPermanentLineID = TRUE;
  921. }
  922. /* --- Free allocated space --- */
  923. free(pLnDevCaps);
  924. pLnDevCaps = NULL;
  925. }
  926. // Load the direct to com port stuff first
  927. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  928. TEXT("hardware\\devicemap\\serialcomm"),
  929. 0, KEY_READ, &hKey) != ERROR_SUCCESS)
  930. {
  931. assert(FALSE);
  932. // We used to return FALSE here which would mean the TCP/IP
  933. // would not be in the enumerated connection methods (modem,
  934. // COM port or Winsock) in the "Connect Using:" dropdown
  935. // combobox in the properties for the entries. Since the
  936. // return value was never checked, we can just continue on
  937. // to finish the enumerations for the combobox. Now we just
  938. // set the number of COM ports to enumerate to 0. REV 8/13/99.
  939. //
  940. //return FALSE;
  941. iMaxComPortEnum = 0;
  942. }
  943. // Make sure we don't enumerate mar than the maximum number of ports
  944. // minus the number of TAPI devices. If we are including WINSOCK, then
  945. // subtract 1 for the TCP/IP (WinSock) combobox item.
  946. #if defined(INCL_WINSOCK)
  947. iMaxComPortEnum = iMaxComPortEnum - (DWORD)nNumberItemInList - 1;
  948. #else
  949. iMaxComPortEnum = iMaxComPortEnum - (DWORD)nNumberItemInList;
  950. #endif
  951. // We now use a variable for the number of drives to enumerate.
  952. // We have set the number of COM ports to enumerate in a variable
  953. // above (iMaxComPortEnum == 0 if no COM ports installed). REV 8/13/99.
  954. //
  955. for (i = 0 ; i < iMaxComPortEnum ; ++i)
  956. {
  957. dwSizeBuf = sizeof(ab) / sizeof(TCHAR);
  958. dwSize = sizeof(ach) / sizeof(TCHAR);
  959. // Enumerate devices under our serialcomm key
  960. //
  961. if (RegEnumValue(hKey, i, ach, &dwSize, 0, &dwType, ab,
  962. &dwSizeBuf) != ERROR_SUCCESS)
  963. {
  964. break;
  965. }
  966. // Ignore anything that isn't a string.
  967. //
  968. if (dwType != REG_SZ)
  969. continue;
  970. if (IsWindow(hwndCB))
  971. {
  972. lr = SendMessage(hwndCB, CB_INSERTSTRING, (WPARAM)-1,
  973. (LPARAM)ab);
  974. //
  975. // See if an error occured due to out of memory. If so,
  976. // then don't enumerate any more ports. REV: 11/15/2000
  977. //
  978. if( lr == CB_ERRSPACE || lr == CB_ERR )
  979. {
  980. break;
  981. }
  982. nNumberItemInList++;
  983. pstLineIds = malloc(sizeof(*pstLineIds));
  984. if (pstLineIds == 0)
  985. {
  986. assert(FALSE);
  987. continue;
  988. }
  989. // We don't use a line id here, only a permanent line id.
  990. //
  991. pstLineIds->dwPermanentLineId = DIRECT_COM_DEVICE;
  992. // Note: lr was set above CB_INSERTSTRING call.
  993. //
  994. if (SendMessage(hwndCB, CB_SETITEMDATA, (WPARAM)lr,
  995. (LPARAM)pstLineIds) == CB_ERR)
  996. {
  997. assert(FALSE);
  998. free(pstLineIds);
  999. pstLineIds = NULL;
  1000. continue;
  1001. }
  1002. }
  1003. //
  1004. // Only set the serial port as a match if the drivers
  1005. // dwPermanentLineId is equal to DIRECT_COM_DEVICE or
  1006. // in the range from DIRECT_COM1 to DIRECT_COM4 and the
  1007. // driver's name is the same as the serial port's name.
  1008. //
  1009. // NOTE: We will set the default in the property page if a match
  1010. // is not found in this function. REV: 11/5/2001
  1011. //
  1012. if ( hhDriver->fMatchedPermanentLineID == FALSE &&
  1013. StrCharCmp(hhDriver->achComDeviceName, ab) == 0 &&
  1014. ( //hhDriver->dwPermanentLineId == (DWORD)-1 ||
  1015. IN_RANGE(hhDriver->dwPermanentLineId, DIRECT_COM1, DIRECT_COM4) ||
  1016. hhDriver->dwPermanentLineId == DIRECT_COM_DEVICE ) )
  1017. {
  1018. hhDriver->dwLine = 0;
  1019. StrCharCopyN(hhDriver->achLineName, ab,
  1020. sizeof(hhDriver->achLineName) / sizeof(TCHAR));
  1021. if (IsWindow(hwndCB))
  1022. {
  1023. // Note: lr was set above CB_ADDSTRING call.
  1024. //
  1025. SendMessage(hwndCB, CB_SETCURSEL, (WPARAM)lr, 0);
  1026. }
  1027. hhDriver->fMatchedPermanentLineID = TRUE;
  1028. }
  1029. }
  1030. #if defined(INCL_WINSOCK)
  1031. // This is causing a syntax error, so I am fixing it. Why nobody
  1032. // found this sooner, I have no idea. - cab:11/14/96
  1033. //
  1034. //if (LoadString(glblQueryDllHinst(), IDS_WINSOCK_SETTINGS_STR, ach,
  1035. // sizeof(ach));
  1036. //
  1037. if (LoadString(glblQueryDllHinst(), IDS_WINSOCK_SETTINGS_STR, ach,
  1038. sizeof(ach) / sizeof(TCHAR)) == 0)
  1039. {
  1040. assert(FALSE);
  1041. // The loading of the string has failed from the resource, so
  1042. // add the non-localized string here (I don't believe this string
  1043. // is ever translated). REV 8/13/99
  1044. //
  1045. StrCharCopyN(ach, TEXT("TCP/IP (Winsock)"), sizeof(ach) / sizeof(TCHAR));
  1046. //return -1;
  1047. }
  1048. if (IsWindow(hwndCB))
  1049. {
  1050. lr = SendMessage(hwndCB, CB_INSERTSTRING, (WPARAM)-1,
  1051. (LPARAM)ach);
  1052. //
  1053. // See if an error occured due to out of memory. If so,
  1054. // then delete the last COM port added so there is room
  1055. // for the TCP/IP (Winsock) item. REV: 11/15/2000
  1056. //
  1057. if( lr == CB_ERRSPACE )
  1058. {
  1059. lr = SendMessage(hwndCB, CB_DELETESTRING, (WPARAM)nNumberItemInList - 1,
  1060. (LPARAM)0);
  1061. lr = SendMessage(hwndCB, CB_INSERTSTRING, (WPARAM)-1,
  1062. (LPARAM)ach);
  1063. }
  1064. if (lr != CB_ERR && lr != CB_ERRSPACE)
  1065. {
  1066. pstLineIds = malloc(sizeof(*pstLineIds));
  1067. if (pstLineIds == 0)
  1068. {
  1069. assert(FALSE);
  1070. free(pstLineIds);
  1071. pstLineIds = NULL;
  1072. return 0;
  1073. }
  1074. // We don't use a line id here, only a permanent line id.
  1075. //
  1076. pstLineIds->dwPermanentLineId = DIRECT_COMWINSOCK;
  1077. // Note: lr was set above CB_INSERTSTRING call.
  1078. //
  1079. if (SendMessage(hwndCB, CB_SETITEMDATA, (WPARAM)lr,
  1080. (LPARAM)pstLineIds) == CB_ERR)
  1081. {
  1082. assert(FALSE);
  1083. }
  1084. }
  1085. }
  1086. // Check to see if the current connection is winsock. - cab:11/15/96
  1087. //
  1088. // Only set the Winsock(TCP/IP) as a match if the drivers
  1089. // dwPermanentLineId is DIRECT_COMWSOCK.
  1090. //
  1091. // NOTE: We will set the default in the property page if a match
  1092. // is not found in this function. REV: 11/5/2001
  1093. //
  1094. if (DIRECT_COMWINSOCK == hhDriver->dwPermanentLineId) //||
  1095. //hhDriver->dwLine == (DWORD)-1)
  1096. {
  1097. hhDriver->dwLine = 0;
  1098. StrCharCopyN(hhDriver->achLineName, ach,
  1099. sizeof(hhDriver->achLineName) / sizeof(TCHAR));
  1100. if (IsWindow(hwndCB))
  1101. {
  1102. // Note: lr was set above CB_INSERTSTRING call.
  1103. //
  1104. SendMessage(hwndCB, CB_SETCURSEL, (WPARAM)lr, 0);
  1105. }
  1106. if (DIRECT_COMWINSOCK == hhDriver->dwPermanentLineId)
  1107. {
  1108. hhDriver->fMatchedPermanentLineID = TRUE;
  1109. }
  1110. // Don't free the pstLineIds since it will be freed in the
  1111. // mscResetComboBox() function. We were previously freeing the
  1112. // memory twice causing a crash with the MSVC 6.0 runtime DLL's.
  1113. // I'm suprised this did not present itself earlier. REV 8/17/98
  1114. //
  1115. //free(pstLineIds);
  1116. }
  1117. #endif
  1118. return 0;
  1119. }
  1120. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1121. * FUNCTION:
  1122. * DoLineGetCountry
  1123. *
  1124. * DESCRIPTION:
  1125. * Wrapper indended to query for a single country. The caller must
  1126. * free the pcl when finished.
  1127. *
  1128. * ARGUMENTS:
  1129. * dwCountryID - ID of country
  1130. * dwApiVersion - Api version (no longer used)
  1131. * ppcl - pointer to a LPLINECOUNTRYLIST
  1132. *
  1133. * RETURNS:
  1134. * 0=OK
  1135. *
  1136. */
  1137. int DoLineGetCountry(const DWORD dwCountryID, const DWORD dwAPIVersion,
  1138. LPLINECOUNTRYLIST *ppcl)
  1139. {
  1140. DWORD dwSize;
  1141. LPLINECOUNTRYLIST pcl = NULL;
  1142. if ((pcl = malloc(sizeof(LINECOUNTRYLIST))) == 0)
  1143. {
  1144. assert(FALSE);
  1145. return -1;
  1146. }
  1147. pcl->dwTotalSize = sizeof(LINECOUNTRYLIST);
  1148. if (lineGetCountry(dwCountryID, TAPI_VER, pcl) != 0)
  1149. {
  1150. assert(FALSE);
  1151. free(pcl);
  1152. pcl = NULL;
  1153. return -1;
  1154. }
  1155. if (pcl->dwNeededSize > pcl->dwTotalSize)
  1156. {
  1157. dwSize = pcl->dwNeededSize;
  1158. free(pcl);
  1159. pcl = NULL;
  1160. if ((pcl = malloc(dwSize)) == 0)
  1161. {
  1162. assert(FALSE);
  1163. return -1;
  1164. }
  1165. pcl->dwTotalSize = dwSize;
  1166. if (lineGetCountry(dwCountryID, TAPI_VER, pcl) != 0)
  1167. {
  1168. assert(FALSE);
  1169. free(pcl);
  1170. pcl = NULL;
  1171. return -1;
  1172. }
  1173. }
  1174. *ppcl = pcl;
  1175. return 0;
  1176. }
  1177. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1178. * FUNCTION:
  1179. * cnctdrvGetComSettingsString
  1180. *
  1181. * DESCRIPTION:
  1182. * Retrieves a string formatted for display on the status line.
  1183. *
  1184. * ARGUMENTS:
  1185. * hhDriver - private driver handle
  1186. * pachStr - buffer to store string
  1187. * cb - size of buffer
  1188. *
  1189. * RETURNS:
  1190. * 0=OK,else error
  1191. *
  1192. */
  1193. int cnctdrvGetComSettingsString(const HHDRIVER hhDriver, LPTSTR pachStr,
  1194. const size_t cb)
  1195. {
  1196. static CHAR acParity[] = "NOEMS"; // see com.h
  1197. static CHAR *pachStop[] = {"1", "1.5", "2"};
  1198. HCOM hCom;
  1199. TCHAR ach[100];
  1200. LPVARSTRING pvs = NULL;
  1201. int fAutoDetect = FALSE;
  1202. long lBaud = 0;
  1203. int iDataBits = 8;
  1204. int iParity = 0;
  1205. int iStopBits = 0;
  1206. #if defined(MODEM_NEGOTIATED_DCE_RATE) // TODO:REV 5/29/2002
  1207. long lNegBaud = 0;
  1208. #endif // defined(MODEM_NEGOTIATED_DCE_RATE)
  1209. // Check the parameters
  1210. //
  1211. if (hhDriver == 0)
  1212. {
  1213. assert(0);
  1214. return -1;
  1215. }
  1216. if (pachStr == 0 || cb == 0)
  1217. {
  1218. assert(0);
  1219. return -2;
  1220. }
  1221. ach[0] = TEXT('\0');
  1222. if ((hCom = sessQueryComHdl(hhDriver->hSession)) == 0)
  1223. return -7;
  1224. // //MPT:11-01-98 Microsoft made these changes to fix a bug relating
  1225. // // to working with multiple connection devices.
  1226. // if (ComGetAutoDetect(hCom, &fAutoDetect) == COM_OK && fAutoDetect)
  1227. // {
  1228. // LoadString(glblQueryDllHinst(), IDS_STATUSBR_AUTODETECT, ach,
  1229. // sizeof(ach) / sizeof(TCHAR));
  1230. // }
  1231. #if defined(INCL_WINSOCK)
  1232. /*else*/ if (hhDriver->dwPermanentLineId == DIRECT_COMWINSOCK)
  1233. {
  1234. // Baud rate, data bits, parity, stop bits don't make sense in
  1235. // TCP/IP. Load an alternate string.
  1236. //
  1237. LoadString(glblQueryDllHinst(), IDS_STATUSBR_COM_TCPIP, ach,
  1238. sizeof(ach) / sizeof(TCHAR));
  1239. }
  1240. #endif
  1241. else if (IN_RANGE(hhDriver->dwPermanentLineId, DIRECT_COM1, DIRECT_COM4)
  1242. || hhDriver->dwPermanentLineId == DIRECT_COM_DEVICE)
  1243. {
  1244. ComGetBaud(hCom, &lBaud);
  1245. ComGetDataBits(hCom, &iDataBits);
  1246. ComGetParity(hCom, &iParity);
  1247. ComGetStopBits(hCom, &iStopBits);
  1248. wsprintf(ach, "%ld %d-%c-%s", lBaud, iDataBits,
  1249. acParity[iParity], pachStop[iStopBits]);
  1250. }
  1251. // Usual lines of code for a TAPI call
  1252. //
  1253. else if (hhDriver->dwLine != (DWORD)-1)
  1254. {
  1255. int retValue = 0;
  1256. iDataBits = 8;
  1257. iParity = NOPARITY;
  1258. iStopBits = ONESTOPBIT;
  1259. retValue = cncttapiGetLineConfig( hhDriver->dwLine, (VOID **) &pvs);
  1260. if (retValue != 0)
  1261. {
  1262. return retValue;
  1263. }
  1264. else
  1265. {
  1266. // The structure of the DevConfig block is as follows
  1267. //
  1268. // VARSTRING
  1269. // UMDEVCFGHDR
  1270. // COMMCONFIG
  1271. // MODEMSETTINGS
  1272. //
  1273. // The UMDEVCFG structure used below is defined in the
  1274. // UNIMODEM.H provided in the platform SDK (in the nih
  1275. // directory for HTPE). REV: 12/01/2000
  1276. //
  1277. PUMDEVCFG pDevCfg = NULL;
  1278. pDevCfg = (UMDEVCFG *)((BYTE *)pvs + pvs->dwStringOffset);
  1279. // commconfig struct has a DCB structure we dereference for the
  1280. // com settings.
  1281. //
  1282. lBaud = pDevCfg->commconfig.dcb.BaudRate;
  1283. iDataBits = pDevCfg->commconfig.dcb.ByteSize;
  1284. iParity = pDevCfg->commconfig.dcb.Parity;
  1285. iStopBits = pDevCfg->commconfig.dcb.StopBits;
  1286. #if defined(MODEM_NEGOTIATED_DCE_RATE) // TODO:REV 5/29/2002
  1287. //
  1288. // See if this is a modem connection and connected, then get
  1289. // the negotiated baud rate instead of the default max rate
  1290. // the modem is set up for. -- REV: 5/29/2002
  1291. //
  1292. if (pDevCfg->commconfig.dwProviderSubType == PST_MODEM)
  1293. {
  1294. MODEMSETTINGS * pModemSettings = (MODEMSETTINGS *)pDevCfg->commconfig.wcProviderData;
  1295. if (pModemSettings)
  1296. {
  1297. lNegBaud = pModemSettings->dwNegotiatedDCERate;
  1298. }
  1299. }
  1300. #endif // defined(MODEM_NEGOTIATED_DCE_RATE)
  1301. }
  1302. #if defined(MODEM_NEGOTIATED_DCE_RATE) // TODO:REV 5/29/2002
  1303. if (lNegBaud > 0)
  1304. {
  1305. wsprintf(ach, "%ld %d-%c-%s", lNegBaud, iDataBits,
  1306. acParity[iParity], pachStop[iStopBits]);
  1307. }
  1308. else
  1309. {
  1310. wsprintf(ach, "%ld %d-%c-%s", lBaud, iDataBits,
  1311. acParity[iParity], pachStop[iStopBits]);
  1312. }
  1313. #else // defined(MODEM_NEGOTIATED_DCE_RATE)
  1314. wsprintf(ach, "%ld %d-%c-%s", lBaud, iDataBits,
  1315. acParity[iParity], pachStop[iStopBits]);
  1316. #endif //defined(MODEM_NEGOTIATED_DCE_RATE)
  1317. }
  1318. // Moved this test to last so any change from 8N1 will not show auto-detect jkh 9/9/98
  1319. if (iDataBits == 8 && iParity == NOPARITY && iStopBits == ONESTOPBIT &&
  1320. ComGetAutoDetect(hCom, &fAutoDetect) == COM_OK && fAutoDetect)
  1321. {
  1322. LoadString(glblQueryDllHinst(), IDS_STATUSBR_AUTODETECT, ach,
  1323. sizeof(ach) / sizeof(TCHAR));
  1324. }
  1325. StrCharCopyN(pachStr, ach, cb);
  1326. pachStr[cb-1] = TEXT('\0');
  1327. free(pvs);
  1328. pvs = NULL;
  1329. return 0;
  1330. }
  1331. #if !defined(NDEBUG)
  1332. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1333. * FUNCTION:
  1334. * tapiTrap
  1335. *
  1336. * DESCRIPTION:
  1337. * Trap TAPI error conditions.
  1338. *
  1339. * ARGUMENTS:
  1340. * dw - result code from tapi
  1341. * file - file where error occured
  1342. * line - line where error occured
  1343. *
  1344. * RETURNS:
  1345. * dw
  1346. *
  1347. */
  1348. DWORD tapiTrap(const DWORD dw, const TCHAR *file, const int line)
  1349. {
  1350. char ach[256];
  1351. if (dw != 0)
  1352. {
  1353. wsprintf(ach, "TAPI returned %x on line %d of file %s", dw, line, file);
  1354. MessageBox(NULL, ach, "TAPI Trap", MB_OK | MB_ICONINFORMATION);
  1355. }
  1356. return dw;
  1357. }
  1358. #endif