1 /*
2  * PROJECT:         ReactOS API Tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Stress Test for virtual memory allocation
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 static PVOID Allocations[4096] = { NULL };
11 static ULONG CurrentAllocation = 0;
12 
13 static
14 VOID
15 ValidateAllocations(VOID)
16 {
17     ULONG i;
18 
19     ASSERT(CurrentAllocation < sizeof(Allocations) / sizeof(Allocations[0]));
20     for (i = 0; i < CurrentAllocation; ++i)
21     {
22         PUCHAR UserBuffer = Allocations[i];
23         SIZE_T AllocationSize;
24         SIZE_T DataSize;
25 
26         if (UserBuffer == NULL)
27             continue;
28 
29         AllocationSize = ((PSIZE_T)UserBuffer)[-2];
30         DataSize = ((PSIZE_T)UserBuffer)[-1];
31         ASSERT(AllocationSize != 0);
32         ASSERT(AllocationSize % PAGE_SIZE == 0);
33         ASSERT(DataSize != 0);
34         ASSERT(((SIZE_T)UserBuffer + DataSize) % PAGE_SIZE == 0);
35     }
36 }
37 
38 static
39 PVOID
40 Allocate(
41     SIZE_T DataSize)
42 {
43     NTSTATUS Status;
44     PVOID AllocationStart = NULL;
45     SIZE_T AllocationSize = PAGE_ROUND_UP(DataSize + PAGE_SIZE + 2 * sizeof(SIZE_T));
46     PVOID FirstPageStart;
47     SIZE_T NumberOfPages = AllocationSize / PAGE_SIZE;
48     SIZE_T Size;
49     PUCHAR UserBuffer;
50 
51     Status = NtAllocateVirtualMemory(NtCurrentProcess(), &AllocationStart, 0, &AllocationSize, MEM_RESERVE, PAGE_NOACCESS);
52 
53     if (!NT_SUCCESS(Status))
54         return NULL;
55 
56     FirstPageStart = (PUCHAR)AllocationStart + AllocationSize - PAGE_SIZE * NumberOfPages;
57     Size = (NumberOfPages - 1) * PAGE_SIZE;
58     Status = NtAllocateVirtualMemory(NtCurrentProcess(), &FirstPageStart, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
59     if (!NT_SUCCESS(Status))
60     {
61         AllocationSize = 0;
62         Status = NtFreeVirtualMemory(NtCurrentProcess(), &AllocationStart, &AllocationSize, MEM_RELEASE);
63         ASSERT(Status == STATUS_SUCCESS);
64         return NULL;
65     }
66     ASSERT(Size % sizeof(ULONG) == 0);
67     ASSERT(RtlCompareMemoryUlong(FirstPageStart, Size, 0) == Size);
68 
69     UserBuffer = AllocationStart;
70     UserBuffer += AllocationSize - PAGE_SIZE - DataSize;
71     RtlFillMemory(FirstPageStart, UserBuffer - (PUCHAR)FirstPageStart, 0xae);
72     RtlZeroMemory(UserBuffer, DataSize);
73     ((PSIZE_T)UserBuffer)[-2] = AllocationSize;
74     ((PSIZE_T)UserBuffer)[-1] = DataSize;
75 
76     Allocations[CurrentAllocation++] = UserBuffer;
77     ValidateAllocations();
78     return UserBuffer;
79 }
80 
81 static
82 VOID
83 Free(
84     PVOID UserBuffer)
85 {
86     NTSTATUS Status;
87     PVOID AllocationStart;
88     SIZE_T Zero = 0;
89     SIZE_T AllocationSize;
90     SIZE_T DataSize;
91     ULONG i;
92 
93     AllocationSize = ((PSIZE_T)UserBuffer)[-2];
94     DataSize = ((PSIZE_T)UserBuffer)[-1];
95     ASSERT(DataSize != 0);
96 
97     AllocationStart = (PUCHAR)UserBuffer + DataSize + PAGE_SIZE - AllocationSize;
98     ASSERT((SIZE_T)AllocationStart % PAGE_SIZE == 0);
99 
100     RtlFillMemory(UserBuffer, DataSize, 0xbe);
101     ((PSIZE_T)UserBuffer)[-1] = 0;
102     ((PSIZE_T)UserBuffer)[-2] = 0xFAFBFCFD;
103 
104     for (i = 0; i < CurrentAllocation; ++i)
105         if (Allocations[i] == UserBuffer)
106         {
107             Allocations[i] = NULL;
108             break;
109         }
110     ValidateAllocations();
111 
112     Status = NtFreeVirtualMemory(NtCurrentProcess(), &AllocationStart, &Zero, MEM_RELEASE);
113     ASSERT(Status == STATUS_SUCCESS);
114 }
115 
116 static
117 PVOID
118 ReAllocate(
119     PVOID OldUserBuffer,
120     SIZE_T NewDataSize)
121 {
122     PVOID NewUserBuffer;
123     SIZE_T OldDataSize;
124 
125     OldDataSize = ((PSIZE_T)OldUserBuffer)[-1];
126     ASSERT(OldDataSize != 0);
127 
128     NewUserBuffer = Allocate(NewDataSize);
129     ASSERT(((PSIZE_T)OldUserBuffer)[-1] == OldDataSize);
130     RtlCopyMemory(NewUserBuffer, OldUserBuffer, min(OldDataSize, NewDataSize));
131     ASSERT(((PSIZE_T)OldUserBuffer)[-1] == OldDataSize);
132     Free(OldUserBuffer);
133     return NewUserBuffer;
134 }
135 
136 static
137 VOID
138 AccessMemory1(
139     PVOID UserBuffer,
140     SIZE_T DataSize)
141 {
142     PBYTE Buffer = UserBuffer;
143     SIZE_T i;
144 
145     for (i = 0; i < DataSize; ++i)
146         Buffer[i] = LOBYTE(i);
147 }
148 
149 static
150 BOOLEAN
151 CheckMemory1(
152     PVOID UserBuffer,
153     SIZE_T DataSize)
154 {
155     PBYTE Buffer = UserBuffer;
156     SIZE_T i;
157 
158     for (i = 0; i < DataSize; ++i)
159         if (Buffer[i] != LOBYTE(i))
160         {
161             trace("Mismatch in region %p at index %lu. Value=%02x\n", UserBuffer, (ULONG)i, Buffer[i]);
162             ASSERT(FALSE);
163             return FALSE;
164         }
165     return TRUE;
166 }
167 
168 static
169 VOID
170 AccessMemory2(
171     PVOID UserBuffer,
172     SIZE_T DataSize)
173 {
174     PBYTE Buffer = UserBuffer;
175     SIZE_T i;
176 
177     for (i = 0; i < DataSize; ++i)
178         Buffer[i] = UCHAR_MAX - LOBYTE(i);
179 }
180 
181 static
182 BOOLEAN
183 CheckMemory2(
184     PVOID UserBuffer,
185     SIZE_T DataSize)
186 {
187     PBYTE Buffer = UserBuffer;
188     SIZE_T i;
189 
190     for (i = 0; i < DataSize; ++i)
191         if (Buffer[i] != UCHAR_MAX - LOBYTE(i))
192         {
193             trace("Mismatch in region %p at index %lu. Value=%02x\n", UserBuffer, (ULONG)i, Buffer[i]);
194             ASSERT(FALSE);
195             return FALSE;
196         }
197     return TRUE;
198 }
199 
200 VOID
201 CheckSize(ULONG_PTR Base, SIZE_T InSize, SIZE_T ExpectedSize)
202 {
203     NTSTATUS Status;
204     PVOID BaseAddress;
205     SIZE_T Size;
206 
207     /* Reserve memory */
208     BaseAddress = (PVOID)Base;
209     Size = InSize;
210     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
211                                      &BaseAddress,
212                                      0,
213                                      &Size,
214                                      MEM_RESERVE,
215                                      PAGE_NOACCESS);
216     ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed!\n");
217     ok(BaseAddress == (PVOID)(Base & ~((ULONG_PTR)0xFFFF)), "Got back wrong base address: %p\n", BaseAddress);
218     ok(Size == ExpectedSize, "Alloc of 0x%Ix: got back wrong size: 0x%Ix, expected 0x%Ix\n", InSize, Size, ExpectedSize);
219     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
220     ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed!\n");
221 }
222 
223 VOID
224 CheckAlignment()
225 {
226     NTSTATUS Status;
227     PVOID BaseAddress;
228     SIZE_T Size;
229 
230     CheckSize(0x50000000, 0x0001, 0x1000);
231     CheckSize(0x50008000, 0x0001, 0x9000);
232     CheckSize(0x50000010, 0x1000, 0x2000);
233     CheckSize(0x50010000, 0x2000, 0x2000);
234     CheckSize(0x5000FFFF, 0x3000, 0x13000);
235     CheckSize(0x50001010, 0x7000, 0x9000);
236     CheckSize(0x50001010, 0xC000, 0xe000);
237 
238     /* Reserve memory not aligned to allocation granularity */
239     BaseAddress = UlongToPtr(0x50001010);
240     Size = 0x1000;
241     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
242                                      &BaseAddress,
243                                      0,
244                                      &Size,
245                                      MEM_RESERVE,
246                                      PAGE_NOACCESS);
247     ok_ntstatus(Status, STATUS_SUCCESS);
248     ok(BaseAddress == UlongToPtr(0x50000000), "Got back wrong base address: %p", BaseAddress);
249     ok(Size == 0x3000, "Got back wrong size: 0x%Ix", Size);
250 
251     /* Try to reserve again in the same 64k region */
252     BaseAddress = UlongToPtr(0x50008000);
253     Size = 0x1000;
254     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
255                                      &BaseAddress,
256                                      0,
257                                      &Size,
258                                      MEM_RESERVE,
259                                      PAGE_NOACCESS);
260     ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES);
261 
262     /* Commit memory */
263     BaseAddress = UlongToPtr(0x50002000);
264     Size = 0x1000;
265     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
266                                      &BaseAddress,
267                                      0,
268                                      &Size,
269                                      MEM_COMMIT,
270                                      PAGE_NOACCESS);
271     ok_ntstatus(Status, STATUS_SUCCESS);
272     ok(BaseAddress == UlongToPtr(0x50002000), "Got back wrong base address: %p", BaseAddress);
273     ok(Size == 0x1000, "Got back wrong size: 0x%Ix", Size);
274 
275     /* Commit the same address again with a different protection */
276     BaseAddress = UlongToPtr(0x50002000);
277     Size = 0x1000;
278     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
279                                      &BaseAddress,
280                                      0,
281                                      &Size,
282                                      MEM_COMMIT,
283                                      PAGE_READWRITE);
284     ok_ntstatus(Status, STATUS_SUCCESS);
285     ok(BaseAddress == UlongToPtr(0x50002000), "Got back wrong base address: %p", BaseAddress);
286     ok(Size == 0x1000, "Got back wrong size: 0x%Ix", Size);
287 
288     /* Commit memory at a too high address */
289     BaseAddress = UlongToPtr(0x50003000);
290     Size = 0x1000;
291     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
292                                      &BaseAddress,
293                                      0,
294                                      &Size,
295                                      MEM_COMMIT,
296                                      PAGE_NOACCESS);
297     ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES);
298 
299     /* Decommit the memory, even those pages that were not committed */
300     BaseAddress = UlongToPtr(0x50000000);
301     Size = 0x3000;
302     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_DECOMMIT);
303     ok_ntstatus(Status, STATUS_SUCCESS);
304 
305     /* Try to release memory in a different 64k region */
306     BaseAddress = UlongToPtr(0x50010000);
307     Size = 0x1000;
308     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
309     ok_ntstatus(Status, STATUS_MEMORY_NOT_ALLOCATED);
310 
311     /* Release the memory in the same 64k region at a different address */
312     BaseAddress = UlongToPtr(0x50008000);
313     Size = 0x1000;
314     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
315     ok_ntstatus(Status, STATUS_MEMORY_NOT_ALLOCATED);
316 
317     /* Release the memory at the correct address but with wrong size */
318     BaseAddress = UlongToPtr(0x50000000);
319     Size = 0x4000;
320     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
321     ok_ntstatus(Status, STATUS_UNABLE_TO_FREE_VM);
322 
323     /* Release the memory */
324     BaseAddress = UlongToPtr(0x50000000);
325     Size = 0x3000;
326     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
327     ok_ntstatus(Status, STATUS_SUCCESS);
328 
329     /* Reserve and commit at once */
330     BaseAddress = UlongToPtr(0x50004080);
331     Size = 0x1000;
332     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
333                                      &BaseAddress,
334                                      0,
335                                      &Size,
336                                      MEM_RESERVE | MEM_COMMIT,
337                                      PAGE_READWRITE);
338     ok_ntstatus(Status, STATUS_SUCCESS);
339     ok(BaseAddress == UlongToPtr(0x50000000), "Got back wrong base address: %p", BaseAddress);
340     ok(Size == 0x6000, "Got back wrong size: 0x%Ix", Size);
341 
342     _SEH2_TRY
343     {
344         *(int*)BaseAddress = 1;
345         *(int*)UlongToPtr(0x50004080) = 1;
346     }
347     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
348     {
349         ok(0, "Got exception\n");
350     }
351     _SEH2_END;
352 
353     /* Release the memory */
354     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
355     ok_ntstatus(Status, STATUS_SUCCESS);
356 
357 }
358 
359 static
360 VOID
361 CheckAdjacentVADs()
362 {
363     NTSTATUS Status;
364     PVOID BaseAddress;
365     SIZE_T Size;
366     MEMORY_BASIC_INFORMATION MemoryBasicInfo;
367 
368     /* Reserve a full 64k region */
369     BaseAddress = UlongToPtr(0x50000000);
370     Size = 0x10000;
371     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
372                                      &BaseAddress,
373                                      0,
374                                      &Size,
375                                      MEM_RESERVE,
376                                      PAGE_NOACCESS);
377     ok_ntstatus(Status, STATUS_SUCCESS);
378     if (!NT_SUCCESS(Status))
379         return;
380 
381     /* Reserve another 64k region, but with 64k between */
382     BaseAddress = UlongToPtr(0x50020000);
383     Size = 0x10000;
384     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
385                                      &BaseAddress,
386                                      0,
387                                      &Size,
388                                      MEM_RESERVE,
389                                      PAGE_NOACCESS);
390     ok_ntstatus(Status, STATUS_SUCCESS);
391     if (!NT_SUCCESS(Status))
392         return;
393 
394     /* Try to free the whole at once */
395     BaseAddress = UlongToPtr(0x50000000);
396     Size = 0x30000;
397     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
398     ok_ntstatus(Status, STATUS_UNABLE_TO_FREE_VM);
399 
400     /* Reserve the part in the middle */
401     BaseAddress = UlongToPtr(0x50010000);
402     Size = 0x10000;
403     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
404                                      &BaseAddress,
405                                      0,
406                                      &Size,
407                                      MEM_RESERVE,
408                                      PAGE_NOACCESS);
409     ok_ntstatus(Status, STATUS_SUCCESS);
410 
411     /* Try to commit memory covering 2 allocations */
412     BaseAddress = UlongToPtr(0x50004000);
413     Size = 0x10000;
414     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
415                                      &BaseAddress,
416                                      0,
417                                      &Size,
418                                      MEM_COMMIT,
419                                      PAGE_NOACCESS);
420     ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES);
421 
422     /* Commit a page */
423     BaseAddress = UlongToPtr(0x50000000);
424     Size = 0x1000;
425     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
426                                      &BaseAddress,
427                                      0,
428                                      &Size,
429                                      MEM_COMMIT,
430                                      PAGE_READWRITE);
431     ok_ntstatus(Status, STATUS_SUCCESS);
432 
433     /* Commit another page */
434     BaseAddress = UlongToPtr(0x50002000);
435     Size = 0x1000;
436     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
437                                      &BaseAddress,
438                                      0,
439                                      &Size,
440                                      MEM_COMMIT,
441                                      PAGE_NOACCESS);
442     ok_ntstatus(Status, STATUS_SUCCESS);
443 
444     _SEH2_TRY
445     {
446         *(int*)UlongToPtr(0x50000000) = 1;
447     }
448     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
449     {
450         ok(0, "Got exception\n");
451     }
452     _SEH2_END;
453 
454     _SEH2_TRY
455     {
456         (void)*(volatile int*)UlongToPtr(0x50002000);
457     }
458     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
459     {
460         Status = _SEH2_GetExceptionCode();
461     }
462     _SEH2_END;
463     ok_ntstatus(Status, STATUS_ACCESS_VIOLATION);
464 
465     /* Allocate 3 pages, on top of the previous 2 */
466     BaseAddress = UlongToPtr(0x50000000);
467     Size = 0x3000;
468     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
469                                      &BaseAddress,
470                                      0,
471                                      &Size,
472                                      MEM_COMMIT,
473                                      PAGE_READONLY);
474     ok_ntstatus(Status, STATUS_SUCCESS);
475 
476     _SEH2_TRY
477     {
478         *(int*)UlongToPtr(0x50000000) = 1;
479     }
480     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
481     {
482         Status = _SEH2_GetExceptionCode();
483     }
484     _SEH2_END;
485     ok_ntstatus(Status, STATUS_ACCESS_VIOLATION);
486 
487     /* Commit a page at the end of the first region */
488     BaseAddress = UlongToPtr(0x5000F000);
489     Size = 0x1000;
490     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
491                                      &BaseAddress,
492                                      0,
493                                      &Size,
494                                      MEM_COMMIT,
495                                      PAGE_READWRITE);
496     ok_ntstatus(Status, STATUS_SUCCESS);
497     ok_ptr(BaseAddress, UlongToPtr(0x5000F000));
498 
499     /* See where is the base of this newly committed area
500      * (choose a base address in the middle of it) */
501     Status = NtQueryVirtualMemory(NtCurrentProcess(),
502                                   UlongToPtr(0x5000F700),
503                                   MemoryBasicInformation,
504                                   &MemoryBasicInfo,
505                                   sizeof(MemoryBasicInfo),
506                                   NULL);
507     ok_ntstatus(Status, STATUS_SUCCESS);
508     /* The base address is the beginning of the committed area */
509     ok_ptr(MemoryBasicInfo.BaseAddress, UlongToPtr(0x5000F000));
510     /* The allocation base address is the beginning of the whole region */
511     ok_ptr(MemoryBasicInfo.AllocationBase, UlongToPtr(0x50000000));
512     /* This is the protection of the memory when it was reserved. */
513     ok_long(MemoryBasicInfo.AllocationProtect, PAGE_NOACCESS);
514     /* This is the size of the committed region. (ie, smallest chunk size) */
515     ok_long(MemoryBasicInfo.RegionSize, 0x1000);
516     /* This is the state of the queried address */
517     ok_long(MemoryBasicInfo.State, MEM_COMMIT);
518     /* This is the protection of the queried address */
519     ok_long(MemoryBasicInfo.Protect, PAGE_READWRITE);
520     /* NtAllocateVirtualMemory makes it MEM_PRIVATE */
521     ok_long(MemoryBasicInfo.Type, MEM_PRIVATE);
522 
523     /* Try to free the whole region at once */
524     BaseAddress = UlongToPtr(0x50000000);
525     Size = 0x30000;
526     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
527     ok_ntstatus(Status, STATUS_UNABLE_TO_FREE_VM);
528 
529     BaseAddress = UlongToPtr(0x50000000);
530     Size = 0x10000;
531     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
532     ok_ntstatus(Status, STATUS_SUCCESS);
533 
534     BaseAddress = UlongToPtr(0x50010000);
535     Size = 0x10000;
536     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
537     ok_ntstatus(Status, STATUS_SUCCESS);
538 
539     BaseAddress = UlongToPtr(0x50020000);
540     Size = 0x10000;
541     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
542     ok_ntstatus(Status, STATUS_SUCCESS);
543 
544     /* Reserve 3 full 64k region */
545     BaseAddress = UlongToPtr(0x50000000);
546     Size = 0x30000;
547     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
548                                      &BaseAddress,
549                                      0,
550                                      &Size,
551                                      MEM_RESERVE,
552                                      PAGE_NOACCESS);
553     ok_ntstatus(Status, STATUS_SUCCESS);
554     if (!NT_SUCCESS(Status))
555         return;
556 
557     /* Release the 64k region in the middle */
558     BaseAddress = UlongToPtr(0x50010000);
559     Size = 0x10000;
560     Status = NtFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &Size, MEM_RELEASE);
561     ok_ntstatus(Status, STATUS_SUCCESS);
562 
563 }
564 
565 #define RUNS 32
566 
567 START_TEST(NtAllocateVirtualMemory)
568 {
569     PVOID Mem1, Mem2;
570     SIZE_T Size1, Size2;
571     ULONG i;
572     NTSTATUS Status;
573 
574     CheckAlignment();
575     CheckAdjacentVADs();
576 
577     /* Reserve memory below 0x10000 */
578     Mem1 = UlongToPtr(0xf000);
579     Size1 = 0x1000;
580     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
581                                      &Mem1,
582                                      0,
583                                      &Size1,
584                                      MEM_RESERVE,
585                                      PAGE_READWRITE);
586     ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2);
587 
588     /* Reserve memory at 0x10000 */
589     Mem1 = UlongToPtr(0x10000);
590     Size1 = 0x1000;
591     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
592                                      &Mem1,
593                                      0,
594                                      &Size1,
595                                      MEM_RESERVE,
596                                      PAGE_READWRITE);
597     ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES);
598 
599     Size1 = 32;
600     Mem1 = Allocate(Size1);
601     AccessMemory1(Mem1, Size1);
602     Size2 = 128;
603     Mem2 = Allocate(Size2);
604     AccessMemory2(Mem2, Size2);
605     for (i = 0; i < RUNS; ++i)
606     {
607         PVOID New;
608         ok(CheckMemory1(Mem1, Size1) == TRUE, "CheckMemory1 failure\n");
609         New = ReAllocate(Mem1, Size1 * 3 / 2);
610         if (New == NULL)
611         {
612             skip("Realloc failure\n");
613             break;
614         }
615         Mem1 = New;
616         ok(CheckMemory1(Mem1, Size1) == TRUE, "CheckMemory1 failure\n");
617         Size1 = Size1 * 3 / 2;
618         AccessMemory1(Mem1, Size1);
619 
620         ok(CheckMemory2(Mem2, Size2) == TRUE, "CheckMemory2 failure\n");
621         New = ReAllocate(Mem2, Size2 + 128);
622         if (New == NULL)
623         {
624             skip("Realloc failure\n");
625             break;
626         }
627         Mem2 = New;
628         ok(CheckMemory2(Mem2, Size2) == TRUE, "CheckMemory2 failure\n");
629         Size2 += 128;
630         AccessMemory2(Mem2, Size2);
631     }
632     ok(CheckMemory2(Mem2, Size2) == TRUE, "CheckMemory2 failure\n");
633     Free(Mem2);
634     ok(CheckMemory1(Mem1, Size1) == TRUE, "CheckMemory1 failure\n");
635     Free(Mem1);
636 }
637