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.

346 lines
8.2 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <stdlib.h>
  5. BOOLEAN DebugFlag;
  6. PVOID HeapHandle;
  7. PVOID
  8. TestAlloc(
  9. IN ULONG Size
  10. )
  11. {
  12. PVOID a;
  13. if ((a = RtlAllocateHeap( HeapHandle, 0, Size )) == NULL) {
  14. RtlValidateHeap( HeapHandle, TRUE );
  15. DbgPrint( "\nUHEAP: RtlAllocateHeap( %lx ) failed\n", Size );
  16. DbgBreakPoint();
  17. NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  18. }
  19. if (DebugFlag) {
  20. DbgPrint( "\n" );
  21. DbgPrint( "\nRtlAllocateHeap( %lx ) => %lx\n", Size, a );
  22. }
  23. if (!RtlValidateHeap( HeapHandle, DebugFlag )) {
  24. NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  25. }
  26. return( a );
  27. }
  28. PVOID
  29. TestFree(
  30. IN PVOID BaseAddress,
  31. IN ULONG Size
  32. )
  33. {
  34. PVOID a;
  35. if ((a = RtlFreeHeap( HeapHandle, 0, BaseAddress )) != NULL) {
  36. DbgPrint( "\nUHEAP: RtlFreeHeap( %lx ) failed\n", BaseAddress );
  37. RtlValidateHeap( HeapHandle, TRUE );
  38. DbgBreakPoint();
  39. NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  40. }
  41. if (DebugFlag) {
  42. DbgPrint( "\n" );
  43. DbgPrint( "\nRtlFreeHeap( %lx ) => %lx\n", BaseAddress, a );
  44. }
  45. if (!RtlValidateHeap( HeapHandle, DebugFlag )) {
  46. NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  47. }
  48. return( a );
  49. }
  50. BOOLEAN
  51. TestHeap(
  52. IN PVOID UserHeapBase,
  53. IN BOOLEAN Serialize,
  54. IN BOOLEAN Sparse,
  55. IN ULONG GrowthThreshold,
  56. IN ULONG InitialSize
  57. )
  58. {
  59. PVOID a1,a2,a3,a4;
  60. DWORD Flags;
  61. Flags = 0;
  62. if (!Serialize) {
  63. Flags |= HEAP_NO_SERIALIZE;
  64. }
  65. if (!Sparse) {
  66. Flags |= HEAP_GROWABLE;
  67. }
  68. HeapHandle = RtlCreateHeap( Flags,
  69. UserHeapBase,
  70. InitialSize,
  71. 0,
  72. 0,
  73. GrowthThreshold
  74. );
  75. if ( HeapHandle == NULL ) {
  76. DbgPrint( "UHEAP: RtlCreateHeap failed\n" );
  77. DbgBreakPoint();
  78. goto exit;
  79. }
  80. if (!RtlValidateHeap( HeapHandle, DebugFlag )) {
  81. NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  82. }
  83. //
  84. // TEST 0:
  85. // Allocate and free a large chunk of memory so that the following
  86. // tests are valid.
  87. //
  88. DbgPrint( "UHEAP: Test #0\n" );
  89. a1 = TestAlloc( 4096-16 );
  90. TestFree( a1, 0 );
  91. //
  92. // TEST 1:
  93. // Allocate three chunks, deallocate the middle one, and reallocate it.
  94. //
  95. DbgPrint( "UHEAP: Test #1\n" );
  96. a1 = TestAlloc( 16 );
  97. a2 = TestAlloc( 32 );
  98. a3 = TestAlloc( 112 );
  99. TestFree( a2, 32 );
  100. a4 = TestAlloc( 32 );
  101. //
  102. // TEST 2:
  103. // Deallocate first chunk and reallocate it.
  104. //
  105. DbgPrint( "UHEAP: Test #2\n" );
  106. TestFree( a1, 16 );
  107. a4 = TestAlloc( 16 );
  108. //
  109. // TEST 3:
  110. // Deallocate last chunk and reallocate it.
  111. //
  112. DbgPrint( "UHEAP: Test #3\n" );
  113. TestFree( a3, 112 );
  114. a4 = TestAlloc( 112 );
  115. //
  116. // TEST 4:
  117. // Deallocate last chunk and reallocate larger one.
  118. //
  119. DbgPrint( "UHEAP: Test #4\n" );
  120. TestFree( a4, 112 );
  121. a4 = TestAlloc( 112+64 );
  122. //
  123. // TEST 5:
  124. // Deallocate first two chunks and reallocate combined one.
  125. //
  126. DbgPrint( "UHEAP: Test #5\n" );
  127. TestFree( a1, 16 );
  128. TestFree( a2, 32 );
  129. a4 = TestAlloc( 16+32-4 );
  130. //
  131. // TEST 6:
  132. // There should be room between blocks 2 and 3 for a small allocation.
  133. // Make sure zero byte allocations work.
  134. //
  135. DbgPrint( "UHEAP: Test #6\n" );
  136. a4 = TestAlloc( 0 );
  137. //
  138. // TEST 7:
  139. // Deallocate last two chunks and reallocate one. Address should change.
  140. //
  141. DbgPrint( "UHEAP: Test #7\n" );
  142. TestFree( a3, 112+64 );
  143. TestFree( a4, 0 );
  144. a3 = TestAlloc( 112 );
  145. //
  146. // TEST 8:
  147. // Deallocate everything and make sure it can be reallocated.
  148. //
  149. DbgPrint( "UHEAP: Test #8\n" );
  150. TestFree( a1, 16+32-4 );
  151. TestFree( a3, 112 );
  152. a2 = TestAlloc( 200 );
  153. //
  154. // TEST 9:
  155. // Allocate more than is committed.
  156. //
  157. DbgPrint( "UHEAP: Test #9\n" );
  158. a1 = TestAlloc( 100000 );
  159. TestFree( a2, 200 );
  160. TestFree( a1, 100000 );
  161. //
  162. // TEST 10:
  163. // Allocate more than maximum size of heap
  164. //
  165. DbgPrint( "UHEAP: Test #10\n" );
  166. a3 = TestAlloc( 100000 );
  167. TestFree( a3, 100000 );
  168. //
  169. // TEST 11:
  170. // Destroy the heap
  171. //
  172. DbgPrint( "UHEAP: Test #11\n" );
  173. HeapHandle = RtlDestroyHeap( HeapHandle );
  174. if ( HeapHandle != NULL ) {
  175. DbgPrint( "UHEAP: RtlDestroyHeap failed\n" );
  176. DbgBreakPoint();
  177. goto exit;
  178. }
  179. return( TRUE );
  180. exit:
  181. if (HeapHandle != NULL) {
  182. HeapHandle = RtlDestroyHeap( HeapHandle );
  183. }
  184. return( FALSE );
  185. }
  186. VOID
  187. Usage( VOID )
  188. {
  189. DbgPrint( "Usage: UHEAP [-s ReserveSize] | [-g InitialSize GrowthThreshold]\n" );
  190. (VOID)NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  191. }
  192. NTSTATUS
  193. main(
  194. int argc,
  195. char *argv[],
  196. char *envp[],
  197. ULONG DebugParameter OPTIONAL
  198. )
  199. {
  200. NTSTATUS Status;
  201. PCH s;
  202. PVOID UserHeapBase = NULL;
  203. BOOLEAN Serialize = FALSE;
  204. BOOLEAN Sparse = FALSE;
  205. ULONG GrowthThreshold = 0;
  206. ULONG InitialSize = 0x8000;
  207. DebugFlag = DebugParameter;
  208. DbgPrint( "** Start of User Mode Test of RtlAllocateHeap/RtlFreeHeap **\n" );
  209. while (--argc) {
  210. s = *++argv;
  211. if (*s == '-') {
  212. switch( *++s ) {
  213. case 'x':
  214. case 'X':
  215. Serialize = TRUE;
  216. break;
  217. case 's':
  218. case 'S':
  219. Sparse = TRUE;
  220. if (--argc) {
  221. InitialSize = atoi( *++argv );
  222. Status = NtAllocateVirtualMemory( NtCurrentProcess(),
  223. (PVOID *)&UserHeapBase,
  224. 0,
  225. &InitialSize,
  226. MEM_RESERVE,
  227. PAGE_READWRITE
  228. );
  229. if (!NT_SUCCESS( Status )) {
  230. DbgPrint( "UHEAP: Unable to allocate heap - 0x%lx bytes\n",
  231. InitialSize
  232. );
  233. Usage();
  234. }
  235. }
  236. else {
  237. Usage();
  238. }
  239. break;
  240. case 'g':
  241. case 'G':
  242. if (argc >= 2) {
  243. argc -= 2;
  244. InitialSize = atoi( *++argv );
  245. GrowthThreshold = atoi( *++argv );
  246. }
  247. else {
  248. Usage();
  249. }
  250. break;
  251. default:
  252. Usage();
  253. }
  254. }
  255. else {
  256. Usage();
  257. }
  258. }
  259. TestHeap( UserHeapBase,
  260. Serialize,
  261. Sparse,
  262. GrowthThreshold,
  263. InitialSize
  264. );
  265. if (UserHeapBase != NULL) {
  266. Status = NtFreeVirtualMemory( NtCurrentProcess(),
  267. (PVOID *)&UserHeapBase,
  268. &InitialSize,
  269. MEM_RELEASE
  270. );
  271. }
  272. DbgPrint( "** End of User Mode Test of RtlAllocateHeap/RtlFreeHeap **\n" );
  273. (VOID)NtTerminateProcess( NtCurrentProcess(), STATUS_SUCCESS );
  274. return STATUS_SUCCESS;
  275. }