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.

200 lines
4.8 KiB

  1. #include "stdafx.h"
  2. // Tree Memory Allocation structure.
  3. typedef struct _POOLMEMORYBLOCK POOLMEMORYBLOCK, *PPOOLMEMORYBLOCK;
  4. struct _POOLMEMORYBLOCK {
  5. DWORD_PTR Index;
  6. DWORD_PTR Size;
  7. PPOOLMEMORYBLOCK NextBlock;
  8. PPOOLMEMORYBLOCK PrevBlock;
  9. PBYTE RawMemory;
  10. };
  11. typedef struct _POOLHEADER {
  12. PPOOLMEMORYBLOCK PoolHead;
  13. HANDLE Heap;
  14. } POOLHEADER, *PPOOLHEADER;
  15. BOOL
  16. PoolMemAddMemory (
  17. IN POOLHANDLE Handle,
  18. IN DWORD_PTR Size
  19. )
  20. {
  21. PBYTE allocedMemory;
  22. PPOOLMEMORYBLOCK newBlock;
  23. PPOOLHEADER poolHeader = (PPOOLHEADER) Handle;
  24. DWORD_PTR sizeNeeded;
  25. assert(poolHeader != NULL);
  26. //
  27. // Determine size needed and attempt to allocate memory.
  28. //
  29. if (Size + sizeof(POOLMEMORYBLOCK) > POOLMEMORYBLOCKSIZE) {
  30. sizeNeeded = Size + sizeof(POOLMEMORYBLOCK);
  31. }
  32. else {
  33. sizeNeeded = POOLMEMORYBLOCKSIZE;
  34. }
  35. allocedMemory = (unsigned char *) HeapAlloc(poolHeader -> Heap,0,sizeNeeded);
  36. if (allocedMemory) {
  37. //
  38. // Use the beginning of the alloc'ed block as the poolblock structure.
  39. //
  40. newBlock = (PPOOLMEMORYBLOCK) allocedMemory;
  41. newBlock -> Size = sizeNeeded - sizeof(POOLMEMORYBLOCK);
  42. newBlock -> RawMemory = allocedMemory + sizeof(POOLMEMORYBLOCK);
  43. newBlock -> Index = 0;
  44. //
  45. // Link the block into the list.
  46. //
  47. if (poolHeader -> PoolHead) {
  48. poolHeader -> PoolHead -> PrevBlock = newBlock;
  49. }
  50. newBlock -> NextBlock = poolHeader -> PoolHead;
  51. newBlock -> PrevBlock = NULL;
  52. poolHeader -> PoolHead = newBlock;
  53. }
  54. //
  55. // Assuming allocedMemory is non-NULL, we have succeeded.
  56. //
  57. return allocedMemory != NULL;
  58. }
  59. POOLHANDLE
  60. WINAPI
  61. PoolMemInitPool (
  62. )
  63. {
  64. BOOL ableToAddMemory;
  65. PPOOLHEADER header = NULL;
  66. HANDLE procHeap;
  67. procHeap = GetProcessHeap();
  68. //
  69. // Allocate the header of this pool.
  70. //
  71. header = (PPOOLHEADER) HeapAlloc(procHeap,0,sizeof(POOLHEADER));
  72. if (header) {
  73. //
  74. // Allocation was successful. Now, initialize the pool.
  75. //
  76. header -> PoolHead = NULL;
  77. header -> Heap = procHeap;
  78. //
  79. // Actually add some memory to the pool.
  80. //
  81. ableToAddMemory = PoolMemAddMemory(header,0);
  82. if (!ableToAddMemory) {
  83. //
  84. // Unable to add memory to the pool.
  85. //
  86. HeapFree(header -> Heap,0,header);
  87. header = NULL;
  88. }
  89. }
  90. return (POOLHANDLE) header;
  91. }
  92. VOID
  93. WINAPI
  94. PoolMemDestroyPool (
  95. POOLHANDLE Handle
  96. )
  97. {
  98. PPOOLMEMORYBLOCK nextBlock;
  99. PPOOLMEMORYBLOCK blockToFree;
  100. PPOOLHEADER poolHeader;
  101. assert(Handle != NULL);
  102. poolHeader = (PPOOLHEADER) Handle;
  103. //
  104. // Walk the list, freeing as we go.
  105. //
  106. blockToFree = poolHeader -> PoolHead;
  107. while (blockToFree != NULL) {
  108. nextBlock = blockToFree->NextBlock;
  109. HeapFree(poolHeader -> Heap,0,blockToFree);
  110. blockToFree = nextBlock;
  111. }
  112. //
  113. // Also, deallocate the poolheader itself.
  114. //
  115. HeapFree(poolHeader -> Heap,0,poolHeader);
  116. }
  117. PVOID
  118. WINAPI
  119. PoolMemGetAlignedMemory (
  120. IN POOLHANDLE Handle,
  121. IN DWORD_PTR Size,
  122. IN DWORD_PTR AlignSize
  123. )
  124. {
  125. BOOL haveEnoughMemory = TRUE;
  126. PVOID rMemory = NULL;
  127. PPOOLHEADER poolHeader = (PPOOLHEADER) Handle;
  128. PPOOLMEMORYBLOCK currentBlock;
  129. DWORD_PTR sizeNeeded;
  130. DWORD_PTR padLength;
  131. assert(poolHeader != NULL);
  132. currentBlock = poolHeader -> PoolHead;
  133. // Determine if more memory is needed, attempt to add if needed.
  134. sizeNeeded = Size;
  135. if (currentBlock -> Size - currentBlock -> Index < sizeNeeded + AlignSize) {
  136. haveEnoughMemory = PoolMemAddMemory(poolHeader,sizeNeeded + AlignSize);
  137. currentBlock = poolHeader -> PoolHead;
  138. }
  139. // If there is enough memory available, return it.
  140. if (haveEnoughMemory) {
  141. if (AlignSize) {
  142. padLength = (DWORD_PTR) currentBlock + sizeof(POOLMEMORYBLOCK)
  143. + currentBlock -> Index;
  144. currentBlock -> Index += (AlignSize - (padLength % AlignSize)) % AlignSize;
  145. }
  146. //Now, get the address of the memory to return.
  147. rMemory = (PVOID)
  148. &(currentBlock->RawMemory[currentBlock -> Index]);
  149. currentBlock->Index += sizeNeeded;
  150. }
  151. return rMemory;
  152. }