kernel32/tests: Move allocation tests into heap.c.
This commit is contained in:
parent
bdd1fcd89e
commit
7420b7fe73
|
@ -3,7 +3,6 @@ IMPORTS = user32 advapi32
|
|||
|
||||
C_SRCS = \
|
||||
actctx.c \
|
||||
alloc.c \
|
||||
atom.c \
|
||||
change.c \
|
||||
codepage.c \
|
||||
|
|
|
@ -1,404 +0,0 @@
|
|||
/*
|
||||
* Unit test suite for memory allocation functions.
|
||||
*
|
||||
* Copyright 2002 Geoffrey Hausheer
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
|
||||
/* The following functions don't have tests, because either I don't know how
|
||||
to test them, or they are WinNT only, or require multiple threads.
|
||||
Since the last two issues shouldn't really stop the tests from being
|
||||
written, assume for now that it is all due to the first case
|
||||
HeapCompact
|
||||
HeapLock
|
||||
HeapQueryInformation
|
||||
HeapSetInformation
|
||||
HeapUnlock
|
||||
HeapValidate
|
||||
HeapWalk
|
||||
*/
|
||||
/* In addition, these features aren't being tested
|
||||
HEAP_NO_SERIALIZE
|
||||
HEAP_GENERATE_EXCEPTIONS
|
||||
STATUS_ACCESS_VIOLATION (error code from HeapAlloc)
|
||||
*/
|
||||
|
||||
static void test_Heap(void)
|
||||
{
|
||||
SYSTEM_INFO sysInfo;
|
||||
ULONG memchunk;
|
||||
HANDLE heap;
|
||||
LPVOID mem1,mem1a,mem3;
|
||||
UCHAR *mem2,*mem2a;
|
||||
UINT i;
|
||||
BOOL error;
|
||||
DWORD dwSize;
|
||||
|
||||
/* Retrieve the page size for this system */
|
||||
sysInfo.dwPageSize=0;
|
||||
GetSystemInfo(&sysInfo);
|
||||
ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
|
||||
|
||||
/* Create a Heap with a minimum and maximum size */
|
||||
/* Note that Windows and Wine seem to behave a bit differently with respect
|
||||
to memory allocation. In Windows, you can't access all the memory
|
||||
specified in the heap (due to overhead), so choosing a reasonable maximum
|
||||
size for the heap was done mostly by trial-and-error on Win2k. It may need
|
||||
more tweaking for otherWindows variants.
|
||||
*/
|
||||
memchunk=10*sysInfo.dwPageSize;
|
||||
heap=HeapCreate(0,2*memchunk,5*memchunk);
|
||||
ok( !((ULONG_PTR)heap & 0xffff), "heap %p not 64K aligned\n", heap );
|
||||
|
||||
/* Check that HeapCreate allocated the right amount of ram */
|
||||
mem1=HeapAlloc(heap,0,5*memchunk+1);
|
||||
ok(mem1==NULL,"HeapCreate allocated more Ram than it should have\n");
|
||||
HeapFree(heap,0,mem1);
|
||||
|
||||
/* Check that a normal alloc works */
|
||||
mem1=HeapAlloc(heap,0,memchunk);
|
||||
ok(mem1!=NULL,"HeapAlloc failed\n");
|
||||
if(mem1) {
|
||||
ok(HeapSize(heap,0,mem1)>=memchunk, "HeapAlloc should return a big enough memory block\n");
|
||||
}
|
||||
|
||||
/* Check that a 'zeroing' alloc works */
|
||||
mem2=HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk);
|
||||
ok(mem2!=NULL,"HeapAlloc failed\n");
|
||||
if(mem2) {
|
||||
ok(HeapSize(heap,0,mem2)>=memchunk,"HeapAlloc should return a big enough memory block\n");
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2[i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"HeapAlloc should have zeroed out its allocated memory\n");
|
||||
}
|
||||
|
||||
/* Check that HeapAlloc returns NULL when requested way too much memory */
|
||||
mem3=HeapAlloc(heap,0,5*memchunk);
|
||||
ok(mem3==NULL,"HeapAlloc should return NULL\n");
|
||||
if(mem3) {
|
||||
ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully\n");
|
||||
}
|
||||
|
||||
/* Check that HeapRealloc works */
|
||||
mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
|
||||
ok(mem2a!=NULL,"HeapReAlloc failed\n");
|
||||
if(mem2a) {
|
||||
ok(HeapSize(heap,0,mem2a)>=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed\n");
|
||||
error=FALSE;
|
||||
for(i=0;i<5*sysInfo.dwPageSize;i++) {
|
||||
if(mem2a[memchunk+i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"HeapReAlloc should have zeroed out its allocated memory\n");
|
||||
}
|
||||
|
||||
/* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */
|
||||
error=FALSE;
|
||||
mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize);
|
||||
if(mem1a!=NULL) {
|
||||
if(mem1a!=mem1) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(mem1a==NULL || !error,"HeapReAlloc didn't honour HEAP_REALLOC_IN_PLACE_ONLY\n");
|
||||
|
||||
/* Check that HeapFree works correctly */
|
||||
if(mem1a) {
|
||||
ok(HeapFree(heap,0,mem1a),"HeapFree failed\n");
|
||||
} else {
|
||||
ok(HeapFree(heap,0,mem1),"HeapFree failed\n");
|
||||
}
|
||||
if(mem2a) {
|
||||
ok(HeapFree(heap,0,mem2a),"HeapFree failed\n");
|
||||
} else {
|
||||
ok(HeapFree(heap,0,mem2),"HeapFree failed\n");
|
||||
}
|
||||
|
||||
/* 0-length buffer */
|
||||
mem1 = HeapAlloc(heap, 0, 0);
|
||||
ok(mem1 != NULL, "Reserved memory\n");
|
||||
|
||||
dwSize = HeapSize(heap, 0, mem1);
|
||||
/* should work with 0-length buffer */
|
||||
ok(dwSize < 0xFFFFFFFF, "The size of the 0-length buffer\n");
|
||||
ok(HeapFree(heap, 0, mem1), "Freed the 0-length buffer\n");
|
||||
|
||||
/* Check that HeapDestry works */
|
||||
ok(HeapDestroy(heap),"HeapDestroy failed\n");
|
||||
}
|
||||
|
||||
/* The following functions don't have tests, because either I don't know how
|
||||
to test them, or they are WinNT only, or require multiple threads.
|
||||
Since the last two issues shouldn't really stop the tests from being
|
||||
written, assume for now that it is all due to the first case
|
||||
GlobalFlags
|
||||
GlobalMemoryStatus
|
||||
GlobalMemoryStatusEx
|
||||
*/
|
||||
/* In addition, these features aren't being tested
|
||||
GMEM_DISCARDABLE
|
||||
GMEM_NOCOMPACT
|
||||
*/
|
||||
static void test_Global(void)
|
||||
{
|
||||
ULONG memchunk;
|
||||
HGLOBAL mem1,mem2,mem2a,mem2b;
|
||||
UCHAR *mem2ptr;
|
||||
UINT i;
|
||||
BOOL error;
|
||||
memchunk=100000;
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
/* Check that a normal alloc works */
|
||||
mem1=GlobalAlloc(0,memchunk);
|
||||
ok(mem1!=NULL,"GlobalAlloc failed\n");
|
||||
if(mem1) {
|
||||
ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block\n");
|
||||
}
|
||||
|
||||
/* Check that a 'zeroing' alloc works */
|
||||
mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk);
|
||||
ok(mem2!=NULL,"GlobalAlloc failed: error=%d\n",GetLastError());
|
||||
if(mem2) {
|
||||
ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block\n");
|
||||
mem2ptr=GlobalLock(mem2);
|
||||
ok(mem2ptr==mem2,"GlobalLock should have returned the same memory as was allocated\n");
|
||||
if(mem2ptr) {
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2ptr[i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"GlobalAlloc should have zeroed out its allocated memory\n");
|
||||
}
|
||||
}
|
||||
/* Check that GlobalReAlloc works */
|
||||
/* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
|
||||
mem2a=GlobalReAlloc(mem2,0,GMEM_MODIFY | GMEM_MOVEABLE);
|
||||
if(mem2a!=NULL) {
|
||||
mem2=mem2a;
|
||||
mem2ptr=GlobalLock(mem2a);
|
||||
ok(mem2ptr!=NULL && !GlobalUnlock(mem2a)&&GetLastError()==NO_ERROR,
|
||||
"Converting from FIXED to MOVEABLE didn't REALLY work\n");
|
||||
}
|
||||
|
||||
/* Check that ReAllocing memory works as expected */
|
||||
mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
|
||||
ok(mem2a!=NULL,"GlobalReAlloc failed\n");
|
||||
if(mem2a) {
|
||||
ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed\n");
|
||||
mem2ptr=GlobalLock(mem2a);
|
||||
ok(mem2ptr!=NULL,"GlobalLock Failed\n");
|
||||
if(mem2ptr) {
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2ptr[memchunk+i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"GlobalReAlloc should have zeroed out its allocated memory\n");
|
||||
|
||||
/* Check that GlobalHandle works */
|
||||
mem2b=GlobalHandle(mem2ptr);
|
||||
ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle\n");
|
||||
|
||||
/* Check that we can't discard locked memory */
|
||||
mem2b=GlobalDiscard(mem2a);
|
||||
if(mem2b==NULL) {
|
||||
ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(mem1) {
|
||||
ok(GlobalFree(mem1)==NULL,"GlobalFree failed\n");
|
||||
}
|
||||
if(mem2a) {
|
||||
ok(GlobalFree(mem2a)==NULL,"GlobalFree failed\n");
|
||||
} else {
|
||||
ok(GlobalFree(mem2)==NULL,"GlobalFree failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The following functions don't have tests, because either I don't know how
|
||||
to test them, or they are WinNT only, or require multiple threads.
|
||||
Since the last two issues shouldn't really stop the tests from being
|
||||
written, assume for now that it is all due to the first case
|
||||
LocalDiscard
|
||||
LocalFlags
|
||||
*/
|
||||
/* In addition, these features aren't being tested
|
||||
LMEM_DISCARDABLE
|
||||
LMEM_NOCOMPACT
|
||||
*/
|
||||
static void test_Local(void)
|
||||
{
|
||||
ULONG memchunk;
|
||||
HLOCAL mem1,mem2,mem2a,mem2b;
|
||||
UCHAR *mem2ptr;
|
||||
UINT i;
|
||||
BOOL error;
|
||||
memchunk=100000;
|
||||
|
||||
/* Check that a normal alloc works */
|
||||
mem1=LocalAlloc(0,memchunk);
|
||||
ok(mem1!=NULL,"LocalAlloc failed: error=%d\n",GetLastError());
|
||||
if(mem1) {
|
||||
ok(LocalSize(mem1)>=memchunk, "LocalAlloc should return a big enough memory block\n");
|
||||
}
|
||||
|
||||
/* Check that a 'zeroing' and lock alloc works */
|
||||
mem2=LocalAlloc(LMEM_ZEROINIT|LMEM_MOVEABLE,memchunk);
|
||||
ok(mem2!=NULL,"LocalAlloc failed: error=%d\n",GetLastError());
|
||||
if(mem2) {
|
||||
ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block\n");
|
||||
mem2ptr=LocalLock(mem2);
|
||||
ok(mem2ptr!=NULL,"LocalLock: error=%d\n",GetLastError());
|
||||
if(mem2ptr) {
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2ptr[i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"LocalAlloc should have zeroed out its allocated memory\n");
|
||||
SetLastError(0);
|
||||
error=LocalUnlock(mem2);
|
||||
ok(!error && GetLastError()==NO_ERROR,
|
||||
"LocalUnlock Failed: rc=%d err=%d\n",error,GetLastError());
|
||||
}
|
||||
}
|
||||
mem2a=LocalFree(mem2);
|
||||
ok(mem2a==NULL, "LocalFree failed: %p\n",mem2a);
|
||||
|
||||
/* Reallocate mem2 as moveable memory */
|
||||
mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
|
||||
ok(mem2!=NULL, "LocalAlloc failed to create moveable memory, error=%d\n",GetLastError());
|
||||
|
||||
/* Check that ReAllocing memory works as expected */
|
||||
mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||
ok(mem2a!=NULL,"LocalReAlloc failed, error=%d\n",GetLastError());
|
||||
if(mem2a) {
|
||||
ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed\n");
|
||||
mem2ptr=LocalLock(mem2a);
|
||||
ok(mem2ptr!=NULL,"LocalLock Failed\n");
|
||||
if(mem2ptr) {
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2ptr[memchunk+i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"LocalReAlloc should have zeroed out its allocated memory\n");
|
||||
/* Check that LocalHandle works */
|
||||
mem2b=LocalHandle(mem2ptr);
|
||||
ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle\n");
|
||||
/* Check that we can't discard locked memory */
|
||||
mem2b=LocalDiscard(mem2a);
|
||||
ok(mem2b==NULL,"Discarded memory we shouldn't have\n");
|
||||
SetLastError(NO_ERROR);
|
||||
ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed\n");
|
||||
}
|
||||
}
|
||||
if(mem1) {
|
||||
ok(LocalFree(mem1)==NULL,"LocalFree failed\n");
|
||||
}
|
||||
if(mem2a) {
|
||||
ok(LocalFree(mem2a)==NULL,"LocalFree failed\n");
|
||||
} else {
|
||||
ok(LocalFree(mem2)==NULL,"LocalFree failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* The Virtual* routines are not tested as thoroughly,
|
||||
since I don't really understand how to use them correctly :)
|
||||
The following routines are not tested at all
|
||||
VirtualAllocEx
|
||||
VirtualFreeEx
|
||||
VirtualLock
|
||||
VirtualProtect
|
||||
VirtualProtectEx
|
||||
VirtualQuery
|
||||
VirtualQueryEx
|
||||
VirtualUnlock
|
||||
And the only features (flags) being tested are
|
||||
MEM_COMMIT
|
||||
MEM_RELEASE
|
||||
PAGE_READWRITE
|
||||
Testing the rest requires using exceptions, which I really don't
|
||||
understand well
|
||||
*/
|
||||
static void test_Virtual(void)
|
||||
{
|
||||
SYSTEM_INFO sysInfo;
|
||||
ULONG memchunk;
|
||||
UCHAR *mem1;
|
||||
UINT i;
|
||||
BOOL error;
|
||||
|
||||
/* Retrieve the page size for this system */
|
||||
sysInfo.dwPageSize=0;
|
||||
GetSystemInfo(&sysInfo);
|
||||
ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
|
||||
|
||||
/* Choose a reasonable allocation size */
|
||||
memchunk=10*sysInfo.dwPageSize;
|
||||
|
||||
/* Check that a normal alloc works */
|
||||
mem1=VirtualAlloc(NULL,memchunk,MEM_COMMIT,PAGE_READWRITE);
|
||||
ok(mem1!=NULL,"VirtualAlloc failed\n");
|
||||
if(mem1) {
|
||||
/* check that memory is initialized to 0 */
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem1[i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"VirtualAlloc did not initialize memory to '0's\n");
|
||||
/* Check that we can read/write to memory */
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i+=100) {
|
||||
mem1[i]='a';
|
||||
if(mem1[i]!='a') {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"Virtual memory was not writable\n");
|
||||
}
|
||||
ok(VirtualFree(mem1,0,MEM_RELEASE),"VirtualFree failed\n");
|
||||
}
|
||||
START_TEST(alloc)
|
||||
{
|
||||
test_Heap();
|
||||
test_Global();
|
||||
test_Local();
|
||||
test_Virtual();
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Unit test suite for heap functions
|
||||
*
|
||||
* Copyright 2002 Geoffrey Hausheer
|
||||
* Copyright 2003 Dimitrie O. Paun
|
||||
* Copyright 2006 Detlef Riekenberg
|
||||
*
|
||||
|
@ -480,6 +481,278 @@ static void test_heap(void)
|
|||
|
||||
}
|
||||
|
||||
|
||||
static void test_HeapCreate(void)
|
||||
{
|
||||
SYSTEM_INFO sysInfo;
|
||||
ULONG memchunk;
|
||||
HANDLE heap;
|
||||
LPVOID mem1,mem1a,mem3;
|
||||
UCHAR *mem2,*mem2a;
|
||||
UINT i;
|
||||
BOOL error;
|
||||
DWORD dwSize;
|
||||
|
||||
/* Retrieve the page size for this system */
|
||||
GetSystemInfo(&sysInfo);
|
||||
ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
|
||||
|
||||
/* Create a Heap with a minimum and maximum size */
|
||||
/* Note that Windows and Wine seem to behave a bit differently with respect
|
||||
to memory allocation. In Windows, you can't access all the memory
|
||||
specified in the heap (due to overhead), so choosing a reasonable maximum
|
||||
size for the heap was done mostly by trial-and-error on Win2k. It may need
|
||||
more tweaking for otherWindows variants.
|
||||
*/
|
||||
memchunk=10*sysInfo.dwPageSize;
|
||||
heap=HeapCreate(0,2*memchunk,5*memchunk);
|
||||
ok( !((ULONG_PTR)heap & 0xffff), "heap %p not 64K aligned\n", heap );
|
||||
|
||||
/* Check that HeapCreate allocated the right amount of ram */
|
||||
mem1=HeapAlloc(heap,0,5*memchunk+1);
|
||||
ok(mem1==NULL,"HeapCreate allocated more Ram than it should have\n");
|
||||
HeapFree(heap,0,mem1);
|
||||
|
||||
/* Check that a normal alloc works */
|
||||
mem1=HeapAlloc(heap,0,memchunk);
|
||||
ok(mem1!=NULL,"HeapAlloc failed\n");
|
||||
if(mem1) {
|
||||
ok(HeapSize(heap,0,mem1)>=memchunk, "HeapAlloc should return a big enough memory block\n");
|
||||
}
|
||||
|
||||
/* Check that a 'zeroing' alloc works */
|
||||
mem2=HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk);
|
||||
ok(mem2!=NULL,"HeapAlloc failed\n");
|
||||
if(mem2) {
|
||||
ok(HeapSize(heap,0,mem2)>=memchunk,"HeapAlloc should return a big enough memory block\n");
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2[i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"HeapAlloc should have zeroed out its allocated memory\n");
|
||||
}
|
||||
|
||||
/* Check that HeapAlloc returns NULL when requested way too much memory */
|
||||
mem3=HeapAlloc(heap,0,5*memchunk);
|
||||
ok(mem3==NULL,"HeapAlloc should return NULL\n");
|
||||
if(mem3) {
|
||||
ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully\n");
|
||||
}
|
||||
|
||||
/* Check that HeapRealloc works */
|
||||
mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
|
||||
ok(mem2a!=NULL,"HeapReAlloc failed\n");
|
||||
if(mem2a) {
|
||||
ok(HeapSize(heap,0,mem2a)>=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed\n");
|
||||
error=FALSE;
|
||||
for(i=0;i<5*sysInfo.dwPageSize;i++) {
|
||||
if(mem2a[memchunk+i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"HeapReAlloc should have zeroed out its allocated memory\n");
|
||||
}
|
||||
|
||||
/* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */
|
||||
error=FALSE;
|
||||
mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize);
|
||||
if(mem1a!=NULL) {
|
||||
if(mem1a!=mem1) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(mem1a==NULL || !error,"HeapReAlloc didn't honour HEAP_REALLOC_IN_PLACE_ONLY\n");
|
||||
|
||||
/* Check that HeapFree works correctly */
|
||||
if(mem1a) {
|
||||
ok(HeapFree(heap,0,mem1a),"HeapFree failed\n");
|
||||
} else {
|
||||
ok(HeapFree(heap,0,mem1),"HeapFree failed\n");
|
||||
}
|
||||
if(mem2a) {
|
||||
ok(HeapFree(heap,0,mem2a),"HeapFree failed\n");
|
||||
} else {
|
||||
ok(HeapFree(heap,0,mem2),"HeapFree failed\n");
|
||||
}
|
||||
|
||||
/* 0-length buffer */
|
||||
mem1 = HeapAlloc(heap, 0, 0);
|
||||
ok(mem1 != NULL, "Reserved memory\n");
|
||||
|
||||
dwSize = HeapSize(heap, 0, mem1);
|
||||
/* should work with 0-length buffer */
|
||||
ok(dwSize < 0xFFFFFFFF, "The size of the 0-length buffer\n");
|
||||
ok(HeapFree(heap, 0, mem1), "Freed the 0-length buffer\n");
|
||||
|
||||
/* Check that HeapDestroy works */
|
||||
ok(HeapDestroy(heap),"HeapDestroy failed\n");
|
||||
}
|
||||
|
||||
|
||||
static void test_GlobalAlloc(void)
|
||||
{
|
||||
ULONG memchunk;
|
||||
HGLOBAL mem1,mem2,mem2a,mem2b;
|
||||
UCHAR *mem2ptr;
|
||||
UINT i;
|
||||
BOOL error;
|
||||
memchunk=100000;
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
/* Check that a normal alloc works */
|
||||
mem1=GlobalAlloc(0,memchunk);
|
||||
ok(mem1!=NULL,"GlobalAlloc failed\n");
|
||||
if(mem1) {
|
||||
ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block\n");
|
||||
}
|
||||
|
||||
/* Check that a 'zeroing' alloc works */
|
||||
mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk);
|
||||
ok(mem2!=NULL,"GlobalAlloc failed: error=%d\n",GetLastError());
|
||||
if(mem2) {
|
||||
ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block\n");
|
||||
mem2ptr=GlobalLock(mem2);
|
||||
ok(mem2ptr==mem2,"GlobalLock should have returned the same memory as was allocated\n");
|
||||
if(mem2ptr) {
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2ptr[i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"GlobalAlloc should have zeroed out its allocated memory\n");
|
||||
}
|
||||
}
|
||||
/* Check that GlobalReAlloc works */
|
||||
/* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
|
||||
mem2a=GlobalReAlloc(mem2,0,GMEM_MODIFY | GMEM_MOVEABLE);
|
||||
if(mem2a!=NULL) {
|
||||
mem2=mem2a;
|
||||
mem2ptr=GlobalLock(mem2a);
|
||||
ok(mem2ptr!=NULL && !GlobalUnlock(mem2a)&&GetLastError()==NO_ERROR,
|
||||
"Converting from FIXED to MOVEABLE didn't REALLY work\n");
|
||||
}
|
||||
|
||||
/* Check that ReAllocing memory works as expected */
|
||||
mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
|
||||
ok(mem2a!=NULL,"GlobalReAlloc failed\n");
|
||||
if(mem2a) {
|
||||
ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed\n");
|
||||
mem2ptr=GlobalLock(mem2a);
|
||||
ok(mem2ptr!=NULL,"GlobalLock Failed\n");
|
||||
if(mem2ptr) {
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2ptr[memchunk+i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"GlobalReAlloc should have zeroed out its allocated memory\n");
|
||||
|
||||
/* Check that GlobalHandle works */
|
||||
mem2b=GlobalHandle(mem2ptr);
|
||||
ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle %p/%p for %p\n",
|
||||
mem2a, mem2b, mem2ptr);
|
||||
/* Check that we can't discard locked memory */
|
||||
mem2b=GlobalDiscard(mem2a);
|
||||
if(mem2b==NULL) {
|
||||
ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(mem1) {
|
||||
ok(GlobalFree(mem1)==NULL,"GlobalFree failed\n");
|
||||
}
|
||||
if(mem2a) {
|
||||
ok(GlobalFree(mem2a)==NULL,"GlobalFree failed\n");
|
||||
} else {
|
||||
ok(GlobalFree(mem2)==NULL,"GlobalFree failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void test_LocalAlloc(void)
|
||||
{
|
||||
ULONG memchunk;
|
||||
HLOCAL mem1,mem2,mem2a,mem2b;
|
||||
UCHAR *mem2ptr;
|
||||
UINT i;
|
||||
BOOL error;
|
||||
memchunk=100000;
|
||||
|
||||
/* Check that a normal alloc works */
|
||||
mem1=LocalAlloc(0,memchunk);
|
||||
ok(mem1!=NULL,"LocalAlloc failed: error=%d\n",GetLastError());
|
||||
if(mem1) {
|
||||
ok(LocalSize(mem1)>=memchunk, "LocalAlloc should return a big enough memory block\n");
|
||||
}
|
||||
|
||||
/* Check that a 'zeroing' and lock alloc works */
|
||||
mem2=LocalAlloc(LMEM_ZEROINIT|LMEM_MOVEABLE,memchunk);
|
||||
ok(mem2!=NULL,"LocalAlloc failed: error=%d\n",GetLastError());
|
||||
if(mem2) {
|
||||
ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block\n");
|
||||
mem2ptr=LocalLock(mem2);
|
||||
ok(mem2ptr!=NULL,"LocalLock: error=%d\n",GetLastError());
|
||||
if(mem2ptr) {
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2ptr[i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"LocalAlloc should have zeroed out its allocated memory\n");
|
||||
SetLastError(0);
|
||||
error=LocalUnlock(mem2);
|
||||
ok(!error && GetLastError()==NO_ERROR,
|
||||
"LocalUnlock Failed: rc=%d err=%d\n",error,GetLastError());
|
||||
}
|
||||
}
|
||||
mem2a=LocalFree(mem2);
|
||||
ok(mem2a==NULL, "LocalFree failed: %p\n",mem2a);
|
||||
|
||||
/* Reallocate mem2 as moveable memory */
|
||||
mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
|
||||
ok(mem2!=NULL, "LocalAlloc failed to create moveable memory, error=%d\n",GetLastError());
|
||||
|
||||
/* Check that ReAllocing memory works as expected */
|
||||
mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||
ok(mem2a!=NULL,"LocalReAlloc failed, error=%d\n",GetLastError());
|
||||
if(mem2a) {
|
||||
ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed\n");
|
||||
mem2ptr=LocalLock(mem2a);
|
||||
ok(mem2ptr!=NULL,"LocalLock Failed\n");
|
||||
if(mem2ptr) {
|
||||
error=FALSE;
|
||||
for(i=0;i<memchunk;i++) {
|
||||
if(mem2ptr[memchunk+i]!=0) {
|
||||
error=TRUE;
|
||||
}
|
||||
}
|
||||
ok(!error,"LocalReAlloc should have zeroed out its allocated memory\n");
|
||||
/* Check that LocalHandle works */
|
||||
mem2b=LocalHandle(mem2ptr);
|
||||
ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle %p/%p for %p\n",
|
||||
mem2a, mem2b, mem2ptr);
|
||||
/* Check that we can't discard locked memory */
|
||||
mem2b=LocalDiscard(mem2a);
|
||||
ok(mem2b==NULL,"Discarded memory we shouldn't have\n");
|
||||
SetLastError(NO_ERROR);
|
||||
ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed\n");
|
||||
}
|
||||
}
|
||||
if(mem1) {
|
||||
ok(LocalFree(mem1)==NULL,"LocalFree failed\n");
|
||||
}
|
||||
if(mem2a) {
|
||||
ok(LocalFree(mem2a)==NULL,"LocalFree failed\n");
|
||||
} else {
|
||||
ok(LocalFree(mem2)==NULL,"LocalFree failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_obsolete_flags(void)
|
||||
{
|
||||
static struct {
|
||||
|
@ -888,6 +1161,9 @@ START_TEST(heap)
|
|||
|
||||
test_heap();
|
||||
test_obsolete_flags();
|
||||
test_HeapCreate();
|
||||
test_GlobalAlloc();
|
||||
test_LocalAlloc();
|
||||
|
||||
/* Test both short and very long blocks */
|
||||
test_sized_HeapAlloc(1);
|
||||
|
|
Loading…
Reference in New Issue