ReactOS  0.4.12-dev-418-g3df31a8
ExPools.c File Reference
#include <kmt_test.h>
#include <debug.h>
Include dependency graph for ExPools.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define TAG_POOLTEST   'tstP'
 
#define BASE_POOL_TYPE_MASK   1
 
#define QUOTA_POOL_MASK   8
 

Functions

static LONG GetRefCount (_In_ PVOID Object)
 
static VOID PoolsTest (VOID)
 
static VOID PoolsCorruption (VOID)
 
static VOID TestPoolTags (VOID)
 
static VOID TestPoolQuota (VOID)
 
static VOID TestBigPoolExpansion (VOID)
 
 START_TEST (ExPools)
 

Macro Definition Documentation

◆ BASE_POOL_TYPE_MASK

#define BASE_POOL_TYPE_MASK   1

Definition at line 15 of file ExPools.c.

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file ExPools.c.

◆ QUOTA_POOL_MASK

#define QUOTA_POOL_MASK   8

Definition at line 16 of file ExPools.c.

◆ TAG_POOLTEST

#define TAG_POOLTEST   'tstP'

Definition at line 13 of file ExPools.c.

Function Documentation

◆ GetRefCount()

static LONG GetRefCount ( _In_ PVOID  Object)
static

Definition at line 20 of file ExPools.c.

22 {
24  return Header->PointerCount;
25 }
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
Definition: Header.h:8
static IUnknown Object
Definition: main.c:512

Referenced by TestPoolQuota().

◆ PoolsCorruption()

static VOID PoolsCorruption ( VOID  )
static

Definition at line 112 of file ExPools.c.

113 {
114  PULONG Ptr;
115  ULONG AllocSize;
116 
117  // start with non-paged pool
118  AllocSize = 4096 + 0x10;
120 
121  // touch all bytes, it shouldn't cause an exception
122  RtlZeroMemory(Ptr, AllocSize);
123 
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
128  _SEH2_TRY
129  {
130  TestPtr = (PULONG)((PUCHAR)Ptr + AllocSize);
131  //Ptr[4] = 0xd33dbeef;
132  *TestPtr = 0xd33dbeef;
133  }
135  {
136  /* Get the status */
138  } _SEH2_END;
139 
140  ok(Status == STATUS_ACCESS_VIOLATION, "Exception should occur, but got Status 0x%08lX\n", Status);
141 
142  // test overrun in a distant byte range, but within 4096KB
143  _SEH2_TRY
144  {
145  Ptr[2020] = 0xdeadb33f;
146  }
148  {
149  /* Get the status */
151  } _SEH2_END;
152 
153  ok(Status == STATUS_ACCESS_VIOLATION, "Exception should occur, but got Status 0x%08lX\n", Status);
154 #endif
155 
156  // free the pool
158 }
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ok(value,...)
Definition: CComObject.cpp:34
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#define TAG_POOLTEST
Definition: ExPools.c:13
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12

Referenced by START_TEST().

◆ PoolsTest()

static VOID PoolsTest ( VOID  )
static

Definition at line 27 of file ExPools.c.

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  {
105  ExFreePoolWithTag(Allocs[i], TAG_POOLTEST);
106  }
107 
108 
110 }
_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 ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TAG_POOLTEST
Definition: ExPools.c:13
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( ExPools  )

Definition at line 308 of file ExPools.c.

309 {
310  PoolsTest();
311  PoolsCorruption();
312  TestPoolTags();
313  TestPoolQuota();
315 }
static VOID TestBigPoolExpansion(VOID)
Definition: ExPools.c:269
static VOID PoolsCorruption(VOID)
Definition: ExPools.c:112
static VOID TestPoolTags(VOID)
Definition: ExPools.c:162
static VOID TestPoolQuota(VOID)
Definition: ExPools.c:189
static VOID PoolsTest(VOID)
Definition: ExPools.c:27

◆ TestBigPoolExpansion()

static VOID TestBigPoolExpansion ( VOID  )
static

Definition at line 269 of file ExPools.c.

270 {
272  PVOID *BigAllocations;
273  const ULONG MaxAllocations = 1024 * 128;
274  ULONG NumAllocations;
275 
277  {
278  BigAllocations = ExAllocatePoolWithTag(PoolType,
279  MaxAllocations * sizeof(*BigAllocations),
280  'ABmK');
281 
282  /* Allocate a lot of pages (== big pool allocations) */
283  for (NumAllocations = 0; NumAllocations < MaxAllocations; NumAllocations++)
284  {
285  BigAllocations[NumAllocations] = ExAllocatePoolWithTag(PoolType,
286  PAGE_SIZE,
287  'aPmK');
288  if (BigAllocations[NumAllocations] == NULL)
289  {
290  NumAllocations--;
291  break;
292  }
293  }
294 
295  trace("Got %lu allocations for PoolType %d\n", NumAllocations, PoolType);
296 
297  /* Free them */
298  for (; NumAllocations < MaxAllocations; NumAllocations--)
299  {
300  ASSERT(BigAllocations[NumAllocations] != NULL);
301  ExFreePoolWithTag(BigAllocations[NumAllocations],
302  'aPmK');
303  }
304  ExFreePoolWithTag(BigAllocations, 'ABmK');
305  }
306 }
#define trace(...)
Definition: kmt_test.h:217
smooth NULL
Definition: ftsmooth.c:416
INT POOL_TYPE
Definition: typedefs.h:76
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444

Referenced by START_TEST().

◆ TestPoolQuota()

static VOID TestPoolQuota ( VOID  )
static

Definition at line 189 of file ExPools.c.

190 {
192  PEPROCESS StoredProcess;
193  PVOID Memory;
194  LONG InitialRefCount;
195  LONG RefCount;
197 
198  InitialRefCount = GetRefCount(Process);
199 
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 */
203  sizeof(LIST_ENTRY),
204  'tQmK');
205  ok(Memory != NULL, "ExAllocatePoolWithQuotaTag returned NULL\n");
206  if (!skip(Memory != NULL, "No memory\n"))
207  {
208  ok((ULONG_PTR)Memory % sizeof(LIST_ENTRY) == 0,
209  "Allocation %p is badly aligned\n",
210  Memory);
211  RefCount = GetRefCount(Process);
212  ok_eq_long(RefCount, InitialRefCount + 1);
213 
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);
217 
218  /* Pool type should have QUOTA_POOL_MASK set */
220  ok(PoolType != 0, "PoolType is 0\n");
221  PoolType--;
222  ok(PoolType & QUOTA_POOL_MASK, "PoolType = %x\n", PoolType);
223  ok((PoolType & BASE_POOL_TYPE_MASK) == PagedPool, "PoolType = %x\n", PoolType);
224 
225  ExFreePoolWithTag(Memory, 'tQmK');
226  RefCount = GetRefCount(Process);
227  ok_eq_long(RefCount, InitialRefCount);
228  }
229 
230  /* Large allocations are page-aligned, don't reference the process */
232  PAGE_SIZE,
233  'tQmK');
234  ok(Memory != NULL, "ExAllocatePoolWithQuotaTag returned NULL\n");
235  if (!skip(Memory != NULL, "No memory\n"))
236  {
237  ok((ULONG_PTR)Memory % PAGE_SIZE == 0,
238  "Allocation %p is badly aligned\n",
239  Memory);
240  RefCount = GetRefCount(Process);
241  ok_eq_long(RefCount, InitialRefCount);
242  ExFreePoolWithTag(Memory, 'tQmK');
243  RefCount = GetRefCount(Process);
244  ok_eq_long(RefCount, InitialRefCount);
245  }
246 
247  /* Function raises by default */
248  KmtStartSeh()
250  0x7FFFFFFF,
251  'tQmK');
252  if (Memory)
253  ExFreePoolWithTag(Memory, 'tQmK');
255 
256  /* Function returns NULL with POOL_QUOTA_FAIL_INSTEAD_OF_RAISE */
257  KmtStartSeh()
259  0x7FFFFFFF,
260  'tQmK');
261  ok(Memory == NULL, "Successfully got 2GB block: %p\n", Memory);
262  if (Memory)
263  ExFreePoolWithTag(Memory, 'tQmK');
265 }
static unsigned int block
Definition: xmlmemory.c:118
static BYTE Memory[0x20]
Definition: ps2.c:54
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID NTAPI ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: expool.c:2928
#define ok_eq_pointer(value, expected)
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:283
GLdouble n
Definition: glext.h:7729
static LONG GetRefCount(_In_ PVOID Object)
Definition: ExPools.c:20
uint32_t ULONG_PTR
Definition: typedefs.h:63
long LONG
Definition: pedump.c:60
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
#define ok(value,...)
Definition: CComObject.cpp:34
if(!(yy_init))
Definition: macro.lex.yy.c:717
USHORT KmtGetPoolType(PVOID Memory)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
#define KmtStartSeh()
Definition: kmt_test.h:277
#define QUOTA_POOL_MASK
Definition: ExPools.c:16
unsigned short USHORT
Definition: pedump.c:61
#define skip(...)
Definition: CString.cpp:57
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
#define GB
Definition: setuplib.h:54
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
GLfloat GLfloat p
Definition: glext.h:8902
#define LIST_ENTRY(type)
Definition: queue.h:175
return STATUS_SUCCESS
Definition: btrfs.c:2725
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
#define ok_eq_long(value, expected)
Definition: kmt_test.h:240

Referenced by START_TEST().

◆ TestPoolTags()

static VOID TestPoolTags ( VOID  )
static

Definition at line 162 of file ExPools.c.

163 {
164  PVOID Memory;
165 
166  Memory = ExAllocatePoolWithTag(PagedPool, 8, 'MyTa');
167  ok_eq_tag(KmtGetPoolTag(Memory), 'MyTa');
168  ExFreePoolWithTag(Memory, 'MyTa');
169 
171  ok_eq_tag(KmtGetPoolTag(Memory), 'TooL');
172  ExFreePoolWithTag(Memory, 'MyTa');
173 
174  Memory = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE - 3 * sizeof(PVOID), 'MyTa');
175  ok_eq_tag(KmtGetPoolTag(Memory), 'TooL');
176  ExFreePoolWithTag(Memory, 'MyTa');
177 
178  Memory = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE - 4 * sizeof(PVOID) + 1, 'MyTa');
179  ok_eq_tag(KmtGetPoolTag(Memory), 'TooL');
180  ExFreePoolWithTag(Memory, 'MyTa');
181 
182  Memory = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE - 4 * sizeof(PVOID), 'MyTa');
183  ok_eq_tag(KmtGetPoolTag(Memory), 'MyTa');
184  ExFreePoolWithTag(Memory, 'MyTa');
185 }
static BYTE Memory[0x20]
Definition: ps2.c:54
#define ok_eq_tag(value, expected)
Definition: kmt_test.h:263
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ULONG KmtGetPoolTag(PVOID Memory)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by START_TEST().