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

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