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

771 lines
23 KiB

  1. /*
  2. (C) Copyright 1998
  3. All rights reserved.
  4. Portions of this software are:
  5. (C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
  6. License to use this software is granted under the terms outlined in
  7. the TriplePoint Software Services Agreement.
  8. (C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
  9. License to use this software is granted under the terms outlined in
  10. the Microsoft Windows Device Driver Development Kit.
  11. @doc INTERNAL Tspi Tspi_c
  12. @module Tspi.c |
  13. This module contains all the Miniport TAPI OID processing routines. It
  14. is called by the <f MiniportSetInformation> and <f MiniportQueryInformation>
  15. routines to handle the TAPI OIDs.
  16. This driver conforms to the NDIS 3.0 Miniport interface and provides
  17. extensions to support Telephonic Services.
  18. @head3 Contents |
  19. @index class,mfunc,func,msg,mdata,struct,enum | Tspi_c
  20. @end
  21. */
  22. /* @doc EXTERNAL INTERNAL
  23. @topic 4.0 NDISWAN TAPI Service Provider Interface |
  24. The Connection Wrapper interface defines how WAN miniport NIC drivers
  25. implement telephonic services. It is closely related to the Service
  26. Provider Interface established in Windows Telephony version 1.0, with
  27. telephony-aware NDIS miniport NIC drivers taking the place of TAPI
  28. service providers. This section touches briefly on the concepts
  29. embodied in Windows Telephony, but the reader is advised to consult the
  30. documentation published with the Telephony SDK for an in-depth
  31. discussion.
  32. <f Note>: There are subtle differences between the TAPI specification and the
  33. Windows 95 TAPI implementation. Please refer to the Microsoft Win32 SDK
  34. for details on the Win32 TAPI specification.
  35. The Connection Wrapper itself is an extension of the NDIS WAN library,
  36. and serves as a router for telephonic requests passed down through TAPI
  37. from user-mode client applications. WAN Miniport NIC drivers register
  38. for Connection Wrapper services by calling NdisMRegisterMiniport, and
  39. then register one or more adapters. When registration and other driver
  40. initialization have successfully completed, WAN miniport NIC drivers can
  41. receive telephonic requests from the Connection Wrapper via the standard
  42. NdisMSetInformation and NdisMQueryInformation mechanisms, and respond by
  43. calling NdisMQueryInformationComplete or NdisMSetInformationComplete and
  44. NdisMIndicateStatus to notify the Connection Wrapper of asynchronous
  45. request completion and unsolicited events (e.g. incoming calls, remote
  46. disconnections), respectively.
  47. @end
  48. */
  49. #define __FILEID__ TSPI_OBJECT_TYPE
  50. // Unique file ID for error logging
  51. #include "Miniport.h" // Defines all the miniport objects
  52. #include "string.h"
  53. #if defined(NDIS_LCODE)
  54. # pragma NDIS_LCODE // Windows 95 wants this code locked down!
  55. # pragma NDIS_LDATA
  56. #endif
  57. /* @doc INTERNAL Tspi Tspi_c STR_EQU
  58. @func
  59. <f STR_EQU> compares two strings for equality, ignoring case.
  60. @parm IN PCHAR | s1 |
  61. A pointer to the string to be compared.
  62. @parm IN PCHAR | s2 |
  63. A pointer to the string to be compared.
  64. @parm IN int | len |
  65. The length of the strings in bytes.
  66. @rdesc STR_EQU returns TRUE if the strings are equal, otherwise FASLE.
  67. */
  68. BOOLEAN STR_EQU(
  69. IN PCHAR s1,
  70. IN PCHAR s2,
  71. IN int len
  72. )
  73. {
  74. DBG_FUNC("STR_EQU")
  75. int index;
  76. int c1 = 0;
  77. int c2 = 0;
  78. for (index = 0; index < len; index++)
  79. {
  80. c1 = *s1++;
  81. c2 = *s2++;
  82. if (c1 == 0 || c2 == 0)
  83. {
  84. break;
  85. }
  86. if (c1 >= 'A' && c1 <= 'Z')
  87. {
  88. c1 += 'a' - 'A';
  89. }
  90. if (c2 >= 'A' && c2 <= 'Z')
  91. {
  92. c2 += 'a' - 'A';
  93. }
  94. if (c1 != c2)
  95. {
  96. break;
  97. }
  98. }
  99. return (c1 == c2);
  100. }
  101. /*
  102. // This defines the prototype for all TAPI OID request handlers.
  103. */
  104. typedef NDIS_STATUS (__stdcall * PTSPI_REQUEST)
  105. (
  106. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  107. IN PVOID Request,
  108. OUT PULONG BytesUsed,
  109. OUT PULONG BytesNeeded
  110. );
  111. /* @doc EXTERNAL INTERNAL Tspi Tspi_c TSPI_OID_INFO
  112. @struct TSPI_OID_INFO |
  113. This structure defines the format of the TAPI OID table entries.
  114. @comm
  115. */
  116. typedef struct TSPI_OID_INFO
  117. {
  118. ULONG Oid; // @field
  119. // TSPI OID value which identifies this record uniquely.
  120. ULONG MinBytesNeeded; // @field
  121. // Minimum number of bytes needed when this request is given to
  122. // the miniport.
  123. PTSPI_REQUEST Request; // @field
  124. // Pointer to a function which will be invoked to handle the
  125. // TSPI request.
  126. PUCHAR OidString; // @field
  127. // OID description string.
  128. } TSPI_OID_INFO, *PTSPI_OID_INFO;
  129. /*
  130. // The NDISTAPI.H file defines some of the variable length structures with
  131. // an extra byte at end (e.g. UCHAR VarArgs[1]). Since the caller is not
  132. // required to use the optional fields, the length of the structure passed
  133. // in can be exactly equal to the size of the TAPI request structure, without
  134. // any extra bytes. So we use TSPI_OPTIONAL_SIZE compensate for this
  135. // problem in our minimum structure size requirements. With structure pad,
  136. // there is an additional 4 bytes at the end.
  137. */
  138. #define TSPI_OPTIONAL_SIZE sizeof(ULONG)
  139. /*
  140. // The following is a list of all the possible TAPI OIDs.
  141. // WARNING! The list is ordered so that it can be indexed directly by the
  142. // (OID_TAPI_xxx - OID_TAPI_ACCEPT).
  143. */
  144. DBG_STATIC TSPI_OID_INFO TspiSupportedOidTable[] =
  145. {
  146. {
  147. OID_TAPI_ACCEPT,
  148. sizeof(NDIS_TAPI_ACCEPT)-TSPI_OPTIONAL_SIZE,
  149. TspiAccept,
  150. "OID_TAPI_ACCEPT"
  151. },
  152. {
  153. OID_TAPI_ANSWER,
  154. sizeof(NDIS_TAPI_ANSWER)-TSPI_OPTIONAL_SIZE,
  155. TspiAnswer,
  156. "OID_TAPI_ANSWER"
  157. },
  158. {
  159. OID_TAPI_CLOSE,
  160. sizeof(NDIS_TAPI_CLOSE),
  161. TspiClose,
  162. "OID_TAPI_CLOSE"
  163. },
  164. {
  165. OID_TAPI_CLOSE_CALL,
  166. sizeof(NDIS_TAPI_CLOSE_CALL),
  167. TspiCloseCall,
  168. "OID_TAPI_CLOSE_CALL"
  169. },
  170. {
  171. OID_TAPI_CONDITIONAL_MEDIA_DETECTION,
  172. sizeof(NDIS_TAPI_CONDITIONAL_MEDIA_DETECTION),
  173. TspiConditionalMediaDetection,
  174. "OID_TAPI_CONDITIONAL_MEDIA_DETECTION"
  175. },
  176. {
  177. OID_TAPI_DROP,
  178. sizeof(NDIS_TAPI_DROP)-TSPI_OPTIONAL_SIZE,
  179. TspiDrop,
  180. "OID_TAPI_DROP"
  181. },
  182. {
  183. OID_TAPI_GET_ADDRESS_CAPS,
  184. sizeof(NDIS_TAPI_GET_ADDRESS_CAPS),
  185. TspiGetAddressCaps,
  186. "OID_TAPI_GET_ADDRESS_CAPS"
  187. },
  188. {
  189. OID_TAPI_GET_ADDRESS_ID,
  190. sizeof(NDIS_TAPI_GET_ADDRESS_ID)-TSPI_OPTIONAL_SIZE,
  191. TspiGetAddressID,
  192. "OID_TAPI_GET_ADDRESS_ID"
  193. },
  194. {
  195. OID_TAPI_GET_ADDRESS_STATUS,
  196. sizeof(NDIS_TAPI_GET_ADDRESS_STATUS),
  197. TspiGetAddressStatus,
  198. "OID_TAPI_GET_ADDRESS_STATUS"
  199. },
  200. {
  201. OID_TAPI_GET_CALL_ADDRESS_ID,
  202. sizeof(NDIS_TAPI_GET_CALL_ADDRESS_ID),
  203. TspiGetCallAddressID,
  204. "OID_TAPI_GET_CALL_ADDRESS_ID"
  205. },
  206. {
  207. OID_TAPI_GET_CALL_INFO,
  208. sizeof(NDIS_TAPI_GET_CALL_INFO),
  209. TspiGetCallInfo,
  210. "OID_TAPI_GET_CALL_INFO"
  211. },
  212. {
  213. OID_TAPI_GET_CALL_STATUS,
  214. sizeof(NDIS_TAPI_GET_CALL_STATUS),
  215. TspiGetCallStatus,
  216. "OID_TAPI_GET_CALL_STATUS"
  217. },
  218. {
  219. OID_TAPI_GET_DEV_CAPS,
  220. sizeof(NDIS_TAPI_GET_DEV_CAPS),
  221. TspiGetDevCaps,
  222. "OID_TAPI_GET_DEV_CAPS"
  223. },
  224. {
  225. OID_TAPI_GET_DEV_CONFIG,
  226. sizeof(NDIS_TAPI_GET_DEV_CONFIG),
  227. TspiGetDevConfig,
  228. "OID_TAPI_GET_DEV_CONFIG"
  229. },
  230. {
  231. OID_TAPI_GET_ID,
  232. sizeof(NDIS_TAPI_GET_ID),
  233. TspiGetID,
  234. "OID_TAPI_GET_ID"
  235. },
  236. {
  237. OID_TAPI_GET_LINE_DEV_STATUS,
  238. sizeof(NDIS_TAPI_GET_LINE_DEV_STATUS),
  239. TspiGetLineDevStatus,
  240. "OID_TAPI_GET_LINE_DEV_STATUS"
  241. },
  242. {
  243. OID_TAPI_MAKE_CALL,
  244. sizeof(NDIS_TAPI_MAKE_CALL),
  245. TspiMakeCall,
  246. "OID_TAPI_MAKE_CALL"
  247. },
  248. {
  249. OID_TAPI_OPEN,
  250. sizeof(NDIS_TAPI_OPEN),
  251. TspiOpen,
  252. "OID_TAPI_OPEN"
  253. },
  254. {
  255. OID_TAPI_PROVIDER_INITIALIZE,
  256. sizeof(OID_TAPI_PROVIDER_INITIALIZE),
  257. TspiProviderInitialize,
  258. "OID_TAPI_PROVIDER_INITIALIZE"
  259. },
  260. {
  261. OID_TAPI_PROVIDER_SHUTDOWN,
  262. sizeof(NDIS_TAPI_PROVIDER_SHUTDOWN),
  263. TspiProviderShutdown,
  264. "OID_TAPI_PROVIDER_SHUTDOWN"
  265. },
  266. {
  267. OID_TAPI_SET_APP_SPECIFIC,
  268. sizeof(NDIS_TAPI_SET_APP_SPECIFIC),
  269. TspiSetAppSpecific,
  270. "OID_TAPI_SET_APP_SPECIFIC"
  271. },
  272. {
  273. OID_TAPI_SET_CALL_PARAMS,
  274. sizeof(NDIS_TAPI_SET_CALL_PARAMS),
  275. TspiSetCallParams,
  276. "OID_TAPI_SET_CALL_PARAMS"
  277. },
  278. {
  279. OID_TAPI_SET_DEFAULT_MEDIA_DETECTION,
  280. sizeof(NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION),
  281. TspiSetDefaultMediaDetection,
  282. "OID_TAPI_SET_DEFAULT_MEDIA_DETECTION"
  283. },
  284. {
  285. OID_TAPI_SET_DEV_CONFIG,
  286. sizeof(NDIS_TAPI_SET_DEV_CONFIG)-TSPI_OPTIONAL_SIZE,
  287. TspiSetDevConfig,
  288. "OID_TAPI_SET_DEV_CONFIG"
  289. },
  290. {
  291. OID_TAPI_SET_MEDIA_MODE,
  292. sizeof(NDIS_TAPI_SET_MEDIA_MODE),
  293. TspiSetMediaMode,
  294. "OID_TAPI_SET_MEDIA_MODE"
  295. },
  296. {
  297. OID_TAPI_SET_STATUS_MESSAGES,
  298. sizeof(NDIS_TAPI_SET_STATUS_MESSAGES),
  299. TspiSetStatusMessages,
  300. "OID_TAPI_SET_STATUS_MESSAGES"
  301. },
  302. {
  303. 0,
  304. 0,
  305. NULL,
  306. "OID_UNKNOWN"
  307. }
  308. };
  309. #define NUM_OID_ENTRIES (sizeof(TspiSupportedOidTable) / sizeof(TspiSupportedOidTable[0]))
  310. /* @doc INTERNAL Tspi Tspi_c GetOidInfo
  311. @func
  312. <f GetOidInfo> converts an NDIS TAPI OID to a TSPI_OID_INFO pointer.
  313. @parm IN NDIS_OID | Oid |
  314. The OID to be converted.
  315. @rdesc GetOidInfo returns a pointer into the TspiSupportedOidTable for the
  316. associated OID. If the Oid is not supported in the table, a pointer
  317. to the last entry is returned, which will contain a NULL Request pointer.
  318. */
  319. PTSPI_OID_INFO GetOidInfo(
  320. IN NDIS_OID Oid
  321. )
  322. {
  323. DBG_FUNC("GetOidInfo")
  324. UINT i;
  325. for (i = 0; i < NUM_OID_ENTRIES-1; i++)
  326. {
  327. if (TspiSupportedOidTable[i].Oid == Oid)
  328. {
  329. break;
  330. }
  331. }
  332. return (&TspiSupportedOidTable[i]);
  333. }
  334. /* @doc INTERNAL Tspi Tspi_c TspiRequestHandler
  335. @func
  336. The <f TspiRequestHandler> request allows for inspection of the TAPI
  337. portion of the driver's capabilities and current line status.
  338. If the Miniport does not complete the call immediately (by returning
  339. NDIS_STATUS_PENDING), it must call NdisMQueryInformationComplete to
  340. complete the call. The Miniport controls the buffers pointed to by
  341. InformationBuffer, BytesWritten, and BytesNeeded until the request
  342. completes.
  343. No other requests will be submitted to the Miniport until
  344. this request has been completed.
  345. <f Note>: Interrupts are in any state during this call.
  346. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  347. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  348. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  349. @parm IN NDIS_OID | Oid |
  350. The OID. (See section 2.2.1,2 of the Extensions to NDIS 3.0 Miniports to
  351. support Telephonic Services specification for a complete description of
  352. the OIDs.)
  353. @parm IN PVOID | InformationBuffer |
  354. The buffer that will receive the information. (See section 2.2.1,2 of
  355. the Extensions to NDIS 3.0 Miniports to support Telephonic Services
  356. specification for a description of the length required for each OID.)
  357. @parm IN ULONG | InformationBufferLength |
  358. The length in bytes of InformationBuffer.
  359. @parm OUT PULONG | BytesUsed |
  360. Returns the number of bytes used from the InformationBuffer.
  361. @parm OUT PULONG | BytesNeeded |
  362. Returns the number of additional bytes needed to satisfy the OID.
  363. @rdesc This routine returns one of the following values:
  364. @flag NDIS_STATUS_SUCCESS |
  365. If this function is successful.
  366. <f Note>: A non-zero return value indicates one of the following error codes:
  367. @iex
  368. NDIS_STATUS_INVALID_DATA
  369. NDIS_STATUS_INVALID_LENGTH
  370. NDIS_STATUS_NOT_SUPPORTED
  371. NDIS_STATUS_PENDING
  372. NDIS_STATUS_SUCCESS
  373. */
  374. NDIS_STATUS TspiRequestHandler(
  375. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  376. IN NDIS_OID Oid,
  377. IN PVOID InformationBuffer,
  378. IN ULONG InformationBufferLength,
  379. OUT PULONG BytesUsed,
  380. OUT PULONG BytesNeeded
  381. )
  382. {
  383. DBG_FUNC("TspiRequestHandler")
  384. NDIS_STATUS Status;
  385. PTSPI_OID_INFO OidInfo;
  386. DBG_ENTER(pAdapter);
  387. /*
  388. // Get TSPI_OID_INFO pointer.
  389. */
  390. OidInfo = GetOidInfo(Oid);
  391. DBG_REQUEST(pAdapter,
  392. ("(OID=0x%08X %s)\n\t\tInfoLength=%d InfoBuffer=0x%X MinLength=%d\n",
  393. Oid, OidInfo->OidString,
  394. InformationBufferLength,
  395. InformationBuffer,
  396. OidInfo->MinBytesNeeded
  397. ));
  398. /*
  399. // Make sure this is a valid request.
  400. */
  401. if (OidInfo->Request != NULL)
  402. {
  403. /*
  404. // If the buffer provided is at least the minimum required,
  405. // call the handler to do the work.
  406. */
  407. if (InformationBufferLength >= OidInfo->MinBytesNeeded)
  408. {
  409. /*
  410. // Default BytesUsed indicates that we used the minimum necessary.
  411. */
  412. *BytesUsed = OidInfo->MinBytesNeeded;
  413. /*
  414. // Default BytesNeeded indicates that we don't need any more.
  415. */
  416. *BytesNeeded = 0;
  417. Status = OidInfo->Request(pAdapter, InformationBuffer,
  418. BytesUsed, BytesNeeded);
  419. }
  420. else
  421. {
  422. /*
  423. // The caller did not provide an adequate buffer, so we have to
  424. // tell them how much more we need to satisfy the request.
  425. // Actually, this is the minimum additional bytes we'll need,
  426. // the request handler may have even more bytes to add.
  427. */
  428. *BytesUsed = 0;
  429. *BytesNeeded = (OidInfo->MinBytesNeeded - InformationBufferLength);
  430. Status = NDIS_STATUS_INVALID_LENGTH;
  431. }
  432. }
  433. else
  434. {
  435. Status = NDIS_STATUS_TAPI_OPERATIONUNAVAIL;
  436. }
  437. DBG_REQUEST(pAdapter,
  438. ("RETURN: Status=0x%X Needed=%d Used=%d\n",
  439. Status, *BytesNeeded, *BytesUsed));
  440. /*
  441. // Indicate a status complete if it's needed.
  442. */
  443. if (pAdapter->NeedStatusCompleteIndication)
  444. {
  445. pAdapter->NeedStatusCompleteIndication = FALSE;
  446. NdisMIndicateStatusComplete(pAdapter->MiniportAdapterHandle);
  447. }
  448. DBG_RETURN(pAdapter, Status);
  449. return (Status);
  450. }
  451. /* @doc INTERNAL Tspi Tspi_c TspiProviderInitialize
  452. @func
  453. This request initializes the TAPI portion of the miniport.
  454. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  455. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  456. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  457. @parm IN PNDIS_TAPI_PROVIDER_INITIALIZE | Request |
  458. A pointer to the NDIS_TAPI request structure for this call.
  459. @iex
  460. typedef struct _NDIS_TAPI_PROVIDER_INITIALIZE
  461. {
  462. IN ULONG ulRequestID;
  463. IN ULONG ulDeviceIDBase;
  464. OUT ULONG ulNumLineDevs;
  465. OUT ULONG ulProviderID;
  466. } NDIS_TAPI_PROVIDER_INITIALIZE, *PNDIS_TAPI_PROVIDER_INITIALIZE;
  467. @rdesc This routine returns one of the following values:
  468. @flag NDIS_STATUS_SUCCESS |
  469. If this function is successful.
  470. <f Note>: A non-zero return value indicates one of the following error codes:
  471. @iex
  472. NDIS_STATUS_RESOURCES
  473. NDIS_STATUS_FAILURE
  474. NDIS_STATUS_TAPI_RESOURCEUNAVAIL
  475. */
  476. NDIS_STATUS TspiProviderInitialize(
  477. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  478. IN PNDIS_TAPI_PROVIDER_INITIALIZE Request,
  479. OUT PULONG BytesWritten,
  480. OUT PULONG BytesNeeded
  481. )
  482. {
  483. DBG_FUNC("TspiProviderInitialize")
  484. DBG_ENTER(pAdapter);
  485. DBG_PARAMS(pAdapter,
  486. ("\n\tulDeviceIDBase=%d\n"
  487. "\tNumLineDevs=%d\n",
  488. Request->ulDeviceIDBase,
  489. pAdapter->NumBChannels
  490. ));
  491. /*
  492. // Save the device ID base value.
  493. */
  494. pAdapter->DeviceIdBase = Request->ulDeviceIDBase;
  495. /*
  496. // Return the number of lines.
  497. */
  498. Request->ulNumLineDevs = pAdapter->NumBChannels;
  499. /*
  500. // Before completing the PROVIDER_INIT request, the miniport should fill
  501. // in the ulNumLineDevs field of the request with the number of line
  502. // devices supported by the adapter. The miniport should also set the
  503. // ulProviderID field to a unique (per adapter) value. (There is no
  504. // method currently in place to guarantee unique ulProviderID values,
  505. // so we use the virtual address of our adapter structure.)
  506. */
  507. Request->ulProviderID = (ULONG) (ULONG_PTR)pAdapter;
  508. /*
  509. // TODO - Reinitialize the stat counters.
  510. */
  511. pAdapter->TotalRxBytes = 0;
  512. pAdapter->TotalTxBytes = 0;
  513. pAdapter->TotalRxPackets = 0;
  514. pAdapter->TotalTxPackets = 0;
  515. /*
  516. // Try to connect to the DChannel.
  517. */
  518. if (DChannelOpen(pAdapter->pDChannel) != NDIS_STATUS_SUCCESS)
  519. {
  520. DBG_ERROR(pAdapter,("Returning NDIS_STATUS_TAPI_NODRIVER\n"));
  521. return (NDIS_STATUS_TAPI_NODRIVER);
  522. }
  523. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  524. return (NDIS_STATUS_SUCCESS);
  525. }
  526. /* @doc INTERNAL Tspi Tspi_c TspiProviderShutdown
  527. @func
  528. This request shuts down the miniport. The miniport should terminate any
  529. activities it has in progress.
  530. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  531. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  532. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  533. @parm IN PNDIS_TAPI_PROVIDER_SHUTDOWN | Request |
  534. A pointer to the NDIS_TAPI request structure for this call.
  535. @iex
  536. typedef struct _NDIS_TAPI_PROVIDER_SHUTDOWN
  537. {
  538. IN ULONG ulRequestID;
  539. } NDIS_TAPI_PROVIDER_SHUTDOWN, *PNDIS_TAPI_PROVIDER_SHUTDOWN;
  540. @rdesc This routine returns one of the following values:
  541. @flag NDIS_STATUS_SUCCESS |
  542. If this function is successful.
  543. */
  544. NDIS_STATUS TspiProviderShutdown(
  545. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  546. IN PNDIS_TAPI_PROVIDER_SHUTDOWN Request,
  547. OUT PULONG BytesRead,
  548. OUT PULONG BytesNeeded
  549. )
  550. {
  551. DBG_FUNC("TspiProviderShutdown")
  552. PBCHANNEL_OBJECT pBChannel;
  553. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  554. USHORT BChannelIndex;
  555. // Index into the pBChannelArray.
  556. DBG_ENTER(pAdapter);
  557. /*
  558. // Hangup all of the lines.
  559. */
  560. for (BChannelIndex = 0; BChannelIndex < pAdapter->NumBChannels; BChannelIndex++)
  561. {
  562. pBChannel = GET_BCHANNEL_FROM_INDEX(pAdapter, BChannelIndex);
  563. if (pBChannel->IsOpen)
  564. {
  565. /*
  566. // Close the BChannel - any open call will be dropped.
  567. */
  568. BChannelClose(pBChannel);
  569. }
  570. }
  571. pAdapter->NumLineOpens = 0;
  572. /*
  573. // Close DChannel.
  574. */
  575. DChannelClose(pAdapter->pDChannel);
  576. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  577. return (NDIS_STATUS_SUCCESS);
  578. }
  579. /* @doc INTERNAL Tspi Tspi_c TspiResetHandler
  580. @func
  581. <f TspiResetHandler> is called by the MiniportReset routine after the
  582. hardware has been reset due to some failure detection. We need to make
  583. sure the line and call state information is conveyed properly to the
  584. Connection Wrapper.
  585. We only generate hangups on streams which have issued ENABLE_D_CHANNELs
  586. This function is called when the PRI board is RESET and when we receive a
  587. T1_STATUS message with RED alarm set. When we get a RED alarm, we issue
  588. disable D channel messages for all open links. This is indicated by the
  589. argument nohup_Link set to NULL.
  590. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  591. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  592. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  593. */
  594. VOID TspiResetHandler(
  595. IN PMINIPORT_ADAPTER_OBJECT pAdapter
  596. )
  597. {
  598. DBG_FUNC("TspiResetHandler")
  599. PBCHANNEL_OBJECT pBChannel;
  600. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  601. USHORT BChannelIndex;
  602. // Index into the pBChannelArray.
  603. DBG_ENTER(pAdapter);
  604. /*
  605. // Force disconnect on all lines.
  606. */
  607. for (BChannelIndex = 0; BChannelIndex < pAdapter->NumBChannels; BChannelIndex++)
  608. {
  609. pBChannel = GET_BCHANNEL_FROM_INDEX(pAdapter, BChannelIndex);
  610. if (pBChannel->IsOpen &&
  611. pBChannel->CallState != 0 &&
  612. pBChannel->CallState != LINECALLSTATE_IDLE)
  613. {
  614. TspiCallStateHandler(pAdapter, pBChannel,
  615. LINECALLSTATE_IDLE,
  616. 0);
  617. pBChannel->CallState = 0;
  618. }
  619. }
  620. DBG_LEAVE(pAdapter);
  621. }