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.

202 lines
6.1 KiB

  1. #include <wininetp.h>
  2. #include <cache.hxx>
  3. #ifdef TEST
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <windows.h>
  7. #include "hndlmgr.hxx"
  8. #define ALLOCATE_FIXED_MEMORY(size) malloc(size)
  9. #define REALLOCATE_MEMORY(ptr, size, flags) realloc(ptr, size)
  10. #define FREE_MEMORY(ptr) free(ptr)
  11. int main ()
  12. {
  13. HNDLMGR HandleMgr;
  14. HANDLE h[10];
  15. HANDLE hBad = (HANDLE) 5150;
  16. // Test alloc and realloc of handle heap.
  17. for (int i=9; i>=0; i--)
  18. {
  19. h[i] = HandleMgr.Alloc (54);
  20. printf ("Alloc h[%d] = %d\n", i, (DWORD) h[i]);
  21. }
  22. // Test invalid, valid, and double free.
  23. printf ("Free(%d) returns %d\n", NULL, HandleMgr.Free(NULL));
  24. printf ("Free(%d) returns %d\n", hBad, HandleMgr.Free(hBad));
  25. printf ("Free(%d) returns %d\n", h[3], HandleMgr.Free(h[3]));
  26. printf ("Free(%d) returns %d\n", h[3], HandleMgr.Free(h[3]));
  27. printf ("Free(%d) returns %d\n", h[9], HandleMgr.Free(h[9]));
  28. // Test mapping of invalid, free, and valid handles.
  29. printf ("Map(%d) = %d\n", NULL, HandleMgr.Map(NULL));
  30. printf ("Map(%d) = %d\n", hBad, HandleMgr.Map(hBad));
  31. printf ("Map(%d) = %d\n", h[3], HandleMgr.Map(h[3]));
  32. printf ("Map(%d) = %d\n", h[5], HandleMgr.Map(h[5]));
  33. // Test recycling of handles from free list.
  34. i = 3;
  35. h[i] = HandleMgr.Alloc (42);
  36. printf ("Alloc h[%d] = %d\n", i, (DWORD) h[i]);
  37. i = 9;
  38. h[i] = HandleMgr.Alloc (42);
  39. printf ("Alloc h[%d] = %d\n", i, (DWORD) h[i]);
  40. return 1;
  41. }
  42. #endif // TEST
  43. #define INC_GROW 8
  44. //=========================================================================
  45. void HNDLMGR::Destroy (void)
  46. {
  47. if (pHeap)
  48. {
  49. for (DWORD iHandle=0; iHandle < pHeap->dwNumHandles; iHandle++)
  50. {
  51. if ((DWORD_PTR) pHeap->pvHandles[iHandle] >= pHeap->dwMaxHandles)
  52. FREE_MEMORY (pHeap->pvHandles[iHandle]);
  53. }
  54. FREE_MEMORY (pHeap);
  55. }
  56. }
  57. //=========================================================================
  58. BOOL HNDLMGR::IsValidOffset (DWORD_PTR dwp)
  59. {
  60. return (pHeap && (dwp < pHeap->dwNumHandles) &&
  61. ((DWORD_PTR) pHeap->pvHandles[dwp]) >= pHeap->dwMaxHandles);
  62. }
  63. //=========================================================================
  64. HANDLE HNDLMGR::Alloc (DWORD cbAlloc)
  65. {
  66. PVOID pTemp;
  67. if (!pHeap)
  68. {
  69. // Allocate the heap.
  70. pHeap = (HNDLHEAP*) ALLOCATE_FIXED_MEMORY
  71. (sizeof(HNDLHEAP) + INC_GROW * sizeof(LPVOID));
  72. if (!pHeap)
  73. return NULL;
  74. // Initialize the heap.
  75. pHeap->dwNumHandles = 0;
  76. pHeap->dwNumInUse = 0;
  77. pHeap->dwMaxHandles = 0xFFFFFFFF;
  78. pHeap->dwFirstFree = 0;
  79. for (DWORD iHandle = 0; iHandle < INC_GROW; iHandle++)
  80. {
  81. pHeap->pvHandles[pHeap->dwNumHandles] =
  82. (HANDLE) (pHeap->dwNumHandles + 1);
  83. pHeap->dwNumHandles++;
  84. }
  85. }
  86. else if (pHeap->dwFirstFree == pHeap->dwNumHandles)
  87. {
  88. // Reallocate the heap.
  89. if (pHeap->dwNumHandles + INC_GROW >= pHeap->dwMaxHandles)
  90. {
  91. // Uh oh, heap is hit the lower bound set by the allocator.
  92. return NULL;
  93. }
  94. pTemp = REALLOCATE_MEMORY (pHeap, sizeof(HNDLHEAP)
  95. + (pHeap->dwNumHandles + INC_GROW) * sizeof(LPVOID), LMEM_MOVEABLE);
  96. if (!pTemp)
  97. return NULL;
  98. pHeap = (HNDLHEAP*) pTemp;
  99. // Extend the free list.
  100. for (DWORD iHandle = 0; iHandle < INC_GROW; iHandle++)
  101. {
  102. pHeap->pvHandles[pHeap->dwNumHandles] =
  103. (HANDLE) (pHeap->dwNumHandles + 1);
  104. pHeap->dwNumHandles++;
  105. }
  106. }
  107. // Allocate a handle.
  108. pTemp = ALLOCATE_FIXED_MEMORY (cbAlloc);
  109. if (!pTemp)
  110. return NULL;
  111. if ((DWORD_PTR) pTemp < pHeap->dwNumHandles)
  112. {
  113. // Uh oh, allocator returned a low value!
  114. FREE_MEMORY (pTemp);
  115. return NULL;
  116. }
  117. if (pHeap->dwMaxHandles >= ((DWORD_PTR) pTemp))
  118. pHeap->dwMaxHandles = ((DWORD_PTR) pTemp);
  119. INET_ASSERT(pHeap->dwFirstFree < pHeap->dwNumHandles);
  120. // Pop the handle off the top of the free list.
  121. DWORD_PTR dwOffset = pHeap->dwFirstFree;
  122. pHeap->dwFirstFree = (DWORD_PTR) pHeap->pvHandles[pHeap->dwFirstFree];
  123. pHeap->pvHandles[dwOffset] = pTemp;
  124. pHeap->dwNumInUse++;
  125. return (HANDLE) (dwOffset + 1);
  126. }
  127. //=========================================================================
  128. LPVOID HNDLMGR::Map (HANDLE h)
  129. {
  130. // Subtract one from handle to get offset.
  131. DWORD_PTR dwOffset = (DWORD_PTR)h - 1;
  132. if (!IsValidOffset (dwOffset) || (((DWORD_PTR) pHeap->pvHandles[dwOffset]) == -1))
  133. {
  134. return NULL;
  135. }
  136. else
  137. return pHeap->pvHandles[dwOffset];
  138. }
  139. //=========================================================================
  140. BOOL HNDLMGR::Free (HANDLE h)
  141. {
  142. // Subtract one from handle to get offset.
  143. DWORD_PTR dwOffset = (DWORD_PTR)h - 1;
  144. if (!IsValidOffset (dwOffset))
  145. return FALSE;
  146. if (((DWORD_PTR) pHeap->pvHandles[dwOffset]) != -1)
  147. {
  148. // Push the handle on the top of the free list.
  149. FREE_MEMORY (pHeap->pvHandles[dwOffset]);
  150. }
  151. INET_ASSERT(pHeap->dwFirstFree <= pHeap->dwNumHandles);
  152. pHeap->pvHandles[dwOffset] = (LPVOID) pHeap->dwFirstFree;
  153. pHeap->dwFirstFree = dwOffset;
  154. pHeap->dwNumInUse--;
  155. return TRUE;
  156. }
  157. //=========================================================================
  158. VOID HNDLMGR::InvalidateAll()
  159. {
  160. // We're in the process of switching identities; all cache handles
  161. // should be invalidated so that they can no longer be used.
  162. if (pHeap)
  163. {
  164. for (DWORD iHandle=0; iHandle < pHeap->dwNumHandles; iHandle++)
  165. {
  166. if (((DWORD_PTR) pHeap->pvHandles[iHandle] > pHeap->dwNumHandles)
  167. && ((DWORD_PTR) pHeap->pvHandles[iHandle] != -1))
  168. {
  169. FREE_MEMORY (pHeap->pvHandles[iHandle]);
  170. pHeap->pvHandles[iHandle] = (HANDLE)-1;
  171. }
  172. }
  173. }
  174. }