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.

937 lines
20 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. D:\nt\private\ntos\tdi\rawwan\core\addr.c
  5. Abstract:
  6. TDI Entry points and support routines for Address Objects.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. arvindm 04-29-97 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. #define _FILENUMBER 'RDDA'
  15. //
  16. // Context we use to keep track of NDIS SAP registration
  17. //
  18. typedef struct _RWAN_REGISTER_SAP_CONTEXT
  19. {
  20. PRWAN_NDIS_SAP pRWanNdisSap;
  21. CO_SAP CoSap;
  22. } RWAN_REGISTER_SAP_CONTEXT, *PRWAN_REGISTER_SAP_CONTEXT;
  23. TDI_STATUS
  24. RWanTdiOpenAddress(
  25. IN PTDI_REQUEST pTdiRequest,
  26. IN TRANSPORT_ADDRESS UNALIGNED *pAddrList,
  27. IN ULONG AddrListLength,
  28. IN UINT Protocol,
  29. IN PUCHAR pOptions
  30. )
  31. /*++
  32. Routine Description:
  33. This is the TDI entry point for opening (creating) an Address Object.
  34. Arguments:
  35. pTdiRequest - Pointer to the TDI Request
  36. pAddrList - List of alternative addresses, one of which we're to open.
  37. AddrListLength - Length of the above
  38. Protocol - Identifies the TDI Protocol being opened.
  39. pOptions - Unused.
  40. Return Value:
  41. TDI_STATUS -- TDI_SUCCESS if a new Address Object was successfully
  42. created, TDI_BAD_ADDR if the given address isn't valid,
  43. TDI_ADDR_IN_USE if it is a duplicate.
  44. --*/
  45. {
  46. PRWAN_TDI_PROTOCOL pProtocol;
  47. PRWAN_TDI_ADDRESS pAddrObject;
  48. TA_ADDRESS * pTransportAddress;
  49. TDI_STATUS Status;
  50. INT rc;
  51. UNREFERENCED_PARAMETER(pOptions);
  52. //
  53. // Initialize.
  54. //
  55. pAddrObject = NULL_PRWAN_TDI_ADDRESS;
  56. Status = TDI_SUCCESS;
  57. do
  58. {
  59. //
  60. // Get our protocol structure for the protocol being opened.
  61. //
  62. pProtocol = RWanGetProtocolFromNumber(Protocol);
  63. if (pProtocol == NULL_PRWAN_TDI_PROTOCOL)
  64. {
  65. RWANDEBUGP(DL_WARN, DC_ADDRESS,
  66. ("RWanTdiOpenAddress: unknown protocol number %d\n", Protocol));
  67. Status = TDI_BAD_ADDR;
  68. break;
  69. }
  70. //
  71. // Does this protocol allow creation of address objects?
  72. //
  73. if (!pProtocol->bAllowAddressObjects)
  74. {
  75. RWANDEBUGP(DL_WARN, DC_ADDRESS,
  76. ("RWanTdiOpenAddress: Protocol %d/x%x doesn't allow addr objs\n",
  77. Protocol, pProtocol));
  78. Status = TDI_BAD_ADDR;
  79. break;
  80. }
  81. //
  82. // Go through the given Address list and find the first one
  83. // that matches the protocol.
  84. //
  85. pTransportAddress = (*pProtocol->pAfInfo->AfChars.pAfSpGetValidTdiAddress)(
  86. pProtocol->pAfInfo->AfSpContext,
  87. pAddrList,
  88. AddrListLength
  89. );
  90. if (pTransportAddress == NULL)
  91. {
  92. RWANDEBUGP(DL_WARN, DC_ADDRESS,
  93. ("RWanTdiOpenAddress: No valid addr for Protocol x%x in list x%x\n",
  94. pProtocol, pAddrList));
  95. Status = TDI_BAD_ADDR;
  96. break;
  97. }
  98. RWANDEBUGP(DL_VERY_LOUD, DC_ADDRESS,
  99. ("RWanTdiOpenAddress: pProto x%x, addr x%x, type %d, length %d\n",
  100. pProtocol,
  101. pTransportAddress,
  102. pTransportAddress->AddressType,
  103. pTransportAddress->AddressLength));
  104. //
  105. // Allocate an Address Object.
  106. //
  107. pAddrObject = RWanAllocateAddressObject(pTransportAddress);
  108. if (pAddrObject == NULL_PRWAN_TDI_ADDRESS)
  109. {
  110. RWANDEBUGP(DL_WARN, DC_ADDRESS,
  111. ("RWanTdiOpenAddress: couldnt allocate addr obj: %d bytes\n",
  112. sizeof(RWAN_TDI_ADDRESS)+pTransportAddress->AddressLength));
  113. Status = TDI_NO_RESOURCES;
  114. break;
  115. }
  116. pAddrObject->pProtocol = pProtocol;
  117. //
  118. // Get a context for this address object from the media-specific
  119. // module.
  120. //
  121. if (pAddrObject->pProtocol->pAfInfo->AfChars.pAfSpOpenAddress)
  122. {
  123. RWAN_STATUS RWanStatus;
  124. RWanStatus = (*pAddrObject->pProtocol->pAfInfo->AfChars.pAfSpOpenAddress)(
  125. pAddrObject->pProtocol->pAfInfo->AfSpContext,
  126. (RWAN_HANDLE)pAddrObject,
  127. &(pAddrObject->AfSpAddrContext));
  128. if (RWanStatus != RWAN_STATUS_SUCCESS)
  129. {
  130. Status = RWanToTdiStatus(RWanStatus);
  131. break;
  132. }
  133. RWAN_SET_BIT(pAddrObject->Flags, RWANF_AO_AFSP_CONTEXT_VALID);
  134. }
  135. RWAN_ACQUIRE_ADDRESS_LIST_LOCK();
  136. //
  137. // If this is a non-NULL address, register NDIS SAPs on all
  138. // AF bindings for this protocol.
  139. //
  140. if (!((*pProtocol->pAfInfo->AfChars.pAfSpIsNullAddress)(
  141. pProtocol->pAfInfo->AfSpContext,
  142. pTransportAddress)))
  143. {
  144. //
  145. // Add a temp ref so that the address object doesn't go away.
  146. //
  147. RWanReferenceAddressObject(pAddrObject); // TdiOpenAddress temp ref
  148. Status = RWanCreateNdisSaps(pAddrObject, pProtocol);
  149. if (Status != TDI_SUCCESS)
  150. {
  151. if (RWAN_IS_BIT_SET(pAddrObject->Flags, RWANF_AO_AFSP_CONTEXT_VALID))
  152. {
  153. (*pAddrObject->pProtocol->pAfInfo->AfChars.pAfSpCloseAddress)(
  154. pAddrObject->AfSpAddrContext);
  155. RWAN_RESET_BIT(pAddrObject->Flags, RWANF_AO_AFSP_CONTEXT_VALID);
  156. }
  157. }
  158. //
  159. // Get rid of the temp reference.
  160. //
  161. RWAN_ACQUIRE_ADDRESS_LOCK(pAddrObject);
  162. rc = RWanDereferenceAddressObject(pAddrObject); // TdiOpenAddr temp ref
  163. if (rc != 0)
  164. {
  165. RWAN_RELEASE_ADDRESS_LOCK(pAddrObject);
  166. }
  167. else
  168. {
  169. //
  170. // The address object is gone. Meaning no SAPs got registered.
  171. //
  172. pAddrObject = NULL;
  173. //
  174. // Fix up the status only if we haven't got one already.
  175. //
  176. if (Status == TDI_SUCCESS)
  177. {
  178. Status = TDI_BAD_ADDR;
  179. }
  180. }
  181. if (Status != TDI_SUCCESS)
  182. {
  183. RWAN_RELEASE_ADDRESS_LIST_LOCK();
  184. break;
  185. }
  186. }
  187. RWAN_ASSERT(pAddrObject != NULL);
  188. RWanReferenceAddressObject(pAddrObject); // TdiOpenAddress ref
  189. //
  190. // Link this to the list of address objects on this protocol.
  191. //
  192. RWAN_INSERT_HEAD_LIST(&(pProtocol->AddrObjList),
  193. &(pAddrObject->AddrLink));
  194. RWAN_RELEASE_ADDRESS_LIST_LOCK();
  195. //
  196. // Fix up all return values.
  197. //
  198. pTdiRequest->Handle.AddressHandle = (PVOID)pAddrObject;
  199. break;
  200. }
  201. while (FALSE);
  202. if (Status != TDI_SUCCESS)
  203. {
  204. //
  205. // Clean up.
  206. //
  207. if (pAddrObject != NULL_PRWAN_TDI_ADDRESS)
  208. {
  209. RWAN_FREE_MEM(pAddrObject);
  210. }
  211. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  212. ("OpenAddr: failure status %x\n", Status));
  213. }
  214. return (Status);
  215. }
  216. TDI_STATUS
  217. RWanTdiSetEvent(
  218. IN PVOID AddrObjContext,
  219. IN INT TdiEventType,
  220. IN PVOID Handler,
  221. IN PVOID HandlerContext
  222. )
  223. /*++
  224. Routine Description:
  225. Set an event handler (up-call) for an address object.
  226. Arguments:
  227. AddrObjContext - Our context for an Address Object (pointer to it).
  228. TdiEventType - The TDI Event for which we are given an up-call handler.
  229. Handler - The handler function
  230. HandlerContext - Context to be passed to the handler function.
  231. Return Value:
  232. TDI_STATUS - TDI_SUCCESS if the event type is a supported one, else
  233. TDI_BAD_EVENT_TYPE
  234. --*/
  235. {
  236. PRWAN_TDI_ADDRESS pAddrObject;
  237. TDI_STATUS Status;
  238. pAddrObject = (PRWAN_TDI_ADDRESS)AddrObjContext;
  239. RWAN_STRUCT_ASSERT(pAddrObject, nta);
  240. Status = TDI_SUCCESS;
  241. RWAN_ACQUIRE_ADDRESS_LOCK(pAddrObject);
  242. switch (TdiEventType)
  243. {
  244. case TDI_EVENT_CONNECT:
  245. RWANDEBUGP(DL_VERY_LOUD, DC_ADDRESS,
  246. ("SetEvent[CONN IND]: pAddrObject x%x, Handler x%x, Ctxt x%x\n",
  247. pAddrObject, Handler, HandlerContext));
  248. pAddrObject->pConnInd = Handler;
  249. pAddrObject->ConnIndContext = HandlerContext;
  250. break;
  251. case TDI_EVENT_DISCONNECT:
  252. RWANDEBUGP(DL_VERY_LOUD, DC_ADDRESS,
  253. ("SetEvent[DISC IND]: pAddrObject x%x, Handler x%x, Ctxt x%x\n",
  254. pAddrObject, Handler, HandlerContext));
  255. pAddrObject->pDisconInd = Handler;
  256. pAddrObject->DisconIndContext = HandlerContext;
  257. break;
  258. case TDI_EVENT_ERROR:
  259. RWANDEBUGP(DL_VERY_LOUD, DC_ADDRESS,
  260. ("SetEvent[ERRORIND]: pAddrObject x%x, Handler x%x, Ctxt x%x\n",
  261. pAddrObject, Handler, HandlerContext));
  262. pAddrObject->pErrorInd = Handler;
  263. pAddrObject->ErrorIndContext = HandlerContext;
  264. break;
  265. case TDI_EVENT_RECEIVE:
  266. RWANDEBUGP(DL_VERY_LOUD, DC_ADDRESS,
  267. ("SetEvent[RECV IND]: pAddrObject x%x, Handler x%x, Ctxt x%x\n",
  268. pAddrObject, Handler, HandlerContext));
  269. pAddrObject->pRcvInd = Handler;
  270. pAddrObject->RcvIndContext = HandlerContext;
  271. break;
  272. default:
  273. Status = TDI_BAD_EVENT_TYPE;
  274. break;
  275. }
  276. RWAN_RELEASE_ADDRESS_LOCK(pAddrObject);
  277. return (Status);
  278. }
  279. TDI_STATUS
  280. RWanTdiCloseAddress(
  281. IN PTDI_REQUEST pTdiRequest
  282. )
  283. /*++
  284. Routine Description:
  285. This is the TDI entry point for closing (deleting) an Address Object.
  286. Arguments:
  287. pTdiRequest - Pointer to the TDI Request
  288. Return Value:
  289. TDI_STATUS -- TDI_SUCCESS if we successfully deleted the address
  290. object immediately, TDI_PENDING if we have to complete some operations
  291. (e.g. deregister NDIS SAP) before we can complete this.
  292. --*/
  293. {
  294. TDI_STATUS Status;
  295. PRWAN_TDI_ADDRESS pAddrObject;
  296. PRWAN_TDI_PROTOCOL pProtocol;
  297. INT rc;
  298. #if DBG
  299. RWAN_IRQL EntryIrq, ExitIrq;
  300. #endif // DBG
  301. RWAN_GET_ENTRY_IRQL(EntryIrq);
  302. pAddrObject = (PRWAN_TDI_ADDRESS)pTdiRequest->Handle.AddressHandle;
  303. RWAN_STRUCT_ASSERT(pAddrObject, nta);
  304. pProtocol = pAddrObject->pProtocol;
  305. RWANDEBUGP(DL_EXTRA_LOUD, DC_BIND,
  306. ("TdiCloseAddr: pAddrObj x%x, RefCnt %d\n",
  307. pAddrObject, pAddrObject->RefCount));
  308. //
  309. // Delete this from the list of address objects on this protocol.
  310. //
  311. RWAN_ACQUIRE_ADDRESS_LIST_LOCK();
  312. RWAN_DELETE_FROM_LIST(&(pAddrObject->AddrLink));
  313. RWAN_RELEASE_ADDRESS_LIST_LOCK();
  314. //
  315. // Tell the media-specific module that this address object is closing.
  316. //
  317. if (RWAN_IS_BIT_SET(pAddrObject->Flags, RWANF_AO_AFSP_CONTEXT_VALID))
  318. {
  319. (*pAddrObject->pProtocol->pAfInfo->AfChars.pAfSpCloseAddress)(
  320. pAddrObject->AfSpAddrContext);
  321. RWAN_RESET_BIT(pAddrObject->Flags, RWANF_AO_AFSP_CONTEXT_VALID);
  322. }
  323. RWAN_ACQUIRE_ADDRESS_LOCK(pAddrObject);
  324. #if DBG
  325. if (!RWAN_IS_LIST_EMPTY(&pAddrObject->SapList) ||
  326. !RWAN_IS_LIST_EMPTY(&pAddrObject->IdleConnList) ||
  327. !RWAN_IS_LIST_EMPTY(&pAddrObject->ListenConnList) ||
  328. !RWAN_IS_LIST_EMPTY(&pAddrObject->ActiveConnList)
  329. )
  330. {
  331. RWAN_ASSERT(pAddrObject->RefCount > 1);
  332. }
  333. #endif // DBG
  334. rc = RWanDereferenceAddressObject(pAddrObject); // CloseAddress deref
  335. if (rc == 0)
  336. {
  337. Status = TDI_SUCCESS;
  338. }
  339. else
  340. {
  341. //
  342. // Mark this address object as closing, so that we
  343. // complete this operation when the reference count
  344. // falls to 0.
  345. //
  346. RWAN_SET_BIT(pAddrObject->Flags, RWANF_AO_CLOSING);
  347. RWANDEBUGP(DL_LOUD, DC_BIND,
  348. ("TdiCloseAddr: will pend, pAddrObj x%x, RefCnt %d, DelNotify x%x\n",
  349. pAddrObject, pAddrObject->RefCount, pTdiRequest->RequestNotifyObject));
  350. RWAN_SET_DELETE_NOTIFY(&pAddrObject->DeleteNotify,
  351. pTdiRequest->RequestNotifyObject,
  352. pTdiRequest->RequestContext);
  353. //
  354. // Deregister all NDIS SAPs attached to this Address Object.
  355. //
  356. RWanDeleteNdisSaps(pAddrObject);
  357. Status = TDI_PENDING;
  358. }
  359. RWAN_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  360. return (Status);
  361. }
  362. TDI_STATUS
  363. RWanCreateNdisSaps(
  364. IN PRWAN_TDI_ADDRESS pAddrObject,
  365. IN PRWAN_TDI_PROTOCOL pProtocol
  366. )
  367. /*++
  368. Routine Description:
  369. Create NDIS SAPs on behalf of the given TDI Address Object.
  370. We create NDIS SAPs on all AF opens that match the specified
  371. TDI protocol.
  372. Arguments:
  373. pAddrObject - Pointer to our TDI Address Object
  374. pProtocol - Pointer to TDI protocol to which the addr object belongs
  375. Return Value:
  376. TDI_STATUS -- this is TDI_SUCCESS if we started SAP registration
  377. on atleast one NDIS AF open, TDI_NOT_ASSOCIATED otherwise.
  378. --*/
  379. {
  380. TDI_STATUS Status;
  381. PCO_SAP pCoSap;
  382. PRWAN_NDIS_SAP pSap;
  383. PLIST_ENTRY pSapEntry;
  384. PLIST_ENTRY pNextSapEntry;
  385. PRWAN_NDIS_ADAPTER pAdapter;
  386. PLIST_ENTRY pAdEntry;
  387. PRWAN_NDIS_AF pAf;
  388. PLIST_ENTRY pAfEntry;
  389. PRWAN_NDIS_AF_INFO pAfInfo;
  390. pAfInfo = pProtocol->pAfInfo;
  391. RWANDEBUGP(DL_VERY_LOUD, DC_BIND,
  392. ("CreateNdisSaps: pAddrObject x%x, pProtocol x%x, pAfInfo x%x\n",
  393. pAddrObject, pProtocol, pAfInfo));
  394. RWAN_ASSERT(RWAN_IS_LIST_EMPTY(&pAddrObject->SapList));
  395. RWAN_ACQUIRE_GLOBAL_LOCK();
  396. //
  397. // Prepare NDIS SAP structures for each NDIS AF open that matches
  398. // this protocol.
  399. //
  400. for (pAdEntry = pRWanGlobal->AdapterList.Flink;
  401. pAdEntry != &(pRWanGlobal->AdapterList);
  402. pAdEntry = pAdEntry->Flink)
  403. {
  404. pAdapter = CONTAINING_RECORD(pAdEntry, RWAN_NDIS_ADAPTER, AdapterLink);
  405. RWANDEBUGP(DL_EXTRA_LOUD, DC_BIND,
  406. ("CreateNdisSaps: looking at adapter x%x\n", pAdapter));
  407. for (pAfEntry = pAdapter->AfList.Flink;
  408. pAfEntry != &(pAdapter->AfList);
  409. pAfEntry = pAfEntry->Flink)
  410. {
  411. pAf = CONTAINING_RECORD(pAfEntry, RWAN_NDIS_AF, AfLink);
  412. RWANDEBUGP(DL_EXTRA_LOUD, DC_BIND,
  413. ("CreateNdisSaps: looking at AF x%x, AfInfo x%x\n",
  414. pAf, pAf->pAfInfo));
  415. if (pAf->pAfInfo == pAfInfo)
  416. {
  417. //
  418. // This NDIS AF open matches the TDI protocol for which
  419. // the address object is opened. We will create an NDIS
  420. // SAP here.
  421. //
  422. ULONG SapSize;
  423. //
  424. // Allocate a new SAP structure.
  425. //
  426. SapSize = sizeof(RWAN_NDIS_SAP);
  427. RWAN_ALLOC_MEM(pSap, RWAN_NDIS_SAP, SapSize);
  428. if (pSap == NULL_PRWAN_NDIS_SAP)
  429. {
  430. RWANDEBUGP(DL_WARN, DC_ADDRESS,
  431. ("RWanCreateNdisSaps: failed to alloc SAP %d bytes\n",
  432. SapSize));
  433. continue;
  434. }
  435. //
  436. // Fill it in.
  437. //
  438. RWAN_SET_SIGNATURE(pSap, nsp);
  439. pSap->pAddrObject = pAddrObject;
  440. pSap->NdisSapHandle = NULL;
  441. pSap->pNdisAf = pAf;
  442. pSap->pCoSap = NULL;
  443. //
  444. // Link to all SAPs associated with address object.
  445. //
  446. RWAN_INSERT_TAIL_LIST(&(pAddrObject->SapList),
  447. &(pSap->AddrObjLink));
  448. RWanReferenceAddressObject(pAddrObject); // NDIS SAP ref
  449. }
  450. }
  451. }
  452. RWAN_RELEASE_GLOBAL_LOCK();
  453. //
  454. // Now go through the SAP list and call NDIS to register them.
  455. //
  456. for (pSapEntry = pAddrObject->SapList.Flink;
  457. pSapEntry != &(pAddrObject->SapList);
  458. pSapEntry = pNextSapEntry)
  459. {
  460. RWAN_STATUS RWanStatus;
  461. NDIS_STATUS NdisStatus;
  462. pSap = CONTAINING_RECORD(pSapEntry, RWAN_NDIS_SAP, AddrObjLink);
  463. pNextSapEntry = pSap->AddrObjLink.Flink;
  464. //
  465. // Convert the transport address to NDIS SAP format.
  466. //
  467. RWanStatus = (*pAfInfo->AfChars.pAfSpTdi2NdisSap)(
  468. pAfInfo->AfSpContext,
  469. pAddrObject->AddressType,
  470. pAddrObject->AddressLength,
  471. pAddrObject->pAddress,
  472. &(pSap->pCoSap));
  473. if (RWanStatus == RWAN_STATUS_SUCCESS)
  474. {
  475. RWAN_ASSERT(pSap->pCoSap != NULL);
  476. //
  477. // Register this SAP with the Call Manager.
  478. //
  479. NdisStatus = NdisClRegisterSap(
  480. pSap->pNdisAf->NdisAfHandle,
  481. (NDIS_HANDLE)pSap,
  482. pSap->pCoSap,
  483. &(pSap->NdisSapHandle)
  484. );
  485. }
  486. else
  487. {
  488. NdisStatus = NDIS_STATUS_FAILURE;
  489. }
  490. if (NdisStatus != NDIS_STATUS_PENDING)
  491. {
  492. RWanNdisRegisterSapComplete(
  493. NdisStatus,
  494. (NDIS_HANDLE)pSap,
  495. pSap->pCoSap,
  496. pSap->NdisSapHandle
  497. );
  498. }
  499. }
  500. if (!RWAN_IS_LIST_EMPTY(&pAddrObject->SapList))
  501. {
  502. Status = TDI_SUCCESS;
  503. }
  504. else
  505. {
  506. Status = RWanNdisToTdiStatus(pAddrObject->SapStatus);
  507. RWANDEBUGP(DL_WARN, DC_WILDCARD,
  508. ("CreateNdisSaps: NdisStatus %x, TdiStatus %x\n",
  509. pAddrObject->SapStatus, Status));
  510. }
  511. return (Status);
  512. }
  513. VOID
  514. RWanNdisRegisterSapComplete(
  515. IN NDIS_STATUS NdisStatus,
  516. IN NDIS_HANDLE OurSapContext,
  517. IN PCO_SAP pCoSap,
  518. IN NDIS_HANDLE NdisSapHandle
  519. )
  520. /*++
  521. Routine Description:
  522. This is called by NDIS to signal completion of a previously
  523. pended call to NdisClRegisterSap.
  524. Arguments:
  525. NdisStatus - Final status of SAP registration.
  526. OurSapContext - Points to our NDIS SAP structure.
  527. pCoSap - The parameter we passed to NdisClRegisterSap. Not used.
  528. NdisSapHandle - If NdisStatus indicates success, this contains the
  529. assigned handle for this SAP.
  530. Return Value:
  531. None
  532. --*/
  533. {
  534. PRWAN_NDIS_SAP pSap;
  535. PRWAN_TDI_ADDRESS pAddrObject;
  536. INT rc;
  537. PRWAN_NDIS_AF_INFO pAfInfo;
  538. PRWAN_NDIS_AF pAf;
  539. UNREFERENCED_PARAMETER(pCoSap);
  540. pSap = (PRWAN_NDIS_SAP)OurSapContext;
  541. RWAN_STRUCT_ASSERT(pSap, nsp);
  542. pAddrObject = pSap->pAddrObject;
  543. pAfInfo = pSap->pNdisAf->pAfInfo;
  544. pCoSap = pSap->pCoSap;
  545. pSap->pCoSap = NULL;
  546. RWANDEBUGP(DL_LOUD, DC_BIND,
  547. ("RegisterSapComplete: pAddrObj x%x, pSap x%x, Status x%x\n",
  548. pAddrObject, pSap, NdisStatus));
  549. if (NdisStatus == NDIS_STATUS_SUCCESS)
  550. {
  551. pSap->NdisSapHandle = NdisSapHandle;
  552. pAf = pSap->pNdisAf;
  553. //
  554. // Link this SAP to the list of all SAPs on the AF.
  555. //
  556. RWAN_ACQUIRE_AF_LOCK(pAf);
  557. RWAN_INSERT_TAIL_LIST(&pAf->NdisSapList,
  558. &pSap->AfLink);
  559. RWanReferenceAf(pAf); // New SAP registered.
  560. RWAN_RELEASE_AF_LOCK(pAf);
  561. }
  562. else
  563. {
  564. //
  565. // Failed to register this SAP. Clean up.
  566. //
  567. RWAN_ACQUIRE_ADDRESS_LOCK(pAddrObject);
  568. pAddrObject->SapStatus = NdisStatus;
  569. RWAN_DELETE_FROM_LIST(&(pSap->AddrObjLink));
  570. rc = RWanDereferenceAddressObject(pAddrObject); // Reg SAP failed
  571. if (rc != 0)
  572. {
  573. RWAN_RELEASE_ADDRESS_LOCK(pAddrObject);
  574. }
  575. RWAN_FREE_MEM(pSap);
  576. }
  577. //
  578. // If the AF-specific module had given us a SAP structure,
  579. // return it now.
  580. //
  581. if (pCoSap != NULL)
  582. {
  583. (*pAfInfo->AfChars.pAfSpReturnNdisSap)(
  584. pAfInfo->AfSpContext,
  585. pCoSap
  586. );
  587. }
  588. return;
  589. }
  590. VOID
  591. RWanDeleteNdisSaps(
  592. IN PRWAN_TDI_ADDRESS pAddrObject
  593. )
  594. /*++
  595. Routine Description:
  596. Delete all NDIS SAPs on the given address object. We call NDIS
  597. to deregister them.
  598. Arguments:
  599. pAddrObject - Pointer to TDI Address Object
  600. Return Value:
  601. None
  602. --*/
  603. {
  604. PRWAN_NDIS_SAP pSap;
  605. PLIST_ENTRY pSapEntry;
  606. PLIST_ENTRY pFirstSapEntry;
  607. PLIST_ENTRY pNextSapEntry;
  608. NDIS_STATUS NdisStatus;
  609. NDIS_HANDLE NdisSapHandle;
  610. //
  611. // Mark all SAPs as closing, while we hold a lock to the address object.
  612. //
  613. for (pSapEntry = pAddrObject->SapList.Flink;
  614. pSapEntry != &(pAddrObject->SapList);
  615. pSapEntry = pNextSapEntry)
  616. {
  617. pSap = CONTAINING_RECORD(pSapEntry, RWAN_NDIS_SAP, AddrObjLink);
  618. pNextSapEntry = pSap->AddrObjLink.Flink;
  619. RWAN_SET_BIT(pSap->Flags, RWANF_SAP_CLOSING);
  620. }
  621. //
  622. // Unlink the SAP list from the Address Object.
  623. // This will protect us if at all we re-enter this routine.
  624. //
  625. pFirstSapEntry = pAddrObject->SapList.Flink;
  626. RWAN_INIT_LIST(&pAddrObject->SapList);
  627. RWAN_RELEASE_ADDRESS_LOCK(pAddrObject);
  628. for (pSapEntry = pFirstSapEntry;
  629. pSapEntry != &(pAddrObject->SapList);
  630. pSapEntry = pNextSapEntry)
  631. {
  632. pSap = CONTAINING_RECORD(pSapEntry, RWAN_NDIS_SAP, AddrObjLink);
  633. pNextSapEntry = pSap->AddrObjLink.Flink;
  634. NdisSapHandle = pSap->NdisSapHandle;
  635. RWAN_ASSERT(NdisSapHandle != NULL);
  636. RWANDEBUGP(DL_LOUD, DC_BIND,
  637. ("RWanDeleteNdisSaps: pAddrObj x%x, pSap x%x, pAf x%x\n",
  638. pAddrObject, pSap, pSap->pNdisAf));
  639. NdisStatus = NdisClDeregisterSap(NdisSapHandle);
  640. if (NdisStatus != NDIS_STATUS_PENDING)
  641. {
  642. RWanNdisDeregisterSapComplete(
  643. NdisStatus,
  644. (NDIS_HANDLE)pSap
  645. );
  646. }
  647. }
  648. }
  649. VOID
  650. RWanNdisDeregisterSapComplete(
  651. IN NDIS_STATUS NdisStatus,
  652. IN NDIS_HANDLE ProtocolSapContext
  653. )
  654. /*++
  655. Routine Description:
  656. This is called by NDIS to signal completion of a previously
  657. pended call to NdisClDeregisterSap.
  658. We unlink the SAP from the two lists it is linked to: the
  659. Address Object's SAP list and the AF's SAP list.
  660. Arguments:
  661. NdisStatus - Final status of SAP deregistration.
  662. Return Value:
  663. None
  664. --*/
  665. {
  666. PRWAN_NDIS_SAP pSap;
  667. PRWAN_TDI_ADDRESS pAddrObject;
  668. PRWAN_NDIS_AF pAf;
  669. INT rc;
  670. RWAN_ASSERT(NdisStatus == NDIS_STATUS_SUCCESS);
  671. pSap = (PRWAN_NDIS_SAP)ProtocolSapContext;
  672. RWAN_STRUCT_ASSERT(pSap, nsp);
  673. RWANDEBUGP(DL_VERY_LOUD, DC_BIND,
  674. ("RWanDeregSapComplete: pSap x%x, pAddrObj x%x, pAf x%x\n",
  675. pSap, pSap->pAddrObject, pSap->pNdisAf));
  676. pAddrObject = pSap->pAddrObject;
  677. //
  678. // Unlink the SAP from the Address Object.
  679. //
  680. RWAN_ACQUIRE_ADDRESS_LOCK(pAddrObject);
  681. RWAN_DELETE_FROM_LIST(&(pSap->AddrObjLink));
  682. rc = RWanDereferenceAddressObject(pAddrObject); // SAP dereg complete
  683. if (rc != 0)
  684. {
  685. RWAN_RELEASE_ADDRESS_LOCK(pAddrObject);
  686. }
  687. //
  688. // Unlink the SAP from the AF.
  689. //
  690. pAf = pSap->pNdisAf;
  691. RWAN_STRUCT_ASSERT(pAf, naf);
  692. RWAN_ACQUIRE_AF_LOCK(pAf);
  693. RWAN_DELETE_FROM_LIST(&(pSap->AfLink));
  694. rc = RWanDereferenceAf(pAf); // SAP deregister complete
  695. if (rc != 0)
  696. {
  697. RWAN_RELEASE_AF_LOCK(pAf);
  698. }
  699. RWAN_FREE_MEM(pSap);
  700. }