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;
58 /* Retreive the page size for this system */
60 GetSystemInfo(&sysInfo);
61 ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size");
63 /* Create a Heap with a minimum and maximum size */
64 /* Note that Windows and Wine seem to behave a bit differently with respect
65 to memory allocation. In Windows, you can't access all the memory
66 specified in the heap (due to overhead), so choosing a reasonable maximum
67 size for the heap was done mostly by trial-and-error on Win2k. It may need
68 more tweaking for otherWindows variants.
70 memchunk=10*sysInfo.dwPageSize;
71 heap=HeapCreate((DWORD)NULL,2*memchunk,5*memchunk);
73 /* Check that HeapCreate allocated the right amount of ram */
75 /* Today HeapCreate seems to return a memory block larger than specified.
76 MSDN says the maximum heap size should be dwMaximumSize rounded up to the
79 mem1=HeapAlloc(heap,(DWORD)NULL,5*memchunk+1);
80 ok(mem1==NULL,"HeapCreate allocated more Ram than it should have");
82 HeapFree(heap,(DWORD)NULL,mem1);
86 /* Check that a normal alloc works */
87 mem1=HeapAlloc(heap,(DWORD)NULL,memchunk);
88 ok(mem1!=NULL,"HeapAlloc failed");
90 ok(HeapSize(heap,(DWORD)NULL,mem1)>=memchunk, "HeapAlloc should return a big enough memory block");
93 /* Check that a 'zeroing' alloc works */
94 mem2=(UCHAR *)HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk);
95 ok(mem2!=NULL,"HeapAlloc failed");
97 ok(HeapSize(heap,(DWORD)NULL,mem2)>=memchunk,"HeapAlloc should return a big enough memory block");
99 for(i=0;i<memchunk;i++) {
104 ok(!error,"HeapAlloc should have zeroed out it's allocated memory");
107 /* Check that HeapAlloc returns NULL when requested way too much memory */
108 mem3=HeapAlloc(heap,(DWORD)NULL,5*memchunk);
109 ok(mem3==NULL,"HeapAlloc should return NULL");
111 ok(HeapFree(heap,(DWORD)NULL,mem3),"HeapFree didn't pass successfully");
114 /* Check that HeapRealloc works */
115 mem2a=(UCHAR *)HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
116 ok(mem2a!=NULL,"HeapReAlloc failed");
118 ok(HeapSize(heap,(DWORD)NULL,mem2a)>=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed");
120 for(i=0;i<5*sysInfo.dwPageSize;i++) {
121 if(mem2a[memchunk+i]!=0) {
125 ok(!error,"HeapReAlloc should have zeroed out it's allocated memory");
128 /* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */
130 mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize);
136 ok(mem1a==NULL || error==0,"HeapReAlloc didn't honour HEAP_REALLOC_IN_PLACE_ONLY");
138 /* Check that HeapFree works correctly */
140 ok(HeapFree(heap,(DWORD)NULL,mem1a),"HeapFree failed");
142 ok(HeapFree(heap,(DWORD)NULL,mem1),"HeapFree failed");
145 ok(HeapFree(heap,(DWORD)NULL,mem2a),"HeapFree failed");
147 ok(HeapFree(heap,(DWORD)NULL,mem2),"HeapFree failed");
150 /* Check that HeapDestry works */
151 ok(HeapDestroy(heap),"HeapDestroy failed");
154 /* The following functions don't have tests, because either I don't know how
155 to test them, or they are WinNT only, or require multiple threads.
156 Since the last two issues shouldn't really stop the tests from being
157 written, assume for now that it is all due to the first case
162 /* In addition, these features aren't being tested
166 static void test_Global(void)
169 HGLOBAL mem1,mem2,mem2a,mem2b;
174 SetLastError(NO_ERROR);
175 /* Check that a normal alloc works */
176 mem1=GlobalAlloc((UINT)NULL,memchunk);
177 ok(mem1!=(HGLOBAL)NULL,"GlobalAlloc failed");
179 ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block");
182 /* Check that a 'zeroing' alloc works */
183 mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk);
184 ok(mem2!=(HGLOBAL)NULL,"GlobalAlloc failed");
186 ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block");
187 mem2ptr=(UCHAR *)GlobalLock(mem2);
188 ok(mem2ptr==(UCHAR *)mem2,"GlobalLock should have returned the same memory as was allocated");
191 for(i=0;i<memchunk;i++) {
196 ok(!error,"GlobalAlloc should have zeroed out it's allocated memory");
199 /* Check that GlobalReAlloc works */
200 /* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
201 mem2a=GlobalReAlloc(mem2,0,GMEM_MODIFY | GMEM_MOVEABLE);
202 ok(mem2a!=(HGLOBAL)NULL,"GlobalReAlloc failed to convert FIXED to MOVEABLE");
203 if(mem2a!=(HGLOBAL)NULL) {
206 mem2ptr=GlobalLock(mem2a);
207 ok(mem2ptr!=NULL && !GlobalUnlock(mem2a)&&GetLastError()==NO_ERROR,
208 "Converting from FIXED to MOVEABLE didn't REALLY work");
210 /* Check that ReAllocing memory works as expected */
211 mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
212 ok(mem2a!=(HGLOBAL)NULL,"GlobalReAlloc failed");
214 ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed");
215 mem2ptr=(UCHAR *)GlobalLock(mem2a);
216 ok(mem2ptr!=NULL,"GlobalLock Failed.");
219 for(i=0;i<memchunk;i++) {
220 if(mem2ptr[memchunk+i]!=0) {
224 ok(!error,"GlobalReAlloc should have zeroed out it's allocated memory");
226 /* Check that GlobalHandle works */
227 mem2b=GlobalHandle(mem2ptr);
228 ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle");
230 /* Check that we can't discard locked memory */
232 /* Wine doesn't include the GlobalDiscard function */
233 mem2b=GlobalDiscard(mem2a);
234 ok(mem2b==(HGLOBAL)NULL,"Discarded memory we shouldn't have");
236 /* This is functionally equivalent to the above */
237 mem2b=GlobalReAlloc(mem2a,0,GMEM_MOVEABLE);
238 ok(mem2b==(HGLOBAL)NULL,"Discarded memory we shouldn't have");
240 ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed.");
244 ok(GlobalFree(mem1)==(HGLOBAL)NULL,"GlobalFree failed");
247 ok(GlobalFree(mem2a)==(HGLOBAL)NULL,"GlobalFree failed");
249 ok(GlobalFree(mem2)==(HGLOBAL)NULL,"GlobalFree failed");
254 /* The following functions don't have tests, because either I don't know how
255 to test them, or they are WinNT only, or require multiple threads.
256 Since the last two issues shouldn't really stop the tests from being
257 written, assume for now that it is all due to the first case
261 /* In addition, these features aren't being tested
265 static void test_Local(void)
268 HLOCAL mem1,mem2,mem2a,mem2b;
273 /* Check that a normal alloc works */
274 mem1=LocalAlloc((UINT)NULL,memchunk);
275 ok(mem1!=(HLOCAL)NULL,"LocalAlloc failed");
277 ok(LocalSize(mem1)>=memchunk, "LocalAlloc should return a big enough memory block");
280 /* Check that a 'zeroing' alloc works */
281 mem2=LocalAlloc(LMEM_ZEROINIT,memchunk);
282 ok(mem2!=(HLOCAL)NULL,"LocalAlloc failed");
284 ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block");
285 mem2ptr=(UCHAR *)LocalLock(mem2);
286 ok(mem2ptr==(UCHAR *)mem2,"LocalLock Didn't lock it's memory");
289 for(i=0;i<memchunk;i++) {
294 ok(!error,"LocalAlloc should have zeroed out it's allocated memory");
295 ok(!(error=LocalUnlock(mem2)) &&
296 (GetLastError()==ERROR_NOT_LOCKED || GetLastError()==NO_ERROR),
297 "LocalUnlock Failed.");
301 /* Reallocate mem2 as moveable memory */
302 mem2a=LocalFree(mem2);
303 mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
304 ok(mem2a==(HLOCAL)NULL && mem2!=(HLOCAL)NULL, "LocalAlloc failed to create moveable memory");
306 /* Check that ReAllocing memory works as expected */
307 mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
308 ok(mem2a!=(HLOCAL)NULL,"LocalReAlloc failed");
310 ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed");
311 mem2ptr=(UCHAR *)LocalLock(mem2a);
312 ok(mem2ptr!=NULL,"LocalLock Failed.");
315 for(i=0;i<memchunk;i++) {
316 if(mem2ptr[memchunk+i]!=0) {
320 ok(!error,"LocalReAlloc should have zeroed out it's allocated memory");
321 /* Check that LocalHandle works */
322 mem2b=LocalHandle(mem2ptr);
323 ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle");
324 /* Check that we can't discard locked memory */
326 /* Wine doesn't include the LocalDiscard function */
327 mem2b=LocalDiscard(mem2a);
328 ok(mem2b==(HLOCAL)NULL,"Discarded memory we shouldn't have");
330 /* This is functionally equivalent to the above */
331 mem2b=LocalReAlloc(mem2a,0,GMEM_MOVEABLE);
332 ok(mem2b==(HLOCAL)NULL,"Discarded memory we shouldn't have");
334 SetLastError(NO_ERROR);
335 ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed.");
339 ok(LocalFree(mem1)==(HLOCAL)NULL,"LocalFree failed");
342 ok(LocalFree(mem2a)==(HLOCAL)NULL,"LocalFree failed");
344 ok(LocalFree(mem2)==(HLOCAL)NULL,"LocalFree failed");
348 /* The Virtual* routines are not tested as thoroughly,
349 since I don't really understand how to use them correctly :)
350 The following routines are not tested at all
359 And the only features (flags) being tested are
363 Testing the rest requires using exceptions, which I really don't
366 static void test_Virtual(void)
373 /* Retreive the page size for this system */
374 sysInfo.dwPageSize=0;
375 GetSystemInfo(&sysInfo);
376 ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size");
378 /* Chhose a reasonable allocation size */
379 memchunk=10*sysInfo.dwPageSize;
381 /* Check that a normal alloc works */
382 mem1=VirtualAlloc(NULL,memchunk,MEM_COMMIT,PAGE_READWRITE);
383 ok(mem1!=NULL,"VirtualAlloc failed");
385 /* check that memory is initialized to 0 */
387 for(i=0;i<memchunk;i++) {
392 ok(!error,"VirtualAlloc did not initialize memory to '0's");
393 /* Check that we can read/write to memory */
395 for(i=0;i<memchunk;i+=100) {
401 ok(!error,"Virtual memory was not writable");
403 ok(VirtualFree(mem1,0,MEM_RELEASE),"VirtualFree failed");