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.

236 lines
5.5 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. mdlpool9x.c
  5. Abstract:
  6. This file contains the implementation of an NDIS_BUFFER pool.
  7. Author:
  8. Shaun Cox (shaunco) 11-Nov-1999
  9. --*/
  10. #include "ndis.h"
  11. #include "mdlpool.h"
  12. // The pool structure itself is just a look aside list allocated out of
  13. // non-paged pool.
  14. //
  15. // Each entry in the look aside list is an NDIS_BUFFER structure followed
  16. // by the buffer itself. We initialize the NDIS_BUFFER structure each
  17. // time we allocate from the look aside list. We need to do this in order
  18. // to properly associate the NDIS_BUFFER with its owning pool. This is not
  19. // possible to do with a custom allocate routine for the look aside list
  20. // because their is no provision for an extra context parameter to the
  21. // look aside allocate function.
  22. //
  23. // ---- Temporary Definitions until ndis.h is updated for Millennium -----
  24. //
  25. typedef struct _XNDIS_BUFFER {
  26. struct _NDIS_BUFFER *Next;
  27. PVOID VirtualAddress;
  28. PVOID Pool;
  29. UINT Length;
  30. UINT Signature;
  31. } XNDIS_BUFFER, *PXNDIS_BUFFER;
  32. __inline
  33. SIZE_T
  34. NDIS_SIZEOF_NDIS_BUFFER(
  35. VOID
  36. )
  37. {
  38. return sizeof(XNDIS_BUFFER);
  39. }
  40. __inline
  41. VOID
  42. NdisInitializeNdisBuffer(
  43. OUT PNDIS_BUFFER Buffer,
  44. IN PVOID Pool,
  45. IN PVOID VirtualAddress,
  46. IN UINT Length
  47. )
  48. {
  49. PXNDIS_BUFFER Internal = (PXNDIS_BUFFER)Buffer;
  50. Internal->Next = 0;
  51. Internal->Pool = Pool;
  52. Internal->VirtualAddress = VirtualAddress;
  53. Internal->Length = Length;
  54. Internal->Signature = 0;
  55. }
  56. __inline
  57. PVOID
  58. NdisGetPoolFromNdisBuffer(
  59. IN PNDIS_BUFFER Buffer
  60. )
  61. {
  62. PXNDIS_BUFFER Internal = (PXNDIS_BUFFER)Buffer;
  63. return Internal->Pool;
  64. }
  65. // ---- End temporary Definitions until ndis.h is updated for Millennium -----
  66. UINT SizeOfNdisBufferStructure;
  67. // Creates a pool of NDIS_BUFFERs built over non-paged pool. Each
  68. // NDIS_BUFFER describes a buffer that is BufferSize bytes long.
  69. // If NULL is not returned, MdpDestroyPool should be called at a later time
  70. // to reclaim the resources used by the pool.
  71. //
  72. // Arguments:
  73. // BufferSize - The size, in bytes, of the buffer that each MDL
  74. // should describe.
  75. // Tag - The pool tag to be used internally for calls to
  76. // ExAllocatePoolWithTag. This allows callers to track
  77. // memory consumption for different pools.
  78. //
  79. // Returns the handle used to identify the pool.
  80. //
  81. // Caller IRQL: [PASSIVE_LEVEL, DISPATCH_LEVEL]
  82. //
  83. HANDLE
  84. MdpCreatePool(
  85. IN USHORT BufferSize,
  86. IN ULONG Tag
  87. )
  88. {
  89. PNPAGED_LOOKASIDE_LIST Lookaside;
  90. ASSERT(BufferSize);
  91. // Cache the constant value of an NDIS_BUFFER structure size to
  92. // avoid calling back into NDIS everytime we want a buffer.
  93. //
  94. if (0 == SizeOfNdisBufferStructure)
  95. {
  96. SizeOfNdisBufferStructure = NDIS_SIZEOF_NDIS_BUFFER();
  97. }
  98. ASSERT(SizeOfNdisBufferStructure);
  99. // Allocate the pool header. This is a look aside list on Millenium.
  100. //
  101. Lookaside = ExAllocatePoolWithTag(
  102. NonPagedPool,
  103. sizeof(NPAGED_LOOKASIDE_LIST),
  104. ' pdM');
  105. if (Lookaside)
  106. {
  107. // The size of the entries allocated by the look aside list are
  108. // the NDIS_BUFFER structure size plus the buffer size requested by
  109. // the caller.
  110. //
  111. ExInitializeNPagedLookasideList(
  112. Lookaside,
  113. NULL,
  114. NULL,
  115. 0,
  116. SizeOfNdisBufferStructure + BufferSize,
  117. Tag,
  118. 0);
  119. }
  120. return Lookaside;
  121. }
  122. // Destroys a pool of NDIS_BUFFERs previously created by a call to
  123. // MdpCreatePool.
  124. //
  125. // Arguments:
  126. // PoolHandle - Handle which identifies the pool being destroyed.
  127. //
  128. // Caller IRQL: [PASSIVE_LEVEL, DISPATCH_LEVEL]
  129. //
  130. VOID
  131. MdpDestroyPool(
  132. IN HANDLE PoolHandle
  133. )
  134. {
  135. ExDeleteNPagedLookasideList(PoolHandle);
  136. }
  137. // Returns an NDIS_BUFFER allocated from a pool. NULL is returned if the
  138. // request could not be granted.
  139. //
  140. // Arguments:
  141. // PoolHandle - Handle which identifies the pool being allocated from.
  142. // Buffer - Address to receive the pointer to the underlying mapped buffer
  143. // described by the MDL.
  144. //
  145. // Caller IRQL: [PASSIVE_LEVEL, DISPATCH_LEVEL]
  146. //
  147. PNDIS_BUFFER
  148. MdpAllocate(
  149. IN HANDLE PoolHandle,
  150. OUT PVOID* Buffer
  151. )
  152. {
  153. PNPAGED_LOOKASIDE_LIST Lookaside;
  154. PNDIS_BUFFER NdisBuffer;
  155. PUCHAR VirtualAddress;
  156. ASSERT(PoolHandle);
  157. Lookaside = (PNPAGED_LOOKASIDE_LIST)PoolHandle;
  158. // Get an item from the look aside list.
  159. //
  160. NdisBuffer = ExAllocateFromNPagedLookasideList(Lookaside);
  161. if (NdisBuffer)
  162. {
  163. // (Re)Initialize it to associate it with the pool handle so that
  164. // we know which look aside list to return it to when it is freed.
  165. //
  166. VirtualAddress = (PUCHAR)NdisBuffer + SizeOfNdisBufferStructure;
  167. NdisInitializeNdisBuffer(
  168. NdisBuffer,
  169. PoolHandle,
  170. VirtualAddress,
  171. Lookaside->L.Size - SizeOfNdisBufferStructure);
  172. *Buffer = VirtualAddress;
  173. }
  174. return NdisBuffer;
  175. }
  176. // Free an NDIS_BUFFER to the pool from which it was allocated.
  177. //
  178. // Arguments:
  179. // NdisBuffer - An NDIS_BUFFER returned from a prior call to MdpAllocate.
  180. //
  181. // Caller IRQL: [PASSIVE_LEVEL, DISPATCH_LEVEL]
  182. //
  183. VOID
  184. MdpFree(
  185. IN PNDIS_BUFFER NdisBuffer
  186. )
  187. {
  188. PNPAGED_LOOKASIDE_LIST Lookaside;
  189. // Locate the owning look aside list for this buffer and return it.
  190. //
  191. Lookaside = NdisGetPoolFromNdisBuffer(NdisBuffer);
  192. ASSERT(Lookaside);
  193. ExFreeToNPagedLookasideList(Lookaside, NdisBuffer);
  194. }