Example #1
0
void FREE(void* pv)
{
#ifdef _DEBUG
	if (NULL != pv) // under debug always initialize to -1 to catch unitialize errors.
	{
#if later // malloc doesn't have a size so need to keep track separately, should be able if keep track of heap
		UINT cb;

		Assert(LMEM_INVALID_HANDLE != LocalFlags(pv));

		cb = LocalSize(pv); // returns zero on failure
		memset(pv, MEMFREEVALUE, cb);
#endif
	}

	Assert(pv);

#endif // _DEBUG

	free(pv); //  LocalFree(pv);
}
Example #2
0
File: heap.c Project: baskanov/wine
static void test_heap(void)
{
    LPVOID  mem;
    LPVOID  msecond;
    DWORD   res;
    UINT    flags;
    HGLOBAL gbl;
    HGLOBAL hsecond;
    SIZE_T  size, size2;
    const SIZE_T max_size = 1024, init_size = 10;

    /* Heap*() functions */
    mem = HeapAlloc(GetProcessHeap(), 0, 0);
    ok(mem != NULL, "memory not allocated for size 0\n");
    HeapFree(GetProcessHeap(), 0, mem);

    mem = HeapReAlloc(GetProcessHeap(), 0, NULL, 10);
    ok(mem == NULL, "memory allocated by HeapReAlloc\n");

    for (size = 0; size <= 256; size++)
    {
        SIZE_T heap_size;
        mem = HeapAlloc(GetProcessHeap(), 0, size);
        heap_size = HeapSize(GetProcessHeap(), 0, mem);
        ok(heap_size == size || heap_size == resize_9x(size), 
            "HeapSize returned %lu instead of %lu or %lu\n", heap_size, size, resize_9x(size));
        HeapFree(GetProcessHeap(), 0, mem);
    }

    /* test some border cases of HeapAlloc and HeapReAlloc */
    mem = HeapAlloc(GetProcessHeap(), 0, 0);
    ok(mem != NULL, "memory not allocated for size 0\n");
    msecond = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, ~(SIZE_T)0 - 7);
    ok(msecond == NULL, "HeapReAlloc(~0 - 7) should have failed\n");
    msecond = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, ~(SIZE_T)0);
    ok(msecond == NULL, "HeapReAlloc(~0) should have failed\n");
    HeapFree(GetProcessHeap(), 0, mem);
    mem = HeapAlloc(GetProcessHeap(), 0, ~(SIZE_T)0);
    ok(mem == NULL, "memory allocated for size ~0\n");

    /* large blocks must be 16-byte aligned */
    mem = HeapAlloc(GetProcessHeap(), 0, 512 * 1024);
    ok( mem != NULL, "failed for size 512K\n" );
    ok( (ULONG_PTR)mem % 16 == 0 || broken((ULONG_PTR)mem % 16) /* win9x */,
        "512K block not 16-byte aligned\n" );
    HeapFree(GetProcessHeap(), 0, mem);

    /* Global*() functions */
    gbl = GlobalAlloc(GMEM_MOVEABLE, 0);
    ok(gbl != NULL, "global memory not allocated for size 0\n");

    gbl = GlobalReAlloc(gbl, 10, GMEM_MOVEABLE);
    ok(gbl != NULL, "Can't realloc global memory\n");
    size = GlobalSize(gbl);
    ok(size >= 10 && size <= 16, "Memory not resized to size 10, instead size=%ld\n", size);

    gbl = GlobalReAlloc(gbl, 0, GMEM_MOVEABLE);
    ok(gbl != NULL, "GlobalReAlloc should not fail on size 0\n");

    size = GlobalSize(gbl);
    ok(size == 0, "Memory not resized to size 0, instead size=%ld\n", size);
    ok(GlobalFree(gbl) == NULL, "Memory not freed\n");
    size = GlobalSize(gbl);
    ok(size == 0, "Memory should have been freed, size=%ld\n", size);

    gbl = GlobalReAlloc(0, 10, GMEM_MOVEABLE);
    ok(gbl == NULL, "global realloc allocated memory\n");

    /* GlobalLock / GlobalUnlock with a valid handle */
    gbl = GlobalAlloc(GMEM_MOVEABLE, 256);

    SetLastError(MAGIC_DEAD);
    mem = GlobalLock(gbl);      /* #1 */
    ok(mem != NULL, "returned %p with %d (expected '!= NULL')\n", mem, GetLastError());
    SetLastError(MAGIC_DEAD);
    flags = GlobalFlags(gbl);
    ok( flags == 1, "returned 0x%04x with %d (expected '0x0001')\n",
        flags, GetLastError());

    SetLastError(MAGIC_DEAD);
    msecond = GlobalLock(gbl);   /* #2 */
    ok( msecond == mem, "returned %p with %d (expected '%p')\n",
        msecond, GetLastError(), mem);
    SetLastError(MAGIC_DEAD);
    flags = GlobalFlags(gbl);
    ok( flags == 2, "returned 0x%04x with %d (expected '0x0002')\n",
        flags, GetLastError());
    SetLastError(MAGIC_DEAD);

    SetLastError(MAGIC_DEAD);
    res = GlobalUnlock(gbl);    /* #1 */
    ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
    SetLastError(MAGIC_DEAD);
    flags = GlobalFlags(gbl);
    ok( flags , "returned 0x%04x with %d (expected '!= 0')\n",
        flags, GetLastError());

    SetLastError(MAGIC_DEAD);
    res = GlobalUnlock(gbl);    /* #0 */
    /* NT: ERROR_SUCCESS (documented on MSDN), 9x: untouched */
    ok(!res && ((GetLastError() == ERROR_SUCCESS) || (GetLastError() == MAGIC_DEAD)),
        "returned %d with %d (expected '0' with: ERROR_SUCCESS or "
        "MAGIC_DEAD)\n", res, GetLastError());
    SetLastError(MAGIC_DEAD);
    flags = GlobalFlags(gbl);
    ok( !flags , "returned 0x%04x with %d (expected '0')\n",
        flags, GetLastError());

    /* Unlock an already unlocked Handle */
    SetLastError(MAGIC_DEAD);
    res = GlobalUnlock(gbl);
    /* NT: ERROR_NOT_LOCKED,  9x: untouched */
    ok( !res &&
        ((GetLastError() == ERROR_NOT_LOCKED) || (GetLastError() == MAGIC_DEAD)),
        "returned %d with %d (expected '0' with: ERROR_NOT_LOCKED or "
        "MAGIC_DEAD)\n", res, GetLastError());
 
    GlobalFree(gbl);
    /* invalid handles are caught in windows: */
    SetLastError(MAGIC_DEAD);
    hsecond = GlobalFree(gbl);      /* invalid handle: free memory twice */
    ok( (hsecond == gbl) && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n",
        hsecond, GetLastError(), gbl);
    SetLastError(MAGIC_DEAD);
    flags = GlobalFlags(gbl);
    ok( (flags == GMEM_INVALID_HANDLE) && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned 0x%04x with 0x%08x (expected GMEM_INVALID_HANDLE with "
        "ERROR_INVALID_HANDLE)\n", flags, GetLastError());
    SetLastError(MAGIC_DEAD);
    size = GlobalSize(gbl);
    ok( (size == 0) && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned %ld with 0x%08x (expected '0' with ERROR_INVALID_HANDLE)\n",
        size, GetLastError());

    SetLastError(MAGIC_DEAD);
    mem = GlobalLock(gbl);
    ok( (mem == NULL) && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned %p with 0x%08x (expected NULL with ERROR_INVALID_HANDLE)\n",
        mem, GetLastError());

    /* documented on MSDN: GlobalUnlock() return FALSE on failure.
       Win9x and wine return FALSE with ERROR_INVALID_HANDLE, but on 
       NT 3.51 and XPsp2, TRUE with ERROR_INVALID_HANDLE is returned.
       The similar Test for LocalUnlock() works on all Systems */
    SetLastError(MAGIC_DEAD);
    res = GlobalUnlock(gbl);
    ok(GetLastError() == ERROR_INVALID_HANDLE,
        "returned %d with %d (expected ERROR_INVALID_HANDLE)\n",
        res, GetLastError());

    gbl = GlobalAlloc(GMEM_DDESHARE, 100);

    /* first free */
    mem = GlobalFree(gbl);
    ok(mem == NULL, "Expected NULL, got %p\n", mem);

    /* invalid free */
    if (sizeof(void *) != 8)  /* crashes on 64-bit Vista */
    {
        SetLastError(MAGIC_DEAD);
        mem = GlobalFree(gbl);
        ok(mem == gbl || broken(mem == NULL) /* nt4 */, "Expected gbl, got %p\n", mem);
        if (mem == gbl)
            ok(GetLastError() == ERROR_INVALID_HANDLE ||
               GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
               "Expected ERROR_INVALID_HANDLE or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
    }

    /* GMEM_FIXED block expands in place only without flags */
    for (size = 1; size <= max_size; size <<= 1) {
        gbl = GlobalAlloc(GMEM_FIXED, init_size);
        SetLastError(MAGIC_DEAD);
        hsecond = GlobalReAlloc(gbl, size + init_size, 0);
        ok(hsecond == gbl || (hsecond == NULL && GetLastError() == ERROR_NOT_ENOUGH_MEMORY),
           "got %p with %x (expected %p or NULL) @%ld\n", hsecond, GetLastError(), gbl, size);
        GlobalFree(gbl);
    }

    /* GMEM_FIXED block can be relocated with GMEM_MOVEABLE */
    for (size = 1; size <= max_size; size <<= 1) {
        gbl = GlobalAlloc(GMEM_FIXED, init_size);
        SetLastError(MAGIC_DEAD);
        hsecond = GlobalReAlloc(gbl, size + init_size, GMEM_MOVEABLE);
        ok(hsecond != NULL,
           "got %p with %x (expected non-NULL) @%ld\n", hsecond, GetLastError(), size);
        mem = GlobalLock(hsecond);
        ok(mem == hsecond, "got %p (expected %p) @%ld\n", mem, hsecond, size);
        GlobalFree(hsecond);
    }

    gbl = GlobalAlloc(GMEM_DDESHARE, 100);

    res = GlobalUnlock(gbl);
    ok(res == 1 ||
       broken(res == 0), /* win9x */
       "Expected 1 or 0, got %d\n", res);

    res = GlobalUnlock(gbl);
    ok(res == 1 ||
       broken(res == 0), /* win9x */
       "Expected 1 or 0, got %d\n", res);

    GlobalFree(gbl);

    gbl = GlobalAlloc(GMEM_FIXED, 100);

    SetLastError(0xdeadbeef);
    res = GlobalUnlock(gbl);
    ok(res == 1 ||
       broken(res == 0), /* win9x */
       "Expected 1 or 0, got %d\n", res);
    ok(GetLastError() == 0xdeadbeef, "got %d\n", GetLastError());

    GlobalFree(gbl);

    /* GlobalSize on an invalid handle */
    if (sizeof(void *) != 8)  /* crashes on 64-bit Vista */
    {
        SetLastError(MAGIC_DEAD);
        size = GlobalSize((HGLOBAL)0xc042);
        ok(size == 0, "Expected 0, got %ld\n", size);
        ok(GetLastError() == ERROR_INVALID_HANDLE ||
           GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
           "Expected ERROR_INVALID_HANDLE or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
    }

    gbl = GlobalAlloc( GMEM_FIXED, 0 );
    SetLastError(0xdeadbeef);
    size = GlobalSize( gbl );
    ok( size == 1, "wrong size %lu\n", size );
    GlobalFree( gbl );

    /* ####################################### */
    /* Local*() functions */
    gbl = LocalAlloc(LMEM_MOVEABLE, 0);
    ok(gbl != NULL, "local memory not allocated for size 0\n");

    gbl = LocalReAlloc(gbl, 10, LMEM_MOVEABLE);
    ok(gbl != NULL, "Can't realloc local memory\n");
    size = LocalSize(gbl);
    ok(size >= 10 && size <= 16, "Memory not resized to size 10, instead size=%ld\n", size);

    gbl = LocalReAlloc(gbl, 0, LMEM_MOVEABLE);
    ok(gbl != NULL, "LocalReAlloc should not fail on size 0\n");

    size = LocalSize(gbl);
    ok(size == 0, "Memory not resized to size 0, instead size=%ld\n", size);
    ok(LocalFree(gbl) == NULL, "Memory not freed\n");
    size = LocalSize(gbl);
    ok(size == 0, "Memory should have been freed, size=%ld\n", size);

    gbl = LocalReAlloc(0, 10, LMEM_MOVEABLE);
    ok(gbl == NULL, "local realloc allocated memory\n");

    /* LocalLock / LocalUnlock with a valid handle */
    gbl = LocalAlloc(LMEM_MOVEABLE, 256);
    SetLastError(MAGIC_DEAD);
    mem = LocalLock(gbl);      /* #1 */
    ok(mem != NULL, "returned %p with %d (expected '!= NULL')\n", mem, GetLastError());
    SetLastError(MAGIC_DEAD);
    flags = LocalFlags(gbl);
    ok( flags == 1, "returned 0x%04x with %d (expected '0x0001')\n",
        flags, GetLastError());

    SetLastError(MAGIC_DEAD);
    msecond = LocalLock(gbl);   /* #2 */
    ok( msecond == mem, "returned %p with %d (expected '%p')\n",
        msecond, GetLastError(), mem);
    SetLastError(MAGIC_DEAD);
    flags = LocalFlags(gbl);
    ok( flags == 2, "returned 0x%04x with %d (expected '0x0002')\n",
        flags, GetLastError());
    SetLastError(MAGIC_DEAD);

    SetLastError(MAGIC_DEAD);
    res = LocalUnlock(gbl);    /* #1 */
    ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
    SetLastError(MAGIC_DEAD);
    flags = LocalFlags(gbl);
    ok( flags , "returned 0x%04x with %d (expected '!= 0')\n",
        flags, GetLastError());

    SetLastError(MAGIC_DEAD);
    res = LocalUnlock(gbl);    /* #0 */
    /* NT: ERROR_SUCCESS (documented on MSDN), 9x: untouched */
    ok(!res && ((GetLastError() == ERROR_SUCCESS) || (GetLastError() == MAGIC_DEAD)),
        "returned %d with %d (expected '0' with: ERROR_SUCCESS or "
        "MAGIC_DEAD)\n", res, GetLastError());
    SetLastError(MAGIC_DEAD);
    flags = LocalFlags(gbl);
    ok( !flags , "returned 0x%04x with %d (expected '0')\n",
        flags, GetLastError());

    /* Unlock an already unlocked Handle */
    SetLastError(MAGIC_DEAD);
    res = LocalUnlock(gbl);
    /* NT: ERROR_NOT_LOCKED,  9x: untouched */
    ok( !res &&
        ((GetLastError() == ERROR_NOT_LOCKED) || (GetLastError() == MAGIC_DEAD)),
        "returned %d with %d (expected '0' with: ERROR_NOT_LOCKED or "
        "MAGIC_DEAD)\n", res, GetLastError());

    LocalFree(gbl);
    /* invalid handles are caught in windows: */
    SetLastError(MAGIC_DEAD);
    hsecond = LocalFree(gbl);       /* invalid handle: free memory twice */
    ok( (hsecond == gbl) && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n",
        hsecond, GetLastError(), gbl);
    SetLastError(MAGIC_DEAD);
    flags = LocalFlags(gbl);
    ok( (flags == LMEM_INVALID_HANDLE) && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned 0x%04x with 0x%08x (expected LMEM_INVALID_HANDLE with "
        "ERROR_INVALID_HANDLE)\n", flags, GetLastError());
    SetLastError(MAGIC_DEAD);
    size = LocalSize(gbl);
    ok( (size == 0) && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned %ld with 0x%08x (expected '0' with ERROR_INVALID_HANDLE)\n",
        size, GetLastError());

    SetLastError(MAGIC_DEAD);
    mem = LocalLock(gbl);
    ok( (mem == NULL) && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned %p with 0x%08x (expected NULL with ERROR_INVALID_HANDLE)\n",
        mem, GetLastError());

    /* This Test works the same on all Systems (GlobalUnlock() is different) */
    SetLastError(MAGIC_DEAD);
    res = LocalUnlock(gbl);
    ok(!res && (GetLastError() == ERROR_INVALID_HANDLE),
        "returned %d with %d (expected '0' with ERROR_INVALID_HANDLE)\n",
        res, GetLastError());

    /* LMEM_FIXED block expands in place only without flags */
    for (size = 1; size <= max_size; size <<= 1) {
        gbl = LocalAlloc(LMEM_FIXED, init_size);
        SetLastError(MAGIC_DEAD);
        hsecond = LocalReAlloc(gbl, size + init_size, 0);
        ok(hsecond == gbl || (hsecond == NULL && GetLastError() == ERROR_NOT_ENOUGH_MEMORY),
           "got %p with %x (expected %p or NULL) @%ld\n", hsecond, GetLastError(), gbl, size);
        LocalFree(gbl);
    }

    /* LMEM_FIXED memory can be relocated with LMEM_MOVEABLE */
    for (size = 1; size <= max_size; size <<= 1) {
        gbl = LocalAlloc(LMEM_FIXED, init_size);
        SetLastError(MAGIC_DEAD);
        hsecond = LocalReAlloc(gbl, size + init_size, LMEM_MOVEABLE);
        ok(hsecond != NULL,
           "got %p with %x (expected non-NULL) @%ld\n", hsecond, GetLastError(), size);
        mem = LocalLock(hsecond);
        ok(mem == hsecond, "got %p (expected %p) @%ld\n", mem, hsecond, size);
        LocalFree(hsecond);
    }

    /* trying to unlock pointer from LocalAlloc */
    gbl = LocalAlloc(LMEM_FIXED, 100);
    SetLastError(0xdeadbeef);
    res = LocalUnlock(gbl);
    ok(res == 0, "Expected 0, got %d\n", res);
    ok(GetLastError() == ERROR_NOT_LOCKED ||
       broken(GetLastError() == 0xdeadbeef) /* win9x */, "got %d\n", GetLastError());
    LocalFree(gbl);

    gbl = LocalAlloc( LMEM_FIXED, 0 );
    SetLastError(0xdeadbeef);
    size = LocalSize( gbl );
    ok( !size || broken(size == 1), /* vistau64 */
        "wrong size %lu\n", size );
    LocalFree( gbl );

    /* trying to lock empty memory should give an error */
    gbl = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,0);
    ok(gbl != NULL, "returned NULL\n");
    SetLastError(MAGIC_DEAD);
    mem = GlobalLock(gbl);
    /* NT: ERROR_DISCARDED,  9x: untouched */
    ok( (mem == NULL) &&
        ((GetLastError() == ERROR_DISCARDED) || (GetLastError() == MAGIC_DEAD)),
        "returned %p with 0x%x/%d (expected 'NULL' with: ERROR_DISCARDED or "
        "MAGIC_DEAD)\n", mem, GetLastError(), GetLastError());

    GlobalFree(gbl);

    /* trying to get size from data pointer (GMEM_MOVEABLE) */
    gbl = GlobalAlloc(GMEM_MOVEABLE, 0x123);
    ok(gbl != NULL, "returned NULL\n");
    mem = GlobalLock(gbl);
    ok(mem != NULL, "returned NULL.\n");
    ok(gbl != mem, "unexpectedly equal.\n");

    size = GlobalSize(gbl);
    size2 = GlobalSize(mem);
    ok(size == 0x123, "got %lu\n", size);
    ok(size2 == 0x123, "got %lu\n", size2);

    GlobalFree(gbl);

    /* trying to get size from data pointer (GMEM_FIXED) */
    gbl = GlobalAlloc(GMEM_FIXED, 0x123);
    ok(gbl != NULL, "returned NULL\n");
    mem = GlobalLock(gbl);
    ok(mem != NULL, "returned NULL.\n");
    ok(gbl == mem, "got %p, %p.\n", gbl, mem);

    size = GlobalSize(gbl);
    ok(size == 0x123, "got %lu\n", size);

    GlobalFree(gbl);

    size = GlobalSize((void *)0xdeadbee0);
    ok(size == 0, "got %lu\n", size);

}