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.

2519 lines
63 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. Ndiswan.c
  5. Abstract:
  6. This is the initialization file for the NdisWan driver. This driver
  7. is a shim between the protocols, where it conforms to the NDIS 3.1
  8. Miniport interface spec, and the WAN Miniport drivers, where it exports
  9. the WAN Extensions for Miniports (it looks like a protocol to the WAN
  10. Miniport drivers).
  11. Author:
  12. Tony Bell (TonyBe) June 06, 1995
  13. Environment:
  14. Kernel Mode
  15. Revision History:
  16. TonyBe 06/06/95 Created
  17. --*/
  18. #include "wan.h"
  19. #define __FILE_SIG__ MEMORY_FILESIG
  20. #ifdef ALLOC_PRAGMA
  21. #pragma alloc_text(INIT, NdisWanCreateProtocolInfoTable)
  22. #endif
  23. EXPORT
  24. VOID
  25. NdisTapiDeregisterProvider(
  26. IN NDIS_HANDLE
  27. );
  28. //
  29. // Local function prototypes
  30. //
  31. PVOID
  32. AllocateWanPacket(
  33. IN POOL_TYPE PoolType,
  34. IN SIZE_T NumberOfBytes,
  35. IN ULONG Tag
  36. );
  37. VOID
  38. FreeWanPacket(
  39. PVOID WanPacket
  40. );
  41. //
  42. // End local function prototypes
  43. //
  44. PMINIPORTCB
  45. NdisWanAllocateMiniportCB(
  46. IN PNDIS_STRING AdapterName
  47. )
  48. /*++
  49. Routine Name:
  50. NdisWanAllocateMiniportCB
  51. Routine Description:
  52. This routine creates and initializes an MiniportCB
  53. Arguments:
  54. Return Values:
  55. --*/
  56. {
  57. PMINIPORTCB LocalMiniportCB;
  58. ULONG ulAllocationSize, i;
  59. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateMiniportCB: Enter"));
  60. //
  61. // Allocate and zero out the memory block
  62. //
  63. NdisWanAllocateMemory(&LocalMiniportCB, MINIPORTCB_SIZE, MINIPORTCB_TAG);
  64. if (LocalMiniportCB == NULL) {
  65. return (NULL);
  66. }
  67. NdisZeroMemory(LocalMiniportCB, MINIPORTCB_SIZE);
  68. //
  69. // setup the new control block
  70. //
  71. NdisAllocateSpinLock(&LocalMiniportCB->Lock);
  72. #ifdef MINIPORT_NAME
  73. NdisWanAllocateAdapterName(&LocalMiniportCB->AdapterName, AdapterName);
  74. #endif
  75. #if DBG
  76. InitializeListHead(&LocalMiniportCB->SendPacketList);
  77. InitializeListHead(&LocalMiniportCB->RecvPacketList);
  78. #endif
  79. InitializeListHead(&LocalMiniportCB->ProtocolCBList);
  80. InitializeListHead(&LocalMiniportCB->AfSapCBList);
  81. NdisWanInitializeSyncEvent(&LocalMiniportCB->HaltEvent);
  82. NdisWanClearSyncEvent(&LocalMiniportCB->HaltEvent);
  83. //
  84. // Add to global list
  85. //
  86. InsertTailGlobalList(MiniportCBList, &(LocalMiniportCB->Linkage));
  87. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("%ls MiniportCB: 0x%x, Number: %d",
  88. LocalMiniportCB->AdapterName.Buffer, LocalMiniportCB, MiniportCBList.ulCount));
  89. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateMiniportCB: Exit"));
  90. return (LocalMiniportCB);
  91. }
  92. VOID
  93. NdisWanFreeMiniportCB(
  94. IN PMINIPORTCB pMiniportCB
  95. )
  96. /*++
  97. Routine Name:
  98. NdisWanFreeMiniportCB
  99. Routine Description:
  100. This frees a MiniportCB
  101. Arguments:
  102. pMiniportCB - Pointer to to the MiniportCB that is being destroyed
  103. Return Values:
  104. None
  105. --*/
  106. {
  107. PMINIPORTCB mcb;
  108. BOOLEAN Found = FALSE;
  109. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanFreeMiniportCB: Enter"));
  110. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("MiniportCB: 0x%x", pMiniportCB));
  111. #ifdef MINIPORT_NAME
  112. NdisWanFreeNdisString(&pMiniportCB->AdapterName);
  113. #endif
  114. NdisFreeSpinLock(&pMiniportCB->Lock);
  115. NdisAcquireSpinLock(&MiniportCBList.Lock);
  116. RemoveEntryList(&pMiniportCB->Linkage);
  117. MiniportCBList.ulCount--;
  118. //
  119. // Walk the miniportcb list and see if this is the only
  120. // instance of this protocol. If it is we need to notify
  121. // user-mode that a protocol has been removed.
  122. //
  123. mcb = (PMINIPORTCB)MiniportCBList.List.Flink;
  124. while ((PVOID)mcb != (PVOID)&MiniportCBList.List) {
  125. if (mcb->ProtocolType == pMiniportCB->ProtocolType) {
  126. Found = TRUE;
  127. break;
  128. }
  129. mcb = (PMINIPORTCB)mcb->Linkage.Flink;
  130. }
  131. NdisReleaseSpinLock(&MiniportCBList.Lock);
  132. if (Found == FALSE) {
  133. PROTOCOL_INFO pinfo;
  134. NdisZeroMemory(&pinfo, sizeof(pinfo));
  135. pinfo.ProtocolType = pMiniportCB->ProtocolType;
  136. pinfo.Flags = PROTOCOL_UNBOUND;
  137. SetProtocolInfo(&pinfo);
  138. }
  139. NdisWanFreeMemory(pMiniportCB);
  140. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanFreeMiniportCB: Exit"));
  141. }
  142. POPENCB
  143. NdisWanAllocateOpenCB(
  144. IN PUNICODE_STRING BindName
  145. )
  146. /*++
  147. Routine Name:
  148. NdisWanAllocateOpenCB
  149. Routine Description:
  150. This routine creates and initializes a OpenCB
  151. Arguments:
  152. BindName - Pointer to an NDIS_STRING that has the name of the WAN Miniport
  153. that will be used in the NdisOpenAdapter call when we bind to
  154. the WAN Miniport.
  155. Return Values:
  156. --*/
  157. {
  158. POPENCB pOpenCB;
  159. ULONG ulAllocationSize;
  160. USHORT i;
  161. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateOpenCB: Enter"));
  162. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("BindName: %ls", BindName));
  163. //
  164. // Allocate memory for OpenCB
  165. //
  166. NdisWanAllocateMemory(&pOpenCB, OPENCB_SIZE, OPENCB_TAG);
  167. if (pOpenCB == NULL) {
  168. return (NULL);
  169. }
  170. NdisZeroMemory(pOpenCB, OPENCB_SIZE);
  171. NdisWanInitializeNotificationEvent(&pOpenCB->InitEvent);
  172. //
  173. // Parse out the GUID for this miniport
  174. //
  175. //
  176. // Setup new control block
  177. //
  178. NdisWanAllocateMemory(&pOpenCB->MiniportName.Buffer, BindName->MaximumLength, NDISSTRING_TAG);
  179. pOpenCB->MiniportName.MaximumLength = BindName->MaximumLength;
  180. pOpenCB->MiniportName.Length = BindName->Length;
  181. RtlCopyUnicodeString(&pOpenCB->MiniportName, BindName);
  182. //
  183. // Go to the end of the string and work back until we find
  184. // the first "{". Now start parsing the string converting
  185. // and copying from WCHAR to CHAR all digits until we hit
  186. // the closing "}".
  187. //
  188. for (i = pOpenCB->MiniportName.Length/sizeof(WCHAR); i > 0; i--) {
  189. if (pOpenCB->MiniportName.Buffer[i-1] == (WCHAR)L'{') {
  190. break;
  191. }
  192. }
  193. if (i != 0) {
  194. NDIS_STRING Src;
  195. Src.Length =
  196. BindName->Length - ((i-1)*sizeof(WCHAR));
  197. Src.MaximumLength =
  198. BindName->Length - ((i-1)*sizeof(WCHAR));
  199. Src.Buffer = &BindName->Buffer[i-1];
  200. RtlGUIDFromString(&Src, &pOpenCB->Guid);
  201. }
  202. NdisAllocateSpinLock(&pOpenCB->Lock);
  203. InitializeListHead(&pOpenCB->AfSapCBList);
  204. InitializeListHead(&pOpenCB->AfSapCBClosing);
  205. InitializeListHead(&pOpenCB->WanRequestList);
  206. #if DBG
  207. InitializeListHead(&pOpenCB->SendPacketList);
  208. #endif
  209. //
  210. // Put OpenCB on global list
  211. //
  212. InsertTailGlobalList(OpenCBList, &(pOpenCB->Linkage));
  213. pOpenCB->RefCount = 1;
  214. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("WanMiniport %ls OpenCB: 0x%x",
  215. pOpenCB->MiniportName.Buffer, pOpenCB));
  216. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateOpenCB: Exit"));
  217. return(pOpenCB);
  218. }
  219. VOID
  220. NdisWanFreeOpenCB(
  221. IN POPENCB pOpenCB
  222. )
  223. /*++
  224. Routine Name:
  225. NdisWanFreeOpenCB
  226. Routine Description:
  227. This routine frees a OpenCB
  228. Arguments:
  229. pOpenCB - Pointer to the OpenCB that is being destroyed
  230. Return Values:
  231. None
  232. --*/
  233. {
  234. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanFreeOpenCB: Enter - OpenCB: 0x%p", pOpenCB));
  235. if (pOpenCB->Flags & OPEN_LEGACY &&
  236. pOpenCB->Flags & SEND_RESOURCES) {
  237. NdisWanFreeSendResources(pOpenCB);
  238. }
  239. //
  240. // Remove from OpenCB global list
  241. //
  242. RemoveEntryGlobalList(OpenCBList, &(pOpenCB->Linkage));
  243. //
  244. // Free the memory allocated for the NDIS_STRING
  245. //
  246. NdisWanFreeNdisString(&pOpenCB->MiniportName);
  247. //
  248. // Free the memory allocated for the control block
  249. //
  250. NdisWanFreeMemory(pOpenCB);
  251. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanFreeOpenCB: Exit"));
  252. }
  253. PPROTOCOLCB
  254. NdisWanAllocateProtocolCB(
  255. IN PNDISWAN_ROUTE Route
  256. )
  257. /*++
  258. Routine Name:
  259. Routine Description:
  260. Arguments:
  261. Return Values:
  262. --*/
  263. {
  264. PPROTOCOLCB LocalProtocolCB;
  265. PUCHAR AllocatedMemory;
  266. PROTOCOL_INFO ProtocolInfo = {0};
  267. LocalProtocolCB =
  268. NdisAllocateFromNPagedLookasideList(&LinkProtoCBList);
  269. if (LocalProtocolCB == NULL) {
  270. return(NULL);
  271. }
  272. NdisZeroMemory(LocalProtocolCB, PROTOCOLCB_SIZE);
  273. LocalProtocolCB->Signature = PROTOCB_SIG;
  274. if (Route->ulBufferLength > 0) {
  275. NdisWanAllocateMemory(&AllocatedMemory,
  276. Route->ulBufferLength,
  277. PROTOCOLCB_TAG);
  278. if (AllocatedMemory == NULL) {
  279. NdisFreeToNPagedLookasideList(&LinkProtoCBList, LocalProtocolCB);
  280. return (NULL);
  281. }
  282. LocalProtocolCB->LineUpInfo = AllocatedMemory;
  283. }
  284. //
  285. // Copy the bindingname
  286. //
  287. if (Route->usBindingNameLength != 0) {
  288. USHORT usBindingNameLength;
  289. WCHAR BindingName[MAX_NAME_LENGTH+1] = {0};
  290. usBindingNameLength = Route->usBindingNameLength;
  291. //
  292. // We will limit the binding name string to 256 wchars
  293. //
  294. if (usBindingNameLength > (MAX_NAME_LENGTH * sizeof(WCHAR))) {
  295. usBindingNameLength = MAX_NAME_LENGTH * sizeof(WCHAR);
  296. }
  297. NdisMoveMemory((PUCHAR)BindingName,
  298. (PUCHAR)Route->BindingName,
  299. usBindingNameLength);
  300. BindingName[usBindingNameLength/sizeof(WCHAR)] = L'\0';
  301. NdisWanStringToNdisString(&LocalProtocolCB->BindingName, BindingName);
  302. }
  303. if (Route->usDeviceNameLength != 0) {
  304. USHORT usDeviceNameLength;
  305. usDeviceNameLength = Route->usDeviceNameLength;
  306. //
  307. // We will limit the binding name string to 256 wchars
  308. //
  309. if (usDeviceNameLength > (MAX_NAME_LENGTH * sizeof(WCHAR))) {
  310. usDeviceNameLength = (MAX_NAME_LENGTH * sizeof(WCHAR));
  311. }
  312. NdisWanAllocateMemory(&(LocalProtocolCB->InDeviceName.Buffer),
  313. usDeviceNameLength,
  314. NDISSTRING_TAG);
  315. if (LocalProtocolCB->InDeviceName.Buffer != NULL) {
  316. LocalProtocolCB->InDeviceName.MaximumLength = usDeviceNameLength;
  317. LocalProtocolCB->InDeviceName.Length = usDeviceNameLength;
  318. NdisMoveMemory((PUCHAR)LocalProtocolCB->InDeviceName.Buffer,
  319. (PUCHAR)Route->DeviceName,
  320. usDeviceNameLength);
  321. }
  322. }
  323. //
  324. // Copy over the protocol info
  325. //
  326. LocalProtocolCB->ulLineUpInfoLength = Route->ulBufferLength;
  327. if (Route->ulBufferLength != 0) {
  328. NdisMoveMemory(LocalProtocolCB->LineUpInfo,
  329. Route->Buffer,
  330. Route->ulBufferLength);
  331. }
  332. //
  333. // Setup the protocol type
  334. //
  335. LocalProtocolCB->ProtocolType = Route->usProtocolType;
  336. //
  337. // Get the PPP protocol value for this protocol type
  338. //
  339. ProtocolInfo.ProtocolType = Route->usProtocolType;
  340. if (GetProtocolInfo(&ProtocolInfo) != TRUE) {
  341. if (LocalProtocolCB->BindingName.Length != 0) {
  342. NdisWanFreeNdisString(&LocalProtocolCB->BindingName);
  343. }
  344. if (LocalProtocolCB->LineUpInfo != NULL) {
  345. NdisWanFreeMemory(LocalProtocolCB->LineUpInfo);
  346. }
  347. if (LocalProtocolCB->InDeviceName.Length != 0) {
  348. NdisWanFreeMemory(LocalProtocolCB->InDeviceName.Buffer);
  349. }
  350. NdisFreeToNPagedLookasideList(&LinkProtoCBList, LocalProtocolCB);
  351. return (NULL);
  352. }
  353. InitializeListHead(&LocalProtocolCB->VcList);
  354. NdisWanInitializeSyncEvent(&LocalProtocolCB->UnrouteEvent);
  355. LocalProtocolCB->PPPProtocolID = ProtocolInfo.PPPId;
  356. LocalProtocolCB->MTU = ProtocolInfo.MTU;
  357. LocalProtocolCB->TunnelMTU = ProtocolInfo.TunnelMTU;
  358. LocalProtocolCB->State = PROTOCOL_ROUTING;
  359. LocalProtocolCB->RefCount = 1;
  360. switch (Route->usProtocolType) {
  361. case PROTOCOL_IP:
  362. LocalProtocolCB->NonIdleDetectFunc = IpIsDataFrame;
  363. break;
  364. case PROTOCOL_IPX:
  365. LocalProtocolCB->NonIdleDetectFunc = IpxIsDataFrame;
  366. break;
  367. case PROTOCOL_NBF:
  368. LocalProtocolCB->NonIdleDetectFunc = NbfIsDataFrame;
  369. break;
  370. default:
  371. LocalProtocolCB->NonIdleDetectFunc = NULL;
  372. break;
  373. }
  374. NdisWanGetSystemTime(&LocalProtocolCB->LastNonIdleData);
  375. return(LocalProtocolCB);
  376. }
  377. VOID
  378. NdisWanFreeProtocolCB(
  379. IN PPROTOCOLCB ProtocolCB
  380. )
  381. /*++
  382. Routine Name:
  383. Routine Description:
  384. Arguments:
  385. Return Values:
  386. --*/
  387. {
  388. #if DBG
  389. {
  390. ULONG i;
  391. for (i = 0; i < MAX_MCML; i++) {
  392. ASSERT(ProtocolCB->PacketQueue[i].HeadQueue == NULL);
  393. ASSERT(ProtocolCB->PacketQueue[i].TailQueue == NULL);
  394. }
  395. }
  396. #endif
  397. if (ProtocolCB->InDeviceName.Length != 0) {
  398. NdisWanFreeMemory(ProtocolCB->InDeviceName.Buffer);
  399. }
  400. if (ProtocolCB->OutDeviceName.Length != 0) {
  401. NdisWanFreeNdisString(&ProtocolCB->OutDeviceName);
  402. }
  403. if (ProtocolCB->BindingName.Length != 0) {
  404. NdisWanFreeNdisString(&ProtocolCB->BindingName);
  405. }
  406. if (ProtocolCB->LineUpInfo != NULL) {
  407. NdisWanFreeMemory(ProtocolCB->LineUpInfo);
  408. }
  409. NdisFreeSpinLock(&ProtocolCB->Lock);
  410. NdisFreeToNPagedLookasideList(&LinkProtoCBList, ProtocolCB);
  411. }
  412. PLINKCB
  413. NdisWanAllocateLinkCB(
  414. IN POPENCB OpenCB,
  415. IN ULONG SendWindow
  416. )
  417. /*++
  418. Routine Name:
  419. NdisWanGetLinkCB
  420. Routine Description:
  421. This function returns a pointer to a LinkCB. The LinkCB is either retrieved
  422. from the WanAdapters free list or, if this list is empty, it is allocated.
  423. Arguments:
  424. OpenCB - Pointer to the WanAdapter control block that this Link is
  425. associated with
  426. Return Values:
  427. None
  428. --*/
  429. {
  430. PLINKCB LocalLinkCB;
  431. //
  432. // Figure out how much we need to allocate
  433. //
  434. LocalLinkCB =
  435. NdisAllocateFromNPagedLookasideList(&LinkProtoCBList);
  436. if (LocalLinkCB == NULL) {
  437. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for LinkCB"));
  438. return (NULL);
  439. }
  440. NdisZeroMemory(LocalLinkCB, LINKCB_SIZE);
  441. //
  442. // Initialize the control block
  443. //
  444. NdisWanInitializeSyncEvent(&LocalLinkCB->OutstandingFramesEvent);
  445. LocalLinkCB->Signature = LINKCB_SIG;
  446. LocalLinkCB->hLinkContext = NULL;
  447. LocalLinkCB->State = LINK_UP;
  448. LocalLinkCB->OpenCB = OpenCB;
  449. LocalLinkCB->OutstandingFrames = 0;
  450. LocalLinkCB->SendWindowOpen = TRUE;
  451. LocalLinkCB->SBandwidth = 100;
  452. LocalLinkCB->RBandwidth = 100;
  453. LocalLinkCB->SFlowSpec.MaxSduSize = glMaxMTU;
  454. LocalLinkCB->RFlowSpec.MaxSduSize = glMRRU;
  455. LocalLinkCB->LinkInfo.HeaderPadding = OpenCB->WanInfo.HeaderPadding;
  456. LocalLinkCB->LinkInfo.TailPadding = OpenCB->WanInfo.TailPadding;
  457. LocalLinkCB->LinkInfo.SendACCM =
  458. LocalLinkCB->LinkInfo.RecvACCM = OpenCB->WanInfo.DesiredACCM;
  459. LocalLinkCB->LinkInfo.MaxSendFrameSize = glMaxMTU;
  460. LocalLinkCB->LinkInfo.MaxRecvFrameSize = glMRU;
  461. if (OpenCB->Flags & OPEN_LEGACY) {
  462. LocalLinkCB->SendHandler = SendOnLegacyLink;
  463. } else {
  464. LocalLinkCB->SendHandler = SendOnLink;
  465. }
  466. if (OpenCB->MediumType == NdisMediumAtm ||
  467. (OpenCB->MediumType == NdisMediumWan &&
  468. (OpenCB->MediumSubType == NdisWanMediumAtm ||
  469. OpenCB->MediumSubType == NdisWanMediumPppoe)) ||
  470. (OpenCB->MediumType == NdisMediumCoWan &&
  471. (OpenCB->MediumSubType == NdisWanMediumAtm ||
  472. OpenCB->MediumSubType == NdisWanMediumPppoe))) {
  473. LocalLinkCB->RecvHandler = DetectBroadbandFraming;
  474. LocalLinkCB->LinkInfo.SendFramingBits =
  475. PPP_FRAMING | PPP_COMPRESS_ADDRESS_CONTROL;
  476. LocalLinkCB->LinkInfo.RecvFramingBits =
  477. PPP_FRAMING | PPP_COMPRESS_ADDRESS_CONTROL;
  478. } else {
  479. LocalLinkCB->RecvHandler = DetectFraming;
  480. }
  481. LocalLinkCB->SendWindow =
  482. (SendWindow == 0 || SendWindow > OpenCB->WanInfo.MaxTransmit) ?
  483. OpenCB->WanInfo.MaxTransmit : SendWindow;
  484. if (LocalLinkCB->SendWindow == 0) {
  485. LocalLinkCB->SendWindow = 1;
  486. }
  487. if (OpenCB->Flags & OPEN_LEGACY) {
  488. LocalLinkCB->SendResources = OpenCB->SendResources;
  489. } else {
  490. LocalLinkCB->SendResources = 1000;
  491. }
  492. NdisAllocateSpinLock(&LocalLinkCB->Lock);
  493. LocalLinkCB->RefCount = 1;
  494. REF_OPENCB(OpenCB);
  495. InterlockedIncrement(&OpenCB->ActiveLinkCount);
  496. return (LocalLinkCB);
  497. }
  498. VOID
  499. NdisWanFreeLinkCB(
  500. PLINKCB LinkCB
  501. )
  502. /*++
  503. Routine Name:
  504. Routine Description:
  505. Arguments:
  506. Return Values:
  507. --*/
  508. {
  509. POPENCB pOpenCB = LinkCB->OpenCB;
  510. ASSERT(LinkCB->OutstandingFrames == 0);
  511. LinkCB->State = LINK_DOWN;
  512. NdisFreeSpinLock(&LocalLinkCB->Lock);
  513. NdisFreeToNPagedLookasideList(&LinkProtoCBList, LinkCB);
  514. InterlockedDecrement(&pOpenCB->ActiveLinkCount);
  515. DEREF_OPENCB(pOpenCB);
  516. }
  517. NDIS_STATUS
  518. NdisWanAllocateSendResources(
  519. POPENCB OpenCB
  520. )
  521. /*++
  522. Routine Name:
  523. NdisWanAllocateSendResources
  524. Routine Description:
  525. Allocates all resources (SendDescriptors, WanPackets, ...)
  526. required for sending data. Should be called at line up time.
  527. Arguments:
  528. LinkCB - Pointer to the linkcb that the send resources will be attached to.
  529. SendWindow - Maximum number of sends that this link can handle
  530. Return Values:
  531. NDIS_STATUS_SUCCESS
  532. NDIS_STATUS_RESOURCES
  533. --*/
  534. {
  535. ULONG SendWindow;
  536. ULONG Endpoints;
  537. ULONG NumberOfPackets;
  538. ULONG BufferSize;
  539. ULONG WanPacketSize;
  540. PNDIS_WAN_PACKET WanPacket;
  541. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  542. do {
  543. //
  544. // We have to have atleast of sendwindow+1 of packets for
  545. // each link on the open. In the case of MCML we need
  546. // this amount for each fragment queue and for the
  547. // single non-fragment queue. So this leaves us with...
  548. //
  549. //
  550. // SendWindow + 1 + (glMaxMTU/glMinFragSize * MAX_MCML) *
  551. // number of links on the open
  552. //
  553. SendWindow = OpenCB->WanInfo.MaxTransmit;
  554. Endpoints = OpenCB->WanInfo.Endpoints;
  555. //
  556. // Sendwindow
  557. //
  558. NumberOfPackets = SendWindow;
  559. //
  560. // We keep track of how many fragmenting resources we have
  561. // available for each link
  562. //
  563. NumberOfPackets += ((glMaxMTU/glMinFragSize) * MAX_MCML);
  564. OpenCB->SendResources = NumberOfPackets;
  565. //
  566. // Add one for compression data manipulation
  567. //
  568. NumberOfPackets += 1;
  569. //
  570. // multiplied by the # of links on this open
  571. //
  572. NumberOfPackets *= Endpoints;
  573. //
  574. // The size of the buffer that we create is
  575. //
  576. BufferSize = OpenCB->WanInfo.MaxFrameSize +
  577. OpenCB->WanInfo.HeaderPadding +
  578. OpenCB->WanInfo.TailPadding +
  579. 40 + sizeof(PVOID);
  580. //
  581. // We assume compression is always on so we pad out 12%
  582. // incase the compressor expands. I don't know where the
  583. // 12% figure comes from.
  584. //
  585. BufferSize += (OpenCB->WanInfo.MaxFrameSize + 7) / 8;
  586. //
  587. // Make sure that the buffer is dword aligned.
  588. //
  589. BufferSize &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  590. OpenCB->BufferSize = BufferSize;
  591. WanPacketSize =
  592. sizeof(DATA_DESC) + sizeof(NDIS_WAN_PACKET) +
  593. 3*sizeof(PVOID) + BufferSize;
  594. //
  595. // If this device needs some special memory flags
  596. // we need to allocate memory for it's WanPackets now.
  597. // Otherwise we will intialize a lookaside list and
  598. // retrieve the packets as needed.
  599. if (OpenCB->WanInfo.MemoryFlags == 0) {
  600. NdisInitializeNPagedLookasideList(&OpenCB->WanPacketPool,
  601. AllocateWanPacket,
  602. FreeWanPacket,
  603. 0,
  604. WanPacketSize,
  605. WANPACKET_TAG,
  606. 0);
  607. } else {
  608. ULONG PacketMemorySize;
  609. PUCHAR PacketMemory;
  610. ULONG n;
  611. PacketMemorySize =
  612. WanPacketSize * NumberOfPackets;
  613. //
  614. // Allocate the memory for the wan packet buffer pool
  615. //
  616. NdisAllocateMemory(&PacketMemory,
  617. PacketMemorySize,
  618. OpenCB->WanInfo.MemoryFlags,
  619. OpenCB->WanInfo.HighestAcceptableAddress);
  620. if (PacketMemory == NULL) {
  621. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for BufferPool, AllocationSize: %d",
  622. PacketMemorySize));
  623. Status = NDIS_STATUS_RESOURCES;
  624. break;
  625. }
  626. OpenCB->PacketMemory = PacketMemory;
  627. OpenCB->PacketMemorySize = PacketMemorySize;
  628. NdisInitializeSListHead(&OpenCB->WanPacketList);
  629. for (n = 0; n < NumberOfPackets; n++) {
  630. PDATA_DESC DataDesc;
  631. //
  632. // Point to the DataDesc
  633. //
  634. DataDesc =
  635. (PDATA_DESC)PacketMemory;
  636. PacketMemory =
  637. ((PUCHAR)(DataDesc + 1) + sizeof(PVOID));
  638. (ULONG_PTR)PacketMemory &=
  639. ~((ULONG_PTR)sizeof(PVOID) - 1);
  640. //
  641. // Point to the WanPacket
  642. //
  643. WanPacket =
  644. (PNDIS_WAN_PACKET)PacketMemory;
  645. PacketMemory =
  646. ((PUCHAR)(WanPacket + 1) + sizeof(PVOID));
  647. (ULONG_PTR)PacketMemory &=
  648. ~((ULONG_PTR)sizeof(PVOID) - 1);
  649. //
  650. // Point to the begining of the data buffer
  651. //
  652. WanPacket->StartBuffer = PacketMemory;
  653. WanPacket->EndBuffer =
  654. PacketMemory + BufferSize - sizeof(PVOID);
  655. NdisInterlockedPushEntrySList(&OpenCB->WanPacketList,
  656. (PSLIST_ENTRY)DataDesc,
  657. &OpenCB->Lock);
  658. PacketMemory += BufferSize + sizeof(PVOID);
  659. (ULONG_PTR)PacketMemory &=
  660. ~((ULONG_PTR)sizeof(PVOID) - 1);
  661. }
  662. }
  663. } while ( FALSE );
  664. if (Status == NDIS_STATUS_SUCCESS) {
  665. OpenCB->Flags |= SEND_RESOURCES;
  666. }
  667. return (Status);
  668. }
  669. VOID
  670. NdisWanFreeSendResources(
  671. POPENCB OpenCB
  672. )
  673. /*++
  674. Routine Name:
  675. NdisWanFreeSendResources
  676. Routine Description:
  677. This routine removes the WanPackets from this opencb's send list
  678. and free's the memory allocated for these packets. Should be called
  679. when we are cleaningup an opencb.
  680. Arguments:
  681. OpenCB - Pointer to the opencb that the resources are being freed from.
  682. Return Values:
  683. None
  684. --*/
  685. {
  686. PUCHAR PacketMemory;
  687. ULONG PacketMemorySize, Flags;
  688. PacketMemory = OpenCB->PacketMemory;
  689. PacketMemorySize = OpenCB->PacketMemorySize;
  690. Flags = OpenCB->WanInfo.MemoryFlags;
  691. if (OpenCB->WanInfo.MemoryFlags == 0) {
  692. NdisDeleteNPagedLookasideList(&OpenCB->WanPacketPool);
  693. return;
  694. }
  695. //
  696. // Remove the packets from the wan packet pool
  697. //
  698. for (; ;) {
  699. PDATA_DESC DataDesc;
  700. DataDesc = (PDATA_DESC)
  701. NdisInterlockedPopEntrySList(&OpenCB->WanPacketList,
  702. &OpenCB->Lock);
  703. if (DataDesc == NULL) {
  704. break;
  705. }
  706. }
  707. ASSERT(NdisQueryDepthSList(&OpenCB->WanPacketList) == 0);
  708. //
  709. // Free the block of memory allocated for this send
  710. //
  711. if (PacketMemory != NULL) {
  712. NdisFreeMemory(OpenCB->PacketMemory,
  713. OpenCB->PacketMemorySize,
  714. OpenCB->Flags);
  715. }
  716. }
  717. PBUNDLECB
  718. NdisWanAllocateBundleCB(
  719. VOID
  720. )
  721. /*++
  722. Routine Name:
  723. Routine Description:
  724. Arguments:
  725. Return Values:
  726. --*/
  727. {
  728. PBUNDLECB LocalBundleCB = NULL;
  729. PWSTR IOName = L"I/O ProtocolCB";
  730. PPROTOCOLCB ProtocolCB;
  731. PSAMPLE_TABLE SampleTable;
  732. PBOND_INFO BonDInfo;
  733. UINT Class;
  734. PUCHAR pMem;
  735. //
  736. // Allocation size is the size of the control block plus the size
  737. // of a table of pointers to protocolcb's that might be routed to
  738. // this bundle.
  739. //
  740. pMem =
  741. NdisAllocateFromNPagedLookasideList(&BundleCBList);
  742. if (pMem == NULL) {
  743. return (NULL);
  744. }
  745. NdisZeroMemory(pMem, BUNDLECB_SIZE);
  746. LocalBundleCB = (PBUNDLECB)pMem;
  747. pMem += sizeof(BUNDLECB) + sizeof(PVOID);
  748. //
  749. // This is the memory used for the I/O protocolcb
  750. //
  751. (PUCHAR)ProtocolCB = pMem;
  752. (ULONG_PTR)ProtocolCB &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  753. pMem += sizeof(PROTOCOLCB) + sizeof(PVOID);
  754. //
  755. // This is the protocolcb table
  756. //
  757. (PUCHAR)LocalBundleCB->ProtocolCBTable = pMem;
  758. (ULONG_PTR)LocalBundleCB->ProtocolCBTable &=
  759. ~((ULONG_PTR)sizeof(PVOID) - 1);
  760. pMem += (MAX_PROTOCOLS * sizeof(PPROTOCOLCB)) + sizeof(PVOID);
  761. //
  762. // Initialize the BundleCB
  763. //
  764. NdisAllocateSpinLock(&LocalBundleCB->Lock);
  765. InitializeListHead(&LocalBundleCB->LinkCBList);
  766. for (Class = 0; Class < MAX_MCML; Class++) {
  767. PRECV_DESC RecvDescHole;
  768. PSEND_FRAG_INFO FragInfo;
  769. PBUNDLE_RECV_INFO RecvInfo;
  770. FragInfo = &LocalBundleCB->SendFragInfo[Class];
  771. RecvInfo = &LocalBundleCB->RecvInfo[Class];
  772. InitializeListHead(&FragInfo->FragQueue);
  773. FragInfo->MinFragSize = glMinFragSize;
  774. FragInfo->MaxFragSize = glMaxFragSize;
  775. InitializeListHead(&RecvInfo->AssemblyList);
  776. //
  777. // Init the recv hole desc
  778. //
  779. RecvDescHole =
  780. NdisWanAllocateRecvDesc(0);
  781. if (RecvDescHole == NULL) {
  782. UINT i;
  783. for (i = 0; i < MAX_MCML; i++) {
  784. RecvInfo = &LocalBundleCB->RecvInfo[i];
  785. if (RecvInfo->RecvDescHole != NULL) {
  786. NdisWanFreeRecvDesc(RecvInfo->RecvDescHole);
  787. }
  788. }
  789. NdisFreeToNPagedLookasideList(&BundleCBList, LocalBundleCB);
  790. return (NULL);
  791. }
  792. RecvDescHole->Flags = MULTILINK_HOLE_FLAG;
  793. RecvInfo->RecvDescHole = RecvDescHole;
  794. InsertHeadList(&RecvInfo->AssemblyList, &RecvDescHole->Linkage);
  795. RecvInfo->AssemblyCount++;
  796. }
  797. InitializeListHead(&LocalBundleCB->ProtocolCBList);
  798. NdisWanInitializeSyncEvent(&LocalBundleCB->OutstandingFramesEvent);
  799. LocalBundleCB->State = BUNDLE_UP;
  800. LocalBundleCB->FramingInfo.MaxRSendFrameSize = glMaxMTU;
  801. LocalBundleCB->FramingInfo.MaxRRecvFrameSize = glMRRU;
  802. LocalBundleCB->SFlowSpec.MaxSduSize = glMaxMTU;
  803. LocalBundleCB->RFlowSpec.MaxSduSize = glMRRU;
  804. NdisWanGetSystemTime(&LocalBundleCB->LastNonIdleData);
  805. LocalBundleCB->SendCompInfo.CompType =
  806. LocalBundleCB->RecvCompInfo.CompType = COMPTYPE_NONE;
  807. //
  808. // Add the protocolcb to the bundle's table and list
  809. //
  810. ProtocolCB->ProtocolType = PROTOCOL_PRIVATE_IO;
  811. ProtocolCB->PPPProtocolID = PPP_PROTOCOL_PRIVATE_IO;
  812. ProtocolCB->BundleCB = LocalBundleCB;
  813. ProtocolCB->State = PROTOCOL_ROUTED;
  814. NdisWanStringToNdisString(&ProtocolCB->InDeviceName, IOName);
  815. LocalBundleCB->IoProtocolCB = ProtocolCB;
  816. return (LocalBundleCB);
  817. }
  818. VOID
  819. NdisWanFreeBundleCB(
  820. IN PBUNDLECB BundleCB
  821. )
  822. /*++
  823. Routine Name:
  824. Routine Description:
  825. Arguments:
  826. Return Values:
  827. --*/
  828. {
  829. UINT Class;
  830. PPROTOCOLCB IoProtocolCB;
  831. PPACKET_QUEUE PacketQueue;
  832. FlushAssemblyLists(BundleCB);
  833. if (BundleCB->Flags & BOND_ENABLED) {
  834. RemoveEntryGlobalList(BonDWorkList, &BundleCB->BonDLinkage);
  835. }
  836. //
  837. // Free the hole place holders
  838. //
  839. for (Class = 0; Class < MAX_MCML; Class++) {
  840. PBUNDLE_RECV_INFO RecvInfo =
  841. &BundleCB->RecvInfo[Class];
  842. ASSERT(RecvInfo->RecvDescHole != NULL);
  843. NdisWanFreeRecvDesc(RecvInfo->RecvDescHole);
  844. RecvInfo->RecvDescHole = NULL;
  845. }
  846. #if 0
  847. KeCancelTimer(&BundleCB->BonDTimer);
  848. #endif
  849. IoProtocolCB = BundleCB->IoProtocolCB;
  850. PacketQueue = &IoProtocolCB->PacketQueue[MAX_MCML];
  851. ASSERT(IsPacketQueueEmpty(PacketQueue));
  852. //
  853. // If we have ppp packets queued we need
  854. // to flush them and free the memory!
  855. //
  856. while (!IsPacketQueueEmpty(PacketQueue)) {
  857. PNDIS_PACKET Packet;
  858. Packet =
  859. RemoveHeadPacketQueue(PacketQueue)
  860. CompleteNdisPacket(IoProtocolCB->MiniportCB,
  861. IoProtocolCB,
  862. Packet);
  863. }
  864. sl_compress_terminate(&BundleCB->VJCompress);
  865. if (BundleCB->Flags & SEND_CCP_ALLOCATED) {
  866. WanDeallocateCCP(BundleCB,
  867. &BundleCB->SendCompInfo,
  868. TRUE);
  869. BundleCB->Flags &= ~SEND_CCP_ALLOCATED;
  870. }
  871. if (BundleCB->Flags & RECV_CCP_ALLOCATED) {
  872. WanDeallocateCCP(BundleCB,
  873. &BundleCB->RecvCompInfo,
  874. FALSE);
  875. BundleCB->Flags &= ~RECV_CCP_ALLOCATED;
  876. }
  877. if (BundleCB->Flags & SEND_ECP_ALLOCATED) {
  878. WanDeallocateECP(BundleCB,
  879. &BundleCB->SendCompInfo,
  880. &BundleCB->SendCryptoInfo);
  881. BundleCB->Flags &= ~SEND_ECP_ALLOCATED;
  882. }
  883. if (BundleCB->Flags & RECV_ECP_ALLOCATED) {
  884. WanDeallocateECP(BundleCB,
  885. &BundleCB->RecvCompInfo,
  886. &BundleCB->RecvCryptoInfo);
  887. BundleCB->Flags &= ~RECV_ECP_ALLOCATED;
  888. }
  889. if (BundleCB->BonDAllocation != NULL) {
  890. NdisWanFreeMemory(BundleCB->BonDAllocation);
  891. BundleCB->BonDAllocation = NULL;
  892. }
  893. BundleCB->State = BUNDLE_DOWN;
  894. NdisFreeSpinLock(&BundleCB->Lock);
  895. NdisWanFreeNdisString(&BundleCB->IoProtocolCB->InDeviceName);
  896. NdisFreeToNPagedLookasideList(&BundleCBList, BundleCB);
  897. }
  898. NDIS_STATUS
  899. NdisWanCreateProtocolInfoTable(
  900. VOID
  901. )
  902. /*++
  903. Routine Name:
  904. Routine Description:
  905. Arguments:
  906. Return Values:
  907. --*/
  908. {
  909. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  910. ULONG ulAllocationSize = 0;
  911. PUCHAR AllocatedMemory;
  912. PROTOCOL_INFO ProtocolInfo;
  913. //
  914. // Allocate ProtocolLookupTable. This table is used to match protocol values
  915. // with their corresponding PPP Protocol values. The table size is set to
  916. // MAX_PROTOCOLS.
  917. //
  918. ulAllocationSize = sizeof(PROTOCOL_INFO_TABLE) +
  919. (sizeof(PROTOCOL_INFO) * MAX_PROTOCOLS);
  920. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize, PROTOCOLTABLE_TAG);
  921. if (AllocatedMemory == NULL) {
  922. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  923. ("Failed allocating memory for ProtocolLookupTable! TableSize: %d",
  924. ulAllocationSize));
  925. return (NDIS_STATUS_RESOURCES);
  926. }
  927. ProtocolInfoTable = (PPROTOCOL_INFO_TABLE)AllocatedMemory;
  928. //
  929. // Save the allocation size
  930. //
  931. ProtocolInfoTable->ulAllocationSize = ulAllocationSize;
  932. //
  933. // Store the array size. This should be read from the registry
  934. //
  935. ProtocolInfoTable->ulArraySize = MAX_PROTOCOLS;
  936. NdisAllocateSpinLock(&ProtocolInfoTable->Lock);
  937. //
  938. // Setup the pointer to the ProtocolValue array
  939. //
  940. AllocatedMemory += sizeof(PROTOCOL_INFO_TABLE);
  941. ProtocolInfoTable->ProtocolInfo = (PPROTOCOL_INFO)(AllocatedMemory);
  942. //
  943. // Insert default values for Netbuei, IP, IPX
  944. //
  945. ProtocolInfo.ProtocolType = PROTOCOL_PRIVATE_IO;
  946. ProtocolInfo.PPPId = PPP_PROTOCOL_PRIVATE_IO;
  947. ProtocolInfo.MTU = DEFAULT_MTU;
  948. ProtocolInfo.TunnelMTU = DEFAULT_MTU;
  949. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  950. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  951. SetProtocolInfo(&ProtocolInfo);
  952. ProtocolInfo.ProtocolType = PROTOCOL_IP;
  953. ProtocolInfo.PPPId = PPP_PROTOCOL_IP;
  954. ProtocolInfo.MTU = DEFAULT_MTU;
  955. ProtocolInfo.TunnelMTU = DEFAULT_TUNNEL_MTU;
  956. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  957. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  958. SetProtocolInfo(&ProtocolInfo);
  959. ProtocolInfo.ProtocolType = PROTOCOL_IPX;
  960. ProtocolInfo.PPPId = PPP_PROTOCOL_IPX;
  961. ProtocolInfo.MTU = DEFAULT_MTU;
  962. ProtocolInfo.TunnelMTU = DEFAULT_MTU;
  963. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  964. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  965. SetProtocolInfo(&ProtocolInfo);
  966. ProtocolInfo.ProtocolType = PROTOCOL_NBF;
  967. ProtocolInfo.PPPId = PPP_PROTOCOL_NBF;
  968. ProtocolInfo.MTU = DEFAULT_MTU;
  969. ProtocolInfo.TunnelMTU = DEFAULT_MTU;
  970. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  971. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  972. SetProtocolInfo(&ProtocolInfo);
  973. ProtocolInfo.ProtocolType = PROTOCOL_APPLETALK;
  974. ProtocolInfo.PPPId = PPP_PROTOCOL_APPLETALK;
  975. ProtocolInfo.MTU = DEFAULT_MTU;
  976. ProtocolInfo.TunnelMTU = DEFAULT_MTU;
  977. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  978. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  979. SetProtocolInfo(&ProtocolInfo);
  980. return (Status);
  981. }
  982. VOID
  983. NdisWanDestroyProtocolInfoTable(
  984. VOID
  985. )
  986. /*++
  987. Routine Name:
  988. Routine Description:
  989. Arguments:
  990. Return Values:
  991. --*/
  992. {
  993. NdisFreeSpinLock(&ProtocolInfoTable->Lock);
  994. NdisWanFreeMemory(ProtocolInfoTable);
  995. }
  996. NDIS_STATUS
  997. NdisWanCreateConnectionTable(
  998. ULONG TableSize
  999. )
  1000. /*++
  1001. Routine Name:
  1002. Routine Description:
  1003. Arguments:
  1004. Return Values:
  1005. --*/
  1006. {
  1007. ULONG ulAllocationSize = 0;
  1008. ULONG ulArraySize;
  1009. PUCHAR AllocatedMemory;
  1010. PCONNECTION_TABLE NewTable;
  1011. //
  1012. // Since we skip the first place in the tables we increase the
  1013. // size by one.
  1014. //
  1015. ulArraySize = TableSize + 1;
  1016. //
  1017. // Allocate the Bundle and Link Arrays based on the number of possible connections
  1018. // that we have in the system. This should be grown if we get called
  1019. // to reinitialize and gain new ports.
  1020. //
  1021. ulAllocationSize = sizeof(CONNECTION_TABLE) +
  1022. (sizeof(PBUNDLECB) * ulArraySize) +
  1023. (sizeof(PLINKCB) * ulArraySize);
  1024. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize, CONNECTIONTABLE_TAG);
  1025. if (AllocatedMemory == NULL) {
  1026. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1027. ("Failed allocating memory for ConnectionTable! Size: %d, Links: %d",
  1028. ulAllocationSize, TableSize));
  1029. return (NDIS_STATUS_RESOURCES);
  1030. }
  1031. NewTable = (PCONNECTION_TABLE)AllocatedMemory;
  1032. //
  1033. // This is the amount of memory we allocated
  1034. //
  1035. NewTable->ulAllocationSize = ulAllocationSize;
  1036. NewTable->ulArraySize = TableSize;
  1037. NewTable->ulNextLink =
  1038. NewTable->ulNextBundle = 1;
  1039. InitializeListHead(&NewTable->BundleList);
  1040. InitializeListHead(&NewTable->LinkList);
  1041. //
  1042. // Setup pointer to the linkcb array
  1043. //
  1044. AllocatedMemory += sizeof(CONNECTION_TABLE);
  1045. NewTable->LinkArray = (PLINKCB*)(AllocatedMemory);
  1046. //
  1047. // Setup the pointer to the bundlecb array
  1048. //
  1049. AllocatedMemory += (sizeof(PLINKCB) * ulArraySize);
  1050. NewTable->BundleArray = (PBUNDLECB*)(AllocatedMemory);
  1051. if (ConnectionTable != NULL) {
  1052. PCONNECTION_TABLE FreeTable;
  1053. //
  1054. // We must be growing the table. This will be
  1055. // called with the current connectiontable lock
  1056. // held!
  1057. //
  1058. NewTable->ulNumActiveLinks = ConnectionTable->ulNumActiveLinks;
  1059. NewTable->ulNumActiveBundles = ConnectionTable->ulNumActiveBundles;
  1060. NewTable->ulNextLink = ConnectionTable->ulNextLink;
  1061. NewTable->ulNextBundle = ConnectionTable->ulNextBundle;
  1062. NdisMoveMemory((PUCHAR)NewTable->LinkArray,
  1063. (PUCHAR)ConnectionTable->LinkArray,
  1064. ConnectionTable->ulArraySize * sizeof(PLINKCB));
  1065. NdisMoveMemory((PUCHAR)NewTable->BundleArray,
  1066. (PUCHAR)ConnectionTable->BundleArray,
  1067. ConnectionTable->ulArraySize * sizeof(PBUNDLECB));
  1068. while (!IsListEmpty(&ConnectionTable->BundleList)) {
  1069. PBUNDLECB BundleCB;
  1070. BundleCB = (PBUNDLECB)RemoveHeadList(&ConnectionTable->BundleList);
  1071. InsertTailList(&NewTable->BundleList, &BundleCB->Linkage);
  1072. }
  1073. while (!IsListEmpty(&ConnectionTable->LinkList)) {
  1074. PLIST_ENTRY Entry;
  1075. PLINKCB LinkCB;
  1076. Entry = RemoveHeadList(&ConnectionTable->LinkList);
  1077. LinkCB =
  1078. (PLINKCB)CONTAINING_RECORD(Entry, LINKCB, ConnTableLinkage);
  1079. InsertTailList(&NewTable->LinkList, &LinkCB->ConnTableLinkage);
  1080. }
  1081. FreeTable = ConnectionTable;
  1082. ConnectionTable = NewTable;
  1083. //
  1084. // Destroy the old table
  1085. //
  1086. NdisWanFreeMemory(FreeTable);
  1087. } else {
  1088. ConnectionTable = NewTable;
  1089. }
  1090. return (NDIS_STATUS_SUCCESS);
  1091. }
  1092. PNDIS_PACKET
  1093. NdisWanAllocateNdisPacket(
  1094. ULONG MagicNumber
  1095. )
  1096. {
  1097. PNDIS_PACKET ReturnPacket = NULL;
  1098. PPOOL_DESC PoolDesc;
  1099. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1100. ULONG i;
  1101. PSINGLE_LIST_ENTRY p = NULL;
  1102. PNDISWAN_PROTOCOL_RESERVED pres;
  1103. NdisAcquireSpinLock(&PacketPoolList.Lock);
  1104. //
  1105. // Walk the pool desc list and try to allocate a packet
  1106. //
  1107. PoolDesc = (PPOOL_DESC)PacketPoolList.List.Flink;
  1108. while (PoolDesc != (PPOOL_DESC)&PacketPoolList.List) {
  1109. p = PopEntryList(&PoolDesc->Head);
  1110. if (p != NULL) {
  1111. break;
  1112. }
  1113. PoolDesc = (PPOOL_DESC)PoolDesc->Linkage.Flink;
  1114. }
  1115. if (p == NULL) {
  1116. //
  1117. // We have walked the pool list and did not find any
  1118. // free packets on any of the free pools, so allocate
  1119. // a new pool and get a packet from it.
  1120. //
  1121. NdisWanAllocatePriorityMemory(&PoolDesc,
  1122. sizeof(POOL_DESC),
  1123. POOLDESC_TAG,
  1124. NormalPoolPriority);
  1125. if (PoolDesc == NULL) {
  1126. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1127. return (NULL);
  1128. }
  1129. NdisAllocatePacketPoolEx(&Status,
  1130. &PoolDesc->PoolHandle,
  1131. glPacketPoolCount,
  1132. 0,
  1133. sizeof(NDISWAN_PROTOCOL_RESERVED));
  1134. if (Status != NDIS_STATUS_SUCCESS) {
  1135. NdisWanFreeMemory(PoolDesc);
  1136. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1137. return (NULL);
  1138. }
  1139. for (i = 0; i < glPacketPoolCount; i++) {
  1140. PNDIS_PACKET np;
  1141. NdisAllocatePacket(&Status,
  1142. &np,
  1143. PoolDesc->PoolHandle);
  1144. ASSERT(np != NULL);
  1145. pres = PPROTOCOL_RESERVED_FROM_NDIS(np);
  1146. PushEntryList(&PoolDesc->Head, &pres->SLink);
  1147. PoolDesc->FreeCount++;
  1148. }
  1149. InsertTailList(&PacketPoolList.List, &PoolDesc->Linkage);
  1150. PacketPoolList.TotalDescCount++;
  1151. PacketPoolList.FreeCount += PoolDesc->FreeCount;
  1152. if (PacketPoolList.TotalDescCount >
  1153. PacketPoolList.MaxDescCount) {
  1154. PacketPoolList.MaxDescCount = PacketPoolList.TotalDescCount;
  1155. }
  1156. p = PopEntryList(&PoolDesc->Head);
  1157. }
  1158. ASSERT(p != NULL);
  1159. pres = CONTAINING_RECORD(p, NDISWAN_PROTOCOL_RESERVED, SLink);
  1160. ReturnPacket = CONTAINING_RECORD(pres, NDIS_PACKET, ProtocolReserved);
  1161. NdisReinitializePacket(ReturnPacket);
  1162. PoolDesc->AllocatedCount++;
  1163. PoolDesc->FreeCount--;
  1164. ASSERT((PoolDesc->AllocatedCount + PoolDesc->FreeCount) == glPacketPoolCount);
  1165. if (PoolDesc->AllocatedCount >
  1166. PoolDesc->MaxAllocatedCount) {
  1167. PoolDesc->MaxAllocatedCount =
  1168. PoolDesc->AllocatedCount;
  1169. }
  1170. PacketPoolList.AllocatedCount++;
  1171. PacketPoolList.FreeCount--;
  1172. #if DBG
  1173. {
  1174. PPOOL_DESC pdesc;
  1175. ULONG FreeCount, AllocatedCount;
  1176. pdesc = (PPOOL_DESC)PacketPoolList.List.Flink;
  1177. FreeCount = AllocatedCount = 0;
  1178. while ((PVOID)pdesc != (PVOID)&PacketPoolList.List) {
  1179. FreeCount += pdesc->FreeCount;
  1180. AllocatedCount += pdesc->AllocatedCount;
  1181. pdesc = (PPOOL_DESC)pdesc->Linkage.Flink;
  1182. }
  1183. if (PacketPoolList.AllocatedCount != AllocatedCount ||
  1184. PacketPoolList.FreeCount != FreeCount){
  1185. DbgPrint("NDISWAN: AllocatePacket - PacketPool counts out of sync!\n");
  1186. DbgBreakPoint();
  1187. }
  1188. #if 0
  1189. if (PacketPoolList.AllocatedCount > 200) {
  1190. DbgPrint("NDISWAN: AllocatePacket - Over 200 outstanding packets!\n");
  1191. DbgBreakPoint();
  1192. }
  1193. #endif
  1194. }
  1195. #endif
  1196. if (PacketPoolList.AllocatedCount >
  1197. PacketPoolList.MaxAllocatedCount) {
  1198. PacketPoolList.MaxAllocatedCount =
  1199. PacketPoolList.AllocatedCount;
  1200. }
  1201. pres->MagicNumber = MagicNumber;
  1202. pres->PoolDesc = PoolDesc;
  1203. NDIS_SET_PACKET_HEADER_SIZE(ReturnPacket,
  1204. MAC_HEADER_LENGTH);
  1205. NDIS_SET_PACKET_STATUS(ReturnPacket,
  1206. NDIS_STATUS_SUCCESS);
  1207. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1208. return (ReturnPacket);
  1209. }
  1210. VOID
  1211. NdisWanFreeNdisPacket(
  1212. PNDIS_PACKET NdisPacket
  1213. )
  1214. {
  1215. PNDISWAN_PROTOCOL_RESERVED pres;
  1216. PPOOL_DESC PoolDesc;
  1217. PNDIS_BUFFER NdisBuffer;
  1218. PUCHAR DataBuffer;
  1219. pres = PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket);
  1220. ASSERT(pres->MagicNumber == MAGIC_INTERNAL_ALLOC ||
  1221. pres->MagicNumber == MAGIC_INTERNAL_IO ||
  1222. pres->MagicNumber == MAGIC_INTERNAL_SEND ||
  1223. pres->MagicNumber == MAGIC_INTERNAL_RECV ||
  1224. pres->MagicNumber == MAGIC_INTERNAL_ALLOC);
  1225. PoolDesc = pres->PoolDesc;
  1226. NdisAcquireSpinLock(&PacketPoolList.Lock);
  1227. #if DBG
  1228. {
  1229. PPOOL_DESC pdesc;
  1230. pdesc = (PPOOL_DESC)PacketPoolList.List.Flink;
  1231. while ((PVOID)pdesc != (PVOID)&PacketPoolList.List) {
  1232. if (PoolDesc == pdesc) {
  1233. //
  1234. // We found the correct pool
  1235. //
  1236. break;
  1237. }
  1238. pdesc = (PPOOL_DESC)pdesc->Linkage.Flink;
  1239. }
  1240. if((PVOID)PoolDesc == (PVOID)&PacketPoolList.List){
  1241. DbgPrint("NDISWAN: FreePacket PoolDesc %x not on PacketPoolList!\n",
  1242. PoolDesc);
  1243. DbgBreakPoint();
  1244. }
  1245. }
  1246. #endif
  1247. PushEntryList(&PoolDesc->Head, &pres->SLink);
  1248. PoolDesc->AllocatedCount--;
  1249. PoolDesc->FreeCount++;
  1250. ASSERT((PoolDesc->AllocatedCount + PoolDesc->FreeCount) == glPacketPoolCount);
  1251. PacketPoolList.AllocatedCount--;
  1252. PacketPoolList.FreeCount++;
  1253. #if DBG
  1254. {
  1255. PPOOL_DESC pdesc;
  1256. ULONG FreeCount, AllocatedCount;
  1257. pdesc = (PPOOL_DESC)PacketPoolList.List.Flink;
  1258. FreeCount = AllocatedCount = 0;
  1259. while ((PVOID)pdesc != (PVOID)&PacketPoolList.List) {
  1260. FreeCount += pdesc->FreeCount;
  1261. AllocatedCount += pdesc->AllocatedCount;
  1262. pdesc = (PPOOL_DESC)pdesc->Linkage.Flink;
  1263. }
  1264. if (PacketPoolList.AllocatedCount != AllocatedCount ||
  1265. PacketPoolList.FreeCount != FreeCount){
  1266. DbgPrint("NDISWAN: FreePacket - PacketPool counts out of sync!\n");
  1267. DbgBreakPoint();
  1268. }
  1269. }
  1270. #endif
  1271. //
  1272. // If all of the packets have been returned to this pool desc
  1273. // and this is not the only pool desc then free it!
  1274. //
  1275. if (PoolDesc->AllocatedCount == 0 &&
  1276. PacketPoolList.TotalDescCount > 1 &&
  1277. PacketPoolList.FreeCount > PoolDesc->FreeCount) {
  1278. PSINGLE_LIST_ENTRY p = NULL;
  1279. RemoveEntryList(&PoolDesc->Linkage);
  1280. PacketPoolList.TotalDescCount--;
  1281. PacketPoolList.FreeCount -= PoolDesc->FreeCount;
  1282. p = PopEntryList(&PoolDesc->Head);
  1283. while (p != NULL) {
  1284. PNDIS_PACKET ReturnPacket;
  1285. pres = CONTAINING_RECORD(p, NDISWAN_PROTOCOL_RESERVED, SLink);
  1286. ReturnPacket = CONTAINING_RECORD(pres, NDIS_PACKET, ProtocolReserved);
  1287. NdisFreePacket(ReturnPacket);
  1288. p = PopEntryList(&PoolDesc->Head);
  1289. }
  1290. NdisFreePacketPool(PoolDesc->PoolHandle);
  1291. NdisWanFreeMemory(PoolDesc);
  1292. }
  1293. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1294. }
  1295. PVOID
  1296. AllocateDataDesc(
  1297. POOL_TYPE PoolType,
  1298. SIZE_T NumberOfBytes,
  1299. ULONG Tag
  1300. )
  1301. /*++
  1302. Routine Name:
  1303. AllocateDataDesc
  1304. Routine Description:
  1305. This routine is called by the lookasidelist manager if there are not
  1306. any descriptors available. It will allocated memory for: DATA_DESC,
  1307. NDIS_BUFFER, NDIS_PACKET, and a block of memory of size.
  1308. Arguments:
  1309. Return Values:
  1310. --*/
  1311. {
  1312. PDATA_DESC DataDesc;
  1313. PUCHAR DataBuffer;
  1314. NDIS_STATUS Status;
  1315. NdisWanAllocatePriorityMemory(&DataDesc,
  1316. NumberOfBytes,
  1317. Tag,
  1318. NormalPoolPriority);
  1319. if (DataDesc == NULL) {
  1320. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1321. ("AllocateDataDesc failed! Size %d",
  1322. NumberOfBytes));
  1323. return (NULL);
  1324. }
  1325. DataBuffer =
  1326. ((PUCHAR)(DataDesc + 1) + sizeof(PVOID));
  1327. (ULONG_PTR)DataBuffer &=
  1328. ~((ULONG_PTR)sizeof(PVOID) - 1);
  1329. DataDesc->DataBuffer = DataBuffer;
  1330. DataDesc->DataBufferLength =
  1331. (ULONG)(((PUCHAR)DataDesc + NumberOfBytes) - DataBuffer);
  1332. // This is not portable to Win95! I need to allocate a buffer
  1333. // pool and use a valid handle.
  1334. //
  1335. NdisAllocateBuffer(&Status,
  1336. &DataDesc->NdisBuffer,
  1337. NULL,
  1338. DataDesc->DataBuffer,
  1339. DataDesc->DataBufferLength);
  1340. if (Status != NDIS_STATUS_SUCCESS) {
  1341. NdisWanFreeMemory(DataDesc);
  1342. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1343. ("NdisAllocateBuffer failed! DataBufferSize %d",
  1344. DataDesc->DataBufferLength));
  1345. return (NULL);
  1346. }
  1347. DataDesc->NdisPacket =
  1348. NdisWanAllocateNdisPacket(MAGIC_INTERNAL_ALLOC);
  1349. if (DataDesc->NdisPacket == NULL) {
  1350. NdisFreeBuffer(DataDesc->NdisBuffer);
  1351. NdisWanFreeMemory(DataDesc);
  1352. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1353. ("NdisWanAllocateNdisPacket failed! DataBufferSize %d"));
  1354. return (NULL);
  1355. }
  1356. NdisChainBufferAtFront(DataDesc->NdisPacket,
  1357. DataDesc->NdisBuffer);
  1358. return(DataDesc);
  1359. }
  1360. VOID
  1361. FreeDataDesc(
  1362. PVOID Buffer
  1363. )
  1364. /*++
  1365. Routine Name:
  1366. Routine Description:
  1367. Arguments:
  1368. Return Values:
  1369. --*/
  1370. {
  1371. PDATA_DESC DataDesc;
  1372. DataDesc = (PDATA_DESC)Buffer;
  1373. NdisReinitializePacket(DataDesc->NdisPacket);
  1374. NdisWanFreeNdisPacket(DataDesc->NdisPacket);
  1375. NdisFreeBuffer(DataDesc->NdisBuffer);
  1376. NdisWanFreeMemory(Buffer);
  1377. }
  1378. PRECV_DESC
  1379. NdisWanAllocateRecvDesc(
  1380. ULONG SizeNeeded
  1381. )
  1382. /*++
  1383. Routine Name:
  1384. Routine Description:
  1385. Arguments:
  1386. Return Values:
  1387. --*/
  1388. {
  1389. PDATA_DESC DataDesc;
  1390. PRECV_DESC RecvDesc;
  1391. ULONG Length;
  1392. PNPAGED_LOOKASIDE_LIST LookasideList;
  1393. if (SizeNeeded > glLargeDataBufferSize) {
  1394. DbgPrint("NDISWAN: Error Allocating RecvDesc Size %d\n",
  1395. SizeNeeded);
  1396. return (NULL);
  1397. } else if (SizeNeeded > glSmallDataBufferSize) {
  1398. LookasideList = &LargeDataDescList;
  1399. } else {
  1400. LookasideList = &SmallDataDescList;
  1401. }
  1402. DataDesc =
  1403. NdisAllocateFromNPagedLookasideList(LookasideList);
  1404. if (DataDesc == NULL) {
  1405. return (NULL);
  1406. }
  1407. PPROTOCOL_RESERVED_FROM_NDIS(DataDesc->NdisPacket)->MagicNumber =
  1408. MAGIC_INTERNAL_RECV;
  1409. DataDesc->LookasideList = LookasideList;
  1410. RecvDesc = &DataDesc->RecvDesc;
  1411. NdisZeroMemory(RecvDesc, sizeof(RECV_DESC));
  1412. RecvDesc->Signature = RECVDESC_SIG;
  1413. RecvDesc->DataBuffer =
  1414. DataDesc->DataBuffer;
  1415. RecvDesc->NdisBuffer =
  1416. DataDesc->NdisBuffer;
  1417. RecvDesc->NdisPacket =
  1418. DataDesc->NdisPacket;
  1419. NdisQueryBuffer(RecvDesc->NdisBuffer,
  1420. &RecvDesc->StartBuffer,
  1421. &Length);
  1422. RecvDesc->CurrentBuffer =
  1423. RecvDesc->StartBuffer + MAC_HEADER_LENGTH + PROTOCOL_HEADER_LENGTH;
  1424. return (RecvDesc);
  1425. }
  1426. VOID
  1427. NdisWanFreeRecvDesc(
  1428. PRECV_DESC RecvDesc
  1429. )
  1430. /*++
  1431. Routine Name:
  1432. Routine Description:
  1433. Arguments:
  1434. Return Values:
  1435. --*/
  1436. {
  1437. PDATA_DESC DataDesc;
  1438. PNDIS_BUFFER NdisBuffer;
  1439. PNDIS_PACKET NdisPacket;
  1440. PNPAGED_LOOKASIDE_LIST LookasideList;
  1441. if (RecvDesc->OriginalPacket != NULL) {
  1442. NdisReturnPackets(&RecvDesc->OriginalPacket, 1);
  1443. RecvDesc->OriginalPacket = NULL;
  1444. }
  1445. DataDesc =
  1446. CONTAINING_RECORD(RecvDesc, DATA_DESC, RecvDesc);
  1447. NdisBuffer =
  1448. DataDesc->NdisBuffer;
  1449. NdisPacket =
  1450. DataDesc->NdisPacket;
  1451. LookasideList =
  1452. DataDesc->LookasideList;
  1453. #if DBG
  1454. {
  1455. ULONG BufferCount;
  1456. NdisQueryPacket(NdisPacket,
  1457. NULL,
  1458. &BufferCount,
  1459. NULL,
  1460. NULL);
  1461. ASSERT(BufferCount == 1);
  1462. }
  1463. #endif
  1464. NdisAdjustBufferLength(NdisBuffer,
  1465. DataDesc->DataBufferLength);
  1466. NdisRecalculatePacketCounts(NdisPacket);
  1467. NDIS_SET_PACKET_HEADER_SIZE(NdisPacket,
  1468. MAC_HEADER_LENGTH);
  1469. NDIS_SET_PACKET_STATUS(NdisPacket,
  1470. NDIS_STATUS_SUCCESS);
  1471. ASSERT(PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket)->MagicNumber == MAGIC_INTERNAL_RECV);
  1472. NdisFreeToNPagedLookasideList(LookasideList, DataDesc);
  1473. }
  1474. PSEND_DESC
  1475. NdisWanAllocateSendDesc(
  1476. PLINKCB LinkCB,
  1477. ULONG SizeNeeded
  1478. )
  1479. /*++
  1480. Routine Name:
  1481. Routine Description:
  1482. Arguments:
  1483. Return Values:
  1484. --*/
  1485. {
  1486. POPENCB OpenCB;
  1487. PSEND_DESC SendDesc;
  1488. //
  1489. // Need to determine if this link represents a legacy
  1490. // wan miniport or a NDIS 5.0 miniport and get the
  1491. // appropriate buffer descriptor.
  1492. //
  1493. OpenCB = LinkCB->OpenCB;
  1494. if (OpenCB->Flags & OPEN_LEGACY) {
  1495. PDATA_DESC DataDesc;
  1496. PNDIS_WAN_PACKET WanPacket;
  1497. //
  1498. // Get a buffer desriptor off of the open block
  1499. //
  1500. if (OpenCB->WanInfo.MemoryFlags == 0) {
  1501. PNPAGED_LOOKASIDE_LIST LookasideList;
  1502. LookasideList = &OpenCB->WanPacketPool;
  1503. DataDesc =
  1504. NdisAllocateFromNPagedLookasideList(LookasideList);
  1505. if (DataDesc == NULL) {
  1506. return(NULL);
  1507. }
  1508. DataDesc->LookasideList = LookasideList;
  1509. WanPacket = (PNDIS_WAN_PACKET)
  1510. ((PUCHAR)(DataDesc + 1) + sizeof(PVOID));
  1511. (ULONG_PTR)WanPacket &=
  1512. ~((ULONG_PTR)sizeof(PVOID) - 1);
  1513. //
  1514. // Point to the begining of the data.
  1515. //
  1516. WanPacket->StartBuffer =
  1517. ((PUCHAR)(WanPacket + 1) + sizeof(PVOID));
  1518. (ULONG_PTR)WanPacket->StartBuffer &=
  1519. ~((ULONG_PTR)sizeof(PVOID) - 1);
  1520. WanPacket->EndBuffer = WanPacket->StartBuffer +
  1521. OpenCB->BufferSize - sizeof(PVOID);
  1522. } else {
  1523. DataDesc = (PDATA_DESC)
  1524. NdisInterlockedPopEntrySList(&OpenCB->WanPacketList,
  1525. &OpenCB->Lock);
  1526. if (DataDesc == NULL) {
  1527. return (NULL);
  1528. }
  1529. }
  1530. SendDesc = &DataDesc->SendDesc;
  1531. NdisZeroMemory(SendDesc, sizeof(SEND_DESC));
  1532. SendDesc->Signature = SENDESC_SIG;
  1533. SendDesc->LinkCB = LinkCB;
  1534. SendDesc->WanPacket = WanPacket;
  1535. WanPacket->CurrentBuffer =
  1536. WanPacket->StartBuffer + OpenCB->WanInfo.HeaderPadding;
  1537. SendDesc->StartBuffer =
  1538. WanPacket->CurrentBuffer;
  1539. } else {
  1540. PDATA_DESC DataDesc;
  1541. ULONG Length;
  1542. PNPAGED_LOOKASIDE_LIST LookasideList;
  1543. if (SizeNeeded > glLargeDataBufferSize) {
  1544. DbgPrint("NDISWAN: Error Allocating SendDesc Size %d\n",
  1545. SizeNeeded);
  1546. return (NULL);
  1547. } else if (SizeNeeded > glSmallDataBufferSize) {
  1548. LookasideList = &LargeDataDescList;
  1549. } else {
  1550. LookasideList = &SmallDataDescList;
  1551. }
  1552. DataDesc =
  1553. NdisAllocateFromNPagedLookasideList(LookasideList);
  1554. if (DataDesc == NULL) {
  1555. return (NULL);
  1556. }
  1557. DataDesc->LookasideList = LookasideList;
  1558. PPROTOCOL_RESERVED_FROM_NDIS(DataDesc->NdisPacket)->MagicNumber =
  1559. MAGIC_INTERNAL_SEND;
  1560. SendDesc = &DataDesc->SendDesc;
  1561. NdisZeroMemory(SendDesc, sizeof(SEND_DESC));
  1562. SendDesc->Signature = SENDESC_SIG;
  1563. SendDesc->LinkCB = LinkCB;
  1564. SendDesc->NdisPacket =
  1565. DataDesc->NdisPacket;
  1566. SendDesc->NdisBuffer =
  1567. DataDesc->NdisBuffer;
  1568. NdisQueryBuffer(SendDesc->NdisBuffer,
  1569. &SendDesc->StartBuffer,
  1570. &Length);
  1571. }
  1572. LinkCB->SendResources -= 1;
  1573. LinkCB->BundleCB->SendResources -= 1;
  1574. return (SendDesc);
  1575. }
  1576. VOID
  1577. NdisWanFreeSendDesc(
  1578. PSEND_DESC SendDesc
  1579. )
  1580. /*++
  1581. Routine Name:
  1582. Routine Description:
  1583. Arguments:
  1584. Return Values:
  1585. --*/
  1586. {
  1587. POPENCB OpenCB;
  1588. PDATA_DESC DataDesc;
  1589. PLINKCB LinkCB;
  1590. PNPAGED_LOOKASIDE_LIST LookasideList;
  1591. LinkCB =
  1592. SendDesc->LinkCB;
  1593. OpenCB = LinkCB->OpenCB;
  1594. DataDesc =
  1595. CONTAINING_RECORD(SendDesc, DATA_DESC, SendDesc);
  1596. LookasideList = DataDesc->LookasideList;
  1597. if (OpenCB->Flags & OPEN_LEGACY) {
  1598. if (OpenCB->WanInfo.MemoryFlags == 0) {
  1599. NdisFreeToNPagedLookasideList(LookasideList, DataDesc);
  1600. } else {
  1601. NdisInterlockedPushEntrySList(&OpenCB->WanPacketList,
  1602. (PSLIST_ENTRY)DataDesc,
  1603. &OpenCB->Lock);
  1604. }
  1605. } else {
  1606. PNDIS_BUFFER NdisBuffer;
  1607. PNDIS_PACKET NdisPacket;
  1608. NdisBuffer =
  1609. DataDesc->NdisBuffer;
  1610. NdisPacket =
  1611. DataDesc->NdisPacket;
  1612. #if DBG
  1613. {
  1614. ULONG BufferCount;
  1615. NdisQueryPacket(NdisPacket,
  1616. NULL,
  1617. &BufferCount,
  1618. NULL,
  1619. NULL);
  1620. ASSERT(BufferCount == 1);
  1621. }
  1622. #endif
  1623. NdisAdjustBufferLength(NdisBuffer,
  1624. DataDesc->DataBufferLength);
  1625. NdisRecalculatePacketCounts(NdisPacket);
  1626. NDIS_SET_PACKET_HEADER_SIZE(NdisPacket,
  1627. MAC_HEADER_LENGTH);
  1628. NDIS_SET_PACKET_STATUS(NdisPacket,
  1629. NDIS_STATUS_SUCCESS);
  1630. ASSERT(PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket)->MagicNumber == MAGIC_INTERNAL_SEND);
  1631. NdisFreeToNPagedLookasideList(LookasideList, DataDesc);
  1632. }
  1633. LinkCB->SendResources += 1;
  1634. LinkCB->BundleCB->SendResources += 1;
  1635. }
  1636. PCL_AFSAPCB
  1637. NdisWanAllocateClAfSapCB(
  1638. POPENCB OpenCB,
  1639. PCO_ADDRESS_FAMILY AddressFamily
  1640. )
  1641. {
  1642. PCL_AFSAPCB AfSapCB;
  1643. AfSapCB =
  1644. NdisAllocateFromNPagedLookasideList(&AfSapVcCBList);
  1645. if (AfSapCB == NULL) {
  1646. return (NULL);
  1647. }
  1648. NdisZeroMemory(AfSapCB, sizeof(CL_AFSAPCB));
  1649. AfSapCB->Signature = CLAFSAP_SIG;
  1650. AfSapCB->OpenCB = OpenCB;
  1651. AfSapCB->Af.AddressFamily = AddressFamily->AddressFamily;
  1652. AfSapCB->Af.MajorVersion = AddressFamily->MajorVersion;
  1653. AfSapCB->Af.MinorVersion = AddressFamily->MinorVersion;
  1654. AfSapCB->RefCount = 1;
  1655. AfSapCB->Flags = AF_OPENING;
  1656. return (AfSapCB);
  1657. }
  1658. VOID
  1659. NdisWanFreeClAfSapCB(
  1660. PCL_AFSAPCB AfSapCB
  1661. )
  1662. {
  1663. NdisFreeToNPagedLookasideList(&AfSapVcCBList,
  1664. AfSapCB);
  1665. }
  1666. PCM_AFSAPCB
  1667. NdisWanAllocateCmAfSapCB(
  1668. PMINIPORTCB MiniportCB
  1669. )
  1670. {
  1671. PCM_AFSAPCB AfSapCB;
  1672. AfSapCB =
  1673. NdisAllocateFromNPagedLookasideList(&AfSapVcCBList);
  1674. if (AfSapCB == NULL) {
  1675. return (NULL);
  1676. }
  1677. NdisZeroMemory(AfSapCB, sizeof(CM_AFSAPCB));
  1678. AfSapCB->Signature = CMAFSAP_SIG;
  1679. AfSapCB->MiniportCB = MiniportCB;
  1680. REF_MINIPORTCB(MiniportCB);
  1681. NdisAcquireSpinLock(&MiniportCB->Lock);
  1682. InsertHeadList(&MiniportCB->AfSapCBList,
  1683. &AfSapCB->Linkage);
  1684. NdisWanInitializeNotificationEvent(&AfSapCB->NotificationEvent);
  1685. NdisWanInterlockedInc(&MiniportCB->AfRefCount);
  1686. NdisReleaseSpinLock(&MiniportCB->Lock);
  1687. return (AfSapCB);
  1688. }
  1689. VOID
  1690. NdisWanFreeCmAfSapCB(
  1691. PCM_AFSAPCB AfSapCB
  1692. )
  1693. {
  1694. PMINIPORTCB MiniportCB = AfSapCB->MiniportCB;
  1695. NdisAcquireSpinLock(&MiniportCB->Lock);
  1696. NdisWanInterlockedDec(&MiniportCB->AfRefCount);
  1697. RemoveEntryList(&AfSapCB->Linkage);
  1698. NdisReleaseSpinLock(&MiniportCB->Lock);
  1699. DEREF_MINIPORTCB(MiniportCB);
  1700. NdisFreeToNPagedLookasideList(&AfSapVcCBList,
  1701. AfSapCB);
  1702. }
  1703. PCM_VCCB
  1704. NdisWanAllocateCmVcCB(
  1705. PCM_AFSAPCB AfSapCB,
  1706. NDIS_HANDLE NdisVcHandle
  1707. )
  1708. {
  1709. PCM_VCCB CmVcCB;
  1710. CmVcCB =
  1711. NdisAllocateFromNPagedLookasideList(&AfSapVcCBList);
  1712. if (CmVcCB == NULL) {
  1713. return (NULL);
  1714. }
  1715. NdisZeroMemory(CmVcCB, sizeof(CM_VCCB));
  1716. CmVcCB->AfSapCB = AfSapCB;
  1717. CmVcCB->Signature = CMVC_SIG;
  1718. CmVcCB->NdisVcHandle = NdisVcHandle;
  1719. return (CmVcCB);
  1720. }
  1721. VOID
  1722. NdisWanFreeCmVcCB(
  1723. PCM_VCCB CmVcCB
  1724. )
  1725. {
  1726. NdisFreeToNPagedLookasideList(&AfSapVcCBList, CmVcCB);
  1727. }
  1728. NDIS_STATUS
  1729. AllocateIoNdisPacket(
  1730. ULONG SizeNeeded,
  1731. PNDIS_PACKET *NdisPacket,
  1732. PNDIS_BUFFER *NdisBuffer,
  1733. PUCHAR *DataBuffer
  1734. )
  1735. /*++
  1736. Routine Name:
  1737. AllocateIoNdisPacket
  1738. Routine Description:
  1739. This routine will alocate a packet used to send a PPP control
  1740. packet over a wan endpoint. The routine is written with the
  1741. assumption that there will only ever be a single NDIS_BUFFER
  1742. attached to the packet. This buffer is attached immediately
  1743. to the front of the packet. Before calling a miniport the
  1744. NDIS_BUFFER must have it's length adjusted and the packet must
  1745. recalculate all counts.
  1746. Arguments:
  1747. Return Values:
  1748. --*/
  1749. {
  1750. PDATA_DESC DataDesc;
  1751. ULONG Length;
  1752. PNPAGED_LOOKASIDE_LIST LookasideList;
  1753. if (SizeNeeded > glLargeDataBufferSize) {
  1754. DbgPrint("NDISWAN: Error Allocating IoNdisPacket Size %d\n",
  1755. SizeNeeded);
  1756. return (NDIS_STATUS_FAILURE);
  1757. } else if (SizeNeeded > glSmallDataBufferSize) {
  1758. LookasideList = &LargeDataDescList;
  1759. } else {
  1760. LookasideList = &SmallDataDescList;
  1761. }
  1762. DataDesc =
  1763. NdisAllocateFromNPagedLookasideList(LookasideList);
  1764. if (DataDesc == NULL) {
  1765. return (NDIS_STATUS_RESOURCES);
  1766. }
  1767. DataDesc->LookasideList = LookasideList;
  1768. *NdisPacket =
  1769. DataDesc->NdisPacket;
  1770. PPROTOCOL_RESERVED_FROM_NDIS(DataDesc->NdisPacket)->MagicNumber =
  1771. MAGIC_INTERNAL_IO;
  1772. PPROTOCOL_RESERVED_FROM_NDIS(DataDesc->NdisPacket)->DataDesc =
  1773. DataDesc;
  1774. *NdisBuffer =
  1775. DataDesc->NdisBuffer;
  1776. NdisQueryBuffer(DataDesc->NdisBuffer,
  1777. &DataDesc->DataBuffer,
  1778. &Length);
  1779. *DataBuffer =
  1780. DataDesc->DataBuffer;
  1781. return (NDIS_STATUS_SUCCESS);
  1782. }
  1783. VOID
  1784. FreeIoNdisPacket(
  1785. PNDIS_PACKET NdisPacket
  1786. )
  1787. /*++
  1788. Routine Name:
  1789. FreeIoNdisPacket
  1790. Routine Description:
  1791. This routine will free a packet used to send a PPP control
  1792. packet over a wan endpoint. The routine is written with the
  1793. assumption that there will only ever be a single NDIS_BUFFER
  1794. attached to the packet. This buffer does not have to be
  1795. explicitly removed from the packet here as a pointer to it
  1796. is stored in the DATA_DESC itself and will be freed when
  1797. the DATA_DESC is freed.
  1798. Arguments:
  1799. Return Values:
  1800. --*/
  1801. {
  1802. PDATA_DESC DataDesc;
  1803. PNDIS_BUFFER NdisBuffer;
  1804. PNPAGED_LOOKASIDE_LIST LookasideList;
  1805. DataDesc =
  1806. PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket)->DataDesc;
  1807. ASSERT(PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket)->MagicNumber == MAGIC_INTERNAL_IO);
  1808. LookasideList =
  1809. DataDesc->LookasideList;
  1810. NdisAdjustBufferLength(DataDesc->NdisBuffer,
  1811. DataDesc->DataBufferLength);
  1812. NdisRecalculatePacketCounts(NdisPacket);
  1813. NDIS_SET_PACKET_HEADER_SIZE(NdisPacket,
  1814. MAC_HEADER_LENGTH);
  1815. NDIS_SET_PACKET_STATUS(NdisPacket,
  1816. NDIS_STATUS_SUCCESS);
  1817. NdisFreeToNPagedLookasideList(LookasideList, DataDesc);
  1818. }
  1819. PVOID
  1820. AllocateWanPacket(
  1821. IN POOL_TYPE PoolType,
  1822. IN SIZE_T NumberOfBytes,
  1823. IN ULONG Tag
  1824. )
  1825. {
  1826. PVOID pMem;
  1827. NdisWanAllocatePriorityMemory(&pMem,
  1828. NumberOfBytes,
  1829. Tag,
  1830. NormalPoolPriority);
  1831. return(pMem);
  1832. }
  1833. VOID
  1834. FreeWanPacket(
  1835. PVOID WanPacket
  1836. )
  1837. {
  1838. NdisWanFreeMemory(WanPacket);
  1839. }