/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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");

/* 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");
      if(mem1) {
        HeapFree(heap,0,mem1);
      }
    }

/* Check that a normal alloc works */
    mem1=HeapAlloc(heap,0,memchunk);
    ok(mem1!=NULL,"HeapAlloc failed");
    if(mem1) {
      ok(HeapSize(heap,0,mem1)>=memchunk, "HeapAlloc should return a big enough memory block");
    }

/* Check that a 'zeroing' alloc works */
    mem2=HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk);
    ok(mem2!=NULL,"HeapAlloc failed");
    if(mem2) {
      ok(HeapSize(heap,0,mem2)>=memchunk,"HeapAlloc should return a big enough memory block");
      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");
    }

/* Check that HeapAlloc returns NULL when requested way too much memory */
    mem3=HeapAlloc(heap,0,5*memchunk);
    ok(mem3==NULL,"HeapAlloc should return NULL");
    if(mem3) {
      ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully");
    }

/* Check that HeapRealloc works */
    mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
    ok(mem2a!=NULL,"HeapReAlloc failed");
    if(mem2a) {
      ok(HeapSize(heap,0,mem2a)>=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed");
      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");
    }

/* 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");

/* Check that HeapFree works correctly */
   if(mem1a) {
     ok(HeapFree(heap,0,mem1a),"HeapFree failed");
   } else {
     ok(HeapFree(heap,0,mem1),"HeapFree failed");
   }
   if(mem2a) {
     ok(HeapFree(heap,0,mem2a),"HeapFree failed");
   } else {
     ok(HeapFree(heap,0,mem2),"HeapFree failed");
   }

   /* 0-length buffer */
   mem1 = HeapAlloc(heap, 0, 0);
   ok(mem1 != NULL, "Reserved memory");

   dwSize = HeapSize(heap, 0, mem1);
   /* should work with 0-length buffer */
   ok((dwSize >= 0) && (dwSize < 0xFFFFFFFF),
      "The size of the 0-length buffer");
   ok(HeapFree(heap, 0, mem1), "Freed the 0-length buffer");

/* Check that HeapDestry works */
   ok(HeapDestroy(heap),"HeapDestroy failed");
}

/* 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");
    if(mem1) {
      ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block");
    }

/* Check that a 'zeroing' alloc works */
    mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk);
    ok(mem2!=NULL,"GlobalAlloc failed: error=%ld",GetLastError());
    if(mem2) {
      ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block");
      mem2ptr=GlobalLock(mem2);
      ok(mem2ptr==mem2,"GlobalLock should have returned the same memory as was allocated");
      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");
      }
   }
/* Check that GlobalReAlloc works */
/* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
    mem2a=GlobalReAlloc(mem2,0,GMEM_MODIFY | GMEM_MOVEABLE);
    ok(mem2a!=NULL,"GlobalReAlloc failed to convert FIXED to MOVEABLE: error=%ld",GetLastError());
    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");

/* Check that ReAllocing memory works as expected */
    mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
    ok(mem2a!=NULL,"GlobalReAlloc failed");
    if(mem2a) {
      ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed");
      mem2ptr=GlobalLock(mem2a);
      ok(mem2ptr!=NULL,"GlobalLock Failed.");
      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");

/* Check that GlobalHandle works */
        mem2b=GlobalHandle(mem2ptr);
        ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle");

/* Check that we can't discard locked memory */
        mem2b=GlobalDiscard(mem2a);
        ok(mem2b==NULL,"Discarded memory we shouldn't have");
        ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed.");
      }
    }
    if(mem1) {
      ok(GlobalFree(mem1)==NULL,"GlobalFree failed");
    }
    if(mem2a) {
      ok(GlobalFree(mem2a)==NULL,"GlobalFree failed");
    } else {
      ok(GlobalFree(mem2)==NULL,"GlobalFree failed");
    }
}


/* 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=%ld",GetLastError());
    if(mem1) {
      ok(LocalSize(mem1)>=memchunk, "LocalAlloc should return a big enough memory block");
    }

/* Check that a 'zeroing' and lock alloc works */
    mem2=LocalAlloc(LMEM_ZEROINIT|LMEM_MOVEABLE,memchunk);
    ok(mem2!=NULL,"LocalAlloc failed: error=%ld",GetLastError());
    if(mem2) {
      ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block");
      mem2ptr=LocalLock(mem2);
      ok(mem2ptr!=NULL,"LocalLock: error=%ld",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");
        SetLastError(0);
        error=LocalUnlock(mem2);
        ok(error==0 && GetLastError()==NO_ERROR,
           "LocalUnlock Failed: rc=%d err=%ld",error,GetLastError());
      }
    }
   mem2a=LocalFree(mem2);
   ok(mem2a==NULL, "LocalFree failed: %p",mem2a);

/* Reallocate mem2 as moveable memory */
   mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
   ok(mem2!=NULL, "LocalAlloc failed to create moveable memory, error=%ld",GetLastError());

/* Check that ReAllocing memory works as expected */
    mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
    ok(mem2a!=NULL,"LocalReAlloc failed, error=%ld",GetLastError());
    if(mem2a) {
      ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed");
      mem2ptr=LocalLock(mem2a);
      ok(mem2ptr!=NULL,"LocalLock Failed.");
      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");
/* Check that LocalHandle works */
        mem2b=LocalHandle(mem2ptr);
        ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle");
/* Check that we can't discard locked memory */
        mem2b=LocalDiscard(mem2a);
        ok(mem2b==NULL,"Discarded memory we shouldn't have");
        SetLastError(NO_ERROR);
        ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed.");
      }
    }
    if(mem1) {
      ok(LocalFree(mem1)==NULL,"LocalFree failed");
    }
    if(mem2a) {
      ok(LocalFree(mem2a)==NULL,"LocalFree failed");
    } else {
      ok(LocalFree(mem2)==NULL,"LocalFree failed");
    }
}

/* 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");

/* 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");
    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");
/* 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");
    }
    ok(VirtualFree(mem1,0,MEM_RELEASE),"VirtualFree failed");
}
START_TEST(alloc)
{
    test_Heap();
    test_Global();
    test_Local();
    test_Virtual();
}
