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.

5065 lines
135 KiB

  1. /*++
  2. Copyright (C) 1992-98 Microsft Corporation. All rights reserved.
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This file contains init code for TAPI.DLL
  7. Author:
  8. Gurdeep Singh Pall (gurdeep) 06-Jun-1997
  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 <stdio.h>
  16. #include <windows.h>
  17. #include <tapi.h>
  18. #include <rasman.h>
  19. #include <raserror.h>
  20. #include <mprlog.h>
  21. #include <rtutils.h>
  22. #include <media.h>
  23. #include <device.h>
  24. #include <rasmxs.h>
  25. #include <isdn.h>
  26. #include <stdlib.h>
  27. #include <malloc.h>
  28. #include <string.h>
  29. #include "rastapi.h"
  30. #include "reghelp.h"
  31. #include <ntddndis.h> //for NDIS_WAN_MEDIUM_SUBTYPE
  32. #define STRSAFE_NO_DEPRECATE
  33. #include <strsafe.h>
  34. #define NUMBUFFERS 10
  35. extern DWORD dwTraceId;
  36. DWORD g_dwTotalDialIn = 0;
  37. BOOL g_fRestrictDialIn = FALSE;
  38. DWORD APIENTRY
  39. DeviceListen(HANDLE hPort,
  40. char *pszDeviceType,
  41. char *pszDeviceName);
  42. VOID
  43. MapNdiswanDTtoRasDT(DeviceInfo *pDeviceInfo,
  44. NDIS_WAN_MEDIUM_SUBTYPE eMediaType);
  45. HLINEAPP RasLine = 0 ;
  46. HINSTANCE RasInstance = 0 ;
  47. TapiLineInfo *RasTapiLineInfoList = NULL;
  48. DWORD TotalLines = 0 ;
  49. DWORD TotalPorts ;
  50. TapiPortControlBlock *RasPortsList = NULL;
  51. TapiPortControlBlock *RasPortsEnd ;
  52. HANDLE RasTapiMutex ;
  53. BOOL Initialized = FALSE ;
  54. DWORD TapiThreadId ;
  55. HANDLE TapiThreadHandle;
  56. // DWORD LoaderThreadId;
  57. DWORD ValidPorts = 0;
  58. DWORD NumberOfRings = 2 ;
  59. HANDLE g_hAsyMac = INVALID_HANDLE_VALUE;
  60. HANDLE g_hIoCompletionPort = INVALID_HANDLE_VALUE;
  61. pDeviceInfo g_pDeviceInfoList = NULL;
  62. LIST_ENTRY ZombieCallList;
  63. DWORD dwTraceId;
  64. extern BOOL g_fDllLoaded;
  65. TapiLineInfo *FindLineByHandle (HLINE) ;
  66. TapiPortControlBlock *FindPortByRequestId (DWORD) ;
  67. TapiPortControlBlock *FindPortByAddressId (TapiLineInfo *, DWORD) ;
  68. TapiPortControlBlock *FindPortByAddress (CHAR *) ;
  69. TapiPortControlBlock *FindPortByCallHandle(
  70. TapiLineInfo *line,
  71. HCALL callhandle);
  72. TapiPortControlBlock *FindListeningPort(TapiLineInfo *line,
  73. DWORD AddressID);
  74. DWORD InitiatePortDisconnection (TapiPortControlBlock *hIOPort) ;
  75. TapiPortControlBlock *FindPortByAddressAndName (CHAR *address,
  76. CHAR *name) ;
  77. /*++
  78. Routine Description:
  79. Trace
  80. Arguments:
  81. Formatting string,...
  82. Return Value:
  83. void.
  84. --*/
  85. VOID
  86. RasTapiTrace(
  87. CHAR * Format,
  88. ...
  89. )
  90. {
  91. va_list arglist;
  92. va_start(arglist, Format);
  93. TraceVprintfEx(dwTraceId,
  94. 0x00010000 | TRACE_USE_MASK
  95. | TRACE_USE_MSEC | TRACE_USE_DATE,
  96. Format,
  97. arglist);
  98. va_end(arglist);
  99. }
  100. /*++
  101. Routine Description:
  102. Initialize the RasPorts List
  103. Arguments:
  104. void
  105. Return Value:
  106. SUCCESS.
  107. --*/
  108. DWORD
  109. InitializeRasPorts()
  110. {
  111. RasPortsList = NULL;
  112. InitializeListHead(&ZombieCallList);
  113. return 0;
  114. }
  115. /*++
  116. Routine Description:
  117. Gets Next available port from the list of
  118. port control blocks. Allocates a block if
  119. no block is available.
  120. Arguments:
  121. pfNewBlock -address of bool which received
  122. if a new block was created
  123. Return Value:
  124. Pointer to the newly created block. NULL is
  125. returned in case of failures.
  126. --*/
  127. TapiPortControlBlock *
  128. GetNextAvailablePort( BOOL *pfNewBlock )
  129. {
  130. //
  131. // Run down the global list looking for an
  132. // unused block. If no such block is found
  133. // allocate a new block.
  134. //
  135. TapiPortControlBlock *ptpcb = RasPortsList;
  136. while ( NULL != ptpcb )
  137. {
  138. if ( PS_UNINITIALIZED == ptpcb->TPCB_State )
  139. break;
  140. ptpcb = ptpcb->TPCB_next;
  141. }
  142. if ( NULL != ptpcb )
  143. {
  144. *pfNewBlock = FALSE;
  145. goto done;
  146. }
  147. ptpcb = LocalAlloc ( LPTR, sizeof ( TapiPortControlBlock ) );
  148. if ( NULL == ptpcb )
  149. goto done;
  150. *pfNewBlock = TRUE;
  151. ptpcb->TPCB_State = PS_UNINITIALIZED;
  152. //
  153. // insert the new block in the global list
  154. //
  155. ptpcb->TPCB_next = RasPortsList;
  156. RasPortsList = ptpcb;
  157. TotalPorts++;
  158. done:
  159. return ptpcb;
  160. }
  161. #if 0
  162. DWORD
  163. dwGetNextInstanceNumber(CHAR *pszMediaName,
  164. DWORD *pdwExclusiveDialIn,
  165. DWORD *pdwExclusiveDialOut,
  166. DWORD *pdwExclusiveRouter,
  167. BOOL *pfIn)
  168. {
  169. DWORD dwCount;
  170. DWORD dwInstanceNum = 0;
  171. DWORD dwTemp;
  172. TapiPortControlBlock *ptpcb = RasPortsList;
  173. *pdwExclusiveDialIn = 0;
  174. *pdwExclusiveDialOut = 0;
  175. *pdwExclusiveRouter = 0;
  176. *pfIn = FALSE;
  177. while ( ptpcb )
  178. {
  179. if ( PS_UNINITIALIZED != ptpcb->TPCB_State
  180. && ptpcb->TPCB_Name[0] != '\0'
  181. && strstr( ptpcb->TPCB_Name, pszMediaName ))
  182. {
  183. dwTemp = atoi(ptpcb->TPCB_Name + strlen(pszMediaName) + 1);
  184. if (dwTemp > dwInstanceNum)
  185. {
  186. dwInstanceNum = dwTemp;
  187. }
  188. if (CALL_IN == ptpcb->TPCB_Usage)
  189. {
  190. *pdwExclusiveDialIn += 1;
  191. }
  192. else if (CALL_OUT == ptpcb->TPCB_Usage)
  193. {
  194. *pdwExclusiveDialOut += 1;
  195. }
  196. else if (CALL_ROUTER == ptpcb->TPCB_Usage)
  197. {
  198. *pdwExclusiveRouter += 1;
  199. }
  200. }
  201. if ( CALL_IN & ptpcb->TPCB_Usage)
  202. {
  203. *pfIn = TRUE;
  204. }
  205. ptpcb = ptpcb->TPCB_next;
  206. }
  207. return dwInstanceNum + 1;
  208. }
  209. #endif
  210. /*++
  211. Routine Description:
  212. Gets the Guid of the adapter identified by the
  213. dwID parameter. Also returns the media type of
  214. the device in szMediaType parameter.
  215. Arguments:
  216. dwNegotiatedApiVersion
  217. dwNegotiatedExtVersion
  218. pbyte - buffer to receive the Guid
  219. dwID - line Id of the device
  220. dwAddressID - Address Id of the device
  221. szMediaType - buffer to receive the media type
  222. Return Value:
  223. return codes from tapi calls. SUCCESS is
  224. returned if there are no failures.
  225. --*/
  226. DWORD
  227. dwGetLineAddress( DWORD dwNegotiatedApiVersion,
  228. DWORD dwNegotiatedExtVersion,
  229. LPBYTE pbyte,
  230. DWORD dwID,
  231. DWORD dwAddressID,
  232. CHAR* szMediaType,
  233. PNDIS_WAN_MEDIUM_SUBTYPE peMedia)
  234. {
  235. DWORD dwRetCode;
  236. HLINE hLine = 0;
  237. LINECALLPARAMS lineparams;
  238. BYTE *bvar[100];
  239. LPVARSTRING pvar;
  240. RasTapiTrace("dwGetLineAddress:...");
  241. //
  242. // Open the line
  243. //
  244. if ( dwRetCode = lineOpen ( RasLine,
  245. dwID,
  246. &hLine,
  247. dwNegotiatedApiVersion,
  248. dwNegotiatedExtVersion,
  249. 0,
  250. LINECALLPRIVILEGE_NONE,
  251. LINEMEDIAMODE_UNKNOWN,
  252. &lineparams))
  253. {
  254. RasTapiTrace("dwGetLineAddress: lineOpen failed. "
  255. "0x%x", dwRetCode );
  256. goto done;
  257. }
  258. pvar = (VARSTRING *) bvar;
  259. pvar->dwTotalSize = sizeof (bvar);
  260. //
  261. // Get the Guid for this line from TAPI
  262. //
  263. if ( dwRetCode = lineGetID ( hLine,
  264. dwAddressID,
  265. 0,
  266. LINECALLSELECT_LINE,
  267. pvar,
  268. "LineGuid"))
  269. {
  270. RasTapiTrace("dwGetLineAddress: lineGetID LineGuid "
  271. "failed. 0x%x", dwRetCode );
  272. goto done;
  273. }
  274. lineClose (hLine);
  275. hLine = 0;
  276. if ( 0 != pvar->dwStringSize
  277. && 1 != pvar->dwStringSize)
  278. {
  279. DWORD Index;
  280. UCHAR MediaTypes[][MAX_DEVICETYPE_NAME] = {
  281. "GENERIC",
  282. "X25",
  283. "ISDN",
  284. "SERIAL",
  285. "FRAMERELAY",
  286. "ATM",
  287. "SONET",
  288. "SW56",
  289. "VPN",
  290. "VPN",
  291. "IRDA",
  292. "PARALLEL",
  293. "PPPoE"
  294. };
  295. //
  296. // Copy the GUID
  297. //
  298. memcpy ( pbyte,
  299. (PBYTE) (((PBYTE) pvar) +
  300. pvar->dwStringOffset),
  301. sizeof (GUID) );
  302. memcpy ((PBYTE)&Index, (PBYTE) (((PBYTE) pvar) +
  303. pvar->dwStringOffset + sizeof (GUID)),
  304. sizeof(DWORD));
  305. if (Index > 12) {
  306. Index = 0;
  307. }
  308. //
  309. // Copy the media name
  310. //
  311. strcpy (szMediaType, MediaTypes[Index]);
  312. if(peMedia)
  313. {
  314. *peMedia = (NDIS_WAN_MEDIUM_SUBTYPE) Index;
  315. }
  316. }
  317. else
  318. {
  319. ASSERT(FALSE);
  320. dwRetCode = E_FAIL;
  321. RasTapiTrace(
  322. "dwGetLineAddress: pvar->dwStringSize != 0,1"
  323. " returning 0x%x",
  324. dwRetCode);
  325. }
  326. done:
  327. if (hLine)
  328. {
  329. lineClose (hLine);
  330. }
  331. RasTapiTrace("dwGetLineAddress: done. 0x%x", dwRetCode );
  332. RasTapiTrace(" ");
  333. return dwRetCode;
  334. }
  335. /*++
  336. Routine Description:
  337. DLL Main routine for rastapi dll.
  338. Arguments:
  339. hInst - instance handle of the dll
  340. dwReason
  341. lpReserved
  342. Return Value:
  343. returns 1 if successfule. 0 otherwise.
  344. --*/
  345. BOOL
  346. InitRasTapi (
  347. HANDLE hInst,
  348. DWORD dwReason,
  349. LPVOID lpReserved)
  350. {
  351. static BOOLEAN DllInitialized = FALSE ;
  352. switch (dwReason)
  353. {
  354. case DLL_PROCESS_ATTACH:
  355. if (RasPortsList != NULL)
  356. {
  357. return 1 ;
  358. }
  359. RasInstance = hInst ;
  360. #if 0
  361. //
  362. // Register for tracing
  363. //
  364. dwTraceId = TraceRegister("RASTAPI");
  365. #if DBG
  366. if(dwTraceId == (DWORD) -1)
  367. {
  368. DbgPrint("RASTAPI: TraceRegister Failed\n");
  369. }
  370. else
  371. {
  372. DbgPrint("RASTAPI: TraceId = %d\n",
  373. dwTraceId);
  374. }
  375. #endif
  376. #endif
  377. //
  378. // initialize RasPorts
  379. //
  380. if (InitializeRasPorts())
  381. {
  382. return 0;
  383. }
  384. if ((RasTapiMutex = CreateMutex (NULL, FALSE, NULL))
  385. == NULL)
  386. {
  387. return 0 ;
  388. }
  389. DllInitialized = TRUE ;
  390. break ;
  391. case DLL_PROCESS_DETACH:
  392. //
  393. // If DLL did not successfully initialize for
  394. // this process
  395. // dont try to clean up
  396. //
  397. if ( !DllInitialized
  398. || !g_fDllLoaded)
  399. {
  400. break ;
  401. }
  402. if (RasLine)
  403. {
  404. lineShutdown (RasLine) ;
  405. RasLine = 0;
  406. }
  407. // TraceDeregister( dwTraceId );
  408. g_fDllLoaded = FALSE;
  409. PostThreadMessage (TapiThreadId, WM_QUIT, 0, 0) ;
  410. if(NULL != TapiThreadHandle)
  411. {
  412. CloseHandle(TapiThreadHandle);
  413. TapiThreadHandle = NULL;
  414. }
  415. break ;
  416. case DLL_THREAD_ATTACH:
  417. break;
  418. case DLL_THREAD_DETACH:
  419. break;
  420. }
  421. return 1 ;
  422. }
  423. /*++
  424. Routine Description:
  425. Gets the device information associated with
  426. the Guid passed in if the device is not a
  427. modem. Gets the information about modem if
  428. the the address passed in is the device name
  429. of a modem.
  430. Arguments:
  431. pbAddress - Guid of the device if fModem is
  432. FALSE or Device Name of a modem if fModem
  433. is TRUE.
  434. Return Value:
  435. Pointer to a DeviceInfo structure if the info
  436. was found. NULL otherwise.
  437. --*/
  438. DeviceInfo *
  439. GetDeviceInfo(
  440. PBYTE pbAddress,
  441. BOOL fModem)
  442. {
  443. DeviceInfo *pDeviceInfo = g_pDeviceInfoList;
  444. while ( pDeviceInfo )
  445. {
  446. if( fModem
  447. && !_stricmp(
  448. (CHAR *) pbAddress,
  449. pDeviceInfo->rdiDeviceInfo.szDeviceName))
  450. {
  451. break;
  452. }
  453. else if( !fModem
  454. && 0 == memcmp(pbAddress,
  455. &pDeviceInfo->rdiDeviceInfo.guidDevice,
  456. sizeof (GUID)))
  457. {
  458. break;
  459. }
  460. pDeviceInfo = pDeviceInfo->Next;
  461. }
  462. return pDeviceInfo;
  463. }
  464. /*++
  465. Routine Description:
  466. Trace the information in the Device Info block.
  467. Arguments:
  468. DeviceInfo
  469. Return Value:
  470. void
  471. --*/
  472. VOID
  473. TraceEndPointInfo(DeviceInfo *pInfo)
  474. {
  475. if('\0' != pInfo->rdiDeviceInfo.szDeviceName[0])
  476. {
  477. RasTapiTrace("------DeviceInfo for %s--------",
  478. pInfo->rdiDeviceInfo.szDeviceName);
  479. }
  480. else
  481. {
  482. RasTapiTrace("------DeviceInfo for Unknown----");
  483. }
  484. RasTapiTrace(" ");
  485. RasTapiTrace("WanEndPoints =%d",
  486. pInfo->rdiDeviceInfo.dwNumEndPoints);
  487. RasTapiTrace("RasEnabled =%d",
  488. (DWORD) pInfo->rdiDeviceInfo.fRasEnabled);
  489. RasTapiTrace("RasEnabledRouter =%d",
  490. (DWORD) pInfo->rdiDeviceInfo.fRouterEnabled);
  491. RasTapiTrace("MinWanEndPoints =0x%x",
  492. pInfo->rdiDeviceInfo.dwMinWanEndPoints);
  493. RasTapiTrace("MaxWanEndPoints =0x%x",
  494. pInfo->rdiDeviceInfo.dwMaxWanEndPoints);
  495. RasTapiTrace(" ");
  496. RasTapiTrace("------------------------------------");
  497. }
  498. /*++
  499. Routine Description:
  500. Gets the Device information of the device
  501. represented by the Guid. Depending on the flags
  502. passed reads the information from registry.
  503. Uses the functions in reghelp.lib
  504. Arguments:
  505. ppDeviceInfo - Address to receive the DeviceInfo
  506. structure.
  507. pbAddress - Guid of the device.
  508. fForceRead - if TRUE the information is read from
  509. the registry. If FALSE only cached information
  510. is searched for the information on this device.
  511. Return Value:
  512. void
  513. --*/
  514. DWORD
  515. GetEndPointInfo(DeviceInfo **ppDeviceInfo,
  516. PBYTE pbAddress,
  517. BOOL fForceRead,
  518. NDIS_WAN_MEDIUM_SUBTYPE eMediaType)
  519. {
  520. DeviceInfo *pDeviceInfo = g_pDeviceInfoList;
  521. DWORD retcode = SUCCESS;
  522. DeviceInfo *pdi;
  523. //
  524. // Run through the device info list to see if we already
  525. // have the device
  526. //
  527. if ( !fForceRead
  528. && ( pDeviceInfo = GetDeviceInfo(pbAddress, FALSE) ))
  529. {
  530. RasTapiTrace("GetEndPointInfo: Device already present");
  531. goto done;
  532. }
  533. pDeviceInfo = LocalAlloc ( LPTR, sizeof ( DeviceInfo ) );
  534. if ( NULL == pDeviceInfo )
  535. {
  536. retcode = GetLastError();
  537. RasTapiTrace("GetEndPointInfo: Failed to alloc. %d",
  538. retcode );
  539. goto done;
  540. }
  541. MapNdiswanDTtoRasDT(pDeviceInfo, eMediaType);
  542. retcode = DwGetEndPointInfo( pDeviceInfo,
  543. pbAddress );
  544. if ( retcode )
  545. {
  546. RasTapiTrace("GetEndPpointInfo: DwGetEndPointInfo "
  547. "failed. 0x%x", retcode );
  548. goto done;
  549. }
  550. pDeviceInfo->fValid = TRUE;
  551. //
  552. // Run through our device list and check to see if
  553. // we already have a device with the same name. If
  554. // we do then append the instance number of the
  555. // device with the device name
  556. //
  557. pdi = g_pDeviceInfoList;
  558. while(pdi)
  559. {
  560. if(!_stricmp(
  561. pdi->rdiDeviceInfo.szDeviceName,
  562. pDeviceInfo->rdiDeviceInfo.szDeviceName))
  563. {
  564. RasTapiTrace(
  565. "GetEndPointInfo: found another"
  566. " device with the same name %s",
  567. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  568. break;
  569. }
  570. pdi = pdi->Next;
  571. }
  572. if(NULL != pdi)
  573. {
  574. CHAR szDeviceInstance[40];
  575. WCHAR wszDeviceInstance[40];
  576. (VOID)StringCchPrintfA(szDeviceInstance,
  577. 40, " (%d)",
  578. pDeviceInfo->dwInstanceNumber);
  579. (VOID)StringCchPrintfW(wszDeviceInstance,
  580. 40, L" (%d)",
  581. pDeviceInfo->dwInstanceNumber);
  582. //
  583. // Append the instance number to the device name
  584. //
  585. retcode = StringCchCatA(pDeviceInfo->rdiDeviceInfo.szDeviceName,
  586. MAX_DEVICE_NAME + 1,
  587. szDeviceInstance);
  588. if(SUCCESS != retcode)
  589. {
  590. goto done;
  591. }
  592. retcode = StringCchCatW(pDeviceInfo->rdiDeviceInfo.wszDeviceName,
  593. MAX_DEVICE_NAME + 1,
  594. wszDeviceInstance);
  595. if(SUCCESS != retcode)
  596. {
  597. goto done;
  598. }
  599. RasTapiTrace("New DeviceName=%s",
  600. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  601. RasTapiTrace("New WDeviceName=%s",
  602. pDeviceInfo->rdiDeviceInfo.wszDeviceName);
  603. }
  604. //
  605. // Insert the DeviceInfo at the head of the
  606. // global list
  607. //
  608. if ( !fForceRead )
  609. {
  610. pDeviceInfo->Next = g_pDeviceInfoList;
  611. g_pDeviceInfoList = pDeviceInfo;
  612. //
  613. // Trace all this information for this adapter
  614. //
  615. TraceEndPointInfo(pDeviceInfo);
  616. }
  617. done:
  618. if( (SUCCESS != retcode)
  619. && (NULL != pDeviceInfo))
  620. {
  621. LocalFree(pDeviceInfo);
  622. pDeviceInfo = NULL;
  623. }
  624. *ppDeviceInfo = pDeviceInfo;
  625. return retcode;
  626. }
  627. /*++
  628. Routine Description:
  629. This routine maps the devicetypes declared in the
  630. NDIS_WAN_MEDIUM_SUBTYPE enum in ntddndis.h to the
  631. RASDEVICETYPE enum declared in rasman.h. This
  632. mapping is done to enable flexibility at the ras
  633. layer to further categorize the device type into
  634. paricular classes.
  635. Arguments:
  636. pDeviceInfo - address of the DeviceInfo structure
  637. containing the informatio pertaining
  638. to the device.
  639. eMediaType - Device type as defined in ndis for this
  640. device.
  641. Return Value:
  642. Nothing;
  643. --*/
  644. VOID
  645. MapNdiswanDTtoRasDT(DeviceInfo *pDeviceInfo,
  646. NDIS_WAN_MEDIUM_SUBTYPE eMediaType)
  647. {
  648. RASDEVICETYPE rdt = 0;
  649. switch (eMediaType)
  650. {
  651. case NdisWanMediumHub:
  652. {
  653. rdt = RDT_Other;
  654. break;
  655. }
  656. case NdisWanMediumX_25:
  657. {
  658. rdt = RDT_X25;
  659. break;
  660. }
  661. case NdisWanMediumIsdn:
  662. {
  663. rdt = RDT_Isdn;
  664. break;
  665. }
  666. case NdisWanMediumSerial:
  667. {
  668. rdt = RDT_Serial;
  669. break;
  670. }
  671. case NdisWanMediumFrameRelay:
  672. {
  673. rdt = RDT_FrameRelay;
  674. break;
  675. }
  676. case NdisWanMediumAtm:
  677. {
  678. rdt = RDT_Atm;
  679. break;
  680. }
  681. case NdisWanMediumSonet:
  682. {
  683. rdt = RDT_Sonet;
  684. break;
  685. }
  686. case NdisWanMediumSW56K:
  687. {
  688. rdt = RDT_Sw56;
  689. break;
  690. }
  691. case NdisWanMediumPPTP:
  692. {
  693. rdt = RDT_Tunnel_Pptp | RDT_Tunnel;
  694. break;
  695. }
  696. case NdisWanMediumL2TP:
  697. {
  698. rdt = RDT_Tunnel_L2tp | RDT_Tunnel;
  699. break;
  700. }
  701. case NdisWanMediumIrda:
  702. {
  703. rdt = RDT_Irda | RDT_Direct;
  704. break;
  705. }
  706. case NdisWanMediumParallel:
  707. {
  708. rdt = RDT_Parallel | RDT_Direct;
  709. break;
  710. }
  711. case NdisWanMediumPppoe:
  712. {
  713. rdt = RDT_PPPoE | RDT_Broadband;
  714. break;
  715. }
  716. default:
  717. {
  718. rdt = RDT_Other;
  719. break;
  720. }
  721. } // switch
  722. pDeviceInfo->rdiDeviceInfo.eDeviceType = rdt;
  723. }
  724. /*++
  725. Routine Description:
  726. Checks if a port identified by the line/Address/Call
  727. is already configured.
  728. Arguments:
  729. dwLineId - lineID
  730. dwAddressID - AddressID
  731. dwCallID - CallID
  732. ppLine - address to receive the TapiLineInfo to which this
  733. address/call belongs.
  734. Return Value:
  735. void
  736. --*/
  737. BOOL
  738. fIsPortAlreadyPresent( DWORD dwlineId,
  739. DWORD dwAddressId,
  740. DWORD dwCallId,
  741. TapiLineInfo** ppLine)
  742. {
  743. TapiPortControlBlock *ptpcb = RasPortsList;
  744. BOOL fPortPresent = FALSE;
  745. while(ptpcb)
  746. {
  747. if(dwlineId == ptpcb->TPCB_Line->TLI_LineId)
  748. {
  749. *ppLine = ptpcb->TPCB_Line;
  750. if( PS_UNINITIALIZED != ptpcb->TPCB_State
  751. && dwCallId == ptpcb->TPCB_CallId
  752. && dwAddressId == ptpcb->TPCB_AddressId
  753. && PS_UNAVAILABLE != ptpcb->TPCB_State
  754. && (0 ==
  755. (ptpcb->TPCB_dwFlags & RASTAPI_FLAG_UNAVAILABLE)))
  756. {
  757. fPortPresent = TRUE;
  758. break;
  759. }
  760. }
  761. ptpcb = ptpcb->TPCB_next;
  762. }
  763. return fPortPresent;
  764. }
  765. DWORD
  766. DwLineGetDevCaps(DWORD lineId,
  767. DWORD NegotiatedApiVersion,
  768. DWORD NegotiatedExtVersion,
  769. DWORD dwSize,
  770. BYTE *pBuffer,
  771. BYTE **ppBuffer,
  772. BOOL fUnicode)
  773. {
  774. DWORD retcode = SUCCESS;
  775. LINEDEVCAPS *pLineDevCaps;
  776. ZeroMemory(pBuffer, dwSize);
  777. *ppBuffer = pBuffer;
  778. pLineDevCaps = (LINEDEVCAPS *) pBuffer;
  779. pLineDevCaps->dwTotalSize = dwSize;
  780. if(!fUnicode)
  781. {
  782. retcode = (DWORD)lineGetDevCaps (
  783. RasLine,
  784. lineId,
  785. NegotiatedApiVersion,
  786. NegotiatedExtVersion,
  787. pLineDevCaps);
  788. }
  789. else
  790. {
  791. retcode = (DWORD)lineGetDevCapsW(
  792. RasLine,
  793. lineId,
  794. NegotiatedApiVersion,
  795. NegotiatedExtVersion,
  796. pLineDevCaps);
  797. }
  798. if( (LINEERR_STRUCTURETOOSMALL == retcode)
  799. || (pLineDevCaps->dwNeededSize > dwSize))
  800. {
  801. DWORD dwNeededSize = pLineDevCaps->dwNeededSize;
  802. if(0 == dwNeededSize)
  803. {
  804. RasTapiTrace("DwLineGetDevCaps: dwNeededSize == 0!!");
  805. goto done;
  806. }
  807. *ppBuffer = LocalAlloc(LPTR, pLineDevCaps->dwNeededSize);
  808. if(NULL == *ppBuffer)
  809. {
  810. retcode = GetLastError();
  811. }
  812. else
  813. {
  814. pLineDevCaps = (LINEDEVCAPS *) *ppBuffer;
  815. pLineDevCaps->dwTotalSize = dwNeededSize;
  816. if(!fUnicode)
  817. {
  818. retcode = (DWORD)lineGetDevCaps(
  819. RasLine,
  820. lineId,
  821. NegotiatedApiVersion,
  822. NegotiatedExtVersion,
  823. pLineDevCaps);
  824. }
  825. else
  826. {
  827. retcode = (DWORD)lineGetDevCapsW(
  828. RasLine,
  829. lineId,
  830. NegotiatedApiVersion,
  831. NegotiatedExtVersion,
  832. pLineDevCaps);
  833. }
  834. }
  835. }
  836. done:
  837. return retcode;
  838. }
  839. DWORD
  840. DwLineGetAddrCaps(DWORD lineId,
  841. DWORD addressId,
  842. DWORD NegotiatedApiVersion,
  843. DWORD NegotiatedExtVersion,
  844. DWORD dwSize,
  845. BYTE *pBuffer,
  846. BYTE **ppBuffer)
  847. {
  848. DWORD retcode = SUCCESS;
  849. LINEADDRESSCAPS *pAddressCaps;
  850. ZeroMemory(pBuffer, dwSize);
  851. *ppBuffer = pBuffer;
  852. pAddressCaps = (LINEADDRESSCAPS *) pBuffer;
  853. pAddressCaps->dwTotalSize = dwSize;
  854. retcode = (DWORD) lineGetAddressCaps (
  855. RasLine,
  856. lineId,
  857. addressId,
  858. NegotiatedApiVersion,
  859. NegotiatedExtVersion,
  860. pAddressCaps);
  861. if( (LINEERR_STRUCTURETOOSMALL == retcode)
  862. || (pAddressCaps->dwNeededSize > dwSize))
  863. {
  864. DWORD dwNeededSize = pAddressCaps->dwNeededSize;
  865. if(0 == dwNeededSize)
  866. {
  867. RasTapiTrace("DwLineGetAddrCaps: NeededSize==0!!");
  868. goto done;
  869. }
  870. *ppBuffer = LocalAlloc(LPTR, dwNeededSize);
  871. if(NULL == *ppBuffer)
  872. {
  873. retcode = GetLastError();
  874. }
  875. else
  876. {
  877. pAddressCaps = (LINEADDRESSCAPS *) *ppBuffer;
  878. pAddressCaps->dwTotalSize = dwNeededSize;
  879. retcode = (DWORD) lineGetAddressCaps(
  880. RasLine,
  881. lineId,
  882. addressId,
  883. NegotiatedApiVersion,
  884. NegotiatedExtVersion,
  885. pAddressCaps);
  886. }
  887. }
  888. done:
  889. return retcode;
  890. }
  891. /*++
  892. Routine Description:
  893. Creates RasTapiPorts given the lineID of the newline.
  894. Returns success without creating ports if ports already
  895. exist in rastapi corresponding to the line. Iterates
  896. over all Addresses on a line and all the calls on an
  897. address to create the ports.
  898. Arguments:
  899. dwidDevice - ID of the device
  900. pcNewPorts [out] - address of the number of new ports
  901. created. can be NULL.
  902. ppptpcbNewPorts [out] - addressreturns an array of
  903. pointers to newly created
  904. ports. Cannot be NULL if
  905. pcNewPorts is not NULL.
  906. Return Value:
  907. SUCCESS if operation was successful. error otherwise.
  908. --*/
  909. //
  910. // Temp workaround
  911. // Work around the alpha compiler bug.
  912. //
  913. #ifdef _ALPHA_
  914. #pragma function(strcpy)
  915. #endif
  916. DWORD
  917. dwCreateTapiPortsPerLine(DWORD dwidDevice,
  918. DWORD *pcNewPorts,
  919. TapiPortControlBlock ***ppptpcbNewPorts)
  920. {
  921. WORD i, k ;
  922. TapiLineInfo *nextline = NULL;
  923. // BYTE buffer[800] ;
  924. LINEADDRESSCAPS *lineaddrcaps ;
  925. LINEDEVCAPS *linedevcaps ;
  926. CHAR address[100] ;
  927. CHAR devicetype[MAX_DEVICETYPE_NAME+1] = {0};
  928. DWORD devicetypelength;
  929. CHAR devicename[MAX_DEVICE_NAME+1] = {0};
  930. DWORD devicenamelength;
  931. LINEEXTENSIONID extensionid ;
  932. DWORD totaladdresses ;
  933. DWORD totalports = 0;
  934. TapiPortControlBlock *nextport ;
  935. MSG msg ;
  936. HINSTANCE hInst;
  937. TapiPortControlBlock *pports ;
  938. LINEINITIALIZEEXPARAMS param ;
  939. DWORD version = HIGH_VERSION ;
  940. HLINE hLine;
  941. VARSTRING *pvar;
  942. BYTE bvar[100];
  943. LINECALLPARAMS lineparams;
  944. CHAR szMediaName [MAX_DEVICETYPE_NAME] = {0};
  945. DWORD dwPortUsage;
  946. DWORD dwEndPoints;
  947. DWORD dwRetcode;
  948. BOOL fModem = FALSE ;
  949. DWORD retcode = SUCCESS;
  950. DWORD dwPortIndex;
  951. DWORD fCreatedINetCfg = FALSE;
  952. CHAR *pszDeviceType;
  953. DeviceInfo *pDeviceInfo = NULL;
  954. BOOL fRasEnabled;
  955. BOOL fRouterEnabled;
  956. BOOL fRouterOutboundEnabled = FALSE;
  957. DWORD NegotiatedApiVersion,
  958. NegotiatedExtVersion;
  959. HKEY hkey = NULL;
  960. BOOL fCharModeSupported = FALSE;
  961. BOOL fIsValid = FALSE;
  962. LPBYTE pBuffer = NULL;
  963. BYTE* pBufferAlloc = NULL;
  964. RasTapiTrace( "dwCreateTapiPortsPerLine: line %d...", dwidDevice );
  965. pBufferAlloc = LocalAlloc(LPTR, 800);
  966. if(NULL == pBufferAlloc)
  967. {
  968. retcode = E_OUTOFMEMORY;
  969. goto error;
  970. }
  971. nextport = NULL;
  972. if ( pcNewPorts )
  973. {
  974. *pcNewPorts = 0;
  975. }
  976. i = ( WORD ) dwidDevice;
  977. //
  978. // for all lines get the addresses -> ports
  979. //
  980. if ( retcode = ( DWORD ) lineNegotiateAPIVersion (
  981. RasLine,
  982. i,
  983. LOW_VERSION,
  984. HIGH_VERSION,
  985. &NegotiatedApiVersion,
  986. &extensionid) )
  987. {
  988. RasTapiTrace (
  989. "dwCreateTapiPortsPerLine: "
  990. "lineNegotiateAPIVersion() failed. %d",
  991. retcode );
  992. goto error ;
  993. }
  994. if ( lineNegotiateExtVersion( RasLine,
  995. i,
  996. NegotiatedApiVersion,
  997. LOW_EXT_VERSION,
  998. HIGH_EXT_VERSION,
  999. &NegotiatedExtVersion))
  1000. {
  1001. NegotiatedExtVersion = 0;
  1002. }
  1003. if( (NULL != pBuffer)
  1004. && (pBufferAlloc != pBuffer))
  1005. {
  1006. LocalFree(pBuffer);
  1007. pBuffer = NULL;
  1008. }
  1009. retcode = DwLineGetDevCaps(
  1010. i,
  1011. NegotiatedApiVersion,
  1012. NegotiatedExtVersion,
  1013. 800,
  1014. pBufferAlloc,
  1015. &pBuffer,
  1016. FALSE);
  1017. if(SUCCESS != retcode)
  1018. {
  1019. RasTapiTrace("dwCreateTapiPortsPerLine: "
  1020. "lineGetDevCaps Failed. 0x%x",
  1021. retcode );
  1022. goto error;
  1023. }
  1024. linedevcaps = (LINEDEVCAPS *) pBuffer;
  1025. //
  1026. // Figure out if this is a unimodem device or not
  1027. //
  1028. if (NegotiatedApiVersion == HIGH_VERSION)
  1029. {
  1030. //
  1031. // first convert all nulls in the device class
  1032. // string to non nulls.
  1033. //
  1034. DWORD j ;
  1035. char *temp ;
  1036. for ( j = 0,
  1037. temp = (CHAR *)
  1038. linedevcaps+linedevcaps->dwDeviceClassesOffset;
  1039. j < linedevcaps->dwDeviceClassesSize;
  1040. j++, temp++)
  1041. if (*temp == '\0')
  1042. *temp = ' ' ;
  1043. //
  1044. // flag those devices that have comm/datamodem as a
  1045. // device class
  1046. //
  1047. if (strstr( (CHAR *)linedevcaps
  1048. + linedevcaps->dwDeviceClassesOffset,
  1049. "comm/datamodem") != NULL)
  1050. {
  1051. fModem = TRUE ;
  1052. RasTapiTrace("dwCreateTapiPortsPerLine: fModem = TRUE");
  1053. }
  1054. }
  1055. if (fModem)
  1056. {
  1057. CHAR *pszRegKeyPath;
  1058. DWORD stringlen = (linedevcaps->dwLineNameSize
  1059. > MAX_DEVICE_NAME - 1
  1060. ? MAX_DEVICE_NAME - 1
  1061. : linedevcaps->dwLineNameSize);
  1062. PRODUCT_TYPE pt = PT_SERVER;
  1063. strcpy (devicetype, DEVICETYPE_UNIMODEM) ;
  1064. strncpy ( devicename,
  1065. (CHAR *)linedevcaps
  1066. + linedevcaps->dwLineNameOffset,
  1067. stringlen) ;
  1068. devicename[stringlen] = '\0' ;
  1069. //
  1070. // Get the AttachedToValue.
  1071. //
  1072. if ( retcode = ( DWORD ) lineOpen (
  1073. RasLine,
  1074. i,
  1075. &hLine,
  1076. NegotiatedApiVersion,
  1077. NegotiatedExtVersion,
  1078. 0,
  1079. LINECALLPRIVILEGE_NONE,
  1080. LINEMEDIAMODE_DATAMODEM,
  1081. &lineparams))
  1082. {
  1083. RasTapiTrace ("dwCreateTapiPortsPerLine: "
  1084. "lineOpen(%d) Failed. %d",
  1085. i,
  1086. retcode );
  1087. goto error;
  1088. }
  1089. pvar = (VARSTRING *) bvar;
  1090. pvar->dwTotalSize = sizeof (bvar);
  1091. //
  1092. // Find Out the AttachedTo address
  1093. //
  1094. if ( retcode = ( DWORD ) lineGetID (
  1095. hLine,
  1096. i,
  1097. 0,
  1098. LINECALLSELECT_LINE,
  1099. pvar,
  1100. "comm/datamodem/portname"))
  1101. {
  1102. lineClose (hLine);
  1103. RasTapiTrace("dwCreateTapiPortsPerLine: "
  1104. "lineGetID(%d) failed. %d",
  1105. i,
  1106. retcode );
  1107. goto error;
  1108. }
  1109. lineClose (hLine);
  1110. if ( 0 != pvar->dwStringSize
  1111. && 1 != pvar->dwStringSize)
  1112. {
  1113. strcpy ( address, (CHAR *) pvar + pvar->dwStringOffset );
  1114. }
  1115. else
  1116. {
  1117. RasTapiTrace(
  1118. "dwCreateTapiPortsPerLine: lineGetID(portname) "
  1119. "didn't return a portname for line %d",
  1120. i);
  1121. retcode = E_FAIL;
  1122. goto error;
  1123. }
  1124. //
  1125. // Create a device info structure for the modem and
  1126. // insert it in the deviceinfo list
  1127. //
  1128. if(NULL == (pDeviceInfo = GetDeviceInfo((LPBYTE) devicename,
  1129. TRUE)))
  1130. {
  1131. PBYTE pTempBuffer = NULL;
  1132. PBYTE pcaps = NULL;
  1133. if(NULL == (pDeviceInfo = (DeviceInfo *) LocalAlloc(
  1134. LPTR, sizeof(DeviceInfo))))
  1135. {
  1136. retcode = GetLastError();
  1137. RasTapiTrace("dwCreateTapiPortsPerLine: Failed"
  1138. " to alloc. %d",
  1139. retcode);
  1140. goto error;
  1141. }
  1142. //
  1143. // Add the device info in the global list maintained
  1144. // and fill in available information
  1145. //
  1146. pDeviceInfo->Next = g_pDeviceInfoList;
  1147. g_pDeviceInfoList = pDeviceInfo;
  1148. strcpy(
  1149. pDeviceInfo->rdiDeviceInfo.szDeviceName,
  1150. devicename);
  1151. if(linedevcaps->dwBearerModes & LINEBEARERMODE_DATA)
  1152. {
  1153. pDeviceInfo->rdiDeviceInfo.eDeviceType = RDT_Modem
  1154. | RDT_Direct
  1155. | RDT_Null_Modem;
  1156. }
  1157. else
  1158. {
  1159. pDeviceInfo->rdiDeviceInfo.eDeviceType =
  1160. RDT_Modem;
  1161. }
  1162. //
  1163. // Get the unicode version of the devicename
  1164. //
  1165. pTempBuffer = LocalAlloc(LPTR, 800);
  1166. if(NULL == pTempBuffer)
  1167. {
  1168. retcode = GetLastError();
  1169. RasTapiTrace("Failed to allocate unicode name");
  1170. goto error;
  1171. }
  1172. retcode = DwLineGetDevCaps(
  1173. i,
  1174. NegotiatedApiVersion,
  1175. NegotiatedExtVersion,
  1176. 800,
  1177. pTempBuffer,
  1178. &pBuffer,
  1179. TRUE);
  1180. if(ERROR_SUCCESS == retcode)
  1181. {
  1182. DWORD strLen = (((LINEDEVCAPS *) pBuffer)->dwLineNameSize
  1183. > sizeof(WCHAR) * (MAX_DEVICE_NAME - 1)
  1184. ? sizeof(WCHAR) * (MAX_DEVICE_NAME - 1)
  1185. : ((LINEDEVCAPS *) pBuffer)->dwLineNameSize);
  1186. CopyMemory((PBYTE) pDeviceInfo->rdiDeviceInfo.wszDeviceName,
  1187. pBuffer +
  1188. ((LINEDEVCAPS *)pBuffer)->dwLineNameOffset,
  1189. strLen);
  1190. pDeviceInfo->rdiDeviceInfo.
  1191. wszDeviceName[strLen/sizeof(WCHAR)] =
  1192. L'\0';
  1193. RasTapiTrace("ReadModemname=%ws, strlen=%d",
  1194. pDeviceInfo->rdiDeviceInfo.wszDeviceName, strlen);
  1195. }
  1196. if(NULL != pTempBuffer)
  1197. {
  1198. LocalFree(pTempBuffer);
  1199. }
  1200. if((pcaps != pTempBuffer) && (NULL != pcaps))
  1201. {
  1202. LocalFree(pcaps);
  1203. }
  1204. }
  1205. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints = 1;
  1206. RasTapiTrace("**rdiDeviceInfo.dwNumEndPoints=1");
  1207. pDeviceInfo->dwCurrentDialedInClients = 0;
  1208. pDeviceInfo->rdiDeviceInfo.dwMinWanEndPoints
  1209. = pDeviceInfo->rdiDeviceInfo.dwMaxWanEndPoints
  1210. = 1;
  1211. pDeviceInfo->rdiDeviceInfo.dwTapiLineId = dwidDevice;
  1212. pDeviceInfo->fValid = TRUE;
  1213. pszRegKeyPath = ( CHAR *) linedevcaps +
  1214. linedevcaps->dwDevSpecificOffset + 8;
  1215. if ( retcode = ( DWORD ) RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1216. pszRegKeyPath,
  1217. 0,
  1218. KEY_ALL_ACCESS,
  1219. &hkey ) )
  1220. {
  1221. RasTapiTrace("dwCreateTapiPortsPerLine: "
  1222. "failed to open %s. 0x%x",
  1223. pszRegKeyPath,
  1224. retcode );
  1225. goto error;
  1226. }
  1227. //
  1228. // Per SteveFal, we should not be posting listens on
  1229. // devices by default on workstation. The exception
  1230. // is for NULL modems because WinCE depends on this.
  1231. //
  1232. if(ERROR_SUCCESS != lrGetProductType(&pt))
  1233. {
  1234. RasTapiTrace("Failed to get product type");
  1235. }
  1236. if( (PT_WORKSTATION == pt)
  1237. && (0 == (linedevcaps->dwBearerModes & LINEBEARERMODE_DATA)))
  1238. {
  1239. //
  1240. // On a workstation don't listen on modems unless its a NULL
  1241. // modem
  1242. //
  1243. fRasEnabled = FALSE;
  1244. }
  1245. else
  1246. {
  1247. //
  1248. // We enable the devices for dial-in for all other cases
  1249. // if its a server or if its a NULL modem.
  1250. //
  1251. fRasEnabled = TRUE;
  1252. }
  1253. //
  1254. // Check to see if this device is ras enabled
  1255. //
  1256. retcode = (DWORD) lrIsModemRasEnabled(
  1257. hkey,
  1258. &fRasEnabled,
  1259. &fRouterEnabled);
  1260. pDeviceInfo->rdiDeviceInfo.fRasEnabled = fRasEnabled;
  1261. if(!fRasEnabled)
  1262. {
  1263. RasTapiTrace(
  1264. "dwCreateTapiPortsPerLine: device %s is not"
  1265. "enabled for DialIn",
  1266. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  1267. }
  1268. //
  1269. // Get the calledid info for this modem
  1270. //
  1271. retcode = DwGetCalledIdInfo(NULL,
  1272. pDeviceInfo);
  1273. if(SUCCESS != retcode)
  1274. {
  1275. RasTapiTrace("DwGetCalledIdInfo for %s returned 0x%xd",
  1276. pDeviceInfo->rdiDeviceInfo.szDeviceName,
  1277. retcode);
  1278. }
  1279. pDeviceInfo->rdiDeviceInfo.fRouterEnabled = fRouterEnabled;
  1280. if(!fRouterEnabled)
  1281. {
  1282. RasTapiTrace(
  1283. "dwCreateTapiPortsPerLine: device %s is not"
  1284. "enabled for routing",
  1285. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  1286. }
  1287. fRouterOutboundEnabled =
  1288. pDeviceInfo->rdiDeviceInfo.fRouterOutboundEnabled = FALSE;
  1289. }
  1290. else
  1291. {
  1292. //
  1293. // The address that we are returning here is the same
  1294. // for all addresses/calls on this line device. We only
  1295. // need to get it once.
  1296. //
  1297. NDIS_WAN_MEDIUM_SUBTYPE eMediaType;
  1298. if (retcode = dwGetLineAddress (NegotiatedApiVersion,
  1299. NegotiatedExtVersion,
  1300. (LPBYTE) address,
  1301. i,
  1302. 0,
  1303. szMediaName,
  1304. &eMediaType))
  1305. {
  1306. RasTapiTrace(
  1307. "dwCreateTapiPortsPerLine: dwGetLineAddrss Failed. %d",
  1308. retcode );
  1309. goto error;
  1310. }
  1311. //
  1312. // Copy the media name to devicetype
  1313. //
  1314. strncpy(devicetype, szMediaName,MAX_DEVICETYPE_NAME-1);
  1315. //
  1316. // Get the device information from registry and insert the
  1317. // device info structure in the global list
  1318. //
  1319. if (retcode = GetEndPointInfo(
  1320. &pDeviceInfo,
  1321. address,
  1322. FALSE,
  1323. eMediaType))
  1324. {
  1325. RasTapiTrace(
  1326. "dwCreateTapiPortsPerLine: Failed to get "
  1327. "deviceinformation for %s. %d",
  1328. szMediaName,
  1329. retcode );
  1330. RasTapiTrace(
  1331. "dwCreateTapiPortsPerLine: Enumerating all "
  1332. "lines/addresses on this adapter");
  1333. goto error;
  1334. }
  1335. //
  1336. // Fill in the device type for this device
  1337. //
  1338. MapNdiswanDTtoRasDT(pDeviceInfo, eMediaType);
  1339. //
  1340. // Copy the device name
  1341. //
  1342. strcpy(devicename,
  1343. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  1344. pDeviceInfo->rdiDeviceInfo.dwTapiLineId = dwidDevice;
  1345. fRasEnabled = pDeviceInfo->rdiDeviceInfo.fRasEnabled;
  1346. if (!fRasEnabled)
  1347. {
  1348. RasTapiTrace(
  1349. "dwCreateTapiPortsPerLine: Device "
  1350. "%s not enabled for DialIn",
  1351. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  1352. }
  1353. fRouterEnabled = pDeviceInfo->rdiDeviceInfo.fRouterEnabled;
  1354. if (!fRouterEnabled)
  1355. {
  1356. RasTapiTrace(
  1357. "dwCreateTapiPortsPerLine: Device %s not enabled "
  1358. "for Routing",
  1359. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  1360. }
  1361. fRouterOutboundEnabled =
  1362. pDeviceInfo->rdiDeviceInfo.fRouterOutboundEnabled;
  1363. if(!fRouterOutboundEnabled)
  1364. {
  1365. RasTapiTrace(
  1366. "dwCreateTapiPortsPerLine: Device %s not enabled "
  1367. "for outbound routing",
  1368. pDeviceInfo->rdiDeviceInfo.szDeviceName);
  1369. }
  1370. }
  1371. //
  1372. // Get Device Specific information. This is used by
  1373. // the miniport to indicate if it can support character
  1374. // mode
  1375. //
  1376. if (linedevcaps->dwDevSpecificSize
  1377. >= sizeof(RASTAPI_DEV_DATA_MODES))
  1378. {
  1379. PRASTAPI_DEV_DATA_MODES devdatamodes =
  1380. (PRASTAPI_DEV_DATA_MODES)
  1381. ((CHAR*)linedevcaps +
  1382. linedevcaps->dwDevSpecificOffset);
  1383. if ( devdatamodes->MagicCookie == MINIPORT_COOKIE
  1384. && devdatamodes->DataModes & CHAR_MODE)
  1385. {
  1386. fCharModeSupported = TRUE;
  1387. }
  1388. }
  1389. //
  1390. // A legacy device might not be filling this field. If so
  1391. // give them a single address on their line.
  1392. //
  1393. totaladdresses = (linedevcaps->dwNumAddresses == 0)
  1394. ? 1
  1395. : linedevcaps->dwNumAddresses;
  1396. for (k = 0; k < totaladdresses; k++)
  1397. {
  1398. if( (NULL != pBuffer)
  1399. && (pBufferAlloc != pBuffer))
  1400. {
  1401. LocalFree(pBuffer);
  1402. pBuffer = NULL;
  1403. }
  1404. retcode = DwLineGetAddrCaps(
  1405. i,
  1406. k,
  1407. NegotiatedApiVersion,
  1408. NegotiatedExtVersion,
  1409. 800,
  1410. pBufferAlloc,
  1411. &pBuffer);
  1412. if(SUCCESS != retcode)
  1413. {
  1414. RasTapiTrace(
  1415. "dwCreateTapiPortsPerLine: lineGetAddresscaps"
  1416. " Failed. 0x%x",
  1417. retcode );
  1418. goto error ;
  1419. }
  1420. lineaddrcaps = (LINEADDRESSCAPS *)pBuffer;
  1421. //
  1422. // Some of the legacy wan miniports might not be filling
  1423. // the NumActiveCalls correctly. They will have at least
  1424. // a single call on each address.
  1425. //
  1426. totalports += (lineaddrcaps->dwMaxNumActiveCalls == 0)
  1427. ? 1
  1428. : lineaddrcaps->dwMaxNumActiveCalls;
  1429. }
  1430. if ( ppptpcbNewPorts )
  1431. {
  1432. *ppptpcbNewPorts = LocalAlloc (
  1433. LPTR,
  1434. totalports * sizeof (TapiPortControlBlock *));
  1435. if ( NULL == *ppptpcbNewPorts )
  1436. {
  1437. retcode = ERROR_OUTOFMEMORY;
  1438. RasTapiTrace(
  1439. "dwCreateTapiPortsPerLine: LocalAlloc Failed. %d",
  1440. retcode );
  1441. goto error;
  1442. }
  1443. }
  1444. #if DBG
  1445. ASSERT( NULL != pDeviceInfo );
  1446. #endif
  1447. for (k = 0; k < totaladdresses; k++)
  1448. {
  1449. ULONG totalcalls;
  1450. if( (NULL != pBuffer)
  1451. && (pBufferAlloc != pBuffer))
  1452. {
  1453. LocalFree(pBuffer);
  1454. pBuffer = NULL;
  1455. }
  1456. retcode = DwLineGetAddrCaps(
  1457. i,
  1458. k,
  1459. NegotiatedApiVersion,
  1460. NegotiatedExtVersion,
  1461. 800,
  1462. pBufferAlloc,
  1463. &pBuffer);
  1464. if(SUCCESS != retcode)
  1465. {
  1466. RasTapiTrace(
  1467. "dwCreateTapiPortsPerLine: "
  1468. "lineGetAddressCaps() Failed."
  1469. "0x%x",
  1470. retcode );
  1471. goto error ;
  1472. }
  1473. lineaddrcaps = (LINEADDRESSCAPS *) pBuffer;
  1474. //
  1475. // Some of the legacy wan miniports might not be filling
  1476. // the NumActiveCalls correctly. They will have at least
  1477. // a single call on each address.
  1478. //
  1479. totalcalls = (lineaddrcaps->dwMaxNumActiveCalls == 0)
  1480. ? 1
  1481. : lineaddrcaps->dwMaxNumActiveCalls;
  1482. for ( ; totalcalls ; totalcalls--)
  1483. {
  1484. if (!fModem)
  1485. {
  1486. if ( pDeviceInfo->dwCurrentEndPoints >=
  1487. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints )
  1488. {
  1489. RasTapiTrace(
  1490. "dwCreateTapiPortsPerLine: "
  1491. "CurrentEndPoints=NumEndPoints=%d",
  1492. pDeviceInfo->dwCurrentEndPoints );
  1493. goto error;
  1494. }
  1495. dwEndPoints = pDeviceInfo->rdiDeviceInfo.dwNumEndPoints;
  1496. RasTapiTrace ("dwCreateTapiPortsPerLine: Total = %d",
  1497. dwEndPoints);
  1498. }
  1499. else
  1500. {
  1501. retcode = (DWORD) dwGetPortUsage(&dwPortUsage);
  1502. if ( retcode )
  1503. {
  1504. RasTapiTrace(
  1505. "dwCreateTapiPortsPerLine: failed to get "
  1506. "modem port usage for %s. 0x%x",
  1507. devicename,
  1508. retcode );
  1509. }
  1510. else
  1511. {
  1512. //
  1513. // If not rasenabled mask off the callin/router flags
  1514. //
  1515. if(!fRasEnabled)
  1516. {
  1517. dwPortUsage &= ~CALL_IN;
  1518. }
  1519. if(!fRouterEnabled)
  1520. {
  1521. dwPortUsage &= ~CALL_ROUTER;
  1522. if(fRouterOutboundEnabled)
  1523. {
  1524. dwPortUsage |= CALL_OUTBOUND_ROUTER;
  1525. }
  1526. }
  1527. RasTapiTrace("dwCreateTapiPortsPerLine: "
  1528. "PortUsage for %s = %x",
  1529. devicename,
  1530. dwPortUsage);
  1531. }
  1532. }
  1533. //
  1534. // Check to see if we already have this port
  1535. // Also get back the information if we already
  1536. // have the line.
  1537. //
  1538. if(fIsPortAlreadyPresent( i,
  1539. k, totalcalls - 1,
  1540. &nextline))
  1541. {
  1542. RasTapiTrace(
  1543. "dwCreateTapiPortsPerLine: line=%d,address=%d,"
  1544. "call=%d already present",
  1545. i,k, totalcalls - 1);
  1546. pDeviceInfo->dwCurrentEndPoints += 1;
  1547. continue;
  1548. }
  1549. if(nextline)
  1550. {
  1551. RasTapiTrace(
  1552. "dwCreateTapiPortsPerLine: line=%d already present",
  1553. i);
  1554. nextline->TLI_MultiEndpoint = TRUE;
  1555. }
  1556. else
  1557. {
  1558. RasTapiTrace(
  1559. "dwCreateTapiPortsPerLine: Creating line=%d",
  1560. i);
  1561. nextline = LocalAlloc (LPTR, sizeof ( TapiLineInfo ));
  1562. if ( NULL == nextline )
  1563. {
  1564. retcode = GetLastError();
  1565. RasTapiTrace (
  1566. "dwCreateTapiPortsPerLine: Failed to allocate"
  1567. " nextline. %d",
  1568. retcode );
  1569. goto error;
  1570. }
  1571. //
  1572. // Insert the new Line Block into global list
  1573. //
  1574. nextline->TLI_Next = RasTapiLineInfoList;
  1575. RasTapiLineInfoList = nextline;
  1576. nextline->TLI_pDeviceInfo = pDeviceInfo;
  1577. nextline->TLI_LineId = i ;
  1578. nextline->TLI_LineState = PS_CLOSED ;
  1579. nextline->NegotiatedApiVersion = NegotiatedApiVersion;
  1580. nextline->NegotiatedExtVersion = NegotiatedExtVersion;
  1581. nextline->CharModeSupported = fCharModeSupported;
  1582. }
  1583. //
  1584. // Get a available TPCB from the global pool
  1585. // this will expand the global pool if necessary
  1586. //
  1587. if (NULL == (nextport = GetNextAvailablePort( &dwPortIndex)))
  1588. {
  1589. retcode = ERROR_OUTOFMEMORY;
  1590. RasTapiTrace (
  1591. "dwCreateTapiPortsPerLine: GetNextAvailablePort "
  1592. "Failed. %d",
  1593. retcode );
  1594. goto error;
  1595. }
  1596. if (ppptpcbNewPorts)
  1597. {
  1598. (*ppptpcbNewPorts) [*pcNewPorts] = nextport;
  1599. *pcNewPorts += 1;
  1600. fIsValid = TRUE;
  1601. }
  1602. pDeviceInfo->dwCurrentEndPoints += 1;
  1603. //
  1604. // nextport is the TPCB for this address
  1605. //
  1606. nextport->TPCB_Line = nextline ;
  1607. nextport->TPCB_Endpoint = INVALID_HANDLE_VALUE ;
  1608. nextport->TPCB_AddressId = k;
  1609. nextport->TPCB_Signature = CONTROLBLOCKSIGNATURE;
  1610. nextport->TPCB_CallId = totalcalls - 1;
  1611. //
  1612. // Copy over the devicetype and devicename
  1613. //
  1614. (VOID) StringCchCopyA(nextport->TPCB_DeviceType,
  1615. MAX_DEVICETYPE_NAME,
  1616. devicetype);
  1617. //
  1618. // For unimodem devices we need to fix up names
  1619. //
  1620. if (fModem)
  1621. {
  1622. //
  1623. // Device Name is of the form "COM1: Hayes"
  1624. //
  1625. // strcpy (nextport->TPCB_Address, address);
  1626. (VOID) StringCchCopyA(nextport->TPCB_Address,
  1627. MAX_PORT_NAME,
  1628. address);
  1629. // strcpy (nextport->TPCB_DeviceName, devicename) ;
  1630. (VOID) StringCchCopyA(nextport->TPCB_DeviceName,
  1631. MAX_DEVICE_NAME,
  1632. devicename);
  1633. //
  1634. // also fix the port name to be the same as address "COM1"
  1635. //
  1636. //strcpy (nextport->TPCB_Name, address) ;
  1637. (VOID) StringCchCopyA(nextport->TPCB_Name,
  1638. MAX_PORT_NAME,
  1639. address);
  1640. }
  1641. else if(RDT_Parallel == RAS_DEVICE_TYPE(
  1642. pDeviceInfo->rdiDeviceInfo.eDeviceType
  1643. ))
  1644. {
  1645. BYTE bDevCaps[800];
  1646. LINEDEVCAPS *pLineDevCaps = NULL;
  1647. retcode = DwLineGetDevCaps(
  1648. i,
  1649. NegotiatedApiVersion,
  1650. NegotiatedExtVersion,
  1651. sizeof(bDevCaps),
  1652. bDevCaps,
  1653. (PBYTE *) &pLineDevCaps,
  1654. FALSE);
  1655. if(SUCCESS != retcode)
  1656. {
  1657. RasTapiTrace("dwCreateTapiPortsPerLine: "
  1658. "lineGetDevCaps Failed. 0x%x",
  1659. retcode );
  1660. goto error;
  1661. }
  1662. if(pLineDevCaps->dwLineNameSize > 0)
  1663. {
  1664. ZeroMemory(nextport->TPCB_Name,
  1665. MAX_PORT_NAME);
  1666. memcpy((PBYTE) nextport->TPCB_Name,
  1667. (PBYTE) (((PBYTE) pLineDevCaps) +
  1668. pLineDevCaps->dwLineNameOffset),
  1669. (pLineDevCaps->dwLineNameSize < MAX_PORT_NAME - 1)
  1670. ? pLineDevCaps->dwLineNameSize
  1671. : MAX_PORT_NAME - 1);
  1672. RasTapiTrace("dwCreateTapiPortsPerLine: found %s",
  1673. nextport->TPCB_Name);
  1674. }
  1675. else
  1676. {
  1677. RasTapiTrace("dwCreateTapiPortsPerLine: No name found!!");
  1678. wsprintf(nextport->TPCB_Name, "%s%d-%d",
  1679. szMediaName,
  1680. pDeviceInfo->dwInstanceNumber,
  1681. pDeviceInfo->dwNextPortNumber);
  1682. pDeviceInfo->dwNextPortNumber += 1;
  1683. }
  1684. if(bDevCaps != (PBYTE) pLineDevCaps)
  1685. {
  1686. LocalFree(pLineDevCaps);
  1687. }
  1688. }
  1689. else
  1690. {
  1691. wsprintf(nextport->TPCB_Name, "%s%d-%d",
  1692. szMediaName,
  1693. pDeviceInfo->dwInstanceNumber,
  1694. pDeviceInfo->dwNextPortNumber);
  1695. pDeviceInfo->dwNextPortNumber += 1;
  1696. }
  1697. if(!fModem)
  1698. {
  1699. memcpy (nextport->TPCB_Address, address, sizeof (GUID));
  1700. if (devicename[0] != '\0')
  1701. {
  1702. // strcpy (nextport->TPCB_DeviceName, devicename) ;
  1703. (VOID) StringCchCopyA(nextport->TPCB_DeviceName,
  1704. MAX_DEVICE_NAME,
  1705. devicename);
  1706. }
  1707. retcode = dwGetPortUsage(&dwPortUsage);
  1708. if (retcode)
  1709. {
  1710. RasTapiTrace ("dwCreateTapiPortsPerLine: "
  1711. "GetPortUsage failed. %d",
  1712. retcode );
  1713. }
  1714. else
  1715. {
  1716. if(!fRasEnabled)
  1717. {
  1718. dwPortUsage &= ~CALL_IN;
  1719. }
  1720. if(!fRouterEnabled)
  1721. {
  1722. dwPortUsage &= ~CALL_ROUTER;
  1723. if(fRouterOutboundEnabled)
  1724. {
  1725. dwPortUsage |= CALL_OUTBOUND_ROUTER;
  1726. }
  1727. }
  1728. }
  1729. #if 0
  1730. //
  1731. // Special Case PPPoE (not really a good thing).
  1732. // Mark the device as CALL_OUT_ONLY if nothing
  1733. // was specified in registry.
  1734. //
  1735. if( (0 == pDeviceInfo->dwUsage)
  1736. && (RDT_PPPoE == RAS_DEVICE_TYPE(
  1737. pDeviceInfo->rdiDeviceInfo.eDeviceType)))
  1738. {
  1739. pDeviceInfo->dwUsage = CALL_OUT_ONLY;
  1740. }
  1741. #endif
  1742. if(CALL_IN_ONLY & pDeviceInfo->dwUsage)
  1743. {
  1744. dwPortUsage &= ~(CALL_OUT | CALL_OUT_ONLY);
  1745. dwPortUsage |= CALL_IN_ONLY;
  1746. }
  1747. else if (CALL_OUT_ONLY & pDeviceInfo->dwUsage)
  1748. {
  1749. dwPortUsage &= ~(CALL_IN | CALL_ROUTER | CALL_IN_ONLY);
  1750. dwPortUsage |= CALL_OUT_ONLY;
  1751. }
  1752. RasTapiTrace ("dwCreateTapiPortsPerLine:"
  1753. " Friendly Name = %s",
  1754. nextport->TPCB_Name );
  1755. }
  1756. nextport->TPCB_State = PS_CLOSED ;
  1757. nextport->TPCB_Usage = dwPortUsage;
  1758. RasTapiTrace ("dwCreateTapiPortsPerLine: "
  1759. "Port Usage for %s = %d",
  1760. nextport->TPCB_Name,
  1761. dwPortUsage );
  1762. if('\0' == pDeviceInfo->rdiDeviceInfo.szPortName[0])
  1763. {
  1764. strcpy(
  1765. pDeviceInfo->rdiDeviceInfo.szPortName,
  1766. nextport->TPCB_Name);
  1767. }
  1768. //
  1769. // Initialize overlapped structures.
  1770. //
  1771. nextport->TPCB_ReadOverlapped.RO_EventType =
  1772. OVEVT_DEV_ASYNCOP;
  1773. nextport->TPCB_WriteOverlapped.RO_EventType =
  1774. OVEVT_DEV_IGNORED;
  1775. nextport->TPCB_DiscOverlapped.RO_EventType =
  1776. OVEVT_DEV_STATECHANGE;
  1777. } // total calls
  1778. } // total addresses
  1779. error:
  1780. if( retcode
  1781. || !fIsValid)
  1782. {
  1783. if(pcNewPorts)
  1784. {
  1785. *pcNewPorts = 0;
  1786. }
  1787. if( ppptpcbNewPorts
  1788. && *ppptpcbNewPorts)
  1789. {
  1790. LocalFree(*ppptpcbNewPorts);
  1791. *ppptpcbNewPorts = NULL;
  1792. }
  1793. }
  1794. if( (NULL != pBufferAlloc)
  1795. && (pBufferAlloc != pBuffer))
  1796. {
  1797. LocalFree(pBuffer);
  1798. }
  1799. LocalFree(pBufferAlloc);
  1800. RasTapiTrace ("dwGetFriendlyNameAndUsage: done. %d", retcode );
  1801. RasTapiTrace(" ");
  1802. return retcode;
  1803. }
  1804. VOID
  1805. InitializeDialInRestriction()
  1806. {
  1807. OSVERSIONINFOEX osvi;
  1808. ULONGLONG ConditionMask;
  1809. //
  1810. // if its a server and the flavour is not Enterprise (ads) or DataCenter
  1811. // apply the restriction. Note his doesn't take care of various other
  1812. // combinations like embedded/blade, etc.
  1813. //
  1814. ConditionMask = 0;
  1815. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  1816. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  1817. osvi.wProductType = (USHORT)VER_NT_SERVER;
  1818. VER_SET_CONDITION(ConditionMask, VER_PRODUCT_TYPE, VER_EQUAL);
  1819. if(VerifyVersionInfo(&osvi, VER_PRODUCT_TYPE, ConditionMask))
  1820. {
  1821. RasTapiTrace("ProductType is Server");
  1822. ConditionMask = 0;
  1823. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  1824. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  1825. osvi.wSuiteMask = VER_SUITE_ENTERPRISE
  1826. | VER_SUITE_DATACENTER
  1827. | VER_SUITE_SECURITY_APPLIANCE;
  1828. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_OR);
  1829. if(VerifyVersionInfo(&osvi, VER_SUITENAME, ConditionMask))
  1830. {
  1831. RasTapiTrace("Flavour is ads or dtc. No restriction applied");
  1832. g_fRestrictDialIn = FALSE;
  1833. }
  1834. else
  1835. {
  1836. RasTapiTrace("Flavour is neither ads nor dtc. Max allowed"
  1837. " dialin=%d", MAX_ALLOWED_DIALIN);
  1838. g_fRestrictDialIn = TRUE;
  1839. }
  1840. }
  1841. else
  1842. {
  1843. RasTapiTrace("ProductType is not Server");
  1844. }
  1845. }
  1846. /*++
  1847. Routine Description:
  1848. Enumerates all lines available in the system and creates
  1849. rastapi ports from each of the lines. Most of the work
  1850. is done by dwCreateTapiPortsPerLine function.
  1851. Arguments:
  1852. event - Event handle. This handle is signalled when the
  1853. enumeration is over.
  1854. Return Value:
  1855. SUCCESS if operation was successful. error otherwise.
  1856. --*/
  1857. DWORD
  1858. EnumerateTapiPorts (HANDLE event)
  1859. {
  1860. WORD i ;
  1861. DWORD lines = 0 ;
  1862. MSG msg ;
  1863. HINSTANCE hInst;
  1864. TapiPortControlBlock *pports ;
  1865. LINEINITIALIZEEXPARAMS param ;
  1866. DWORD version = HIGH_VERSION ;
  1867. HKEY hkey = NULL;
  1868. DWORD retcode;
  1869. RasTapiTrace("EnumerateTapiPorts");
  1870. memset (&param, 0, sizeof (LINEINITIALIZEEXPARAMS)) ;
  1871. param.dwOptions = LINEINITIALIZEEXOPTION_USEHIDDENWINDOW ;
  1872. param.dwTotalSize = sizeof(param) ;
  1873. //
  1874. // lineInitialize
  1875. //
  1876. if (lineInitializeEx (&RasLine,
  1877. RasInstance,
  1878. (LINECALLBACK) RasTapiCallback,
  1879. REMOTEACCESS_APP,
  1880. &lines,
  1881. &version,
  1882. &param))
  1883. {
  1884. RasTapiTrace( "EnumerateTapiPorts: lineInitializeEx Failed" );
  1885. goto error ;
  1886. }
  1887. RasTapiTrace( "EnumerateTapiPorts: Number of lines = %d",
  1888. lines );
  1889. if (lines == 0)
  1890. {
  1891. goto error;
  1892. }
  1893. TotalLines = lines;
  1894. for ( i = 0; i < lines; i++ )
  1895. {
  1896. dwCreateTapiPortsPerLine( i,
  1897. NULL,
  1898. NULL);
  1899. }
  1900. InitializeDialInRestriction();
  1901. //
  1902. // Calculate the number of valid ports
  1903. //
  1904. pports = RasPortsList;
  1905. while ( pports )
  1906. {
  1907. if (pports->TPCB_State != PS_UNINITIALIZED)
  1908. ValidPorts++;
  1909. pports = pports->TPCB_next;
  1910. }
  1911. dwGetNumberOfRings( &NumberOfRings );
  1912. //
  1913. // Increase the reference count on our DLL
  1914. // so it won't get unloaded out from under us.
  1915. //
  1916. hInst = LoadLibrary("rastapi.dll");
  1917. g_fDllLoaded = TRUE;
  1918. //
  1919. // Notify the api that the initialization is done
  1920. //
  1921. SetEvent (event) ;
  1922. //
  1923. // In the pnp world, we need to hang around even if
  1924. // there aren't any ports. ports may be added on the
  1925. // fly
  1926. //
  1927. while ((retcode = GetMessage(&msg, NULL, 0, 0)) &&
  1928. (retcode != -1))
  1929. {
  1930. TranslateMessage(&msg);
  1931. DispatchMessage(&msg) ;
  1932. }
  1933. if(retcode == -1)
  1934. {
  1935. retcode = GetLastError();
  1936. RasTapiTrace("GetMessage failed and returned -1. rc=0x%x",
  1937. retcode);
  1938. }
  1939. lineShutdown (RasLine) ;
  1940. RasLine = 0;
  1941. RasTapiTrace("EnumerateTapiPorts done");
  1942. RasTapiTrace(" ");
  1943. TraceDeregister( dwTraceId );
  1944. dwTraceId = INVALID_TRACEID;
  1945. //
  1946. // The following call atomically unloads our
  1947. // DLL and terminates this thread.
  1948. //
  1949. FreeLibraryAndExitThread(hInst, SUCCESS);
  1950. error:
  1951. if (RasLine)
  1952. {
  1953. lineShutdown (RasLine) ;
  1954. }
  1955. if(INVALID_TRACEID != dwTraceId)
  1956. {
  1957. TraceDeregister( dwTraceId );
  1958. dwTraceId = INVALID_TRACEID;
  1959. }
  1960. RasLine = 0 ;
  1961. SetEvent (event) ;
  1962. return ((DWORD)-1) ;
  1963. }
  1964. DWORD
  1965. DwDropIncomingCall(HCALL hcall)
  1966. {
  1967. DWORD RequestID;
  1968. DWORD retcode = ERROR_SUCCESS;
  1969. ZOMBIE_CALL *ZombieCall;
  1970. ZombieCall = LocalAlloc(LPTR, sizeof(ZOMBIE_CALL));
  1971. if (ZombieCall == NULL)
  1972. {
  1973. retcode = GetLastError();
  1974. RasTapiTrace ( "DwDropIncomingCall: Failed to allocate Zombie" );
  1975. goto done;
  1976. }
  1977. //
  1978. // We will initiate a drop of the call and insert an element on our
  1979. // zombie call list so we can deallocate the call when the drop
  1980. // completes.
  1981. //
  1982. RequestID = lineDrop(hcall, NULL, 0);
  1983. if ( RequestID == 0
  1984. || RequestID > 0x80000000)
  1985. {
  1986. //
  1987. // Either the drop completed sync or there was
  1988. // an error. Either way just deallocate the call.
  1989. //
  1990. lineDeallocateCall(hcall);
  1991. RasTapiTrace("DwIncomingCall: lineDeallocateCall. RequestID = 0x%x",
  1992. RequestID );
  1993. }
  1994. ZombieCall->hCall = hcall;
  1995. ZombieCall->RequestID = RequestID;
  1996. InsertHeadList(&ZombieCallList, &ZombieCall->Linkage);
  1997. done:
  1998. return retcode;
  1999. }
  2000. /*++
  2001. Routine Description:
  2002. Processes the LINECALLSTATE_OFFERING event.
  2003. Arguments:
  2004. hcall - handle of call being offerred
  2005. ppPort - address of location where the port answering
  2006. the call will be returned.
  2007. line - the line on which the call was offered.
  2008. Return Value:
  2009. SUCCESS if operation was successful. error otherwise.
  2010. --*/
  2011. DWORD
  2012. DwProcessOfferEvent(HCALL hcall,
  2013. TapiPortControlBlock **ppPort,
  2014. TapiLineInfo *line)
  2015. {
  2016. TapiPortControlBlock *port = NULL;
  2017. LINECALLINFO *linecallinfo;
  2018. BYTE buffer[1000];
  2019. BOOL fLimitReached = FALSE;
  2020. DWORD retcode = SUCCESS;
  2021. memset (buffer, 0, sizeof(buffer)) ;
  2022. linecallinfo = (LINECALLINFO *) buffer ;
  2023. linecallinfo->dwTotalSize = sizeof(buffer) ;
  2024. RasTapiTrace("DwProcessOfferEvent: hcall=0x%x",
  2025. hcall);
  2026. //
  2027. // If line get call info fails return.
  2028. //
  2029. if ((retcode = lineGetCallInfo (
  2030. hcall,
  2031. linecallinfo))
  2032. > 0x80000000)
  2033. {
  2034. RasTapiTrace("DwProcessOfferEvent: LINE_CALLSTATE - "
  2035. "lineGetCallInfo Failed. %d",
  2036. retcode );
  2037. goto done ;
  2038. }
  2039. //
  2040. // Find a listening port. First check to see if there are restrictions
  2041. // on the maximum number of dialin ports.
  2042. //
  2043. if ( (g_fRestrictDialIn
  2044. && g_dwTotalDialIn >= MAX_ALLOWED_DIALIN)
  2045. || (NULL == (port = FindListeningPort(
  2046. line,
  2047. linecallinfo->dwAddressID))))
  2048. {
  2049. if(g_dwTotalDialIn >= MAX_ALLOWED_DIALIN)
  2050. {
  2051. RasTapiTrace("DwProcessOfferEvent: Total Dialin clients exceeded"
  2052. " limit. Dropping call 0x%x",
  2053. hcall);
  2054. }
  2055. else
  2056. {
  2057. RasTapiTrace("DwProcessOfferEvent: Couldn't find a listening "
  2058. "port. Dropping call 0x%x",
  2059. hcall);
  2060. }
  2061. (VOID) DwDropIncomingCall(hcall);
  2062. retcode = E_FAIL;
  2063. goto done;
  2064. }
  2065. port->TPCB_CallHandle = hcall ;
  2066. *ppPort = port;
  2067. //
  2068. // for unimodem devices wait for the specified
  2069. // number of rings
  2070. //
  2071. if (_stricmp (port->TPCB_DeviceType,
  2072. DEVICETYPE_UNIMODEM) == 0)
  2073. {
  2074. //
  2075. // call has already been answered by somebody
  2076. // else and is being offered to me
  2077. //
  2078. if (linecallinfo->dwCallStates
  2079. == LINECALLSTATE_CONNECTED)
  2080. {
  2081. RasTapiTrace ("DwProcessOfferEvent: call already "
  2082. "answered on %s",
  2083. port->TPCB_Name );
  2084. port->TPCB_ListenState = LS_COMPLETE ;
  2085. //
  2086. // Complete event so that rasman calls
  2087. // DeviceWork to proceed the listen
  2088. // state machine.
  2089. //
  2090. PostNotificationCompletion(port);
  2091. }
  2092. else
  2093. {
  2094. if(0 == NumberOfRings)
  2095. {
  2096. port->TPCB_ListenState = LS_ACCEPT;
  2097. RasTapiTrace( "Accepting call on %s hcall = 0x%x",
  2098. port->TPCB_Name,
  2099. hcall);
  2100. port->TPCB_NumberOfRings = 0;
  2101. PostNotificationCompletion(port);
  2102. }
  2103. else
  2104. {
  2105. RasTapiTrace(
  2106. "DwProcessOfferEvent: changing listenstate"
  2107. " of %s from %d to LS_RINGING",
  2108. port->TPCB_Name,
  2109. port->TPCB_ListenState);
  2110. port->TPCB_ListenState = LS_RINGING ;
  2111. port->TPCB_NumberOfRings = NumberOfRings ;
  2112. }
  2113. if(line->TLI_pDeviceInfo)
  2114. {
  2115. line->TLI_pDeviceInfo->dwCurrentDialedInClients += 1;
  2116. }
  2117. g_dwTotalDialIn += 1;
  2118. RasTapiTrace( "%s InClients=%d, TotalDialInClients=%d",
  2119. line->TLI_pDeviceInfo->rdiDeviceInfo.szDeviceName,
  2120. line->TLI_pDeviceInfo->dwCurrentDialedInClients,
  2121. g_dwTotalDialIn);
  2122. port->TPCB_dwFlags |= RASTAPI_FLAG_DIALEDIN;
  2123. }
  2124. }
  2125. else
  2126. {
  2127. //
  2128. // For other devices make transition to
  2129. // next listening state
  2130. //
  2131. port->TPCB_ListenState = LS_ACCEPT ;
  2132. RasTapiTrace("DwProcessOfferEvent: Accepting call on %s"
  2133. " hcall = 0x%x",
  2134. port->TPCB_Name,
  2135. hcall);
  2136. if(line->TLI_pDeviceInfo)
  2137. {
  2138. line->TLI_pDeviceInfo->dwCurrentDialedInClients += 1;
  2139. }
  2140. g_dwTotalDialIn += 1;
  2141. RasTapiTrace( "%s InClients=%d, TotalDialInClients=%d",
  2142. line->TLI_pDeviceInfo->rdiDeviceInfo.szDeviceName,
  2143. line->TLI_pDeviceInfo->dwCurrentDialedInClients,
  2144. g_dwTotalDialIn);
  2145. port->TPCB_dwFlags |= RASTAPI_FLAG_DIALEDIN;
  2146. //
  2147. // Complete event so that rasman calls DeviceWork
  2148. // to proceed the listen state machine.
  2149. //
  2150. PostNotificationCompletion(port);
  2151. }
  2152. done:
  2153. RasTapiTrace("DwProcessOfferEvent 0x%x",
  2154. retcode);
  2155. return retcode;
  2156. }
  2157. /*++
  2158. Routine Description:
  2159. maps LINEDISCONNECTMODE to a raserror so that the proper
  2160. error string can be displayed to the user.
  2161. Arguments:
  2162. dm - DisconnectMode
  2163. Return Value:
  2164. RasError corresponding to the disconnect mode.
  2165. --*/
  2166. DWORD
  2167. DwRasErrorFromDisconnectMode(DWORD dm)
  2168. {
  2169. DWORD dwErr;
  2170. switch (dm)
  2171. {
  2172. case LINEDISCONNECTMODE_BUSY:
  2173. {
  2174. dwErr = ERROR_LINE_BUSY;
  2175. break;
  2176. }
  2177. case LINEDISCONNECTMODE_NOANSWER:
  2178. {
  2179. dwErr = ERROR_NO_ANSWER;
  2180. break;
  2181. }
  2182. case LINEDISCONNECTMODE_OUTOFORDER:
  2183. {
  2184. dwErr = ERROR_OUTOFORDER;
  2185. break;
  2186. }
  2187. case LINEDISCONNECTMODE_NODIALTONE:
  2188. {
  2189. dwErr = ERROR_NO_DIALTONE;
  2190. break;
  2191. }
  2192. case LINEDISCONNECTMODE_CANCELLED:
  2193. {
  2194. dwErr = ERROR_USER_DISCONNECTION;
  2195. break;
  2196. }
  2197. case LINEDISCONNECTMODE_UNREACHABLE:
  2198. case LINEDISCONNECTMODE_BADADDRESS:
  2199. {
  2200. dwErr = ERROR_BAD_ADDRESS_SPECIFIED;
  2201. break;
  2202. }
  2203. case LINEDISCONNECTMODE_REJECT:
  2204. {
  2205. dwErr = ERROR_CONNECTION_REJECT;
  2206. break;
  2207. }
  2208. case LINEDISCONNECTMODE_CONGESTION:
  2209. {
  2210. dwErr = ERROR_CONGESTION;
  2211. break;
  2212. }
  2213. case LINEDISCONNECTMODE_INCOMPATIBLE:
  2214. {
  2215. dwErr = ERROR_INCOMPATIBLE;
  2216. break;
  2217. }
  2218. case LINEDISCONNECTMODE_NUMBERCHANGED:
  2219. {
  2220. dwErr = ERROR_NUMBERCHANGED;
  2221. break;
  2222. }
  2223. case LINEDISCONNECTMODE_TEMPFAILURE:
  2224. {
  2225. dwErr = ERROR_TEMPFAILURE;
  2226. break;
  2227. }
  2228. case LINEDISCONNECTMODE_BLOCKED:
  2229. {
  2230. dwErr = ERROR_BLOCKED;
  2231. break;
  2232. }
  2233. case LINEDISCONNECTMODE_DONOTDISTURB:
  2234. {
  2235. dwErr = ERROR_DONOTDISTURB;
  2236. break;
  2237. }
  2238. default:
  2239. {
  2240. dwErr = ERROR_FROM_DEVICE;
  2241. break;
  2242. }
  2243. }
  2244. return dwErr;
  2245. }
  2246. /*++
  2247. Routine Description:
  2248. Tapi Call back function as described in win32 sdk.
  2249. Arguments:
  2250. win32 sdk has explanation of each of the arguments.
  2251. Return Value:
  2252. void
  2253. --*/
  2254. VOID FAR PASCAL
  2255. RasTapiCallback (HANDLE context,
  2256. DWORD msg,
  2257. ULONG_PTR instance,
  2258. ULONG_PTR param1,
  2259. ULONG_PTR param2,
  2260. ULONG_PTR param3
  2261. )
  2262. {
  2263. LINECALLINFO *linecallinfo ;
  2264. BYTE buffer [1000] ;
  2265. HCALL hcall ;
  2266. HLINE linehandle ;
  2267. TapiLineInfo *line ;
  2268. TapiPortControlBlock *port = NULL;
  2269. DWORD i ;
  2270. DWORD retcode ;
  2271. BOOL fLimitReached = FALSE;
  2272. // **** Exclusion Begin ****
  2273. GetMutex (RasTapiMutex, INFINITE) ;
  2274. RasTapiTrace("RasTapicallback: msg=%ld , param1=%ul , param2=%ul",msg,param1,param2 );
  2275. switch (msg)
  2276. {
  2277. case LINE_CALLSTATE:
  2278. hcall = (HCALL) HandleToUlong(context) ;
  2279. line = (TapiLineInfo *) instance ;
  2280. RasTapiTrace("RasTapicallback: linecallstate=0x%x", param1);
  2281. //
  2282. // If line is closed dont bother
  2283. //
  2284. if (line->TLI_LineState == PS_CLOSED)
  2285. {
  2286. RasTapiTrace ("RasTapiCallback: LINE_CALLSTATE - "
  2287. "linestate = PS_CLOSED" );
  2288. break ;
  2289. }
  2290. //
  2291. // A new call is coming in
  2292. //
  2293. if (param1 == LINECALLSTATE_OFFERING)
  2294. {
  2295. retcode = DwProcessOfferEvent(hcall,
  2296. &port,
  2297. line);
  2298. if(ERROR_SUCCESS != retcode)
  2299. {
  2300. RasTapiTrace("DwProcessOfferEvent failed. 0x%x",
  2301. retcode);
  2302. break;
  2303. }
  2304. }
  2305. //
  2306. // Find port by call handle
  2307. //
  2308. if ( (NULL == port)
  2309. && ((port = FindPortByCallHandle(line, hcall)) == NULL)
  2310. && (LINECALLSTATE_CONNECTED != param1))
  2311. {
  2312. RasTapiTrace ("RasTapiCallback: FindPortByCallHandle, "
  2313. "hcall = 0x%x failed",
  2314. hcall );
  2315. break;
  2316. }
  2317. else if ( (NULL == port)
  2318. && (LINECALLSTATE_CONNECTED == param1))
  2319. {
  2320. RasTapiTrace("Some one else has already answered "
  2321. "the call ");
  2322. retcode = DwProcessOfferEvent(hcall,
  2323. &port,
  2324. line);
  2325. if( (ERROR_SUCCESS != retcode)
  2326. || (NULL == port))
  2327. {
  2328. RasTapiTrace("DwProcessOfferEvent failed. 0x%x",
  2329. retcode);
  2330. break;
  2331. }
  2332. }
  2333. //
  2334. // Call connected.
  2335. //
  2336. if (param1 == LINECALLSTATE_CONNECTED)
  2337. {
  2338. if(NULL == port->TPCB_pConnectInfo)
  2339. {
  2340. memset (buffer, 0, sizeof(buffer)) ;
  2341. linecallinfo = (LINECALLINFO *) buffer ;
  2342. linecallinfo->dwTotalSize = sizeof(buffer) ;
  2343. if ((retcode = lineGetCallInfo (
  2344. hcall,
  2345. linecallinfo))
  2346. > 0x80000000)
  2347. {
  2348. if( (LINEERR_STRUCTURETOOSMALL == retcode)
  2349. || (linecallinfo->dwNeededSize > sizeof(buffer)))
  2350. {
  2351. DWORD dwSizeNeeded =
  2352. linecallinfo->dwNeededSize;
  2353. //
  2354. // Allocate the correct size and call
  2355. // the api again
  2356. //
  2357. linecallinfo = LocalAlloc(LPTR,
  2358. dwSizeNeeded);
  2359. if(NULL == linecallinfo)
  2360. {
  2361. retcode = GetLastError();
  2362. break;
  2363. }
  2364. linecallinfo->dwTotalSize = dwSizeNeeded;
  2365. retcode = lineGetCallInfo(
  2366. hcall,
  2367. linecallinfo);
  2368. }
  2369. }
  2370. if(retcode > 0x80000000)
  2371. {
  2372. RasTapiTrace("RasTapiCallback: LINE_CALLSTATE - "
  2373. "lineGetCallInfo Failed. %d",
  2374. retcode );
  2375. if(buffer != (PBYTE) linecallinfo)
  2376. {
  2377. LocalFree(linecallinfo);
  2378. }
  2379. break ;
  2380. }
  2381. //
  2382. // Do the work to get CONNECTINFO, CALLER/CALLEDID
  2383. //
  2384. retcode = DwGetConnectInfo(port,
  2385. hcall,
  2386. linecallinfo);
  2387. RasTapiTrace("RasTapiCallback: DwGetConnectInfo"
  2388. "returned 0x%x",
  2389. retcode);
  2390. //
  2391. // don't want to stop the dial from happening
  2392. // because we couldn't the connect info
  2393. //
  2394. retcode = SUCCESS;
  2395. //
  2396. // Free the linecallinfo struct. if we allocated
  2397. // it above
  2398. //
  2399. if(buffer != (PBYTE) linecallinfo)
  2400. {
  2401. LocalFree(linecallinfo);
  2402. }
  2403. }
  2404. RasTapiTrace("RasTapiCallback: Connected on %s",
  2405. port->TPCB_Name);
  2406. if (port->TPCB_State == PS_CONNECTING)
  2407. {
  2408. RasTapiTrace("RasTapiCallback: Outgoing call");
  2409. //
  2410. // We were requesting the call. Complete event
  2411. // so that rasman calls DeviceWork() to complete
  2412. // the connection process.
  2413. //
  2414. PostNotificationCompletion(port);
  2415. }
  2416. else
  2417. {
  2418. //
  2419. // This is a call we are asnwering. Now we can
  2420. // indicate to rasman that the call has come in.
  2421. // Setting listen state to LS_COMPLETE may be
  2422. // redundant but handles the case where the answer
  2423. // completes *after* the connection is indicated
  2424. //
  2425. port->TPCB_ListenState = LS_COMPLETE ;
  2426. RasTapiTrace ("RasTapiCallback: Incoming Call");
  2427. //
  2428. // Complete event so that rasman knows of
  2429. // incoming call and calls devicework.
  2430. //
  2431. PostNotificationCompletion(port);
  2432. }
  2433. }
  2434. //
  2435. // Failure of sorts.
  2436. //
  2437. if ( (param1 == LINECALLSTATE_BUSY)
  2438. || (param1 == LINECALLSTATE_SPECIALINFO))
  2439. {
  2440. RasTapiTrace(
  2441. "RasTapiCallback: LINECALLSTATE."
  2442. " Failure. param1 = 0x%x",
  2443. param1 );
  2444. //
  2445. // If we were connecting, notify rasman to call
  2446. // devicework so that the connection attempt can
  2447. // be gracefully failed.
  2448. //
  2449. if (port->TPCB_State == PS_CONNECTING)
  2450. {
  2451. PostNotificationCompletion(port);
  2452. }
  2453. }
  2454. //
  2455. // Disconnection happened
  2456. //
  2457. if (param1 == LINECALLSTATE_DISCONNECTED)
  2458. {
  2459. //
  2460. // If we were connecting, notify rasman to call
  2461. // devicework so that the connection attempt can
  2462. // be gracefully failed.
  2463. //
  2464. if (port->TPCB_State == PS_CONNECTING)
  2465. {
  2466. /*
  2467. if (param2 == LINEDISCONNECTMODE_BUSY)
  2468. {
  2469. port->TPCB_AsyncErrorCode = ERROR_LINE_BUSY ;
  2470. }
  2471. else if ( (param2 == LINEDISCONNECTMODE_NOANSWER)
  2472. || (param2 == LINEDISCONNECTMODE_OUTOFORDER))
  2473. {
  2474. port->TPCB_AsyncErrorCode = ERROR_NO_ANSWER ;
  2475. }
  2476. else if (param2 == LINEDISCONNECTMODE_NODIALTONE)
  2477. {
  2478. port->TPCB_AsyncErrorCode = ERROR_NO_DIALTONE ;
  2479. }
  2480. else if (param2 == LINEDISCONNECTMODE_CANCELLED)
  2481. {
  2482. port->TPCB_AsyncErrorCode
  2483. = ERROR_USER_DISCONNECTION;
  2484. }
  2485. else if (param2 == LINEDISCONNECTMODE_BADADDRESS)
  2486. {
  2487. port->TPCB_AsyncErrorCode
  2488. = ERROR_BAD_ADDRESS_SPECIFIED;
  2489. }
  2490. */
  2491. port->TPCB_AsyncErrorCode =
  2492. DwRasErrorFromDisconnectMode((DWORD) param2);
  2493. RasTapiTrace("RasTapiCallback: "
  2494. "LINECALLSTATE_DISCONNECTED "
  2495. "for port %s. AsyncErr = %d, "
  2496. "param2=0x%x",
  2497. port->TPCB_Name,
  2498. port->TPCB_AsyncErrorCode,
  2499. param2);
  2500. PostNotificationCompletion(port);
  2501. }
  2502. else if (port->TPCB_State != PS_CLOSED)
  2503. {
  2504. //
  2505. // If we were connected and got a disconnect
  2506. // notification then this could be hardware
  2507. // failure or a remote disconnection. Determine
  2508. // this and save the reason away.
  2509. //
  2510. if (port->TPCB_State == PS_CONNECTED)
  2511. {
  2512. LINECALLSTATUS *pcallstatus ;
  2513. BYTE LineCallStatusBuffer[200] ;
  2514. memset (LineCallStatusBuffer, 0, sizeof(LineCallStatusBuffer)) ;
  2515. pcallstatus = (LINECALLSTATUS *) LineCallStatusBuffer ;
  2516. pcallstatus->dwTotalSize = sizeof (LineCallStatusBuffer) ;
  2517. lineGetCallStatus (
  2518. port->TPCB_CallHandle,
  2519. pcallstatus) ;
  2520. if (pcallstatus->dwCallState ==
  2521. LINECALLSTATE_DISCONNECTED)
  2522. {
  2523. port->TPCB_DisconnectReason =
  2524. SS_LINKDROPPED ;
  2525. }
  2526. else
  2527. {
  2528. port->TPCB_DisconnectReason =
  2529. SS_HARDWAREFAILURE ;
  2530. }
  2531. RasTapiTrace("RasTapiCallback: "
  2532. "lineGetCallStatus"
  2533. " for %s returned 0x%x",
  2534. port->TPCB_Name,
  2535. pcallstatus->dwCallState );
  2536. RasTapiTrace ("RasTapiCallback: "
  2537. "DisconnectReason "
  2538. "mapped to %d",
  2539. port->TPCB_DisconnectReason);
  2540. }
  2541. else
  2542. {
  2543. port->TPCB_DisconnectReason = 0 ;
  2544. }
  2545. //
  2546. // This means that we got a disconnect indication
  2547. // in one of the other states (listening, connected,
  2548. // etc.). We initiate our disconnect state machine.
  2549. //
  2550. RasTapiTrace ("RasTapiCallback: LINECALLSTATE"
  2551. " - initiating Port Disconnect");
  2552. if (InitiatePortDisconnection (port) != PENDING)
  2553. {
  2554. //
  2555. // Disconnection succeeded or failed. Both
  2556. // are end states for the disconnect state
  2557. // machine so notify rasman that a
  2558. // disconnection has happened.
  2559. //
  2560. RasTapiTrace ("RasTapiCallback: "
  2561. "PortDisconnected sync");
  2562. PostDisconnectCompletion(port);
  2563. }
  2564. }
  2565. }
  2566. //
  2567. // A busy call state - our attempt to dialout failed
  2568. //
  2569. if (param1 == LINECALLSTATE_BUSY)
  2570. {
  2571. if (port->TPCB_State == PS_CONNECTING)
  2572. {
  2573. port->TPCB_AsyncErrorCode = ERROR_LINE_BUSY ;
  2574. RasTapiTrace("RasTapiCallback: Failed to initiate "
  2575. "connection. LINECALLSTATE_BUSY" );
  2576. PostNotificationCompletion(port);
  2577. }
  2578. }
  2579. //
  2580. // Idle indication is useful to complete the disconnect
  2581. // state machine.
  2582. //
  2583. if (param1 == LINECALLSTATE_IDLE)
  2584. {
  2585. if ( ( (port->TPCB_State == PS_DISCONNECTING)
  2586. && (port->TPCB_RequestId == INFINITE))
  2587. || ( (port->TPCB_State == PS_OPEN )
  2588. && (port->TPCB_ListenState == LS_RINGING))
  2589. || ( (PS_UNAVAILABLE == port->TPCB_State))
  2590. || ( (port->TPCB_ListenState == LS_RINGING)
  2591. && (port->TPCB_State == PS_LISTENING)))
  2592. {
  2593. if ( LS_RINGING == port->TPCB_ListenState )
  2594. {
  2595. RasTapiTrace("RasTapiCallback: Receied IDLE in "
  2596. "LS_RINGING state!" );
  2597. port->TPCB_DisconnectReason = SS_HARDWAREFAILURE;
  2598. }
  2599. //
  2600. // IDLE notification came after LineDrop Succeeded
  2601. // so safe to deallocate the call
  2602. //
  2603. if(PS_UNAVAILABLE != port->TPCB_State)
  2604. {
  2605. port->TPCB_State = PS_OPEN ;
  2606. }
  2607. RasTapiTrace(
  2608. "RasTapiCallback: Received Idle. "
  2609. "Deallocating for %s, callhandle = 0x%x",
  2610. port->TPCB_Name,
  2611. port->TPCB_CallHandle );
  2612. lineDeallocateCall (port->TPCB_CallHandle) ;
  2613. port->TPCB_CallHandle = (HCALL) -1 ;
  2614. port->IdleReceived = FALSE;
  2615. PostDisconnectCompletion(port);
  2616. }
  2617. else
  2618. {
  2619. //
  2620. // We have not yet disconnected so do not
  2621. // deallocate call yet. This will be done
  2622. // when the disconnect completes.
  2623. //
  2624. port->IdleReceived = TRUE;
  2625. }
  2626. }
  2627. break ;
  2628. case LINE_REPLY:
  2629. RasTapiTrace("LINE_REPLY. param1=0x%x", param1);
  2630. //
  2631. // This message is sent to indicate completion of an
  2632. // asynchronous API.Find for which port the async request
  2633. // succeeded. This is done by searching for pending
  2634. // request id that is also provided in this message.
  2635. //
  2636. if ((port = FindPortByRequestId ((DWORD) param1)) == NULL)
  2637. {
  2638. ZOMBIE_CALL *ZombieCall =
  2639. (ZOMBIE_CALL*)ZombieCallList.Flink;
  2640. RasTapiTrace("PortByRequestId found");
  2641. //
  2642. // If this is the completion of a drop that is
  2643. // in the zombie call state just deallocate
  2644. // the call.
  2645. //
  2646. while ((PLIST_ENTRY)ZombieCall != &ZombieCallList)
  2647. {
  2648. if (param1 = ZombieCall->RequestID)
  2649. {
  2650. RasTapiTrace (
  2651. "RasTapiCallback: LINE_REPLY "
  2652. "Deallocatingcall. hcall = 0x%x",
  2653. ZombieCall->hCall );
  2654. lineDeallocateCall(ZombieCall->hCall);
  2655. RemoveEntryList(&ZombieCall->Linkage);
  2656. LocalFree(ZombieCall);
  2657. break;
  2658. }
  2659. ZombieCall = (ZOMBIE_CALL*)
  2660. ZombieCall->Linkage.Flink;
  2661. }
  2662. break ;
  2663. }
  2664. else
  2665. ;
  2666. if (port->TPCB_SendRequestId == param1)
  2667. {
  2668. //
  2669. // A char mode send has completed. Clean up
  2670. // the buffer and notify rasman.
  2671. //
  2672. port->TPCB_SendRequestId = INFINITE;
  2673. //
  2674. // Free the send desc
  2675. //
  2676. LocalFree(port->TPCB_SendDesc);
  2677. port->TPCB_SendDesc = NULL;
  2678. }
  2679. else if (port->TPCB_RecvRequestId == param1)
  2680. {
  2681. //
  2682. // A char mode recv has completed.
  2683. //
  2684. port->TPCB_RecvRequestId = INFINITE;
  2685. //
  2686. // If possible notify rasman
  2687. //
  2688. if (port->TPCB_State == PS_CONNECTED)
  2689. {
  2690. //
  2691. // Copy into circular buffer
  2692. //
  2693. CopyDataToFifo(port->TPCB_RecvFifo,
  2694. ((PRASTAPI_DEV_SPECIFIC)
  2695. (port->TPCB_RecvDesc))->Data,
  2696. ((PRASTAPI_DEV_SPECIFIC)
  2697. (port->TPCB_RecvDesc))->DataSize);
  2698. }
  2699. PostNotificationCompletion( port );
  2700. //
  2701. // Free the recv desc
  2702. //
  2703. LocalFree(port->TPCB_RecvDesc);
  2704. port->TPCB_RecvDesc = NULL;
  2705. }
  2706. else if (port->TPCB_ModeRequestId == param1)
  2707. {
  2708. LocalFree(port->TPCB_ModeRequestDesc);
  2709. port->TPCB_ModeRequestDesc = NULL;
  2710. }
  2711. else
  2712. {
  2713. //
  2714. // Set request id to invalid.
  2715. //
  2716. port->TPCB_RequestId = INFINITE ;
  2717. if ( (PS_DISCONNECTING == port->TPCB_State)
  2718. || (PS_UNAVAILABLE == port->TPCB_State))
  2719. {
  2720. //
  2721. // lineDrop completed. Clear the flag that we set to indicate
  2722. // pend of linedrop.
  2723. //
  2724. RasTapiTrace("RasTapiCallback: lineDropped. port %s, id=0x%x",
  2725. port->TPCB_Name,
  2726. port->TPCB_RequestId);
  2727. port->TPCB_dwFlags &= ~(RASTAPI_FLAG_LINE_DROP_PENDING);
  2728. //
  2729. // Note that we ignore
  2730. // the return code in param2. This is because
  2731. // we cant do anything else.
  2732. //
  2733. if (port->IdleReceived)
  2734. {
  2735. //
  2736. // We received IDLE notification before/during
  2737. // disconnect so deallocate this call
  2738. //
  2739. port->IdleReceived = FALSE;
  2740. RasTapiTrace (
  2741. "RasTapiCallback: Idle Received for port %s",
  2742. port->TPCB_Name );
  2743. if(PS_UNAVAILABLE != port->TPCB_State)
  2744. {
  2745. RasTapiTrace(
  2746. "RasTapiCallback: changing state"
  2747. " of %s. %d -> %d",
  2748. port->TPCB_Name,
  2749. port->TPCB_State,
  2750. PS_OPEN );
  2751. port->TPCB_State = PS_OPEN ;
  2752. }
  2753. RasTapiTrace(
  2754. "RasTapiCallback: lineDeallocateCall "
  2755. "for %s,hcall = 0x%x",
  2756. port->TPCB_Name,
  2757. port->TPCB_CallHandle );
  2758. lineDeallocateCall (port->TPCB_CallHandle) ;
  2759. port->TPCB_CallHandle = (HCALL) -1 ;
  2760. //
  2761. // Check to see if rasman had attempted to listen on
  2762. // this port while linedrop was pending. If so, do a
  2763. // listen on rasmans behalf and return. Don't post a
  2764. // disconnect notification to rasman in this case.
  2765. //
  2766. if(port->TPCB_dwFlags & RASTAPI_FLAG_LISTEN_PENDING)
  2767. {
  2768. DWORD TempError;
  2769. RasTapiTrace("RasTapiCallback: Posting listen on"
  2770. " rasman's behalf on port %s",
  2771. port->TPCB_Name);
  2772. port->TPCB_dwFlags &= ~(RASTAPI_FLAG_LISTEN_PENDING);
  2773. TempError = DeviceListen(port, NULL, NULL);
  2774. RasTapiTrace("DeviceListen returned 0x%x",
  2775. TempError);
  2776. }
  2777. else
  2778. {
  2779. PostDisconnectCompletion(port);
  2780. }
  2781. }
  2782. else
  2783. {
  2784. //
  2785. // wait for idle message before signalling
  2786. // disconnect
  2787. //
  2788. ;
  2789. }
  2790. break ;
  2791. }
  2792. //
  2793. // Some other api completed
  2794. //
  2795. if (param2 == SUCCESS)
  2796. {
  2797. //
  2798. // Success means take no action - unless we are
  2799. // listening in which case it means move to the
  2800. // next state - we simply set the event that will
  2801. // result in a call to DeviceWork() to make the
  2802. // actual call for the next state
  2803. //
  2804. if (port->TPCB_State != PS_LISTENING)
  2805. {
  2806. break ;
  2807. }
  2808. //
  2809. // Proceed to the next listening sub-state
  2810. //
  2811. if (port->TPCB_ListenState == LS_ACCEPT)
  2812. {
  2813. RasTapiTrace(
  2814. "RasTapiCallback: LINE_REPLY. Changing "
  2815. "Listen state for %s from %d -> %d",
  2816. port->TPCB_Name,
  2817. port->TPCB_ListenState,
  2818. LS_ANSWER );
  2819. port->TPCB_ListenState = LS_ANSWER ;
  2820. PostNotificationCompletion(port);
  2821. }
  2822. else if (port->TPCB_ListenState == LS_ANSWER)
  2823. {
  2824. RasTapiTrace(
  2825. "RasTapiCallback: LINE_REPLY. Changing "
  2826. "Listen state for %s from %d -> %d",
  2827. port->TPCB_Name,
  2828. port->TPCB_ListenState,
  2829. LS_COMPLETE );
  2830. port->TPCB_ListenState = LS_COMPLETE ;
  2831. //
  2832. // Don't post completion notification in this case.
  2833. // We should post the completion when the connected
  2834. // indication is given. Otherwise we may end up
  2835. // calling lineGetId before it has give a callstate
  2836. // connected to us.
  2837. //
  2838. // PostNotificationCompletion(port);
  2839. RasTapiTrace(
  2840. "**** Not posting completion for lineAnswer ***");
  2841. }
  2842. }
  2843. else
  2844. {
  2845. //
  2846. // For connecting and listening ports this means
  2847. // the attempt failed because of some error
  2848. //
  2849. if (port->TPCB_State == PS_CONNECTING)
  2850. {
  2851. {
  2852. if ( LINEERR_INUSE == param2
  2853. || LINEERR_CALLUNAVAIL == param2)
  2854. {
  2855. //
  2856. // this means that some other tapi
  2857. // device is using this port
  2858. //
  2859. port->TPCB_AsyncErrorCode =
  2860. ERROR_LINE_BUSY;
  2861. RasTapiTrace(
  2862. "RasTapiCallback: Connect Attempt "
  2863. "on %s failed. 0x%x",
  2864. port->TPCB_Name,
  2865. param2 );
  2866. RasTapiTrace (
  2867. "RasTapiCallback: LINE_REPLY. "
  2868. "AsyncErr = %d",
  2869. port->TPCB_AsyncErrorCode );
  2870. }
  2871. else
  2872. {
  2873. port->TPCB_AsyncErrorCode =
  2874. ERROR_PORT_OR_DEVICE ;
  2875. RasTapiTrace(
  2876. "RasTapiCallback: ConnectAttempt "
  2877. "on %s failed. 0x%x",
  2878. port->TPCB_Name,
  2879. param2 );
  2880. RasTapiTrace(
  2881. "RasTapiCallback: LINE_REPLY. "
  2882. "AsyncErr = %d",
  2883. port->TPCB_AsyncErrorCode );
  2884. }
  2885. PostNotificationCompletion(port);
  2886. }
  2887. }
  2888. else if (port->TPCB_State == PS_LISTENING)
  2889. {
  2890. //
  2891. // Because ACCEPT may not be supported by
  2892. // the device - treat error as success
  2893. //
  2894. if (port->TPCB_ListenState == LS_ACCEPT)
  2895. {
  2896. RasTapiTrace(
  2897. "RasTapiCallback: Changing Listen "
  2898. "State for %s from %d -> %d",
  2899. port->TPCB_Name,
  2900. port->TPCB_ListenState,
  2901. LS_ANSWER );
  2902. port->TPCB_ListenState = LS_ANSWER ;
  2903. }
  2904. else
  2905. {
  2906. RasTapiTrace(
  2907. "RasTapiCallback: Changing "
  2908. "Listen State for %s from %d -> %d."
  2909. "param2=0x%x",
  2910. port->TPCB_Name,
  2911. port->TPCB_ListenState,
  2912. LS_ERROR,
  2913. param2);
  2914. port->TPCB_ListenState = LS_ERROR ;
  2915. }
  2916. PostNotificationCompletion(port);
  2917. }
  2918. //
  2919. // Some other API failed, we dont know and
  2920. // we dont care. Ignore.
  2921. //
  2922. else if (port->TPCB_State != PS_CLOSED)
  2923. {
  2924. ;
  2925. }
  2926. }
  2927. }
  2928. break ;
  2929. case LINE_CLOSE:
  2930. RasTapiTrace("LINE_CLOSE. line=0x%x", instance);
  2931. //
  2932. // Typically sent when things go really wrong.
  2933. // Find which line is indication came for.
  2934. //
  2935. line = (TapiLineInfo *) instance ;
  2936. //
  2937. // if line not found or if it is closed just return
  2938. //
  2939. if ( (line == NULL)
  2940. || (line->TLI_LineState == PS_CLOSED))
  2941. {
  2942. break ;
  2943. }
  2944. //
  2945. // For every port that is on the line - open the
  2946. // line again and signal hw failure
  2947. //
  2948. port = RasPortsList;
  2949. while ( port )
  2950. {
  2951. //
  2952. // Skip ports that arent initialized
  2953. //
  2954. if (port->TPCB_State == PS_UNINITIALIZED)
  2955. {
  2956. port = port->TPCB_next;
  2957. continue ;
  2958. }
  2959. //
  2960. // Open the line only if its closed.
  2961. //
  2962. if (port->TPCB_Line == line)
  2963. {
  2964. if(port->TPCB_Line->TLI_LineState != PS_OPEN)
  2965. {
  2966. if (retcode = lineOpen (
  2967. RasLine,
  2968. port->TPCB_Line->TLI_LineId,
  2969. &port->TPCB_Line->TLI_LineHandle,
  2970. port->TPCB_Line->NegotiatedApiVersion,
  2971. port->TPCB_Line->NegotiatedExtVersion,
  2972. (DWORD_PTR) port->TPCB_Line,
  2973. LINECALLPRIVILEGE_OWNER,
  2974. port->TPCB_Line->TLI_MediaMode,
  2975. NULL))
  2976. {
  2977. RasTapiTrace(
  2978. "RasTapiCallback: LINECLOSE:"
  2979. " lineOpen Failed. 0x%x",
  2980. retcode );
  2981. }
  2982. else
  2983. {
  2984. port->TPCB_Line->TLI_LineState = PS_OPEN ;
  2985. RasTapiTrace("RasTapiCallback: Linestate changed from"
  2986. "%d to PS_OPEN",
  2987. port->TPCB_Line->TLI_LineState );
  2988. }
  2989. //
  2990. // Set monitoring of rings
  2991. //
  2992. lineSetStatusMessages (
  2993. port->TPCB_Line->TLI_LineHandle,
  2994. LINEDEVSTATE_RINGING, 0) ;
  2995. }
  2996. if(0 == port->TPCB_AsyncErrorCode)
  2997. {
  2998. port->TPCB_AsyncErrorCode = ERROR_FROM_DEVICE ;
  2999. }
  3000. port->TPCB_DisconnectReason = SS_HARDWAREFAILURE;
  3001. port->TPCB_CallHandle = (HCALL) -1 ;
  3002. port->TPCB_ListenState = LS_ERROR ;
  3003. RasTapiTrace(
  3004. "RasTapiCallback: LINECLOSE - "
  3005. "Signalling HW Failure for %s",
  3006. port->TPCB_Name );
  3007. RasTapiTrace(
  3008. "RasTapiCallback: LINECLOSE - "
  3009. "AsyncErr = %d",
  3010. port->TPCB_AsyncErrorCode );
  3011. PostDisconnectCompletion(port);
  3012. }
  3013. port = port->TPCB_next;
  3014. }
  3015. break;
  3016. case LINE_LINEDEVSTATE:
  3017. RasTapiTrace("LINE_LINEDEVSTATE. param1=0x%x, line=0x%x", param1, instance);
  3018. //
  3019. // we are only interested in ringing message
  3020. //
  3021. if (param1 != LINEDEVSTATE_RINGING)
  3022. {
  3023. break ;
  3024. }
  3025. //
  3026. // Find which line is indication came for.
  3027. //
  3028. line = (TapiLineInfo *) instance ;
  3029. //
  3030. // if line not found or if it is closed
  3031. // just return
  3032. //
  3033. if ( (line == NULL)
  3034. || (line->TLI_LineState == PS_CLOSED))
  3035. {
  3036. break ;
  3037. }
  3038. //
  3039. // get the port from the line
  3040. //
  3041. port = RasPortsList;
  3042. while ( port )
  3043. {
  3044. //
  3045. // Skip ports that arent initialized
  3046. //
  3047. if (port->TPCB_State == PS_UNINITIALIZED)
  3048. {
  3049. port = port->TPCB_next;
  3050. continue ;
  3051. }
  3052. if ( (port->TPCB_Line == line)
  3053. && (port->TPCB_State == PS_LISTENING)
  3054. && (port->TPCB_ListenState == LS_RINGING))
  3055. {
  3056. if(port->TPCB_NumberOfRings > 0)
  3057. {
  3058. //
  3059. // count down the rings
  3060. //
  3061. port->TPCB_NumberOfRings -= 1 ;
  3062. }
  3063. RasTapiTrace("RasTapiCallback: LINEDEVSTATE - "
  3064. "Number of rings for %s = %d",
  3065. port->TPCB_Name,
  3066. port->TPCB_NumberOfRings);
  3067. //
  3068. // if the ring count has gone down to zero
  3069. // this means that we should pick up the call.
  3070. //
  3071. if (port->TPCB_NumberOfRings == 0)
  3072. {
  3073. RasTapiTrace (
  3074. "RasTapiCallback: Changing Listen "
  3075. "State for %s from %d -> %d",
  3076. port->TPCB_Name,
  3077. port->TPCB_ListenState,
  3078. LS_ACCEPT );
  3079. if(line->TLI_pDeviceInfo)
  3080. {
  3081. line->TLI_pDeviceInfo->dwCurrentDialedInClients
  3082. += 1;
  3083. RasTapiTrace(
  3084. "CurrentDialInClients=0x%x",
  3085. line->TLI_pDeviceInfo->dwCurrentDialedInClients);
  3086. }
  3087. port->TPCB_dwFlags |= RASTAPI_FLAG_DIALEDIN;
  3088. port->TPCB_ListenState = LS_ACCEPT ;
  3089. //
  3090. // Complete event so that rasman calls
  3091. // DeviceWork to proceed the listen state
  3092. // machine.
  3093. //
  3094. PostNotificationCompletion(port);
  3095. }
  3096. break ;
  3097. }
  3098. port = port->TPCB_next;
  3099. }
  3100. break ;
  3101. case LINE_CREATE:
  3102. {
  3103. DWORD dwError;
  3104. PortMediaInfo *pmiNewDevice = NULL;
  3105. DWORD cNewPorts,
  3106. iNewPort;
  3107. DWORD adwPortsCreated[ LEGACY_MAX ] = {0};
  3108. TapiPortControlBlock *ptpcbPort = NULL,
  3109. **pptpcbNewPorts = NULL;
  3110. //
  3111. // A new device was added. Create a new port
  3112. // and add it to rastapi datastructures
  3113. //
  3114. RasTapiTrace ("RasTapiaCallback: LINE_CREATE");
  3115. TotalLines++;
  3116. dwError = dwCreateTapiPortsPerLine(
  3117. (DWORD) param1,
  3118. &cNewPorts,
  3119. &pptpcbNewPorts);
  3120. if ( dwError )
  3121. {
  3122. RasTapiTrace ("RasTapiCallback: "
  3123. "dwCreateTapiPortsPerLine "
  3124. "Failed. 0x%x",
  3125. dwError );
  3126. break;
  3127. }
  3128. RasTapiTrace ("RasTapiCallback: cNewPorts = %d",
  3129. cNewPorts );
  3130. for (iNewPort = 0; iNewPort < cNewPorts; iNewPort++)
  3131. {
  3132. ptpcbPort = pptpcbNewPorts [ iNewPort ];
  3133. //
  3134. // Allocate a PortMediaInfo Structure and fill
  3135. // it with the information about the new device
  3136. // added. This structure will be freed by rasman.
  3137. //
  3138. pmiNewDevice = LocalAlloc (
  3139. LPTR,
  3140. sizeof (PortMediaInfo));
  3141. if (NULL == pmiNewDevice)
  3142. {
  3143. break;
  3144. }
  3145. strcpy (pmiNewDevice->PMI_Name, ptpcbPort->TPCB_Name);
  3146. pmiNewDevice->PMI_Usage = ptpcbPort->TPCB_Usage;
  3147. strcpy (pmiNewDevice->PMI_DeviceType,
  3148. ptpcbPort->TPCB_DeviceType);
  3149. strcpy (pmiNewDevice->PMI_DeviceName,
  3150. ptpcbPort->TPCB_DeviceName);
  3151. pmiNewDevice->PMI_LineDeviceId =
  3152. ptpcbPort->TPCB_Line->TLI_LineId;
  3153. pmiNewDevice->PMI_AddressId =
  3154. ptpcbPort->TPCB_AddressId;
  3155. pmiNewDevice->PMI_pDeviceInfo =
  3156. ptpcbPort->TPCB_Line->TLI_pDeviceInfo;
  3157. RasTapiTrace("RasTapiCallback: New Device Created - %s",
  3158. (ptpcbPort->TPCB_DeviceName
  3159. ? ptpcbPort->TPCB_DeviceName
  3160. : "NULL!"));
  3161. PostNotificationNewPort ( pmiNewDevice );
  3162. }
  3163. LocalFree ( pptpcbNewPorts );
  3164. break;
  3165. }
  3166. case LINE_REMOVE:
  3167. {
  3168. //TapiPortControlBlock *port = RasPortsList;
  3169. RasTapiTrace ("RasTapiCallback: LINE_REMOVE");
  3170. PostNotificationRemoveLine((DWORD) param1);
  3171. /*
  3172. while ( port )
  3173. {
  3174. if ( port->TPCB_Line->TLI_LineId == param1 )
  3175. {
  3176. PostNotificationRemoveLine(param1);
  3177. RasTapiTrace ("RasTapiCallback: Marking port %s "
  3178. "for removal\n",
  3179. port->TPCB_DeviceName);
  3180. //
  3181. // Mark the port for removal. The port will be
  3182. // removed when it is closed.
  3183. //
  3184. RasTapiTrace(
  3185. "RasTapiCallback: Changing state of %s "
  3186. "from %d -> %d",
  3187. port->TPCB_Name,
  3188. port->TPCB_State,
  3189. PS_UNAVAILABLE );
  3190. port->TPCB_State = PS_UNAVAILABLE ;
  3191. }
  3192. port = port->TPCB_next;
  3193. } */
  3194. break;
  3195. }
  3196. case LINE_DEVSPECIFIC:
  3197. {
  3198. DWORD Status;
  3199. hcall = (HCALL) HandleToUlong(context) ;
  3200. line = (TapiLineInfo *) instance ;
  3201. if(NULL == line)
  3202. {
  3203. break;
  3204. }
  3205. RasTapiTrace("RasTapiCallback:LINE_DEVSPECIFIC");
  3206. //
  3207. // If line is closed dont bother
  3208. //
  3209. if (line->TLI_LineState == PS_CLOSED)
  3210. {
  3211. break ;
  3212. }
  3213. //
  3214. // Locate the ras port for this call
  3215. //
  3216. memset (buffer, 0, sizeof(buffer)) ;
  3217. linecallinfo = (LINECALLINFO *) buffer ;
  3218. linecallinfo->dwTotalSize = sizeof(buffer) ;
  3219. //
  3220. // If line get call info fails return.
  3221. //
  3222. if ((Status = lineGetCallInfo(
  3223. hcall,
  3224. linecallinfo))
  3225. > 0x80000000)
  3226. {
  3227. RasTapiTrace(
  3228. "RastapiCallback: lineGetCallInfo "
  3229. "failed. 0x%x. hcall=0x%x, line=0x%x",
  3230. Status,
  3231. hcall,
  3232. line );
  3233. break ;
  3234. }
  3235. //
  3236. // Locate the ras port for this call
  3237. //
  3238. if ((port = FindPortByAddressId (line,
  3239. linecallinfo->dwAddressID)) == NULL)
  3240. {
  3241. RasTapiTrace("RasTapiCallback: Port not found! "
  3242. "line=0x%x, AddressID=0x%x",
  3243. line,
  3244. linecallinfo->dwAddressID );
  3245. //
  3246. // Did not find a ras port for the call. Ignore it.
  3247. //
  3248. break ;
  3249. }
  3250. switch (param1)
  3251. {
  3252. case RASTAPI_DEV_RECV:
  3253. {
  3254. PRASTAPI_DEV_SPECIFIC TapiRecv;
  3255. DWORD TapiRecvSize;
  3256. DWORD requestid;
  3257. TapiRecvSize = sizeof(RASTAPI_DEV_SPECIFIC) + 1500;
  3258. if ((TapiRecv = LocalAlloc(
  3259. LPTR, TapiRecvSize)) == NULL)
  3260. {
  3261. RasTapiTrace(
  3262. "RasTapiCallback: RASTAPI_DEV_RECV. "
  3263. "LocalAlloc failed. %d",
  3264. GetLastError() );
  3265. break;
  3266. }
  3267. TapiRecv->Command = RASTAPI_DEV_RECV;
  3268. TapiRecv->DataSize = 1500;
  3269. port->TPCB_RecvDesc = TapiRecv;
  3270. port->TPCB_RecvRequestId =
  3271. lineDevSpecific(port->TPCB_Line->TLI_LineHandle,
  3272. port->TPCB_AddressId,
  3273. port->TPCB_CallHandle,
  3274. TapiRecv,
  3275. TapiRecvSize);
  3276. if (port->TPCB_RecvRequestId == 0)
  3277. {
  3278. //
  3279. // Copy the memory into the circular buffer
  3280. //
  3281. CopyDataToFifo(port->TPCB_RecvFifo,
  3282. TapiRecv->Data,
  3283. TapiRecv->DataSize);
  3284. port->TPCB_RecvDesc = NULL;
  3285. LocalFree(TapiRecv);
  3286. }
  3287. else if (port->TPCB_RecvRequestId > 0x80000000)
  3288. {
  3289. RasTapiTrace(
  3290. "RasTapiCallback: lineDevSpecific "
  3291. "failed. 0x%x",
  3292. port->TPCB_RecvRequestId );
  3293. port->TPCB_RecvDesc = NULL;
  3294. port->TPCB_RecvRequestId = INFINITE;
  3295. LocalFree(TapiRecv);
  3296. }
  3297. else
  3298. {
  3299. }
  3300. }
  3301. break;
  3302. default:
  3303. break;
  3304. }
  3305. }
  3306. break;
  3307. case LINE_ADDRESSSTATE:
  3308. case LINE_CALLINFO:
  3309. case LINE_DEVSPECIFICFEATURE:
  3310. case LINE_GATHERDIGITS:
  3311. case LINE_GENERATE:
  3312. case LINE_MONITORDIGITS:
  3313. case LINE_MONITORMEDIA:
  3314. case LINE_MONITORTONE:
  3315. case LINE_REQUEST:
  3316. default:
  3317. //
  3318. // All unhandled unsolicited messages.
  3319. //
  3320. ;
  3321. }
  3322. // **** Exclusion End ****
  3323. FreeMutex (RasTapiMutex) ;
  3324. }
  3325. /*++
  3326. Routine Description:
  3327. Find a rastapi port given the AddressID
  3328. Arguments:
  3329. line - the lineinfo structure of the line this
  3330. address id one
  3331. addid - AddressID of the address.
  3332. Return Value:
  3333. Pointer to the control block of the port if found.
  3334. NULL otherwise.
  3335. --*/
  3336. TapiPortControlBlock *
  3337. FindPortByAddressId (TapiLineInfo *line, DWORD addid)
  3338. {
  3339. DWORD i ;
  3340. TapiPortControlBlock *port = RasPortsList;
  3341. while ( port )
  3342. {
  3343. if ( (port->TPCB_AddressId == addid)
  3344. && (port->TPCB_Line == line))
  3345. {
  3346. return port ;
  3347. }
  3348. port = port->TPCB_next;
  3349. }
  3350. return NULL ;
  3351. }
  3352. /*++
  3353. Routine Description:
  3354. Find a rastapi port given the Address
  3355. Arguments:
  3356. address
  3357. Return Value:
  3358. Pointer to the control block of the port if found.
  3359. NULL otherwise.
  3360. --*/
  3361. TapiPortControlBlock *
  3362. FindPortByAddress (CHAR *address)
  3363. {
  3364. DWORD i ;
  3365. TapiPortControlBlock *port = RasPortsList;
  3366. while ( port )
  3367. {
  3368. if (_stricmp (port->TPCB_Address,
  3369. address) == 0)
  3370. {
  3371. return port ;
  3372. }
  3373. port = port->TPCB_next;
  3374. }
  3375. return NULL ;
  3376. }
  3377. /*++
  3378. Routine Description:
  3379. Find a rastapi port given the Address and name
  3380. Arguments:
  3381. address
  3382. name
  3383. Return Value:
  3384. Pointer to the control block of the port if found.
  3385. NULL otherwise.
  3386. --*/
  3387. TapiPortControlBlock *
  3388. FindPortByAddressAndName (CHAR *address, CHAR *name)
  3389. {
  3390. DWORD i ;
  3391. TapiPortControlBlock *port = RasPortsList;
  3392. while ( port )
  3393. {
  3394. if ( (_stricmp (
  3395. port->TPCB_Address,
  3396. address) == 0)
  3397. && (_strnicmp (
  3398. port->TPCB_Name,
  3399. name,
  3400. MAX_PORT_NAME-1) == 0))
  3401. {
  3402. return port ;
  3403. }
  3404. port = port->TPCB_next;
  3405. }
  3406. return NULL ;
  3407. }
  3408. /*++
  3409. Routine Description:
  3410. Find a rastapi port given the request id
  3411. Arguments:
  3412. reqid
  3413. Return Value:
  3414. Pointer to the control block of the port if found.
  3415. NULL otherwise.
  3416. --*/
  3417. TapiPortControlBlock *
  3418. FindPortByRequestId (DWORD reqid)
  3419. {
  3420. DWORD i ;
  3421. TapiPortControlBlock *port = RasPortsList;
  3422. while ( port )
  3423. {
  3424. if (port->TPCB_RequestId == reqid)
  3425. {
  3426. return port ;
  3427. }
  3428. else if ( port->TPCB_CharMode )
  3429. {
  3430. if ( port->TPCB_SendRequestId == reqid
  3431. || port->TPCB_RecvRequestId == reqid
  3432. || port->TPCB_ModeRequestId == reqid )
  3433. {
  3434. return port;
  3435. }
  3436. }
  3437. port = port->TPCB_next;
  3438. }
  3439. return NULL ;
  3440. }
  3441. /*++
  3442. Routine Description:
  3443. Find a rastapi port given the call handle
  3444. Arguments:
  3445. line - line control block of the line on which
  3446. the call was received/made.
  3447. callhandle
  3448. Return Value:
  3449. Pointer to the control block of the port if found.
  3450. NULL otherwise.
  3451. --*/
  3452. TapiPortControlBlock *
  3453. FindPortByCallHandle(TapiLineInfo *line, HCALL callhandle)
  3454. {
  3455. DWORD i ;
  3456. TapiPortControlBlock *port = RasPortsList;
  3457. while ( port )
  3458. {
  3459. if ( (port->TPCB_CallHandle == callhandle)
  3460. && (port->TPCB_Line == line))
  3461. {
  3462. return port ;
  3463. }
  3464. port = port->TPCB_next;
  3465. }
  3466. return NULL ;
  3467. }
  3468. /*++
  3469. Routine Description:
  3470. Finds a port of with the specified addressid
  3471. which is in a listening state
  3472. Arguments:
  3473. line - line control block of the line to which this
  3474. address belongs.
  3475. AddressID
  3476. Return Value:
  3477. Pointer to the control block of the port if found.
  3478. NULL otherwise.
  3479. --*/
  3480. TapiPortControlBlock *
  3481. FindListeningPort(TapiLineInfo *line, DWORD AddressID)
  3482. {
  3483. DWORD i ;
  3484. TapiPortControlBlock *port = RasPortsList;
  3485. while ( port )
  3486. {
  3487. if ( (port->TPCB_Line == line)
  3488. && (line->TLI_LineState == PS_LISTENING)
  3489. && (port->TPCB_State == PS_LISTENING)
  3490. && (port->TPCB_ListenState == LS_WAIT))
  3491. {
  3492. port->TPCB_AddressId = AddressID;
  3493. return port ;
  3494. }
  3495. port = port->TPCB_next;
  3496. }
  3497. return NULL ;
  3498. }
  3499. /*++
  3500. Routine Description:
  3501. Finds a line control block of with the specified
  3502. addressid which is in a listening state
  3503. Arguments:
  3504. linehandle
  3505. Return Value:
  3506. Pointer to the control block of the line if found.
  3507. NULL otherwise.
  3508. --*/
  3509. TapiLineInfo *
  3510. FindLineByHandle (HLINE linehandle)
  3511. {
  3512. DWORD i ;
  3513. TapiLineInfo *line = RasTapiLineInfoList;
  3514. while ( line )
  3515. {
  3516. if (line->TLI_LineHandle == linehandle)
  3517. {
  3518. return line ;
  3519. }
  3520. line = line->TLI_Next;
  3521. }
  3522. return NULL ;
  3523. }
  3524. /*++
  3525. Routine Description:
  3526. Posts a disconnect event notification to rasmans
  3527. completion port.
  3528. Arguments:
  3529. pointer to the port control block on which the
  3530. disconnect happened.
  3531. Return Value:
  3532. void.
  3533. --*/
  3534. VOID
  3535. PostDisconnectCompletion(
  3536. TapiPortControlBlock *port
  3537. )
  3538. {
  3539. BOOL fSuccess;
  3540. if(NULL == port->TPCB_IoCompletionPort)
  3541. {
  3542. RasTapiTrace("PostDisconnectionCompletion: NULL completion port");
  3543. return;
  3544. }
  3545. fSuccess = PostQueuedCompletionStatus(
  3546. port->TPCB_IoCompletionPort,
  3547. 0,
  3548. port->TPCB_CompletionKey,
  3549. (LPOVERLAPPED)&port->TPCB_DiscOverlapped);
  3550. if (!fSuccess)
  3551. {
  3552. DWORD dwerror = GetLastError();
  3553. RasTapiTrace(
  3554. "PostDisconnectCompletion:"
  3555. "PostQueuedCompletionStatus failed. 0x%x",
  3556. dwerror);
  3557. }
  3558. }
  3559. /*++
  3560. Routine Description:
  3561. Posts a notification to rasmans completion port
  3562. indicating the completion of an asynchronous
  3563. operation.
  3564. Arguments:
  3565. pointer to the port control block on which the
  3566. asynchronous operation completed.
  3567. Return Value:
  3568. void.
  3569. --*/
  3570. VOID
  3571. PostNotificationCompletion(
  3572. TapiPortControlBlock *port
  3573. )
  3574. {
  3575. BOOL fSuccess;
  3576. if(NULL == port->TPCB_IoCompletionPort)
  3577. {
  3578. RasTapiTrace("PostNotificationCompletion: NULL completion port");
  3579. return;
  3580. }
  3581. fSuccess = PostQueuedCompletionStatus(
  3582. port->TPCB_IoCompletionPort,
  3583. 0,
  3584. port->TPCB_CompletionKey,
  3585. (LPOVERLAPPED)&port->TPCB_ReadOverlapped);
  3586. if (!fSuccess)
  3587. {
  3588. DWORD dwerror = GetLastError();
  3589. RasTapiTrace(
  3590. "PostNotificationCompletion:"
  3591. "PostQueuedCompletionStatus failed. 0x%x",
  3592. dwerror);
  3593. }
  3594. }
  3595. /*++
  3596. Routine Description:
  3597. Posts a notification to rasmans completion port
  3598. indicating that a new port was created. For PnP
  3599. Arguments:
  3600. pointer to the media control block corresponding
  3601. to the port that was created. Look in
  3602. ..\routing\ras\inc\media.h for the definition
  3603. of PortMediaInfo structure.
  3604. Return Value:
  3605. void.
  3606. --*/
  3607. VOID
  3608. PostNotificationNewPort(
  3609. PortMediaInfo *pmiNewPort
  3610. )
  3611. {
  3612. BOOL fSuccess;
  3613. PRAS_OVERLAPPED pOvNewPortNotification;
  3614. PNEW_PORT_NOTIF pNewPortNotif;
  3615. RasTapiTrace ("PostNotificationNewPort %s",
  3616. pmiNewPort->PMI_Name );
  3617. pOvNewPortNotification = LocalAlloc (
  3618. LPTR, sizeof ( RAS_OVERLAPPED));
  3619. if (NULL == pOvNewPortNotification)
  3620. {
  3621. RasTapiTrace ("PostNotificationNewPort: "
  3622. "Failed to allocate ov.");
  3623. goto done;
  3624. }
  3625. pNewPortNotif = LocalAlloc (
  3626. LPTR, sizeof (NEW_PORT_NOTIF) );
  3627. if (NULL == pNewPortNotif)
  3628. {
  3629. RasTapiTrace ("PostNotificationNewPort: Failed "
  3630. "to allocate NEW_PORT_NOTIF");
  3631. LocalFree(pOvNewPortNotification);
  3632. goto done;
  3633. }
  3634. pNewPortNotif->NPN_pmiNewPort = (PVOID) pmiNewPort;
  3635. strcpy (
  3636. pNewPortNotif->NPN_MediaName,
  3637. "rastapi");
  3638. pOvNewPortNotification->RO_EventType = OVEVT_DEV_CREATE;
  3639. pOvNewPortNotification->RO_Info = (PVOID) pNewPortNotif;
  3640. fSuccess = PostQueuedCompletionStatus(
  3641. g_hIoCompletionPort,
  3642. 0,
  3643. 0,
  3644. (LPOVERLAPPED) pOvNewPortNotification);
  3645. if (!fSuccess)
  3646. {
  3647. RasTapiTrace(
  3648. "PostNotificationNewPort: Failed"
  3649. " to Post notification. %d",
  3650. GetLastError());
  3651. LocalFree(pOvNewPortNotification);
  3652. LocalFree(pNewPortNotif);
  3653. }
  3654. else
  3655. {
  3656. RasTapiTrace(
  3657. "PostNotificationNewPort: "
  3658. "Posted 0x%x",
  3659. pOvNewPortNotification );
  3660. }
  3661. done:
  3662. return;
  3663. }
  3664. /*++
  3665. Routine Description:
  3666. Posts a notification to rasmans completion port
  3667. indicating that a port was removed. For PnP.
  3668. Arguments:
  3669. Pointer to the port control block of the port that
  3670. was removed.
  3671. Return Value:
  3672. void.
  3673. --*/
  3674. VOID
  3675. PostNotificationRemoveLine (
  3676. DWORD dwLineId
  3677. )
  3678. {
  3679. PRAS_OVERLAPPED pOvRemovePortNotification;
  3680. PREMOVE_LINE_NOTIF pRemovePortNotification;
  3681. pOvRemovePortNotification = LocalAlloc (
  3682. LPTR,
  3683. sizeof (RAS_OVERLAPPED));
  3684. RasTapiTrace ("PostNotificationRemoveLine: %d",
  3685. dwLineId);
  3686. if ( NULL == pOvRemovePortNotification )
  3687. {
  3688. RasTapiTrace("PostNotificationRemovePort: "
  3689. "failed to allocate",
  3690. GetLastError());
  3691. goto done;
  3692. }
  3693. pRemovePortNotification = LocalAlloc(
  3694. LPTR,
  3695. sizeof(REMOVE_LINE_NOTIF));
  3696. if(NULL == pRemovePortNotification)
  3697. {
  3698. RasTapiTrace("PostNotificationRemovePort: "
  3699. "failed to allocate",
  3700. GetLastError());
  3701. LocalFree(pOvRemovePortNotification);
  3702. goto done;
  3703. }
  3704. pRemovePortNotification->dwLineId = dwLineId;
  3705. pOvRemovePortNotification->RO_EventType = OVEVT_DEV_REMOVE;
  3706. pOvRemovePortNotification->RO_Info = (PVOID)
  3707. pRemovePortNotification;
  3708. if ( !PostQueuedCompletionStatus (
  3709. g_hIoCompletionPort,
  3710. 0,
  3711. 0,
  3712. (LPOVERLAPPED) pOvRemovePortNotification ))
  3713. {
  3714. RasTapiTrace("PostNotificationRemovePort: Failed"
  3715. " to post the notification. %d",
  3716. GetLastError());
  3717. LocalFree(pOvRemovePortNotification);
  3718. }
  3719. else
  3720. {
  3721. RasTapiTrace("PostNotificationRemovePort:"
  3722. " Posted 0x%x",
  3723. pOvRemovePortNotification );
  3724. }
  3725. done:
  3726. return;
  3727. }
  3728. /*++
  3729. Routine Description:
  3730. Removes a port from the global ports list. For PnP
  3731. Arguments:
  3732. Pointer to the port control block of the port that
  3733. is being removed.
  3734. Return Value:
  3735. SUCCESS.
  3736. --*/
  3737. DWORD
  3738. dwRemovePort ( TapiPortControlBlock * ptpcb )
  3739. {
  3740. TapiPortControlBlock *pport;
  3741. GetMutex ( RasTapiMutex, INFINITE );
  3742. if ( NULL == ptpcb )
  3743. {
  3744. goto done;
  3745. }
  3746. RasTapiTrace ("dwRemovePort: %s",
  3747. ptpcb->TPCB_Name );
  3748. if ( RasPortsList == ptpcb )
  3749. {
  3750. RasPortsList = RasPortsList->TPCB_next;
  3751. LocalFree ( ptpcb );
  3752. goto done;
  3753. }
  3754. //
  3755. // Remove this port from the global list
  3756. //
  3757. pport = RasPortsList;
  3758. while (pport->TPCB_next)
  3759. {
  3760. if ( ptpcb == pport->TPCB_next )
  3761. {
  3762. pport->TPCB_next = pport->TPCB_next->TPCB_next;
  3763. LocalFree (ptpcb);
  3764. break;
  3765. }
  3766. pport = pport->TPCB_next;
  3767. }
  3768. done:
  3769. FreeMutex ( RasTapiMutex );
  3770. return SUCCESS;
  3771. }
  3772. /*++
  3773. Routine Description:
  3774. Creates ports represented by the guid. For PnP
  3775. Arguments:
  3776. pbGuidAdapter - Guid of the adapter corresponding
  3777. to the ports that are to be created.
  3778. pvReserved.
  3779. Return Value:
  3780. SUCCESS.
  3781. --*/
  3782. DWORD
  3783. dwAddPorts( PBYTE pbGuidAdapter, PVOID pvReserved )
  3784. {
  3785. DWORD retcode = SUCCESS;
  3786. DWORD dwLine;
  3787. DWORD cNewPorts;
  3788. TapiPortControlBlock **pptpcbNewPorts = NULL,
  3789. *ptpcbPort;
  3790. DWORD iNewPort;
  3791. PortMediaInfo *pmiNewDevice = NULL;
  3792. TapiLineInfo *pLineInfo = NULL;
  3793. DeviceInfo *pDeviceInfo = NULL;
  3794. RasTapiTrace ("dwAddPorts" );
  3795. pDeviceInfo = GetDeviceInfo (pbGuidAdapter, FALSE);
  3796. #if DBG
  3797. ASSERT( NULL != pDeviceInfo );
  3798. #endif
  3799. //
  3800. // Iterate over all the lines to add the new ports
  3801. //
  3802. for ( dwLine = 0; dwLine < TotalLines; dwLine++)
  3803. {
  3804. retcode = dwCreateTapiPortsPerLine( dwLine,
  3805. &cNewPorts,
  3806. &pptpcbNewPorts);
  3807. if ( retcode
  3808. || NULL == pptpcbNewPorts)
  3809. {
  3810. continue;
  3811. }
  3812. //
  3813. // Added a new pptp port. Fill in the rasman port
  3814. // structure and notify rasman
  3815. //
  3816. for ( iNewPort = 0; iNewPort < cNewPorts; iNewPort++ )
  3817. {
  3818. ptpcbPort = pptpcbNewPorts [ iNewPort ];
  3819. //
  3820. // Allocate a PortMediaInfo Structure and fill it
  3821. // with the information about the new device added.
  3822. // This structure will be freed by rasman.
  3823. //
  3824. pmiNewDevice = LocalAlloc (
  3825. LPTR,
  3826. sizeof (PortMediaInfo));
  3827. if (NULL == pmiNewDevice)
  3828. {
  3829. RasTapiTrace("dwAddPorts: Failed to allocate "
  3830. "memory. %d",
  3831. GetLastError() );
  3832. retcode = GetLastError();
  3833. break;
  3834. }
  3835. strcpy (
  3836. pmiNewDevice->PMI_Name,
  3837. ptpcbPort->TPCB_Name);
  3838. pmiNewDevice->PMI_Usage = ptpcbPort->TPCB_Usage;
  3839. strcpy (
  3840. pmiNewDevice->PMI_DeviceType,
  3841. ptpcbPort->TPCB_DeviceType);
  3842. strcpy (
  3843. pmiNewDevice->PMI_DeviceName,
  3844. ptpcbPort->TPCB_DeviceName);
  3845. pmiNewDevice->PMI_LineDeviceId =
  3846. ptpcbPort->TPCB_Line->TLI_LineId;
  3847. pmiNewDevice->PMI_AddressId =
  3848. ptpcbPort->TPCB_AddressId;
  3849. pmiNewDevice->PMI_pDeviceInfo = pDeviceInfo;
  3850. RasTapiTrace ("dwAddPorts: Posting new port "
  3851. "notification for %s",
  3852. ptpcbPort->TPCB_Name);
  3853. PostNotificationNewPort (pmiNewDevice);
  3854. }
  3855. LocalFree ( pptpcbNewPorts );
  3856. pptpcbNewPorts = NULL;
  3857. //
  3858. // We already reached the limit. Don't create any
  3859. // more ports
  3860. //
  3861. if (pDeviceInfo->dwCurrentEndPoints ==
  3862. pDeviceInfo->rdiDeviceInfo.dwNumEndPoints)
  3863. {
  3864. break;
  3865. }
  3866. }
  3867. return retcode;
  3868. }
  3869. /*++
  3870. Routine Description:
  3871. Copies data from the input buffer to the fifo
  3872. maintained. This is for the devices supporting
  3873. Character Mode.
  3874. Arguments:
  3875. Fifo - to which the data has to be copied.
  3876. Data - data buffer.
  3877. DataLength - length of the data.
  3878. Return Value:
  3879. Number of bytes copied.
  3880. --*/
  3881. DWORD
  3882. CopyDataToFifo(
  3883. PRECV_FIFO Fifo,
  3884. PBYTE Data,
  3885. DWORD DataLength
  3886. )
  3887. {
  3888. DWORD bytescopied = 0;
  3889. while ( Fifo->Count != Fifo->Size
  3890. && bytescopied < DataLength)
  3891. {
  3892. Fifo->Buffer[Fifo->In++] = Data[bytescopied++];
  3893. Fifo->Count++;
  3894. Fifo->In %= Fifo->Size;
  3895. }
  3896. return (bytescopied);
  3897. }
  3898. /*++
  3899. Routine Description:
  3900. Copies data to the buffer from fifo
  3901. This is for the devices supporting
  3902. Character Mode.
  3903. Arguments:
  3904. Fifo - to which the data has to be copied.
  3905. Data - buffer to receive data
  3906. DataLength - length of the buffer.
  3907. Return Value:
  3908. Number of bytes copied.
  3909. --*/
  3910. DWORD
  3911. CopyDataFromFifo(
  3912. PRECV_FIFO Fifo,
  3913. PBYTE Buffer,
  3914. DWORD BufferSize
  3915. )
  3916. {
  3917. DWORD bytescopied = 0;
  3918. while ( bytescopied < BufferSize
  3919. && Fifo->Count != 0)
  3920. {
  3921. Buffer[bytescopied++] = Fifo->Buffer[Fifo->Out++];
  3922. Fifo->Count--;
  3923. Fifo->Out %= Fifo->Size;
  3924. }
  3925. return (bytescopied);
  3926. }