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>
18 POBJECT_HEADER Header
= OBJECT_TO_OBJECT_HEADER(Object
);
19 return Header
->PointerCount
;
22 #define TAG_POOLTEST 'tstP'
24 static VOID
PoolsTest(VOID
)
27 ULONG AllocSize
, i
, AllocNumber
;
30 // Stress-test nonpaged pool
31 for (i
=1; i
<10000; i
++)
33 // make up some increasing, a bit irregular size
42 // start with non-paged pool
43 Ptr
= ExAllocatePoolWithTag(NonPagedPool
, AllocSize
, TAG_POOLTEST
);
45 // it may fail due to no-memory condition
48 // try to fully fill it
49 RtlFillMemory(Ptr
, AllocSize
, 0xAB);
52 ExFreePoolWithTag(Ptr
, TAG_POOLTEST
);
56 for (i
=1; i
<10000; i
++)
58 // make up some increasing, a bit irregular size
67 // start with non-paged pool
68 Ptr
= ExAllocatePoolWithTag(PagedPool
, AllocSize
, TAG_POOLTEST
);
70 // it may fail due to no-memory condition
73 // try to fully fill it
74 RtlFillMemory(Ptr
, AllocSize
, 0xAB);
77 ExFreePoolWithTag(Ptr
, TAG_POOLTEST
);
80 // test super-big allocations
81 /*AllocSize = 2UL * 1024 * 1024 * 1024;
82 Ptr = ExAllocatePoolWithTag(NonPagedPool, AllocSize, TAG_POOLTEST);
83 ok(Ptr == NULL, "Allocating 2Gb of nonpaged pool should fail\n");
85 Ptr = ExAllocatePoolWithTag(PagedPool, AllocSize, TAG_POOLTEST);
86 ok(Ptr == NULL, "Allocating 2Gb of paged pool should fail\n");*/
88 // now test allocating lots of small/medium blocks
90 Allocs
= ExAllocatePoolWithTag(PagedPool
, sizeof(Allocs
) * AllocNumber
, TAG_POOLTEST
);
93 for (i
=0; i
<AllocNumber
; i
++)
96 Allocs
[i
] = ExAllocatePoolWithTag(NonPagedPool
, AllocSize
, TAG_POOLTEST
);
100 for (i
=0; i
<AllocNumber
; i
++)
102 ExFreePoolWithTag(Allocs
[i
], TAG_POOLTEST
);
106 ExFreePoolWithTag(Allocs
, TAG_POOLTEST
);
109 static VOID
PoolsCorruption(VOID
)
114 // start with non-paged pool
115 AllocSize
= 4096 + 0x10;
116 Ptr
= ExAllocatePoolWithTag(NonPagedPool
, AllocSize
, TAG_POOLTEST
);
118 // touch all bytes, it shouldn't cause an exception
119 RtlZeroMemory(Ptr
, AllocSize
);
121 /* TODO: These fail because accessing invalid memory doesn't necessarily
122 cause an access violation */
123 #ifdef THIS_DOESNT_WORK
124 // test buffer overrun, right after our allocation ends
127 TestPtr
= (PULONG
)((PUCHAR
)Ptr
+ AllocSize
);
128 //Ptr[4] = 0xd33dbeef;
129 *TestPtr
= 0xd33dbeef;
131 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
134 Status
= _SEH2_GetExceptionCode();
137 ok(Status
== STATUS_ACCESS_VIOLATION
, "Exception should occur, but got Status 0x%08lX\n", Status
);
139 // test overrun in a distant byte range, but within 4096KB
142 Ptr
[2020] = 0xdeadb33f;
144 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
147 Status
= _SEH2_GetExceptionCode();
150 ok(Status
== STATUS_ACCESS_VIOLATION
, "Exception should occur, but got Status 0x%08lX\n", Status
);
154 ExFreePoolWithTag(Ptr
, TAG_POOLTEST
);
163 Memory
= ExAllocatePoolWithTag(PagedPool
, 8, 'MyTa');
164 ok_eq_tag(KmtGetPoolTag(Memory
), 'MyTa');
165 ExFreePoolWithTag(Memory
, 'MyTa');
167 Memory
= ExAllocatePoolWithTag(PagedPool
, PAGE_SIZE
, 'MyTa');
168 ok_eq_tag(KmtGetPoolTag(Memory
), 'TooL');
169 ExFreePoolWithTag(Memory
, 'MyTa');
171 Memory
= ExAllocatePoolWithTag(PagedPool
, PAGE_SIZE
- 3 * sizeof(PVOID
), 'MyTa');
172 ok_eq_tag(KmtGetPoolTag(Memory
), 'TooL');
173 ExFreePoolWithTag(Memory
, 'MyTa');
175 Memory
= ExAllocatePoolWithTag(PagedPool
, PAGE_SIZE
- 4 * sizeof(PVOID
) + 1, 'MyTa');
176 ok_eq_tag(KmtGetPoolTag(Memory
), 'TooL');
177 ExFreePoolWithTag(Memory
, 'MyTa');
179 Memory
= ExAllocatePoolWithTag(PagedPool
, PAGE_SIZE
- 4 * sizeof(PVOID
), 'MyTa');
180 ok_eq_tag(KmtGetPoolTag(Memory
), 'MyTa');
181 ExFreePoolWithTag(Memory
, 'MyTa');
188 PEPROCESS Process
= PsGetCurrentProcess();
189 PEPROCESS StoredProcess
;
191 LONG InitialRefCount
;
193 NTSTATUS ExceptionStatus
;
195 InitialRefCount
= GetRefCount(Process
);
197 /* We get some memory from this function, and it's properly aligned.
198 * Also, it takes a reference to the process, and releases it on free */
199 Memory
= ExAllocatePoolWithQuotaTag(PagedPool
| POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
,
202 ok(Memory
!= NULL
, "ExAllocatePoolWithQuotaTag returned NULL\n");
203 if (!skip(Memory
!= NULL
, "No memory\n"))
205 ok((ULONG_PTR
)Memory
% sizeof(LIST_ENTRY
) == 0,
206 "Allocation %p is badly aligned\n",
208 RefCount
= GetRefCount(Process
);
209 ok_eq_long(RefCount
, InitialRefCount
+ 1);
211 /* A pointer to the process is found right before the next pool header */
212 StoredProcess
= ((PVOID
*)((ULONG_PTR
)Memory
+ 2 * sizeof(LIST_ENTRY
)))[-1];
213 ok_eq_pointer(StoredProcess
, Process
);
215 ExFreePoolWithTag(Memory
, 'tQmK');
216 RefCount
= GetRefCount(Process
);
217 ok_eq_long(RefCount
, InitialRefCount
);
220 /* Large allocations are page-aligned, don't reference the process */
221 Memory
= ExAllocatePoolWithQuotaTag(PagedPool
| POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
,
224 ok(Memory
!= NULL
, "ExAllocatePoolWithQuotaTag returned NULL\n");
225 if (!skip(Memory
!= NULL
, "No memory\n"))
227 ok((ULONG_PTR
)Memory
% PAGE_SIZE
== 0,
228 "Allocation %p is badly aligned\n",
230 RefCount
= GetRefCount(Process
);
231 ok_eq_long(RefCount
, InitialRefCount
);
232 ExFreePoolWithTag(Memory
, 'tQmK');
233 RefCount
= GetRefCount(Process
);
234 ok_eq_long(RefCount
, InitialRefCount
);
237 /* Function raises by default */
239 Memory
= ExAllocatePoolWithQuotaTag(PagedPool
,
243 ExFreePoolWithTag(Memory
, 'tQmK');
244 KmtEndSeh(STATUS_INSUFFICIENT_RESOURCES
);
246 /* Function returns NULL with POOL_QUOTA_FAIL_INSTEAD_OF_RAISE */
248 Memory
= ExAllocatePoolWithQuotaTag(PagedPool
| POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
,
251 ok(Memory
== NULL
, "Successfully got 2GB block: %p\n", Memory
);
253 ExFreePoolWithTag(Memory
, 'tQmK');
254 KmtEndSeh(STATUS_SUCCESS
);