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

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