ReactOS 0.4.16-dev-1946-g52006dd
ExPools.c
Go to the documentation of this file.
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#include <kmt_test.h>
9
10#define NDEBUG
11#include <debug.h>
12
13#define TAG_POOLTEST 'tstP'
14
15#define BASE_POOL_TYPE_MASK 3
16#define QUOTA_POOL_MASK 8
17
18static
19LONG
22{
24 return Header->PointerCount;
25}
26
28{
29 PVOID Ptr;
30 ULONG AllocSize, i, AllocNumber;
31 PVOID *Allocs;
32
33 // Stress-test nonpaged pool
34 for (i=1; i<10000; i++)
35 {
36 // make up some increasing, a bit irregular size
37 AllocSize = i*10;
38
39 if (i % 10)
40 AllocSize++;
41
42 if (i % 25)
43 AllocSize += 13;
44
45 // start with non-paged pool
47
48 // it may fail due to no-memory condition
49 if (!Ptr) break;
50
51 // try to fully fill it
52 RtlFillMemory(Ptr, AllocSize, 0xAB);
53
54 // free it
56 }
57
58 // now paged one
59 for (i=1; i<10000; i++)
60 {
61 // make up some increasing, a bit irregular size
62 AllocSize = i*50;
63
64 if (i % 10)
65 AllocSize++;
66
67 if (i % 25)
68 AllocSize += 13;
69
70 // start with non-paged pool
72
73 // it may fail due to no-memory condition
74 if (!Ptr) break;
75
76 // try to fully fill it
77 RtlFillMemory(Ptr, AllocSize, 0xAB);
78
79 // free it
81 }
82
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");
87
88 Ptr = ExAllocatePoolWithTag(PagedPool, AllocSize, TAG_POOLTEST);
89 ok(Ptr == NULL, "Allocating 2Gb of paged pool should fail\n");*/
90
91 // now test allocating lots of small/medium blocks
92 AllocNumber = 100000;
93 Allocs = ExAllocatePoolWithTag(PagedPool, sizeof(*Allocs) * AllocNumber, TAG_POOLTEST);
94
95 // alloc blocks
96 for (i=0; i<AllocNumber; i++)
97 {
98 AllocSize = 42;
99 Allocs[i] = ExAllocatePoolWithTag(NonPagedPool, AllocSize, TAG_POOLTEST);
100 }
101
102 // now free them
103 for (i=0; i<AllocNumber; i++)
104 {
106 }
107
108
110}
111
112static
113VOID
115{
117
120 ExFreePoolWithTag(Memory, 'MyTa');
121
124 ExFreePoolWithTag(Memory, 'MyTa');
125
126 Memory = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE - 3 * sizeof(PVOID), 'MyTa');
128 ExFreePoolWithTag(Memory, 'MyTa');
129
130 Memory = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE - 4 * sizeof(PVOID) + 1, 'MyTa');
132 ExFreePoolWithTag(Memory, 'MyTa');
133
134 Memory = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE - 4 * sizeof(PVOID), 'MyTa');
136 ExFreePoolWithTag(Memory, 'MyTa');
137}
138
139static
140VOID
142{
145 LONG InitialRefCount;
146 LONG RefCount;
148
149 InitialRefCount = GetRefCount(Process);
150
151 /* We get some memory from this function, and it's properly aligned.
152 * Also, it takes a reference to the process, and releases it on free */
154 sizeof(LIST_ENTRY),
155 'tQmK');
156 ok(Memory != NULL, "ExAllocatePoolWithQuotaTag returned NULL\n");
157 if (!skip(Memory != NULL, "No memory\n"))
158 {
159 ok((ULONG_PTR)Memory % sizeof(LIST_ENTRY) == 0,
160 "Allocation %p is badly aligned\n",
161 Memory);
162 RefCount = GetRefCount(Process);
163 ok_eq_long(RefCount, InitialRefCount + 1);
164
165#ifdef _M_IX86
167 {
168 /* For x86 NT 6.2 and older: a pointer to the process is found right before the next pool header */
169 PEPROCESS StoredProcess = ((PVOID *)((ULONG_PTR)Memory + 2 * sizeof(LIST_ENTRY)))[-1];
170 ok_eq_pointer(StoredProcess, Process);
171 }
172#endif
173
174 /* Pool type should have QUOTA_POOL_MASK set */
176 ok(PoolType != 0, "PoolType is 0\n");
177 PoolType--;
178 ok(PoolType & QUOTA_POOL_MASK, "PoolType = %x\n", PoolType);
179 ok((PoolType & BASE_POOL_TYPE_MASK) == PagedPool || // Win2k3
180 (PoolType & BASE_POOL_TYPE_MASK) == NonPagedPoolMustSucceed, // Vista+ promotes the memory allocation
181 "PoolType = %x\n", PoolType);
182
183 ExFreePoolWithTag(Memory, 'tQmK');
184 RefCount = GetRefCount(Process);
185 ok_eq_long(RefCount, InitialRefCount);
186 }
187
188 /* Large allocations are page-aligned, don't reference the process */
190 PAGE_SIZE,
191 'tQmK');
192 ok(Memory != NULL, "ExAllocatePoolWithQuotaTag returned NULL\n");
193 if (!skip(Memory != NULL, "No memory\n"))
194 {
196 "Allocation %p is badly aligned\n",
197 Memory);
198 RefCount = GetRefCount(Process);
199 ok_eq_long(RefCount, InitialRefCount);
200 ExFreePoolWithTag(Memory, 'tQmK');
201 RefCount = GetRefCount(Process);
202 ok_eq_long(RefCount, InitialRefCount);
203 }
204
205#ifdef _WIN64
208 0x7FFFFFFF,
209 'tQmK');
210 ok(Memory != NULL, "Failed to get 2GB block: %p\n", Memory);
211 if (Memory)
212 ExFreePoolWithTag(Memory, 'tQmK');
214#else
215 /* Function raises by default */
218 0x7FFFFFFF,
219 'tQmK');
220 if (Memory)
221 ExFreePoolWithTag(Memory, 'tQmK');
223
224 /* Function returns NULL with POOL_QUOTA_FAIL_INSTEAD_OF_RAISE */
227 0x7FFFFFFF,
228 'tQmK');
229 ok(Memory == NULL, "Successfully got 2GB block: %p\n", Memory);
230 if (Memory)
231 ExFreePoolWithTag(Memory, 'tQmK');
233#endif // _WIN64
234}
235
236static
237VOID
239{
241 PVOID *BigAllocations;
242 const ULONG MaxAllocations = 1024 * 128;
243 ULONG NumAllocations;
244
246 {
247 BigAllocations = ExAllocatePoolWithTag(PoolType,
248 MaxAllocations * sizeof(*BigAllocations),
249 'ABmK');
250
251 /* Allocate a lot of pages (== big pool allocations) */
252 for (NumAllocations = 0; NumAllocations < MaxAllocations; NumAllocations++)
253 {
254 BigAllocations[NumAllocations] = ExAllocatePoolWithTag(PoolType,
255 PAGE_SIZE,
256 'aPmK');
257 if (BigAllocations[NumAllocations] == NULL)
258 {
259 NumAllocations--;
260 break;
261 }
262 }
263
264 trace("Got %lu allocations for PoolType %d\n", NumAllocations, PoolType);
265
266 /* Free them */
267 for (; NumAllocations < MaxAllocations; NumAllocations--)
268 {
269 ASSERT(BigAllocations[NumAllocations] != NULL);
270 ExFreePoolWithTag(BigAllocations[NumAllocations],
271 'aPmK');
272 }
273 ExFreePoolWithTag(BigAllocations, 'ABmK');
274 }
275}
276
278{
279 PoolsTest();
280 TestPoolTags();
283}
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
static VOID PoolsTest(VOID)
Definition: ExPools.c:27
static VOID TestBigPoolExpansion(VOID)
Definition: ExPools.c:238
static VOID TestPoolTags(VOID)
Definition: ExPools.c:114
static VOID TestPoolQuota(VOID)
Definition: ExPools.c:141
#define TAG_POOLTEST
Definition: ExPools.c:13
static LONG GetRefCount(_In_ PVOID Object)
Definition: ExPools.c:20
#define QUOTA_POOL_MASK
Definition: ExPools.c:16
#define ok_eq_pointer(value, expected)
Definition: apitest.h:116
#define ok_eq_long(value, expected)
Definition: apitest.h:119
#define ok_eq_tag(value, expected)
Definition: apitest.h:142
#define GetNTVersion()
Definition: apitest.h:17
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
Definition: Header.h:9
#define NULL
Definition: types.h:112
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:603
#define KmtStartSeh()
Definition: kmt_test.h:285
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:291
USHORT KmtGetPoolType(PVOID Memory)
ULONG KmtGetPoolTag(PVOID Memory)
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
#define _In_
Definition: no_sal2.h:158
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: typedefs.h:120
#define LIST_ENTRY(type)
Definition: queue.h:175
INT POOL_TYPE
Definition: typedefs.h:78
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3821
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169
#define ExAllocatePoolWithQuotaTag(a, b, c)
Definition: exfuncs.h:530
#define POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
@ NonPagedPoolMustSucceed
Definition: ketypes.h:932
#define PsGetCurrentProcess
Definition: psfuncs.h:17