[KMTESTS]
[reactos.git] / kmtests / ntos_ex / ExPools.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Pools test routines KM-Test
5 * PROGRAMMER: Aleksey Bragin <aleksey@reactos.org>
6 */
7
8 /* TODO: PoolsCorruption tests fail because accessing invalid memory doesn't necessarily cause an access violation */
9
10 #include <kmt_test.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 #define TAG_POOLTEST 'tstP'
16
17 static VOID PoolsTest(VOID)
18 {
19 PVOID Ptr;
20 ULONG AllocSize, i, AllocNumber;
21 PVOID *Allocs;
22
23 // Stress-test nonpaged pool
24 for (i=1; i<10000; i++)
25 {
26 // make up some increasing, a bit irregular size
27 AllocSize = i*10;
28
29 if (i % 10)
30 AllocSize++;
31
32 if (i % 25)
33 AllocSize += 13;
34
35 // start with non-paged pool
36 Ptr = ExAllocatePoolWithTag(NonPagedPool, AllocSize, TAG_POOLTEST);
37
38 // it may fail due to no-memory condition
39 if (!Ptr) break;
40
41 // try to fully fill it
42 RtlFillMemory(Ptr, AllocSize, 0xAB);
43
44 // free it
45 ExFreePoolWithTag(Ptr, TAG_POOLTEST);
46 }
47
48 // now paged one
49 for (i=1; i<10000; i++)
50 {
51 // make up some increasing, a bit irregular size
52 AllocSize = i*50;
53
54 if (i % 10)
55 AllocSize++;
56
57 if (i % 25)
58 AllocSize += 13;
59
60 // start with non-paged pool
61 Ptr = ExAllocatePoolWithTag(PagedPool, AllocSize, TAG_POOLTEST);
62
63 // it may fail due to no-memory condition
64 if (!Ptr) break;
65
66 // try to fully fill it
67 RtlFillMemory(Ptr, AllocSize, 0xAB);
68
69 // free it
70 ExFreePoolWithTag(Ptr, TAG_POOLTEST);
71 }
72
73 // test super-big allocations
74 /*AllocSize = 2UL * 1024 * 1024 * 1024;
75 Ptr = ExAllocatePoolWithTag(NonPagedPool, AllocSize, TAG_POOLTEST);
76 ok(Ptr == NULL, "Allocating 2Gb of nonpaged pool should fail\n");
77
78 Ptr = ExAllocatePoolWithTag(PagedPool, AllocSize, TAG_POOLTEST);
79 ok(Ptr == NULL, "Allocating 2Gb of paged pool should fail\n");*/
80
81 // now test allocating lots of small/medium blocks
82 AllocNumber = 100000;
83 Allocs = ExAllocatePoolWithTag(PagedPool, sizeof(Allocs) * AllocNumber, TAG_POOLTEST);
84
85 // alloc blocks
86 for (i=0; i<AllocNumber; i++)
87 {
88 AllocSize = 42;
89 Allocs[i] = ExAllocatePoolWithTag(NonPagedPool, AllocSize, TAG_POOLTEST);
90 }
91
92 // now free them
93 for (i=0; i<AllocNumber; i++)
94 {
95 ExFreePoolWithTag(Allocs[i], TAG_POOLTEST);
96 }
97
98
99 ExFreePoolWithTag(Allocs, TAG_POOLTEST);
100 }
101
102 static VOID PoolsCorruption(VOID)
103 {
104 PULONG Ptr, TestPtr;
105 ULONG AllocSize;
106 NTSTATUS Status = STATUS_SUCCESS;
107
108 // start with non-paged pool
109 AllocSize = 4096 + 0x10;
110 Ptr = ExAllocatePoolWithTag(NonPagedPool, AllocSize, TAG_POOLTEST);
111
112 // touch all bytes, it shouldn't cause an exception
113 RtlZeroMemory(Ptr, AllocSize);
114
115 // test buffer overrun, right after our allocation ends
116 _SEH2_TRY
117 {
118 TestPtr = (PULONG)((PUCHAR)Ptr + AllocSize);
119 //Ptr[4] = 0xd33dbeef;
120 *TestPtr = 0xd33dbeef;
121 }
122 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
123 {
124 /* Get the status */
125 Status = _SEH2_GetExceptionCode();
126 } _SEH2_END;
127
128 ok(Status == STATUS_ACCESS_VIOLATION, "Exception should occur, but got Status 0x%08lX\n", Status);
129
130 // test overrun in a distant byte range, but within 4096KB
131 _SEH2_TRY
132 {
133 Ptr[2020] = 0xdeadb33f;
134 }
135 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
136 {
137 /* Get the status */
138 Status = _SEH2_GetExceptionCode();
139 } _SEH2_END;
140
141 ok(Status == STATUS_ACCESS_VIOLATION, "Exception should occur, but got Status 0x%08lX\n", Status);
142
143 // free the pool
144 ExFreePoolWithTag(Ptr, TAG_POOLTEST);
145 }
146
147 START_TEST(ExPools)
148 {
149 PoolsTest();
150 PoolsCorruption();
151 }