/*
 * 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 error,i;
    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);

/* Check that HeapCreate allocated the right amount of ram */
    todo_wine {
    /* Today HeapCreate seems to return a memory block larger than specified.
       MSDN says the maximum heap size should be dwMaximumSize rounded up to the
       nearest page boundary
    */
      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=0;
      for(i=0;i<memchunk;i++) {
        if(mem2[i]!=0) {
          error=1;
        }
      }
      ok(!error,"HeapAlloc should have zeroed out it's 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=0;
      for(i=0;i<5*sysInfo.dwPageSize;i++) {
        if(mem2a[memchunk+i]!=0) {
          error=1;
        }
      }
      ok(!error,"HeapReAlloc should have zeroed out it's allocated memory\n");
    }

/* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */
    error=0;
    mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize);
    if(mem1a!=NULL) {
      if(mem1a!=mem1) {
        error=1;
      }
    }
    ok(mem1a==NULL || error==0,"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_DISCADABLE
       GMEM_NOCOMPACT
*/
static void test_Global(void)
{
    ULONG memchunk;
    HGLOBAL mem1,mem2,mem2a,mem2b;
    UCHAR *mem2ptr;
    UINT error,i;
    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=0;
        for(i=0;i<memchunk;i++) {
          if(mem2ptr[i]!=0) {
            error=1;
          }
        }
        ok(!error,"GlobalAlloc should have zeroed out it's 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=0;
        for(i=0;i<memchunk;i++) {
          if(mem2ptr[memchunk+i]!=0) {
            error=1;
          }
        }
        ok(!error,"GlobalReAlloc should have zeroed out it's 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_DISCADABLE
       LMEM_NOCOMPACT
*/
static void test_Local(void)
{
    ULONG memchunk;
    HLOCAL mem1,mem2,mem2a,mem2b;
    UCHAR *mem2ptr;
    UINT error,i;
    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=0;
        for(i=0;i<memchunk;i++) {
          if(mem2ptr[i]!=0) {
            error=1;
          }
        }
        ok(!error,"LocalAlloc should have zeroed out it's allocated memory\n");
        SetLastError(0);
        error=LocalUnlock(mem2);
        ok(error==0 && 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=0;
        for(i=0;i<memchunk;i++) {
          if(mem2ptr[memchunk+i]!=0) {
            error=1;
          }
        }
        ok(!error,"LocalReAlloc should have zeroed out it's 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 error,i;

/* 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=0;
      for(i=0;i<memchunk;i++) {
        if(mem1[i]!=0) {
          error=1;
        }
      }
      ok(!error,"VirtualAlloc did not initialize memory to '0's\n");
/* Check that we can read/write to memory */
      error=0;
      for(i=0;i<memchunk;i+=100) {
        mem1[i]='a';
        if(mem1[i]!='a') {
          error=1;
        }
      }
      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();
}
