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.

878 lines
15 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <malloc.h>
  6. #include <stdio.h>
  7. #include <suballoc.h>
  8. typedef struct _MemTrack *PMEMTRACK;
  9. typedef struct _MemTrack {
  10. PMEMTRACK Next;
  11. ULONG Address;
  12. ULONG Size;
  13. } MEMTRACK;
  14. VOID
  15. SimpleTest1(
  16. PVOID SA
  17. );
  18. VOID
  19. SimpleTest2(
  20. PVOID SA
  21. );
  22. VOID
  23. SimpleTest3(
  24. PVOID SA
  25. );
  26. VOID
  27. SimpleTest4(
  28. PVOID
  29. );
  30. VOID
  31. SimpleTest5(
  32. PVOID
  33. );
  34. VOID
  35. SimpleTest6(
  36. PVOID
  37. );
  38. NTSTATUS
  39. DecommitMem(
  40. ULONG BaseAddress,
  41. ULONG Size
  42. );
  43. NTSTATUS
  44. CommitMem(
  45. ULONG BaseAddress,
  46. ULONG Size
  47. );
  48. VOID
  49. MoveMem(
  50. ULONG Destination,
  51. ULONG Source,
  52. ULONG Size
  53. );
  54. main(argv, argc)
  55. char **argv;
  56. int argc;
  57. {
  58. NTSTATUS Status;
  59. PVOID BaseAddress, SA;
  60. ULONG Size;
  61. ULONG TotalFree, LargestFree;
  62. ULONG i,j;
  63. BOOL Success;
  64. //
  65. // Allocate a region of memory for SA to manage
  66. //
  67. BaseAddress = NULL;
  68. Size = 15*1024*1024 - 64 * 1024;
  69. Status = NtAllocateVirtualMemory(
  70. NtCurrentProcess(),
  71. &BaseAddress,
  72. 0,
  73. &Size,
  74. MEM_RESERVE,
  75. PAGE_READWRITE
  76. );
  77. if (!NT_SUCCESS(Status)) {
  78. printf("Couldn't allocate memory, %lx\n", Status);
  79. return(0);
  80. }
  81. //
  82. // Initialize the suballocation stuff
  83. //
  84. SA = SAInitialize(
  85. (ULONG)BaseAddress,
  86. Size,
  87. CommitMem,
  88. DecommitMem,
  89. MoveMem
  90. );
  91. if (SA == NULL) {
  92. printf("SAInitialize Failed\n");
  93. }
  94. //
  95. // Find out how much free memory we have
  96. //
  97. Success = SAQueryFree(
  98. SA,
  99. &TotalFree,
  100. &LargestFree
  101. );
  102. if (!Success) {
  103. printf("Could not query free\n");
  104. return;
  105. }
  106. //
  107. // Run some tests
  108. //
  109. SimpleTest1(SA);
  110. //
  111. // Allocate blocks spanning two commit blocks
  112. //
  113. SimpleTest2(SA);
  114. //
  115. // Allocate and free all of memory (twice)
  116. //
  117. SimpleTest3(SA);
  118. //
  119. // More complex alloc and free test
  120. //
  121. SimpleTest4(SA);
  122. //
  123. // Test realloc
  124. //
  125. SimpleTest5(SA);
  126. //
  127. // Test Queryfree
  128. //
  129. SimpleTest6(SA);
  130. //
  131. // Make sure we didn't leak
  132. //
  133. Success = SAQueryFree(
  134. SA,
  135. &i,
  136. &j
  137. );
  138. if (!Success){
  139. printf("Couldn't requery free\n");
  140. return;
  141. }
  142. if ((i != TotalFree) || (j != LargestFree)) {
  143. printf("We leaked\n");
  144. }
  145. }
  146. VOID
  147. SimpleTest1(
  148. PVOID SA
  149. )
  150. {
  151. ULONG Address;
  152. BOOL Success;
  153. Success = SAAllocate(
  154. SA,
  155. 50,
  156. &Address
  157. );
  158. if (!Success) {
  159. printf("SimpleTest1: Failed to allocate\n");
  160. return;
  161. }
  162. try {
  163. *((PULONG)(Address + 4)) = 1;
  164. } except (EXCEPTION_EXECUTE_HANDLER) {
  165. printf("SimpleTest1: Faulted accessing memory\n");
  166. return;
  167. }
  168. Success = SAFree(
  169. SA,
  170. 50,
  171. Address
  172. );
  173. if (!Success) {
  174. printf("SimpleTest1: Failed to free\n");
  175. return;
  176. }
  177. Success = TRUE;
  178. try {
  179. *((PULONG)Address + 4) = 1;
  180. } except (EXCEPTION_EXECUTE_HANDLER) {
  181. Success = FALSE;
  182. }
  183. if (Success) {
  184. printf("SimpleTest1: memory not decommited\n");
  185. }
  186. }
  187. VOID
  188. SimpleTest2(
  189. PVOID SA
  190. )
  191. {
  192. ULONG SmallAddress, LargeAddress;
  193. BOOL Success;
  194. Success = SAAllocate(
  195. SA,
  196. 50,
  197. &SmallAddress
  198. );
  199. if (!Success) {
  200. printf("SimpleTest2: Could not alloc small block\n");
  201. return;
  202. }
  203. try {
  204. *((PULONG)(SmallAddress + 4)) = 1;
  205. } except (EXCEPTION_EXECUTE_HANDLER) {
  206. printf("SimpleTest2: small block not committed\n");
  207. return;
  208. }
  209. Success = SAAllocate(
  210. SA,
  211. COMMIT_GRANULARITY + 50,
  212. &LargeAddress
  213. );
  214. if (!Success) {
  215. printf("SimpleTest2: Could not alloc large block\n");
  216. return;
  217. }
  218. try {
  219. *((PULONG)(LargeAddress + 4)) = 1;
  220. *((PULONG)(LargeAddress + COMMIT_GRANULARITY)) = 1;
  221. } except (EXCEPTION_EXECUTE_HANDLER) {
  222. printf("SimpleTest2: Large block not committed\n");
  223. return;
  224. }
  225. Success = SAFree(
  226. SA,
  227. 50,
  228. SmallAddress
  229. );
  230. if (!Success) {
  231. printf("SimpleTest2: failed to free small block\n");
  232. return;
  233. }
  234. try {
  235. *((PULONG)(LargeAddress + 4)) = 1;
  236. } except (EXCEPTION_EXECUTE_HANDLER) {
  237. printf("SimpleTest2: LargeBlock decommited!!\n");
  238. return;
  239. }
  240. Success = SAFree(
  241. SA,
  242. COMMIT_GRANULARITY + 50,
  243. LargeAddress
  244. );
  245. if (!Success) {
  246. printf("SimpleTest2: failed to free Large block\n");
  247. return;
  248. }
  249. Success = FALSE;
  250. try {
  251. *((PULONG)(LargeAddress + 4)) = 1;
  252. } except (EXCEPTION_EXECUTE_HANDLER) {
  253. Success = TRUE;
  254. }
  255. if (!Success) {
  256. printf("SimpleTest2: First block not decommited\n");
  257. }
  258. Success = FALSE;
  259. try {
  260. *((PULONG)(LargeAddress + COMMIT_GRANULARITY + 4)) = 1;
  261. } except (EXCEPTION_EXECUTE_HANDLER) {
  262. Success = TRUE;
  263. }
  264. if (!Success) {
  265. printf("SimpleTest2: Last block not decommited\n");
  266. }
  267. }
  268. VOID
  269. SimpleTest3(
  270. PVOID SA
  271. )
  272. {
  273. ULONG BlockCount, i, Address;
  274. PMEMTRACK p, Head, f;
  275. BOOL Success;
  276. Head = NULL;
  277. BlockCount = 0;
  278. do {
  279. Success = SAAllocate(
  280. SA,
  281. 3072,
  282. &Address
  283. );
  284. if (Success) {
  285. p = malloc(sizeof(MEMTRACK));
  286. if (p == NULL) {
  287. printf("SimpleTest3: malloc error\n");
  288. return;
  289. }
  290. p->Next = Head;
  291. p->Size = 3072;
  292. p->Address = Address;
  293. Head = p;
  294. BlockCount++;
  295. }
  296. } while (Success);
  297. try {
  298. p = Head;
  299. while (p != NULL) {
  300. *((PULONG)(p->Address + 100)) = 1;
  301. p = p->Next;
  302. }
  303. } except (EXCEPTION_EXECUTE_HANDLER) {
  304. printf("SimpleTest3: failed first access test\n");
  305. return;
  306. }
  307. p = Head;
  308. while (p != NULL) {
  309. Success = SAFree(
  310. SA,
  311. 3072,
  312. p->Address
  313. );
  314. if (!Success) {
  315. printf("SimpleTest3: Failed first free test\n");
  316. return;
  317. }
  318. f = p;
  319. p = p->Next;
  320. free(f);
  321. }
  322. Head = NULL;
  323. for (i = 0; i < BlockCount; i++) {
  324. Success = SAAllocate(
  325. SA,
  326. 3072,
  327. &Address
  328. );
  329. if (!Success) {
  330. printf("SimpleTest3: Failed second alloc test\n");
  331. return;
  332. }
  333. p = malloc(sizeof(MEMTRACK));
  334. if (p == NULL) {
  335. printf("SimpleTest3: malloc error\n");
  336. return;
  337. }
  338. p->Next = Head;
  339. p->Size = 3072;
  340. p->Address = Address;
  341. Head = p;
  342. }
  343. try {
  344. p = Head;
  345. while (p != NULL) {
  346. *((PULONG)(p->Address + 100)) = 1;
  347. p = p->Next;
  348. }
  349. } except (EXCEPTION_EXECUTE_HANDLER) {
  350. printf("SimpleTest3: failed second access test\n");
  351. return;
  352. }
  353. p = Head;
  354. while (p != NULL) {
  355. Success = SAFree(
  356. SA,
  357. 3072,
  358. p->Address
  359. );
  360. if (!Success) {
  361. printf("SimpleTest3: Failed second free test\n");
  362. return;
  363. }
  364. f = p;
  365. p = p->Next;
  366. free(f);
  367. }
  368. }
  369. VOID
  370. SimpleTest4(
  371. PVOID SA
  372. )
  373. {
  374. ULONG i, Address;
  375. PMEMTRACK p, Head, f;
  376. BOOL Success;
  377. Head = NULL;
  378. do {
  379. Success = SAAllocate(
  380. SA,
  381. 3072,
  382. &Address
  383. );
  384. if (Success) {
  385. p = malloc(sizeof(MEMTRACK));
  386. if (p == NULL) {
  387. printf("SimpleTest4: malloc error\n");
  388. return;
  389. }
  390. p->Next = Head;
  391. p->Size = 3072;
  392. p->Address = Address;
  393. Head = p;
  394. }
  395. } while (Success);
  396. p = Head;
  397. p = p->Next;
  398. p = p->Next;
  399. Success = SAFree(
  400. SA,
  401. 3072,
  402. p->Next->Address
  403. );
  404. if (!Success) {
  405. printf("SimpleTest4: could not free\n");
  406. return;
  407. }
  408. f = p->Next;
  409. p->Next = p->Next->Next;
  410. free (f);
  411. p = p->Next;
  412. p = p->Next;
  413. Success = SAFree(
  414. SA,
  415. 3072,
  416. p->Next->Address
  417. );
  418. if (!Success) {
  419. printf("SimpleTest4: could not free\n");
  420. return;
  421. }
  422. f = p->Next;
  423. p->Next = p->Next->Next;
  424. free (f);
  425. Success = SAFree(
  426. SA,
  427. 3072,
  428. p->Next->Address
  429. );
  430. if (!Success) {
  431. printf("SimpleTest4: could not free\n");
  432. return;
  433. }
  434. f = p->Next;
  435. p->Next = p->Next->Next;
  436. free (f);
  437. Success = SAAllocate(
  438. SA,
  439. 3072,
  440. &Address
  441. );
  442. try {
  443. *((PULONG)(Address + 4)) = 1;
  444. } except (EXCEPTION_EXECUTE_HANDLER) {
  445. printf("SimpleTest4: failed to access\n");
  446. return;
  447. }
  448. if (!Success) {
  449. printf("SimpleTest4: could not allocate\n");
  450. return;
  451. }
  452. p = malloc(sizeof(MEMTRACK));
  453. if (!p) {
  454. printf("SimpleTest4: could not malloc\n");
  455. return;
  456. }
  457. p->Next = Head;
  458. p->Size = 3072;
  459. p->Address = Address;
  460. Head = p;
  461. Success = SAAllocate(
  462. SA,
  463. 3072,
  464. &Address
  465. );
  466. try {
  467. *((PULONG)(Address + 4)) = 1;
  468. } except (EXCEPTION_EXECUTE_HANDLER) {
  469. printf("SimpleTest4: failed to access\n");
  470. return;
  471. }
  472. if (!Success) {
  473. printf("SimpleTest4: could not allocate\n");
  474. return;
  475. }
  476. p = malloc(sizeof(MEMTRACK));
  477. if (!p) {
  478. printf("SimpleTest4: could not malloc\n");
  479. return;
  480. }
  481. p->Next = Head;
  482. p->Size = 3072;
  483. p->Address = Address;
  484. Head = p;
  485. p = Head;
  486. while (p != NULL) {
  487. Success = SAFree(
  488. SA,
  489. 3072,
  490. p->Address
  491. );
  492. if (!Success) {
  493. printf("SimpleTest3: Failed second free test\n");
  494. return;
  495. }
  496. f = p;
  497. p = p->Next;
  498. free(f);
  499. }
  500. }
  501. VOID
  502. SimpleTest5(
  503. PVOID SA
  504. )
  505. {
  506. ULONG Address, NewAddress;
  507. ULONG Address1, Address2, Address3;
  508. ULONG Size1, Size2, Size3;
  509. BOOL Success;
  510. Success = SAAllocate(
  511. SA,
  512. 3072,
  513. &Address
  514. );
  515. if (!Success) {
  516. printf("SimpleTest5: failed to allocate\n");
  517. return;
  518. }
  519. Success = SAReallocate(
  520. SA,
  521. 3072,
  522. Address,
  523. 3000,
  524. &NewAddress
  525. );
  526. if (!Success) {
  527. printf("SimpleTest5: failed to reallocate\n");
  528. return;
  529. }
  530. if (NewAddress != Address) {
  531. printf("SimpleTest5: Realloc in place failed\n");
  532. }
  533. Success = SAReallocate(
  534. SA,
  535. 3072,
  536. Address,
  537. 200,
  538. &NewAddress
  539. );
  540. if (!Success) {
  541. printf("SimpleTest5: failed to reallocate\n");
  542. return;
  543. }
  544. if (NewAddress != Address) {
  545. printf("SimpleTest5: Realloc in place failed\n");
  546. return;
  547. }
  548. Success = SAReallocate(
  549. SA,
  550. 200,
  551. Address,
  552. 6000,
  553. &NewAddress
  554. );
  555. if (!Success) {
  556. printf("SimpleTest5: failed to reallocate\n");
  557. return;
  558. }
  559. if (NewAddress != Address) {
  560. printf("SimpleTest5: realloc in place failed\n");
  561. return;
  562. }
  563. Success = SAAllocate(
  564. SA,
  565. 1500,
  566. &Address
  567. );
  568. if (!Success) {
  569. printf("SimpleTest5: failed to allocate\n");
  570. return;
  571. }
  572. Address1 = NewAddress;
  573. Size1 = 6000;
  574. Address2 = Address;
  575. Size2 = 1500;
  576. Success = SAReallocate(
  577. SA,
  578. Size1,
  579. Address1,
  580. 3000,
  581. &NewAddress
  582. );
  583. if (!Success) {
  584. printf("SimpleTest5: failed to reallocate\n");
  585. return;
  586. }
  587. if (Address1 != NewAddress) {
  588. printf("SimpleTest5: realloc in place failed\n");
  589. return;
  590. }
  591. Size1= 3000;
  592. Success = SAAllocate(
  593. SA,
  594. 2000,
  595. &Address
  596. );
  597. if (!Success) {
  598. printf("SimpleTest5: failed to allocate\n");
  599. return;
  600. }
  601. Address3 = Address;
  602. Size3 = 2000;
  603. Success = SAFree(
  604. SA,
  605. Size1,
  606. Address1
  607. );
  608. if (!Success) {
  609. printf("SimpleTest5: failed to free\n");
  610. return;
  611. }
  612. Success = SAReallocate(
  613. SA,
  614. Size3,
  615. Address3,
  616. 5000,
  617. &Address
  618. );
  619. if (!Success) {
  620. printf("SimpleTest5: failed to reallocate\n");
  621. return;
  622. }
  623. Address3 = Address;
  624. Size3 = 5000;
  625. Success = SAReallocate(
  626. SA,
  627. Size3,
  628. Address3,
  629. 10000,
  630. &Address
  631. );
  632. if (!Success) {
  633. printf("SimpleTest5: failed to reallocate\n");
  634. return;
  635. }
  636. Address3 = Address;
  637. Size3 = 10000;
  638. Success = SAFree(
  639. SA,
  640. Size2,
  641. Address2
  642. );
  643. if (!Success) {
  644. printf("SimpleTest5: failed to free\n");
  645. return;
  646. }
  647. Success = SAFree(
  648. SA,
  649. Size3,
  650. Address3
  651. );
  652. if (!Success) {
  653. printf("SimpleTest5: failed to free\n");
  654. return;
  655. }
  656. }
  657. VOID
  658. SimpleTest6(
  659. PVOID SA
  660. )
  661. {
  662. ULONG LargestFree, TotalFree;
  663. BOOL Success;
  664. Success = SAQueryFree(
  665. SA,
  666. &TotalFree,
  667. &LargestFree
  668. );
  669. }
  670. NTSTATUS
  671. CommitMem(
  672. ULONG BaseAddress,
  673. ULONG Size
  674. )
  675. {
  676. NTSTATUS Status;
  677. PVOID Address;
  678. ULONG size;
  679. Address = (PVOID)BaseAddress;
  680. size = Size;
  681. Status = NtAllocateVirtualMemory(
  682. NtCurrentProcess(),
  683. &Address,
  684. 0L,
  685. &size,
  686. MEM_COMMIT,
  687. PAGE_READWRITE
  688. );
  689. if (!NT_SUCCESS(Status)) {
  690. printf(
  691. "CommitMem failed to commit %lx, %lx, error %lx\n",
  692. Address,
  693. size,
  694. Status
  695. );
  696. }
  697. return Status;
  698. }
  699. NTSTATUS
  700. DecommitMem(
  701. ULONG BaseAddress,
  702. ULONG Size
  703. )
  704. {
  705. NTSTATUS Status;
  706. PVOID Address;
  707. ULONG size;
  708. Address = (PVOID)BaseAddress;
  709. size = Size;
  710. Status = NtFreeVirtualMemory(
  711. NtCurrentProcess(),
  712. &Address,
  713. &size,
  714. MEM_DECOMMIT
  715. );
  716. if (!NT_SUCCESS(Status)) {
  717. printf(
  718. "DecommitMem failed to decommit %lx, %lx, error %lx\n",
  719. Address,
  720. size,
  721. Status
  722. );
  723. }
  724. return Status;
  725. }
  726. VOID
  727. MoveMem(
  728. ULONG Destination,
  729. ULONG Source,
  730. ULONG Size
  731. )
  732. {
  733. RtlMoveMemory(
  734. (PVOID)Destination,
  735. (PVOID)Source,
  736. Size
  737. );
  738. }