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