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.

5749 lines
135 KiB

  1. /*++
  2. Copyright (C) 1994-98 Microsft Corporation. All rights reserved.
  3. Module Name:
  4. rastapi.c
  5. Abstract:
  6. This file contains all entry points for TAPI.DLL
  7. Author:
  8. Gurdeep Singh Pall (gurdeep) 06-Mar-1995
  9. Revision History:
  10. Miscellaneous Modifications - raos 31-Dec-1997
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <tapi.h>
  17. #include <rasman.h>
  18. #include <raserror.h>
  19. #include <mprlog.h>
  20. #include <rtutils.h>
  21. #include <wanpub.h>
  22. #include <asyncpub.h>
  23. #include <media.h>
  24. #include <device.h>
  25. #include <rasmxs.h>
  26. #include <isdn.h>
  27. #include <serial.h>
  28. #include <stdlib.h>
  29. #include <tchar.h>
  30. #include <malloc.h>
  31. #include <setupapi.h>
  32. #include <string.h>
  33. #include "rastapi.h"
  34. #include <unimodem.h>
  35. #include "reghelp.h"
  36. extern DWORD TotalPorts ;
  37. extern HLINEAPP RasLine ;
  38. extern HINSTANCE RasInstance ;
  39. extern TapiLineInfo *RasTapiLineInfoList ;
  40. extern TapiPortControlBlock *RasPortsList ;
  41. extern TapiPortControlBlock *RasPortsEnd ;
  42. extern HANDLE RasTapiMutex ;
  43. extern BOOL Initialized ;
  44. extern DWORD TapiThreadId ;
  45. extern HANDLE TapiThreadHandle;
  46. // extern DWORD LoaderThreadId;
  47. extern DWORD ValidPorts;
  48. extern HANDLE g_hAsyMac ;
  49. extern HANDLE g_hIoCompletionPort;
  50. extern DWORD *g_pdwNumEndPoints;
  51. extern DeviceInfo *g_pDeviceInfoList;
  52. BOOL g_fDllLoaded = FALSE;
  53. DWORD GetInfo ( TapiPortControlBlock *,
  54. BYTE *,
  55. DWORD *) ;
  56. DWORD SetInfo ( TapiPortControlBlock *,
  57. RASMAN_PORTINFO *) ;
  58. DWORD GetGenericParams ( TapiPortControlBlock *,
  59. RASMAN_PORTINFO *,
  60. PDWORD) ;
  61. DWORD GetIsdnParams ( TapiPortControlBlock *,
  62. RASMAN_PORTINFO * ,
  63. PDWORD) ;
  64. DWORD GetX25Params ( TapiPortControlBlock *,
  65. RASMAN_PORTINFO *,
  66. PDWORD) ;
  67. DWORD FillInX25Params ( TapiPortControlBlock *,
  68. RASMAN_PORTINFO *) ;
  69. DWORD FillInIsdnParams ( TapiPortControlBlock *,
  70. RASMAN_PORTINFO *) ;
  71. DWORD FillInGenericParams ( TapiPortControlBlock *,
  72. RASMAN_PORTINFO *) ;
  73. DWORD FillInUnimodemParams ( TapiPortControlBlock *,
  74. RASMAN_PORTINFO *) ;
  75. VOID SetModemParams ( TapiPortControlBlock *hIOPort,
  76. LINECALLPARAMS *linecallparams) ;
  77. VOID SetGenericParams (TapiPortControlBlock *,
  78. LINECALLPARAMS *);
  79. VOID
  80. SetAtmParams (TapiPortControlBlock *,
  81. LINECALLPARAMS *);
  82. VOID
  83. SetX25Params(TapiPortControlBlock *hIOPort,
  84. LINECALLPARAMS *linecallparams);
  85. DWORD InitiatePortDisconnection (TapiPortControlBlock *hIOPort) ;
  86. TapiPortControlBlock *LookUpControlBlock (HANDLE hPort) ;
  87. DWORD ValueToNum(RAS_PARAMS *p) ;
  88. extern DWORD dwTraceId;
  89. #define CCH_GUID_STRING_LEN 39 // 38 chars + terminator null
  90. /*++
  91. Routine Description:
  92. Searches for a specific device on a given interface.
  93. It does this by using setup api to return all of the
  94. devices in the class given by pguidInterfaceId. It then
  95. gets device path for each of these device interfaces and
  96. looks for pguidDeviceId and pszwReferenceString as
  97. substrings.
  98. Arguments:
  99. pguidDeviceId [in] The device id to find.
  100. pguidInterfaceId [in] The interface on which to look.
  101. pszwReferenceString [in] Optional. Further match on this ref string.
  102. dwFlagsAndAttributes [in] See CreateFile. This is how the device is
  103. opened if it is found.
  104. phFile [out] The returned device handle.
  105. Return Value:
  106. TRUE if found and opened, FALSE if not found, or an error.
  107. --*/
  108. BOOL
  109. FindDeviceOnInterface (
  110. const GUID* pguidDeviceId,
  111. const GUID* pguidInterfaceId,
  112. LPCWSTR pszwReferenceString,
  113. DWORD dwFlagsAndAttributes,
  114. HANDLE* phFile)
  115. {
  116. WCHAR szwDeviceId [CCH_GUID_STRING_LEN];
  117. INT cch;
  118. HDEVINFO hdi;
  119. BOOL fFound = FALSE;
  120. ASSERT (pguidDeviceId);
  121. ASSERT (pguidInterfaceId);
  122. ASSERT (phFile);
  123. //
  124. // Initialize the output parameter.
  125. //
  126. *phFile = INVALID_HANDLE_VALUE;
  127. cch = StringFromGUID2 (pguidDeviceId,
  128. szwDeviceId,
  129. CCH_GUID_STRING_LEN);
  130. ASSERT (CCH_GUID_STRING_LEN == cch);
  131. CharLowerW (szwDeviceId);
  132. //
  133. // Get the devices in this class.
  134. //
  135. hdi = SetupDiGetClassDevsW ((LPGUID)pguidInterfaceId,
  136. NULL, NULL,
  137. DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
  138. if (hdi)
  139. {
  140. //
  141. // pDetail is used to get device interface
  142. // detail for each device interface enumerated
  143. // below.
  144. //
  145. PSP_DEVICE_INTERFACE_DETAIL_DATA_W pDetail;
  146. const ULONG cbDetail = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)
  147. +(MAX_PATH * sizeof(WCHAR));
  148. pDetail = malloc (cbDetail);
  149. if (pDetail)
  150. {
  151. //
  152. // Enumerate the device interfaces looking for
  153. // the one specified.
  154. //
  155. DWORD dwIndex;
  156. SP_DEVICE_INTERFACE_DATA did;
  157. ZeroMemory (&did, sizeof(did));
  158. for (dwIndex = 0;
  159. did.cbSize = sizeof(did),
  160. SetupDiEnumDeviceInterfaces (hdi, NULL,
  161. (LPGUID)(pguidInterfaceId),
  162. dwIndex,
  163. &did);
  164. dwIndex++)
  165. {
  166. //
  167. // Now get the details so we can compare the
  168. // device path.
  169. //
  170. pDetail->cbSize = sizeof(*pDetail);
  171. if (SetupDiGetDeviceInterfaceDetailW (hdi, &did,
  172. pDetail, cbDetail, NULL, NULL))
  173. {
  174. CharLowerW (pDetail->DevicePath);
  175. //
  176. // Look for a substring containing szwDeviceId. Also
  177. // look for a substring containing pszwReferenceString
  178. // if it is specified.
  179. //
  180. if ( wcsstr (pDetail->DevicePath, szwDeviceId)
  181. && ( !pszwReferenceString
  182. || !*pszwReferenceString
  183. || wcsstr (pDetail->DevicePath,
  184. pszwReferenceString)))
  185. {
  186. //
  187. // We found it, so open the device and return it.
  188. //
  189. HANDLE hFile = CreateFileW (
  190. pDetail->DevicePath,
  191. GENERIC_READ | GENERIC_WRITE,
  192. 0,
  193. NULL,
  194. OPEN_EXISTING,
  195. dwFlagsAndAttributes,
  196. NULL);
  197. if ( hFile
  198. && (INVALID_HANDLE_VALUE != hFile))
  199. {
  200. *phFile = hFile;
  201. fFound = TRUE;
  202. }
  203. else
  204. {
  205. DWORD dwErr = GetLastError();
  206. RasTapiTrace("Createfile %ws failed with %d",
  207. pDetail->DevicePath, dwErr);
  208. }
  209. //
  210. // Now that we've found it, break out of the loop.
  211. //
  212. break;
  213. }
  214. }
  215. }
  216. free (pDetail);
  217. }
  218. SetupDiDestroyDeviceInfoList (hdi);
  219. }
  220. return fFound;
  221. }
  222. DWORD
  223. OpenAsyncMac (
  224. HANDLE *phAsyMac
  225. )
  226. {
  227. static const GUID DEVICE_GUID_ASYNCMAC =
  228. {0xeeab7790,0xc514,0x11d1,{0xb4,0x2b,0x00,0x80,0x5f,0xc1,0x27,0x0e}};
  229. static const GUID GUID_NDIS_LAN_CLASS =
  230. {0xad498944,0x762f,0x11d0,{0x8d,0xcb,0x00,0xc0,0x4f,0xc3,0x35,0x8c}};
  231. HANDLE hAsyMac = INVALID_HANDLE_VALUE;
  232. HANDLE hSwenum;
  233. BOOL fFound;
  234. DWORD dwErr = SUCCESS;
  235. fFound = FindDeviceOnInterface (
  236. &DEVICE_GUID_ASYNCMAC,
  237. &GUID_NDIS_LAN_CLASS,
  238. L"asyncmac",
  239. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  240. &hSwenum);
  241. if (fFound)
  242. {
  243. hAsyMac = CreateFileW (
  244. L"\\\\.\\ASYNCMAC",
  245. GENERIC_READ | GENERIC_WRITE,
  246. FILE_SHARE_READ | FILE_SHARE_WRITE,
  247. NULL,
  248. OPEN_EXISTING,
  249. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  250. NULL);
  251. if(INVALID_HANDLE_VALUE == hAsyMac)
  252. {
  253. dwErr = GetLastError();
  254. RasTapiTrace("Failed to createfile asyncmac. rc=0x%x",
  255. dwErr);
  256. }
  257. CloseHandle (hSwenum);
  258. }
  259. else
  260. {
  261. dwErr = ERROR_FILE_NOT_FOUND;
  262. RasTapiTrace("FindDeviceOnInterface returned FALSE");
  263. }
  264. *phAsyMac = hAsyMac;
  265. return dwErr;
  266. }
  267. DWORD APIENTRY
  268. PortSetIoCompletionPort(HANDLE hIoCompletionPort)
  269. {
  270. g_hIoCompletionPort = hIoCompletionPort;
  271. return SUCCESS;
  272. }
  273. /*++
  274. Routine Description:
  275. This API returns a buffer containing
  276. a PortMediaInfo struct.
  277. Arguments:
  278. Return Value:
  279. SUCCESS
  280. ERROR_BUFFER_TOO_SMALL
  281. ERROR_READING_SECTIONNAME
  282. ERROR_READING_DEVICETYPE
  283. ERROR_READING_DEVICENAME
  284. ERROR_READING_USAGE
  285. ERROR_BAD_USAGE_IN_INI_FILE
  286. --*/
  287. DWORD APIENTRY
  288. PortEnum(
  289. BYTE *pBuffer,
  290. DWORD *pdwSize,
  291. DWORD *pdwNumPorts
  292. )
  293. {
  294. PortMediaInfo *pinfo ;
  295. TapiPortControlBlock *pports ;
  296. DWORD numports = 0;
  297. DWORD i ;
  298. // **** Exclusion Begin ****
  299. GetMutex (RasTapiMutex, INFINITE) ;
  300. RasTapiTrace ("PortEnum");
  301. if (!Initialized)
  302. {
  303. HANDLE event;
  304. // LoaderThreadId = GetCurrentThreadId();
  305. event = CreateEvent (NULL, FALSE, FALSE, NULL) ;
  306. if(NULL == event)
  307. {
  308. DWORD dwError = GetLastError();
  309. RasTapiTrace("PortEnum: CreateEvent failed %d",
  310. dwError);
  311. FreeMutex(RasTapiMutex);
  312. return dwError;
  313. }
  314. TapiThreadHandle = CreateThread (
  315. NULL,
  316. 5000,
  317. (LPTHREAD_START_ROUTINE)
  318. EnumerateTapiPorts,
  319. (LPVOID) event,
  320. 0,
  321. &TapiThreadId);
  322. if(NULL == TapiThreadHandle)
  323. {
  324. DWORD dwError = GetLastError();
  325. CloseHandle(event);
  326. FreeMutex(RasTapiMutex);
  327. RasTapiTrace("PortEnum: CreateThread failed %d",
  328. dwError);
  329. return dwError;
  330. }
  331. WaitForSingleObject (event, INFINITE) ;
  332. if ( RasLine == 0 )
  333. {
  334. //
  335. // Wait for the thread to go away!
  336. //
  337. WaitForSingleObject(TapiThreadHandle, INFINITE);
  338. CloseHandle (TapiThreadHandle) ;
  339. // *** Exclusion End ***
  340. FreeMutex (RasTapiMutex) ;
  341. CloseHandle(event);
  342. RasTapiTrace("PortEnum: RasLine == 0, returning "
  343. "ERROR_TAPI_CONFIGURATION");
  344. RasTapiTrace(" ");
  345. return ERROR_TAPI_CONFIGURATION ;
  346. }
  347. CloseHandle (event) ;
  348. Initialized = TRUE ;
  349. }
  350. //
  351. // calculate the number of valid ports
  352. //
  353. pports = RasPortsList;
  354. while ( pports )
  355. {
  356. if (pports->TPCB_State != PS_UNINITIALIZED)
  357. numports++ ;
  358. pports = pports->TPCB_next;
  359. }
  360. RasTapiTrace("PortEnum: Number of Ports = %d", numports );
  361. if (*pdwSize < numports * sizeof(PortMediaInfo))
  362. {
  363. RasTapiTrace ("PortEnum: size required = %d,"
  364. " size avail = %d, returning %d",
  365. numports * sizeof(PortMediaInfo),
  366. *pdwSize, ERROR_BUFFER_TOO_SMALL );
  367. *pdwNumPorts = numports ;
  368. *pdwSize = *pdwNumPorts * sizeof(PortMediaInfo) ;
  369. // *** Exclusion End ***
  370. FreeMutex (RasTapiMutex) ;
  371. return ERROR_BUFFER_TOO_SMALL ;
  372. }
  373. *pdwNumPorts = 0 ;
  374. pinfo = (PortMediaInfo *)pBuffer ;
  375. pports = RasPortsList;
  376. while ( pports )
  377. {
  378. if (pports->TPCB_State == PS_UNINITIALIZED)
  379. {
  380. pports = pports->TPCB_next;
  381. continue ;
  382. }
  383. strcpy (pinfo->PMI_Name, pports->TPCB_Name) ;
  384. pinfo->PMI_Usage = pports->TPCB_Usage ;
  385. strcpy (pinfo->PMI_DeviceType, pports->TPCB_DeviceType) ;
  386. strcpy (pinfo->PMI_DeviceName, pports->TPCB_DeviceName) ;
  387. pinfo->PMI_LineDeviceId = pports->TPCB_Line->TLI_LineId;
  388. pinfo->PMI_AddressId = pports->TPCB_AddressId;
  389. pinfo->PMI_pDeviceInfo =
  390. pports->TPCB_Line->TLI_pDeviceInfo;
  391. pinfo++ ;
  392. (*pdwNumPorts)++ ;
  393. pports = pports->TPCB_next;
  394. }
  395. // *** Exclusion End ***
  396. FreeMutex (RasTapiMutex) ;
  397. return(SUCCESS);
  398. }
  399. DWORD
  400. DwEnableModemDiagnostics(TapiPortControlBlock *pport)
  401. {
  402. DWORD dwErr = SUCCESS;
  403. BYTE bvar[1000];
  404. LPVARSTRING pvar = (LPVARSTRING) bvar;
  405. LONG lr = ERROR_SUCCESS;
  406. RasTapiTrace("DwEnableModemDiagnostics");
  407. //
  408. // Get the device config information regarding
  409. // line diagnostics
  410. //
  411. pvar->dwTotalSize = 1000;
  412. pvar->dwStringSize = 0;
  413. lr = lineGetDevConfig(pport->TPCB_Line->TLI_LineId,
  414. pvar,
  415. "tapi/line/diagnostics");
  416. if( LINEERR_STRUCTURETOOSMALL == lr
  417. || pvar->dwNeededSize > pvar->dwTotalSize)
  418. {
  419. DWORD dwNeededSize = pvar->dwNeededSize;
  420. //
  421. // Allocate the required size
  422. //
  423. if(NULL == (pvar = LocalAlloc(LPTR,
  424. dwNeededSize)))
  425. {
  426. lr = (LONG) GetLastError();
  427. goto done;
  428. }
  429. pvar->dwTotalSize = dwNeededSize;
  430. //
  431. // Call the api again
  432. //
  433. lr = lineGetDevConfig(pport->TPCB_Line->TLI_LineId,
  434. pvar,
  435. "tapi/line/diagnostics");
  436. }
  437. if(ERROR_SUCCESS != lr)
  438. {
  439. goto done;
  440. }
  441. if( STRINGFORMAT_BINARY != pvar->dwStringFormat
  442. || pvar->dwStringSize < sizeof(LINEDIAGNOSTICSCONFIG))
  443. {
  444. RasTapiTrace("No diagnostics information available");
  445. goto done;
  446. }
  447. else
  448. {
  449. PLINEDIAGNOSTICSCONFIG lpConfig;
  450. lpConfig = (PLINEDIAGNOSTICSCONFIG)
  451. ((LPBYTE) pvar + pvar->dwStringOffset);
  452. if(LDSIG_LINEDIAGNOSTICSCONFIG != lpConfig->hdr.dwSig)
  453. {
  454. RasTapiTrace("Invalid LineDiagnostics sig. 0x%x",
  455. lpConfig->hdr.dwSig);
  456. }
  457. lpConfig->hdr.dwParam |= fSTANDARD_CALL_DIAGNOSTICS;
  458. lr = lineSetDevConfig(pport->TPCB_Line->TLI_LineId,
  459. lpConfig,
  460. pvar->dwStringSize,
  461. "tapi/line/diagnostics");
  462. }
  463. done:
  464. if(bvar != (PBYTE) pvar)
  465. {
  466. LocalFree(pvar);
  467. }
  468. RasTapiTrace("DwEnableModemDiagnostics. 0x%x",
  469. lr);
  470. return (DWORD) lr;
  471. }
  472. /*++
  473. Routine Description:
  474. This API opens a COM port. It takes the port name in ASCIIZ
  475. form and supplies a handle to the open port. hNotify is use
  476. to notify the caller if the device on the port shuts down.
  477. Arguments:
  478. Return Value:
  479. SUCCESS
  480. ERROR_PORT_NOT_CONFIGURED
  481. ERROR_DEVICE_NOT_READY
  482. --*/
  483. DWORD APIENTRY
  484. PortOpen(
  485. char *pszPortName,
  486. HANDLE *phIOPort,
  487. HANDLE hIoCompletionPort,
  488. DWORD dwCompletionKey
  489. )
  490. {
  491. TapiPortControlBlock *pports ;
  492. DWORD retcode ;
  493. DWORD i ;
  494. // **** Exclusion Begin ****
  495. GetMutex (RasTapiMutex, INFINITE) ;
  496. RasTapiTrace ("PortOpen: %s", pszPortName );
  497. pports = RasPortsList ;
  498. while ( pports )
  499. {
  500. if ( (_stricmp(pszPortName, pports->TPCB_Name) == 0)
  501. && (pports->TPCB_State != PS_UNAVAILABLE))
  502. {
  503. break ;
  504. }
  505. pports = pports->TPCB_next ;
  506. }
  507. if ( pports )
  508. {
  509. if (pports->TPCB_State == PS_UNINITIALIZED)
  510. {
  511. RasTapiTrace ("PortOpen: state = PS_UNINITIALIZED,"
  512. " returning %d",
  513. ERROR_TAPI_CONFIGURATION );
  514. // **** Exclusion END ****
  515. FreeMutex (RasTapiMutex) ;
  516. RasTapiTrace(" ");
  517. return ERROR_TAPI_CONFIGURATION ;
  518. }
  519. if (pports->TPCB_State != PS_CLOSED)
  520. {
  521. RasTapiTrace("PortOpen: Port is already open. "
  522. "state = %d != PS_CLOSED",
  523. pports->TPCB_State );
  524. // **** Exclusion END ****
  525. FreeMutex (RasTapiMutex) ;
  526. RasTapiTrace(" ");
  527. return ERROR_PORT_ALREADY_OPEN ;
  528. }
  529. if ((_stricmp (pports->TPCB_DeviceType,
  530. DEVICETYPE_UNIMODEM) == 0)) {
  531. if (INVALID_HANDLE_VALUE == g_hAsyMac)
  532. {
  533. retcode = OpenAsyncMac (&g_hAsyMac);
  534. }
  535. if (INVALID_HANDLE_VALUE == g_hAsyMac)
  536. {
  537. RasTapiTrace ("PortOpen: Failed to CreateFile asyncmac."
  538. " %d", retcode );
  539. if(SUCCESS == retcode)
  540. {
  541. RasTapiTrace("Failed to open asyncmac but no error!!!");
  542. retcode = ERROR_FILE_NOT_FOUND;
  543. }
  544. // *** Exclusion END ****
  545. FreeMutex (RasTapiMutex) ;
  546. RasTapiTrace(" ");
  547. return(retcode);
  548. }
  549. }
  550. if (pports->TPCB_Line->TLI_LineState == PS_CLOSED)
  551. {
  552. //
  553. // open line
  554. //
  555. LINEDEVCAPS *linedevcaps ;
  556. BYTE buffer[400] ;
  557. linedevcaps = (LINEDEVCAPS *)buffer ;
  558. linedevcaps->dwTotalSize = sizeof (buffer) ;
  559. lineGetDevCaps (RasLine,
  560. pports->TPCB_Line->TLI_LineId,
  561. pports->TPCB_Line->NegotiatedApiVersion,
  562. pports->TPCB_Line->NegotiatedExtVersion,
  563. linedevcaps) ;
  564. //
  565. // Remove LINEMEDIAMODE_INTERACTIVEVOICE from the
  566. // media mode since this mode cannot be used for
  567. // receiving calls.
  568. //
  569. pports->TPCB_Line->TLI_MediaMode =
  570. linedevcaps->dwMediaModes &
  571. ~( LINEMEDIAMODE_INTERACTIVEVOICE |
  572. LINEMEDIAMODE_AUTOMATEDVOICE) ;
  573. retcode =
  574. lineOpen (RasLine,
  575. pports->TPCB_Line->TLI_LineId,
  576. &pports->TPCB_Line->TLI_LineHandle,
  577. pports->TPCB_Line->NegotiatedApiVersion,
  578. pports->TPCB_Line->NegotiatedExtVersion,
  579. (DWORD_PTR) pports->TPCB_Line,
  580. LINECALLPRIVILEGE_OWNER,
  581. pports->TPCB_Line->TLI_MediaMode,
  582. NULL) ;
  583. if (retcode)
  584. {
  585. RasTapiTrace ("PortOpen: lineOpen Failed. 0x%x",
  586. retcode );
  587. // **** Exclusion END ****
  588. FreeMutex (RasTapiMutex) ;
  589. RasTapiTrace(" ");
  590. return retcode ;
  591. }
  592. //
  593. // Set monitoring of rings
  594. //
  595. lineSetStatusMessages (pports->TPCB_Line->TLI_LineHandle,
  596. LINEDEVSTATE_RINGING, 0) ;
  597. //
  598. // Always turn off the modem lights incase this
  599. // is a modem device
  600. //
  601. if ((_stricmp (pports->TPCB_DeviceType,
  602. DEVICETYPE_UNIMODEM) == 0))
  603. {
  604. //
  605. // unimodem struct not defined in any header
  606. //
  607. typedef struct _DEVCFG
  608. {
  609. DWORD dwSize;
  610. DWORD dwVersion;
  611. WORD fwOptions;
  612. WORD wWaitBong;
  613. } DEVCFG;
  614. #define LAUNCH_LIGHTS 8
  615. LPVARSTRING var ;
  616. BYTE buffer[1000] ;
  617. DEVCFG *devcfg ;
  618. var = (LPVARSTRING)buffer ;
  619. var->dwTotalSize = 1000 ;
  620. var->dwStringSize = 0 ;
  621. lineGetDevConfig(pports->TPCB_Line->TLI_LineId,
  622. var, "comm/datamodem") ;
  623. devcfg = (DEVCFG*) (((LPBYTE) var)
  624. + var->dwStringOffset) ;
  625. devcfg->fwOptions &= ~LAUNCH_LIGHTS ;
  626. lineSetDevConfig (pports->TPCB_Line->TLI_LineId,
  627. devcfg,
  628. var->dwStringSize,
  629. "comm/datamodem") ;
  630. //
  631. // Enable diagnostics on the modem
  632. //
  633. retcode = DwEnableModemDiagnostics(pports);
  634. RasTapiTrace("DwEnableModemDiagnostics returned 0x%x",
  635. retcode);
  636. //
  637. // clear any error in this case. We don't want
  638. // to fail a connection just because we couldn't
  639. // obtain the connect response.
  640. //
  641. retcode = SUCCESS;
  642. }
  643. pports->TPCB_Line->TLI_LineState = PS_OPEN ;
  644. }
  645. //
  646. // Initialize the parameters
  647. //
  648. pports->TPCB_Info[0][0] = '\0' ;
  649. pports->TPCB_Info[1][0] = '\0' ;
  650. pports->TPCB_Info[2][0] = '\0' ;
  651. pports->TPCB_Info[3][0] = '\0' ;
  652. pports->TPCB_Info[4][0] = '\0' ;
  653. strcpy (pports->TPCB_Info[ISDN_CONNECTBPS_INDEX], "64000") ;
  654. pports->TPCB_Line->TLI_OpenCount++ ;
  655. pports->TPCB_State = PS_OPEN ;
  656. pports->TPCB_DisconnectReason = 0 ;
  657. pports->TPCB_CommHandle = INVALID_HANDLE_VALUE ;
  658. pports->TPCB_IoCompletionPort = hIoCompletionPort;
  659. pports->TPCB_CompletionKey = dwCompletionKey;
  660. if (pports->TPCB_Line->CharModeSupported)
  661. {
  662. pports->TPCB_SendRequestId =
  663. pports->TPCB_RecvRequestId = INFINITE;
  664. pports->TPCB_CharMode = FALSE;
  665. //
  666. // If this port does not have a receive fifo
  667. // allocated to it get one and init.
  668. //
  669. if (pports->TPCB_RecvFifo == NULL)
  670. {
  671. if ((pports->TPCB_RecvFifo =
  672. LocalAlloc(LPTR, sizeof(RECV_FIFO) + 1500))
  673. == NULL)
  674. {
  675. RasTapiTrace("PortOpen: LocalAlloc Failed. "
  676. "%d, port %s, state = %d",
  677. GetLastError(),
  678. pports->TPCB_Name,
  679. pports->TPCB_State );
  680. // **** Exclusion END ****
  681. FreeMutex (RasTapiMutex) ;
  682. return(GetLastError()) ;
  683. }
  684. pports->TPCB_RecvFifo->In =
  685. pports->TPCB_RecvFifo->Out =
  686. pports->TPCB_RecvFifo->Count = 0;
  687. pports->TPCB_RecvFifo->Size = 1500;
  688. }
  689. }
  690. *phIOPort = (HANDLE) pports ;
  691. // **** Exclusion END ****
  692. FreeMutex (RasTapiMutex) ;
  693. RasTapiTrace("PortOpen: successfully opened %s",
  694. pszPortName );
  695. RasTapiTrace(" ");
  696. return(SUCCESS);
  697. }
  698. else
  699. {
  700. RasTapiTrace("PortOpen: Port %s not found",
  701. pszPortName );
  702. }
  703. // **** Exclusion END ****
  704. FreeMutex (RasTapiMutex) ;
  705. RasTapiTrace(" ");
  706. return ERROR_PORT_NOT_CONFIGURED ;
  707. }
  708. /*++
  709. Routine Description:
  710. This API closes the COM port for the input handle.
  711. It also finds the SerialPCB for the input handle,
  712. removes it from the linked list, and frees the
  713. memory for it
  714. Arguments:
  715. Return Value:
  716. SUCCESS
  717. Values returned by GetLastError()
  718. --*/
  719. DWORD APIENTRY
  720. PortClose (HANDLE hIOPort)
  721. {
  722. TapiPortControlBlock *pports =
  723. (TapiPortControlBlock *) hIOPort ;
  724. // **** Exclusion Begin ****
  725. GetMutex (RasTapiMutex, INFINITE) ;
  726. RasTapiTrace("PortClose: %s", pports->TPCB_Name );
  727. pports->TPCB_Line->TLI_OpenCount-- ;
  728. if (pports->TPCB_DevConfig)
  729. {
  730. LocalFree (pports->TPCB_DevConfig) ;
  731. }
  732. pports->TPCB_DevConfig = NULL ;
  733. if (pports->TPCB_Line->TLI_OpenCount == 0)
  734. {
  735. pports->TPCB_Line->TLI_LineState = PS_CLOSED ;
  736. lineClose (pports->TPCB_Line->TLI_LineHandle) ;
  737. }
  738. if (pports->TPCB_RecvFifo != NULL)
  739. {
  740. LocalFree(pports->TPCB_RecvFifo);
  741. pports->TPCB_RecvFifo = NULL;
  742. }
  743. if ( pports->TPCB_State == PS_UNAVAILABLE )
  744. {
  745. RasTapiTrace("PortClose: Removing port %s",
  746. pports->TPCB_Name );
  747. //
  748. // This port has been marked for removal
  749. //
  750. dwRemovePort ( pports );
  751. RasTapiTrace("PortClose: Port removed");
  752. }
  753. else
  754. {
  755. RasTapiTrace ("PortClose: Changing state for"
  756. " %s from %d -> %d",
  757. pports->TPCB_Name,
  758. pports->TPCB_State,
  759. PS_CLOSED );
  760. pports->TPCB_State = PS_CLOSED ;
  761. }
  762. // **** Exclusion END ****
  763. FreeMutex (RasTapiMutex) ;
  764. RasTapiTrace(" ");
  765. return(SUCCESS);
  766. }
  767. /*++
  768. Routine Description:
  769. This API returns a block of information to the caller about
  770. the port state. This API may be called before the port is
  771. open in which case it will return inital default values
  772. instead of actual port values.
  773. hIOPort can be null in which case use portname to give
  774. information hIOPort may be the actual file handle or
  775. the hIOPort returned in port open.
  776. Arguments:
  777. Return Value:
  778. SUCCESS
  779. --*/
  780. DWORD APIENTRY
  781. PortGetInfo(
  782. HANDLE hIOPort,
  783. TCHAR *pszPortName,
  784. BYTE *pBuffer,
  785. DWORD *pdwSize
  786. )
  787. {
  788. DWORD i ;
  789. DWORD retcode = ERROR_FROM_DEVICE ;
  790. TapiPortControlBlock *port = RasPortsList;
  791. // **** Exclusion Begin ****
  792. GetMutex (RasTapiMutex, INFINITE) ;
  793. while ( port )
  794. {
  795. if ( !_stricmp(port->TPCB_Name, pszPortName)
  796. || (hIOPort == (HANDLE) port)
  797. || (hIOPort == port->TPCB_CommHandle))
  798. {
  799. hIOPort = (HANDLE) port ;
  800. retcode = GetInfo ((TapiPortControlBlock *) hIOPort,
  801. pBuffer, pdwSize) ;
  802. break ;
  803. }
  804. port = port->TPCB_next;
  805. }
  806. // **** Exclusion END ****
  807. FreeMutex (RasTapiMutex) ;
  808. return (retcode);
  809. }
  810. /*++
  811. Routine Description:
  812. The values for most input keys are used to set the port
  813. parameters directly. However, the carrier BPS and the
  814. error conrol on flag set fields in the Serial Port Control
  815. Block only, and not the port.
  816. hIOPort may the port handle returned in portopen or the
  817. actual file handle.
  818. Arguments:
  819. Return Value:
  820. SUCCESS
  821. ERROR_WRONG_INFO_SPECIFIED
  822. Values returned by GetLastError()
  823. --*/
  824. DWORD APIENTRY
  825. PortSetInfo(HANDLE hIOPort, RASMAN_PORTINFO *pInfo)
  826. {
  827. DWORD retcode ;
  828. // **** Exclusion Begin ****
  829. GetMutex (RasTapiMutex, INFINITE) ;
  830. hIOPort = LookUpControlBlock(hIOPort) ;
  831. if (NULL == hIOPort)
  832. {
  833. FreeMutex ( RasTapiMutex );
  834. RasTapiTrace ("PortSetInfo: Port Not found");
  835. RasTapiTrace(" ");
  836. return ERROR_PORT_NOT_FOUND;
  837. }
  838. retcode = SetInfo ((TapiPortControlBlock *) hIOPort, pInfo) ;
  839. // **** Exclusion END ****
  840. FreeMutex (RasTapiMutex) ;
  841. RasTapiTrace(" ");
  842. return (retcode);
  843. }
  844. /*++
  845. Routine Description:
  846. Really only has meaning if the
  847. call was active. Will return
  848. Arguments:
  849. Return Value:
  850. SUCCESS
  851. Values returned by GetLastError()
  852. --*/
  853. DWORD APIENTRY
  854. PortTestSignalState(HANDLE hPort, DWORD *pdwDeviceState)
  855. {
  856. BYTE buffer[200] ;
  857. LINECALLSTATUS *pcallstatus ;
  858. DWORD retcode = SUCCESS ;
  859. TapiPortControlBlock *hIOPort
  860. = (TapiPortControlBlock *) hPort;
  861. // **** Exclusion Begin ****
  862. GetMutex (RasTapiMutex, INFINITE) ;
  863. *pdwDeviceState = 0 ;
  864. memset (buffer, 0, sizeof(buffer)) ;
  865. pcallstatus = (LINECALLSTATUS *) buffer ;
  866. pcallstatus->dwTotalSize = sizeof (buffer) ;
  867. //
  868. // First check if we have a disconnect reason stored away.
  869. // if so return that.
  870. //
  871. if (hIOPort->TPCB_DisconnectReason)
  872. {
  873. *pdwDeviceState = hIOPort->TPCB_DisconnectReason ;
  874. RasTapiTrace("PortTestSignalState: DisconnectReason = %d",
  875. *pdwDeviceState );
  876. }
  877. else if (hIOPort->TPCB_State != PS_CLOSED)
  878. {
  879. //
  880. // Only in case of CONNECTING or CONNECTED do we care
  881. // how the link dropped
  882. //
  883. if ( hIOPort->TPCB_State == PS_CONNECTING
  884. || hIOPort->TPCB_State == PS_CONNECTED)
  885. {
  886. retcode = lineGetCallStatus(hIOPort->TPCB_CallHandle,
  887. pcallstatus) ;
  888. if (retcode)
  889. {
  890. #if DBG
  891. DbgPrint("PortTestSignalState: "
  892. "lineGetCallStatus Failed. retcode = %d\n",
  893. retcode);
  894. #endif
  895. *pdwDeviceState = SS_HARDWAREFAILURE;
  896. }
  897. else if (pcallstatus->dwCallState ==
  898. LINECALLSTATE_DISCONNECTED)
  899. {
  900. *pdwDeviceState = SS_LINKDROPPED ;
  901. }
  902. else if (pcallstatus->dwCallState ==
  903. LINECALLSTATE_IDLE)
  904. {
  905. *pdwDeviceState = SS_HARDWAREFAILURE ;
  906. }
  907. else if (pcallstatus->dwCallState ==
  908. LINECALLSTATE_SPECIALINFO)
  909. {
  910. *pdwDeviceState = SS_HARDWAREFAILURE ;
  911. }
  912. RasTapiTrace("PortTestSignalState: CallState"
  913. " = 0x%x, DeviceState = %d",
  914. pcallstatus->dwCallState,
  915. *pdwDeviceState );
  916. }
  917. else
  918. {
  919. RasTapiTrace("PortTestSignalState: DeviceState = %d",
  920. *pdwDeviceState );
  921. *pdwDeviceState = SS_LINKDROPPED | SS_HARDWAREFAILURE ;
  922. }
  923. }
  924. // **** Exclusion END ****
  925. FreeMutex (RasTapiMutex) ;
  926. return retcode ;
  927. }
  928. /*++
  929. Routine Description:
  930. This API is called when a connection has been completed.
  931. It in turn calls the asyncmac device driver in order to
  932. indicate to asyncmac that the port and the connection
  933. over it are ready for commumication.
  934. Arguments:
  935. Return Value:
  936. SUCCESS
  937. ERROR_PORT_NOT_OPEN
  938. ERROR_NO_CONNECTION
  939. Values returned by GetLastError()
  940. --*/
  941. DWORD APIENTRY
  942. PortConnect(HANDLE hPort,
  943. BOOL bLegacyFlagNotUsed,
  944. ULONG_PTR *endpoint )
  945. {
  946. DCB DCB ;
  947. LINECALLINFO linecall ;
  948. ASYMAC_OPEN AsyMacOpen;
  949. ASYMAC_DCDCHANGE A ;
  950. DWORD dwBytesReturned ;
  951. TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
  952. VARSTRING *varstring ;
  953. BYTE buffer [100] ;
  954. // **** Exclusion Begin ****
  955. GetMutex (RasTapiMutex, INFINITE) ;
  956. RasTapiTrace("PortConnect: %s", hIOPort->TPCB_Name );
  957. //
  958. // We must be connected to process this
  959. //
  960. if (hIOPort->TPCB_State != PS_CONNECTED)
  961. {
  962. RasTapiTrace (
  963. "PortConnect: Port %s not connected. state = %d",
  964. hIOPort->TPCB_Name,
  965. hIOPort->TPCB_State );
  966. // **** Exclusion END ****
  967. FreeMutex (RasTapiMutex) ;
  968. RasTapiTrace(" ");
  969. return ERROR_PORT_DISCONNECTED ;
  970. }
  971. //
  972. // get the cookie to realize tapi and ndis endpoints
  973. //
  974. memset (buffer, 0, sizeof(buffer));
  975. varstring = (VARSTRING *) buffer ;
  976. varstring->dwTotalSize = sizeof(buffer) ;
  977. //
  978. // get the actual line speed at which we connected
  979. //
  980. memset (&linecall, 0, sizeof (linecall)) ;
  981. linecall.dwTotalSize = sizeof (linecall) ;
  982. lineGetCallInfo (hIOPort->TPCB_CallHandle, &linecall) ;
  983. _ltoa(linecall.dwRate, hIOPort->TPCB_Info[CONNECTBPS_INDEX], 10);
  984. if (_stricmp (hIOPort->TPCB_DeviceType,
  985. DEVICETYPE_UNIMODEM) == 0)
  986. {
  987. if(INVALID_HANDLE_VALUE == hIOPort->TPCB_CommHandle)
  988. {
  989. DWORD retcode;
  990. if ( retcode =
  991. lineGetID (hIOPort->TPCB_Line->TLI_LineHandle,
  992. hIOPort->TPCB_AddressId,
  993. hIOPort->TPCB_CallHandle,
  994. LINECALLSELECT_CALL,
  995. varstring,
  996. "comm/datamodem"))
  997. {
  998. RasTapiTrace("PortConnect: %s lineGetID Failed. 0x%x",
  999. hIOPort->TPCB_Name, retcode );
  1000. // **** Exclusion End ****
  1001. FreeMutex (RasTapiMutex) ;
  1002. RasTapiTrace(" ");
  1003. return ERROR_FROM_DEVICE ;
  1004. }
  1005. hIOPort->TPCB_CommHandle = (HANDLE)
  1006. UlongToPtr((*((DWORD UNALIGNED *)
  1007. ((BYTE *)varstring+varstring->dwStringOffset))));
  1008. RasTapiTrace("PortConnect: TPCB_CommHandle=%d",
  1009. hIOPort->TPCB_CommHandle );
  1010. //
  1011. // Create the I/O completion port for
  1012. // asynchronous operation completion
  1013. // notificiations.
  1014. //
  1015. if (CreateIoCompletionPort(
  1016. hIOPort->TPCB_CommHandle,
  1017. hIOPort->TPCB_IoCompletionPort,
  1018. hIOPort->TPCB_CompletionKey,
  1019. 0) == NULL)
  1020. {
  1021. retcode = GetLastError();
  1022. RasTapiTrace("PortConnect: %s. CreateIoCompletionPort "
  1023. "failed. %d",
  1024. hIOPort->TPCB_Name,
  1025. retcode );
  1026. FreeMutex(RasTapiMutex);
  1027. RasTapiTrace(" ");
  1028. return retcode;
  1029. }
  1030. //
  1031. // Initialize the port for approp. buffers
  1032. //
  1033. SetupComm (hIOPort->TPCB_CommHandle, 1514, 1514) ;
  1034. }
  1035. //
  1036. // Before we send IOCTL to asyncmac - sanitize the DCB in
  1037. // case some app left databits, stopbits, parity set to bad
  1038. // values.
  1039. //
  1040. if (!GetCommState(hIOPort->TPCB_CommHandle, &DCB))
  1041. {
  1042. RasTapiTrace ("PortConnect: GetCommState failed for %s",
  1043. hIOPort->TPCB_Name);
  1044. FreeMutex(RasTapiMutex);
  1045. RasTapiTrace(" ");
  1046. return(GetLastError());
  1047. }
  1048. DCB.ByteSize = 8 ;
  1049. DCB.StopBits = ONESTOPBIT ;
  1050. DCB.Parity = NOPARITY ;
  1051. if (!SetCommState(hIOPort->TPCB_CommHandle, &DCB))
  1052. {
  1053. DWORD retcode = GetLastError();
  1054. RasTapiTrace ("PortConnect: SetCommState failed "
  1055. "for %s.handle=0x%x. %d",
  1056. hIOPort->TPCB_Name,
  1057. hIOPort->TPCB_CommHandle,
  1058. retcode);
  1059. // FreeMutex(RasTapiMutex);
  1060. RasTapiTrace(" ");
  1061. // return(retcode);
  1062. // This is not a fatal error. Ignore the error.
  1063. retcode = ERROR_SUCCESS;
  1064. }
  1065. RasTapiTrace("PortConnect: dwRate=%d", linecall.dwRate );
  1066. AsyMacOpen.hNdisEndpoint = INVALID_HANDLE_VALUE ;
  1067. AsyMacOpen.LinkSpeed = linecall.dwRate ;
  1068. AsyMacOpen.FileHandle = hIOPort->TPCB_CommHandle ;
  1069. AsyMacOpen.QualOfConnect = (UINT)NdisWanErrorControl;
  1070. {
  1071. OVERLAPPED overlapped ;
  1072. memset (&overlapped, 0, sizeof(OVERLAPPED)) ;
  1073. if (!DeviceIoControl(g_hAsyMac,
  1074. IOCTL_ASYMAC_OPEN,
  1075. &AsyMacOpen,
  1076. sizeof(AsyMacOpen),
  1077. &AsyMacOpen,
  1078. sizeof(AsyMacOpen),
  1079. &dwBytesReturned,
  1080. &overlapped))
  1081. {
  1082. DWORD dwError = GetLastError();
  1083. RasTapiTrace("PortConnect: IOCTL_ASYMAC_OPEN "
  1084. "failed. %d", dwError );
  1085. // *** Exclusion END ****
  1086. FreeMutex (RasTapiMutex) ;
  1087. RasTapiTrace(" ");
  1088. return(dwError);
  1089. }
  1090. }
  1091. hIOPort->TPCB_Endpoint = AsyMacOpen.hNdisEndpoint;
  1092. *endpoint = (ULONG_PTR) AsyMacOpen.hNdisEndpoint;
  1093. }
  1094. else
  1095. {
  1096. DWORD retcode;
  1097. if ( retcode = lineGetID (hIOPort->TPCB_Line->TLI_LineHandle,
  1098. hIOPort->TPCB_AddressId,
  1099. hIOPort->TPCB_CallHandle,
  1100. LINECALLSELECT_CALL,
  1101. varstring,
  1102. "NDIS"))
  1103. {
  1104. RasTapiTrace ("PortConnect: %s. lineGetId Failed. 0x%x",
  1105. hIOPort->TPCB_Name,
  1106. retcode );
  1107. // **** Exclusion End ****
  1108. FreeMutex (RasTapiMutex) ;
  1109. RasTapiTrace(" ");
  1110. return ERROR_FROM_DEVICE ;
  1111. }
  1112. hIOPort->TPCB_Endpoint =
  1113. *((HANDLE UNALIGNED *) ((BYTE *)varstring+varstring->dwStringOffset)) ;
  1114. *endpoint = (ULONG_PTR) hIOPort->TPCB_Endpoint ;
  1115. if ( hIOPort->TPCB_Line->CharModeSupported
  1116. && hIOPort->TPCB_CharMode)
  1117. {
  1118. PRASTAPI_DEV_SPECIFIC SetPPP;
  1119. hIOPort->TPCB_CharMode = FALSE;
  1120. if ((SetPPP =
  1121. LocalAlloc(LPTR, sizeof(RASTAPI_DEV_SPECIFIC))) == NULL)
  1122. {
  1123. DWORD dwErr = GetLastError();
  1124. RasTapiTrace("PortConnect: Failed to allocate. %d, "
  1125. "port %s, State=%d",
  1126. dwErr,
  1127. hIOPort->TPCB_Name,
  1128. hIOPort->TPCB_State );
  1129. // **** Exclusion END ****
  1130. FreeMutex (RasTapiMutex) ;
  1131. return(dwErr);
  1132. }
  1133. SetPPP->Command = RASTAPI_DEV_PPP_MODE;
  1134. hIOPort->TPCB_ModeRequestDesc = SetPPP;
  1135. hIOPort->TPCB_ModeRequestId =
  1136. lineDevSpecific(hIOPort->TPCB_Line->TLI_LineHandle,
  1137. hIOPort->TPCB_AddressId,
  1138. hIOPort->TPCB_CallHandle,
  1139. SetPPP,
  1140. sizeof(RASTAPI_DEV_SPECIFIC));
  1141. if ( hIOPort->TPCB_ModeRequestId == 0
  1142. || hIOPort->TPCB_ModeRequestId > 0x80000000)
  1143. {
  1144. LocalFree(SetPPP);
  1145. hIOPort->TPCB_ModeRequestId = INFINITE;
  1146. hIOPort->TPCB_ModeRequestDesc = NULL;
  1147. }
  1148. }
  1149. }
  1150. // **** Exclusion END ****
  1151. FreeMutex (RasTapiMutex) ;
  1152. RasTapiTrace(" ");
  1153. return(SUCCESS);
  1154. }
  1155. /*++
  1156. Routine Description:
  1157. This API is called to drop a connection and close AsyncMac.
  1158. Arguments:
  1159. Return Value:
  1160. SUCCESS
  1161. PENDING
  1162. ERROR_PORT_NOT_OPEN
  1163. --*/
  1164. DWORD APIENTRY
  1165. PortDisconnect(HANDLE hPort)
  1166. {
  1167. DWORD retcode = SUCCESS ;
  1168. TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
  1169. if(NULL == hIOPort)
  1170. {
  1171. RasTapiTrace("PortDisconnect: hioport==NULL");
  1172. return E_INVALIDARG;
  1173. }
  1174. // **** Exclusion Begin ****
  1175. GetMutex (RasTapiMutex, INFINITE) ;
  1176. RasTapiTrace("PortDisconnect: %s", hIOPort->TPCB_Name );
  1177. if ( (hIOPort->TPCB_State == PS_CONNECTED)
  1178. || (hIOPort->TPCB_State == PS_CONNECTING)
  1179. || ( (hIOPort->TPCB_State == PS_LISTENING)
  1180. && (hIOPort->TPCB_ListenState != LS_WAIT)))
  1181. {
  1182. retcode = InitiatePortDisconnection (hIOPort) ;
  1183. //
  1184. // If we had saved away the device config then we
  1185. // restore it here.
  1186. //
  1187. if (hIOPort->TPCB_DefaultDevConfig)
  1188. {
  1189. lineSetDevConfig (hIOPort->TPCB_Line->TLI_LineId,
  1190. hIOPort->TPCB_DefaultDevConfig,
  1191. hIOPort->TPCB_DefaultDevConfigSize,
  1192. "comm/datamodem") ;
  1193. LocalFree (hIOPort->TPCB_DefaultDevConfig) ;
  1194. hIOPort->TPCB_DefaultDevConfig = NULL ;
  1195. }
  1196. }
  1197. else if (hIOPort->TPCB_State == PS_LISTENING)
  1198. {
  1199. RasTapiTrace ("PortDisconnect: Changing State"
  1200. " of %s from %d -> %d",
  1201. hIOPort->TPCB_Name,
  1202. hIOPort->TPCB_State,
  1203. PS_OPEN );
  1204. //
  1205. // for LS_WAIT listen state case
  1206. //
  1207. hIOPort->TPCB_State = PS_OPEN ;
  1208. retcode = SUCCESS ;
  1209. }
  1210. else if (hIOPort->TPCB_State == PS_DISCONNECTING)
  1211. {
  1212. retcode = PENDING ;
  1213. }
  1214. if (hIOPort->TPCB_Line->CharModeSupported)
  1215. {
  1216. hIOPort->TPCB_RecvFifo->In =
  1217. hIOPort->TPCB_RecvFifo->Out =
  1218. hIOPort->TPCB_RecvFifo->Count = 0;
  1219. }
  1220. // **** Exclusion END ****
  1221. FreeMutex (RasTapiMutex) ;
  1222. RasTapiTrace(" ");
  1223. return retcode ;
  1224. }
  1225. /*++
  1226. Routine Description:
  1227. This API re-initializes the com port after use.
  1228. Arguments:
  1229. Return Value:
  1230. SUCCESS
  1231. ERROR_PORT_NOT_CONFIGURED
  1232. ERROR_DEVICE_NOT_READY
  1233. --*/
  1234. DWORD APIENTRY
  1235. PortInit(HANDLE hIOPort)
  1236. {
  1237. return(SUCCESS);
  1238. }
  1239. /*++
  1240. Routine Description:
  1241. This API sends a buffer to the port. This API is
  1242. asynchronous and normally returns PENDING; however, if
  1243. WriteFile returns synchronously, the API will return
  1244. SUCCESS.
  1245. Arguments:
  1246. Return Value:
  1247. SUCCESS
  1248. PENDING
  1249. Return code from GetLastError
  1250. --*/
  1251. DWORD
  1252. PortSend(
  1253. HANDLE hPort, BYTE *pBuffer,
  1254. DWORD dwSize
  1255. )
  1256. {
  1257. TapiPortControlBlock *hIOPort =
  1258. (TapiPortControlBlock *) hPort;
  1259. DWORD retcode ;
  1260. DWORD pdwBytesWritten;
  1261. BOOL bIODone;
  1262. // **** Exclusion Begin ****
  1263. GetMutex (RasTapiMutex, INFINITE) ;
  1264. if (_stricmp (hIOPort->TPCB_DeviceType,
  1265. DEVICETYPE_UNIMODEM) == 0)
  1266. {
  1267. // DbgPrint("sending %c\n", (CHAR) *pBuffer);
  1268. // Send Buffer to Port
  1269. //
  1270. bIODone = WriteFile(
  1271. hIOPort->TPCB_CommHandle,
  1272. pBuffer,
  1273. dwSize,
  1274. &pdwBytesWritten,
  1275. (LPOVERLAPPED)&(hIOPort->TPCB_WriteOverlapped));
  1276. if (bIODone)
  1277. {
  1278. retcode = PENDING;
  1279. }
  1280. else if ((retcode = GetLastError()) == ERROR_IO_PENDING)
  1281. {
  1282. retcode = PENDING ;
  1283. }
  1284. }
  1285. else if (hIOPort->TPCB_Line->CharModeSupported)
  1286. {
  1287. PRASTAPI_DEV_SPECIFIC TapiSend;
  1288. DWORD TapiSendSize;
  1289. if (hIOPort->TPCB_State != PS_CONNECTED)
  1290. {
  1291. // **** Exclusion END ****
  1292. FreeMutex (RasTapiMutex) ;
  1293. return SUCCESS;
  1294. }
  1295. TapiSendSize = sizeof(RASTAPI_DEV_SPECIFIC) + dwSize;
  1296. if ((TapiSend = LocalAlloc(LPTR, TapiSendSize)) == NULL)
  1297. {
  1298. // **** Exclusion END ****
  1299. FreeMutex(RasTapiMutex);
  1300. return(GetLastError());
  1301. }
  1302. TapiSend->Command = RASTAPI_DEV_SEND;
  1303. TapiSend->DataSize = dwSize;
  1304. memcpy(TapiSend->Data, pBuffer, dwSize);
  1305. hIOPort->TPCB_SendDesc = TapiSend;
  1306. hIOPort->TPCB_CharMode = TRUE;
  1307. hIOPort->TPCB_SendRequestId =
  1308. lineDevSpecific(hIOPort->TPCB_Line->TLI_LineHandle,
  1309. hIOPort->TPCB_AddressId,
  1310. hIOPort->TPCB_CallHandle,
  1311. TapiSend,
  1312. TapiSendSize);
  1313. if (hIOPort->TPCB_SendRequestId == 0)
  1314. {
  1315. //
  1316. // Do I need to set the event?
  1317. //
  1318. LocalFree(TapiSend);
  1319. hIOPort->TPCB_SendDesc = NULL;
  1320. hIOPort->TPCB_SendRequestId = INFINITE;
  1321. retcode = SUCCESS;
  1322. }
  1323. else if (hIOPort->TPCB_SendRequestId > 0x80000000)
  1324. {
  1325. LocalFree(TapiSend);
  1326. hIOPort->TPCB_SendDesc = NULL;
  1327. hIOPort->TPCB_SendRequestId = INFINITE;
  1328. retcode = ERROR_FROM_DEVICE;
  1329. }
  1330. else
  1331. {
  1332. //
  1333. // The request has been pended. We need to free the
  1334. // buffer at completion time.
  1335. //
  1336. //
  1337. retcode = PENDING;
  1338. }
  1339. }
  1340. else
  1341. {
  1342. retcode = SUCCESS;
  1343. }
  1344. // **** Exclusion END ****
  1345. FreeMutex (RasTapiMutex) ;
  1346. return retcode ;
  1347. }
  1348. /*++
  1349. Routine Description:
  1350. This API reads from the port. This API is
  1351. asynchronous and normally returns PENDING; however, if
  1352. ReadFile returns synchronously, the API will return
  1353. SUCCESS.
  1354. Arguments:
  1355. Return Value:
  1356. SUCCESS
  1357. PENDING
  1358. Return code from GetLastError
  1359. --*/
  1360. DWORD
  1361. PortReceive(HANDLE hPort,
  1362. BYTE *pBuffer,
  1363. DWORD dwSize,
  1364. DWORD dwTimeOut)
  1365. {
  1366. TapiPortControlBlock *hIOPort
  1367. = (TapiPortControlBlock *) hPort;
  1368. COMMTIMEOUTS CT;
  1369. DWORD pdwBytesRead;
  1370. BOOL bIODone;
  1371. DWORD retcode ;
  1372. // **** Exclusion Begin ****
  1373. GetMutex (RasTapiMutex, INFINITE) ;
  1374. if (_stricmp (hIOPort->TPCB_DeviceType,
  1375. DEVICETYPE_UNIMODEM) == 0)
  1376. {
  1377. // Set Read Timeouts
  1378. CT.ReadIntervalTimeout = 0;
  1379. CT.ReadTotalTimeoutMultiplier = 0;
  1380. CT.ReadTotalTimeoutConstant = dwTimeOut;
  1381. if (!SetCommTimeouts(hIOPort->TPCB_CommHandle, &CT))
  1382. {
  1383. DWORD dwError = GetLastError();
  1384. RasTapiTrace("PorTReceive: SetCommTimeouts failed "
  1385. "for %s. %d", hIOPort->TPCB_Name,
  1386. dwError);
  1387. // **** Exclusion END ****
  1388. FreeMutex (RasTapiMutex) ;
  1389. RasTapiTrace(" ");
  1390. return(dwError);
  1391. }
  1392. //
  1393. // Read from Port
  1394. //
  1395. bIODone = ReadFile(hIOPort->TPCB_CommHandle,
  1396. pBuffer,
  1397. dwSize,
  1398. &pdwBytesRead,
  1399. (LPOVERLAPPED) &(hIOPort->TPCB_ReadOverlapped));
  1400. if (bIODone)
  1401. {
  1402. retcode = PENDING;
  1403. }
  1404. else if ((retcode = GetLastError()) == ERROR_IO_PENDING)
  1405. {
  1406. retcode = PENDING;
  1407. }
  1408. }
  1409. else if (hIOPort->TPCB_Line->CharModeSupported)
  1410. {
  1411. if (hIOPort->TPCB_State != PS_CONNECTED)
  1412. {
  1413. // **** Exclusion END ****
  1414. FreeMutex (RasTapiMutex) ;
  1415. return SUCCESS;
  1416. }
  1417. //
  1418. // What to do about timeouts?
  1419. //
  1420. hIOPort->TPCB_RasmanRecvBuffer = pBuffer;
  1421. hIOPort->TPCB_RasmanRecvBufferSize = dwSize;
  1422. //
  1423. // If we already have some data buffered
  1424. // go ahead and notify
  1425. //
  1426. if (hIOPort->TPCB_RecvFifo->Count > 0)
  1427. {
  1428. //
  1429. //SetEvent(hAsyncEvent);
  1430. //
  1431. PostNotificationCompletion( hIOPort );
  1432. }
  1433. else
  1434. {
  1435. }
  1436. retcode = PENDING;
  1437. }
  1438. else
  1439. {
  1440. retcode = SUCCESS ;
  1441. }
  1442. // **** Exclusion END ****
  1443. FreeMutex (RasTapiMutex) ;
  1444. return retcode ;
  1445. }
  1446. /*++
  1447. Routine Description:
  1448. Completes a read - if still PENDING it cancels it -
  1449. else it returns the bytes read. PortClearStatistics.
  1450. Arguments:
  1451. Return Value:
  1452. SUCCESS
  1453. --*/
  1454. DWORD
  1455. PortReceiveComplete (HANDLE hPort, PDWORD bytesread)
  1456. {
  1457. TapiPortControlBlock *hIOPort =
  1458. (TapiPortControlBlock *) hPort;
  1459. DWORD retcode = SUCCESS;
  1460. // **** Exclusion Begin ****
  1461. GetMutex (RasTapiMutex, INFINITE) ;
  1462. if (!GetOverlappedResult(
  1463. hIOPort->TPCB_CommHandle,
  1464. (LPOVERLAPPED)&(hIOPort->TPCB_ReadOverlapped),
  1465. bytesread,
  1466. FALSE))
  1467. {
  1468. retcode = GetLastError() ;
  1469. RasTapiTrace("PortReceiveComplete: GetOverlappedResult "
  1470. "Failed.%s, %d", hIOPort->TPCB_Name,
  1471. retcode );
  1472. PurgeComm (hIOPort->TPCB_CommHandle, PURGE_RXABORT) ;
  1473. *bytesread = 0 ;
  1474. }
  1475. else if (hIOPort->TPCB_Line->CharModeSupported)
  1476. {
  1477. *bytesread =
  1478. CopyDataFromFifo(hIOPort->TPCB_RecvFifo,
  1479. hIOPort->TPCB_RasmanRecvBuffer,
  1480. hIOPort->TPCB_RasmanRecvBufferSize);
  1481. hIOPort->TPCB_RasmanRecvBuffer = NULL;
  1482. hIOPort->TPCB_RasmanRecvBufferSize = 0;
  1483. }
  1484. else
  1485. {
  1486. retcode = SUCCESS ;
  1487. }
  1488. // **** Exclusion END ****
  1489. FreeMutex (RasTapiMutex) ;
  1490. return retcode ;
  1491. }
  1492. /*++
  1493. Routine Description:
  1494. This API selects Asyncmac compression mode
  1495. by setting Asyncmac's compression bits.
  1496. Arguments:
  1497. Return Value:
  1498. SUCCESS
  1499. Return code from GetLastError
  1500. --*/
  1501. DWORD
  1502. PortCompressionSetInfo(HANDLE hIOPort)
  1503. {
  1504. return SUCCESS;
  1505. }
  1506. /*++
  1507. Routine Description:
  1508. This API is used to mark the beginning of the
  1509. period for which statistics will be reported.
  1510. The current numbers are copied from the MAC and
  1511. stored in the Serial Port Control Block. At
  1512. the end of the period PortGetStatistics will be
  1513. called to compute the difference.
  1514. Arguments:
  1515. Return Value:
  1516. SUCCESS
  1517. ERROR_PORT_NOT_OPEN
  1518. --*/
  1519. DWORD
  1520. PortClearStatistics(HANDLE hIOPort)
  1521. {
  1522. return SUCCESS;
  1523. }
  1524. /*++
  1525. Routine Description:
  1526. This API reports MAC statistics since the last call to
  1527. PortClearStatistics.
  1528. Arguments:
  1529. Return Value:
  1530. SUCCESS
  1531. ERROR_PORT_NOT_OPEN
  1532. --*/
  1533. DWORD
  1534. PortGetStatistics(
  1535. HANDLE hIOPort,
  1536. RAS_STATISTICS *pStat
  1537. )
  1538. {
  1539. return(SUCCESS);
  1540. }
  1541. /*++
  1542. Routine Description:
  1543. Sets the framing type with the mac
  1544. Arguments:
  1545. Return Value:
  1546. SUCCESS
  1547. --*/
  1548. DWORD APIENTRY
  1549. PortSetFraming(
  1550. HANDLE hIOPort,
  1551. DWORD SendFeatureBits,
  1552. DWORD RecvFeatureBits,
  1553. DWORD SendBitMask,
  1554. DWORD RecvBitMask
  1555. )
  1556. {
  1557. return(SUCCESS);
  1558. }
  1559. /*++
  1560. Routine Description:
  1561. This API is used in MS-DOS only.
  1562. Arguments:
  1563. Return Value:
  1564. SUCCESS
  1565. --*/
  1566. DWORD APIENTRY
  1567. PortGetPortState(char *pszPortName, DWORD *pdwUsage)
  1568. {
  1569. return(SUCCESS);
  1570. }
  1571. /*++
  1572. Routine Description:
  1573. This API is used in MS-DOS only.
  1574. Arguments:
  1575. Return Value:
  1576. SUCCESS
  1577. --*/
  1578. DWORD APIENTRY
  1579. PortChangeCallback(HANDLE hIOPort)
  1580. {
  1581. return(SUCCESS);
  1582. }
  1583. /*++
  1584. Routine Description:
  1585. For the given hIOPort this returns the file
  1586. handle for the connection
  1587. Arguments:
  1588. Return Value:
  1589. SUCCESS
  1590. --*/
  1591. DWORD APIENTRY
  1592. PortGetIOHandle(HANDLE hPort, HANDLE *FileHandle)
  1593. {
  1594. DWORD retcode ;
  1595. TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
  1596. // **** Exclusion Begin ****
  1597. GetMutex (RasTapiMutex, INFINITE) ;
  1598. if (hIOPort->TPCB_State == PS_CONNECTED)
  1599. {
  1600. //
  1601. // purge the comm since it may still have
  1602. // characters from modem responses
  1603. //
  1604. RasTapiTrace("PortGetIOHandle: Purging Comm %s",
  1605. hIOPort->TPCB_Name );
  1606. Sleep ( 10 );
  1607. PurgeComm (hIOPort->TPCB_CommHandle,
  1608. PURGE_RXABORT
  1609. | PURGE_TXCLEAR
  1610. | PURGE_RXCLEAR );
  1611. *FileHandle = hIOPort->TPCB_CommHandle ;
  1612. retcode = SUCCESS ;
  1613. }
  1614. else
  1615. {
  1616. RasTapiTrace("PortGetIOHandle: %s. port not "
  1617. "open. State = %d",
  1618. hIOPort->TPCB_Name,
  1619. hIOPort->TPCB_Name);
  1620. retcode = ERROR_PORT_NOT_OPEN ;
  1621. }
  1622. // **** Exclusion Begin ****
  1623. FreeMutex (RasTapiMutex) ;
  1624. return retcode ;
  1625. }
  1626. /*++
  1627. Routine Description:
  1628. Enumerates all devices in the device INF file for the
  1629. specified DevictType.
  1630. Arguments:
  1631. Return Value:
  1632. Return codes from RasDevEnumDevices
  1633. --*/
  1634. DWORD APIENTRY
  1635. DeviceEnum (char *pszDeviceType,
  1636. DWORD *pcEntries,
  1637. BYTE *pBuffer,
  1638. DWORD *pdwSize)
  1639. {
  1640. *pdwSize = 0 ;
  1641. *pcEntries = 0 ;
  1642. return(SUCCESS);
  1643. }
  1644. /*++
  1645. Routine Description:
  1646. Returns a summary of current information from
  1647. the InfoTable for the device on the port in Pcb.
  1648. Arguments:
  1649. Return Value:
  1650. Return codes from GetDeviceCB, BuildOutputTable
  1651. --*/
  1652. DWORD APIENTRY
  1653. DeviceGetInfo(HANDLE hPort,
  1654. char *pszDeviceType,
  1655. char *pszDeviceName,
  1656. BYTE *pInfo,
  1657. DWORD *pdwSize)
  1658. {
  1659. DWORD retcode ;
  1660. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  1661. if (!hIOPort)
  1662. {
  1663. RasTapiTrace("DeviceGetInfo: Port Not "
  1664. "found. hPort = 0x%x ",
  1665. hPort );
  1666. return ERROR_PORT_NOT_FOUND ;
  1667. }
  1668. // **** Exclusion Begin ****
  1669. GetMutex (RasTapiMutex, INFINITE) ;
  1670. retcode = GetInfo (hIOPort, pInfo, pdwSize) ;
  1671. // **** Exclusion End ****
  1672. FreeMutex (RasTapiMutex) ;
  1673. return(retcode);
  1674. }
  1675. /*++
  1676. Routine Description:
  1677. Sets attributes in the InfoTable for the device on the
  1678. port in Pcb.
  1679. Arguments:
  1680. Return Value:
  1681. Return codes from GetDeviceCB, UpdateInfoTable
  1682. --*/
  1683. DWORD APIENTRY
  1684. DeviceSetInfo(HANDLE hPort,
  1685. char *pszDeviceType,
  1686. char *pszDeviceName,
  1687. RASMAN_DEVICEINFO *pInfo)
  1688. {
  1689. DWORD retcode ;
  1690. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  1691. if (!hIOPort)
  1692. {
  1693. RasTapiTrace ("DeviceSetInfo: Port not "
  1694. "found. hPort = 0x%x",
  1695. hPort );
  1696. RasTapiTrace(" ");
  1697. return ERROR_PORT_NOT_FOUND ;
  1698. }
  1699. // **** Exclusion Begin ****
  1700. GetMutex (RasTapiMutex, INFINITE) ;
  1701. retcode = SetInfo (hIOPort, (RASMAN_PORTINFO*) pInfo) ;
  1702. // **** Exclusion End ****
  1703. FreeMutex (RasTapiMutex) ;
  1704. return (retcode);
  1705. }
  1706. /*++
  1707. Routine Description:
  1708. Initiates the process of connecting a device.
  1709. Arguments:
  1710. Return Value:
  1711. Return codes from ConnectListen
  1712. --*/
  1713. DWORD APIENTRY
  1714. DeviceConnect(HANDLE hPort,
  1715. char *pszDeviceType,
  1716. char *pszDeviceName)
  1717. {
  1718. LINECALLPARAMS *linecallparams ;
  1719. LPVARSTRING var ;
  1720. BYTE buffer [2000] ;
  1721. BYTE *nextstring ;
  1722. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  1723. if (!hIOPort)
  1724. {
  1725. RasTapiTrace ("DeviceConnect: %s not found",
  1726. ( pszDeviceName
  1727. ? pszDeviceName
  1728. : "NULL"));
  1729. return ERROR_PORT_NOT_FOUND ;
  1730. }
  1731. // **** Exclusion Begin ****
  1732. GetMutex (RasTapiMutex, INFINITE) ;
  1733. //
  1734. // Check to see if the port is in disconnecting state
  1735. //
  1736. if ( hIOPort->TPCB_State != PS_OPEN )
  1737. {
  1738. #if DBG
  1739. DbgPrint("RASTAPI: port is not "
  1740. "in PS_OPEN state. State = %d \n",
  1741. hIOPort->TPCB_State );
  1742. #endif
  1743. RasTapiTrace ("DeviceConnect: Device %s is not"
  1744. " in PS_OPEN state state = %d",
  1745. (pszDeviceName)
  1746. ? pszDeviceName
  1747. : "NULL",
  1748. hIOPort->TPCB_State );
  1749. FreeMutex ( RasTapiMutex );
  1750. return ERROR_PORT_NOT_AVAILABLE;
  1751. }
  1752. //
  1753. // if dev config has been set for this device we
  1754. // should call down and set it.
  1755. //
  1756. if ( (hIOPort->TPCB_DevConfig)
  1757. && (_stricmp (hIOPort->TPCB_DeviceType,
  1758. DEVICETYPE_UNIMODEM) == 0))
  1759. {
  1760. RAS_DEVCONFIG *pDevConfig;
  1761. //
  1762. // Before the write this - save away the current
  1763. // setting for the device.
  1764. //
  1765. var = (LPVARSTRING)buffer ;
  1766. var->dwTotalSize = 2000 ;
  1767. var->dwStringSize = 0 ;
  1768. lineGetDevConfig (hIOPort->TPCB_Line->TLI_LineId,
  1769. var,
  1770. "comm/datamodem") ;
  1771. if(NULL != hIOPort->TPCB_DefaultDevConfig)
  1772. {
  1773. LocalFree(hIOPort->TPCB_DefaultDevConfig);
  1774. hIOPort->TPCB_DefaultDevConfig = NULL;
  1775. }
  1776. //
  1777. // Alloc mem for the returned info. If memory allocation
  1778. // fails, its not really fatal - we will just fail to
  1779. // save the dev config - we will try allocating again
  1780. // when this api is called next.
  1781. //
  1782. hIOPort->TPCB_DefaultDevConfigSize = 0;
  1783. hIOPort->TPCB_DefaultDevConfig =
  1784. LocalAlloc (LPTR, var->dwStringSize) ;
  1785. if(NULL != hIOPort->TPCB_DefaultDevConfig)
  1786. {
  1787. hIOPort->TPCB_DefaultDevConfigSize = var->dwStringSize ;
  1788. memcpy (hIOPort->TPCB_DefaultDevConfig,
  1789. (CHAR*)var+var->dwStringOffset,
  1790. var->dwStringSize) ;
  1791. }
  1792. pDevConfig = (RAS_DEVCONFIG *) hIOPort->TPCB_DevConfig;
  1793. lineSetDevConfig (hIOPort->TPCB_Line->TLI_LineId,
  1794. (PBYTE) ((PBYTE) pDevConfig +
  1795. pDevConfig->dwOffsetofModemSettings),
  1796. pDevConfig->dwSizeofModemSettings,
  1797. "comm/datamodem") ;
  1798. }
  1799. memset (buffer, 0, sizeof(buffer)) ;
  1800. linecallparams = (LINECALLPARAMS *) buffer ;
  1801. nextstring = (buffer + sizeof (LINECALLPARAMS)) ;
  1802. linecallparams->dwTotalSize = sizeof(buffer) ;
  1803. strcpy (nextstring, hIOPort->TPCB_Address) ;
  1804. linecallparams->dwOrigAddressSize = strlen (nextstring) ;
  1805. linecallparams->dwOrigAddressOffset = (DWORD)(nextstring - buffer) ;
  1806. linecallparams->dwAddressMode = LINEADDRESSMODE_DIALABLEADDR ;
  1807. nextstring += linecallparams->dwOrigAddressSize ;
  1808. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_ISDN) == 0)
  1809. {
  1810. SetIsdnParams (hIOPort, linecallparams) ;
  1811. }
  1812. else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_X25) == 0)
  1813. {
  1814. if (*hIOPort->TPCB_Info[X25_USERDATA_INDEX] != '\0')
  1815. {
  1816. strcpy (nextstring,
  1817. hIOPort->TPCB_Info[X25_USERDATA_INDEX]) ;
  1818. linecallparams->dwUserUserInfoSize =
  1819. strlen (nextstring) ;
  1820. linecallparams->dwUserUserInfoOffset =
  1821. (DWORD)(nextstring - buffer) ;
  1822. nextstring += linecallparams->dwUserUserInfoSize ;
  1823. }
  1824. if (*hIOPort->TPCB_Info[X25_FACILITIES_INDEX] != '\0')
  1825. {
  1826. strcpy (nextstring, hIOPort->TPCB_Info[X25_FACILITIES_INDEX]) ;
  1827. linecallparams->dwDevSpecificSize =
  1828. strlen (nextstring) ;
  1829. linecallparams->dwDevSpecificOffset =
  1830. (DWORD)(nextstring - buffer) ;
  1831. nextstring += linecallparams->dwDevSpecificSize ;
  1832. }
  1833. //
  1834. // Diagnostic key is ignored.
  1835. //
  1836. SetX25Params(hIOPort, linecallparams);
  1837. }
  1838. else if (_stricmp (hIOPort->TPCB_DeviceType,
  1839. DEVICETYPE_UNIMODEM) == 0)
  1840. {
  1841. SetModemParams (hIOPort, linecallparams) ;
  1842. } else if (_stricmp(hIOPort->TPCB_DeviceType,
  1843. DEVICETYPE_ATM) == 0)
  1844. {
  1845. SetAtmParams (hIOPort, linecallparams) ;
  1846. } else
  1847. {
  1848. SetGenericParams(hIOPort, linecallparams);
  1849. }
  1850. //
  1851. // mark request id as unused
  1852. //
  1853. hIOPort->TPCB_RequestId = INFINITE ;
  1854. //
  1855. // set call handle to bogus value
  1856. //
  1857. hIOPort->TPCB_CallHandle = (HCALL) INFINITE ;
  1858. hIOPort->TPCB_AsyncErrorCode = SUCCESS ;
  1859. RasTapiTrace ("DeviceConnect: calling lineMakeCall"
  1860. " for %s, address=%s",
  1861. hIOPort->TPCB_Name,
  1862. hIOPort->TPCB_Info[ADDRESS_INDEX] );
  1863. if ((hIOPort->TPCB_RequestId =
  1864. lineMakeCall (hIOPort->TPCB_Line->TLI_LineHandle,
  1865. &hIOPort->TPCB_CallHandle,
  1866. hIOPort->TPCB_Info[ADDRESS_INDEX],
  1867. 0,
  1868. linecallparams)) > 0x80000000 )
  1869. {
  1870. RasTapiTrace ("DeviceConnect: lineMakeCall"
  1871. " Failed for %s. 0x%x",
  1872. hIOPort->TPCB_Name,
  1873. hIOPort->TPCB_RequestId );
  1874. // **** Exclusion End ****
  1875. FreeMutex (RasTapiMutex) ;
  1876. if (hIOPort->TPCB_RequestId == LINEERR_INUSE)
  1877. {
  1878. RasTapiTrace("DeviceConnect: ERROR_PORT_NOT_AVAILABLE");
  1879. RasTapiTrace(" ");
  1880. return ERROR_PORT_NOT_AVAILABLE ;
  1881. }
  1882. RasTapiTrace("DeviceConnect: ERROR_FROM_DEVICE");
  1883. RasTapiTrace(" ");
  1884. return ERROR_FROM_DEVICE ;
  1885. }
  1886. RasTapiTrace ("DeviceConnect: Changing state for %s"
  1887. " from %d -> %d",
  1888. hIOPort->TPCB_Name,
  1889. hIOPort->TPCB_State,
  1890. PS_CONNECTING );
  1891. hIOPort->TPCB_State = PS_CONNECTING ;
  1892. hIOPort->TPCB_DisconnectReason = 0 ;
  1893. // **** Exclusion End ****
  1894. FreeMutex (RasTapiMutex) ;
  1895. return (PENDING);
  1896. }
  1897. VOID
  1898. SetIsdnParams (
  1899. TapiPortControlBlock *hIOPort,
  1900. LINECALLPARAMS *linecallparams
  1901. )
  1902. {
  1903. WORD numchannels ;
  1904. WORD fallback ;
  1905. //
  1906. // Line type
  1907. //
  1908. if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX],
  1909. ISDN_LINETYPE_STRING_64DATA) == 0)
  1910. {
  1911. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  1912. linecallparams->dwMinRate = 64000 ;
  1913. linecallparams->dwMaxRate = 64000 ;
  1914. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
  1915. }
  1916. else if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX],
  1917. ISDN_LINETYPE_STRING_56DATA) == 0)
  1918. {
  1919. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  1920. linecallparams->dwMinRate = 56000 ;
  1921. linecallparams->dwMaxRate = 56000 ;
  1922. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
  1923. }
  1924. else if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX],
  1925. ISDN_LINETYPE_STRING_56VOICE) == 0)
  1926. {
  1927. linecallparams->dwBearerMode = LINEBEARERMODE_VOICE ;
  1928. linecallparams->dwMinRate = 56000 ;
  1929. linecallparams->dwMaxRate = 56000 ;
  1930. linecallparams->dwMediaMode = LINEMEDIAMODE_UNKNOWN ;
  1931. }
  1932. else
  1933. { // default
  1934. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  1935. linecallparams->dwMinRate = 64000 ;
  1936. linecallparams->dwMaxRate = 64000 ;
  1937. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
  1938. }
  1939. if (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX][0] != '\0')
  1940. {
  1941. numchannels = (USHORT)atoi(hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]) ;
  1942. }
  1943. else
  1944. {
  1945. numchannels = 1 ; // default
  1946. }
  1947. if (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX] != '\0')
  1948. {
  1949. fallback = (USHORT)atoi(hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]) ;
  1950. }
  1951. else
  1952. {
  1953. fallback = 1 ; // default
  1954. }
  1955. if (fallback)
  1956. {
  1957. //
  1958. // always allow the min
  1959. //
  1960. linecallparams->dwMinRate = 56000 ;
  1961. }
  1962. else
  1963. {
  1964. linecallparams->dwMinRate =
  1965. numchannels * linecallparams->dwMaxRate ;
  1966. }
  1967. linecallparams->dwMaxRate =
  1968. numchannels * linecallparams->dwMaxRate ;
  1969. }
  1970. VOID
  1971. SetModemParams(
  1972. TapiPortControlBlock *hIOPort,
  1973. LINECALLPARAMS *linecallparams
  1974. )
  1975. {
  1976. WORD numchannels ;
  1977. WORD fallback ;
  1978. BYTE buffer[800] ;
  1979. LINEDEVCAPS *linedevcaps ;
  1980. memset (buffer, 0, sizeof(buffer)) ;
  1981. linedevcaps = (LINEDEVCAPS *)buffer ;
  1982. linedevcaps->dwTotalSize = sizeof(buffer) ;
  1983. //
  1984. // Get a count of all addresses across all lines
  1985. //
  1986. if (lineGetDevCaps (RasLine,
  1987. hIOPort->TPCB_Line->TLI_LineId,
  1988. hIOPort->TPCB_Line->NegotiatedApiVersion,
  1989. hIOPort->TPCB_Line->NegotiatedExtVersion,
  1990. linedevcaps))
  1991. {
  1992. linecallparams->dwBearerMode = LINEBEARERMODE_VOICE;
  1993. }
  1994. if (linedevcaps->dwBearerModes & LINEBEARERMODE_VOICE)
  1995. {
  1996. linecallparams->dwBearerMode = LINEBEARERMODE_VOICE ;
  1997. }
  1998. else
  1999. {
  2000. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  2001. }
  2002. //
  2003. // do not dial without dialtone
  2004. //
  2005. linecallparams->dwCallParamFlags |= LINECALLPARAMFLAGS_IDLE ;
  2006. linecallparams->dwMinRate = 2400 ;
  2007. linecallparams->dwMaxRate = 115200 ;
  2008. linecallparams->dwMediaMode = LINEMEDIAMODE_DATAMODEM ;
  2009. }
  2010. VOID
  2011. SetAtmParams (
  2012. TapiPortControlBlock *hIOPort,
  2013. LINECALLPARAMS *linecallparams
  2014. )
  2015. {
  2016. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  2017. //
  2018. // Tell ATM to use the default rates of the underlying
  2019. // miniport adapter.
  2020. //
  2021. linecallparams->dwMinRate = 0;
  2022. linecallparams->dwMaxRate = 0;
  2023. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
  2024. }
  2025. VOID
  2026. SetGenericParams (
  2027. TapiPortControlBlock *hIOPort,
  2028. LINECALLPARAMS *linecallparams
  2029. )
  2030. {
  2031. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  2032. linecallparams->dwMinRate = 64000;
  2033. linecallparams->dwMaxRate = 10000000;
  2034. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
  2035. }
  2036. VOID
  2037. SetX25Params(TapiPortControlBlock *hIOPort,
  2038. LINECALLPARAMS *linecallparams)
  2039. {
  2040. BYTE buffer[800] ;
  2041. LINEDEVCAPS *linedevcaps ;
  2042. memset (buffer, 0, sizeof(buffer)) ;
  2043. linedevcaps = (LINEDEVCAPS *)buffer ;
  2044. linedevcaps->dwTotalSize = sizeof(buffer) ;
  2045. //
  2046. // Get a count of all addresses across all lines
  2047. //
  2048. if (lineGetDevCaps (RasLine,
  2049. hIOPort->TPCB_Line->TLI_LineId,
  2050. hIOPort->TPCB_Line->NegotiatedApiVersion,
  2051. hIOPort->TPCB_Line->NegotiatedExtVersion,
  2052. linedevcaps))
  2053. {
  2054. //
  2055. // go for the gold!!!
  2056. //
  2057. linecallparams->dwMaxRate = 0xFFFFFFFF;
  2058. linecallparams->dwMediaMode = LINEMEDIAMODE_UNKNOWN;
  2059. } else
  2060. {
  2061. linecallparams->dwMaxRate = linedevcaps->dwMaxRate;
  2062. if (linedevcaps->dwMediaModes & LINEMEDIAMODE_DIGITALDATA)
  2063. {
  2064. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA;
  2065. }
  2066. else if (linedevcaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM)
  2067. {
  2068. linecallparams->dwMediaMode = LINEMEDIAMODE_DATAMODEM;
  2069. }
  2070. else
  2071. {
  2072. linecallparams->dwMediaMode = LINEMEDIAMODE_UNKNOWN;
  2073. }
  2074. }
  2075. }
  2076. /*++
  2077. Routine Description:
  2078. Initiates the process of listening for a remote device
  2079. to connect to a local device.
  2080. Arguments:
  2081. Return Value:
  2082. Return codes from ConnectListen
  2083. --*/
  2084. DWORD APIENTRY
  2085. DeviceListen(HANDLE hPort,
  2086. char *pszDeviceType,
  2087. char *pszDeviceName)
  2088. {
  2089. DWORD retcode ;
  2090. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  2091. if (!hIOPort)
  2092. {
  2093. RasTapiTrace ("DeviceListen: hPort "
  2094. "= 0x%x not found",
  2095. hPort );
  2096. return ERROR_PORT_NOT_FOUND ;
  2097. }
  2098. // **** Exclusion Begin ****
  2099. GetMutex (RasTapiMutex, INFINITE) ;
  2100. RasTapiTrace("DeviceListen: %s. State = %d",
  2101. hIOPort->TPCB_Name,
  2102. hIOPort->TPCB_State );
  2103. //
  2104. // If the state is DISCONNECTING (this could happen
  2105. // since rasman waits only 10 seconds for the lower
  2106. // layers to complete a disconnect request), then
  2107. // we have no option but to close and open the line.
  2108. //
  2109. if (hIOPort->TPCB_State == PS_DISCONNECTING &&
  2110. !hIOPort->TPCB_Line->TLI_MultiEndpoint)
  2111. {
  2112. RasTapiTrace ("DeviceListen: Hammering LineClosed!");
  2113. lineClose (hIOPort->TPCB_Line->TLI_LineHandle) ;
  2114. Sleep (30L) ;
  2115. retcode = lineOpen (RasLine,
  2116. hIOPort->TPCB_Line->TLI_LineId,
  2117. &hIOPort->TPCB_Line->TLI_LineHandle,
  2118. hIOPort->TPCB_Line->NegotiatedApiVersion,
  2119. hIOPort->TPCB_Line->NegotiatedExtVersion,
  2120. (DWORD_PTR) hIOPort->TPCB_Line,
  2121. LINECALLPRIVILEGE_OWNER,
  2122. hIOPort->TPCB_Line->TLI_MediaMode,
  2123. NULL) ;
  2124. if (retcode)
  2125. {
  2126. RasTapiTrace ("DeviceListen: %s. lineOpen"
  2127. " failed. 0x%x",
  2128. hIOPort->TPCB_Name,
  2129. retcode );
  2130. // **** Exclusion End ****
  2131. FreeMutex (RasTapiMutex) ;
  2132. RasTapiTrace(" ");
  2133. return ERROR_FROM_DEVICE ;
  2134. }
  2135. //
  2136. // Set monitoring of rings
  2137. //
  2138. retcode = lineSetStatusMessages(
  2139. hIOPort->TPCB_Line->TLI_LineHandle,
  2140. LINEDEVSTATE_RINGING, 0) ;
  2141. if (retcode)
  2142. {
  2143. RasTapiTrace("DeviceListen: %s. Failed"
  2144. " to post listen. %d",
  2145. hIOPort->TPCB_Name,
  2146. retcode );
  2147. }
  2148. }
  2149. if (hIOPort->TPCB_Line->TLI_LineState != PS_LISTENING)
  2150. {
  2151. hIOPort->TPCB_Line->TLI_LineState = PS_LISTENING ;
  2152. }
  2153. RasTapiTrace ("DeviceListen: Changing State"
  2154. " for %s from %d -> %d",
  2155. hIOPort->TPCB_Name,
  2156. hIOPort->TPCB_State,
  2157. PS_LISTENING );
  2158. hIOPort->TPCB_State = PS_LISTENING ;
  2159. RasTapiTrace ("DeviceListen: Changing Listen"
  2160. " State for %s from %d -> %d",
  2161. hIOPort->TPCB_Name,
  2162. hIOPort->TPCB_ListenState,
  2163. PS_LISTENING );
  2164. hIOPort->TPCB_ListenState = LS_WAIT ;
  2165. hIOPort->TPCB_DisconnectReason = 0 ;
  2166. hIOPort->TPCB_CallHandle = -1 ;
  2167. // **** Exclusion End ****
  2168. FreeMutex (RasTapiMutex) ;
  2169. RasTapiTrace(" ");
  2170. return (PENDING);
  2171. }
  2172. /*++
  2173. Routine Description:
  2174. Informs the device dll that the attempt to connect or listen
  2175. has completed.
  2176. Arguments:
  2177. Return Value:
  2178. nothing
  2179. --*/
  2180. VOID APIENTRY
  2181. DeviceDone(HANDLE hPort)
  2182. {
  2183. #ifdef notdef
  2184. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  2185. if (!hIOPort)
  2186. return ;
  2187. // **** Exclusion Begin ****
  2188. GetMutex (RasTapiMutex, INFINITE) ;
  2189. // **** Exclusion End ****
  2190. FreeMutex (RasTapiMutex) ;
  2191. #endif
  2192. }
  2193. /*++
  2194. Routine Description:
  2195. This function is called following DeviceConnect or
  2196. DeviceListen to further the asynchronous process of
  2197. connecting or listening.
  2198. Arguments:
  2199. Return Value:
  2200. ERROR_DCB_NOT_FOUND
  2201. ERROR_STATE_MACHINES_NOT_STARTED
  2202. Return codes from DeviceStateMachine
  2203. --*/
  2204. DWORD APIENTRY
  2205. DeviceWork(HANDLE hPort)
  2206. {
  2207. LINECALLSTATUS *callstatus ;
  2208. BYTE buffer [1000] ;
  2209. DWORD retcode = ERROR_FROM_DEVICE ;
  2210. TapiPortControlBlock *hIOPort =
  2211. LookUpControlBlock(hPort);
  2212. if (!hIOPort)
  2213. {
  2214. RasTapiTrace("DeviceWork: port 0x%x not found",
  2215. hPort );
  2216. return ERROR_PORT_NOT_FOUND ;
  2217. }
  2218. // **** Exclusion Begin ****
  2219. GetMutex (RasTapiMutex, INFINITE) ;
  2220. memset (buffer, 0, sizeof(buffer)) ;
  2221. callstatus = (LINECALLSTATUS *)buffer ;
  2222. callstatus->dwTotalSize = sizeof(buffer) ;
  2223. RasTapiTrace ("DeviceWork: %s. State = %d",
  2224. hIOPort->TPCB_Name,
  2225. hIOPort->TPCB_State );
  2226. if (hIOPort->TPCB_State == PS_CONNECTING)
  2227. {
  2228. if (hIOPort->TPCB_AsyncErrorCode != SUCCESS)
  2229. {
  2230. retcode = hIOPort->TPCB_AsyncErrorCode ;
  2231. hIOPort->TPCB_AsyncErrorCode = SUCCESS ;
  2232. }
  2233. else if (lineGetCallStatus (hIOPort->TPCB_CallHandle,
  2234. callstatus))
  2235. {
  2236. RasTapiTrace( "DeviceWork: lineGetCallStatus failed");
  2237. retcode = ERROR_FROM_DEVICE ;
  2238. }
  2239. else if (callstatus->dwCallState ==
  2240. LINECALLSTATE_CONNECTED)
  2241. {
  2242. RasTapiTrace("DeviceWork: Changing state"
  2243. " for %s from %d -> %d",
  2244. hIOPort->TPCB_Name,
  2245. hIOPort->TPCB_State,
  2246. PS_CONNECTED );
  2247. hIOPort->TPCB_State = PS_CONNECTED ;
  2248. retcode = SUCCESS ;
  2249. }
  2250. else if (callstatus->dwCallState ==
  2251. LINECALLSTATE_DISCONNECTED)
  2252. {
  2253. retcode = ERROR_FROM_DEVICE ;
  2254. /*
  2255. if (callstatus->dwCallStateMode ==
  2256. LINEDISCONNECTMODE_BUSY)
  2257. {
  2258. retcode = ERROR_LINE_BUSY ;
  2259. }
  2260. else if ( (callstatus->dwCallStateMode ==
  2261. LINEDISCONNECTMODE_NOANSWER)
  2262. || (callstatus->dwCallStateMode ==
  2263. LINEDISCONNECTMODE_OUTOFORDER))
  2264. {
  2265. retcode = ERROR_NO_ANSWER ;
  2266. }
  2267. else if (callstatus->dwCallStateMode ==
  2268. LINEDISCONNECTMODE_CANCELLED)
  2269. {
  2270. retcode = ERROR_USER_DISCONNECTION;
  2271. }
  2272. */
  2273. retcode = DwRasErrorFromDisconnectMode(
  2274. callstatus->dwCallStateMode);
  2275. RasTapiTrace("DeviceWork: callstate = 0x%x. "
  2276. "callmode = 0x%x, retcode %d",
  2277. callstatus->dwCallState,
  2278. callstatus->dwCallStateMode,
  2279. retcode );
  2280. }
  2281. else if ( (callstatus->dwCallState ==
  2282. LINECALLSTATE_SPECIALINFO)
  2283. && (callstatus->dwCallStateMode ==
  2284. LINESPECIALINFO_NOCIRCUIT))
  2285. {
  2286. RasTapiTrace ("DeviceWork: ERROR_NO_ACTIVE_ISDN_LINES" );
  2287. retcode = ERROR_NO_ACTIVE_ISDN_LINES ;
  2288. }
  2289. }
  2290. if (hIOPort->TPCB_State == PS_LISTENING)
  2291. {
  2292. if (hIOPort->TPCB_ListenState == LS_ERROR)
  2293. {
  2294. RasTapiTrace ("DeviceWork: %s. ListenState = LS_ERROR",
  2295. hIOPort->TPCB_Name );
  2296. retcode = ERROR_FROM_DEVICE ;
  2297. }
  2298. else if (hIOPort->TPCB_ListenState == LS_ACCEPT)
  2299. {
  2300. hIOPort->TPCB_RequestId =
  2301. lineAccept (hIOPort->TPCB_CallHandle, NULL, 0) ;
  2302. RasTapiTrace( "DeviceWork: %s. lineAccept returned 0x%x",
  2303. hIOPort->TPCB_Name, hIOPort->TPCB_RequestId );
  2304. if (hIOPort->TPCB_RequestId > 0x80000000)
  2305. {
  2306. RasTapiTrace("DeviceWork: changing Listen"
  2307. " state for %s from %d -> %d",
  2308. hIOPort->TPCB_Name,
  2309. hIOPort->TPCB_ListenState,
  2310. LS_ANSWER );
  2311. hIOPort->TPCB_ListenState = LS_ANSWER ;
  2312. }
  2313. else if (hIOPort->TPCB_RequestId == 0)
  2314. {
  2315. RasTapiTrace("DeviceWork: changing Listen "
  2316. "state for %s from %d -> %d",
  2317. hIOPort->TPCB_Name,
  2318. hIOPort->TPCB_ListenState,
  2319. LS_ANSWER);
  2320. hIOPort->TPCB_ListenState = LS_ANSWER ;
  2321. }
  2322. retcode = PENDING ;
  2323. }
  2324. if (hIOPort->TPCB_ListenState == LS_ANSWER)
  2325. {
  2326. hIOPort->TPCB_RequestId =
  2327. lineAnswer (hIOPort->TPCB_CallHandle, NULL, 0) ;
  2328. RasTapiTrace("DeviceWork: %s. lineAnswer returned 0x%x",
  2329. hIOPort->TPCB_Name,
  2330. hIOPort->TPCB_RequestId );
  2331. if (hIOPort->TPCB_RequestId > 0x80000000 )
  2332. {
  2333. RasTapiTrace("DeviceWork: lineAnswer returned "
  2334. "an error");
  2335. retcode = ERROR_FROM_DEVICE ;
  2336. }
  2337. else if (hIOPort->TPCB_RequestId)
  2338. {
  2339. retcode = PENDING ;
  2340. }
  2341. else
  2342. {
  2343. RasTapiTrace("DeviceWork: Changing Listen "
  2344. "state for %s from %d -> %d",
  2345. hIOPort->TPCB_Name,
  2346. hIOPort->TPCB_ListenState,
  2347. LS_COMPLETE );
  2348. hIOPort->TPCB_ListenState = LS_COMPLETE ;
  2349. }
  2350. }
  2351. if (hIOPort->TPCB_ListenState == LS_COMPLETE)
  2352. {
  2353. if (hIOPort->TPCB_CallHandle == (-1))
  2354. {
  2355. retcode = ERROR_FROM_DEVICE ;
  2356. }
  2357. else
  2358. {
  2359. RasTapiTrace("DeviceWork: Changing State"
  2360. " for %s from %d -> %d",
  2361. hIOPort->TPCB_Name,
  2362. hIOPort->TPCB_State,
  2363. PS_CONNECTED );
  2364. hIOPort->TPCB_State = PS_CONNECTED ;
  2365. retcode = SUCCESS ;
  2366. }
  2367. }
  2368. }
  2369. //
  2370. // If we have connected, then get the com port handle for
  2371. // use in terminal modem i/o
  2372. //
  2373. if (hIOPort->TPCB_State == PS_CONNECTED)
  2374. {
  2375. VARSTRING *varstring ;
  2376. BYTE buffer [100] ;
  2377. //
  2378. // get the cookie to realize tapi and ndis endpoints
  2379. //
  2380. varstring = (VARSTRING *) buffer ;
  2381. varstring->dwTotalSize = sizeof(buffer) ;
  2382. //
  2383. // Unimodem/asyncmac linegetid returns a comm port handle.
  2384. // Other medias give the endpoint itself back in linegetid
  2385. // This has to do with the fact that modems/asyncmac are
  2386. // not a miniport.
  2387. //
  2388. if (_stricmp (hIOPort->TPCB_DeviceType,
  2389. DEVICETYPE_UNIMODEM) == 0)
  2390. {
  2391. if ( retcode =
  2392. lineGetID (hIOPort->TPCB_Line->TLI_LineHandle,
  2393. hIOPort->TPCB_AddressId,
  2394. hIOPort->TPCB_CallHandle,
  2395. LINECALLSELECT_CALL,
  2396. varstring,
  2397. "comm/datamodem"))
  2398. {
  2399. RasTapiTrace("DeviceWork: %s lineGetID Failed. 0x%x",
  2400. hIOPort->TPCB_Name, retcode );
  2401. // **** Exclusion End ****
  2402. FreeMutex (RasTapiMutex) ;
  2403. RasTapiTrace(" ");
  2404. return ERROR_FROM_DEVICE ;
  2405. }
  2406. hIOPort->TPCB_CommHandle =
  2407. (HANDLE) UlongToPtr((*((DWORD UNALIGNED *)
  2408. ((BYTE *)varstring+varstring->dwStringOffset)))) ;
  2409. RasTapiTrace("DeviceWork: TPCB_CommHandle=%d",
  2410. hIOPort->TPCB_CommHandle );
  2411. //
  2412. // Create the I/O completion port for
  2413. // asynchronous operation completion
  2414. // notificiations.
  2415. //
  2416. if (CreateIoCompletionPort(
  2417. hIOPort->TPCB_CommHandle,
  2418. hIOPort->TPCB_IoCompletionPort,
  2419. hIOPort->TPCB_CompletionKey,
  2420. 0) == NULL)
  2421. {
  2422. retcode = GetLastError();
  2423. RasTapiTrace("DeviceWork: %s. CreateIoCompletionPort "
  2424. "failed. %d",
  2425. hIOPort->TPCB_Name,
  2426. retcode );
  2427. FreeMutex(RasTapiMutex);
  2428. RasTapiTrace(" ");
  2429. return retcode;
  2430. }
  2431. //
  2432. // Initialize the port for approp. buffers
  2433. //
  2434. SetupComm (hIOPort->TPCB_CommHandle, 1514, 1514) ;
  2435. }
  2436. #if 0
  2437. else
  2438. {
  2439. if ( retcode = lineGetID (hIOPort->TPCB_Line->TLI_LineHandle,
  2440. hIOPort->TPCB_AddressId,
  2441. hIOPort->TPCB_CallHandle,
  2442. LINECALLSELECT_CALL,
  2443. varstring,
  2444. "NDIS"))
  2445. {
  2446. RasTapiTrace ("DeviceWork: %s. lineGetId Failed. 0x%x",
  2447. hIOPort->TPCB_Name,
  2448. retcode );
  2449. // **** Exclusion End ****
  2450. FreeMutex (RasTapiMutex) ;
  2451. RasTapiTrace(" ");
  2452. return ERROR_FROM_DEVICE ;
  2453. }
  2454. hIOPort->TPCB_Endpoint =
  2455. *((HANDLE UNALIGNED *) ((BYTE *)varstring+varstring->dwStringOffset)) ;
  2456. }
  2457. #endif
  2458. }
  2459. // **** Exclusion End ****
  2460. FreeMutex (RasTapiMutex) ;
  2461. return(retcode);
  2462. }
  2463. /*++
  2464. Routine Description:
  2465. Called to set an opaque blob of
  2466. data to configure a device.
  2467. Arguments:
  2468. Return Value:
  2469. LocalAlloc returned values.
  2470. --*/
  2471. DWORD
  2472. DeviceSetDevConfig (
  2473. HANDLE hPort,
  2474. PBYTE devconfig,
  2475. DWORD sizeofdevconfig
  2476. )
  2477. {
  2478. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  2479. if (!hIOPort)
  2480. {
  2481. RasTapiTrace("DeviceSetDevConfig: port"
  2482. " 0x%x not found",
  2483. hPort );
  2484. return ERROR_PORT_NOT_FOUND ;
  2485. }
  2486. if (_stricmp (hIOPort->TPCB_DeviceType,
  2487. DEVICETYPE_UNIMODEM))
  2488. {
  2489. return SUCCESS ;
  2490. }
  2491. // **** Exclusion Begin ****
  2492. GetMutex (RasTapiMutex, INFINITE) ;
  2493. if (hIOPort->TPCB_DevConfig != NULL)
  2494. {
  2495. LocalFree (hIOPort->TPCB_DevConfig) ;
  2496. }
  2497. if ((hIOPort->TPCB_DevConfig =
  2498. LocalAlloc(LPTR, sizeofdevconfig)) == NULL)
  2499. {
  2500. // **** Exclusion End ****
  2501. FreeMutex (RasTapiMutex) ;
  2502. return(GetLastError());
  2503. }
  2504. memcpy (hIOPort->TPCB_DevConfig,
  2505. devconfig,
  2506. sizeofdevconfig) ;
  2507. hIOPort->TPCB_SizeOfDevConfig = sizeofdevconfig ;
  2508. // **** Exclusion End ****
  2509. FreeMutex (RasTapiMutex) ;
  2510. return (SUCCESS);
  2511. }
  2512. DWORD
  2513. DwGetConfigInfoForDeviceClass(
  2514. DWORD LineId,
  2515. CHAR *pszDeviceClass,
  2516. LPVARSTRING *ppVar)
  2517. {
  2518. LPVARSTRING var = NULL;
  2519. LONG lr;
  2520. DWORD dwNeededSize;
  2521. //
  2522. // Make var string
  2523. //
  2524. var = (LPVARSTRING)LocalAlloc(LPTR, 2000) ;
  2525. if(NULL == var)
  2526. {
  2527. lr = (LONG) GetLastError();
  2528. goto done;
  2529. }
  2530. var->dwTotalSize = 2000 ;
  2531. if( (ERROR_SUCCESS != (lr = lineGetDevConfig (
  2532. LineId,
  2533. var,
  2534. pszDeviceClass)))
  2535. && (LINEERR_STRUCTURETOOSMALL != lr))
  2536. {
  2537. goto done;
  2538. }
  2539. if(var->dwNeededSize > 2000)
  2540. {
  2541. dwNeededSize = var->dwNeededSize;
  2542. LocalFree(var);
  2543. var = (LPVARSTRING) LocalAlloc(LPTR, dwNeededSize);
  2544. if(NULL == var)
  2545. {
  2546. lr = (LONG) GetLastError();
  2547. goto done;
  2548. }
  2549. var->dwTotalSize = dwNeededSize;
  2550. lr = lineGetDevConfig(
  2551. LineId,
  2552. var,
  2553. pszDeviceClass);
  2554. }
  2555. done:
  2556. if(ERROR_SUCCESS != lr)
  2557. {
  2558. LocalFree(var);
  2559. var = NULL;
  2560. }
  2561. *ppVar = var;
  2562. return ((DWORD) lr);
  2563. }
  2564. DWORD
  2565. DwGetDevConfig(
  2566. DWORD LineId,
  2567. PBYTE pBuffer,
  2568. DWORD *pcbSize,
  2569. BOOL fDialIn)
  2570. {
  2571. DWORD dwSize;
  2572. DWORD dwErr = ERROR_SUCCESS;
  2573. BYTE buffer[2000];
  2574. LPVARSTRING varModem = NULL,
  2575. varExtendedCaps = NULL;
  2576. if(NULL == pcbSize)
  2577. {
  2578. dwErr = E_INVALIDARG;
  2579. goto done;
  2580. }
  2581. dwSize = *pcbSize;
  2582. *pcbSize = 0;
  2583. if(fDialIn)
  2584. {
  2585. dwErr = DwGetConfigInfoForDeviceClass(
  2586. LineId,
  2587. "comm/datamodem/dialin",
  2588. &varModem);
  2589. }
  2590. else
  2591. {
  2592. dwErr = DwGetConfigInfoForDeviceClass(
  2593. LineId,
  2594. "comm/datamodem",
  2595. &varModem);
  2596. }
  2597. if(ERROR_SUCCESS != dwErr)
  2598. {
  2599. RasTapiTrace("DwGetDevConfig returned error=0x%x",
  2600. dwErr);
  2601. goto done;
  2602. }
  2603. dwErr = DwGetConfigInfoForDeviceClass(
  2604. LineId,
  2605. "comm/extendedcaps",
  2606. &varExtendedCaps);
  2607. if(ERROR_SUCCESS != dwErr)
  2608. {
  2609. /*
  2610. RasTapiTrace("DwGetDevConfig returned error=0x%x",
  2611. dwErr);
  2612. */
  2613. //
  2614. // Ignore the error
  2615. //
  2616. dwErr = ERROR_SUCCESS;
  2617. }
  2618. *pcbSize = sizeof(RAS_DEVCONFIG)
  2619. + varModem->dwStringSize
  2620. + ((NULL != varExtendedCaps)
  2621. ? varExtendedCaps->dwStringSize
  2622. : 0);
  2623. if(dwSize >= *pcbSize)
  2624. {
  2625. RAS_DEVCONFIG *pConfig = (RAS_DEVCONFIG *) pBuffer;
  2626. pConfig->dwOffsetofModemSettings =
  2627. FIELD_OFFSET(RAS_DEVCONFIG, abInfo);
  2628. pConfig->dwSizeofModemSettings = varModem->dwStringSize;
  2629. memcpy(pConfig->abInfo,
  2630. (PBYTE) ((BYTE *) varModem) + varModem->dwStringOffset,
  2631. pConfig->dwSizeofModemSettings);
  2632. if(NULL != varExtendedCaps)
  2633. {
  2634. pConfig->dwOffsetofExtendedCaps =
  2635. pConfig->dwOffsetofModemSettings
  2636. + pConfig->dwSizeofModemSettings;
  2637. pConfig->dwSizeofExtendedCaps =
  2638. varExtendedCaps->dwStringSize;
  2639. memcpy(pConfig->abInfo + pConfig->dwSizeofModemSettings,
  2640. (PBYTE) ((PBYTE) varExtendedCaps)
  2641. + varExtendedCaps->dwStringOffset,
  2642. pConfig->dwSizeofExtendedCaps);
  2643. }
  2644. else
  2645. {
  2646. pConfig->dwOffsetofExtendedCaps = 0;
  2647. pConfig->dwSizeofExtendedCaps = 0;
  2648. }
  2649. }
  2650. else
  2651. {
  2652. dwErr = ERROR_BUFFER_TOO_SMALL;
  2653. }
  2654. done:
  2655. if(NULL != varModem)
  2656. {
  2657. LocalFree(varModem);
  2658. }
  2659. if(NULL != varExtendedCaps)
  2660. {
  2661. LocalFree(varExtendedCaps);
  2662. }
  2663. return dwErr;
  2664. }
  2665. /*++
  2666. Routine Description:
  2667. Called to set an opaque blob of
  2668. data to configure a device.
  2669. Arguments:
  2670. Return Value:
  2671. LocalAlloc returned values.
  2672. --*/
  2673. DWORD
  2674. DwDeviceGetDevConfig (
  2675. char *name,
  2676. PBYTE devconfig,
  2677. DWORD *sizeofdevconfig,
  2678. BOOL fDialIn
  2679. )
  2680. {
  2681. TapiPortControlBlock *hIOPort = RasPortsList;
  2682. DWORD i ;
  2683. BYTE buffer[2000] ;
  2684. LPVARSTRING var ;
  2685. PBYTE configptr ;
  2686. DWORD configsize ;
  2687. DWORD retcode = SUCCESS;
  2688. while ( hIOPort )
  2689. {
  2690. if (!_stricmp(hIOPort->TPCB_Name, name))
  2691. {
  2692. break ;
  2693. }
  2694. hIOPort = hIOPort->TPCB_next;
  2695. }
  2696. if (!hIOPort)
  2697. {
  2698. RasTapiTrace("DeviceGetDevConfig: port"
  2699. " %s not found",
  2700. name );
  2701. RasTapiTrace(" ");
  2702. return ERROR_PORT_NOT_FOUND ;
  2703. }
  2704. if (_stricmp (hIOPort->TPCB_DeviceType,
  2705. DEVICETYPE_UNIMODEM))
  2706. {
  2707. *sizeofdevconfig = 0 ;
  2708. return SUCCESS ;
  2709. }
  2710. // **** Exclusion Begin ****
  2711. GetMutex (RasTapiMutex, INFINITE) ;
  2712. if (hIOPort->TPCB_DevConfig != NULL)
  2713. {
  2714. configptr = hIOPort->TPCB_DevConfig ;
  2715. configsize = hIOPort->TPCB_SizeOfDevConfig ;
  2716. }
  2717. else
  2718. {
  2719. retcode = DwGetDevConfig(
  2720. hIOPort->TPCB_Line->TLI_LineId,
  2721. devconfig,
  2722. sizeofdevconfig,
  2723. fDialIn);
  2724. goto done;
  2725. }
  2726. if (*sizeofdevconfig >= configsize)
  2727. {
  2728. memcpy (devconfig, configptr, configsize) ;
  2729. retcode = SUCCESS ;
  2730. }
  2731. else
  2732. {
  2733. retcode = ERROR_BUFFER_TOO_SMALL ;
  2734. }
  2735. *sizeofdevconfig = configsize ;
  2736. done:
  2737. // **** Exclusion End ****
  2738. FreeMutex (RasTapiMutex) ;
  2739. return (retcode);
  2740. }
  2741. DWORD
  2742. DeviceGetDevConfig(
  2743. char *name,
  2744. PBYTE devconfig,
  2745. DWORD *sizeofdevconfig)
  2746. {
  2747. return DwDeviceGetDevConfig (
  2748. name, devconfig,
  2749. sizeofdevconfig, FALSE);
  2750. }
  2751. DWORD
  2752. DeviceGetDevConfigEx(
  2753. char *name,
  2754. PBYTE devconfig,
  2755. DWORD *sizeofdevconfig)
  2756. {
  2757. return DwDeviceGetDevConfig (
  2758. name, devconfig,
  2759. sizeofdevconfig, TRUE);
  2760. }
  2761. DWORD
  2762. RastapiGetCalledID(PBYTE pbAdapter,
  2763. BOOL fModem,
  2764. RAS_CALLEDID_INFO *pCalledID,
  2765. DWORD *pdwSize)
  2766. {
  2767. DWORD retcode = ERROR_SUCCESS;
  2768. DeviceInfo *pInfo = NULL;
  2769. DWORD dwSize;
  2770. RasTapiTrace("RastapiGetCalledID..");
  2771. if(NULL == pdwSize)
  2772. {
  2773. retcode = E_INVALIDARG;
  2774. goto done;
  2775. }
  2776. dwSize = *pdwSize;
  2777. GetMutex(RasTapiMutex, INFINITE);
  2778. pInfo = GetDeviceInfo(pbAdapter,
  2779. fModem);
  2780. if(NULL == pInfo)
  2781. {
  2782. retcode = E_FAIL;
  2783. goto done;
  2784. }
  2785. /*
  2786. if(NULL != pInfo->pCalledID)
  2787. {
  2788. LocalFree(pInfo->pCalledID);
  2789. pInfo->pCalledID = NULL;
  2790. }
  2791. retcode = DwGetCalledIdInfo(NULL,
  2792. pInfo);
  2793. if(ERROR_SUCCESS != retcode)
  2794. {
  2795. goto done;
  2796. }
  2797. */
  2798. if(NULL == pInfo->pCalledID)
  2799. {
  2800. retcode = E_FAIL;
  2801. goto done;
  2802. }
  2803. *pdwSize = sizeof(RAS_CALLEDID_INFO) +
  2804. pInfo->pCalledID->dwSize;
  2805. if( (NULL != pCalledID)
  2806. && (*pdwSize <= dwSize))
  2807. {
  2808. memcpy(pCalledID,
  2809. pInfo->pCalledID,
  2810. *pdwSize);
  2811. }
  2812. done:
  2813. FreeMutex(RasTapiMutex);
  2814. RasTapiTrace("RastapiGetCalledID. 0x%x",
  2815. retcode);
  2816. return retcode;
  2817. }
  2818. DWORD
  2819. RastapiSetCalledID(PBYTE pbAdapter,
  2820. BOOL fModem,
  2821. RAS_CALLEDID_INFO *pCalledID,
  2822. BOOL fWrite)
  2823. {
  2824. DWORD retcode = ERROR_SUCCESS;
  2825. DeviceInfo *pInfo = NULL;
  2826. RasTapiTrace("RastapiSetCalledID..");
  2827. if(NULL == pCalledID)
  2828. {
  2829. retcode = E_INVALIDARG;
  2830. goto done;
  2831. }
  2832. GetMutex(RasTapiMutex, INFINITE);
  2833. pInfo = GetDeviceInfo(pbAdapter,
  2834. fModem);
  2835. if(NULL == pInfo)
  2836. {
  2837. retcode = E_FAIL;
  2838. goto done;
  2839. }
  2840. if(NULL != pInfo->pCalledID)
  2841. {
  2842. LocalFree(pInfo->pCalledID);
  2843. pInfo->pCalledID = NULL;
  2844. }
  2845. pInfo->pCalledID = LocalAlloc(LPTR,
  2846. sizeof(RAS_CALLEDID_INFO)
  2847. + pCalledID->dwSize);
  2848. if(NULL == pInfo->pCalledID)
  2849. {
  2850. retcode = GetLastError();
  2851. goto done;
  2852. }
  2853. memcpy(pInfo->pCalledID->bCalledId,
  2854. pCalledID->bCalledId,
  2855. pCalledID->dwSize);
  2856. pInfo->pCalledID->dwSize = pCalledID->dwSize;
  2857. if(fWrite)
  2858. {
  2859. retcode = DwSetCalledIdInfo(NULL,
  2860. pInfo);
  2861. if(ERROR_SUCCESS != retcode)
  2862. {
  2863. goto done;
  2864. }
  2865. }
  2866. done:
  2867. FreeMutex(RasTapiMutex);
  2868. RasTapiTrace("RastapiSetCalledID. 0x%x",
  2869. retcode);
  2870. return retcode;
  2871. }
  2872. /*++
  2873. Routine Description:
  2874. Notification that the number of
  2875. pptp endpoints changed
  2876. Arguments:
  2877. Return Value:
  2878. --*/
  2879. DWORD
  2880. AddPorts( PBYTE pbGuidAdapter, PVOID pvReserved )
  2881. {
  2882. DWORD retcode;
  2883. BOOL fINetCfgInited = FALSE;
  2884. DeviceInfo *pDeviceInfo = NULL;
  2885. DeviceInfo *pNewDeviceInfo = NULL;
  2886. GetMutex( RasTapiMutex, INFINITE );
  2887. RasTapiTrace("AddPorts");
  2888. //
  2889. // Get Current DeviceInfo
  2890. //
  2891. pDeviceInfo = GetDeviceInfo(pbGuidAdapter, FALSE);
  2892. RasTapiTrace("OldInfo");
  2893. TraceEndPointInfo(pDeviceInfo);
  2894. #if DBG
  2895. ASSERT( NULL != pDeviceInfo );
  2896. #endif
  2897. RasTapiTrace("AddPorts: Old: NumEndPoints=%d",
  2898. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints );
  2899. retcode = GetEndPointInfo(&pNewDeviceInfo,
  2900. pbGuidAdapter,
  2901. TRUE,
  2902. 0);
  2903. if ( retcode )
  2904. {
  2905. RasTapiTrace("AddPorts: Failed to get enpoint "
  2906. "info from retistry");
  2907. goto error;
  2908. }
  2909. pNewDeviceInfo->rdiDeviceInfo.eDeviceType =
  2910. pDeviceInfo->rdiDeviceInfo.eDeviceType;
  2911. RasTapiTrace("NewInfo");
  2912. TraceEndPointInfo(pNewDeviceInfo);
  2913. //
  2914. // Assign the new Number of endpoints to
  2915. // the deviceinfo in the global list
  2916. //
  2917. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints =
  2918. pNewDeviceInfo->rdiDeviceInfo.dwNumEndPoints;
  2919. //
  2920. // Reset the current endpoints to 0 for
  2921. // this adapter since we are again going
  2922. // to enumerate all the lines.
  2923. //
  2924. pDeviceInfo->dwCurrentEndPoints = 0;
  2925. LocalFree (pNewDeviceInfo);
  2926. RasTapiTrace("AddPorts: New: NumEndPoints=%d",
  2927. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints );
  2928. retcode = dwAddPorts( pbGuidAdapter, pvReserved );
  2929. //
  2930. // At this point the currentendpoints should also
  2931. // be the Numendpoints. Make it so if its not the
  2932. // case - since otherwise we will get out of ssync.
  2933. //
  2934. if(pDeviceInfo->rdiDeviceInfo.dwNumEndPoints !=
  2935. pDeviceInfo->dwCurrentEndPoints)
  2936. {
  2937. RasTapiTrace(
  2938. "AddPorts: NEP==%d != CEP==%d",
  2939. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints,
  2940. pDeviceInfo->dwCurrentEndPoints);
  2941. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints =
  2942. pDeviceInfo->dwCurrentEndPoints;
  2943. }
  2944. if(pvReserved != NULL)
  2945. {
  2946. *((ULONG *) pvReserved) =
  2947. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints;
  2948. }
  2949. error:
  2950. FreeMutex ( RasTapiMutex );
  2951. RasTapiTrace(" ");
  2952. return retcode;
  2953. }
  2954. DWORD
  2955. RemovePort (
  2956. CHAR *pszPortName,
  2957. BOOL fRemovePort,
  2958. PBYTE pbGuidAdapter
  2959. )
  2960. {
  2961. TapiPortControlBlock *pport = RasPortsList;
  2962. DWORD dwRetCode = SUCCESS;
  2963. DeviceInfo *pDeviceInfo = NULL;
  2964. TapiPortControlBlock *pportT = NULL;
  2965. GetMutex ( RasTapiMutex, INFINITE );
  2966. RasTapiTrace("RemovePort: %s", pszPortName );
  2967. /*
  2968. pDeviceInfo = GetDeviceInfo(pbGuidAdapter, FALSE);
  2969. if ( 0 == pDeviceInfo->rdiDeviceInfo.dwNumEndPoints )
  2970. {
  2971. RasTapiTrace("RemovePort: No ports to remove. %s",
  2972. pszPortName );
  2973. goto done;
  2974. } */
  2975. while ( pport )
  2976. {
  2977. if ( 0 == _stricmp (pszPortName, pport->TPCB_Name))
  2978. {
  2979. DeviceInfo *pDeviceInfo = pport->TPCB_Line->TLI_pDeviceInfo;
  2980. pportT = pport;
  2981. if(RDT_Modem !=
  2982. RAS_DEVICE_TYPE(pDeviceInfo->rdiDeviceInfo.eDeviceType))
  2983. {
  2984. break;
  2985. }
  2986. //
  2987. // For modems continue to try to find a port which is marked
  2988. // for removal - this is required since we can end up with 2
  2989. // modems on the same com port and one of them is marked for
  2990. // removal.
  2991. //
  2992. if(PS_UNAVAILABLE == pport->TPCB_State)
  2993. {
  2994. break;
  2995. }
  2996. }
  2997. pport = pport->TPCB_next;
  2998. }
  2999. pport = pportT;
  3000. if ( NULL == pport )
  3001. {
  3002. RasTapiTrace ("RemovePort: port %s not found",
  3003. pszPortName );
  3004. goto done;
  3005. }
  3006. pDeviceInfo = pport->TPCB_Line->TLI_pDeviceInfo;
  3007. if ( fRemovePort )
  3008. {
  3009. RasTapiTrace("RemovePort: removing %s",
  3010. pport->TPCB_Name );
  3011. dwRetCode = dwRemovePort ( pport );
  3012. }
  3013. else
  3014. {
  3015. RasTapiTrace ("RemovePort: Marking %s for removal",
  3016. pport->TPCB_Name );
  3017. RasTapiTrace ("RemovePorT: Changing state"
  3018. " of %s from %d -> %d",
  3019. pport->TPCB_Name,
  3020. pport->TPCB_State,
  3021. PS_UNAVAILABLE );
  3022. pport->TPCB_State = PS_UNAVAILABLE;
  3023. pport->TPCB_dwFlags |= RASTAPI_FLAG_UNAVAILABLE;
  3024. }
  3025. #if DBG
  3026. ASSERT(pDeviceInfo->rdiDeviceInfo.dwNumEndPoints);
  3027. ASSERT(pDeviceInfo->dwCurrentEndPoints);
  3028. if(pDeviceInfo->rdiDeviceInfo.dwNumEndPoints == 0)
  3029. {
  3030. DbgPrint("RemovePort: pDeviceInfo->dwNumEndPoints==0!!!\n");
  3031. }
  3032. if(pDeviceInfo->dwCurrentEndPoints == 0)
  3033. {
  3034. DbgPrint("RemovePort: pDeviceInfo->dwCurrentEndPoints==0!!!\n");
  3035. }
  3036. #endif
  3037. if(pDeviceInfo->rdiDeviceInfo.dwNumEndPoints > 0)
  3038. {
  3039. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints -= 1;
  3040. }
  3041. if(pDeviceInfo->dwCurrentEndPoints > 0)
  3042. {
  3043. pDeviceInfo->dwCurrentEndPoints -= 1;
  3044. }
  3045. RasTapiTrace("RemovePort. dwnumEndPoints for port = %d",
  3046. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints);
  3047. done:
  3048. FreeMutex ( RasTapiMutex );
  3049. RasTapiTrace(" ");
  3050. return dwRetCode;
  3051. }
  3052. DWORD
  3053. EnableDeviceForDialIn(DeviceInfo *pDeviceInfo,
  3054. BOOL fEnable,
  3055. BOOL fEnableRouter,
  3056. BOOL fEnableOutboundRouter)
  3057. {
  3058. DWORD dwRetCode = SUCCESS;
  3059. TapiPortControlBlock *pport = RasPortsList;
  3060. DeviceInfo *pInfo;
  3061. BOOL fModem =
  3062. ((RDT_Modem ==
  3063. RAS_DEVICE_TYPE(
  3064. pDeviceInfo->rdiDeviceInfo.eDeviceType))
  3065. ? TRUE
  3066. : FALSE);
  3067. GetMutex(RasTapiMutex, INFINITE);
  3068. #if DBG
  3069. ASSERT(pDeviceInfo);
  3070. #endif
  3071. if(NULL == pDeviceInfo)
  3072. {
  3073. goto done;
  3074. }
  3075. RasTapiTrace("EnableDeviceForDialIn: fEnable=%d, "
  3076. "fEnableRouter=%d, fEnableOutboundRouter=%d, "
  3077. "device=%s",
  3078. (UINT) fEnable,
  3079. (UINT) fEnableRouter,
  3080. (UINT) fEnableOutboundRouter,
  3081. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  3082. //
  3083. // Run through the list of ports and change the usage of ports
  3084. // on this device.
  3085. //
  3086. while (pport)
  3087. {
  3088. if(fModem)
  3089. {
  3090. if(_stricmp(pport->TPCB_DeviceName,
  3091. pDeviceInfo->rdiDeviceInfo.szDeviceName))
  3092. {
  3093. pport = pport->TPCB_next;
  3094. continue;
  3095. }
  3096. }
  3097. else
  3098. {
  3099. pInfo = pport->TPCB_Line->TLI_pDeviceInfo;
  3100. if(memcmp(&pInfo->rdiDeviceInfo.guidDevice,
  3101. &pDeviceInfo->rdiDeviceInfo.guidDevice,
  3102. sizeof(GUID)))
  3103. {
  3104. pport = pport->TPCB_next;
  3105. continue;
  3106. }
  3107. }
  3108. pInfo = pport->TPCB_Line->TLI_pDeviceInfo;
  3109. pInfo->rdiDeviceInfo.fRasEnabled = fEnable;
  3110. pInfo->rdiDeviceInfo.fRouterEnabled = fEnableRouter;
  3111. pInfo->rdiDeviceInfo.fRouterOutboundEnabled = fEnableOutboundRouter;
  3112. if(fEnable)
  3113. {
  3114. RasTapiTrace("Enabling %s for dialin",
  3115. pport->TPCB_Name);
  3116. pport->TPCB_Usage |= CALL_IN;
  3117. }
  3118. else
  3119. {
  3120. RasTapiTrace("Disabling %s for dialin",
  3121. pport->TPCB_Name);
  3122. pport->TPCB_Usage &= ~CALL_IN;
  3123. }
  3124. if(fEnableRouter)
  3125. {
  3126. RasTapiTrace("Enabling %s for routing",
  3127. pport->TPCB_Name);
  3128. pport->TPCB_Usage |= CALL_ROUTER;
  3129. }
  3130. else
  3131. {
  3132. RasTapiTrace("Disabling %s for routing",
  3133. pport->TPCB_Name);
  3134. pport->TPCB_Usage &= ~CALL_ROUTER;
  3135. }
  3136. if(fEnableOutboundRouter)
  3137. {
  3138. RasTapiTrace("Enabling %s for outboundrouting",
  3139. pport->TPCB_Name);
  3140. pport->TPCB_Usage &= ~(CALL_IN | CALL_ROUTER);
  3141. pport->TPCB_Usage |= CALL_OUTBOUND_ROUTER;
  3142. }
  3143. pport = pport->TPCB_next;
  3144. }
  3145. done:
  3146. FreeMutex(RasTapiMutex);
  3147. return dwRetCode;
  3148. }
  3149. DWORD
  3150. DwGetSizeofMbcs(
  3151. WCHAR *pwszCalledId,
  3152. DWORD *pdwSize)
  3153. {
  3154. DWORD dwSize = 0;
  3155. DWORD retcode = SUCCESS;
  3156. *pdwSize = 0;
  3157. while(*pwszCalledId != L'\0')
  3158. {
  3159. dwSize = WideCharToMultiByte(
  3160. CP_ACP,
  3161. 0,
  3162. pwszCalledId,
  3163. -1,
  3164. NULL,
  3165. 0,
  3166. NULL,
  3167. NULL);
  3168. if(0 == dwSize)
  3169. {
  3170. retcode = GetLastError();
  3171. goto done;
  3172. }
  3173. pwszCalledId += wcslen(pwszCalledId) + 1;
  3174. *pdwSize += dwSize;
  3175. }
  3176. //
  3177. // Include one char for trailing '\0'
  3178. //
  3179. *pdwSize += 1;
  3180. done:
  3181. return retcode;
  3182. }
  3183. DWORD
  3184. DwFillCalledIDInfo(
  3185. RAS_CALLEDID_INFO *pCalledId,
  3186. RASTAPI_CONNECT_INFO *pConnectInfo,
  3187. DWORD *pdwSize,
  3188. DWORD dwSizeAvailable)
  3189. {
  3190. DWORD dwSize = 0;
  3191. DWORD retcode = SUCCESS;
  3192. WCHAR *pwszCalledId = NULL;
  3193. CHAR *pszCalledId = NULL;
  3194. DWORD cchLen;
  3195. ASSERT(NULL != pCalledId);
  3196. pwszCalledId = (WCHAR *) pCalledId->bCalledId;
  3197. //
  3198. // Get size of mbcs string equivalent of
  3199. // the unicode string
  3200. //
  3201. retcode = DwGetSizeofMbcs(
  3202. pwszCalledId,
  3203. &dwSize);
  3204. if(SUCCESS != retcode)
  3205. {
  3206. goto done;
  3207. }
  3208. *pdwSize += dwSize;
  3209. if(dwSizeAvailable < dwSize)
  3210. {
  3211. goto done;
  3212. }
  3213. pConnectInfo->dwAltCalledIdOffset =
  3214. FIELD_OFFSET(RASTAPI_CONNECT_INFO, abdata)
  3215. + RASMAN_ALIGN8(pConnectInfo->dwCallerIdSize)
  3216. + RASMAN_ALIGN8(pConnectInfo->dwCalledIdSize)
  3217. + RASMAN_ALIGN8(pConnectInfo->dwConnectResponseSize);
  3218. pConnectInfo->dwAltCalledIdSize = dwSize;
  3219. pszCalledId = (CHAR *)
  3220. ((LPBYTE)
  3221. pConnectInfo
  3222. + pConnectInfo->dwAltCalledIdOffset);
  3223. //
  3224. // Make the conversion from wchar to char
  3225. //
  3226. while(*pwszCalledId != L'\0')
  3227. {
  3228. if (0 == (dwSize = WideCharToMultiByte (
  3229. CP_ACP,
  3230. 0,
  3231. pwszCalledId,
  3232. -1,
  3233. pszCalledId,
  3234. dwSizeAvailable,
  3235. NULL,
  3236. NULL)))
  3237. {
  3238. retcode = GetLastError();
  3239. goto done;
  3240. }
  3241. dwSizeAvailable -= dwSize;
  3242. pwszCalledId += wcslen(pwszCalledId) + 1;
  3243. pszCalledId = ((PBYTE) pszCalledId) + dwSize;
  3244. }
  3245. //
  3246. // Append a NULL to make the string a multisz
  3247. //
  3248. *pszCalledId = '\0';
  3249. done:
  3250. return retcode;
  3251. }
  3252. DWORD
  3253. GetConnectInfo(
  3254. TapiPortControlBlock *hIOPort,
  3255. PBYTE pbDevice,
  3256. BOOL fModem,
  3257. RASTAPI_CONNECT_INFO *pInfo,
  3258. DWORD *pdwSize)
  3259. {
  3260. DWORD retcode = SUCCESS;
  3261. RASTAPI_CONNECT_INFO *pConnectInfo =
  3262. (NULL != hIOPort)
  3263. ? hIOPort->TPCB_pConnectInfo
  3264. : NULL;
  3265. RAS_CALLEDID_INFO *pCalledId =
  3266. (NULL != hIOPort)
  3267. ? hIOPort->TPCB_Line->TLI_pDeviceInfo->pCalledID
  3268. : NULL;
  3269. DWORD dwSize = 0;
  3270. GetMutex ( RasTapiMutex, INFINITE );
  3271. if( (NULL != hIOPort)
  3272. && (NULL == hIOPort->TPCB_pConnectInfo))
  3273. {
  3274. do
  3275. {
  3276. BYTE buffer[1000];
  3277. LINECALLINFO *linecallinfo;
  3278. RasTapiTrace(
  3279. "GetConnectInfo: Getting connectinfo because"
  3280. " info not available");
  3281. memset (buffer, 0, sizeof(buffer)) ;
  3282. linecallinfo = (LINECALLINFO *) buffer ;
  3283. linecallinfo->dwTotalSize = sizeof(buffer) ;
  3284. if ((retcode = lineGetCallInfo (
  3285. hIOPort->TPCB_CallHandle,
  3286. linecallinfo))
  3287. > 0x80000000)
  3288. {
  3289. if( (LINEERR_STRUCTURETOOSMALL == retcode)
  3290. || (linecallinfo->dwNeededSize > sizeof(buffer)))
  3291. {
  3292. DWORD dwSizeNeeded =
  3293. linecallinfo->dwNeededSize;
  3294. //
  3295. // Allocate the correct size and call
  3296. // the api again
  3297. //
  3298. linecallinfo = LocalAlloc(LPTR,
  3299. dwSizeNeeded);
  3300. if(NULL == linecallinfo)
  3301. {
  3302. retcode = GetLastError();
  3303. break;
  3304. }
  3305. linecallinfo->dwTotalSize = dwSizeNeeded;
  3306. retcode = lineGetCallInfo(
  3307. hIOPort->TPCB_CallHandle,
  3308. linecallinfo);
  3309. }
  3310. }
  3311. if(retcode > 0x80000000)
  3312. {
  3313. RasTapiTrace("GetConnectInfo: LINE_CALLSTATE - "
  3314. "lineGetCallInfo Failed. %d",
  3315. retcode );
  3316. if(buffer != (PBYTE) linecallinfo)
  3317. {
  3318. LocalFree(linecallinfo);
  3319. }
  3320. break ;
  3321. }
  3322. //
  3323. // Do the work to get CONNECTINFO, CALLER/CALLEDID
  3324. //
  3325. retcode = DwGetConnectInfo(hIOPort,
  3326. hIOPort->TPCB_CallHandle,
  3327. linecallinfo);
  3328. RasTapiTrace("GetConnectInfo: DwGetConnectInfo"
  3329. "returned 0x%x",
  3330. retcode);
  3331. //
  3332. // don't want to stop the dial from happening
  3333. // because we couldn't the connect info
  3334. //
  3335. retcode = SUCCESS;
  3336. //
  3337. // Free the linecallinfo struct. if we allocated
  3338. // it above
  3339. //
  3340. if(buffer != (PBYTE) linecallinfo)
  3341. {
  3342. LocalFree(linecallinfo);
  3343. }
  3344. }
  3345. while(FALSE);
  3346. }
  3347. pConnectInfo = (NULL != hIOPort)
  3348. ? hIOPort->TPCB_pConnectInfo
  3349. : NULL;
  3350. if( (NULL == pCalledId)
  3351. && (NULL != pbDevice))
  3352. {
  3353. DeviceInfo * pDeviceInfo = NULL;
  3354. pDeviceInfo = GetDeviceInfo(pbDevice, fModem);
  3355. if(NULL != pDeviceInfo)
  3356. {
  3357. pCalledId = pDeviceInfo->pCalledID;
  3358. }
  3359. }
  3360. if(NULL != pConnectInfo)
  3361. {
  3362. dwSize = sizeof(RASTAPI_CONNECT_INFO)
  3363. + RASMAN_ALIGN8(pConnectInfo->dwCallerIdSize)
  3364. + RASMAN_ALIGN8(pConnectInfo->dwCalledIdSize)
  3365. + RASMAN_ALIGN8(pConnectInfo->dwConnectResponseSize);
  3366. if( (NULL != pInfo)
  3367. && (*pdwSize >= dwSize))
  3368. {
  3369. memcpy((PBYTE) pInfo,
  3370. (PBYTE) pConnectInfo,
  3371. dwSize);
  3372. }
  3373. }
  3374. //
  3375. // Calculate the space required for the alternate
  3376. // calledids - read from registry and adjust the
  3377. // structure to return this information.
  3378. //
  3379. if(NULL != pCalledId)
  3380. {
  3381. DWORD dwSizeRemaining;
  3382. if(0 == dwSize)
  3383. {
  3384. dwSize = sizeof(RASTAPI_CONNECT_INFO);
  3385. }
  3386. dwSizeRemaining = (*pdwSize > dwSize)
  3387. ? (*pdwSize - dwSize)
  3388. : 0;
  3389. retcode = DwFillCalledIDInfo(
  3390. pCalledId,
  3391. pInfo,
  3392. &dwSize,
  3393. dwSizeRemaining);
  3394. }
  3395. if( (NULL == pConnectInfo)
  3396. && (NULL == pCalledId))
  3397. {
  3398. retcode = E_FAIL;
  3399. }
  3400. *pdwSize = dwSize;
  3401. FreeMutex(RasTapiMutex);
  3402. return retcode;
  3403. }
  3404. DWORD
  3405. GetZeroDeviceInfo(DWORD *pcDevices,
  3406. DeviceInfo ***pppDeviceInfo)
  3407. {
  3408. DeviceInfo *pDeviceInfo = g_pDeviceInfoList;
  3409. DeviceInfo **ppDeviceInfo = NULL;
  3410. DWORD cDevices = 0;
  3411. DWORD retcode = SUCCESS;
  3412. ASSERT(NULL != pcDevices);
  3413. ASSERT(NULL != pppDeviceInfo);
  3414. *pcDevices = 0;
  3415. *pppDeviceInfo = NULL;
  3416. while(NULL != pDeviceInfo)
  3417. {
  3418. if( (pDeviceInfo->fValid)
  3419. && (pDeviceInfo->rdiDeviceInfo.dwMinWanEndPoints
  3420. != pDeviceInfo->rdiDeviceInfo.dwMaxWanEndPoints)
  3421. && (0 == pDeviceInfo->rdiDeviceInfo.dwNumEndPoints))
  3422. {
  3423. cDevices += 1;
  3424. }
  3425. pDeviceInfo = pDeviceInfo->Next;
  3426. }
  3427. if(0 == cDevices)
  3428. {
  3429. goto done;
  3430. }
  3431. ppDeviceInfo = (DeviceInfo **) LocalAlloc(
  3432. LPTR,
  3433. cDevices
  3434. * sizeof(DeviceInfo *));
  3435. cDevices = 0;
  3436. if(NULL == ppDeviceInfo)
  3437. {
  3438. retcode = GetLastError();
  3439. goto done;
  3440. }
  3441. pDeviceInfo = g_pDeviceInfoList;
  3442. while(NULL != pDeviceInfo)
  3443. {
  3444. if( (pDeviceInfo->fValid)
  3445. && (pDeviceInfo->rdiDeviceInfo.dwMinWanEndPoints
  3446. != pDeviceInfo->rdiDeviceInfo.dwMaxWanEndPoints)
  3447. && (0 == pDeviceInfo->rdiDeviceInfo.dwNumEndPoints))
  3448. {
  3449. ppDeviceInfo[cDevices] = pDeviceInfo;
  3450. cDevices += 1;
  3451. }
  3452. pDeviceInfo = pDeviceInfo->Next;
  3453. }
  3454. *pppDeviceInfo = ppDeviceInfo;
  3455. *pcDevices = cDevices;
  3456. done:
  3457. RasTapiTrace("GetZeroDeviceInfo. rc=%d, cDevices=%d",
  3458. retcode,
  3459. cDevices);
  3460. return retcode;
  3461. }
  3462. DWORD
  3463. GetInfo (
  3464. TapiPortControlBlock *hIOPort,
  3465. BYTE *pBuffer,
  3466. DWORD *pdwSize
  3467. )
  3468. {
  3469. if (_stricmp (hIOPort->TPCB_DeviceType,
  3470. DEVICETYPE_ISDN) == 0)
  3471. {
  3472. GetIsdnParams (hIOPort, (RASMAN_PORTINFO *) pBuffer,
  3473. pdwSize) ;
  3474. }
  3475. else if (_stricmp (hIOPort->TPCB_DeviceType,
  3476. DEVICETYPE_X25) == 0)
  3477. {
  3478. GetX25Params (hIOPort, (RASMAN_PORTINFO *) pBuffer,
  3479. pdwSize) ;
  3480. }
  3481. else
  3482. {
  3483. GetGenericParams (hIOPort, (RASMAN_PORTINFO *) pBuffer,
  3484. pdwSize) ;
  3485. }
  3486. return SUCCESS ;
  3487. }
  3488. DWORD
  3489. SetInfo (
  3490. TapiPortControlBlock *hIOPort,
  3491. RASMAN_PORTINFO *pBuffer
  3492. )
  3493. {
  3494. if (_stricmp (hIOPort->TPCB_DeviceType,
  3495. DEVICETYPE_UNIMODEM) == 0)
  3496. {
  3497. FillInUnimodemParams (hIOPort, pBuffer) ;
  3498. }
  3499. else if (_stricmp (hIOPort->TPCB_DeviceType,
  3500. DEVICETYPE_ISDN) == 0)
  3501. {
  3502. FillInIsdnParams (hIOPort, pBuffer) ;
  3503. }
  3504. else if (_stricmp (hIOPort->TPCB_DeviceType,
  3505. DEVICETYPE_X25) == 0)
  3506. {
  3507. FillInX25Params (hIOPort, pBuffer) ;
  3508. }
  3509. else
  3510. {
  3511. FillInGenericParams (hIOPort, pBuffer) ;
  3512. }
  3513. return SUCCESS ;
  3514. }
  3515. /*++
  3516. Routine Description:
  3517. We do more than fill in the params if the params are
  3518. ones that are required to be set right then.
  3519. Arguments:
  3520. Return Value:
  3521. ERROR_WRONG_INFO_SPECIFIED.
  3522. Comm related Win32 errors
  3523. SUCCESS.
  3524. --*/
  3525. DWORD
  3526. FillInUnimodemParams (
  3527. TapiPortControlBlock *hIOPort,
  3528. RASMAN_PORTINFO *pInfo
  3529. )
  3530. {
  3531. RAS_PARAMS *p;
  3532. WORD i;
  3533. DWORD index = 0xfefefefe ;
  3534. DCB DCB ;
  3535. #define INITIALIZED_VALUE 0xde
  3536. BYTE DCBByteSize = INITIALIZED_VALUE ;
  3537. BYTE DCBParity = INITIALIZED_VALUE ;
  3538. BYTE DCBStopBits = INITIALIZED_VALUE ;
  3539. BOOL DCBProcessingRequired = FALSE ;
  3540. for (i = 0, p = pInfo->PI_Params;
  3541. i < pInfo->PI_NumOfParams;
  3542. i++, p++)
  3543. {
  3544. if (_stricmp(p->P_Key, SER_DATABITS_KEY) == 0)
  3545. {
  3546. DCBByteSize = (BYTE) ValueToNum(p);
  3547. DCBProcessingRequired = TRUE ;
  3548. }
  3549. else if (_stricmp(p->P_Key, SER_PARITY_KEY) == 0)
  3550. {
  3551. DCBParity = (BYTE) ValueToNum(p);
  3552. DCBProcessingRequired = TRUE ;
  3553. }
  3554. else if (_stricmp(p->P_Key, SER_STOPBITS_KEY) == 0)
  3555. {
  3556. DCBStopBits = (BYTE) ValueToNum(p);
  3557. DCBProcessingRequired = TRUE ;
  3558. }
  3559. //
  3560. // The fact we use ISDN_PHONENUMBER_KEY is not a bug.
  3561. // This is just a define.
  3562. //
  3563. else if (_stricmp(p->P_Key, ISDN_PHONENUMBER_KEY) == 0)
  3564. {
  3565. index = ADDRESS_INDEX ;
  3566. }
  3567. else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
  3568. {
  3569. index = CONNECTBPS_INDEX ;
  3570. }
  3571. else
  3572. {
  3573. return(ERROR_WRONG_INFO_SPECIFIED);
  3574. }
  3575. if (index != 0xfefefefe)
  3576. {
  3577. strncpy (hIOPort->TPCB_Info[index],
  3578. p->P_Value.String.Data,
  3579. p->P_Value.String.Length);
  3580. hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
  3581. }
  3582. }
  3583. //
  3584. // For parameters that should be set right away - check that
  3585. // the port handle is still valid
  3586. // if so set the parameters.
  3587. //
  3588. if ( DCBProcessingRequired
  3589. && hIOPort->TPCB_CommHandle != INVALID_HANDLE_VALUE)
  3590. {
  3591. //
  3592. // Get a Device Control Block with current port values
  3593. //
  3594. if (!GetCommState(hIOPort->TPCB_CommHandle, &DCB))
  3595. {
  3596. return(GetLastError());
  3597. }
  3598. if (DCBByteSize != INITIALIZED_VALUE)
  3599. {
  3600. DCB.ByteSize = DCBByteSize ;
  3601. }
  3602. if (DCBParity != INITIALIZED_VALUE)
  3603. {
  3604. DCB.Parity = DCBParity ;
  3605. }
  3606. if (DCBStopBits != INITIALIZED_VALUE)
  3607. {
  3608. DCB.StopBits = DCBStopBits ;
  3609. }
  3610. //
  3611. // Send DCB to Port
  3612. //
  3613. if (!SetCommState(hIOPort->TPCB_CommHandle, &DCB))
  3614. {
  3615. return(GetLastError());
  3616. }
  3617. }
  3618. return SUCCESS ;
  3619. }
  3620. DWORD
  3621. FillInIsdnParams (
  3622. TapiPortControlBlock *hIOPort,
  3623. RASMAN_PORTINFO *pInfo
  3624. )
  3625. {
  3626. RAS_PARAMS *p;
  3627. WORD i;
  3628. DWORD index ;
  3629. for (i = 0, p = pInfo->PI_Params;
  3630. i < pInfo->PI_NumOfParams;
  3631. i++, p++)
  3632. {
  3633. if (_stricmp(p->P_Key, ISDN_LINETYPE_KEY) == 0)
  3634. {
  3635. index = ISDN_LINETYPE_INDEX ;
  3636. }
  3637. else if (_stricmp(p->P_Key, ISDN_FALLBACK_KEY) == 0)
  3638. {
  3639. index = ISDN_FALLBACK_INDEX ;
  3640. }
  3641. else if (_stricmp(p->P_Key, ISDN_COMPRESSION_KEY) == 0)
  3642. {
  3643. index = ISDN_COMPRESSION_INDEX ;
  3644. }
  3645. else if (_stricmp(p->P_Key, ISDN_CHANNEL_AGG_KEY) == 0)
  3646. {
  3647. index = ISDN_CHANNEL_AGG_INDEX ;
  3648. }
  3649. else if (_stricmp(p->P_Key, ISDN_PHONENUMBER_KEY) == 0)
  3650. {
  3651. index = ADDRESS_INDEX ;
  3652. }
  3653. else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
  3654. {
  3655. index = ISDN_CONNECTBPS_INDEX ;
  3656. }
  3657. else
  3658. {
  3659. return(ERROR_WRONG_INFO_SPECIFIED);
  3660. }
  3661. strncpy (hIOPort->TPCB_Info[index],
  3662. p->P_Value.String.Data,
  3663. p->P_Value.String.Length);
  3664. hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
  3665. }
  3666. //
  3667. // initialize connectbps to a reasonable default
  3668. //
  3669. strcpy (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX], "64000") ;
  3670. return SUCCESS ;
  3671. }
  3672. DWORD
  3673. FillInX25Params (
  3674. TapiPortControlBlock *hIOPort,
  3675. RASMAN_PORTINFO *pInfo
  3676. )
  3677. {
  3678. RAS_PARAMS *p;
  3679. WORD i;
  3680. DWORD index ;
  3681. for (i = 0, p = pInfo->PI_Params;
  3682. i < pInfo->PI_NumOfParams;
  3683. i++, p++)
  3684. {
  3685. if (_stricmp(p->P_Key, MXS_DIAGNOSTICS_KEY) == 0)
  3686. {
  3687. index = X25_DIAGNOSTICS_INDEX ;
  3688. }
  3689. else if (_stricmp(p->P_Key, MXS_USERDATA_KEY) == 0)
  3690. {
  3691. index = X25_USERDATA_INDEX ;
  3692. }
  3693. else if (_stricmp(p->P_Key, MXS_FACILITIES_KEY) == 0)
  3694. {
  3695. index = X25_FACILITIES_INDEX;
  3696. }
  3697. else if (_stricmp(p->P_Key, MXS_X25ADDRESS_KEY) == 0)
  3698. {
  3699. index = ADDRESS_INDEX ;
  3700. }
  3701. else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
  3702. {
  3703. index = X25_CONNECTBPS_INDEX ;
  3704. }
  3705. else
  3706. {
  3707. return(ERROR_WRONG_INFO_SPECIFIED);
  3708. }
  3709. strncpy (hIOPort->TPCB_Info[index],
  3710. p->P_Value.String.Data,
  3711. p->P_Value.String.Length);
  3712. hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0';
  3713. }
  3714. //
  3715. // initialize connectbps to a reasonable default
  3716. //
  3717. strcpy (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX], "9600") ;
  3718. return SUCCESS ;
  3719. }
  3720. DWORD
  3721. FillInGenericParams (
  3722. TapiPortControlBlock *hIOPort,
  3723. RASMAN_PORTINFO *pInfo
  3724. )
  3725. {
  3726. RAS_PARAMS *p;
  3727. WORD i;
  3728. DWORD index ;
  3729. for (i=0, p=pInfo->PI_Params; i<pInfo->PI_NumOfParams; i++, p++)
  3730. {
  3731. if (_stricmp(p->P_Key, ISDN_PHONENUMBER_KEY) == 0)
  3732. {
  3733. index = ADDRESS_INDEX ;
  3734. }
  3735. else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
  3736. {
  3737. index = CONNECTBPS_INDEX ;
  3738. }
  3739. else
  3740. {
  3741. return(ERROR_WRONG_INFO_SPECIFIED);
  3742. }
  3743. strncpy (hIOPort->TPCB_Info[index],
  3744. p->P_Value.String.Data,
  3745. p->P_Value.String.Length);
  3746. hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
  3747. }
  3748. return SUCCESS ;
  3749. }
  3750. DWORD
  3751. GetGenericParams (
  3752. TapiPortControlBlock *hIOPort,
  3753. RASMAN_PORTINFO *pBuffer ,
  3754. PDWORD pdwSize
  3755. )
  3756. {
  3757. RAS_PARAMS *pParam;
  3758. CHAR *pValue;
  3759. DWORD dwAvailable ;
  3760. DWORD dwStructSize = sizeof(RASMAN_PORTINFO)
  3761. + sizeof(RAS_PARAMS) * 2;
  3762. dwAvailable = *pdwSize;
  3763. *pdwSize = (dwStructSize
  3764. + strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
  3765. + strlen (hIOPort->TPCB_Info[CONNECTBPS_INDEX])
  3766. + 1L) ;
  3767. if (*pdwSize > dwAvailable)
  3768. {
  3769. return(ERROR_BUFFER_TOO_SMALL);
  3770. }
  3771. ((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 2;
  3772. pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
  3773. pValue = (CHAR*)pBuffer + dwStructSize;
  3774. strcpy(pParam->P_Key, MXS_PHONENUMBER_KEY);
  3775. pParam->P_Type = String;
  3776. pParam->P_Attributes = 0;
  3777. pParam->P_Value.String.Length =
  3778. strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
  3779. pParam->P_Value.String.Data = pValue;
  3780. strcpy(pParam->P_Value.String.Data,
  3781. hIOPort->TPCB_Info[ADDRESS_INDEX]);
  3782. pParam++;
  3783. strcpy(pParam->P_Key, CONNECTBPS_KEY);
  3784. pParam->P_Type = String;
  3785. pParam->P_Attributes = 0;
  3786. pParam->P_Value.String.Length =
  3787. strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
  3788. pParam->P_Value.String.Data = pValue;
  3789. strcpy(pParam->P_Value.String.Data,
  3790. hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
  3791. return(SUCCESS);
  3792. }
  3793. DWORD
  3794. GetIsdnParams (
  3795. TapiPortControlBlock *hIOPort,
  3796. RASMAN_PORTINFO *pBuffer ,
  3797. PDWORD pdwSize
  3798. )
  3799. {
  3800. RAS_PARAMS *pParam;
  3801. CHAR *pValue;
  3802. DWORD dwAvailable ;
  3803. DWORD dwStructSize = sizeof(RASMAN_PORTINFO)
  3804. + sizeof(RAS_PARAMS) * 5;
  3805. dwAvailable = *pdwSize;
  3806. *pdwSize = (dwStructSize
  3807. + strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
  3808. + strlen (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX])
  3809. + strlen (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX])
  3810. + strlen (hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX])
  3811. + strlen (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX])
  3812. + strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX])
  3813. + 1L) ;
  3814. if (*pdwSize > dwAvailable)
  3815. {
  3816. return(ERROR_BUFFER_TOO_SMALL);
  3817. }
  3818. // Fill in Buffer
  3819. ((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 6;
  3820. pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
  3821. pValue = (CHAR*)pBuffer + dwStructSize;
  3822. strcpy(pParam->P_Key, ISDN_PHONENUMBER_KEY);
  3823. pParam->P_Type = String;
  3824. pParam->P_Attributes = 0;
  3825. pParam->P_Value.String.Length =
  3826. strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
  3827. pParam->P_Value.String.Data = pValue;
  3828. strcpy(pParam->P_Value.String.Data,
  3829. hIOPort->TPCB_Info[ADDRESS_INDEX]);
  3830. pValue += pParam->P_Value.String.Length + 1;
  3831. pParam++;
  3832. strcpy(pParam->P_Key, ISDN_LINETYPE_KEY);
  3833. pParam->P_Type = String;
  3834. pParam->P_Attributes = 0;
  3835. pParam->P_Value.String.Length =
  3836. strlen (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX]);
  3837. pParam->P_Value.String.Data = pValue;
  3838. strcpy(pParam->P_Value.String.Data,
  3839. hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX]);
  3840. pValue += pParam->P_Value.String.Length + 1;
  3841. pParam++;
  3842. strcpy(pParam->P_Key, ISDN_FALLBACK_KEY);
  3843. pParam->P_Type = String;
  3844. pParam->P_Attributes = 0;
  3845. pParam->P_Value.String.Length =
  3846. strlen (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]);
  3847. pParam->P_Value.String.Data = pValue;
  3848. strcpy(pParam->P_Value.String.Data,
  3849. hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]);
  3850. pValue += pParam->P_Value.String.Length + 1;
  3851. pParam++;
  3852. strcpy(pParam->P_Key, ISDN_COMPRESSION_KEY);
  3853. pParam->P_Type = String;
  3854. pParam->P_Attributes = 0;
  3855. pParam->P_Value.String.Length =
  3856. strlen (hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX]);
  3857. pParam->P_Value.String.Data = pValue;
  3858. strcpy(pParam->P_Value.String.Data,
  3859. hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX]);
  3860. pValue += pParam->P_Value.String.Length + 1;
  3861. pParam++;
  3862. strcpy(pParam->P_Key, ISDN_CHANNEL_AGG_KEY);
  3863. pParam->P_Type = String;
  3864. pParam->P_Attributes = 0;
  3865. pParam->P_Value.String.Length =
  3866. strlen (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]);
  3867. pParam->P_Value.String.Data = pValue;
  3868. strcpy(pParam->P_Value.String.Data,
  3869. hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]);
  3870. pValue += pParam->P_Value.String.Length + 1;
  3871. pParam++;
  3872. strcpy(pParam->P_Key, CONNECTBPS_KEY);
  3873. pParam->P_Type = String;
  3874. pParam->P_Attributes = 0;
  3875. pParam->P_Value.String.Length =
  3876. strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
  3877. pParam->P_Value.String.Data = pValue;
  3878. strcpy(pParam->P_Value.String.Data,
  3879. hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
  3880. return(SUCCESS);
  3881. }
  3882. DWORD
  3883. GetX25Params (
  3884. TapiPortControlBlock *hIOPort,
  3885. RASMAN_PORTINFO *pBuffer ,
  3886. PDWORD pdwSize
  3887. )
  3888. {
  3889. RAS_PARAMS *pParam;
  3890. CHAR *pValue;
  3891. DWORD dwAvailable ;
  3892. DWORD dwStructSize = sizeof(RASMAN_PORTINFO)
  3893. + sizeof(RAS_PARAMS) * 4 ;
  3894. dwAvailable = *pdwSize;
  3895. *pdwSize = (dwStructSize
  3896. + strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
  3897. + strlen (hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX])
  3898. + strlen (hIOPort->TPCB_Info[X25_USERDATA_INDEX])
  3899. + strlen (hIOPort->TPCB_Info[X25_FACILITIES_INDEX])
  3900. + strlen (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX])
  3901. + 1L) ;
  3902. if (*pdwSize > dwAvailable)
  3903. {
  3904. return(ERROR_BUFFER_TOO_SMALL);
  3905. }
  3906. // Fill in Buffer
  3907. ((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 5 ;
  3908. pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
  3909. pValue = (CHAR*)pBuffer + dwStructSize;
  3910. strcpy(pParam->P_Key, MXS_X25ADDRESS_KEY);
  3911. pParam->P_Type = String;
  3912. pParam->P_Attributes = 0;
  3913. pParam->P_Value.String.Length =
  3914. strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
  3915. pParam->P_Value.String.Data = pValue;
  3916. strcpy(pParam->P_Value.String.Data,
  3917. hIOPort->TPCB_Info[ADDRESS_INDEX]);
  3918. pValue += pParam->P_Value.String.Length + 1;
  3919. pParam++;
  3920. strcpy(pParam->P_Key, MXS_DIAGNOSTICS_KEY);
  3921. pParam->P_Type = String;
  3922. pParam->P_Attributes = 0;
  3923. pParam->P_Value.String.Length =
  3924. strlen (hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX]);
  3925. pParam->P_Value.String.Data = pValue;
  3926. strcpy(pParam->P_Value.String.Data,
  3927. hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX]);
  3928. pValue += pParam->P_Value.String.Length + 1;
  3929. pParam++;
  3930. strcpy(pParam->P_Key, MXS_USERDATA_KEY);
  3931. pParam->P_Type = String;
  3932. pParam->P_Attributes = 0;
  3933. pParam->P_Value.String.Length =
  3934. strlen (hIOPort->TPCB_Info[X25_USERDATA_INDEX]);
  3935. pParam->P_Value.String.Data = pValue;
  3936. strcpy(pParam->P_Value.String.Data,
  3937. hIOPort->TPCB_Info[X25_USERDATA_INDEX]);
  3938. pValue += pParam->P_Value.String.Length + 1;
  3939. pParam++;
  3940. strcpy(pParam->P_Key, MXS_FACILITIES_KEY);
  3941. pParam->P_Type = String;
  3942. pParam->P_Attributes = 0;
  3943. pParam->P_Value.String.Length =
  3944. strlen (hIOPort->TPCB_Info[X25_FACILITIES_INDEX]);
  3945. pParam->P_Value.String.Data = pValue;
  3946. strcpy(pParam->P_Value.String.Data,
  3947. hIOPort->TPCB_Info[X25_FACILITIES_INDEX]);
  3948. pValue += pParam->P_Value.String.Length + 1;
  3949. pParam++;
  3950. strcpy(pParam->P_Key, CONNECTBPS_KEY);
  3951. pParam->P_Type = String;
  3952. pParam->P_Attributes = 0;
  3953. pParam->P_Value.String.Length =
  3954. strlen (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX]);
  3955. pParam->P_Value.String.Data = pValue;
  3956. strcpy(
  3957. pParam->P_Value.String.Data,
  3958. hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX]);
  3959. return(SUCCESS);
  3960. }
  3961. VOID
  3962. GetMutex (HANDLE mutex, DWORD to)
  3963. {
  3964. if (WaitForSingleObject (mutex, to) == WAIT_FAILED)
  3965. {
  3966. GetLastError() ;
  3967. DbgBreakPoint() ;
  3968. }
  3969. }
  3970. VOID
  3971. FreeMutex (HANDLE mutex)
  3972. {
  3973. if (!ReleaseMutex(mutex))
  3974. {
  3975. GetLastError () ;
  3976. DbgBreakPoint() ;
  3977. }
  3978. }
  3979. /*++
  3980. Routine Description:
  3981. Starts the disconnect process. Note even though
  3982. this covers SYNC completion of lineDrop this
  3983. is not per TAPI spec.
  3984. Arguments:
  3985. Return Value:
  3986. --*/
  3987. DWORD
  3988. InitiatePortDisconnection (TapiPortControlBlock *hIOPort)
  3989. {
  3990. DWORD retcode = SUCCESS;
  3991. hIOPort->TPCB_RequestId = INFINITE ;
  3992. RasTapiTrace("InitiatePortDisconnection: %s",
  3993. hIOPort->TPCB_Name );
  3994. if ( hIOPort->TPCB_dwFlags & RASTAPI_FLAG_DIALEDIN )
  3995. {
  3996. hIOPort->TPCB_dwFlags &= ~(RASTAPI_FLAG_DIALEDIN);
  3997. if (hIOPort->TPCB_Line->TLI_pDeviceInfo)
  3998. {
  3999. DeviceInfo * pDeviceInfo =
  4000. hIOPort->TPCB_Line->TLI_pDeviceInfo;
  4001. #if DBG
  4002. ASSERT(pDeviceInfo->dwCurrentDialedInClients > 0);
  4003. #endif
  4004. pDeviceInfo->dwCurrentDialedInClients -= 1;
  4005. RasTapiTrace(
  4006. "IntiatePortDisconnection: %s, "
  4007. "CurrenDialedInClients=0x%x",
  4008. hIOPort->TPCB_DeviceName,
  4009. pDeviceInfo->dwCurrentDialedInClients );
  4010. }
  4011. }
  4012. //
  4013. // For asyncmac/unimodem give a close indication to asyncmac if
  4014. // the endpoint is still valid
  4015. //
  4016. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0)
  4017. {
  4018. // tell asyncmac to close the link
  4019. //
  4020. if (hIOPort->TPCB_Endpoint != INVALID_HANDLE_VALUE)
  4021. {
  4022. ASYMAC_CLOSE AsyMacClose;
  4023. OVERLAPPED overlapped ;
  4024. DWORD dwBytesReturned ;
  4025. memset (&overlapped, 0, sizeof(OVERLAPPED)) ;
  4026. AsyMacClose.MacAdapter = NULL;
  4027. AsyMacClose.hNdisEndpoint = (HANDLE) hIOPort->TPCB_Endpoint ;
  4028. DeviceIoControl(g_hAsyMac,
  4029. IOCTL_ASYMAC_CLOSE,
  4030. &AsyMacClose,
  4031. sizeof(AsyMacClose),
  4032. &AsyMacClose,
  4033. sizeof(AsyMacClose),
  4034. &dwBytesReturned,
  4035. &overlapped);
  4036. hIOPort->TPCB_Endpoint = INVALID_HANDLE_VALUE ;
  4037. }
  4038. //
  4039. // Close the handle given by lineGetId on unimodem ports
  4040. //
  4041. if (hIOPort->TPCB_CommHandle != INVALID_HANDLE_VALUE)
  4042. {
  4043. CloseHandle (hIOPort->TPCB_CommHandle) ;
  4044. hIOPort->TPCB_CommHandle = INVALID_HANDLE_VALUE ;
  4045. }
  4046. }
  4047. //
  4048. // Handle the case where lineMakeCall is not yet
  4049. // complete and the callhandle is invalid
  4050. //
  4051. if (hIOPort->TPCB_CallHandle == (HCALL) INFINITE)
  4052. {
  4053. RasTapiTrace("InitiatePortDisconnect: Invalid CallHandle - hIOPort %p, State 0x%x",
  4054. hIOPort, hIOPort->TPCB_State);
  4055. if (!hIOPort->TPCB_Line->TLI_MultiEndpoint) {
  4056. RasTapiTrace ("InitiatePortDisconnect: Hammering LineClosed!");
  4057. lineClose (hIOPort->TPCB_Line->TLI_LineHandle) ;
  4058. Sleep (30L) ;
  4059. retcode = lineOpen (
  4060. RasLine,
  4061. hIOPort->TPCB_Line->TLI_LineId,
  4062. &hIOPort->TPCB_Line->TLI_LineHandle,
  4063. hIOPort->TPCB_Line->NegotiatedApiVersion,
  4064. hIOPort->TPCB_Line->NegotiatedExtVersion,
  4065. (DWORD_PTR) hIOPort->TPCB_Line,
  4066. LINECALLPRIVILEGE_OWNER,
  4067. hIOPort->TPCB_Line->TLI_MediaMode,
  4068. NULL) ;
  4069. if (retcode)
  4070. {
  4071. RasTapiTrace("InitiatePortDisconnection: %s."
  4072. " lineOpen Failed. 0x%x",
  4073. hIOPort->TPCB_Name,
  4074. retcode );
  4075. }
  4076. //
  4077. // Set monitoring of rings
  4078. //
  4079. lineSetStatusMessages (hIOPort->TPCB_Line->TLI_LineHandle,
  4080. LINEDEVSTATE_RINGING, 0) ;
  4081. RasTapiTrace(" ");
  4082. retcode = SUCCESS;
  4083. goto done;
  4084. } else {
  4085. //
  4086. // We need to do something here!
  4087. // Change the state?
  4088. // What about the callback case?
  4089. // Fix this post Win2K!
  4090. //
  4091. RasTapiTrace("InitiatePortDisconnect: Possible lost port: %p", hIOPort);
  4092. goto done;
  4093. }
  4094. }
  4095. //
  4096. // Initiate disconnection.
  4097. //
  4098. if ((hIOPort->TPCB_RequestId =
  4099. lineDrop (hIOPort->TPCB_CallHandle, NULL, 0))
  4100. > 0x80000000 )
  4101. {
  4102. RasTapiTrace("InitiatePortDisconnection: Error"
  4103. " issuing lineDrop for %s. 0x%x",
  4104. hIOPort->TPCB_Name,
  4105. hIOPort->TPCB_RequestId );
  4106. //
  4107. // Error issuing the linedrop. Should we try
  4108. // to deallocate anyway?
  4109. //
  4110. RasTapiTrace("InitiatePortDisconnection: Changing "
  4111. "state for %s from %d -> %d",
  4112. hIOPort->TPCB_Name,
  4113. hIOPort->TPCB_State,
  4114. PS_OPEN );
  4115. hIOPort->TPCB_State = PS_OPEN ;
  4116. hIOPort->TPCB_RequestId = INFINITE ;
  4117. lineDeallocateCall (hIOPort->TPCB_CallHandle) ;
  4118. RasTapiTrace(" ");
  4119. retcode = ERROR_DISCONNECTION;
  4120. goto done;
  4121. }
  4122. else if (hIOPort->TPCB_RequestId)
  4123. {
  4124. //
  4125. // The linedrop is completeing async
  4126. //
  4127. RasTapiTrace(
  4128. "InitiatePortDisconnection: Changing"
  4129. " state for %s from %d -> %d",
  4130. hIOPort->TPCB_Name,
  4131. hIOPort->TPCB_State,
  4132. PS_DISCONNECTING );
  4133. hIOPort->TPCB_State = PS_DISCONNECTING ;
  4134. RasTapiTrace(" ");
  4135. retcode = PENDING;
  4136. goto done;
  4137. }
  4138. else
  4139. {
  4140. //
  4141. // The linedrop completed sync
  4142. //
  4143. RasTapiTrace("InitiatePortDisconnection: %s. "
  4144. "linedrop completed sync.",
  4145. hIOPort->TPCB_Name );
  4146. hIOPort->TPCB_RequestId = INFINITE ;
  4147. if (hIOPort->IdleReceived)
  4148. {
  4149. RasTapiTrace(
  4150. "InitiatePortDisconnection: Changing"
  4151. " state for %s from %d -> %d",
  4152. hIOPort->TPCB_Name,
  4153. hIOPort->TPCB_State,
  4154. PS_OPEN );
  4155. hIOPort->IdleReceived = FALSE;
  4156. hIOPort->TPCB_State = PS_OPEN ;
  4157. lineDeallocateCall (hIOPort->TPCB_CallHandle) ;
  4158. hIOPort->TPCB_CallHandle = (HCALL) -1 ;
  4159. RasTapiTrace(" ");
  4160. retcode = SUCCESS;
  4161. goto done;
  4162. }
  4163. else
  4164. {
  4165. //
  4166. // Wait for IdleReceived
  4167. //
  4168. hIOPort->TPCB_State = PS_DISCONNECTING ;
  4169. retcode = PENDING;
  4170. goto done;
  4171. }
  4172. }
  4173. done:
  4174. if(hIOPort->TPCB_pConnectInfo)
  4175. {
  4176. LocalFree(hIOPort->TPCB_pConnectInfo);
  4177. hIOPort->TPCB_pConnectInfo = NULL;
  4178. }
  4179. return retcode;
  4180. }
  4181. VOID
  4182. UnloadRastapiDll()
  4183. {
  4184. //
  4185. // If DLL did not successfully initialize for
  4186. // this process
  4187. // dont try to clean up
  4188. //
  4189. if (!g_fDllLoaded)
  4190. {
  4191. return;
  4192. }
  4193. if (RasLine)
  4194. {
  4195. lineShutdown (RasLine) ;
  4196. RasLine = 0;
  4197. }
  4198. TraceDeregister( dwTraceId );
  4199. g_fDllLoaded = FALSE;
  4200. PostThreadMessage (TapiThreadId, WM_QUIT, 0, 0) ;
  4201. }
  4202. DWORD
  4203. SetCommSettings(TapiPortControlBlock *hIOPort,
  4204. RASMANCOMMSETTINGS *pSettings)
  4205. {
  4206. DCB dcb;
  4207. DWORD retcode = SUCCESS;
  4208. if(NULL == hIOPort)
  4209. {
  4210. RasTapiTrace("SetCommSettings: NULL hIOPort!");
  4211. retcode = E_INVALIDARG;
  4212. return retcode;
  4213. }
  4214. GetMutex(RasTapiMutex, INFINITE);
  4215. if (!GetCommState(hIOPort->TPCB_CommHandle, &dcb))
  4216. {
  4217. retcode = GetLastError();
  4218. RasTapiTrace(
  4219. "SetCommSettings: GetCommState failed for %s",
  4220. hIOPort->TPCB_Name);
  4221. RasTapiTrace(" ");
  4222. goto done;
  4223. }
  4224. dcb.ByteSize = pSettings->bByteSize;
  4225. dcb.StopBits = pSettings->bStop;
  4226. dcb.Parity = pSettings->bParity;
  4227. RasTapiTrace("SetCommSettings: setting parity=%d, stop=%d, data=%d",
  4228. pSettings->bParity,
  4229. pSettings->bStop,
  4230. pSettings->bByteSize);
  4231. if (!SetCommState(hIOPort->TPCB_CommHandle, &dcb))
  4232. {
  4233. retcode = GetLastError();
  4234. RasTapiTrace(
  4235. "SetCommSettings: SetCommState failed "
  4236. "for %s.handle=0x%x. %d",
  4237. hIOPort->TPCB_Name,
  4238. hIOPort->TPCB_CommHandle,
  4239. retcode);
  4240. RasTapiTrace(" ");
  4241. goto done;
  4242. }
  4243. done:
  4244. FreeMutex(RasTapiMutex);
  4245. RasTapiTrace("SetCommSettings: done. rc=0x%x",
  4246. retcode);
  4247. return retcode;
  4248. }
  4249. /*++
  4250. Routine Description:
  4251. This function uses the given handle to find
  4252. which TPCB is it refering to. This handle can be
  4253. either a pointer to TPCB itself (in case of non
  4254. unimodem devices) or it is the CommHandle for the
  4255. unimodem port. Consider: Adding a cache for
  4256. lookup speeding.
  4257. Arguments:
  4258. Return Value:
  4259. Nothing.
  4260. --*/
  4261. TapiPortControlBlock *
  4262. LookUpControlBlock (HANDLE hPort)
  4263. {
  4264. DWORD i ;
  4265. TapiPortControlBlock *pports = RasPortsList;
  4266. while ( pports )
  4267. {
  4268. if ( pports == ( TapiPortControlBlock * ) hPort
  4269. && ((TapiPortControlBlock *)hPort)->TPCB_Signature
  4270. == CONTROLBLOCKSIGNATURE)
  4271. {
  4272. return (TapiPortControlBlock *) hPort;
  4273. }
  4274. pports = pports->TPCB_next;
  4275. }
  4276. //
  4277. // hPort is the TPCB pointer
  4278. //
  4279. pports = RasPortsList;
  4280. //
  4281. // hPort is not the TPCB pointer - see if this
  4282. // matches any of the CommHandles
  4283. //
  4284. while ( pports )
  4285. {
  4286. if (pports->TPCB_CommHandle == hPort)
  4287. {
  4288. return pports ;
  4289. }
  4290. pports = pports->TPCB_next;
  4291. }
  4292. return NULL ;
  4293. }
  4294. /*++
  4295. Routine Description:
  4296. Converts a RAS_PARAMS P_Value, which may
  4297. be either a DWORD or a string, to a DWORD.
  4298. Arguments:
  4299. Return Value:
  4300. The numeric value of the input as a DWORD.
  4301. --*/
  4302. DWORD
  4303. ValueToNum(RAS_PARAMS *p)
  4304. {
  4305. CHAR szStr[RAS_MAXLINEBUFLEN];
  4306. if (p->P_Type == String)
  4307. {
  4308. strncpy(szStr,
  4309. p->P_Value.String.Data,
  4310. p->P_Value.String.Length);
  4311. szStr[p->P_Value.String.Length] = '\0';
  4312. return(atol(szStr));
  4313. }
  4314. else
  4315. {
  4316. return(p->P_Value.Number);
  4317. }
  4318. }