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.

877 lines
13 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. D:\nt\private\ntos\tdi\rawwan\core\utils.c
  5. Abstract:
  6. Revision History:
  7. Who When What
  8. -------- -------- ----------------------------------------------
  9. arvindm 05-07-97 Created
  10. Notes:
  11. --*/
  12. #include <precomp.h>
  13. #define _FILENUMBER 'LITU'
  14. RWAN_STATUS
  15. RWanInitGlobals(
  16. IN PDRIVER_OBJECT pDriverObject
  17. )
  18. /*++
  19. Routine Description:
  20. Initialize global data structures.
  21. Arguments:
  22. pDriverObject - Points to our driver object, from DriverEntry.
  23. Return Value:
  24. RWAN_STATUS_SUCCESS if initialized successfully, else an appropriate
  25. error code.
  26. --*/
  27. {
  28. RWAN_STATUS RWanStatus;
  29. pRWanGlobal = &RWanGlobals;
  30. RWAN_ZERO_MEM(pRWanGlobal, sizeof(RWanGlobals));
  31. RWAN_SET_SIGNATURE(pRWanGlobal, nlg);
  32. RWAN_INIT_LIST(&pRWanGlobal->AfInfoList);
  33. RWAN_INIT_LIST(&pRWanGlobal->ProtocolList);
  34. RWAN_INIT_LIST(&pRWanGlobal->AdapterList);
  35. RWAN_INIT_GLOBAL_LOCK();
  36. RWAN_INIT_ADDRESS_LIST_LOCK();
  37. RWAN_INIT_CONN_TABLE_LOCK();
  38. RWAN_INIT_EVENT_STRUCT(&pRWanGlobal->Event);
  39. pRWanGlobal->MaxConnections = RWanMaxTdiConnections;
  40. #ifdef NT
  41. pRWanGlobal->pDriverObject = pDriverObject;
  42. RWAN_INIT_LIST(&pRWanGlobal->DeviceObjList);
  43. #endif // NT
  44. RWanStatus = RWanInitReceive();
  45. if (RWanStatus == RWAN_STATUS_SUCCESS)
  46. {
  47. RWanStatus = RWanInitSend();
  48. if (RWanStatus != RWAN_STATUS_SUCCESS)
  49. {
  50. RWanShutdownReceive();
  51. }
  52. }
  53. return (RWanStatus);
  54. }
  55. VOID
  56. RWanDeinitGlobals(
  57. VOID
  58. )
  59. /*++
  60. Routine Description:
  61. The flip of RWanInitGlobals.
  62. Arguments:
  63. None
  64. Return Value:
  65. None
  66. --*/
  67. {
  68. RWAN_FREE_EVENT_STRUCT(&pRWanGlobal->Event);
  69. RWAN_FREE_GLOBAL_LOCK();
  70. if (pRWanGlobal->pConnTable != NULL)
  71. {
  72. RWAN_FREE_MEM(pRWanGlobal->pConnTable);
  73. pRWanGlobal->pConnTable = NULL;
  74. }
  75. RWanShutdownReceive();
  76. RWanShutdownSend();
  77. }
  78. PRWAN_TDI_PROTOCOL
  79. RWanGetProtocolFromNumber(
  80. IN UINT Protocol
  81. )
  82. /*++
  83. Routine Description:
  84. Return the TDI Protocol info block that represents the given
  85. TDI protocol number.
  86. Arguments:
  87. Protocol - The TDI protocol number
  88. Return Value:
  89. Pointer to TDI Protocol block if found, else NULL.
  90. --*/
  91. {
  92. PLIST_ENTRY pAfInfoEntry;
  93. PRWAN_NDIS_AF_INFO pAfInfo;
  94. PLIST_ENTRY pProtocolEntry;
  95. PRWAN_TDI_PROTOCOL pProtocol;
  96. BOOLEAN bFound = FALSE;
  97. RWAN_ACQUIRE_GLOBAL_LOCK();
  98. for (pAfInfoEntry = pRWanGlobal->AfInfoList.Flink;
  99. pAfInfoEntry != &(pRWanGlobal->AfInfoList);
  100. pAfInfoEntry = pAfInfoEntry->Flink)
  101. {
  102. pAfInfo = CONTAINING_RECORD(pAfInfoEntry, RWAN_NDIS_AF_INFO, AfInfoLink);
  103. for (pProtocolEntry = pAfInfo->TdiProtocolList.Flink;
  104. pProtocolEntry != &(pAfInfo->TdiProtocolList);
  105. pProtocolEntry = pProtocolEntry->Flink)
  106. {
  107. pProtocol = CONTAINING_RECORD(pProtocolEntry, RWAN_TDI_PROTOCOL, AfInfoLink);
  108. if (pProtocol->TdiProtocol == Protocol)
  109. {
  110. bFound = TRUE;
  111. break;
  112. }
  113. }
  114. if (bFound)
  115. {
  116. break;
  117. }
  118. }
  119. RWAN_RELEASE_GLOBAL_LOCK();
  120. if (!bFound)
  121. {
  122. pProtocol = NULL;
  123. }
  124. return (pProtocol);
  125. }
  126. TA_ADDRESS *
  127. RWanGetValidAddressFromList(
  128. IN TRANSPORT_ADDRESS UNALIGNED *pAddrList,
  129. IN PRWAN_TDI_PROTOCOL pProtocol
  130. )
  131. /*++
  132. Routine Description:
  133. Go through the given transport address list, and return the first
  134. valid protocol address that we find.
  135. Valid address: one that matches the address type and length for
  136. the specified TDI protocol.
  137. Arguments:
  138. pAddrList - Points to list of addresses
  139. pProtocol - Points to TDI Protocol block
  140. Return Value:
  141. Pointer to the first valid address in the list if found, else NULL.
  142. --*/
  143. {
  144. INT i;
  145. TA_ADDRESS * pAddr;
  146. pAddr = (TA_ADDRESS *)pAddrList->Address;
  147. for (i = 0; i < pAddrList->TAAddressCount; i++)
  148. {
  149. if ((pAddr->AddressType == pProtocol->SockAddressFamily) &&
  150. (pAddr->AddressLength >= pProtocol->MaxAddrLength))
  151. {
  152. return (pAddr);
  153. }
  154. pAddr = (TA_ADDRESS *)
  155. ((PUCHAR)(pAddr->Address) + pAddr->AddressLength);
  156. }
  157. return (NULL);
  158. }
  159. PRWAN_TDI_CONNECTION
  160. RWanAllocateConnObject(
  161. VOID
  162. )
  163. /*++
  164. Routine Description:
  165. Allocate a TDI Connection object.
  166. Arguments:
  167. None
  168. Return Value:
  169. Pointer to allocated Connection Object, or NULL.
  170. --*/
  171. {
  172. PRWAN_TDI_CONNECTION pConnObject;
  173. RWAN_ALLOC_MEM(pConnObject, RWAN_TDI_CONNECTION, sizeof(RWAN_TDI_CONNECTION));
  174. if (pConnObject != NULL)
  175. {
  176. RWAN_ZERO_MEM(pConnObject, sizeof(RWAN_TDI_CONNECTION));
  177. RWAN_SET_SIGNATURE(pConnObject, ntc);
  178. RWAN_INIT_LOCK(&(pConnObject->Lock));
  179. #if DBG
  180. pConnObject->ntcd_sig = ' gbD';
  181. #endif
  182. }
  183. return (pConnObject);
  184. }
  185. VOID
  186. RWanReferenceConnObject(
  187. IN PRWAN_TDI_CONNECTION pConnObject
  188. )
  189. /*++
  190. Routine Description:
  191. Add a reference to the specified Connection Object.
  192. Arguments:
  193. pConnObject - Pointer to the TDI Connection Object.
  194. Locks on Entry:
  195. pConnObject
  196. Locks on Exit:
  197. pConnObject
  198. Return Value:
  199. None
  200. --*/
  201. {
  202. RWAN_STRUCT_ASSERT(pConnObject, ntc);
  203. pConnObject->RefCount++;
  204. }
  205. INT
  206. RWanDereferenceConnObject(
  207. IN PRWAN_TDI_CONNECTION pConnObject
  208. )
  209. /*++
  210. Routine Description:
  211. Dereference the specified Connection Object. If the reference
  212. count goes down to 0, free it.
  213. Arguments:
  214. pConnObject - Pointer to the TDI Connection Object.
  215. Locks on Entry:
  216. pConnObject
  217. Locks on Exit:
  218. pConnObject, iff it hasn't been freed.
  219. Return Value:
  220. INT - The resulting reference count.
  221. --*/
  222. {
  223. INT RefCount;
  224. RWAN_DELETE_NOTIFY DeleteNotify;
  225. RWAN_STRUCT_ASSERT(pConnObject, ntc);
  226. RefCount = --pConnObject->RefCount;
  227. if (RefCount == 0)
  228. {
  229. DeleteNotify = pConnObject->DeleteNotify;
  230. RWAN_RELEASE_CONN_LOCK(pConnObject);
  231. RWANDEBUGP(DL_EXTRA_LOUD, DC_UTIL,
  232. ("Derefed away: pConnObj x%x, Notify x%x\n",
  233. pConnObject, DeleteNotify.pDeleteRtn));
  234. if (DeleteNotify.pDeleteRtn)
  235. {
  236. (*DeleteNotify.pDeleteRtn)(DeleteNotify.DeleteContext, TDI_SUCCESS, 0);
  237. }
  238. RWAN_FREE_MEM(pConnObject);
  239. }
  240. return (RefCount);
  241. }
  242. PRWAN_TDI_ADDRESS
  243. RWanAllocateAddressObject(
  244. IN TA_ADDRESS * pTransportAddress
  245. )
  246. /*++
  247. Routine Description:
  248. Allocate a TDI Address object.
  249. Arguments:
  250. pTransportAddress - Points to transport address for which this
  251. Address Object is our context.
  252. Return Value:
  253. Pointer to allocated Address Object, or NULL.
  254. --*/
  255. {
  256. PRWAN_TDI_ADDRESS pAddrObject;
  257. ULONG Size;
  258. NDIS_STATUS Status;
  259. Size = sizeof(RWAN_TDI_ADDRESS) +
  260. pTransportAddress->AddressLength;
  261. RWAN_ALLOC_MEM(pAddrObject, RWAN_TDI_ADDRESS, Size);
  262. if (pAddrObject != NULL)
  263. {
  264. RWAN_ZERO_MEM(pAddrObject, Size);
  265. RWAN_SET_SIGNATURE(pAddrObject, nta);
  266. RWAN_INIT_LOCK(&(pAddrObject->Lock));
  267. Status = NDIS_STATUS_SUCCESS;
  268. try
  269. {
  270. pAddrObject->AddressType = pTransportAddress->AddressType;
  271. pAddrObject->AddressLength = pTransportAddress->AddressLength;
  272. pAddrObject->pAddress = (PVOID)((PUCHAR)pAddrObject + sizeof(RWAN_TDI_ADDRESS));
  273. RWAN_COPY_MEM(pAddrObject->pAddress,
  274. pTransportAddress->Address,
  275. pTransportAddress->AddressLength);
  276. }
  277. except (EXCEPTION_EXECUTE_HANDLER)
  278. {
  279. Status = NDIS_STATUS_FAILURE;
  280. }
  281. if (Status != NDIS_STATUS_SUCCESS)
  282. {
  283. RWAN_FREE_MEM(pAddrObject);
  284. pAddrObject = NULL;
  285. }
  286. else
  287. {
  288. RWAN_INIT_LIST(&pAddrObject->IdleConnList);
  289. RWAN_INIT_LIST(&pAddrObject->ListenConnList);
  290. RWAN_INIT_LIST(&pAddrObject->ActiveConnList);
  291. RWAN_INIT_LIST(&pAddrObject->SapList);
  292. RWAN_INIT_EVENT_STRUCT(&pAddrObject->Event);
  293. }
  294. }
  295. return (pAddrObject);
  296. }
  297. VOID
  298. RWanReferenceAddressObject(
  299. IN PRWAN_TDI_ADDRESS pAddrObject
  300. )
  301. /*++
  302. Routine Description:
  303. Add a reference to the specified Address Object.
  304. Arguments:
  305. pAddrObject - Pointer to the TDI Address Object.
  306. Locks on Entry:
  307. pAddrObject
  308. Locks on Exit:
  309. pAddrObject
  310. Return Value:
  311. None
  312. --*/
  313. {
  314. RWAN_STRUCT_ASSERT(pAddrObject, nta);
  315. pAddrObject->RefCount++;
  316. }
  317. INT
  318. RWanDereferenceAddressObject(
  319. IN PRWAN_TDI_ADDRESS pAddrObject
  320. )
  321. /*++
  322. Routine Description:
  323. Dereference the specified Address Object. If the reference
  324. count goes down to 0, free it.
  325. Arguments:
  326. pAddrObject - Pointer to the TDI Address Object.
  327. Locks on Entry:
  328. pAddrObject
  329. Locks on Exit:
  330. pAddrObject, iff it hasn't been freed.
  331. Return Value:
  332. INT - The resulting reference count.
  333. --*/
  334. {
  335. INT RefCount;
  336. RWAN_DELETE_NOTIFY DeleteNotify;
  337. RWAN_STRUCT_ASSERT(pAddrObject, nta);
  338. RefCount = --pAddrObject->RefCount;
  339. if (RefCount == 0)
  340. {
  341. RWAN_ASSERT(RWAN_IS_LIST_EMPTY(&pAddrObject->IdleConnList));
  342. RWAN_ASSERT(RWAN_IS_LIST_EMPTY(&pAddrObject->ActiveConnList));
  343. RWAN_ASSERT(RWAN_IS_LIST_EMPTY(&pAddrObject->ListenConnList));
  344. RWAN_ASSERT(RWAN_IS_LIST_EMPTY(&pAddrObject->SapList));
  345. DeleteNotify = pAddrObject->DeleteNotify;
  346. RWAN_RELEASE_ADDRESS_LOCK(pAddrObject);
  347. RWANDEBUGP(DL_EXTRA_LOUD, DC_UTIL,
  348. ("Derefed away: pAddrObj x%x, Notify x%x\n",
  349. pAddrObject, DeleteNotify.pDeleteRtn));
  350. if (DeleteNotify.pDeleteRtn)
  351. {
  352. (*DeleteNotify.pDeleteRtn)(DeleteNotify.DeleteContext, (UINT)TDI_ADDR_DELETED, 0);
  353. }
  354. RWAN_FREE_MEM(pAddrObject);
  355. }
  356. return (RefCount);
  357. }
  358. PRWAN_NDIS_AF
  359. RWanAllocateAf(
  360. VOID
  361. )
  362. /*++
  363. Routine Description:
  364. Allocate an NDIS AF block.
  365. Arguments:
  366. None
  367. Return Value:
  368. Pointer to allocated NDIS AF Block, or NULL.
  369. --*/
  370. {
  371. PRWAN_NDIS_AF pAf;
  372. RWAN_ALLOC_MEM(pAf, RWAN_NDIS_AF, sizeof(RWAN_NDIS_AF));
  373. if (pAf != NULL)
  374. {
  375. RWAN_ZERO_MEM(pAf, sizeof(RWAN_NDIS_AF));
  376. RWAN_SET_SIGNATURE(pAf, naf);
  377. RWAN_INIT_LOCK(&(pAf->Lock));
  378. RWAN_INIT_LIST(&(pAf->NdisVcList));
  379. RWAN_INIT_LIST(&(pAf->NdisSapList));
  380. }
  381. RWANDEBUGP(DL_WARN, DC_WILDCARD,
  382. ("Allocated AF x%x\n", pAf));
  383. return (pAf);
  384. }
  385. VOID
  386. RWanReferenceAf(
  387. IN PRWAN_NDIS_AF pAf
  388. )
  389. /*++
  390. Routine Description:
  391. Add a reference to the specified NDIS AF Block.
  392. Arguments:
  393. pAf - Pointer to the NDIS AF Block.
  394. Locks on Entry:
  395. pAf
  396. Locks on Exit:
  397. pAf
  398. Return Value:
  399. None
  400. --*/
  401. {
  402. RWAN_STRUCT_ASSERT(pAf, naf);
  403. pAf->RefCount++;
  404. }
  405. INT
  406. RWanDereferenceAf(
  407. IN PRWAN_NDIS_AF pAf
  408. )
  409. /*++
  410. Routine Description:
  411. Dereference the specified NDIS AF Block. If the reference
  412. count goes down to 0, free it. Some additional work if
  413. freeing this: unlink from the adapter, and check if the
  414. adapter is unbinding.
  415. Arguments:
  416. pAf - Pointer to the NDIS AF Block.
  417. Locks on Entry:
  418. pAf
  419. Locks on Exit:
  420. pAf, iff it hasn't been freed.
  421. Return Value:
  422. INT - The resulting reference count.
  423. --*/
  424. {
  425. INT RefCount;
  426. RWAN_DELETE_NOTIFY DeleteNotify;
  427. PRWAN_NDIS_ADAPTER pAdapter;
  428. RWAN_STRUCT_ASSERT(pAf, naf);
  429. RefCount = --pAf->RefCount;
  430. if (RefCount == 0)
  431. {
  432. DeleteNotify = pAf->DeleteNotify;
  433. pAdapter = pAf->pAdapter;
  434. RWAN_RELEASE_AF_LOCK(pAf);
  435. RWAN_ACQUIRE_GLOBAL_LOCK();
  436. //
  437. // Unlink from list of AF opens for this NDIS AF
  438. //
  439. RWAN_DELETE_FROM_LIST(&(pAf->AfInfoLink));
  440. RWAN_RELEASE_GLOBAL_LOCK();
  441. RWAN_ACQUIRE_ADAPTER_LOCK(pAdapter);
  442. //
  443. // Unlink from list of AF opens on this adapter.
  444. //
  445. if (RWAN_IS_BIT_SET(pAf->Flags, RWANF_AF_IN_ADAPTER_LIST))
  446. {
  447. RWAN_DELETE_FROM_LIST(&(pAf->AfLink));
  448. }
  449. //
  450. // See if we just deleted the last AF on this adapter, and
  451. // we are in the process of unbinding from this adapter.
  452. //
  453. if (RWAN_IS_LIST_EMPTY(&pAdapter->AfList) &&
  454. RWAN_IS_BIT_SET(pAdapter->Flags, RWANF_AD_UNBIND_PENDING))
  455. {
  456. RWanCloseAdapter(pAdapter);
  457. //
  458. // Adapter lock is released within the above.
  459. //
  460. }
  461. else
  462. {
  463. RWAN_RELEASE_ADAPTER_LOCK(pAdapter);
  464. }
  465. RWANDEBUGP(DL_EXTRA_LOUD, DC_UTIL,
  466. ("Derefed away: pAf x%x, Notify x%x\n",
  467. pAf, DeleteNotify.pDeleteRtn));
  468. if (DeleteNotify.pDeleteRtn)
  469. {
  470. (*DeleteNotify.pDeleteRtn)(DeleteNotify.DeleteContext, TDI_SUCCESS, 0);
  471. }
  472. RWAN_FREE_MEM(pAf);
  473. }
  474. return (RefCount);
  475. }
  476. #if 0
  477. VOID
  478. RWanReferenceAdapter(
  479. IN PRWAN_NDIS_ADAPTER pAdapter
  480. )
  481. /*++
  482. Routine Description:
  483. Add a reference to the specified NDIS ADAPTER Block.
  484. Arguments:
  485. pAdapter - Pointer to the NDIS ADAPTER Block.
  486. Locks on Entry:
  487. pAdapter
  488. Locks on Exit:
  489. pAdapter
  490. Return Value:
  491. None
  492. --*/
  493. {
  494. RWAN_STRUCT_ASSERT(pAdapter, nad);
  495. pAdapter->RefCount++;
  496. }
  497. INT
  498. RWanDereferenceAdapter(
  499. IN PRWAN_NDIS_ADAPTER pAdapter
  500. )
  501. /*++
  502. Routine Description:
  503. Dereference the specified NDIS ADAPTER Block. If the reference
  504. count goes down to 0, free it.
  505. Arguments:
  506. pAdapter - Pointer to the NDIS ADAPTER Block.
  507. Locks on Entry:
  508. pAdapter
  509. Locks on Exit:
  510. pAdapter, iff it hasn't been freed.
  511. Return Value:
  512. INT - The resulting reference count.
  513. --*/
  514. {
  515. INT RefCount;
  516. RWAN_DELETE_NOTIFY DeleteNotify;
  517. RWAN_STRUCT_ASSERT(pAdapter, nad);
  518. RefCount = --pAdapter->RefCount;
  519. if (RefCount == 0)
  520. {
  521. DeleteNotify = pAdapter->DeleteNotify;
  522. RWAN_RELEASE_ADAPTER_LOCK(pAdapter);
  523. if (DeleteNotify.pDeleteRtn)
  524. {
  525. (*DeleteNotify.pDeleteRtn)(DeleteNotify.DeleteContext, TDI_SUCCESS, 0);
  526. }
  527. RWAN_FREE_MEM(pAdapter);
  528. }
  529. return (RefCount);
  530. }
  531. #endif // 0
  532. TDI_STATUS
  533. RWanNdisToTdiStatus(
  534. IN NDIS_STATUS Status
  535. )
  536. /*++
  537. Routine Description:
  538. Convert an NDIS Status code to an equivalent TDI code.
  539. TBD: RWanNdisToTdiStatus: support more NDIS status codes.
  540. Arguments:
  541. Status - NDIS status code.
  542. Return Value:
  543. TDI status.
  544. --*/
  545. {
  546. TDI_STATUS TdiStatus;
  547. switch (Status)
  548. {
  549. case NDIS_STATUS_SUCCESS:
  550. TdiStatus = TDI_SUCCESS;
  551. break;
  552. case NDIS_STATUS_RESOURCES:
  553. case NDIS_STATUS_VC_NOT_ACTIVATED:
  554. case NDIS_STATUS_VC_NOT_AVAILABLE:
  555. TdiStatus = TDI_NO_RESOURCES;
  556. break;
  557. case NDIS_STATUS_SAP_IN_USE:
  558. TdiStatus = TDI_ADDR_IN_USE;
  559. break;
  560. default:
  561. TdiStatus = TDI_NOT_ACCEPTED;
  562. break;
  563. }
  564. return (TdiStatus);
  565. }