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.

251 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. util.c
  5. Abstract:
  6. This file contains the code for misc. functions.
  7. Author:
  8. Jameel Hyder (jameelh@microsoft.com) July 1996
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. --*/
  13. #include <precomp.h>
  14. #define _FILENUM_ FILENUM_UTIL
  15. #if DBG
  16. PVOID
  17. ArpSAllocMem(
  18. IN UINT Size,
  19. IN ULONG FileLine,
  20. IN ULONG Tag,
  21. IN BOOLEAN Paged
  22. )
  23. {
  24. PVOID pMem;
  25. pMem = ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool, Size, Tag);
  26. #if _DBG
  27. DBGPRINT(DBG_LEVEL_INFO,
  28. ("ArpSAllocMem: %d bytes (%sPaged) from %lx -> %lx\n",
  29. Size, Paged ? "" : "Non", FileLine, pMem));
  30. #endif
  31. return pMem;
  32. }
  33. VOID
  34. ArpSFreeMem(
  35. IN PVOID pMem,
  36. IN ULONG FileLine
  37. )
  38. {
  39. #if _DBG
  40. DBGPRINT(DBG_LEVEL_INFO,
  41. ("ArpSFreeMem: %lx from %lx\n", FileLine, pMem));
  42. #endif
  43. ExFreePool(pMem);
  44. }
  45. #endif
  46. PVOID
  47. ArpSAllocBlock(
  48. IN PINTF pIntF,
  49. IN ENTRY_TYPE EntryType
  50. )
  51. /*++
  52. Routine Description:
  53. Arguments:
  54. Return Value:
  55. --*/
  56. {
  57. PARP_BLOCK ArpBlock;
  58. PENTRY_HDR pBlock;
  59. PHW_ADDR HwAddr;
  60. USHORT Size;
  61. BOOLEAN Paged;
  62. #if 0
  63. // arvindm - used by MARS
  64. ARPS_PAGED_CODE( );
  65. #endif
  66. ASSERT (EntryType < ARP_BLOCK_TYPES);
  67. pBlock = NULL;
  68. //
  69. // If the block head has no free entries then there are none !!
  70. // Pick the right block based on whether it is file or dir
  71. //
  72. Size = ArpSEntrySize[EntryType];
  73. Paged = ArpSBlockIsPaged[EntryType];
  74. ArpBlock = pIntF->PartialArpBlocks[EntryType];
  75. if (ArpBlock == NULL)
  76. {
  77. DBGPRINT(DBG_LEVEL_INFO,
  78. ("ArpSAllocBlock: ... and allocating a new block for EntryType %ld\n", EntryType));
  79. ArpBlock = Paged ? (PARP_BLOCK)ALLOC_PG_MEM(BLOCK_ALLOC_SIZE) :
  80. (PARP_BLOCK)ALLOC_NP_MEM(BLOCK_ALLOC_SIZE, POOL_TAG_BLK);
  81. if (ArpBlock != NULL)
  82. {
  83. USHORT i;
  84. USHORT Cnt;
  85. DBGPRINT(DBG_LEVEL_WARN,
  86. ("ArpSAllocBlock: Allocated a new block for EntryType %d\n", EntryType));
  87. //
  88. // Link it in the list
  89. //
  90. ArpBlock->IntF = pIntF;
  91. ArpBlock->EntryType = EntryType;
  92. ArpBlock->NumFree = Cnt = ArpSNumEntriesInBlock[EntryType];
  93. LinkDoubleAtHead(pIntF->PartialArpBlocks[EntryType], ArpBlock);
  94. //
  95. // Initialize the list of free entries
  96. //
  97. for (i = 0, pBlock = ArpBlock->FreeHead = (PENTRY_HDR)((PUCHAR)ArpBlock + sizeof(ARP_BLOCK));
  98. i < Cnt;
  99. i++, pBlock = pBlock->Next)
  100. {
  101. HwAddr = (PHW_ADDR)(pBlock + 1);
  102. pBlock->Next = (i == (Cnt - 1)) ? NULL : ((PUCHAR)pBlock + Size);
  103. HwAddr->SubAddress = NULL;
  104. if ((EntryType == ARP_BLOCK_SUBADDR) || (EntryType == MARS_CLUSTER_SUBADDR))
  105. HwAddr->SubAddress = (PATM_ADDRESS)((PUCHAR)pBlock+Size);
  106. }
  107. }
  108. }
  109. else
  110. {
  111. ASSERT(ArpBlock->NumFree <= ArpSNumEntriesInBlock[EntryType]);
  112. ASSERT(ArpBlock->NumFree > 0);
  113. DBGPRINT(DBG_LEVEL_INFO,
  114. ("ArpSAllocBlock: Found space in Block %lx\n", ArpBlock));
  115. }
  116. if (ArpBlock != NULL)
  117. {
  118. PARP_BLOCK pTmp;
  119. pBlock = ArpBlock->FreeHead;
  120. ArpBlock->FreeHead = pBlock->Next;
  121. ArpBlock->NumFree --;
  122. ZERO_MEM(pBlock, Size);
  123. if ((EntryType == ARP_BLOCK_SUBADDR) || (EntryType == MARS_CLUSTER_SUBADDR))
  124. {
  125. HwAddr = (PHW_ADDR)(pBlock + 1);
  126. HwAddr->SubAddress = (PATM_ADDRESS)((PUCHAR)pBlock + Size);
  127. }
  128. //
  129. // If the block is now empty (completely used), unlink it from here and move it
  130. // to the Used list.
  131. //
  132. if (ArpBlock->NumFree == 0)
  133. {
  134. UnlinkDouble(ArpBlock);
  135. LinkDoubleAtHead(pIntF->UsedArpBlocks[EntryType], ArpBlock)
  136. }
  137. }
  138. return pBlock;
  139. }
  140. VOID
  141. ArpSFreeBlock(
  142. IN PVOID pBlock
  143. )
  144. /*++
  145. Routine Description:
  146. Arguments:
  147. Return Value:
  148. --*/
  149. {
  150. PARP_BLOCK ArpBlock;
  151. #if 0
  152. // arvindm - MARS
  153. ARPS_PAGED_CODE( );
  154. #endif
  155. //
  156. // NOTE: The following code *depends* on the fact that we allocate ARP_BLOCKs as
  157. // single page blocks and also that these are allocated *at* page boundaries
  158. // This lets us *cheaply* get to the owning ARP_BLOCK from ARP_ENTRY.
  159. //
  160. ArpBlock = (PARP_BLOCK)((ULONG_PTR)pBlock & ~(PAGE_SIZE-1));
  161. ASSERT (ArpBlock->EntryType < ARP_BLOCK_TYPES);
  162. ASSERT(ArpBlock->NumFree < ArpSNumEntriesInBlock[ArpBlock->EntryType]);
  163. DBGPRINT(DBG_LEVEL_INFO,
  164. ("ArpSFreepBlock: Returning pBlock %lx to Block %lx\n", pBlock, ArpBlock));
  165. ArpBlock->NumFree ++;
  166. ((PENTRY_HDR)pBlock)->Next = ArpBlock->FreeHead;
  167. ArpBlock->FreeHead = pBlock;
  168. if (ArpBlock->NumFree == 1)
  169. {
  170. //
  171. // The block is now partially free (was completely used). Move it to the partial list
  172. //
  173. UnlinkDouble(ArpBlock);
  174. LinkDoubleAtHead(ArpBlock->IntF->PartialArpBlocks[ArpBlock->EntryType], ArpBlock)
  175. }
  176. else if (ArpBlock->NumFree == ArpSNumEntriesInBlock[ArpBlock->EntryType])
  177. {
  178. //
  179. // The block is now completely free (was partially used). Free it.
  180. //
  181. UnlinkDouble(ArpBlock);
  182. FREE_MEM(ArpBlock);
  183. }
  184. }
  185. BOOLEAN
  186. ArpSValidAtmAddress(
  187. IN PATM_ADDRESS AtmAddr,
  188. IN UINT MaxSize
  189. )
  190. {
  191. //
  192. // TODO -- validate
  193. //
  194. return TRUE;
  195. }