2 * Unit test suite for memory allocation functions.
4 * Copyright 2002 Geoffrey Hausheer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "wine/test.h"
25 /* Currently Wine doesn't have macros for LocalDiscard and GlobalDiscard
26 so I am disableing the checks for them. These macros are equivalent
27 to reallocing '0' bytes, so we try that instead
29 #define DISCARD_DEFINED 0
31 /* The following functions don't have tests, because either I don't know how
32 to test them, or they are WinNT only, or require multiple threads.
33 Since the last two issues shouldn't really stop the tests from being
34 written, assume for now that it is all due to the first case
43 /* In addition, these features aren't being tested
45 HEAP_GENERATE_EXCEPTIONS
46 STATUS_ACCESS_VIOLATION (error code from HeapAlloc)
49 static void test_Heap(void)
54 LPVOID mem1,mem1a,mem3;
59 /* Retreive the page size for this system */
61 GetSystemInfo(&sysInfo);
62 ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size");
64 /* Create a Heap with a minimum and maximum size */
65 /* Note that Windows and Wine seem to behave a bit differently with respect
66 to memory allocation. In Windows, you can't access all the memory
67 specified in the heap (due to overhead), so choosing a reasonable maximum
68 size for the heap was done mostly by trial-and-error on Win2k. It may need
69 more tweaking for otherWindows variants.
71 memchunk=10*sysInfo.dwPageSize;
72 heap=HeapCreate((DWORD)NULL,2*memchunk,5*memchunk);
74 /* Check that HeapCreate allocated the right amount of ram */
76 /* Today HeapCreate seems to return a memory block larger than specified.
77 MSDN says the maximum heap size should be dwMaximumSize rounded up to the
80 mem1=HeapAlloc(heap,(DWORD)NULL,5*memchunk+1);
81 ok(mem1==NULL,"HeapCreate allocated more Ram than it should have");
83 HeapFree(heap,(DWORD)NULL,mem1);
87 /* Check that a normal alloc works */
88 mem1=HeapAlloc(heap,(DWORD)NULL,memchunk);
89 ok(mem1!=NULL,"HeapAlloc failed");
91 ok(HeapSize(heap,(DWORD)NULL,mem1)>=memchunk, "HeapAlloc should return a big enough memory block");
94 /* Check that a 'zeroing' alloc works */
95 mem2=(UCHAR *)HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk);
96 ok(mem2!=NULL,"HeapAlloc failed");
98 ok(HeapSize(heap,(DWORD)NULL,mem2)>=memchunk,"HeapAlloc should return a big enough memory block");
100 for(i=0;i<memchunk;i++) {
105 ok(!error,"HeapAlloc should have zeroed out it's allocated memory");
108 /* Check that HeapAlloc returns NULL when requested way too much memory */
109 mem3=HeapAlloc(heap,(DWORD)NULL,5*memchunk);
110 ok(mem3==NULL,"HeapAlloc should return NULL");
112 ok(HeapFree(heap,(DWORD)NULL,mem3),"HeapFree didn't pass successfully");
115 /* Check that HeapRealloc works */
116 mem2a=(UCHAR *)HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
117 ok(mem2a!=NULL,"HeapReAlloc failed");
119 ok(HeapSize(heap,(DWORD)NULL,mem2a)>=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed");
121 for(i=0;i<5*sysInfo.dwPageSize;i++) {
122 if(mem2a[memchunk+i]!=0) {
126 ok(!error,"HeapReAlloc should have zeroed out it's allocated memory");
129 /* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */
131 mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize);
137 ok(mem1a==NULL || error==0,"HeapReAlloc didn't honour HEAP_REALLOC_IN_PLACE_ONLY");
139 /* Check that HeapFree works correctly */
141 ok(HeapFree(heap,(DWORD)NULL,mem1a),"HeapFree failed");
143 ok(HeapFree(heap,(DWORD)NULL,mem1),"HeapFree failed");
146 ok(HeapFree(heap,(DWORD)NULL,mem2a),"HeapFree failed");
148 ok(HeapFree(heap,(DWORD)NULL,mem2),"HeapFree failed");
151 /* take just freed pointer */
155 /* try to free it one more time */
156 HeapFree(heap, 0, mem1);
158 dwSize = HeapSize(heap, 0, mem1);
159 ok(dwSize == 0xFFFFFFFF, "The size");
161 /* 0-length buffer */
162 mem1 = HeapAlloc(heap, 0, 0);
163 ok(mem1 != NULL, "Reserved memory");
165 dwSize = HeapSize(heap, 0, mem1);
166 /* should work with 0-length buffer */
167 ok((dwSize >= 0) && (dwSize < 0xFFFFFFFF),
168 "The size of the 0-length buffer");
169 ok(HeapFree(heap, 0, mem1), "Freed the 0-length buffer");
171 /* Check that HeapDestry works */
172 ok(HeapDestroy(heap),"HeapDestroy failed");
175 /* The following functions don't have tests, because either I don't know how
176 to test them, or they are WinNT only, or require multiple threads.
177 Since the last two issues shouldn't really stop the tests from being
178 written, assume for now that it is all due to the first case
183 /* In addition, these features aren't being tested
187 static void test_Global(void)
190 HGLOBAL mem1,mem2,mem2a,mem2b;
195 SetLastError(NO_ERROR);
196 /* Check that a normal alloc works */
197 mem1=GlobalAlloc((UINT)NULL,memchunk);
198 ok(mem1!=(HGLOBAL)NULL,"GlobalAlloc failed");
200 ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block");
203 /* Check that a 'zeroing' alloc works */
204 mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk);
205 ok(mem2!=(HGLOBAL)NULL,"GlobalAlloc failed");
207 ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block");
208 mem2ptr=(UCHAR *)GlobalLock(mem2);
209 ok(mem2ptr==(UCHAR *)mem2,"GlobalLock should have returned the same memory as was allocated");
212 for(i=0;i<memchunk;i++) {
217 ok(!error,"GlobalAlloc should have zeroed out it's allocated memory");
220 /* Check that GlobalReAlloc works */
221 /* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
222 mem2a=GlobalReAlloc(mem2,0,GMEM_MODIFY | GMEM_MOVEABLE);
223 ok(mem2a!=(HGLOBAL)NULL,"GlobalReAlloc failed to convert FIXED to MOVEABLE");
224 if(mem2a!=(HGLOBAL)NULL) {
227 mem2ptr=GlobalLock(mem2a);
228 ok(mem2ptr!=NULL && !GlobalUnlock(mem2a)&&GetLastError()==NO_ERROR,
229 "Converting from FIXED to MOVEABLE didn't REALLY work");
231 /* Check that ReAllocing memory works as expected */
232 mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
233 ok(mem2a!=(HGLOBAL)NULL,"GlobalReAlloc failed");
235 ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed");
236 mem2ptr=(UCHAR *)GlobalLock(mem2a);
237 ok(mem2ptr!=NULL,"GlobalLock Failed.");
240 for(i=0;i<memchunk;i++) {
241 if(mem2ptr[memchunk+i]!=0) {
245 ok(!error,"GlobalReAlloc should have zeroed out it's allocated memory");
247 /* Check that GlobalHandle works */
248 mem2b=GlobalHandle(mem2ptr);
249 ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle");
251 /* Check that we can't discard locked memory */
253 /* Wine doesn't include the GlobalDiscard function */
254 mem2b=GlobalDiscard(mem2a);
255 ok(mem2b==(HGLOBAL)NULL,"Discarded memory we shouldn't have");
257 /* This is functionally equivalent to the above */
258 mem2b=GlobalReAlloc(mem2a,0,GMEM_MOVEABLE);
259 ok(mem2b==(HGLOBAL)NULL,"Discarded memory we shouldn't have");
261 ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed.");
265 ok(GlobalFree(mem1)==(HGLOBAL)NULL,"GlobalFree failed");
268 ok(GlobalFree(mem2a)==(HGLOBAL)NULL,"GlobalFree failed");
270 ok(GlobalFree(mem2)==(HGLOBAL)NULL,"GlobalFree failed");
275 /* The following functions don't have tests, because either I don't know how
276 to test them, or they are WinNT only, or require multiple threads.
277 Since the last two issues shouldn't really stop the tests from being
278 written, assume for now that it is all due to the first case
282 /* In addition, these features aren't being tested
286 static void test_Local(void)
289 HLOCAL mem1,mem2,mem2a,mem2b;
294 /* Check that a normal alloc works */
295 mem1=LocalAlloc((UINT)NULL,memchunk);
296 ok(mem1!=(HLOCAL)NULL,"LocalAlloc failed");
298 ok(LocalSize(mem1)>=memchunk, "LocalAlloc should return a big enough memory block");
301 /* Check that a 'zeroing' alloc works */
302 mem2=LocalAlloc(LMEM_ZEROINIT,memchunk);
303 ok(mem2!=(HLOCAL)NULL,"LocalAlloc failed");
305 ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block");
306 mem2ptr=(UCHAR *)LocalLock(mem2);
307 ok(mem2ptr==(UCHAR *)mem2,"LocalLock Didn't lock it's memory");
310 for(i=0;i<memchunk;i++) {
315 ok(!error,"LocalAlloc should have zeroed out it's allocated memory");
316 ok(!(error=LocalUnlock(mem2)) &&
317 (GetLastError()==ERROR_NOT_LOCKED || GetLastError()==NO_ERROR),
318 "LocalUnlock Failed.");
322 /* Reallocate mem2 as moveable memory */
323 mem2a=LocalFree(mem2);
324 mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
325 ok(mem2a==(HLOCAL)NULL && mem2!=(HLOCAL)NULL, "LocalAlloc failed to create moveable memory");
327 /* Check that ReAllocing memory works as expected */
328 mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
329 ok(mem2a!=(HLOCAL)NULL,"LocalReAlloc failed");
331 ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed");
332 mem2ptr=(UCHAR *)LocalLock(mem2a);
333 ok(mem2ptr!=NULL,"LocalLock Failed.");
336 for(i=0;i<memchunk;i++) {
337 if(mem2ptr[memchunk+i]!=0) {
341 ok(!error,"LocalReAlloc should have zeroed out it's allocated memory");
342 /* Check that LocalHandle works */
343 mem2b=LocalHandle(mem2ptr);
344 ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle");
345 /* Check that we can't discard locked memory */
347 /* Wine doesn't include the LocalDiscard function */
348 mem2b=LocalDiscard(mem2a);
349 ok(mem2b==(HLOCAL)NULL,"Discarded memory we shouldn't have");
351 /* This is functionally equivalent to the above */
352 mem2b=LocalReAlloc(mem2a,0,GMEM_MOVEABLE);
353 ok(mem2b==(HLOCAL)NULL,"Discarded memory we shouldn't have");
355 SetLastError(NO_ERROR);
356 ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed.");
360 ok(LocalFree(mem1)==(HLOCAL)NULL,"LocalFree failed");
363 ok(LocalFree(mem2a)==(HLOCAL)NULL,"LocalFree failed");
365 ok(LocalFree(mem2)==(HLOCAL)NULL,"LocalFree failed");
369 /* The Virtual* routines are not tested as thoroughly,
370 since I don't really understand how to use them correctly :)
371 The following routines are not tested at all
380 And the only features (flags) being tested are
384 Testing the rest requires using exceptions, which I really don't
387 static void test_Virtual(void)
394 /* Retreive the page size for this system */
395 sysInfo.dwPageSize=0;
396 GetSystemInfo(&sysInfo);
397 ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size");
399 /* Chhose a reasonable allocation size */
400 memchunk=10*sysInfo.dwPageSize;
402 /* Check that a normal alloc works */
403 mem1=VirtualAlloc(NULL,memchunk,MEM_COMMIT,PAGE_READWRITE);
404 ok(mem1!=NULL,"VirtualAlloc failed");
406 /* check that memory is initialized to 0 */
408 for(i=0;i<memchunk;i++) {
413 ok(!error,"VirtualAlloc did not initialize memory to '0's");
414 /* Check that we can read/write to memory */
416 for(i=0;i<memchunk;i+=100) {
422 ok(!error,"Virtual memory was not writable");
424 ok(VirtualFree(mem1,0,MEM_RELEASE),"VirtualFree failed");