[NTDLL_APITEST] Add test for invalid pointer
[reactos.git] / rostests / apitests / ntdll / RtlReAllocateHeap.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for RtlReAllocateHeap
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <apitest.h>
9 #include <ndk/rtlfuncs.h>
10
11 static
12 BOOLEAN
13 CheckBuffer(
14 PVOID Buffer,
15 SIZE_T Size,
16 UCHAR Value)
17 {
18 PUCHAR Array = Buffer;
19 SIZE_T i;
20
21 for (i = 0; i < Size; i++)
22 if (Array[i] != Value)
23 {
24 trace("Expected %x, found %x at offset %lu\n", Value, Array[i], (ULONG)i);
25 return FALSE;
26 }
27 return TRUE;
28 }
29
30 static
31 BOOLEAN
32 ReAllocBuffer(
33 PUCHAR *Buffer,
34 SIZE_T Size,
35 SIZE_T *OldSizePtr,
36 PCSTR Action)
37 {
38 PUCHAR NewBuffer;
39 SIZE_T OldSize = *OldSizePtr;
40
41 RtlFillMemory(*Buffer, OldSize, 0x7a);
42 NewBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
43 HEAP_ZERO_MEMORY,
44 *Buffer,
45 Size);
46 if (!NewBuffer)
47 {
48 skip("RtlReAllocateHeap failed for size %lu (%s)\n", Size, Action);
49 return FALSE;
50 }
51 *Buffer = NewBuffer;
52 ok_hex(RtlSizeHeap(RtlGetProcessHeap(), 0, NewBuffer), Size);
53 if (OldSize < Size)
54 {
55 ok(CheckBuffer(NewBuffer, OldSize, 0x7a), "CheckBuffer failed at size 0x%lx -> 0x%lx\n", OldSize, Size);
56 ok(CheckBuffer(NewBuffer + OldSize, Size - OldSize, 0), "HEAP_ZERO_MEMORY not respected for 0x%lx -> 0x%lx\n", OldSize, Size);
57 }
58 else
59 {
60 ok(CheckBuffer(NewBuffer, Size, 0x7a), "CheckBuffer failed at size 0x%lx -> 0x%lx\n", OldSize, Size);
61 }
62 *OldSizePtr = Size;
63 return TRUE;
64 }
65
66 START_TEST(RtlReAllocateHeap)
67 {
68 PUCHAR Buffer = NULL;
69 SIZE_T OldSize = 0;
70 SIZE_T Size;
71 BOOLEAN Continue = TRUE;
72 BOOLEAN Success;
73 PVOID UserValue;
74 ULONG UserFlags;
75 PVOID Buffer2;
76
77 OldSize = 0x100;
78 Buffer = RtlReAllocateHeap(RtlGetProcessHeap(),
79 HEAP_ZERO_MEMORY,
80 NULL,
81 OldSize);
82 ok(Buffer == NULL, "RtlReAllocateHeap succeeded for NULL\n");
83 if (Buffer)
84 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
85
86 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
87 HEAP_ZERO_MEMORY,
88 OldSize);
89 if (!Buffer)
90 {
91 skip("RtlAllocateHeap failed for size %lu\n", OldSize);
92 return;
93 }
94 ok(CheckBuffer(Buffer, OldSize, 0), "HEAP_ZERO_MEMORY not respected for 0x%lx\n", OldSize);
95
96 for (Size = 0x78000; Size < 0x90000 && Continue; Size += 0x100)
97 {
98 Continue = ReAllocBuffer(&Buffer, Size, &OldSize, "growing");
99 }
100
101 /* and back again */
102 for (Size -= 0x100; Size >= 0x78000 && Continue; Size -= 0x100)
103 {
104 Continue = ReAllocBuffer(&Buffer, Size, &OldSize, "shrinking");
105 }
106 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
107
108 /* Now make sure user flags/values get preserved */
109 OldSize = 0x100;
110 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
111 HEAP_ZERO_MEMORY | HEAP_SETTABLE_USER_VALUE | HEAP_SETTABLE_USER_FLAG2,
112 OldSize);
113 if (!Buffer)
114 {
115 skip("RtlAllocateHeap failed for size %lu\n", OldSize);
116 return;
117 }
118
119 UserValue = InvalidPointer;
120 UserFlags = 0x55555555;
121 Success = RtlGetUserInfoHeap(RtlGetProcessHeap(),
122 0,
123 Buffer,
124 &UserValue,
125 &UserFlags);
126 ok(Success == TRUE, "RtlGetUserInfoHeap returned %u\n", Success);
127 ok(UserValue == NULL, "UserValue = %p\n", UserValue);
128 ok(UserFlags == HEAP_SETTABLE_USER_FLAG2, "UserFlags = %lx\n", UserFlags);
129
130 Success = RtlSetUserFlagsHeap(RtlGetProcessHeap(),
131 0,
132 Buffer,
133 HEAP_SETTABLE_USER_FLAG1 | HEAP_SETTABLE_USER_FLAG2,
134 HEAP_SETTABLE_USER_FLAG3);
135 ok(Success == TRUE, "RtlSetUserFlagsHeap returned %u\n", Success);
136
137 Success = RtlSetUserValueHeap(RtlGetProcessHeap(),
138 0,
139 Buffer,
140 &UserValue);
141 ok(Success == TRUE, "RtlSetUserValueHeap returned %u\n", Success);
142
143 UserValue = InvalidPointer;
144 UserFlags = 0x55555555;
145 Success = RtlGetUserInfoHeap(RtlGetProcessHeap(),
146 0,
147 Buffer,
148 &UserValue,
149 &UserFlags);
150 ok(Success == TRUE, "RtlGetUserInfoHeap returned %u\n", Success);
151 ok(UserValue == &UserValue, "UserValue = %p, expected %p\n", UserValue, &UserValue);
152 ok(UserFlags == HEAP_SETTABLE_USER_FLAG3, "UserFlags = %lx\n", UserFlags);
153
154 /* shrink (preserves flags) */
155 Buffer2 = RtlReAllocateHeap(RtlGetProcessHeap(),
156 HEAP_REALLOC_IN_PLACE_ONLY | HEAP_SETTABLE_USER_FLAG2,
157 Buffer,
158 OldSize / 2);
159 ok(Buffer2 == Buffer, "New Buffer is %p, expected %p\n", Buffer2, Buffer);
160 if (Buffer2) Buffer = Buffer2;
161 UserValue = InvalidPointer;
162 UserFlags = 0x55555555;
163 Success = RtlGetUserInfoHeap(RtlGetProcessHeap(),
164 0,
165 Buffer,
166 &UserValue,
167 &UserFlags);
168 ok(Success == TRUE, "RtlGetUserInfoHeap returned %u\n", Success);
169 ok(UserValue == &UserValue, "UserValue = %p, expected %p\n", UserValue, &UserValue);
170 ok(UserFlags == HEAP_SETTABLE_USER_FLAG3, "UserFlags = %lx\n", UserFlags);
171
172 /* grow (overwrites flags) */
173 Buffer2 = RtlReAllocateHeap(RtlGetProcessHeap(),
174 HEAP_REALLOC_IN_PLACE_ONLY | HEAP_SETTABLE_USER_FLAG1,
175 Buffer,
176 OldSize / 4 * 3);
177 ok(Buffer2 == Buffer, "New Buffer is %p, expected %p\n", Buffer2, Buffer);
178 if (Buffer2) Buffer = Buffer2;
179 UserValue = InvalidPointer;
180 UserFlags = 0x55555555;
181 Success = RtlGetUserInfoHeap(RtlGetProcessHeap(),
182 0,
183 Buffer,
184 &UserValue,
185 &UserFlags);
186 ok(Success == TRUE, "RtlGetUserInfoHeap returned %u\n", Success);
187 ok(UserValue == &UserValue, "UserValue = %p, expected %p\n", UserValue, &UserValue);
188 ok(UserFlags == HEAP_SETTABLE_USER_FLAG1, "UserFlags = %lx\n", UserFlags);
189
190 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
191 }