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>
13 #define TAG_POOLTEST 'tstP'
15 #define BASE_POOL_TYPE_MASK 1
16 #define QUOTA_POOL_MASK 8
23 POBJECT_HEADER Header
= OBJECT_TO_OBJECT_HEADER(Object
);
24 return Header
->PointerCount
;
27 static VOID
PoolsTest(VOID
)
30 ULONG AllocSize
, i
, AllocNumber
;
33 // Stress-test nonpaged pool
34 for (i
=1; i
<10000; i
++)
36 // make up some increasing, a bit irregular size
45 // start with non-paged pool
46 Ptr
= ExAllocatePoolWithTag(NonPagedPool
, AllocSize
, TAG_POOLTEST
);
48 // it may fail due to no-memory condition
51 // try to fully fill it
52 RtlFillMemory(Ptr
, AllocSize
, 0xAB);
55 ExFreePoolWithTag(Ptr
, TAG_POOLTEST
);
59 for (i
=1; i
<10000; i
++)
61 // make up some increasing, a bit irregular size
70 // start with non-paged pool
71 Ptr
= ExAllocatePoolWithTag(PagedPool
, AllocSize
, TAG_POOLTEST
);
73 // it may fail due to no-memory condition
76 // try to fully fill it
77 RtlFillMemory(Ptr
, AllocSize
, 0xAB);
80 ExFreePoolWithTag(Ptr
, TAG_POOLTEST
);
83 // test super-big allocations
84 /*AllocSize = 2UL * 1024 * 1024 * 1024;
85 Ptr = ExAllocatePoolWithTag(NonPagedPool, AllocSize, TAG_POOLTEST);
86 ok(Ptr == NULL, "Allocating 2Gb of nonpaged pool should fail\n");
88 Ptr = ExAllocatePoolWithTag(PagedPool, AllocSize, TAG_POOLTEST);
89 ok(Ptr == NULL, "Allocating 2Gb of paged pool should fail\n");*/
91 // now test allocating lots of small/medium blocks
93 Allocs
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Allocs
) * AllocNumber
, TAG_POOLTEST
);
96 for (i
=0; i
<AllocNumber
; i
++)
99 Allocs
[i
] = ExAllocatePoolWithTag(NonPagedPool
, AllocSize
, TAG_POOLTEST
);
103 for (i
=0; i
<AllocNumber
; i
++)
105 ExFreePoolWithTag(Allocs
[i
], TAG_POOLTEST
);
109 ExFreePoolWithTag(Allocs
, TAG_POOLTEST
);
112 static VOID
PoolsCorruption(VOID
)
117 // start with non-paged pool
118 AllocSize
= 4096 + 0x10;
119 Ptr
= ExAllocatePoolWithTag(NonPagedPool
, AllocSize
, TAG_POOLTEST
);
121 // touch all bytes, it shouldn't cause an exception
122 RtlZeroMemory(Ptr
, AllocSize
);
124 /* TODO: These fail because accessing invalid memory doesn't necessarily
125 cause an access violation */
126 #ifdef THIS_DOESNT_WORK
127 // test buffer overrun, right after our allocation ends
130 TestPtr
= (PULONG
)((PUCHAR
)Ptr
+ AllocSize
);
131 //Ptr[4] = 0xd33dbeef;
132 *TestPtr
= 0xd33dbeef;
134 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
137 Status
= _SEH2_GetExceptionCode();
140 ok(Status
== STATUS_ACCESS_VIOLATION
, "Exception should occur, but got Status 0x%08lX\n", Status
);
142 // test overrun in a distant byte range, but within 4096KB
145 Ptr
[2020] = 0xdeadb33f;
147 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
150 Status
= _SEH2_GetExceptionCode();
153 ok(Status
== STATUS_ACCESS_VIOLATION
, "Exception should occur, but got Status 0x%08lX\n", Status
);
157 ExFreePoolWithTag(Ptr
, TAG_POOLTEST
);
166 Memory
= ExAllocatePoolWithTag(PagedPool
, 8, 'MyTa');
167 ok_eq_tag(KmtGetPoolTag(Memory
), 'MyTa');
168 ExFreePoolWithTag(Memory
, 'MyTa');
170 Memory
= ExAllocatePoolWithTag(PagedPool
, PAGE_SIZE
, 'MyTa');
171 ok_eq_tag(KmtGetPoolTag(Memory
), 'TooL');
172 ExFreePoolWithTag(Memory
, 'MyTa');
174 Memory
= ExAllocatePoolWithTag(PagedPool
, PAGE_SIZE
- 3 * sizeof(PVOID
), 'MyTa');
175 ok_eq_tag(KmtGetPoolTag(Memory
), 'TooL');
176 ExFreePoolWithTag(Memory
, 'MyTa');
178 Memory
= ExAllocatePoolWithTag(PagedPool
, PAGE_SIZE
- 4 * sizeof(PVOID
) + 1, 'MyTa');
179 ok_eq_tag(KmtGetPoolTag(Memory
), 'TooL');
180 ExFreePoolWithTag(Memory
, 'MyTa');
182 Memory
= ExAllocatePoolWithTag(PagedPool
, PAGE_SIZE
- 4 * sizeof(PVOID
), 'MyTa');
183 ok_eq_tag(KmtGetPoolTag(Memory
), 'MyTa');
184 ExFreePoolWithTag(Memory
, 'MyTa');
191 PEPROCESS Process
= PsGetCurrentProcess();
192 PEPROCESS StoredProcess
;
194 LONG InitialRefCount
;
198 InitialRefCount
= GetRefCount(Process
);
200 /* We get some memory from this function, and it's properly aligned.
201 * Also, it takes a reference to the process, and releases it on free */
202 Memory
= ExAllocatePoolWithQuotaTag(PagedPool
| POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
,
205 ok(Memory
!= NULL
, "ExAllocatePoolWithQuotaTag returned NULL\n");
206 if (!skip(Memory
!= NULL
, "No memory\n"))
208 ok((ULONG_PTR
)Memory
% sizeof(LIST_ENTRY
) == 0,
209 "Allocation %p is badly aligned\n",
211 RefCount
= GetRefCount(Process
);
212 ok_eq_long(RefCount
, InitialRefCount
+ 1);
214 /* A pointer to the process is found right before the next pool header */
215 StoredProcess
= ((PVOID
*)((ULONG_PTR
)Memory
+ 2 * sizeof(LIST_ENTRY
)))[-1];
216 ok_eq_pointer(StoredProcess
, Process
);
218 /* Pool type should have QUOTA_POOL_MASK set */
219 PoolType
= KmtGetPoolType(Memory
);
220 ok(PoolType
!= 0, "PoolType is 0\n");
222 ok(PoolType
& QUOTA_POOL_MASK
, "PoolType = %x\n", PoolType
);
223 ok((PoolType
& BASE_POOL_TYPE_MASK
) == PagedPool
, "PoolType = %x\n", PoolType
);
225 ExFreePoolWithTag(Memory
, 'tQmK');
226 RefCount
= GetRefCount(Process
);
227 ok_eq_long(RefCount
, InitialRefCount
);
230 /* Large allocations are page-aligned, don't reference the process */
231 Memory
= ExAllocatePoolWithQuotaTag(PagedPool
| POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
,
234 ok(Memory
!= NULL
, "ExAllocatePoolWithQuotaTag returned NULL\n");
235 if (!skip(Memory
!= NULL
, "No memory\n"))
237 ok((ULONG_PTR
)Memory
% PAGE_SIZE
== 0,
238 "Allocation %p is badly aligned\n",
240 RefCount
= GetRefCount(Process
);
241 ok_eq_long(RefCount
, InitialRefCount
);
242 ExFreePoolWithTag(Memory
, 'tQmK');
243 RefCount
= GetRefCount(Process
);
244 ok_eq_long(RefCount
, InitialRefCount
);
247 /* Function raises by default */
249 Memory
= ExAllocatePoolWithQuotaTag(PagedPool
,
253 ExFreePoolWithTag(Memory
, 'tQmK');
254 KmtEndSeh(STATUS_INSUFFICIENT_RESOURCES
);
256 /* Function returns NULL with POOL_QUOTA_FAIL_INSTEAD_OF_RAISE */
258 Memory
= ExAllocatePoolWithQuotaTag(PagedPool
| POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
,
261 ok(Memory
== NULL
, "Successfully got 2GB block: %p\n", Memory
);
263 ExFreePoolWithTag(Memory
, 'tQmK');
264 KmtEndSeh(STATUS_SUCCESS
);