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.

1603 lines
29 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. D:\nt\private\ntos\tdi\rawwan\core\ndisbind.c
  5. Abstract:
  6. NDIS entry points and helper routines for binding, unbinding, opening
  7. and closing adapters.
  8. Revision History:
  9. Who When What
  10. -------- -------- ----------------------------------------------
  11. arvindm 05-02-97 Created
  12. Notes:
  13. --*/
  14. #include <precomp.h>
  15. #define _FILENUMBER 'DNIB'
  16. VOID
  17. RWanNdisBindAdapter(
  18. OUT PNDIS_STATUS pStatus,
  19. IN NDIS_HANDLE BindContext,
  20. IN PNDIS_STRING pDeviceName,
  21. IN PVOID SystemSpecific1,
  22. IN PVOID SystemSpecific2
  23. )
  24. /*++
  25. Routine Description:
  26. This is the NDIS protocol entry point for binding to an adapter.
  27. We open the adapter and see if it is one of the supported types.
  28. Action continues when we get notified of a Call Manager that
  29. has registered support for an Address Family.
  30. Arguments:
  31. pStatus - Place to return status of this call
  32. BindContext - Used to complete this call, if we pend it.
  33. pDeviceName - Name of adapter we are asked to bind to.
  34. SystemSpecific1 - Handle to use to access configuration information
  35. SystemSpecific2 - Not used
  36. Return Value:
  37. None directly. But we set *pStatus to NDIS_STATUS_PENDING if we
  38. made the call to open the adapter, NDIS_STATUS_NOT_RECOGNIZED
  39. if this adapter isn't one of the supported media types, NDIS_STATUS_RESOURCES
  40. if we hit any allocation failures.
  41. --*/
  42. {
  43. PRWAN_NDIS_ADAPTER pAdapter;
  44. PNDIS_MEDIUM pMediaArray;
  45. UINT MediaCount; // Number of media-types we support
  46. NDIS_STATUS Status;
  47. NDIS_STATUS OpenStatus;
  48. ULONG TotalLength;
  49. RWANDEBUGP(DL_LOUD, DC_BIND,
  50. ("BindAdapter: Context x%x, Device %Z, SS1 x%x, SS2 x%x\n",
  51. BindContext, pDeviceName, SystemSpecific1, SystemSpecific2));
  52. #if DBG
  53. if (RWanSkipAll)
  54. {
  55. RWANDEBUGP(DL_ERROR, DC_WILDCARD,
  56. ("BindAdapter: bailing out!\n"));
  57. *pStatus = NDIS_STATUS_NOT_RECOGNIZED;
  58. return;
  59. }
  60. #endif // DBG
  61. //
  62. // Initialize.
  63. //
  64. pAdapter = NULL_PRWAN_NDIS_ADAPTER;
  65. pMediaArray = NULL;
  66. do
  67. {
  68. //
  69. // Allocate an Adapter structure, along with space for the device
  70. // name.
  71. //
  72. TotalLength = sizeof(RWAN_NDIS_ADAPTER) + (pDeviceName->MaximumLength)*sizeof(WCHAR);
  73. RWAN_ALLOC_MEM(pAdapter, RWAN_NDIS_ADAPTER, TotalLength);
  74. if (pAdapter == NULL_PRWAN_NDIS_ADAPTER)
  75. {
  76. RWANDEBUGP(DL_WARN, DC_BIND,
  77. ("BindAdapter: Couldnt allocate adapter (%d bytes)\n", TotalLength));
  78. Status = NDIS_STATUS_RESOURCES;
  79. break;
  80. }
  81. //
  82. // Get the list of NDIS media that we support.
  83. //
  84. pMediaArray = RWanGetSupportedMedia(&MediaCount);
  85. if (pMediaArray == NULL)
  86. {
  87. RWANDEBUGP(DL_WARN, DC_BIND,
  88. ("BindAdapter: Couldnt get supported media list!\n"));
  89. Status = NDIS_STATUS_NOT_RECOGNIZED;
  90. break;
  91. }
  92. //
  93. // Initialize the Adapter.
  94. //
  95. RWAN_ZERO_MEM(pAdapter, TotalLength);
  96. RWAN_SET_SIGNATURE(pAdapter, nad);
  97. RWAN_INIT_LIST(&(pAdapter->AfList));
  98. RWAN_INIT_LOCK(&(pAdapter->Lock));
  99. pAdapter->pMediaArray = pMediaArray;
  100. pAdapter->BindContext = BindContext;
  101. //
  102. // Copy in the device name.
  103. //
  104. pAdapter->DeviceName.Buffer = (PWCHAR)((PUCHAR)pAdapter + sizeof(RWAN_NDIS_ADAPTER));
  105. pAdapter->DeviceName.MaximumLength = pDeviceName->MaximumLength;
  106. pAdapter->DeviceName.Length = pDeviceName->Length;
  107. RWAN_COPY_MEM(pAdapter->DeviceName.Buffer, pDeviceName->Buffer, pDeviceName->Length);
  108. pAdapter->State = RWANS_AD_OPENING;
  109. //
  110. // Link this adapter to the global list of adapters.
  111. //
  112. RWAN_ACQUIRE_GLOBAL_LOCK();
  113. RWAN_INSERT_HEAD_LIST(&(pRWanGlobal->AdapterList),
  114. &(pAdapter->AdapterLink));
  115. pRWanGlobal->AdapterCount++;
  116. RWAN_RELEASE_GLOBAL_LOCK();
  117. //
  118. // Open the Adapter.
  119. //
  120. NdisOpenAdapter(
  121. &Status,
  122. &OpenStatus,
  123. &(pAdapter->NdisAdapterHandle),
  124. &(pAdapter->MediumIndex), // place to return selected medium index
  125. pMediaArray, // List of media types we support
  126. MediaCount, // Length of above list
  127. pRWanGlobal->ProtocolHandle,
  128. (NDIS_HANDLE)pAdapter, // our context for the adapter binding
  129. pDeviceName,
  130. 0, // open options (none)
  131. (PSTRING)NULL // Addressing info (none)
  132. );
  133. if (Status != NDIS_STATUS_PENDING)
  134. {
  135. RWanNdisOpenAdapterComplete(
  136. (NDIS_HANDLE)pAdapter,
  137. Status,
  138. OpenStatus
  139. );
  140. }
  141. Status = NDIS_STATUS_PENDING;
  142. break;
  143. }
  144. while (FALSE);
  145. if (Status != NDIS_STATUS_PENDING)
  146. {
  147. //
  148. // Failed somewhere; clean up.
  149. //
  150. if (pAdapter != NULL_PRWAN_NDIS_ADAPTER)
  151. {
  152. RWAN_FREE_MEM(pAdapter);
  153. }
  154. if (pMediaArray != NULL)
  155. {
  156. RWAN_FREE_MEM(pMediaArray);
  157. }
  158. }
  159. *pStatus = Status;
  160. RWANDEBUGP(DL_LOUD, DC_BIND,
  161. ("BindAdapter: pAdapter x%x, returning x%x\n", pAdapter, Status));
  162. return;
  163. }
  164. VOID
  165. RWanNdisUnbindAdapter(
  166. OUT PNDIS_STATUS pStatus,
  167. IN NDIS_HANDLE ProtocolBindingContext,
  168. IN NDIS_HANDLE UnbindContext
  169. )
  170. /*++
  171. Routine Description:
  172. This is the NDIS protocol entry point for unbinding from an adapter
  173. that we have opened.
  174. Arguments:
  175. pStatus - Place to return status of this call
  176. ProtocolBindingContext - Our context for the bound adapter
  177. UnbindContext - To be used when we complete the unbind.
  178. Return Value:
  179. None. We set *pStatus to NDIS_STATUS_PENDING.
  180. --*/
  181. {
  182. PRWAN_NDIS_ADAPTER pAdapter;
  183. PLIST_ENTRY pAfEntry;
  184. PLIST_ENTRY pNextAfEntry;
  185. PRWAN_NDIS_AF pAf;
  186. pAdapter = (PRWAN_NDIS_ADAPTER)ProtocolBindingContext;
  187. RWAN_STRUCT_ASSERT(pAdapter, nad);
  188. RWANDEBUGP(DL_WARN, DC_BIND,
  189. ("UnbindAdapter: pAdapter x%x, State x%x\n", pAdapter, pAdapter->State));
  190. RWAN_ACQUIRE_ADAPTER_LOCK(pAdapter);
  191. //
  192. // Store away the unbind context for use in completing this
  193. // unbind later.
  194. //
  195. pAdapter->BindContext = UnbindContext;
  196. RWAN_SET_BIT(pAdapter->Flags, RWANF_AD_UNBIND_PENDING);
  197. *pStatus = NDIS_STATUS_PENDING;
  198. if (RWAN_IS_LIST_EMPTY(&(pAdapter->AfList)))
  199. {
  200. RWanCloseAdapter(pAdapter);
  201. //
  202. // Lock is released within the above.
  203. //
  204. }
  205. else
  206. {
  207. //
  208. // Shut down all AFs on this adapter. We release the lock
  209. // early since we are unbinding and don't expect any other
  210. // events now.
  211. //
  212. RWAN_RELEASE_ADAPTER_LOCK(pAdapter);
  213. for (pAfEntry = pAdapter->AfList.Flink;
  214. pAfEntry != &(pAdapter->AfList);
  215. pAfEntry = pNextAfEntry)
  216. {
  217. pNextAfEntry = pAfEntry->Flink;
  218. pAf = CONTAINING_RECORD(pAfEntry, RWAN_NDIS_AF, AfLink);
  219. RWanShutdownAf(pAf);
  220. }
  221. }
  222. return;
  223. }
  224. VOID
  225. RWanNdisOpenAdapterComplete(
  226. IN NDIS_HANDLE ProtocolContext,
  227. IN NDIS_STATUS Status,
  228. IN NDIS_STATUS OpenErrorStatus
  229. )
  230. /*++
  231. Routine Description:
  232. This is the NDIS Entry point called when a previous call we made
  233. to NdisOpenAdapter has completed.
  234. Arguments:
  235. ProtocolContext - our context for the adapter being opened,
  236. which is a pointer to our Adapter structure.
  237. Status - Final status of NdisOpenAdapter
  238. OpenErrorStatus - Error code in case of failure
  239. Return Value:
  240. None
  241. --*/
  242. {
  243. PRWAN_NDIS_ADAPTER pAdapter;
  244. NDIS_HANDLE BindContext;
  245. PNDIS_MEDIUM pMediaArray;
  246. pAdapter = (PRWAN_NDIS_ADAPTER)ProtocolContext;
  247. RWAN_STRUCT_ASSERT(pAdapter, nad);
  248. BindContext = pAdapter->BindContext;
  249. pMediaArray = pAdapter->pMediaArray;
  250. if (Status == NDIS_STATUS_SUCCESS)
  251. {
  252. RWAN_ACQUIRE_ADAPTER_LOCK(pAdapter);
  253. pAdapter->Medium = pMediaArray[pAdapter->MediumIndex];
  254. pAdapter->State = RWANS_AD_OPENED;
  255. RWAN_RELEASE_ADAPTER_LOCK(pAdapter);
  256. }
  257. else
  258. {
  259. //
  260. // Remove this adapter from the global list.
  261. //
  262. //
  263. RWAN_ACQUIRE_GLOBAL_LOCK();
  264. RWAN_DELETE_FROM_LIST(&(pAdapter->AdapterLink));
  265. pRWanGlobal->AdapterCount--;
  266. RWAN_RELEASE_GLOBAL_LOCK();
  267. RWAN_FREE_MEM(pAdapter);
  268. }
  269. RWAN_FREE_MEM(pMediaArray);
  270. RWANDEBUGP(DL_INFO, DC_BIND, ("OpenAdapterComplete: pAdapter x%x, Status x%x\n",
  271. pAdapter, Status));
  272. //
  273. // Now complete the BindAdapter that we had pended.
  274. //
  275. NdisCompleteBindAdapter(
  276. BindContext,
  277. Status,
  278. OpenErrorStatus
  279. );
  280. return;
  281. }
  282. VOID
  283. RWanNdisCloseAdapterComplete(
  284. IN NDIS_HANDLE ProtocolBindingContext,
  285. IN NDIS_STATUS Status
  286. )
  287. /*++
  288. Routine Description:
  289. This is the NDIS entry point signifying completion of a pended call
  290. to NdisCloseAdapter. If we were unbinding from the adapter, complete
  291. the unbind now.
  292. Arguments:
  293. ProtocolBindingContext - our context for an adapter binding,
  294. which is a pointer to our Adapter structure.
  295. Status - Final status of NdisCloseAdapter
  296. Return Value:
  297. None
  298. --*/
  299. {
  300. PRWAN_NDIS_ADAPTER pAdapter;
  301. NDIS_HANDLE UnbindContext;
  302. RWAN_ASSERT(Status == NDIS_STATUS_SUCCESS);
  303. pAdapter = (PRWAN_NDIS_ADAPTER)ProtocolBindingContext;
  304. RWAN_STRUCT_ASSERT(pAdapter, nad);
  305. //
  306. // Unlink this adapter from the global list of adapters.
  307. //
  308. RWAN_ACQUIRE_GLOBAL_LOCK();
  309. RWAN_DELETE_FROM_LIST(&(pAdapter->AdapterLink));
  310. pRWanGlobal->AdapterCount--;
  311. RWAN_RELEASE_GLOBAL_LOCK();
  312. UnbindContext = pAdapter->BindContext;
  313. RWAN_FREE_MEM(pAdapter);
  314. //
  315. // We would have closed the adapter because of one of the following:
  316. // 1. NDIS told us to Unbind from the adapter -> complete the Unbind
  317. // 2. We are unloading -> continue this process
  318. //
  319. if (UnbindContext != NULL)
  320. {
  321. NdisCompleteUnbindAdapter(
  322. UnbindContext,
  323. NDIS_STATUS_SUCCESS
  324. );
  325. }
  326. else
  327. {
  328. //
  329. // We are here because our Unload handler got called.
  330. // Wake up the thread that's waiting for this adapter
  331. // to be closed.
  332. //
  333. RWAN_SIGNAL_EVENT_STRUCT(&pRWanGlobal->Event, Status);
  334. }
  335. return;
  336. }
  337. VOID
  338. RWanNdisAfRegisterNotify(
  339. IN NDIS_HANDLE ProtocolContext,
  340. IN PCO_ADDRESS_FAMILY pAddressFamily
  341. )
  342. /*++
  343. Routine Description:
  344. This is the NDIS entry point to announce the presence of a
  345. Call manager supporting a specified Address Family on an
  346. adapter that we are bound to.
  347. If this address family is one that we support, we create an
  348. AF block, and open the address family.
  349. Arguments:
  350. ProtocolContext - our context for an adapter binding,
  351. which is a pointer to our Adapter structure.
  352. pAddressFamily - pointer to structure describing the Address Family
  353. Return Value:
  354. None
  355. --*/
  356. {
  357. PRWAN_NDIS_ADAPTER pAdapter;
  358. NDIS_STATUS Status;
  359. PLIST_ENTRY pAfInfoEntry;
  360. PRWAN_NDIS_AF_INFO pAfInfo;
  361. PRWAN_NDIS_AF pAf;
  362. BOOLEAN bFound;
  363. pAdapter = (PRWAN_NDIS_ADAPTER)ProtocolContext;
  364. RWAN_STRUCT_ASSERT(pAdapter, nad);
  365. do
  366. {
  367. //
  368. // Create a new NDIS AF block.
  369. //
  370. pAf = RWanAllocateAf();
  371. if (pAf == NULL)
  372. {
  373. break;
  374. }
  375. pAf->pAdapter = pAdapter;
  376. RWanReferenceAf(pAf); // Open AF ref
  377. //
  378. // Search for an AF_INFO structure matching this <NDIS AF, Medium>
  379. // pair.
  380. //
  381. bFound = FALSE;
  382. RWAN_ACQUIRE_GLOBAL_LOCK();
  383. for (pAfInfoEntry = pRWanGlobal->AfInfoList.Flink;
  384. pAfInfoEntry != &(pRWanGlobal->AfInfoList);
  385. pAfInfoEntry = pAfInfoEntry->Flink)
  386. {
  387. pAfInfo = CONTAINING_RECORD(pAfInfoEntry, RWAN_NDIS_AF_INFO, AfInfoLink);
  388. if ((pAfInfo->AfChars.Medium == pAdapter->Medium)
  389. &&
  390. (RWAN_EQUAL_MEM(pAddressFamily,
  391. &(pAfInfo->AfChars.AddressFamily),
  392. sizeof(*pAddressFamily))))
  393. {
  394. bFound = TRUE;
  395. pAf->pAfInfo = pAfInfo;
  396. RWAN_INSERT_TAIL_LIST(&(pAfInfo->NdisAfList),
  397. &(pAf->AfInfoLink));
  398. break;
  399. }
  400. }
  401. RWAN_RELEASE_GLOBAL_LOCK();
  402. if (!bFound)
  403. {
  404. RWAN_FREE_MEM(pAf);
  405. break;
  406. }
  407. //
  408. // Open the Address Family.
  409. //
  410. Status = NdisClOpenAddressFamily(
  411. pAdapter->NdisAdapterHandle,
  412. pAddressFamily,
  413. (NDIS_HANDLE)pAf,
  414. &RWanNdisClientCharacteristics,
  415. sizeof(RWanNdisClientCharacteristics),
  416. &(pAf->NdisAfHandle)
  417. );
  418. if (Status != NDIS_STATUS_PENDING)
  419. {
  420. RWanNdisOpenAddressFamilyComplete(
  421. Status,
  422. (NDIS_HANDLE)pAf,
  423. pAf->NdisAfHandle
  424. );
  425. }
  426. break;
  427. }
  428. while (FALSE);
  429. return;
  430. }
  431. VOID
  432. RWanNdisOpenAddressFamilyComplete(
  433. IN NDIS_STATUS Status,
  434. IN NDIS_HANDLE ProtocolAfContext,
  435. IN NDIS_HANDLE NdisAfHandle
  436. )
  437. /*++
  438. Routine Description:
  439. This is the NDIS entry point signifying completion of a call
  440. we made to NdisClOpenAddressFamily. If the Address Family open
  441. was successful, we store the returned handle in our AF block.
  442. Otherwise we delete the AF block.
  443. Arguments:
  444. Status - Final status of NdisClOpenAddressFamily
  445. ProtocolAfContext - Our context for an AF open, which is a pointer
  446. to an RWAN_NDIS_AF structure
  447. NdisAfHandle - If successful, this is the handle we should use
  448. to refer to this AF henceforth
  449. Return Value:
  450. None
  451. --*/
  452. {
  453. PRWAN_NDIS_AF pAf;
  454. NDIS_HANDLE NdisAdapterHandle;
  455. PRWAN_NDIS_AF_INFO pAfInfo;
  456. INT rc;
  457. RWAN_STATUS RWanStatus;
  458. ULONG MaxMsgSize;
  459. pAf = (PRWAN_NDIS_AF)ProtocolAfContext;
  460. RWAN_STRUCT_ASSERT(pAf, naf);
  461. RWAN_ACQUIRE_AF_LOCK(pAf);
  462. if (Status == NDIS_STATUS_SUCCESS)
  463. {
  464. pAf->NdisAfHandle = NdisAfHandle;
  465. NdisAdapterHandle = pAf->pAdapter->NdisAdapterHandle;
  466. pAfInfo = pAf->pAfInfo;
  467. RWAN_RELEASE_AF_LOCK(pAf);
  468. //
  469. // Tell the AF-specific module about this successful AF open,
  470. // so that it can initialize and return its context for this open.
  471. //
  472. RWanStatus = (*pAfInfo->AfChars.pAfSpOpenAf)(
  473. pAfInfo->AfSpContext,
  474. (RWAN_HANDLE)pAf,
  475. &pAf->AfSpAFContext,
  476. &MaxMsgSize
  477. );
  478. if (RWanStatus != RWAN_STATUS_PENDING)
  479. {
  480. RWanAfSpOpenAfComplete(
  481. RWanStatus,
  482. (RWAN_HANDLE)pAf,
  483. pAf->AfSpAFContext,
  484. MaxMsgSize
  485. );
  486. }
  487. }
  488. else
  489. {
  490. RWANDEBUGP(DL_WARN, DC_WILDCARD,
  491. ("OpenAfComplete: Af x%x, bad status x%x\n", pAf, Status));
  492. rc = RWanDereferenceAf(pAf); // Open AF failure
  493. RWAN_ASSERT(rc == 0);
  494. }
  495. return;
  496. }
  497. VOID
  498. RWanShutdownAf(
  499. IN PRWAN_NDIS_AF pAf
  500. )
  501. /*++
  502. Routine Description:
  503. Shut down an AF open: deregister all SAPs and abort all calls.
  504. Arguments:
  505. pAf - Points to NDIS AF block
  506. Return Value:
  507. None
  508. --*/
  509. {
  510. PRWAN_TDI_ADDRESS pAddrObject;
  511. PRWAN_NDIS_SAP pSap;
  512. PLIST_ENTRY pSapEntry;
  513. PLIST_ENTRY pNextSapEntry;
  514. NDIS_HANDLE NdisSapHandle;
  515. NDIS_STATUS Status;
  516. PRWAN_TDI_CONNECTION pConnObject;
  517. PLIST_ENTRY pVcEntry;
  518. PLIST_ENTRY pNextVcEntry;
  519. PRWAN_NDIS_VC pVc;
  520. INT rc;
  521. RWAN_HANDLE AfSpAFContext;
  522. RWAN_STATUS RWanStatus;
  523. //
  524. // Check if we are already closing this AF.
  525. //
  526. RWAN_ACQUIRE_AF_LOCK(pAf);
  527. RWANDEBUGP(DL_LOUD, DC_BIND,
  528. ("ShutdownAf: AF x%x, Flags x%x, AfHandle x%x\n", pAf, pAf->Flags, pAf->NdisAfHandle));
  529. if (RWAN_IS_BIT_SET(pAf->Flags, RWANF_AF_CLOSING))
  530. {
  531. RWAN_RELEASE_AF_LOCK(pAf);
  532. return;
  533. }
  534. RWAN_SET_BIT(pAf->Flags, RWANF_AF_CLOSING);
  535. //
  536. // Make sure the AF doesn't go away while we are here.
  537. //
  538. RWanReferenceAf(pAf); // temp ref: RWanShutdownAf
  539. //
  540. // Deregister all SAPs.
  541. //
  542. for (pSapEntry = pAf->NdisSapList.Flink;
  543. pSapEntry != &(pAf->NdisSapList);
  544. pSapEntry = pNextSapEntry)
  545. {
  546. pNextSapEntry = pSapEntry->Flink;
  547. pSap = CONTAINING_RECORD(pSapEntry, RWAN_NDIS_SAP, AfLink);
  548. pAddrObject = pSap->pAddrObject;
  549. RWAN_RELEASE_AF_LOCK(pAf);
  550. RWAN_ACQUIRE_ADDRESS_LOCK(pAddrObject);
  551. if (!RWAN_IS_BIT_SET(pSap->Flags, RWANF_SAP_CLOSING))
  552. {
  553. RWAN_SET_BIT(pSap->Flags, RWANF_SAP_CLOSING);
  554. RWAN_RELEASE_ADDRESS_LOCK(pAddrObject);
  555. NdisSapHandle = pSap->NdisSapHandle;
  556. RWAN_ASSERT(NdisSapHandle != NULL);
  557. Status = NdisClDeregisterSap(NdisSapHandle);
  558. if (Status != NDIS_STATUS_PENDING)
  559. {
  560. RWanNdisDeregisterSapComplete(
  561. Status,
  562. (NDIS_HANDLE)pSap
  563. );
  564. }
  565. }
  566. else
  567. {
  568. //
  569. // This SAP is already closing.
  570. //
  571. RWAN_RELEASE_ADDRESS_LOCK(pAddrObject);
  572. }
  573. RWAN_ACQUIRE_AF_LOCK(pAf);
  574. }
  575. //
  576. // Close all connections on this AF.
  577. //
  578. for (pVcEntry = pAf->NdisVcList.Flink;
  579. pVcEntry != &(pAf->NdisVcList);
  580. pVcEntry = pNextVcEntry)
  581. {
  582. pNextVcEntry = pVcEntry->Flink;
  583. pVc = CONTAINING_RECORD(pVcEntry, RWAN_NDIS_VC, VcLink);
  584. RWAN_STRUCT_ASSERT(pVc, nvc);
  585. pConnObject = pVc->pConnObject;
  586. if (pConnObject != NULL)
  587. {
  588. RWAN_ACQUIRE_CONN_LOCK(pConnObject);
  589. RWanReferenceConnObject(pConnObject); // temp - ShutdownAf
  590. RWAN_RELEASE_CONN_LOCK(pConnObject);
  591. RWAN_RELEASE_AF_LOCK(pAf);
  592. RWAN_ACQUIRE_CONN_LOCK(pConnObject);
  593. rc = RWanDereferenceConnObject(pConnObject); // temp - ShutdownAf
  594. if (rc != 0)
  595. {
  596. RWanDoTdiDisconnect(
  597. pConnObject,
  598. NULL, // pTdiRequest,
  599. NULL, // pTimeout
  600. 0, // Flags
  601. NULL, // pDisconnInfo
  602. NULL // pReturnInfo
  603. );
  604. //
  605. // Conn Object lock is released within the above.
  606. //
  607. }
  608. RWAN_ACQUIRE_AF_LOCK(pAf);
  609. }
  610. }
  611. //
  612. // Tell the Media-specific module to clean up because this AF
  613. // is being closed.
  614. //
  615. AfSpAFContext = pAf->AfSpAFContext;
  616. RWAN_RELEASE_AF_LOCK(pAf);
  617. if (AfSpAFContext != NULL)
  618. {
  619. RWAN_ASSERT(pAf->pAfInfo->AfChars.pAfSpCloseAf != NULL);
  620. RWanStatus = (*pAf->pAfInfo->AfChars.pAfSpCloseAf)(AfSpAFContext);
  621. if (RWanStatus != RWAN_STATUS_PENDING)
  622. {
  623. RWanAfSpCloseAfComplete((RWAN_HANDLE)pAf);
  624. }
  625. }
  626. else
  627. {
  628. //
  629. // We don't have to inform the media-specific module.
  630. //
  631. RWanAfSpCloseAfComplete((RWAN_HANDLE)pAf);
  632. }
  633. RWAN_ACQUIRE_AF_LOCK(pAf);
  634. rc = RWanDereferenceAf(pAf); // temp ref: RWanShutdownAf
  635. if (rc != 0)
  636. {
  637. RWAN_RELEASE_AF_LOCK(pAf);
  638. }
  639. //
  640. // else the AF is gone.
  641. //
  642. return;
  643. }
  644. VOID
  645. RWanNdisCloseAddressFamilyComplete(
  646. IN NDIS_STATUS Status,
  647. IN NDIS_HANDLE OurAfContext
  648. )
  649. /*++
  650. Routine Description:
  651. This is the NDIS entry point signifying completion of
  652. a call to NdisClCloseAddressFamily.
  653. Arguments:
  654. Status - Final status of the Close AF
  655. OurAfContext - Pointer to AF block
  656. Return Value:
  657. None
  658. --*/
  659. {
  660. PRWAN_NDIS_AF pAf;
  661. INT rc;
  662. RWAN_ASSERT(Status == NDIS_STATUS_SUCCESS);
  663. pAf = (PRWAN_NDIS_AF)OurAfContext;
  664. RWAN_STRUCT_ASSERT(pAf, naf);
  665. RWAN_ACQUIRE_AF_LOCK(pAf);
  666. rc = RWanDereferenceAf(pAf); // CloseAfComplete
  667. if (rc != 0)
  668. {
  669. RWAN_RELEASE_AF_LOCK(pAf);
  670. }
  671. return;
  672. }
  673. PNDIS_MEDIUM
  674. RWanGetSupportedMedia(
  675. OUT PULONG pMediaCount
  676. )
  677. /*++
  678. Routine Description:
  679. Return a list of NDIS Media types that we support.
  680. Arguments:
  681. pMediaCount - Place to return the number of media types.
  682. Return Value:
  683. An allocated and filled list of media types. The caller is responsible
  684. for freeing this via RWAN_FREE_MEM.
  685. --*/
  686. {
  687. PNDIS_MEDIUM pMediaArray;
  688. UINT NumMedia;
  689. UINT i;
  690. PLIST_ENTRY pAfInfoEntry;
  691. PRWAN_NDIS_AF_INFO pAfInfo;
  692. pMediaArray = NULL;
  693. do
  694. {
  695. RWAN_ACQUIRE_GLOBAL_LOCK();
  696. //
  697. // An upper bound on the total number of media types supported
  698. // is this:
  699. //
  700. NumMedia = pRWanGlobal->AfInfoCount;
  701. if (NumMedia == 0)
  702. {
  703. break;
  704. }
  705. RWAN_ALLOC_MEM(pMediaArray, NDIS_MEDIUM, NumMedia * sizeof(NDIS_MEDIUM));
  706. if (pMediaArray == NULL)
  707. {
  708. break;
  709. }
  710. NumMedia = 0;
  711. for (pAfInfoEntry = pRWanGlobal->AfInfoList.Flink;
  712. pAfInfoEntry != &(pRWanGlobal->AfInfoList);
  713. pAfInfoEntry = pAfInfoEntry->Flink)
  714. {
  715. NDIS_MEDIUM Medium;
  716. pAfInfo = CONTAINING_RECORD(pAfInfoEntry, RWAN_NDIS_AF_INFO, AfInfoLink);
  717. Medium = pAfInfo->AfChars.Medium;
  718. //
  719. // Check if this medium type is already in the output list.
  720. //
  721. for (i = 0; i < NumMedia; i++)
  722. {
  723. if (pMediaArray[i] == Medium)
  724. {
  725. break;
  726. }
  727. }
  728. if (i == NumMedia)
  729. {
  730. //
  731. // This is the first time we've seen this Medium type.
  732. // Create a new entry.
  733. //
  734. pMediaArray[i] = Medium;
  735. NumMedia++;
  736. }
  737. }
  738. RWAN_RELEASE_GLOBAL_LOCK();
  739. if (NumMedia == 0)
  740. {
  741. RWAN_FREE_MEM(pMediaArray);
  742. pMediaArray = NULL;
  743. }
  744. break;
  745. }
  746. while (FALSE);
  747. *pMediaCount = NumMedia;
  748. return (pMediaArray);
  749. }
  750. VOID
  751. RWanCloseAdapter(
  752. IN PRWAN_NDIS_ADAPTER pAdapter
  753. )
  754. /*++
  755. Routine Description:
  756. Initiate closing an adapter. The caller is assumed to hold
  757. the adapter lock, which will be released here.
  758. Arguments:
  759. pAdapter - Points to adapter to be closed
  760. Return Value:
  761. None
  762. --*/
  763. {
  764. NDIS_HANDLE NdisAdapterHandle;
  765. NDIS_STATUS Status;
  766. NdisAdapterHandle = pAdapter->NdisAdapterHandle;
  767. RWAN_ASSERT(NdisAdapterHandle != NULL);
  768. RWAN_ASSERT(RWAN_IS_LIST_EMPTY(&(pAdapter->AfList)));
  769. pAdapter->State = RWANS_AD_CLOSING;
  770. RWAN_RELEASE_ADAPTER_LOCK(pAdapter);
  771. NdisCloseAdapter(
  772. &Status,
  773. NdisAdapterHandle
  774. );
  775. if (Status != NDIS_STATUS_PENDING)
  776. {
  777. RWanNdisCloseAdapterComplete(
  778. (NDIS_HANDLE)pAdapter,
  779. Status
  780. );
  781. }
  782. }
  783. VOID
  784. RWanNdisRequestComplete(
  785. IN NDIS_HANDLE OurBindingContext,
  786. IN PNDIS_REQUEST pNdisRequest,
  787. IN NDIS_STATUS Status
  788. )
  789. /*++
  790. Routine Description:
  791. This is the NDIS entry point called when a previous pended call
  792. to NdisRequest() has completed. We would have called NdisRequest
  793. on behalf of the media-specific module. Complete it now.
  794. Arguments:
  795. OurBindingContext - Points to our adapter structure
  796. pNdisRequest - Points to completed request
  797. Status - Final status of the request
  798. Return Value:
  799. None
  800. --*/
  801. {
  802. PRWAN_NDIS_ADAPTER pAdapter;
  803. PRWAN_NDIS_REQ_CONTEXT pReqContext;
  804. pAdapter = (PRWAN_NDIS_ADAPTER)OurBindingContext;
  805. RWAN_STRUCT_ASSERT(pAdapter, nad);
  806. pReqContext = (PRWAN_NDIS_REQ_CONTEXT)((PUCHAR)pNdisRequest + sizeof(NDIS_REQUEST));
  807. if (pNdisRequest->RequestType == NdisRequestQueryInformation)
  808. {
  809. (*pReqContext->pAf->pAfInfo->AfChars.pAfSpAdapterRequestComplete)(
  810. Status,
  811. pReqContext->pAf->AfSpAFContext,
  812. pReqContext->AfSpReqContext,
  813. pNdisRequest->RequestType,
  814. pNdisRequest->DATA.QUERY_INFORMATION.Oid,
  815. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
  816. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength
  817. );
  818. }
  819. else
  820. {
  821. (*pReqContext->pAf->pAfInfo->AfChars.pAfSpAdapterRequestComplete)(
  822. Status,
  823. pReqContext->pAf->AfSpAFContext,
  824. pReqContext->AfSpReqContext,
  825. pNdisRequest->RequestType,
  826. pNdisRequest->DATA.SET_INFORMATION.Oid,
  827. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer,
  828. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength
  829. );
  830. }
  831. RWAN_FREE_MEM(pNdisRequest);
  832. return;
  833. }
  834. VOID
  835. RWanNdisStatus(
  836. IN NDIS_HANDLE OurBindingContext,
  837. IN NDIS_STATUS GeneralStatus,
  838. IN PVOID StatusBuffer,
  839. IN UINT StatusBufferSize
  840. )
  841. /*++
  842. Routine Description:
  843. Arguments:
  844. Return Value:
  845. None
  846. --*/
  847. {
  848. //
  849. // Ignore this.
  850. //
  851. return;
  852. }
  853. VOID
  854. RWanNdisCoStatus(
  855. IN NDIS_HANDLE OurBindingContext,
  856. IN NDIS_HANDLE OurVcContext OPTIONAL,
  857. IN NDIS_STATUS GeneralStatus,
  858. IN PVOID StatusBuffer,
  859. IN UINT StatusBufferSize
  860. )
  861. /*++
  862. Routine Description:
  863. Arguments:
  864. Return Value:
  865. None
  866. --*/
  867. {
  868. //
  869. // Ignore this.
  870. //
  871. return;
  872. }
  873. VOID
  874. RWanNdisStatusComplete(
  875. IN NDIS_HANDLE OurBindingContext
  876. )
  877. /*++
  878. Routine Description:
  879. Arguments:
  880. Return Value:
  881. None
  882. --*/
  883. {
  884. //
  885. // Ignore this.
  886. //
  887. return;
  888. }
  889. NDIS_STATUS
  890. RWanNdisCoRequest(
  891. IN NDIS_HANDLE OurAfContext,
  892. IN NDIS_HANDLE OurVcContext OPTIONAL,
  893. IN NDIS_HANDLE OurPartyContext OPTIONAL,
  894. IN OUT PNDIS_REQUEST pNdisRequest
  895. )
  896. /*++
  897. Routine Description:
  898. Handle events from the Call Manager.
  899. Arguments:
  900. OurAfContext - Points to our AF structure
  901. OurVcContext - If not NULL, points to our VC structure
  902. OurPartyContext - If not NULL, points to our Party structure
  903. pNdisRequest - Points to request
  904. Return Value:
  905. NDIS_STATUS_SUCCESS if the OID is one that we know about, else
  906. NDIS_STATUS_NOT_RECOGNIZED.
  907. --*/
  908. {
  909. NDIS_STATUS Status;
  910. PRWAN_NDIS_AF pAf;
  911. Status = NDIS_STATUS_SUCCESS;
  912. if (pNdisRequest->RequestType == NdisRequestSetInformation)
  913. {
  914. switch (pNdisRequest->DATA.SET_INFORMATION.Oid)
  915. {
  916. case OID_CO_ADDRESS_CHANGE:
  917. break;
  918. case OID_CO_AF_CLOSE:
  919. //
  920. // The Call manager wants us to shutdown this AF open.
  921. //
  922. pAf = (PRWAN_NDIS_AF)OurAfContext;
  923. RWAN_STRUCT_ASSERT(pAf, naf);
  924. RWanShutdownAf(pAf);
  925. break;
  926. default:
  927. Status = NDIS_STATUS_NOT_RECOGNIZED;
  928. break;
  929. }
  930. }
  931. return (Status);
  932. }
  933. VOID
  934. RWanNdisCoRequestComplete(
  935. IN NDIS_STATUS Status,
  936. IN NDIS_HANDLE OurAfContext,
  937. IN NDIS_HANDLE OurVcContext OPTIONAL,
  938. IN NDIS_HANDLE OurPartyContext OPTIONAL,
  939. IN PNDIS_REQUEST pNdisRequest
  940. )
  941. /*++
  942. Routine Description:
  943. Handle completion of a CO-request we had sent to the Call Manager on
  944. behalf of a media-specific module. Inform the media-specific module
  945. of this completion.
  946. Arguments:
  947. Status - Status of request.
  948. OurAfContext - Points to our AF structure
  949. OurVcContext - If not NULL, points to our VC structure
  950. OurPartyContext - If not NULL, points to our Party structure
  951. pNdisRequest - Points to request
  952. Return Value:
  953. None
  954. --*/
  955. {
  956. PRWAN_NDIS_AF pAf;
  957. PRWAN_NDIS_REQ_CONTEXT pReqContext;
  958. pAf = (PRWAN_NDIS_AF)OurAfContext;
  959. RWAN_STRUCT_ASSERT(pAf, naf);
  960. pReqContext = (PRWAN_NDIS_REQ_CONTEXT)((PUCHAR)pNdisRequest + sizeof(NDIS_REQUEST));
  961. if (pNdisRequest->RequestType == NdisRequestQueryInformation)
  962. {
  963. (*pReqContext->pAf->pAfInfo->AfChars.pAfSpAfRequestComplete)(
  964. Status,
  965. pReqContext->pAf->AfSpAFContext,
  966. pReqContext->AfSpReqContext,
  967. pNdisRequest->RequestType,
  968. pNdisRequest->DATA.QUERY_INFORMATION.Oid,
  969. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
  970. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength
  971. );
  972. }
  973. else
  974. {
  975. (*pReqContext->pAf->pAfInfo->AfChars.pAfSpAfRequestComplete)(
  976. Status,
  977. pReqContext->pAf->AfSpAFContext,
  978. pReqContext->AfSpReqContext,
  979. pNdisRequest->RequestType,
  980. pNdisRequest->DATA.SET_INFORMATION.Oid,
  981. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer,
  982. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength
  983. );
  984. }
  985. RWAN_FREE_MEM(pNdisRequest);
  986. return;
  987. }
  988. NDIS_STATUS
  989. RWanNdisReset(
  990. IN NDIS_HANDLE OurBindingContext
  991. )
  992. /*++
  993. Routine Description:
  994. Arguments:
  995. Return Value:
  996. None
  997. --*/
  998. {
  999. //
  1000. // Ignore this.
  1001. //
  1002. return (NDIS_STATUS_SUCCESS);
  1003. }
  1004. VOID
  1005. RWanNdisResetComplete(
  1006. IN NDIS_HANDLE OurBindingContext,
  1007. IN NDIS_STATUS Status
  1008. )
  1009. /*++
  1010. Routine Description:
  1011. Arguments:
  1012. Return Value:
  1013. None
  1014. --*/
  1015. {
  1016. //
  1017. // Ignore this.
  1018. //
  1019. return;
  1020. }
  1021. NDIS_STATUS
  1022. RWanNdisPnPEvent(
  1023. IN NDIS_HANDLE ProtocolBindingContext,
  1024. IN PNET_PNP_EVENT pNetPnPEvent
  1025. )
  1026. /*++
  1027. Routine Description:
  1028. Handle a PnP Event from NDIS. The event structure contains the event
  1029. code, includes power-management events and reconfigure events.
  1030. Arguments:
  1031. ProtocolBindingContext - Pointer to our Adapter structure. Could be
  1032. NULL for notification of global config changes
  1033. pNetPnPEvent - Points to event structure
  1034. Return Value:
  1035. NDIS_STATUS_SUCCESS if we processed the event successfully.
  1036. NDIS_STATUS_NOT_SUPPORTED for unsupported notifications.
  1037. --*/
  1038. {
  1039. NDIS_STATUS Status;
  1040. PRWAN_NDIS_ADAPTER pAdapter;
  1041. pAdapter = (PRWAN_NDIS_ADAPTER)ProtocolBindingContext;
  1042. switch (pNetPnPEvent->NetEvent)
  1043. {
  1044. case NetEventSetPower:
  1045. Status = RWanNdisPnPSetPower(pAdapter, pNetPnPEvent);
  1046. break;
  1047. case NetEventQueryPower:
  1048. Status = RWanNdisPnPQueryPower(pAdapter, pNetPnPEvent);
  1049. break;
  1050. case NetEventQueryRemoveDevice:
  1051. Status = RWanNdisPnPQueryRemove(pAdapter, pNetPnPEvent);
  1052. break;
  1053. case NetEventCancelRemoveDevice:
  1054. Status = RWanNdisPnPCancelRemove(pAdapter, pNetPnPEvent);
  1055. break;
  1056. case NetEventReconfigure:
  1057. Status = NDIS_STATUS_NOT_SUPPORTED;
  1058. break;
  1059. case NetEventBindList:
  1060. Status = NDIS_STATUS_NOT_SUPPORTED;
  1061. break;
  1062. default:
  1063. Status = NDIS_STATUS_NOT_SUPPORTED;
  1064. break;
  1065. }
  1066. return (Status);
  1067. }
  1068. NDIS_STATUS
  1069. RWanNdisPnPSetPower(
  1070. IN PRWAN_NDIS_ADAPTER pAdapter,
  1071. IN PNET_PNP_EVENT pNetPnPEvent
  1072. )
  1073. /*++
  1074. Routine Description:
  1075. Handle a Set Power event.
  1076. Arguments:
  1077. pAdapter - Points to our adapter structure
  1078. pNetPnPEvent - Points to event to be processed.
  1079. Return Value:
  1080. NDIS_STATUS_SUCCESS if we successfully processed this event,
  1081. NDIS_STATUS_XXX error code otherwise.
  1082. --*/
  1083. {
  1084. PNET_DEVICE_POWER_STATE pPowerState;
  1085. NDIS_STATUS Status;
  1086. pPowerState = (PNET_DEVICE_POWER_STATE)pNetPnPEvent->Buffer;
  1087. switch (*pPowerState)
  1088. {
  1089. case NetDeviceStateD0:
  1090. Status = NDIS_STATUS_SUCCESS;
  1091. break;
  1092. default:
  1093. //
  1094. // We can't suspend, so we ask NDIS to unbind us
  1095. // by returning this status:
  1096. //
  1097. Status = NDIS_STATUS_NOT_SUPPORTED;
  1098. break;
  1099. }
  1100. return (Status);
  1101. }
  1102. NDIS_STATUS
  1103. RWanNdisPnPQueryPower(
  1104. IN PRWAN_NDIS_ADAPTER pAdapter,
  1105. IN PNET_PNP_EVENT pNetPnPEvent
  1106. )
  1107. /*++
  1108. Routine Description:
  1109. Called to see if we allow power to be shut off to the adapter.
  1110. Arguments:
  1111. pAdapter - Points to our adapter structure
  1112. pNetPnPEvent - Points to event to be processed.
  1113. Return Value:
  1114. NDIS_STATUS_SUCCESS always.
  1115. --*/
  1116. {
  1117. return (NDIS_STATUS_SUCCESS);
  1118. }
  1119. NDIS_STATUS
  1120. RWanNdisPnPQueryRemove(
  1121. IN PRWAN_NDIS_ADAPTER pAdapter,
  1122. IN PNET_PNP_EVENT pNetPnPEvent
  1123. )
  1124. /*++
  1125. Routine Description:
  1126. Called to see if we allow the adapter to be removed.
  1127. Arguments:
  1128. pAdapter - Points to our adapter structure
  1129. pNetPnPEvent - Points to event to be processed.
  1130. Return Value:
  1131. NDIS_STATUS_SUCCESS always.
  1132. --*/
  1133. {
  1134. return (NDIS_STATUS_SUCCESS);
  1135. }
  1136. NDIS_STATUS
  1137. RWanNdisPnPCancelRemove(
  1138. IN PRWAN_NDIS_ADAPTER pAdapter,
  1139. IN PNET_PNP_EVENT pNetPnPEvent
  1140. )
  1141. /*++
  1142. Routine Description:
  1143. Called to cancel the above remove.
  1144. Arguments:
  1145. pAdapter - Points to our adapter structure
  1146. pNetPnPEvent - Points to event to be processed.
  1147. Return Value:
  1148. NDIS_STATUS_SUCCESS always.
  1149. --*/
  1150. {
  1151. return (NDIS_STATUS_SUCCESS);
  1152. }