Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2148 lines
58 KiB

  1. //****************************************************************************
  2. //
  3. // Terminal Server CDmodem
  4. //
  5. //
  6. // Copyright 1996, Citrix Systems Inc.
  7. // Copyright (C) 1994-95 Microsft Corporation. All rights reserved.
  8. //
  9. // Filename: rastapi.c
  10. //
  11. // Revision History
  12. //
  13. // November 1998 updated by Qunbiao Guo for terminal server
  14. // Mar 28 1992 Gurdeep Singh Pall Created
  15. //
  16. //
  17. // Description: This file contains tapi codes for cdmodem.dll
  18. //
  19. //****************************************************************************
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <windows.h>
  24. #include <tapi.h>
  25. #include <rasndis.h>
  26. #include <wanioctl.h>
  27. #include <rasman.h>
  28. #include <raserror.h>
  29. #include <eventlog.h>
  30. #include <media.h>
  31. #include <device.h>
  32. #include <rasmxs.h>
  33. #include <isdn.h>
  34. #include <serial.h>
  35. #include <stdlib.h>
  36. #include <malloc.h>
  37. #include <string.h>
  38. #include "rastapi.h"
  39. #ifdef CITRIX
  40. #include <winstaw.h>
  41. #include <icadd.h>
  42. #include <icaapi.h>
  43. #include "cdmodem.h"
  44. #endif // CITRIX
  45. #ifdef CITRIX
  46. #ifdef DBG
  47. #define DBGPRINT(_arg) DbgPrint _arg
  48. #else
  49. #define DBGPRINT(_arg) { }
  50. #endif
  51. #endif // CITRIX
  52. #pragma warning (error:4312)
  53. extern DWORD TotalPorts ;
  54. extern HLINEAPP RasLine ;
  55. extern HINSTANCE RasInstance ;
  56. extern TapiLineInfo *RasTapiLineInfo ;
  57. extern TapiPortControlBlock *RasPorts ;
  58. extern TapiPortControlBlock *RasPortsEnd ;
  59. extern HANDLE RasTapiMutex ;
  60. extern BOOL Initialized ;
  61. extern DWORD TapiThreadId ;
  62. extern HANDLE TapiThreadHandle;
  63. extern DWORD LoaderThreadId;
  64. extern DWORD ValidPorts;
  65. extern HANDLE ghAsyMac ;
  66. DWORD GetInfo (TapiPortControlBlock *, BYTE *, WORD *) ;
  67. DWORD SetInfo (TapiPortControlBlock *, RASMAN_PORTINFO *) ;
  68. DWORD GetGenericParams (TapiPortControlBlock *, RASMAN_PORTINFO *, PWORD) ;
  69. DWORD GetIsdnParams (TapiPortControlBlock *, RASMAN_PORTINFO * , PWORD) ;
  70. DWORD GetX25Params (TapiPortControlBlock *, RASMAN_PORTINFO *, PWORD) ;
  71. DWORD FillInX25Params (TapiPortControlBlock *, RASMAN_PORTINFO *) ;
  72. DWORD FillInIsdnParams (TapiPortControlBlock *, RASMAN_PORTINFO *) ;
  73. DWORD FillInGenericParams (TapiPortControlBlock *, RASMAN_PORTINFO *) ;
  74. DWORD FillInUnimodemParams (TapiPortControlBlock *, RASMAN_PORTINFO *) ;
  75. VOID SetModemParams (TapiPortControlBlock *hIOPort, LINECALLPARAMS *linecallparams) ;
  76. DWORD InitiatePortDisconnection (TapiPortControlBlock *hIOPort) ;
  77. TapiPortControlBlock *LookUpControlBlock (HANDLE hPort) ;
  78. DWORD ValueToNum(RAS_PARAMS *p) ;
  79. //* Serial APIs ************************************************************
  80. //
  81. //* PortEnum ---------------------------------------------------------------
  82. //
  83. // Function: This API returns a buffer containing a PortMediaInfo struct.
  84. //
  85. // Returns: SUCCESS
  86. // ERROR_BUFFER_TOO_SMALL
  87. // ERROR_READING_SECTIONNAME
  88. // ERROR_READING_DEVICETYPE
  89. // ERROR_READING_DEVICENAME
  90. // ERROR_READING_USAGE
  91. // ERROR_BAD_USAGE_IN_INI_FILE
  92. //
  93. //*
  94. DWORD APIENTRY
  95. PortEnum(PCDMODEM pCdModem, BYTE *pBuffer, WORD *pwSize, WORD *pwNumPorts)
  96. {
  97. PortMediaInfo *pinfo ;
  98. TapiPortControlBlock *pports ;
  99. DWORD numports = 0;
  100. DWORD i ;
  101. DBGPRINT(( "CDMODEM: PortEnum: Entry\n" ));
  102. // **** Exclusion Begin ****
  103. GetMutex (RasTapiMutex, INFINITE) ;
  104. DBGPRINT(( "CDMODEM: PortEnum: Lock obtained\n" ));
  105. if (!Initialized) {
  106. HANDLE event;
  107. LoaderThreadId = GetCurrentThreadId();
  108. event = CreateEvent (NULL, FALSE, FALSE, NULL) ;
  109. TapiThreadHandle = CreateThread (NULL, 5000, (LPTHREAD_START_ROUTINE) EnumerateTapiPorts,
  110. (LPVOID) event,
  111. 0,
  112. &TapiThreadId);
  113. DBGPRINT(( "CDMODEM: PortEnum: waiting for ETP thread..." ));
  114. IcaCdWaitForSingleObject (pCdModem->hStack, event, INFINITE) ;
  115. DBGPRINT(( "complete\n" ));
  116. if (RasLine == 0 || !ValidPorts) {
  117. //
  118. // Wait for the thread to go away!
  119. //
  120. DBGPRINT(( "CDMODEM: PortEnum: ETP didn't init waitin..." ));
  121. IcaCdWaitForSingleObject(pCdModem->hStack, TapiThreadHandle, INFINITE);
  122. DBGPRINT(( "complete\n" ));
  123. CloseHandle (TapiThreadHandle) ;
  124. // *** Exclusion End ***
  125. FreeMutex (RasTapiMutex) ;
  126. return ERROR_TAPI_CONFIGURATION ;
  127. }
  128. CloseHandle (event) ;
  129. Initialized = TRUE ;
  130. }
  131. DBGPRINT(( "CDMODEM: PortEnum: TAPI init complete\n" ));
  132. // calculate the number of valid ports
  133. //
  134. for (pports = RasPorts, i=0; i < TotalPorts; i++, pports++) {
  135. if (pports->TPCB_State == PS_UNINITIALIZED)
  136. continue ;
  137. numports++ ;
  138. }
  139. if (*pwSize < numports*sizeof(PortMediaInfo)) {
  140. *pwNumPorts = (WORD) numports ;
  141. *pwSize = (WORD) *pwNumPorts*sizeof(PortMediaInfo) ;
  142. // *** Exclusion End ***
  143. FreeMutex (RasTapiMutex) ;
  144. return ERROR_BUFFER_TOO_SMALL ;
  145. }
  146. *pwNumPorts = 0 ;
  147. pinfo = (PortMediaInfo *)pBuffer ;
  148. for (pports = RasPorts, i=0; i < TotalPorts; i++, pports++) {
  149. if (pports->TPCB_State == PS_UNINITIALIZED)
  150. continue ;
  151. strcpy (pinfo->PMI_Name, pports->TPCB_Name) ;
  152. pinfo->PMI_Usage = pports->TPCB_Usage ;
  153. strcpy (pinfo->PMI_DeviceType, pports->TPCB_DeviceType) ;
  154. strcpy (pinfo->PMI_DeviceName, pports->TPCB_DeviceName) ;
  155. pinfo->PMI_LineDeviceId = pports->TPCB_Line->TLI_LineId;
  156. pinfo->PMI_AddressId = pports->TPCB_AddressId;
  157. pinfo++ ;
  158. (*pwNumPorts)++ ;
  159. }
  160. // *** Exclusion End ***
  161. FreeMutex (RasTapiMutex) ;
  162. return(SUCCESS);
  163. }
  164. //* PortOpen ---------------------------------------------------------------
  165. //
  166. // Function: This API opens a COM port. It takes the port name in ASCIIZ
  167. // form and supplies a handle to the open port. hNotify is use
  168. // to notify the caller if the device on the port shuts down.
  169. //
  170. // PortOpen allocates a SerialPCB and places it at the head of
  171. // the linked list of Serial Port Control Blocks.
  172. //
  173. // Returns: SUCCESS
  174. // ERROR_PORT_NOT_CONFIGURED
  175. // ERROR_DEVICE_NOT_READY
  176. //
  177. //*
  178. DWORD APIENTRY
  179. PortOpen(char *pszPortName, HANDLE *phIOPort, HANDLE hNotify)
  180. {
  181. TapiPortControlBlock *pports ;
  182. DWORD retcode ;
  183. DWORD i ;
  184. // **** Exclusion Begin ****
  185. GetMutex (RasTapiMutex, INFINITE) ;
  186. pports = RasPorts ;
  187. for (i=0; i < TotalPorts; i++) {
  188. if (_stricmp(pszPortName, pports->TPCB_Name) == 0)
  189. break ;
  190. pports++ ;
  191. }
  192. if (i < TotalPorts) {
  193. if (pports->TPCB_State == PS_UNINITIALIZED) {
  194. // **** Exclusion END ****
  195. FreeMutex (RasTapiMutex) ;
  196. return ERROR_TAPI_CONFIGURATION ;
  197. }
  198. if (pports->TPCB_State != PS_CLOSED) {
  199. // **** Exclusion END ****
  200. FreeMutex (RasTapiMutex) ;
  201. return ERROR_PORT_ALREADY_OPEN ;
  202. }
  203. if (pports->TPCB_Line->TLI_LineState == PS_CLOSED) { // open line
  204. LINEDEVCAPS *linedevcaps ;
  205. BYTE buffer[400] ;
  206. linedevcaps = (LINEDEVCAPS *)buffer ;
  207. linedevcaps->dwTotalSize = sizeof (buffer) ;
  208. lineGetDevCaps (RasLine, pports->TPCB_Line->TLI_LineId, pports->TPCB_Line->NegotiatedApiVersion, pports->TPCB_Line->NegotiatedExtVersion, linedevcaps) ;
  209. // Remove LINEMEDIAMODE_INTERACTIVEVOICE from the media mode since this mode cannot be
  210. // used for receiving calls.
  211. //
  212. pports->TPCB_MediaMode = linedevcaps->dwMediaModes & ~(LINEMEDIAMODE_INTERACTIVEVOICE) ;
  213. retcode =
  214. lineOpen (RasLine,
  215. pports->TPCB_Line->TLI_LineId,
  216. &pports->TPCB_Line->TLI_LineHandle,
  217. pports->TPCB_Line->NegotiatedApiVersion,
  218. pports->TPCB_Line->NegotiatedExtVersion,
  219. (ULONG) (ULONG_PTR)pports->TPCB_Line,
  220. LINECALLPRIVILEGE_OWNER,
  221. pports->TPCB_MediaMode,
  222. NULL) ;
  223. if (retcode) {
  224. // **** Exclusion END ****
  225. FreeMutex (RasTapiMutex) ;
  226. return retcode ;
  227. }
  228. //
  229. // Set monitoring of rings
  230. //
  231. lineSetStatusMessages (pports->TPCB_Line->TLI_LineHandle, LINEDEVSTATE_RINGING, 0) ;
  232. //
  233. // Always turn off the modem lights incase this is a modem device
  234. //
  235. if ((_stricmp (pports->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0)) {
  236. //
  237. // unimodem struct not defined in any header
  238. //
  239. typedef struct _DEVCFG {
  240. DWORD dwSize;
  241. DWORD dwVersion;
  242. WORD fwOptions;
  243. WORD wWaitBong;
  244. } DEVCFG;
  245. #define LAUNCH_LIGHTS 8
  246. LPVARSTRING var ;
  247. BYTE buffer[1000] ;
  248. DEVCFG *devcfg ;
  249. var = (LPVARSTRING)buffer ;
  250. var->dwTotalSize = 1000 ;
  251. var->dwStringSize = 0 ;
  252. lineGetDevConfig (pports->TPCB_Line->TLI_LineId, var, "comm/datamodem") ;
  253. devcfg = (DEVCFG*) (((LPBYTE) var) + var->dwStringOffset) ;
  254. devcfg->fwOptions &= ~LAUNCH_LIGHTS ;
  255. lineSetDevConfig (pports->TPCB_Line->TLI_LineId, devcfg, var->dwStringSize, "comm/datamodem") ;
  256. }
  257. pports->TPCB_Line->TLI_LineState = PS_OPEN ;
  258. }
  259. // Initialize the parameters
  260. //
  261. pports->TPCB_Info[0][0] = '\0' ;
  262. pports->TPCB_Info[1][0] = '\0' ;
  263. pports->TPCB_Info[2][0] = '\0' ;
  264. pports->TPCB_Info[3][0] = '\0' ;
  265. pports->TPCB_Info[4][0] = '\0' ;
  266. strcpy (pports->TPCB_Info[ISDN_CONNECTBPS_INDEX], "64000") ;
  267. pports->TPCB_Line->TLI_OpenCount++ ;
  268. pports->TPCB_DiscNotificationHandle = hNotify ;
  269. // DbgPrint ("RASTAPI: TPCB_DiscNotificationHandle == %x\n", pports->TPCB_DiscNotificationHandle) ;
  270. pports->TPCB_State = PS_OPEN ;
  271. pports->TPCB_DisconnectReason = 0 ;
  272. pports->TPCB_CommHandle = INVALID_HANDLE_VALUE ;
  273. *phIOPort = (HANDLE) pports ;
  274. // **** Exclusion END ****
  275. FreeMutex (RasTapiMutex) ;
  276. return(SUCCESS);
  277. }
  278. // **** Exclusion END ****
  279. FreeMutex (RasTapiMutex) ;
  280. return ERROR_PORT_NOT_CONFIGURED ;
  281. }
  282. //* PortClose --------------------------------------------------------------
  283. //
  284. // Function: This API closes the COM port for the input handle. It also
  285. // finds the SerialPCB for the input handle, removes it from
  286. // the linked list, and frees the memory for it
  287. //
  288. // Returns: SUCCESS
  289. // Values returned by GetLastError()
  290. //
  291. //*
  292. DWORD APIENTRY
  293. PortClose (HANDLE hIOPort)
  294. {
  295. TapiPortControlBlock *pports = (TapiPortControlBlock *) hIOPort ;
  296. // **** Exclusion Begin ****
  297. GetMutex (RasTapiMutex, INFINITE) ;
  298. pports->TPCB_Line->TLI_OpenCount-- ;
  299. pports->TPCB_State = PS_CLOSED ;
  300. if (pports->TPCB_DevConfig)
  301. LocalFree (pports->TPCB_DevConfig) ;
  302. pports->TPCB_DevConfig = NULL ;
  303. if (pports->TPCB_Line->TLI_OpenCount == 0) {
  304. pports->TPCB_Line->TLI_LineState = PS_CLOSED ;
  305. lineClose (pports->TPCB_Line->TLI_LineHandle) ;
  306. }
  307. // **** Exclusion END ****
  308. FreeMutex (RasTapiMutex) ;
  309. return(SUCCESS);
  310. }
  311. //* PortGetInfo ------------------------------------------------------------
  312. //
  313. // Function: This API returns a block of information to the caller about
  314. // the port state. This API may be called before the port is
  315. // open in which case it will return inital default values
  316. // instead of actual port values.
  317. //
  318. // hIOPort can be null in which case use portname to give information
  319. // hIOPort may be the actual file handle or the hIOPort returned in port open.
  320. //
  321. // Returns: SUCCESS
  322. //
  323. //*
  324. DWORD APIENTRY
  325. PortGetInfo(HANDLE hIOPort, CHAR *pszPortName, BYTE *pBuffer, WORD *pwSize)
  326. {
  327. DWORD i ;
  328. DWORD retcode = ERROR_FROM_DEVICE ;
  329. // **** Exclusion Begin ****
  330. GetMutex (RasTapiMutex, INFINITE) ;
  331. // hIOPort or pszPortName must be valid:
  332. //
  333. for (i=0; i < TotalPorts; i++) {
  334. if (!_stricmp(RasPorts[i].TPCB_Name, pszPortName) || (hIOPort == (HANDLE) &RasPorts[i]) || (hIOPort == RasPorts[i].TPCB_CommHandle)) {
  335. hIOPort = (HANDLE) &RasPorts[i] ;
  336. retcode = GetInfo ((TapiPortControlBlock *) hIOPort, pBuffer, pwSize) ;
  337. break ;
  338. }
  339. }
  340. // **** Exclusion END ****
  341. FreeMutex (RasTapiMutex) ;
  342. return (retcode);
  343. }
  344. //* PortSetInfo ------------------------------------------------------------
  345. //
  346. // Function: The values for most input keys are used to set the port
  347. // parameters directly. However, the carrier BPS and the
  348. // error conrol on flag set fields in the Serial Port Control
  349. // Block only, and not the port.
  350. //
  351. // hIOPort may the port handle returned in portopen or the actual file handle.
  352. //
  353. // Returns: SUCCESS
  354. // ERROR_WRONG_INFO_SPECIFIED
  355. // Values returned by GetLastError()
  356. //*
  357. DWORD APIENTRY
  358. PortSetInfo(HANDLE hIOPort, RASMAN_PORTINFO *pInfo)
  359. {
  360. DWORD retcode = ERROR_WRONG_INFO_SPECIFIED ;
  361. // **** Exclusion Begin ****
  362. GetMutex (RasTapiMutex, INFINITE) ;
  363. if (hIOPort = LookUpControlBlock(hIOPort)) {
  364. retcode = SetInfo ((TapiPortControlBlock *) hIOPort, pInfo) ;
  365. }
  366. // **** Exclusion END ****
  367. FreeMutex (RasTapiMutex) ;
  368. return (retcode);
  369. }
  370. //* PortTestSignalState ----------------------------------------------------
  371. //
  372. // Function: Really only has meaning if the call was active. Will return
  373. //
  374. // Returns: SUCCESS
  375. // Values returned by GetLastError()
  376. //
  377. //*
  378. DWORD APIENTRY
  379. PortTestSignalState(HANDLE hPort, DWORD *pdwDeviceState)
  380. {
  381. BYTE buffer[200] ;
  382. LINECALLSTATUS *pcallstatus ;
  383. DWORD retcode = SUCCESS ;
  384. TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
  385. // **** Exclusion Begin ****
  386. GetMutex (RasTapiMutex, INFINITE) ;
  387. *pdwDeviceState = 0 ;
  388. memset (buffer, 0, sizeof(buffer)) ;
  389. pcallstatus = (LINECALLSTATUS *) buffer ;
  390. pcallstatus->dwTotalSize = sizeof (buffer) ;
  391. // First check if we have a disconnect reason stored away. if so return that.
  392. //
  393. if (hIOPort->TPCB_DisconnectReason) {
  394. *pdwDeviceState = hIOPort->TPCB_DisconnectReason ;
  395. } else if (hIOPort->TPCB_State != PS_CLOSED) {
  396. // Only in case of CONNECTING or CONNECTED do we care how the link dropped
  397. //
  398. if (hIOPort->TPCB_State == PS_CONNECTING || hIOPort->TPCB_State == PS_CONNECTED) {
  399. retcode = lineGetCallStatus (hIOPort->TPCB_CallHandle, pcallstatus) ;
  400. if (retcode)
  401. ;
  402. else if (pcallstatus->dwCallState == LINECALLSTATE_DISCONNECTED)
  403. *pdwDeviceState = SS_LINKDROPPED ;
  404. else if (pcallstatus->dwCallState == LINECALLSTATE_IDLE)
  405. *pdwDeviceState = SS_HARDWAREFAILURE ;
  406. else if (pcallstatus->dwCallState == LINECALLSTATE_SPECIALINFO)
  407. *pdwDeviceState = SS_HARDWAREFAILURE ;
  408. } else
  409. *pdwDeviceState = SS_LINKDROPPED | SS_HARDWAREFAILURE ;
  410. }
  411. // **** Exclusion END ****
  412. FreeMutex (RasTapiMutex) ;
  413. return retcode ;
  414. }
  415. //* PortDisconnect ---------------------------------------------------------
  416. //
  417. // Function: This API is called to drop a connection and close AsyncMac.
  418. //
  419. // Returns: SUCCESS
  420. // PENDING
  421. // ERROR_PORT_NOT_OPEN
  422. //
  423. //*
  424. DWORD APIENTRY
  425. PortDisconnect(HANDLE hPort)
  426. {
  427. DWORD retcode = SUCCESS ;
  428. TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
  429. // **** Exclusion Begin ****
  430. GetMutex (RasTapiMutex, INFINITE) ;
  431. // DbgPrint ("PortDisconnect, state = %d\n", hIOPort->TPCB_State) ;
  432. if ((hIOPort->TPCB_State == PS_CONNECTED) ||
  433. (hIOPort->TPCB_State == PS_CONNECTING) ||
  434. ((hIOPort->TPCB_State == PS_LISTENING) && (hIOPort->TPCB_ListenState != LS_WAIT))) {
  435. retcode = InitiatePortDisconnection (hIOPort) ;
  436. // If we had saved away the device config then we restore it here.
  437. //
  438. if (hIOPort->TPCB_DefaultDevConfig) {
  439. lineSetDevConfig (hIOPort->TPCB_Line->TLI_LineId, hIOPort->TPCB_DefaultDevConfig, hIOPort->TPCB_DefaultDevConfigSize, "comm/datamodem") ;
  440. LocalFree (hIOPort->TPCB_DefaultDevConfig) ;
  441. hIOPort->TPCB_DefaultDevConfig = NULL ;
  442. }
  443. } else if (hIOPort->TPCB_State == PS_LISTENING) {
  444. hIOPort->TPCB_State = PS_OPEN ; // for LS_WAIT listen state case
  445. retcode = SUCCESS ;
  446. } else if (hIOPort->TPCB_State == PS_DISCONNECTING) {
  447. retcode = PENDING ;
  448. }
  449. // **** Exclusion END ****
  450. FreeMutex (RasTapiMutex) ;
  451. return retcode ;
  452. }
  453. //* PortInit ---------------------------------------------------------------
  454. //
  455. // Function: This API re-initializes the com port after use.
  456. //
  457. // Returns: SUCCESS
  458. // ERROR_PORT_NOT_CONFIGURED
  459. // ERROR_DEVICE_NOT_READY
  460. //
  461. //*
  462. DWORD APIENTRY
  463. PortInit(HANDLE hIOPort)
  464. {
  465. return(SUCCESS);
  466. }
  467. //* PortCompressionSetInfo -------------------------------------------------
  468. //
  469. // Function: This API selects Asyncmac compression mode by setting
  470. // Asyncmac's compression bits.
  471. //
  472. // Returns: SUCCESS
  473. // Return code from GetLastError
  474. //
  475. //*
  476. DWORD
  477. PortCompressionSetInfo(HANDLE hIOPort)
  478. {
  479. return SUCCESS;
  480. }
  481. //* PortClearStatistics ----------------------------------------------------
  482. //
  483. // Function: This API is used to mark the beginning of the period for which
  484. // statistics will be reported. The current numbers are copied
  485. // from the MAC and stored in the Serial Port Control Block. At
  486. // the end of the period PortGetStatistics will be called to
  487. // compute the difference.
  488. //
  489. // Returns: SUCCESS
  490. // ERROR_PORT_NOT_OPEN
  491. //*
  492. DWORD
  493. PortClearStatistics(HANDLE hIOPort)
  494. {
  495. return SUCCESS;
  496. }
  497. //* PortGetStatistics ------------------------------------------------------
  498. //
  499. // Function: This API reports MAC statistics since the last call to
  500. // PortClearStatistics.
  501. //
  502. // Returns: SUCCESS
  503. // ERROR_PORT_NOT_OPEN
  504. //*
  505. DWORD
  506. PortGetStatistics(HANDLE hIOPort, RAS_STATISTICS *pStat)
  507. {
  508. return(SUCCESS);
  509. }
  510. //* PortSetFraming -------------------------------------------------------
  511. //
  512. // Function: Sets the framing type with the mac
  513. //
  514. // Returns: SUCCESS
  515. //
  516. //*
  517. DWORD APIENTRY
  518. PortSetFraming(HANDLE hIOPort, DWORD SendFeatureBits, DWORD RecvFeatureBits,
  519. DWORD SendBitMask, DWORD RecvBitMask)
  520. {
  521. return(SUCCESS);
  522. }
  523. //* PortGetPortState -------------------------------------------------------
  524. //
  525. // Function: This API is used in MS-DOS only.
  526. //
  527. // Returns: SUCCESS
  528. //
  529. //*
  530. DWORD APIENTRY
  531. PortGetPortState(char *pszPortName, DWORD *pdwUsage)
  532. {
  533. return(SUCCESS);
  534. }
  535. //* PortChangeCallback -----------------------------------------------------
  536. //
  537. // Function: This API is used in MS-DOS only.
  538. //
  539. // Returns: SUCCESS
  540. //
  541. //*
  542. DWORD APIENTRY
  543. PortChangeCallback(HANDLE hIOPort)
  544. {
  545. return(SUCCESS);
  546. }
  547. //* PortGetIOHandle()
  548. //
  549. // Function: For the given hIOPort this returns the file handle for the connection
  550. //
  551. // Returns: SUCCESS
  552. //
  553. //*
  554. DWORD APIENTRY
  555. PortGetIOHandle(HANDLE hPort, HANDLE *FileHandle)
  556. {
  557. DWORD retcode ;
  558. TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
  559. // **** Exclusion Begin ****
  560. GetMutex (RasTapiMutex, INFINITE) ;
  561. if (hIOPort->TPCB_State == PS_CONNECTED) {
  562. *FileHandle = hIOPort->TPCB_CommHandle ;
  563. retcode = SUCCESS ;
  564. } else
  565. retcode = ERROR_PORT_NOT_OPEN ;
  566. // **** Exclusion Begin ****
  567. FreeMutex (RasTapiMutex) ;
  568. return retcode ;
  569. }
  570. //* DeviceEnum() -----------------------------------------------------------
  571. //
  572. // Function: Enumerates all devices in the device INF file for the
  573. // specified DevictType.
  574. //
  575. // Returns: Return codes from RasDevEnumDevices
  576. //
  577. //*
  578. DWORD APIENTRY
  579. DeviceEnum (char *pszDeviceType,
  580. WORD *pcEntries,
  581. BYTE *pBuffer,
  582. WORD *pwSize)
  583. {
  584. *pwSize = 0 ;
  585. *pcEntries = 0 ;
  586. return(SUCCESS);
  587. }
  588. //* DeviceGetInfo() --------------------------------------------------------
  589. //
  590. // Function: Returns a summary of current information from the InfoTable
  591. // for the device on the port in Pcb.
  592. //
  593. // Returns: Return codes from GetDeviceCB, BuildOutputTable
  594. //*
  595. DWORD APIENTRY
  596. DeviceGetInfo(HANDLE hPort,
  597. char *pszDeviceType,
  598. char *pszDeviceName,
  599. BYTE *pInfo,
  600. WORD *pwSize)
  601. {
  602. DWORD retcode ;
  603. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  604. if (!hIOPort)
  605. return ERROR_PORT_NOT_FOUND ;
  606. // **** Exclusion Begin ****
  607. GetMutex (RasTapiMutex, INFINITE) ;
  608. retcode = GetInfo (hIOPort, pInfo, pwSize) ;
  609. // **** Exclusion End ****
  610. FreeMutex (RasTapiMutex) ;
  611. return(retcode);
  612. }
  613. //* DeviceSetInfo() --------------------------------------------------------
  614. //
  615. // Function: Sets attributes in the InfoTable for the device on the
  616. // port in Pcb.
  617. //
  618. // Returns: Return codes from GetDeviceCB, UpdateInfoTable
  619. //*
  620. DWORD APIENTRY
  621. DeviceSetInfo(HANDLE hPort,
  622. char *pszDeviceType,
  623. char *pszDeviceName,
  624. RASMAN_DEVICEINFO *pInfo)
  625. {
  626. DWORD retcode ;
  627. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  628. if (!hIOPort)
  629. return ERROR_PORT_NOT_FOUND ;
  630. // **** Exclusion Begin ****
  631. GetMutex (RasTapiMutex, INFINITE) ;
  632. retcode = SetInfo (hIOPort, (RASMAN_PORTINFO*) pInfo) ;
  633. // **** Exclusion End ****
  634. FreeMutex (RasTapiMutex) ;
  635. return (retcode);
  636. }
  637. //* DeviceConnect() --------------------------------------------------------
  638. //
  639. // Function: Initiates the process of connecting a device.
  640. //
  641. // Returns: Return codes from ConnectListen
  642. //*
  643. DWORD APIENTRY
  644. DeviceConnect(HANDLE hPort,
  645. char *pszDeviceType,
  646. char *pszDeviceName,
  647. HANDLE hNotifier)
  648. {
  649. LINECALLPARAMS *linecallparams ;
  650. LPVARSTRING var ;
  651. BYTE buffer [2000] ;
  652. BYTE *nextstring ;
  653. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  654. if (!hIOPort)
  655. return ERROR_PORT_NOT_FOUND ;
  656. // **** Exclusion Begin ****
  657. GetMutex (RasTapiMutex, INFINITE) ;
  658. // if dev config has been set for this device we should call down and set it.
  659. //
  660. if ((hIOPort->TPCB_DevConfig) && (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0)) {
  661. // Before the write this - save away the current setting for the device.
  662. //
  663. var = (LPVARSTRING)buffer ;
  664. var->dwTotalSize = 2000 ;
  665. var->dwStringSize = 0 ;
  666. lineGetDevConfig (hIOPort->TPCB_Line->TLI_LineId, var, "comm/datamodem") ;
  667. // Alloc mem for the returned info
  668. //
  669. hIOPort->TPCB_DefaultDevConfig = LocalAlloc (LPTR, var->dwStringSize) ;
  670. if (hIOPort->TPCB_DefaultDevConfig == NULL) {
  671. FreeMutex (RasTapiMutex) ;
  672. return ERROR_NOT_ENOUGH_MEMORY;
  673. }
  674. hIOPort->TPCB_DefaultDevConfigSize = var->dwStringSize ;
  675. memcpy (hIOPort->TPCB_DefaultDevConfig, (CHAR*)var+var->dwStringOffset, var->dwStringSize) ;
  676. lineSetDevConfig (hIOPort->TPCB_Line->TLI_LineId, hIOPort->TPCB_DevConfig, hIOPort->TPCB_SizeOfDevConfig, "comm/datamodem") ;
  677. }
  678. memset (buffer, 0, sizeof(buffer)) ;
  679. linecallparams = (LINECALLPARAMS *) buffer ;
  680. nextstring = (buffer + sizeof (LINECALLPARAMS)) ;
  681. linecallparams->dwTotalSize = sizeof(buffer) ;
  682. strcpy (nextstring, hIOPort->TPCB_Address) ;
  683. linecallparams->dwOrigAddressSize = strlen (nextstring) ;
  684. linecallparams->dwOrigAddressOffset = (ULONG) (nextstring - buffer) ;
  685. linecallparams->dwAddressMode = LINEADDRESSMODE_DIALABLEADDR ;
  686. nextstring += linecallparams->dwOrigAddressSize ;
  687. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_ISDN) == 0)
  688. SetIsdnParams (hIOPort, linecallparams) ;
  689. else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_X25) == 0) {
  690. if (*hIOPort->TPCB_Info[X25_USERDATA_INDEX] != '\0') {
  691. strcpy (nextstring, hIOPort->TPCB_Info[X25_USERDATA_INDEX]) ;
  692. linecallparams->dwUserUserInfoSize = strlen (nextstring) ;
  693. linecallparams->dwUserUserInfoOffset = (ULONG) (nextstring - buffer) ;
  694. nextstring += linecallparams->dwUserUserInfoSize ;
  695. }
  696. if (*hIOPort->TPCB_Info[X25_FACILITIES_INDEX] != '\0') {
  697. strcpy (nextstring, hIOPort->TPCB_Info[X25_FACILITIES_INDEX]) ;
  698. linecallparams->dwDevSpecificSize = strlen (nextstring) ;
  699. linecallparams->dwDevSpecificOffset = (ULONG) (nextstring - buffer) ;
  700. nextstring += linecallparams->dwDevSpecificSize ;
  701. }
  702. // Diagnostic key is ignored.
  703. } else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0) {
  704. SetModemParams (hIOPort, linecallparams) ;
  705. }
  706. hIOPort->TPCB_RequestId = INFINITE ; // mark request id as unused
  707. hIOPort->TPCB_CallHandle = (HCALL) INFINITE ; // set call handle to bogus value
  708. hIOPort->TPCB_AsyncErrorCode = SUCCESS ; // initialize
  709. if ((hIOPort->TPCB_RequestId =
  710. lineMakeCall (hIOPort->TPCB_Line->TLI_LineHandle, &hIOPort->TPCB_CallHandle, hIOPort->TPCB_Info[ADDRESS_INDEX], 0, linecallparams)) > 0x80000000 ) {
  711. // **** Exclusion End ****
  712. FreeMutex (RasTapiMutex) ;
  713. // DbgPrint ("RASTAPI: lineMakeCall failed -> returned %x\n", hIOPort->TPCB_RequestId) ;
  714. if (hIOPort->TPCB_RequestId == LINEERR_INUSE)
  715. return ERROR_PORT_NOT_AVAILABLE ;
  716. return ERROR_FROM_DEVICE ;
  717. }
  718. ResetEvent (hNotifier) ;
  719. hIOPort->TPCB_ReqNotificationHandle = hNotifier ;
  720. hIOPort->TPCB_State = PS_CONNECTING ;
  721. hIOPort->TPCB_DisconnectReason = 0 ;
  722. // **** Exclusion End ****
  723. FreeMutex (RasTapiMutex) ;
  724. return (PENDING);
  725. }
  726. //*
  727. //
  728. //
  729. //
  730. //
  731. //*
  732. VOID
  733. SetIsdnParams (TapiPortControlBlock *hIOPort, LINECALLPARAMS *linecallparams)
  734. {
  735. WORD numchannels ;
  736. WORD fallback ;
  737. #ifndef CITRIX
  738. // Line type
  739. //
  740. if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX], ISDN_LINETYPE_STRING_64DATA) == 0) {
  741. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  742. linecallparams->dwMinRate = 64000 ;
  743. linecallparams->dwMaxRate = 64000 ;
  744. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
  745. } else if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX], ISDN_LINETYPE_STRING_56DATA) == 0) {
  746. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  747. linecallparams->dwMinRate = 56000 ;
  748. linecallparams->dwMaxRate = 56000 ;
  749. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
  750. } else if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX], ISDN_LINETYPE_STRING_56VOICE) == 0) {
  751. linecallparams->dwBearerMode = LINEBEARERMODE_VOICE ;
  752. linecallparams->dwMinRate = 56000 ;
  753. linecallparams->dwMaxRate = 56000 ;
  754. linecallparams->dwMediaMode = LINEMEDIAMODE_UNKNOWN ;
  755. } else { // default
  756. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  757. linecallparams->dwMinRate = 64000 ;
  758. linecallparams->dwMaxRate = 64000 ;
  759. linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
  760. }
  761. if (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX][0] != '\0')
  762. numchannels = atoi(hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]) ;
  763. else
  764. numchannels = 1 ; // default
  765. if (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX] != '\0')
  766. fallback = atoi(hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]) ;
  767. else
  768. fallback = 1 ; // default
  769. if (fallback)
  770. linecallparams->dwMinRate = 56000 ; // always allow the min
  771. else
  772. linecallparams->dwMinRate = numchannels * linecallparams->dwMaxRate ;
  773. linecallparams->dwMaxRate = numchannels * linecallparams->dwMaxRate ;
  774. #else // CITRIX
  775. DBGPRINT(("CDMODEM: SetIsdnParams: ISDN not supported\n"));
  776. ASSERT(FALSE);
  777. #endif // CITRIX
  778. }
  779. //*
  780. //
  781. //
  782. //
  783. //
  784. //*
  785. VOID
  786. SetModemParams (TapiPortControlBlock *hIOPort, LINECALLPARAMS *linecallparams)
  787. {
  788. WORD numchannels ;
  789. WORD fallback ;
  790. BYTE buffer[800] ;
  791. LINEDEVCAPS *linedevcaps ;
  792. memset (buffer, 0, sizeof(buffer)) ;
  793. linedevcaps = (LINEDEVCAPS *)buffer ;
  794. linedevcaps->dwTotalSize = sizeof(buffer) ;
  795. // Get a count of all addresses across all lines
  796. //
  797. if (lineGetDevCaps (RasLine, hIOPort->TPCB_Line->TLI_LineId, hIOPort->TPCB_Line->NegotiatedApiVersion, hIOPort->TPCB_Line->NegotiatedExtVersion, linedevcaps))
  798. linecallparams->dwBearerMode = LINEBEARERMODE_VOICE ; // in case of failure try the common case - modems
  799. if (linedevcaps->dwBearerModes & LINEBEARERMODE_VOICE)
  800. linecallparams->dwBearerMode = LINEBEARERMODE_VOICE ;
  801. else
  802. linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
  803. //
  804. // do not dial without dialtone
  805. //
  806. linecallparams->dwCallParamFlags |= LINECALLPARAMFLAGS_IDLE ;
  807. linecallparams->dwMinRate = 2400 ;
  808. linecallparams->dwMaxRate = 115200 ;
  809. linecallparams->dwMediaMode = LINEMEDIAMODE_DATAMODEM ;
  810. }
  811. //* DeviceListen() ---------------------------------------------------------
  812. //
  813. // Function: Initiates the process of listening for a remote device
  814. // to connect to a local device.
  815. //
  816. // Returns: Return codes from ConnectListen
  817. //*
  818. DWORD APIENTRY
  819. DeviceListen(HANDLE hPort,
  820. char *pszDeviceType,
  821. char *pszDeviceName,
  822. HANDLE hNotifier)
  823. {
  824. DWORD retcode ;
  825. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  826. if (!hIOPort)
  827. return ERROR_PORT_NOT_FOUND ;
  828. // **** Exclusion Begin ****
  829. GetMutex (RasTapiMutex, INFINITE) ;
  830. // DbgPrint ("DevListen, State = %d\n", hIOPort->TPCB_State) ;
  831. // If the state is DISCONNECTING (this could happen since rasman waits only 10 seconds
  832. // for the lower layers to complete a disconnect request), then we have no option but
  833. // to close and open the line.
  834. //
  835. if (hIOPort->TPCB_State == PS_DISCONNECTING) {
  836. // DbgPrint ("DevListen: Hit code path where device is still disconnecting\n") ;
  837. lineClose (hIOPort->TPCB_Line->TLI_LineHandle) ;
  838. Sleep (30L) ; // allow a "reasonable" time to allow clean up.
  839. retcode = lineOpen (RasLine,
  840. hIOPort->TPCB_Line->TLI_LineId,
  841. &hIOPort->TPCB_Line->TLI_LineHandle,
  842. hIOPort->TPCB_Line->NegotiatedApiVersion,
  843. hIOPort->TPCB_Line->NegotiatedExtVersion,
  844. (ULONG) (ULONG_PTR) hIOPort->TPCB_Line,
  845. LINECALLPRIVILEGE_OWNER,
  846. hIOPort->TPCB_MediaMode,
  847. NULL) ;
  848. if (retcode) {
  849. // **** Exclusion End ****
  850. FreeMutex (RasTapiMutex) ;
  851. // DbgPrint ("DevListen: lineOpen failed with %d \n", retcode) ;
  852. return ERROR_FROM_DEVICE ;
  853. }
  854. //
  855. // Set monitoring of rings
  856. //
  857. lineSetStatusMessages (hIOPort->TPCB_Line->TLI_LineHandle, LINEDEVSTATE_RINGING, 0) ;
  858. }
  859. if (hIOPort->TPCB_Line->TLI_LineState != PS_LISTENING)
  860. hIOPort->TPCB_Line->TLI_LineState = PS_LISTENING ;
  861. hIOPort->TPCB_State = PS_LISTENING ;
  862. hIOPort->TPCB_ListenState = LS_WAIT ;
  863. hIOPort->TPCB_DisconnectReason = 0 ;
  864. ResetEvent (hNotifier) ;
  865. hIOPort->TPCB_ReqNotificationHandle = hNotifier ;
  866. hIOPort->TPCB_CallHandle = (HCALL)(ULONG_PTR)INVALID_HANDLE_VALUE ;
  867. // **** Exclusion End ****
  868. FreeMutex (RasTapiMutex) ;
  869. return (PENDING);
  870. }
  871. //* DeviceDone() -----------------------------------------------------------
  872. //
  873. // Function: Informs the device dll that the attempt to connect or listen
  874. // has completed.
  875. //
  876. // Returns: nothing
  877. //*
  878. VOID APIENTRY
  879. DeviceDone(HANDLE hPort)
  880. {
  881. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  882. if (!hIOPort)
  883. return ;
  884. // **** Exclusion Begin ****
  885. GetMutex (RasTapiMutex, INFINITE) ;
  886. hIOPort->TPCB_ReqNotificationHandle = NULL ; // no more needed.
  887. // **** Exclusion End ****
  888. FreeMutex (RasTapiMutex) ;
  889. }
  890. //* DeviceWork() -----------------------------------------------------------
  891. //
  892. // Function: This function is called following DeviceConnect or
  893. // DeviceListen to further the asynchronous process of
  894. // connecting or listening.
  895. //
  896. // Returns: ERROR_DCB_NOT_FOUND
  897. // ERROR_STATE_MACHINES_NOT_STARTED
  898. // Return codes from DeviceStateMachine
  899. //*
  900. DWORD APIENTRY
  901. DeviceWork(HANDLE hPort,
  902. HANDLE hNotifier)
  903. {
  904. LINECALLSTATUS *callstatus ;
  905. BYTE buffer [1000] ;
  906. DWORD retcode = ERROR_FROM_DEVICE ;
  907. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  908. if (!hIOPort)
  909. return ERROR_PORT_NOT_FOUND ;
  910. // **** Exclusion Begin ****
  911. GetMutex (RasTapiMutex, INFINITE) ;
  912. memset (buffer, 0, sizeof(buffer)) ;
  913. callstatus = (LINECALLSTATUS *)buffer ;
  914. callstatus->dwTotalSize = sizeof(buffer) ;
  915. DBGPRINT(("Devicework enter with ps status: %d \n", hIOPort->TPCB_State));
  916. if (hIOPort->TPCB_State == PS_CONNECTING) {
  917. if (hIOPort->TPCB_AsyncErrorCode != SUCCESS) {
  918. retcode = hIOPort->TPCB_AsyncErrorCode ;
  919. hIOPort->TPCB_AsyncErrorCode = SUCCESS ;
  920. } else if (lineGetCallStatus (hIOPort->TPCB_CallHandle, callstatus))
  921. retcode = ERROR_FROM_DEVICE ;
  922. else if (callstatus->dwCallState == LINECALLSTATE_CONNECTED) {
  923. hIOPort->TPCB_State = PS_CONNECTED ;
  924. retcode = SUCCESS ;
  925. } else if (callstatus->dwCallState == LINECALLSTATE_DISCONNECTED) {
  926. retcode = ERROR_FROM_DEVICE ;
  927. if (callstatus->dwCallStateMode == LINEDISCONNECTMODE_BUSY)
  928. retcode = ERROR_LINE_BUSY ;
  929. else if (callstatus->dwCallStateMode == LINEDISCONNECTMODE_NOANSWER)
  930. retcode = ERROR_NO_ANSWER ;
  931. else if (callstatus->dwCallStateMode == LINEDISCONNECTMODE_CANCELLED)
  932. retcode = ERROR_USER_DISCONNECTION;
  933. } else if ((callstatus->dwCallState == LINECALLSTATE_SPECIALINFO) &&
  934. (callstatus->dwCallStateMode == LINESPECIALINFO_NOCIRCUIT)) {
  935. retcode = ERROR_NO_ACTIVE_ISDN_LINES ;
  936. }
  937. }
  938. if (hIOPort->TPCB_State == PS_LISTENING) {
  939. DBGPRINT(("DEvicework PS listning, listeining status: %d \n", hIOPort->TPCB_ListenState));
  940. if (hIOPort->TPCB_ListenState == LS_ERROR)
  941. retcode = ERROR_FROM_DEVICE ;
  942. else if (hIOPort->TPCB_ListenState == LS_ACCEPT) {
  943. hIOPort->TPCB_RequestId = lineAccept (hIOPort->TPCB_CallHandle, NULL, 0) ;
  944. DBGPRINT(("Devicework lineAccept return status: 0x%x \n", hIOPort->TPCB_RequestId));
  945. DBGPRINT(("Devicework: change listening status from LS_ACCEPT to LS_ANSWER \n"));
  946. if (hIOPort->TPCB_RequestId > 0x80000000 ) // ERROR or SUCCESS
  947. hIOPort->TPCB_ListenState = LS_ANSWER ;
  948. else if (hIOPort->TPCB_RequestId == 0)
  949. hIOPort->TPCB_ListenState = LS_ANSWER ;
  950. retcode = PENDING ;
  951. }
  952. if (hIOPort->TPCB_ListenState == LS_ANSWER) {
  953. hIOPort->TPCB_RequestId = lineAnswer (hIOPort->TPCB_CallHandle, NULL, 0) ;
  954. DBGPRINT(("Devicework lineAnswer return status: 0x%x \n",
  955. hIOPort->TPCB_RequestId));
  956. if (hIOPort->TPCB_RequestId > 0x80000000 )
  957. retcode = ERROR_FROM_DEVICE ;
  958. else if (hIOPort->TPCB_RequestId)
  959. retcode = PENDING ;
  960. else // SUCCESS
  961. hIOPort->TPCB_ListenState = LS_COMPLETE ;
  962. }
  963. if (hIOPort->TPCB_ListenState == LS_COMPLETE) {
  964. DBGPRINT(("Devicework: LS_COMPLETE \n"));
  965. if (hIOPort->TPCB_CallHandle == (HCALL)(ULONG_PTR)INVALID_HANDLE_VALUE) {
  966. retcode = ERROR_FROM_DEVICE ;
  967. } else {
  968. hIOPort->TPCB_State = PS_CONNECTED ;
  969. retcode = SUCCESS ; //
  970. }
  971. }
  972. }
  973. // If we have connected, then get the com port handle for use in terminal modem i/o
  974. //
  975. if (hIOPort->TPCB_State == PS_CONNECTED) {
  976. VARSTRING *varstring ;
  977. BYTE buffer [100] ;
  978. // get the cookie to realize tapi and ndis endpoints
  979. //
  980. varstring = (VARSTRING *) buffer ;
  981. varstring->dwTotalSize = sizeof(buffer) ;
  982. // Unimodem/asyncmac linegetid returns a comm port handle. Other medias give the endpoint itself back in linegetid
  983. // This has to do with the fact that modems/asyncmac are not a miniport.
  984. //
  985. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0) {
  986. if (lineGetID (hIOPort->TPCB_Line->TLI_LineHandle, hIOPort->TPCB_AddressId, hIOPort->TPCB_CallHandle, LINECALLSELECT_CALL, varstring, "comm/datamodem")) {
  987. // **** Exclusion End ****
  988. FreeMutex (RasTapiMutex) ;
  989. return ERROR_FROM_DEVICE ;
  990. }
  991. hIOPort->TPCB_CommHandle = LongToHandle(*((DWORD *) ((BYTE *)varstring+varstring->dwStringOffset))) ;
  992. // Initialize the port for approp. buffers
  993. //
  994. SetupComm (hIOPort->TPCB_CommHandle, 1514, 1514) ;
  995. } else {
  996. if (lineGetID (hIOPort->TPCB_Line->TLI_LineHandle, hIOPort->TPCB_AddressId, hIOPort->TPCB_CallHandle, LINECALLSELECT_CALL, varstring, "NDIS")) {
  997. // **** Exclusion End ****
  998. FreeMutex (RasTapiMutex) ;
  999. return ERROR_FROM_DEVICE ;
  1000. }
  1001. hIOPort->TPCB_Endpoint = *((DWORD *) ((BYTE *)varstring+varstring->dwStringOffset)) ;
  1002. }
  1003. // DbgPrint ("L\n") ;
  1004. }
  1005. if (retcode == PENDING) {
  1006. DBGPRINT(("Devicework: Reset event \n"));
  1007. ResetEvent (hNotifier) ;
  1008. }
  1009. // **** Exclusion End ****
  1010. FreeMutex (RasTapiMutex) ;
  1011. return(retcode);
  1012. }
  1013. //* DeviceSetDevConfig()
  1014. //
  1015. // Function: Called to set an opaque blob of data to configure a device.
  1016. //
  1017. // Returns: LocalAlloc returned values.
  1018. //
  1019. DWORD
  1020. DeviceSetDevConfig (HANDLE hPort, PBYTE devconfig, DWORD sizeofdevconfig)
  1021. {
  1022. TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
  1023. if (!hIOPort)
  1024. return ERROR_PORT_NOT_FOUND ;
  1025. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM))
  1026. return SUCCESS ;
  1027. // **** Exclusion Begin ****
  1028. GetMutex (RasTapiMutex, INFINITE) ;
  1029. if (hIOPort->TPCB_DevConfig != NULL)
  1030. LocalFree (hIOPort->TPCB_DevConfig) ;
  1031. if ((hIOPort->TPCB_DevConfig = LocalAlloc(LPTR, sizeofdevconfig)) == NULL) {
  1032. // **** Exclusion End ****
  1033. FreeMutex (RasTapiMutex) ;
  1034. return(GetLastError());
  1035. }
  1036. memcpy (hIOPort->TPCB_DevConfig, devconfig, sizeofdevconfig) ;
  1037. hIOPort->TPCB_SizeOfDevConfig = sizeofdevconfig ;
  1038. // **** Exclusion End ****
  1039. FreeMutex (RasTapiMutex) ;
  1040. return (SUCCESS);
  1041. }
  1042. //* DeviceGetDevConfig()
  1043. //
  1044. // Function: Called to set an opaque blob of data to configure a device.
  1045. //
  1046. // Returns: LocalAlloc returned values.
  1047. //
  1048. DWORD
  1049. DeviceGetDevConfig (char *name, PBYTE devconfig, DWORD *sizeofdevconfig)
  1050. {
  1051. TapiPortControlBlock *hIOPort = NULL;
  1052. DWORD i ;
  1053. BYTE buffer[2000] ;
  1054. LPVARSTRING var ;
  1055. PBYTE configptr ;
  1056. DWORD configsize ;
  1057. DWORD retcode ;
  1058. // hIOPort or pszPortName must be valid:
  1059. //
  1060. for (i=0; i < TotalPorts; i++) {
  1061. if (!_stricmp(RasPorts[i].TPCB_Name, name)) {
  1062. hIOPort = (HANDLE) &RasPorts[i] ;
  1063. break ;
  1064. }
  1065. }
  1066. if (!hIOPort)
  1067. return ERROR_PORT_NOT_FOUND ;
  1068. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM)) {
  1069. *sizeofdevconfig = 0 ;
  1070. return SUCCESS ;
  1071. }
  1072. // **** Exclusion Begin ****
  1073. GetMutex (RasTapiMutex, INFINITE) ;
  1074. if (hIOPort->TPCB_DevConfig != NULL) {
  1075. configptr = hIOPort->TPCB_DevConfig ;
  1076. configsize = hIOPort->TPCB_SizeOfDevConfig ;
  1077. } else {
  1078. // Make var string
  1079. //
  1080. var = (LPVARSTRING)buffer ;
  1081. var->dwTotalSize = 2000 ;
  1082. var->dwStringSize = 0 ;
  1083. lineGetDevConfig (hIOPort->TPCB_Line->TLI_LineId, var, "comm/datamodem") ;
  1084. configptr = ((CHAR *)var + var->dwStringOffset) ;
  1085. configsize = var->dwStringSize ;
  1086. }
  1087. if (*sizeofdevconfig > configsize) {
  1088. memcpy (devconfig, configptr, configsize) ;
  1089. retcode = SUCCESS ;
  1090. } else
  1091. retcode = ERROR_BUFFER_TOO_SMALL ;
  1092. *sizeofdevconfig = configsize ;
  1093. // **** Exclusion End ****
  1094. FreeMutex (RasTapiMutex) ;
  1095. return (retcode);
  1096. }
  1097. //*
  1098. //
  1099. //
  1100. //
  1101. //*
  1102. DWORD
  1103. GetInfo (TapiPortControlBlock *hIOPort, BYTE *pBuffer, WORD *pwSize)
  1104. {
  1105. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_ISDN) == 0)
  1106. GetIsdnParams (hIOPort, (RASMAN_PORTINFO *) pBuffer, pwSize) ;
  1107. else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_X25) == 0)
  1108. GetX25Params (hIOPort, (RASMAN_PORTINFO *) pBuffer, pwSize) ;
  1109. else
  1110. GetGenericParams (hIOPort, (RASMAN_PORTINFO *) pBuffer, pwSize) ;
  1111. return SUCCESS ;
  1112. }
  1113. //* SetInfo()
  1114. //
  1115. //
  1116. //
  1117. //*
  1118. DWORD
  1119. SetInfo (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pBuffer)
  1120. {
  1121. DWORD Error;
  1122. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0)
  1123. Error = FillInUnimodemParams (hIOPort, pBuffer) ;
  1124. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_ISDN) == 0)
  1125. Error = FillInIsdnParams (hIOPort, pBuffer) ;
  1126. else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_X25) == 0)
  1127. Error = FillInX25Params (hIOPort, pBuffer) ;
  1128. else
  1129. Error = FillInGenericParams (hIOPort, pBuffer) ;
  1130. return Error ;
  1131. }
  1132. //* FillInUnimodemParams()
  1133. //
  1134. // Function: We do more than fill in the params if the params are ones that are required to be set
  1135. // right then.
  1136. //
  1137. // Returns: ERROR_WRONG_INFO_SPECIFIED.
  1138. // Comm related Win32 errors
  1139. // SUCCESS.
  1140. //*
  1141. DWORD
  1142. FillInUnimodemParams (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pInfo)
  1143. {
  1144. RAS_PARAMS *p;
  1145. WORD i;
  1146. DWORD index = 0xfefefefe ;
  1147. DCB DCB ;
  1148. #define INITIALIZED_VALUE 0xde
  1149. BYTE DCBByteSize = INITIALIZED_VALUE ;
  1150. BYTE DCBParity = INITIALIZED_VALUE ;
  1151. BYTE DCBStopBits = INITIALIZED_VALUE ;
  1152. BOOL DCBProcessingRequired = FALSE ;
  1153. for (i=0, p=pInfo->PI_Params; i<pInfo->PI_NumOfParams; i++, p++) {
  1154. if (_stricmp(p->P_Key, SER_DATABITS_KEY) == 0) {
  1155. DCBByteSize = (BYTE) ValueToNum(p);
  1156. DCBProcessingRequired = TRUE ;
  1157. } else if (_stricmp(p->P_Key, SER_PARITY_KEY) == 0) {
  1158. DCBParity = (BYTE) ValueToNum(p);
  1159. DCBProcessingRequired = TRUE ;
  1160. } else if (_stricmp(p->P_Key, SER_STOPBITS_KEY) == 0) {
  1161. DCBStopBits = (BYTE) ValueToNum(p);
  1162. DCBProcessingRequired = TRUE ;
  1163. }
  1164. //
  1165. // The fact we use ISDN_PHONENUMBER_KEY is not a bug. This is just a define.
  1166. //
  1167. else if (_stricmp(p->P_Key, ISDN_PHONENUMBER_KEY) == 0)
  1168. index = ADDRESS_INDEX ;
  1169. else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
  1170. index = CONNECTBPS_INDEX ;
  1171. else
  1172. return(ERROR_WRONG_INFO_SPECIFIED);
  1173. if (index != 0xfefefefe) {
  1174. strncpy (hIOPort->TPCB_Info[index], p->P_Value.String.Data, p->P_Value.String.Length);
  1175. hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
  1176. }
  1177. }
  1178. //
  1179. // For parameters that should be set right away - check that the port handle is still valid
  1180. // if so set the parameters.
  1181. //
  1182. if (DCBProcessingRequired && hIOPort->TPCB_CommHandle != INVALID_HANDLE_VALUE) {
  1183. //
  1184. // Get a Device Control Block with current port values
  1185. //
  1186. if (!GetCommState(hIOPort->TPCB_CommHandle, &DCB))
  1187. return(GetLastError());
  1188. if (DCBByteSize != INITIALIZED_VALUE)
  1189. DCB.ByteSize = DCBByteSize ;
  1190. if (DCBParity != INITIALIZED_VALUE)
  1191. DCB.Parity = DCBParity ;
  1192. if (DCBStopBits != INITIALIZED_VALUE)
  1193. DCB.StopBits = DCBStopBits ;
  1194. //
  1195. // Send DCB to Port
  1196. //
  1197. if (!SetCommState(hIOPort->TPCB_CommHandle, &DCB))
  1198. return(GetLastError());
  1199. }
  1200. return SUCCESS ;
  1201. }
  1202. //* FillInIsdnParams()
  1203. //
  1204. //
  1205. //
  1206. //*
  1207. DWORD
  1208. FillInIsdnParams (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pInfo)
  1209. {
  1210. RAS_PARAMS *p;
  1211. WORD i;
  1212. DWORD index ;
  1213. DBGPRINT(("CDMODEM: FillInIsdnParams: ISDN not supported\n"));
  1214. ASSERT(FALSE);
  1215. return SUCCESS ;
  1216. }
  1217. //*
  1218. //
  1219. //
  1220. //
  1221. //*
  1222. DWORD
  1223. FillInX25Params (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pInfo)
  1224. {
  1225. RAS_PARAMS *p;
  1226. WORD i;
  1227. DWORD index ;
  1228. #ifndef CITRIX
  1229. for (i=0, p=pInfo->PI_Params; i<pInfo->PI_NumOfParams; i++, p++) {
  1230. if (_stricmp(p->P_Key, MXS_DIAGNOSTICS_KEY) == 0)
  1231. index = X25_DIAGNOSTICS_INDEX ;
  1232. else if (_stricmp(p->P_Key, MXS_USERDATA_KEY) == 0)
  1233. index = X25_USERDATA_INDEX ;
  1234. else if (_stricmp(p->P_Key, MXS_FACILITIES_KEY) == 0)
  1235. index = X25_FACILITIES_INDEX;
  1236. else if (_stricmp(p->P_Key, MXS_X25ADDRESS_KEY) == 0)
  1237. index = ADDRESS_INDEX ;
  1238. else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
  1239. index = X25_CONNECTBPS_INDEX ;
  1240. else
  1241. return(ERROR_WRONG_INFO_SPECIFIED);
  1242. strncpy (hIOPort->TPCB_Info[index], p->P_Value.String.Data, p->P_Value.String.Length);
  1243. hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
  1244. }
  1245. strcpy (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX], "9600") ; // initialize connectbps to a
  1246. // reasonable default
  1247. #else // CITRIX
  1248. DBGPRINT(("CDMODEM: FillInX25Params: X25 not supported\n"));
  1249. ASSERT(FALSE);
  1250. #endif // CITRIX
  1251. return SUCCESS ;
  1252. }
  1253. //*
  1254. //
  1255. //
  1256. //
  1257. //*
  1258. DWORD
  1259. FillInGenericParams (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pInfo)
  1260. {
  1261. RAS_PARAMS *p;
  1262. WORD i;
  1263. DWORD index ;
  1264. for (i=0, p=pInfo->PI_Params; i<pInfo->PI_NumOfParams; i++, p++) {
  1265. if (_stricmp(p->P_Key, ISDN_PHONENUMBER_KEY) == 0)
  1266. index = ADDRESS_INDEX ;
  1267. else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
  1268. index = CONNECTBPS_INDEX ;
  1269. else
  1270. return(ERROR_WRONG_INFO_SPECIFIED);
  1271. strncpy (hIOPort->TPCB_Info[index], p->P_Value.String.Data, p->P_Value.String.Length);
  1272. hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
  1273. }
  1274. return SUCCESS ;
  1275. }
  1276. //*
  1277. //
  1278. //
  1279. //
  1280. //*
  1281. DWORD
  1282. GetGenericParams (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pBuffer , PWORD pwSize)
  1283. {
  1284. RAS_PARAMS *pParam;
  1285. CHAR *pValue;
  1286. WORD wAvailable ;
  1287. DWORD dwStructSize = sizeof(RASMAN_PORTINFO) + sizeof(RAS_PARAMS) * 2;
  1288. wAvailable = *pwSize;
  1289. *pwSize = (WORD) (dwStructSize + strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
  1290. + strlen (hIOPort->TPCB_Info[CONNECTBPS_INDEX])
  1291. + 1L) ;
  1292. if (*pwSize > wAvailable)
  1293. return(ERROR_BUFFER_TOO_SMALL);
  1294. // Fill in Buffer
  1295. ((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 2;
  1296. pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
  1297. pValue = (CHAR*)pBuffer + dwStructSize;
  1298. strcpy(pParam->P_Key, MXS_PHONENUMBER_KEY);
  1299. pParam->P_Type = String;
  1300. pParam->P_Attributes = 0;
  1301. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
  1302. pParam->P_Value.String.Data = pValue;
  1303. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ADDRESS_INDEX]);
  1304. pParam++;
  1305. strcpy(pParam->P_Key, CONNECTBPS_KEY);
  1306. pParam->P_Type = String;
  1307. pParam->P_Attributes = 0;
  1308. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
  1309. pParam->P_Value.String.Data = pValue;
  1310. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
  1311. return(SUCCESS);
  1312. }
  1313. //*
  1314. //
  1315. //
  1316. //
  1317. //*
  1318. DWORD
  1319. GetIsdnParams (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pBuffer , PWORD pwSize)
  1320. {
  1321. RAS_PARAMS *pParam;
  1322. CHAR *pValue;
  1323. WORD wAvailable ;
  1324. DWORD dwStructSize = sizeof(RASMAN_PORTINFO) + sizeof(RAS_PARAMS) * 5;
  1325. #ifndef CITRIX
  1326. wAvailable = *pwSize;
  1327. *pwSize = (WORD) (dwStructSize + strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
  1328. + strlen (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX])
  1329. + strlen (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX])
  1330. + strlen (hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX])
  1331. + strlen (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX])
  1332. + strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX])
  1333. + 1L) ;
  1334. if (*pwSize > wAvailable)
  1335. return(ERROR_BUFFER_TOO_SMALL);
  1336. // Fill in Buffer
  1337. ((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 6;
  1338. pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
  1339. pValue = (CHAR*)pBuffer + dwStructSize;
  1340. strcpy(pParam->P_Key, ISDN_PHONENUMBER_KEY);
  1341. pParam->P_Type = String;
  1342. pParam->P_Attributes = 0;
  1343. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
  1344. pParam->P_Value.String.Data = pValue;
  1345. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ADDRESS_INDEX]);
  1346. pValue += pParam->P_Value.String.Length + 1;
  1347. pParam++;
  1348. strcpy(pParam->P_Key, ISDN_LINETYPE_KEY);
  1349. pParam->P_Type = String;
  1350. pParam->P_Attributes = 0;
  1351. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX]);
  1352. pParam->P_Value.String.Data = pValue;
  1353. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX]);
  1354. pValue += pParam->P_Value.String.Length + 1;
  1355. pParam++;
  1356. strcpy(pParam->P_Key, ISDN_FALLBACK_KEY);
  1357. pParam->P_Type = String;
  1358. pParam->P_Attributes = 0;
  1359. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]);
  1360. pParam->P_Value.String.Data = pValue;
  1361. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]);
  1362. pValue += pParam->P_Value.String.Length + 1;
  1363. pParam++;
  1364. strcpy(pParam->P_Key, ISDN_COMPRESSION_KEY);
  1365. pParam->P_Type = String;
  1366. pParam->P_Attributes = 0;
  1367. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX]);
  1368. pParam->P_Value.String.Data = pValue;
  1369. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX]);
  1370. pValue += pParam->P_Value.String.Length + 1;
  1371. pParam++;
  1372. strcpy(pParam->P_Key, ISDN_CHANNEL_AGG_KEY);
  1373. pParam->P_Type = String;
  1374. pParam->P_Attributes = 0;
  1375. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]);
  1376. pParam->P_Value.String.Data = pValue;
  1377. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]);
  1378. pValue += pParam->P_Value.String.Length + 1;
  1379. pParam++;
  1380. strcpy(pParam->P_Key, CONNECTBPS_KEY);
  1381. pParam->P_Type = String;
  1382. pParam->P_Attributes = 0;
  1383. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
  1384. pParam->P_Value.String.Data = pValue;
  1385. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
  1386. #else // CITRIX
  1387. DBGPRINT(("CDMODEM: GetIsdnParams: ISDN not supported\n"));
  1388. ASSERT(FALSE);
  1389. #endif // CITRIX
  1390. return(SUCCESS);
  1391. }
  1392. //*
  1393. //
  1394. //
  1395. //
  1396. //*
  1397. DWORD
  1398. GetX25Params (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pBuffer ,PWORD pwSize)
  1399. {
  1400. RAS_PARAMS *pParam;
  1401. CHAR *pValue;
  1402. WORD wAvailable ;
  1403. DWORD dwStructSize = sizeof(RASMAN_PORTINFO) + sizeof(RAS_PARAMS) * 4 ;
  1404. #ifndef CITRIX
  1405. wAvailable = *pwSize;
  1406. *pwSize = (WORD) (dwStructSize + strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
  1407. + strlen (hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX])
  1408. + strlen (hIOPort->TPCB_Info[X25_USERDATA_INDEX])
  1409. + strlen (hIOPort->TPCB_Info[X25_FACILITIES_INDEX])
  1410. + strlen (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX])
  1411. + 1L) ;
  1412. if (*pwSize > wAvailable)
  1413. return(ERROR_BUFFER_TOO_SMALL);
  1414. // Fill in Buffer
  1415. ((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 5 ;
  1416. pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
  1417. pValue = (CHAR*)pBuffer + dwStructSize;
  1418. strcpy(pParam->P_Key, MXS_X25ADDRESS_KEY);
  1419. pParam->P_Type = String;
  1420. pParam->P_Attributes = 0;
  1421. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
  1422. pParam->P_Value.String.Data = pValue;
  1423. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[ADDRESS_INDEX]);
  1424. pValue += pParam->P_Value.String.Length + 1;
  1425. pParam++;
  1426. strcpy(pParam->P_Key, MXS_DIAGNOSTICS_KEY);
  1427. pParam->P_Type = String;
  1428. pParam->P_Attributes = 0;
  1429. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX]);
  1430. pParam->P_Value.String.Data = pValue;
  1431. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX]);
  1432. pValue += pParam->P_Value.String.Length + 1;
  1433. pParam++;
  1434. strcpy(pParam->P_Key, MXS_USERDATA_KEY);
  1435. pParam->P_Type = String;
  1436. pParam->P_Attributes = 0;
  1437. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[X25_USERDATA_INDEX]);
  1438. pParam->P_Value.String.Data = pValue;
  1439. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[X25_USERDATA_INDEX]);
  1440. pValue += pParam->P_Value.String.Length + 1;
  1441. pParam++;
  1442. strcpy(pParam->P_Key, MXS_FACILITIES_KEY);
  1443. pParam->P_Type = String;
  1444. pParam->P_Attributes = 0;
  1445. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[X25_FACILITIES_INDEX]);
  1446. pParam->P_Value.String.Data = pValue;
  1447. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[X25_FACILITIES_INDEX]);
  1448. pValue += pParam->P_Value.String.Length + 1;
  1449. pParam++;
  1450. strcpy(pParam->P_Key, CONNECTBPS_KEY);
  1451. pParam->P_Type = String;
  1452. pParam->P_Attributes = 0;
  1453. pParam->P_Value.String.Length = strlen (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX]);
  1454. pParam->P_Value.String.Data = pValue;
  1455. strcpy(pParam->P_Value.String.Data, hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX]);
  1456. #else // CITRIX
  1457. DBGPRINT(("CDMODEM: GetX25Params: X25 not supported\n"));
  1458. ASSERT(FALSE);
  1459. #endif // CITRIX
  1460. return(SUCCESS);
  1461. }
  1462. //* GetMutex
  1463. //
  1464. //
  1465. //
  1466. //*
  1467. VOID
  1468. GetMutex (HANDLE mutex, DWORD to)
  1469. {
  1470. if (WaitForSingleObject (mutex, to) == WAIT_FAILED) {
  1471. GetLastError() ;
  1472. DbgBreakPoint() ;
  1473. }
  1474. }
  1475. //* FreeMutex
  1476. //
  1477. //
  1478. //
  1479. //*
  1480. VOID
  1481. FreeMutex (HANDLE mutex)
  1482. {
  1483. if (!ReleaseMutex(mutex)) {
  1484. GetLastError () ;
  1485. DbgBreakPoint() ;
  1486. }
  1487. }
  1488. //* InitiatePortDisconnection()
  1489. //
  1490. // Function: Starts the disconnect process. Note even though this covers SYNC completion of lineDrop this
  1491. // is not per TAPI spec.
  1492. //
  1493. // Returns:
  1494. //*
  1495. DWORD
  1496. InitiatePortDisconnection (TapiPortControlBlock *hIOPort)
  1497. {
  1498. DWORD retcode ;
  1499. hIOPort->TPCB_RequestId = INFINITE ; // mark requestid as unused
  1500. // For asyncmac/unimodem give a close indication to asyncmac if the endpoint is still valid
  1501. //
  1502. if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0) {
  1503. // tell asyncmac to close the link
  1504. //
  1505. if (hIOPort->TPCB_Endpoint != 0xffffffff) {
  1506. ASYMAC_CLOSE AsyMacClose;
  1507. OVERLAPPED overlapped ;
  1508. DWORD dwBytesReturned ;
  1509. memset (&overlapped, 0, sizeof(OVERLAPPED)) ;
  1510. AsyMacClose.MacAdapter = NULL;
  1511. AsyMacClose.hNdisEndpoint = LongToHandle(hIOPort->TPCB_Endpoint) ;
  1512. DeviceIoControl(ghAsyMac,
  1513. IOCTL_ASYMAC_CLOSE,
  1514. &AsyMacClose,
  1515. sizeof(AsyMacClose),
  1516. &AsyMacClose,
  1517. sizeof(AsyMacClose),
  1518. &dwBytesReturned,
  1519. &overlapped);
  1520. hIOPort->TPCB_Endpoint = 0xffffffff ;
  1521. }
  1522. // Close the handle given by lineGetId on unimodem ports
  1523. //
  1524. if (hIOPort->TPCB_CommHandle != INVALID_HANDLE_VALUE) {
  1525. DBGPRINT(( "InitiatePortDisconnection: Closing handle 0x%x",
  1526. hIOPort->TPCB_CommHandle ));
  1527. CloseHandle (hIOPort->TPCB_CommHandle) ;
  1528. hIOPort->TPCB_CommHandle = INVALID_HANDLE_VALUE ;
  1529. }
  1530. }
  1531. // Handle the case where lineMakeCall is not yet complete and the callhandle is invalid
  1532. //
  1533. if (hIOPort->TPCB_CallHandle == (HCALL) INFINITE) {
  1534. lineClose (hIOPort->TPCB_Line->TLI_LineHandle) ;
  1535. Sleep (30L) ; // arbitrary sleep time to allow cleanup in lower layers
  1536. retcode = lineOpen (RasLine,
  1537. hIOPort->TPCB_Line->TLI_LineId,
  1538. &hIOPort->TPCB_Line->TLI_LineHandle,
  1539. hIOPort->TPCB_Line->NegotiatedApiVersion,
  1540. hIOPort->TPCB_Line->NegotiatedExtVersion,
  1541. (ULONG) (ULONG_PTR) hIOPort->TPCB_Line,
  1542. LINECALLPRIVILEGE_OWNER,
  1543. hIOPort->TPCB_MediaMode,
  1544. NULL) ;
  1545. if (retcode)
  1546. DbgPrint ("InitiateDisconnection: lineOpen failed with %d\n", retcode) ;
  1547. //
  1548. // Set monitoring of rings
  1549. //
  1550. lineSetStatusMessages (hIOPort->TPCB_Line->TLI_LineHandle, LINEDEVSTATE_RINGING, 0) ;
  1551. return SUCCESS ;
  1552. }
  1553. // Initiate disconnection.
  1554. //
  1555. if ((hIOPort->TPCB_RequestId = lineDrop (hIOPort->TPCB_CallHandle, NULL, 0)) > 0x80000000 ) {
  1556. //
  1557. // Error issuing the linedrop. Should we try to deallocate anyway?
  1558. //
  1559. hIOPort->TPCB_State = PS_OPEN ;
  1560. hIOPort->TPCB_RequestId = INFINITE ;
  1561. lineDeallocateCall (hIOPort->TPCB_CallHandle) ;
  1562. // DbgPrint ("D\n") ;
  1563. return ERROR_DISCONNECTION ; // generic disconnect message
  1564. } else if (hIOPort->TPCB_RequestId) {
  1565. //
  1566. // The linedrop is completeing async
  1567. //
  1568. hIOPort->TPCB_State = PS_DISCONNECTING ;
  1569. // DbgPrint ("InitiatePortDisconnection: ReqId:%d\n", hIOPort->TPCB_RequestId) ;
  1570. return PENDING ;
  1571. } else { // SUCCESS
  1572. //
  1573. // The linedrop completed sync
  1574. //
  1575. hIOPort->TPCB_RequestId = INFINITE ;
  1576. if (hIOPort->TPCB_Line->IdleReceived) {
  1577. hIOPort->TPCB_Line->IdleReceived = FALSE;
  1578. hIOPort->TPCB_State = PS_OPEN ;
  1579. lineDeallocateCall (hIOPort->TPCB_CallHandle) ;
  1580. // DbgPrint ("D\n") ;
  1581. hIOPort->TPCB_CallHandle = (HCALL) 0xffffffff ;
  1582. return SUCCESS ;
  1583. } else {
  1584. //
  1585. // Wait for IdleReceived
  1586. //
  1587. hIOPort->TPCB_State = PS_DISCONNECTING ;
  1588. return PENDING ;
  1589. }
  1590. }
  1591. }
  1592. // LookUpControlBlock()
  1593. //
  1594. // Function: This function uses the given handle to find which TPCB is it refering to. This handle can be
  1595. // either a pointer to TPCB itself (in case of non unimodem devices) or it is the CommHandle
  1596. // for the unimodem port.
  1597. //
  1598. // Consider: Adding a cache for lookup speeding.
  1599. //
  1600. // Returns: Nothing.
  1601. //
  1602. TapiPortControlBlock *
  1603. LookUpControlBlock (HANDLE hPort)
  1604. {
  1605. DWORD i ;
  1606. TapiPortControlBlock *pports ;
  1607. // hPort is the TPCB pointer
  1608. //
  1609. if (((TapiPortControlBlock *)hPort >= RasPorts) &&
  1610. ((TapiPortControlBlock *)hPort < RasPortsEnd) &&
  1611. (((TapiPortControlBlock *)hPort)->TPCB_Signature == CONTROLBLOCKSIGNATURE))
  1612. return (TapiPortControlBlock *)hPort ;
  1613. // hPort is not the TPCB pointer - see if this matches any of the CommHandles
  1614. //
  1615. for (pports = RasPorts, i=0; i < TotalPorts; i++, pports++) {
  1616. if (pports->TPCB_CommHandle == hPort)
  1617. return pports ;
  1618. }
  1619. return NULL ;
  1620. }
  1621. //* ValueToNum -------------------------------------------------------------
  1622. //
  1623. // Function: Converts a RAS_PARAMS P_Value, which may be either a DWORD or
  1624. // a string, to a DWORD.
  1625. //
  1626. // Returns: The numeric value of the input as a DWORD.
  1627. //
  1628. //*
  1629. DWORD
  1630. ValueToNum(RAS_PARAMS *p)
  1631. {
  1632. CHAR szStr[RAS_MAXLINEBUFLEN];
  1633. if (p->P_Type == String) {
  1634. strncpy(szStr, p->P_Value.String.Data, p->P_Value.String.Length);
  1635. szStr[p->P_Value.String.Length] = '\0';
  1636. return(atol(szStr));
  1637. } else
  1638. return(p->P_Value.Number);
  1639. }