/*
 * Global heap functions
 *
 * Copyright 1995 Alexandre Julliard
 */

#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "windows.h"
#include "global.h"
#include "heap.h"
#include "toolhelp.h"
#include "selectors.h"
#include "miscemu.h"
#include "dde_mem.h"
#include "stackframe.h"
#include "module.h"
#include "debug.h"
#include "winerror.h"

  /* Global arena block */
typedef struct
{
    DWORD     base;          /* Base address (0 if discarded) */
    DWORD     size;          /* Size in bytes (0 indicates a free block) */
    HGLOBAL16 handle;        /* Handle for this block */
    HGLOBAL16 hOwner;        /* Owner of this block */
    BYTE      lockCount;     /* Count of GlobalFix() calls */
    BYTE      pageLockCount; /* Count of GlobalPageLock() calls */
    BYTE      flags;         /* Allocation flags */
    BYTE      selCount;      /* Number of selectors allocated for this block */
#ifdef CONFIG_IPC
    int       shmid;
#endif
} GLOBALARENA;

  /* Flags definitions */
#define GA_MOVEABLE     0x02  /* same as GMEM_MOVEABLE */
#define GA_DGROUP       0x04
#define GA_DISCARDABLE  0x08
#define GA_IPCSHARE     0x10  /* same as GMEM_DDESHARE */

  /* Arena array */
static GLOBALARENA *pGlobalArena = NULL;
static int globalArenaSize = 0;

#define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000  /* Largest allocation is 16M - 64K */

#define VALID_HANDLE(handle) (((handle)>>__AHSHIFT)<globalArenaSize)
#define GET_ARENA_PTR(handle)  (pGlobalArena + ((handle) >> __AHSHIFT))

/***********************************************************************
 *           GLOBAL_GetArena
 *
 * Return the arena for a given selector, growing the arena array if needed.
 */
static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount )
{
    if (((sel >> __AHSHIFT) + selcount) > globalArenaSize)
    {
        int newsize = ((sel >> __AHSHIFT) + selcount + 0xff) & ~0xff;
        GLOBALARENA *pNewArena = realloc( pGlobalArena,
                                          newsize * sizeof(GLOBALARENA) );
        if (!pNewArena) return 0;
        pGlobalArena = pNewArena;
        memset( pGlobalArena + globalArenaSize, 0,
                (newsize - globalArenaSize) * sizeof(GLOBALARENA) );
        globalArenaSize = newsize;
    }
    return pGlobalArena + (sel >> __AHSHIFT);
}


void debug_handles()
{
    int printed=0;
    int i;
    for (i = globalArenaSize-1 ; i>=0 ; i--) {
	if (pGlobalArena[i].size!=0 && (pGlobalArena[i].handle & 0x8000)){
	    printed=1;
	    DUMP("0x%08x, ",pGlobalArena[i].handle);
	}
    }
    if (printed)
	DUMP("\n");
}


/***********************************************************************
 *           GLOBAL_CreateBlock
 *
 * Create a global heap block for a fixed range of linear memory.
 */
HGLOBAL16 GLOBAL_CreateBlock( WORD flags, const void *ptr, DWORD size,
                              HGLOBAL16 hOwner, BOOL16 isCode,
                              BOOL16 is32Bit, BOOL16 isReadOnly,
                              SHMDATA *shmdata  )
{
    WORD sel, selcount;
    GLOBALARENA *pArena;

      /* Allocate the selector(s) */

    sel = SELECTOR_AllocBlock( ptr, size,
			      isCode ? SEGMENT_CODE : SEGMENT_DATA,
			      is32Bit, isReadOnly );
    
    if (!sel) return 0;
    selcount = (size + 0xffff) / 0x10000;

    if (!(pArena = GLOBAL_GetArena( sel, selcount )))
    {
        SELECTOR_FreeBlock( sel, selcount );
        return 0;
    }

      /* Fill the arena block */

    pArena->base = (DWORD)ptr;
    pArena->size = GET_SEL_LIMIT(sel) + 1;

#ifdef CONFIG_IPC
    if (flags & GMEM_DDESHARE)
    {
	pArena->handle = shmdata->handle;
	pArena->shmid  = shmdata->shmid;
	shmdata->sel   = sel;
    }
    else
    {
	pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
	pArena->shmid  = 0;
    }
#else
    pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
#endif
    pArena->hOwner = hOwner;
    pArena->lockCount = 0;
    pArena->pageLockCount = 0;
    pArena->flags = flags & GA_MOVEABLE;
    if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
    if (flags & GMEM_DDESHARE) pArena->flags |= GA_IPCSHARE;
    if (!isCode) pArena->flags |= GA_DGROUP;
    pArena->selCount = selcount;
    if (selcount > 1)  /* clear the next arena blocks */
        memset( pArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );

    return pArena->handle;
}


/***********************************************************************
 *           GLOBAL_FreeBlock
 *
 * Free a block allocated by GLOBAL_CreateBlock, without touching
 * the associated linear memory range.
 */
BOOL16 GLOBAL_FreeBlock( HGLOBAL16 handle )
{
    WORD sel;
    GLOBALARENA *pArena;

    if (!handle) return TRUE;
    sel = GlobalHandleToSel( handle ); 
    if (!VALID_HANDLE(sel))
    	return FALSE;
    pArena = GET_ARENA_PTR(sel);
    SELECTOR_FreeBlock( sel, (pArena->size + 0xffff) / 0x10000 );
    memset( pArena, 0, sizeof(GLOBALARENA) );
    return TRUE;
}


/***********************************************************************
 *           GLOBAL_Alloc
 *
 * Implementation of GlobalAlloc16()
 */
HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
                        BOOL16 isCode, BOOL16 is32Bit, BOOL16 isReadOnly )
{
    void *ptr;
    HGLOBAL16 handle;
    SHMDATA shmdata;

    TRACE(global, "%ld flags=%04x\n", size, flags );

    /* If size is 0, create a discarded block */

    if (size == 0) return GLOBAL_CreateBlock( flags, NULL, 1, hOwner, isCode,
                                              is32Bit, isReadOnly, NULL );

    /* Fixup the size */

    if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x1f) return 0;
    size = (size + 0x1f) & ~0x1f;

      /* Allocate the linear memory */

#ifdef CONFIG_IPC
    if (flags & GMEM_DDESHARE)
        ptr = DDE_malloc(flags, size, &shmdata);
    else 
#endif  /* CONFIG_IPC */
    {
	ptr = HeapAlloc( SystemHeap, 0, size );
    }
      /* FIXME: free discardable blocks and try again? */
    if (!ptr) return 0;

      /* Allocate the selector(s) */

    handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner,
				isCode, is32Bit, isReadOnly, &shmdata);
    if (!handle)
    {
        HeapFree( SystemHeap, 0, ptr );
        return 0;
    }

    if (flags & GMEM_ZEROINIT) memset( ptr, 0, size );
    return handle;
}


#ifdef CONFIG_IPC
/***********************************************************************
 *           GLOBAL_FindArena
 *
 * Find the arena  for a given handle
 * (when handle is not serial - e.g. DDE)
 */
static GLOBALARENA *GLOBAL_FindArena( HGLOBAL16 handle)
{
    int i;
    for (i = globalArenaSize-1 ; i>=0 ; i--) {
	if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == handle)
	    return ( &pGlobalArena[i] );
    }
    return NULL;
}


/***********************************************************************
 *           DDE_GlobalHandleToSel
 */

WORD DDE_GlobalHandleToSel( HGLOBAL16 handle )
{
    GLOBALARENA *pArena;
    SEGPTR segptr;
    
    pArena= GLOBAL_FindArena(handle);
    if (pArena) {
	int ArenaIdx = pArena - pGlobalArena;

	/* See if synchronized to the shared memory  */
	return DDE_SyncHandle(handle, ( ArenaIdx << __AHSHIFT) | 7);
    }

    /* attach the block */
    DDE_AttachHandle(handle, &segptr);

    return SELECTOROF( segptr );
}
#endif  /* CONFIG_IPC */


/***********************************************************************
 *           GlobalAlloc16   (KERNEL.15)
 * RETURNS
 *	Handle: Success
 *	NULL: Failure
 */
HGLOBAL16 WINAPI GlobalAlloc16(
                 UINT16 flags, /* [in] Object allocation attributes */
                 DWORD size    /* [in] Number of bytes to allocate */
) {
    HANDLE16 owner = GetCurrentPDB();

    if (flags & GMEM_DDESHARE)
        owner = MODULE_HANDLEtoHMODULE16(owner);  /* Make it a module handle */
    return GLOBAL_Alloc( flags, size, owner, FALSE, FALSE, FALSE );
}


/***********************************************************************
 *           GlobalReAlloc16   (KERNEL.16)
 * RETURNS
 *	Handle: Success
 *	NULL: Failure
 */
HGLOBAL16 WINAPI GlobalReAlloc16(
                 HGLOBAL16 handle, /* [in] Handle of global memory object */
                 DWORD size,       /* [in] New size of block */
                 UINT16 flags      /* [in] How to reallocate object */
) {
    WORD selcount;
    DWORD oldsize;
    void *ptr;
    GLOBALARENA *pArena, *pNewArena;
    WORD sel = GlobalHandleToSel( handle );

    TRACE(global, "%04x %ld flags=%04x\n",
                    handle, size, flags );
    if (!handle) return 0;
    
#ifdef CONFIG_IPC
    if (flags & GMEM_DDESHARE || is_dde_handle(handle))
    {
	FIXME(global, "shared memory reallocating unimplemented\n"); 
	return 0;
    }
#endif  /* CONFIG_IPC */

    if (!VALID_HANDLE(handle)) {
    	WARN(global, "Invalid handle 0x%04x!\n", handle);
    	return 0;
    }
    pArena = GET_ARENA_PTR( handle );

      /* Discard the block if requested */

    if ((size == 0) && (flags & GMEM_MOVEABLE) && !(flags & GMEM_MODIFY))
    {
        if (!(pArena->flags & GA_MOVEABLE) ||
            !(pArena->flags & GA_DISCARDABLE) ||
            (pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
        HeapFree( SystemHeap, 0, (void *)pArena->base );
        pArena->base = 0;

        /* Note: we rely on the fact that SELECTOR_ReallocBlock won't 
         * change the selector if we are shrinking the block.
	 * FIXME: shouldn't we keep selectors until the block is deleted?
	 */
        SELECTOR_ReallocBlock( sel, 0, 1, SEGMENT_DATA, 0, 0 );
        return handle;
    }

      /* Fixup the size */

    if (size > GLOBAL_MAX_ALLOC_SIZE - 0x20) return 0;
    if (size == 0) size = 0x20;
    else size = (size + 0x1f) & ~0x1f;

      /* Change the flags */

    if (flags & GMEM_MODIFY)
    {
          /* Change the flags, leaving GA_DGROUP alone */
        pArena->flags = (pArena->flags & GA_DGROUP) | (flags & GA_MOVEABLE);
        if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
        return handle;
    }

      /* Reallocate the linear memory */

    ptr = (void *)pArena->base;
    oldsize = pArena->size;
    TRACE(global,"oldsize %08lx\n",oldsize);
    if (ptr && (size == oldsize)) return handle;  /* Nothing to do */

    ptr = HeapReAlloc( SystemHeap, 0, ptr, size );
    if (!ptr)
    {
        SELECTOR_FreeBlock( sel, (oldsize + 0xffff) / 0x10000 );
        memset( pArena, 0, sizeof(GLOBALARENA) );
        return 0;
    }

      /* Reallocate the selector(s) */

    sel = SELECTOR_ReallocBlock( sel, ptr, size, SEGMENT_DATA, 0, 0 );
    if (!sel)
    {
        HeapFree( SystemHeap, 0, ptr );
        memset( pArena, 0, sizeof(GLOBALARENA) );
        return 0;
    }
    selcount = (size + 0xffff) / 0x10000;

    if (!(pNewArena = GLOBAL_GetArena( sel, selcount )))
    {
        HeapFree( SystemHeap, 0, ptr );
        SELECTOR_FreeBlock( sel, selcount );
        return 0;
    }

      /* Fill the new arena block */

    if (pNewArena != pArena) memcpy( pNewArena, pArena, sizeof(GLOBALARENA) );
    pNewArena->base = (DWORD)ptr;
    pNewArena->size = GET_SEL_LIMIT(sel) + 1;
    pNewArena->selCount = selcount;
    pNewArena->handle = (pNewArena->flags & GA_MOVEABLE) ? sel - 1 : sel;

    if (selcount > 1)  /* clear the next arena blocks */
        memset( pNewArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );

    if ((oldsize < size) && (flags & GMEM_ZEROINIT))
        memset( (char *)ptr + oldsize, 0, size - oldsize );
    return pNewArena->handle;
}


/***********************************************************************
 *           GlobalFree16   (KERNEL.17)
 * RETURNS
 *	NULL: Success
 *	Handle: Failure
 */
HGLOBAL16 WINAPI GlobalFree16(
                 HGLOBAL16 handle /* [in] Handle of global memory object */
) {
    void *ptr;

    if (!VALID_HANDLE(handle)) {
    	fprintf(stderr," Invalid handle 0x%04x passed to GlobalFree16!\n",handle);
    	return 0;
    }
    ptr = (void *)GET_ARENA_PTR(handle)->base;

    TRACE(global, "%04x\n", handle );
    if (!GLOBAL_FreeBlock( handle )) return handle;  /* failed */
#ifdef CONFIG_IPC
    if (is_dde_handle(handle)) return DDE_GlobalFree(handle);
#endif  /* CONFIG_IPC */
    if (ptr) HeapFree( SystemHeap, 0, ptr );
    return 0;
}


/***********************************************************************
 *           WIN16_GlobalLock16   (KERNEL.18)
 *
 * This is the GlobalLock16() function used by 16-bit code.
 */
SEGPTR WINAPI WIN16_GlobalLock16( HGLOBAL16 handle )
{
    TRACE(global, "(%04x) -> %08lx\n",
                    handle, MAKELONG( 0, GlobalHandleToSel(handle)) );
    if (handle)
    {
	if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;

#ifdef CONFIG_IPC
	if (is_dde_handle(handle))
	    return PTR_SEG_OFF_TO_SEGPTR( DDE_GlobalHandleToSel(handle), 0 );
#endif  /* CONFIG_IPC */

	if (!VALID_HANDLE(handle)) {
	    fprintf(stderr,"Invalid handle 0x%04x passed to WIN16_GlobalLock16!\n",handle);
	    return (SEGPTR)0;
	}
	if (!GET_ARENA_PTR(handle)->base) return (SEGPTR)0;
        GET_ARENA_PTR(handle)->lockCount++;
	return PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(handle), 0 );
	/* FIXME: put segment value in CX as well */
    }
    return (SEGPTR)0;
}


/***********************************************************************
 *           GlobalLock16   (KERNEL.18)
 *
 * This is the GlobalLock16() function used by 32-bit code.
 * 
 * RETURNS
 *	Pointer to first byte of memory block
 *	NULL: Failure
 */
LPVOID WINAPI GlobalLock16(
              HGLOBAL16 handle /* [in] Handle of global memory object */
) {
    if (!handle) return 0;
    if (!VALID_HANDLE(handle))
	return (LPVOID)0;
    GET_ARENA_PTR(handle)->lockCount++;
#ifdef CONFIG_IPC
    if (is_dde_handle(handle)) return DDE_AttachHandle(handle, NULL);
#endif
    return (LPVOID)GET_ARENA_PTR(handle)->base;
}


/***********************************************************************
 *           GlobalUnlock16   (KERNEL.19)
 * NOTES
 *	Should the return values be cast to booleans?
 *
 * RETURNS
 *	TRUE: Object is still locked
 *	FALSE: Object is unlocked
 */
BOOL16 WINAPI GlobalUnlock16(
              HGLOBAL16 handle /* [in] Handle of global memory object */
) {
    GLOBALARENA *pArena = GET_ARENA_PTR(handle);
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to GlobalUnlock16!\n",handle);
	return 0;
    }
    TRACE(global, "%04x\n", handle );
    if (pArena->lockCount) pArena->lockCount--;
    return pArena->lockCount;
}


/***********************************************************************
 *           GlobalSize16   (KERNEL.20)
 * RETURNS
 *	Size in bytes of object
 *	0: Failure
 */
DWORD WINAPI GlobalSize16(
             HGLOBAL16 handle /* [in] Handle of global memory object */
) {
    TRACE(global, "%04x\n", handle );
    if (!handle) return 0;
    if (!VALID_HANDLE(handle))
	return 0;
    return GET_ARENA_PTR(handle)->size;
}


/***********************************************************************
 *           GlobalHandle16   (KERNEL.21)
 * NOTES
 *	Why is GlobalHandleToSel used here with the sel as input?
 *
 * RETURNS
 *	Handle: Success
 *	NULL: Failure
 */
DWORD WINAPI GlobalHandle16(
             WORD sel /* [in] Address of global memory block */
) {
    TRACE(global, "%04x\n", sel );
    if (!VALID_HANDLE(sel)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to GlobalHandle16!\n",sel);
	return 0;
    }
    return MAKELONG( GET_ARENA_PTR(sel)->handle, GlobalHandleToSel(sel) );
}

/***********************************************************************
 *           GlobalHandleNoRIP   (KERNEL.159)
 */
DWORD WINAPI GlobalHandleNoRIP( WORD sel )
{
    int i;
    for (i = globalArenaSize-1 ; i>=0 ; i--) {
        if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == sel)
		return MAKELONG( GET_ARENA_PTR(sel)->handle, GlobalHandleToSel(sel) );
    }
    return 0;
}


/***********************************************************************
 *           GlobalFlags16   (KERNEL.22)
 * NOTES
 *	Should this return GMEM_INVALID_HANDLE instead of 0 on invalid
 *	handle?
 *
 * RETURNS
 *	Value specifying flags and lock count
 *	GMEM_INVALID_HANDLE: Invalid handle
 */
UINT16 WINAPI GlobalFlags16(
              HGLOBAL16 handle /* [in] Handle of global memory object */
) {
    GLOBALARENA *pArena;

    TRACE(global, "%04x\n", handle );
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to GlobalFlags16!\n",handle);
	return 0;
    }
    pArena = GET_ARENA_PTR(handle);
    return pArena->lockCount |
           ((pArena->flags & GA_DISCARDABLE) ? GMEM_DISCARDABLE : 0) |
           ((pArena->base == 0) ? GMEM_DISCARDED : 0);
}


/***********************************************************************
 *           LockSegment16   (KERNEL.23)
 */
HGLOBAL16 WINAPI LockSegment16( HGLOBAL16 handle )
{
    TRACE(global, "%04x\n", handle );
    if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to LockSegment16!\n",handle);
	return 0;
    }
    GET_ARENA_PTR(handle)->lockCount++;
    return handle;
}


/***********************************************************************
 *           UnlockSegment16   (KERNEL.24)
 */
void WINAPI UnlockSegment16( HGLOBAL16 handle )
{
    TRACE(global, "%04x\n", handle );
    if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to UnlockSegment16!\n",handle);
	return;
    }
    GET_ARENA_PTR(handle)->lockCount--;
    /* FIXME: this ought to return the lock count in CX (go figure...) */
}


/***********************************************************************
 *           GlobalCompact16   (KERNEL.25)
 */
DWORD WINAPI GlobalCompact16( DWORD desired )
{
    return GLOBAL_MAX_ALLOC_SIZE;
}


/***********************************************************************
 *           GlobalFreeAll   (KERNEL.26)
 */
void WINAPI GlobalFreeAll( HGLOBAL16 owner )
{
    DWORD i;
    GLOBALARENA *pArena;

    pArena = pGlobalArena;
    for (i = 0; i < globalArenaSize; i++, pArena++)
    {
        if ((pArena->size != 0) && (pArena->hOwner == owner))
            GlobalFree16( pArena->handle );
    }
}


/***********************************************************************
 *           GlobalWire16   (KERNEL.111)
 */
SEGPTR WINAPI GlobalWire16( HGLOBAL16 handle )
{
    return WIN16_GlobalLock16( handle );
}


/***********************************************************************
 *           GlobalUnWire16   (KERNEL.112)
 */
BOOL16 WINAPI GlobalUnWire16( HGLOBAL16 handle )
{
    return !GlobalUnlock16( handle );
}


/***********************************************************************
 *           SetSwapAreaSize16   (KERNEL.106)
 */
LONG WINAPI SetSwapAreaSize16( WORD size )
{
    FIXME(global, "(%d) - stub!\n", size );
    return MAKELONG( size, 0xffff );
}


/***********************************************************************
 *           GlobalLRUOldest   (KERNEL.163)
 */
HGLOBAL16 WINAPI GlobalLRUOldest( HGLOBAL16 handle )
{
    TRACE(global, "%04x\n", handle );
    if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
    return handle;
}


/***********************************************************************
 *           GlobalLRUNewest   (KERNEL.164)
 */
HGLOBAL16 WINAPI GlobalLRUNewest( HGLOBAL16 handle )
{
    TRACE(global, "%04x\n", handle );
    if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
    return handle;
}


/***********************************************************************
 *           GetFreeSpace16   (KERNEL.169)
 */
DWORD WINAPI GetFreeSpace16( UINT16 wFlags )
{
    MEMORYSTATUS ms;
    GlobalMemoryStatus( &ms );
    return ms.dwAvailVirtual;
}

/***********************************************************************
 *           GlobalDOSAlloc   (KERNEL.184)
 * RETURNS
 *	Address (HW=Paragraph segment; LW=Selector)
 */
DWORD WINAPI GlobalDOSAlloc(
             DWORD size /* [in] Number of bytes to be allocated */
) {
   UINT16    uParagraph;
   LPVOID    lpBlock = DOSMEM_GetBlock( size, &uParagraph );

   if( lpBlock )
   {
       HMODULE16 hModule = GetModuleHandle16("KERNEL");
       WORD	 wSelector;
   
       wSelector = GLOBAL_CreateBlock(GMEM_FIXED, lpBlock, size, 
				      hModule, 0, 0, 0, NULL );
       return MAKELONG(wSelector,uParagraph);
   }
   return 0;
}


/***********************************************************************
 *           GlobalDOSFree      (KERNEL.185)
 * RETURNS
 *	NULL: Success
 *	sel: Failure
 */
WORD WINAPI GlobalDOSFree(
            WORD sel /* [in] Selector */
) {
   DWORD   block = GetSelectorBase(sel);

   if( block && block < 0x100000 ) 
   {
       LPVOID lpBlock = DOSMEM_MapDosToLinear( block );
       if( DOSMEM_FreeBlock( lpBlock ) )
	   GLOBAL_FreeBlock( sel );
       sel = 0;
   }
   return sel;
}


/***********************************************************************
 *           GlobalPageLock   (KERNEL.191)
 */
WORD WINAPI GlobalPageLock( HGLOBAL16 handle )
{
    TRACE(global, "%04x\n", handle );
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to GlobalPageLock!\n",handle);
	return 0;
    }
    return ++(GET_ARENA_PTR(handle)->pageLockCount);
}


/***********************************************************************
 *           GlobalPageUnlock   (KERNEL.192)
 */
WORD WINAPI GlobalPageUnlock( HGLOBAL16 handle )
{
    TRACE(global, "%04x\n", handle );
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to GlobalPageUnlock!\n",handle);
	return 0;
    }
    return --(GET_ARENA_PTR(handle)->pageLockCount);
}


/***********************************************************************
 *           GlobalFix16   (KERNEL.197)
 */
void WINAPI GlobalFix16( HGLOBAL16 handle )
{
    TRACE(global, "%04x\n", handle );
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to GlobalFix16!\n",handle);
	return;
    }
    GET_ARENA_PTR(handle)->lockCount++;
}


/***********************************************************************
 *           GlobalUnfix16   (KERNEL.198)
 */
void WINAPI GlobalUnfix16( HGLOBAL16 handle )
{
    TRACE(global, "%04x\n", handle );
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to GlobalUnfix16!\n",handle);
	return;
    }
    GET_ARENA_PTR(handle)->lockCount--;
}


/***********************************************************************
 *           FarSetOwner   (KERNEL.403)
 */
void WINAPI FarSetOwner( HGLOBAL16 handle, HANDLE16 hOwner )
{
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to FarSetOwner!\n",handle);
	return;
    }
    GET_ARENA_PTR(handle)->hOwner = hOwner;
}


/***********************************************************************
 *           FarGetOwner   (KERNEL.404)
 */
HANDLE16 WINAPI FarGetOwner( HGLOBAL16 handle )
{
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to FarGetOwner!\n",handle);
	return 0;
    }
    return GET_ARENA_PTR(handle)->hOwner;
}


/***********************************************************************
 *           GlobalHandleToSel   (TOOLHELP.50)
 */
WORD WINAPI GlobalHandleToSel( HGLOBAL16 handle )
{
    TRACE(toolhelp, "%04x\n", handle );
    if (!handle) return 0;
#ifdef CONFIG_IPC
    if (is_dde_handle(handle)) return DDE_GlobalHandleToSel(handle);
#endif
    if (!VALID_HANDLE(handle)) {
	fprintf(stderr,"Invalid handle 0x%04x passed to GlobalHandleToSel!\n",handle);
	return 0;
    }
    if (!(handle & 7))
    {
        fprintf( stderr, "Program attempted invalid selector conversion\n" );
        return handle - 1;
    }
    return handle | 7;
}


/***********************************************************************
 *           GlobalFirst   (TOOLHELP.51)
 */
BOOL16 WINAPI GlobalFirst( GLOBALENTRY *pGlobal, WORD wFlags )
{
    if (wFlags == GLOBAL_LRU) return FALSE;
    pGlobal->dwNext = 0;
    return GlobalNext( pGlobal, wFlags );
}


/***********************************************************************
 *           GlobalNext   (TOOLHELP.52)
 */
BOOL16 WINAPI GlobalNext( GLOBALENTRY *pGlobal, WORD wFlags)
{
    GLOBALARENA *pArena;

    if (pGlobal->dwNext >= globalArenaSize) return FALSE;
    pArena = pGlobalArena + pGlobal->dwNext;
    if (wFlags == GLOBAL_FREE)  /* only free blocks */
    {
        int i;
        for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++)
            if (pArena->size == 0) break;  /* block is free */
        if (i >= globalArenaSize) return FALSE;
        pGlobal->dwNext = i;
    }

    pGlobal->dwAddress    = pArena->base;
    pGlobal->dwBlockSize  = pArena->size;
    pGlobal->hBlock       = pArena->handle;
    pGlobal->wcLock       = pArena->lockCount;
    pGlobal->wcPageLock   = pArena->pageLockCount;
    pGlobal->wFlags       = (GetCurrentPDB() == pArena->hOwner);
    pGlobal->wHeapPresent = FALSE;
    pGlobal->hOwner       = pArena->hOwner;
    pGlobal->wType        = GT_UNKNOWN;
    pGlobal->wData        = 0;
    pGlobal->dwNext++;
    return TRUE;
}


/***********************************************************************
 *           GlobalInfo   (TOOLHELP.53)
 */
BOOL16 WINAPI GlobalInfo( GLOBALINFO *pInfo )
{
    int i;
    GLOBALARENA *pArena;

    pInfo->wcItems = globalArenaSize;
    pInfo->wcItemsFree = 0;
    pInfo->wcItemsLRU = 0;
    for (i = 0, pArena = pGlobalArena; i < globalArenaSize; i++, pArena++)
        if (pArena->size == 0) pInfo->wcItemsFree++;
    return TRUE;
}


/***********************************************************************
 *           GlobalEntryHandle   (TOOLHELP.54)
 */
BOOL16 WINAPI GlobalEntryHandle( GLOBALENTRY *pGlobal, HGLOBAL16 hItem )
{
    GLOBALARENA *pArena = GET_ARENA_PTR(hItem);

    pGlobal->dwAddress    = pArena->base;
    pGlobal->dwBlockSize  = pArena->size;
    pGlobal->hBlock       = pArena->handle;
    pGlobal->wcLock       = pArena->lockCount;
    pGlobal->wcPageLock   = pArena->pageLockCount;
    pGlobal->wFlags       = (GetCurrentPDB() == pArena->hOwner);
    pGlobal->wHeapPresent = FALSE;
    pGlobal->hOwner       = pArena->hOwner;
    pGlobal->wType        = GT_UNKNOWN;
    pGlobal->wData        = 0;
    pGlobal->dwNext++;
    return TRUE;
}


/***********************************************************************
 *           GlobalEntryModule   (TOOLHELP.55)
 */
BOOL16 WINAPI GlobalEntryModule( GLOBALENTRY *pGlobal, HMODULE16 hModule,
                                 WORD wSeg )
{
    return FALSE;
}


/***********************************************************************
 *           MemManInfo   (TOOLHELP.72)
 */
BOOL16 WINAPI MemManInfo( MEMMANINFO *info )
{
    MEMORYSTATUS status;

    /*
     * Not unsurprisingly although the documention says you 
     * _must_ provide the size in the dwSize field, this function
     * (under Windows) always fills the structure and returns true.
     */
    GlobalMemoryStatus( &status );
#ifdef __svr4__
    info->wPageSize            = sysconf(_SC_PAGESIZE);
#else
    info->wPageSize            = getpagesize();
#endif
    info->dwLargestFreeBlock   = status.dwAvailVirtual;
    info->dwMaxPagesAvailable  = info->dwLargestFreeBlock / info->wPageSize;
    info->dwMaxPagesLockable   = info->dwMaxPagesAvailable;
    info->dwTotalLinearSpace   = status.dwTotalVirtual / info->wPageSize;
    info->dwTotalUnlockedPages = info->dwTotalLinearSpace;
    info->dwFreePages          = info->dwMaxPagesAvailable;
    info->dwTotalPages         = info->dwTotalLinearSpace;
    info->dwFreeLinearSpace    = info->dwMaxPagesAvailable;
    info->dwSwapFilePages      = status.dwTotalPageFile / info->wPageSize;
    return TRUE;
}

/***********************************************************************
 *           GetFreeMemInfo   (KERNEL.316)
 */
DWORD WINAPI GetFreeMemInfo(void)
{
    MEMMANINFO info;
    MemManInfo( &info );
    return MAKELONG( info.dwTotalLinearSpace, info.dwMaxPagesAvailable );
}

/*
 * Win32 Global heap functions (GlobalXXX).
 * These functions included in Win32 for compatibility with 16 bit Windows
 * Especially the moveable blocks and handles are oldish. 
 * But the ability to directly allocate memory with GPTR and LPTR is widely
 * used.
 *
 * The handle stuff looks horrible, but it's implemented almost like Win95
 * does it. 
 *
 */

#define MAGIC_GLOBAL_USED 0x5342
#define GLOBAL_LOCK_MAX   0xFF
#define HANDLE_TO_INTERN(h)  ((PGLOBAL32_INTERN)(((char *)(h))-2))
#define INTERN_TO_HANDLE(i)  ((HGLOBAL32) &((i)->Pointer))
#define POINTER_TO_HANDLE(p) (*(((HGLOBAL32 *)(p))-1))
#define ISHANDLE(h)          (((DWORD)(h)&2)!=0)
#define ISPOINTER(h)         (((DWORD)(h)&2)==0)

typedef struct __GLOBAL32_INTERN
{
   WORD         Magic;
   LPVOID       Pointer WINE_PACKED;
   BYTE         Flags;
   BYTE         LockCount;
} GLOBAL32_INTERN, *PGLOBAL32_INTERN;


/***********************************************************************
 *           GlobalAlloc32   (KERNEL32.315)
 * RETURNS
 *	Handle: Success
 *	NULL: Failure
 */
HGLOBAL32 WINAPI GlobalAlloc32(
                 UINT32 flags, /* [in] Object allocation attributes */
                 DWORD size    /* [in] Number of bytes to allocate */
) {
   PGLOBAL32_INTERN     pintern;
   DWORD		hpflags;
   LPVOID               palloc;

   if(flags&GMEM_ZEROINIT)
      hpflags=HEAP_ZERO_MEMORY;
   else
      hpflags=0;
   
   if((flags & GMEM_MOVEABLE)==0) /* POINTER */
   {
      palloc=HeapAlloc(GetProcessHeap(), hpflags, size);
      return (HGLOBAL32) palloc;
   }
   else  /* HANDLE */
   {
      /* HeapLock(GetProcessHeap()); */

      pintern=HeapAlloc(GetProcessHeap(), 0,  sizeof(GLOBAL32_INTERN));
      if(size)
      {
	 palloc=HeapAlloc(GetProcessHeap(), hpflags, size+sizeof(HGLOBAL32));
	 *(HGLOBAL32 *)palloc=INTERN_TO_HANDLE(pintern);
	 pintern->Pointer=palloc+sizeof(HGLOBAL32);
      }
      else
	 pintern->Pointer=NULL;
      pintern->Magic=MAGIC_GLOBAL_USED;
      pintern->Flags=flags>>8;
      pintern->LockCount=0;
      
      /* HeapUnlock(GetProcessHeap()); */
       
      return INTERN_TO_HANDLE(pintern);
   }
}


/***********************************************************************
 *           GlobalLock32   (KERNEL32.326)
 * RETURNS
 *	Pointer to first byte of block
 *	NULL: Failure
 */
LPVOID WINAPI GlobalLock32(
              HGLOBAL32 hmem /* [in] Handle of global memory object */
) {
   PGLOBAL32_INTERN pintern;
   LPVOID           palloc;

   if(ISPOINTER(hmem))
      return (LPVOID) hmem;

   /* HeapLock(GetProcessHeap()); */
   
   pintern=HANDLE_TO_INTERN(hmem);
   if(pintern->Magic==MAGIC_GLOBAL_USED)
   {
      if(pintern->LockCount<GLOBAL_LOCK_MAX)
	 pintern->LockCount++;
      palloc=pintern->Pointer;
   }
   else
   {
      WARN(global, "invalid handle\n");
      palloc=(LPVOID) NULL;
   }
   /* HeapUnlock(GetProcessHeap()); */;
   return palloc;
}


/***********************************************************************
 *           GlobalUnlock32   (KERNEL32.332)
 * RETURNS
 *	TRUE: Object is still locked
 *	FALSE: Object is unlocked
 */
BOOL32 WINAPI GlobalUnlock32(
              HGLOBAL32 hmem /* [in] Handle of global memory object */
) {
   PGLOBAL32_INTERN       pintern;
   BOOL32                 locked;

   if(ISPOINTER(hmem))
      return FALSE;

   /* HeapLock(GetProcessHeap()); */
   pintern=HANDLE_TO_INTERN(hmem);
   
   if(pintern->Magic==MAGIC_GLOBAL_USED)
   {
      if((pintern->LockCount<GLOBAL_LOCK_MAX)&&(pintern->LockCount>0))
	 pintern->LockCount--;

      locked=(pintern->LockCount==0) ? FALSE : TRUE;
   }
   else
   {
      WARN(global, "invalid handle\n");
      locked=FALSE;
   }
   /* HeapUnlock(GetProcessHeap()); */
   return locked;
}


/***********************************************************************
 *           GlobalHandle32   (KERNEL32.325)
 * Returns the handle associated with the specified pointer.
 *
 * NOTES
 *	Since there in only one goto, can it be removed and the return
 *	be put 'inline'?
 *
 * RETURNS
 *	Handle: Success
 *	NULL: Failure
 */
HGLOBAL32 WINAPI GlobalHandle32(
                 LPCVOID pmem /* [in] Pointer to global memory block */
) {
    HGLOBAL32 handle;

    if (!HEAP_IsInsideHeap( GetProcessHeap(), 0, pmem )) goto error;
    handle = POINTER_TO_HANDLE(pmem);
    if (HEAP_IsInsideHeap( GetProcessHeap(), 0, (LPCVOID)handle ))
    {
        if (HANDLE_TO_INTERN(handle)->Magic == MAGIC_GLOBAL_USED)
            return handle;  /* valid moveable block */
    }
    /* maybe FIXED block */
    if (HeapValidate( GetProcessHeap(), 0, pmem ))
        return (HGLOBAL32)pmem;  /* valid fixed block */

error:
    SetLastError( ERROR_INVALID_HANDLE );
    return 0;
}


/***********************************************************************
 *           GlobalReAlloc32   (KERNEL32.328)
 * RETURNS
 *	Handle: Success
 *	NULL: Failure
 */
HGLOBAL32 WINAPI GlobalReAlloc32(
                 HGLOBAL32 hmem, /* [in] Handle of global memory object */
                 DWORD size,     /* [in] New size of block */
                 UINT32 flags    /* [in] How to reallocate object */
) {
   LPVOID               palloc;
   HGLOBAL32            hnew;
   PGLOBAL32_INTERN     pintern;

   hnew = 0;
   /* HeapLock(GetProcessHeap()); */
   if(flags & GMEM_MODIFY) /* modify flags */
   {
      if( ISPOINTER(hmem) && (flags & GMEM_MOVEABLE))
      {
	 /* make a fixed block moveable
	  * actually only NT is able to do this. But it's soo simple
	  */
	 size=HeapSize(GetProcessHeap(), 0, (LPVOID) hmem);
	 hnew=GlobalAlloc32( flags, size);
	 palloc=GlobalLock32(hnew);
	 memcpy(palloc, (LPVOID) hmem, size);
	 GlobalUnlock32(hnew);
	 GlobalFree32(hmem);
      }
      else if( ISPOINTER(hmem) &&(flags & GMEM_DISCARDABLE))
      {
	 /* change the flags to make our block "discardable" */
	 pintern=HANDLE_TO_INTERN(hmem);
	 pintern->Flags = pintern->Flags | (GMEM_DISCARDABLE >> 8);
	 hnew=hmem;
      }
      else
      {
	 SetLastError(ERROR_INVALID_PARAMETER);
	 hnew = 0;
      }
   }
   else
   {
      if(ISPOINTER(hmem))
      {
	 /* reallocate fixed memory */
	 hnew=(HGLOBAL32)HeapReAlloc(GetProcessHeap(), 0, (LPVOID) hmem, size);
      }
      else
      {
	 /* reallocate a moveable block */
	 pintern=HANDLE_TO_INTERN(hmem);
	 if(pintern->LockCount!=0)
	    SetLastError(ERROR_INVALID_HANDLE);
	 else if(size!=0)
	 {
	    hnew=hmem;
	    if(pintern->Pointer)
	    {
	       palloc=HeapReAlloc(GetProcessHeap(), 0,
				  pintern->Pointer-sizeof(HGLOBAL32),
				  size+sizeof(HGLOBAL32) );
	       pintern->Pointer=palloc+sizeof(HGLOBAL32);
	    }
	    else
	    {
	       palloc=HeapAlloc(GetProcessHeap(), 0, size+sizeof(HGLOBAL32));
	       *(HGLOBAL32 *)palloc=hmem;
	       pintern->Pointer=palloc+sizeof(HGLOBAL32);
	    }
	 }
	 else
	 {
	    if(pintern->Pointer)
	    {
	       HeapFree(GetProcessHeap(), 0, pintern->Pointer-sizeof(HGLOBAL32));
	       pintern->Pointer=NULL;
	    }
	 }
      }
   }
   /* HeapUnlock(GetProcessHeap()); */
   return hnew;
}


/***********************************************************************
 *           GlobalFree32   (KERNEL32.322)
 * RETURNS
 *	NULL: Success
 *	Handle: Failure
 */
HGLOBAL32 WINAPI GlobalFree32(
                 HGLOBAL32 hmem /* [in] Handle of global memory object */
) {
   PGLOBAL32_INTERN pintern;
   HGLOBAL32        hreturned = 0;
   
   if(ISPOINTER(hmem)) /* POINTER */
   {
      if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) hmem = 0;
   }
   else  /* HANDLE */
   {
      /* HeapLock(GetProcessHeap()); */      
      pintern=HANDLE_TO_INTERN(hmem);
      
      if(pintern->Magic==MAGIC_GLOBAL_USED)
      {	 
	 if(pintern->LockCount!=0)
	    SetLastError(ERROR_INVALID_HANDLE);
	 if(pintern->Pointer)
	    if(!HeapFree(GetProcessHeap(), 0, 
	                 (char *)(pintern->Pointer)-sizeof(HGLOBAL32)))
	       hreturned=hmem;
	 if(!HeapFree(GetProcessHeap(), 0, pintern)) 
	    hreturned=hmem;
      }      
      /* HeapUnlock(GetProcessHeap()); */
   }
   return hreturned;
}


/***********************************************************************
 *           GlobalSize32   (KERNEL32.329)
 * RETURNS
 *	Size in bytes of the global memory object
 *	0: Failure
 */
DWORD WINAPI GlobalSize32(
             HGLOBAL32 hmem /* [in] Handle of global memory object */
) {
   DWORD                retval;
   PGLOBAL32_INTERN     pintern;

   if(ISPOINTER(hmem)) 
   {
      retval=HeapSize(GetProcessHeap(), 0,  (LPVOID) hmem);
   }
   else
   {
      /* HeapLock(GetProcessHeap()); */
      pintern=HANDLE_TO_INTERN(hmem);
      
      if(pintern->Magic==MAGIC_GLOBAL_USED)
      {
	 retval=HeapSize(GetProcessHeap(), 0, 
	                 (char *)(pintern->Pointer)-sizeof(HGLOBAL32))-4;
      }
      else
      {
	 WARN(global, "invalid handle\n");
	 retval=0;
      }
      /* HeapUnlock(GetProcessHeap()); */
   }
   return retval;
}


/***********************************************************************
 *           GlobalWire32   (KERNEL32.333)
 */
LPVOID WINAPI GlobalWire32(HGLOBAL32 hmem)
{
   return GlobalLock32( hmem );
}


/***********************************************************************
 *           GlobalUnWire32   (KERNEL32.330)
 */
BOOL32 WINAPI GlobalUnWire32(HGLOBAL32 hmem)
{
   return GlobalUnlock32( hmem);
}


/***********************************************************************
 *           GlobalFix32   (KERNEL32.320)
 */
VOID WINAPI GlobalFix32(HGLOBAL32 hmem)
{
    GlobalLock32( hmem );
}


/***********************************************************************
 *           GlobalUnfix32   (KERNEL32.331)
 */
VOID WINAPI GlobalUnfix32(HGLOBAL32 hmem)
{
   GlobalUnlock32( hmem);
}


/***********************************************************************
 *           GlobalFlags32   (KERNEL32.321)
 * Returns information about the specified global memory object
 *
 * NOTES
 *	Should this return GMEM_INVALID_HANDLE on invalid handle?
 *
 * RETURNS
 *	Value specifying allocation flags and lock count
 *	GMEM_INVALID_HANDLE: Failure
 */
UINT32 WINAPI GlobalFlags32(
              HGLOBAL32 hmem /* [in] Handle to global memory object */
) {
   DWORD                retval;
   PGLOBAL32_INTERN     pintern;
   
   if(ISPOINTER(hmem))
   {
      retval=0;
   }
   else
   {
      /* HeapLock(GetProcessHeap()); */
      pintern=HANDLE_TO_INTERN(hmem);
      if(pintern->Magic==MAGIC_GLOBAL_USED)
      {               
	 retval=pintern->LockCount + (pintern->Flags<<8);
	 if(pintern->Pointer==0)
	    retval|= GMEM_DISCARDED;
      }
      else
      {
	 WARN(global,"Invalid handle: %04x", hmem);
	 retval=0;
      }
      /* HeapUnlock(GetProcessHeap()); */
   }
   return retval;
}


/***********************************************************************
 *           GlobalCompact32   (KERNEL32.316)
 */
DWORD WINAPI GlobalCompact32( DWORD minfree )
{
    return 0;  /* GlobalCompact does nothing in Win32 */
}


/***********************************************************************
 *           GlobalMemoryStatus   (KERNEL32.327)
 * RETURNS
 *	None
 */
VOID WINAPI GlobalMemoryStatus(
            LPMEMORYSTATUS lpmem
) {
#ifdef linux
    FILE *f = fopen( "/proc/meminfo", "r" );
    if (f)
    {
        char buffer[256];
        int total, used, free;

        lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
        lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
        while (fgets( buffer, sizeof(buffer), f ))
        {
	    /* old style /proc/meminfo ... */
            if (sscanf( buffer, "Mem: %d %d %d", &total, &used, &free ))
            {
                lpmem->dwTotalPhys += total;
                lpmem->dwAvailPhys += free;
            }
            if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
            {
                lpmem->dwTotalPageFile += total;
                lpmem->dwAvailPageFile += free;
            }

	    /* new style /proc/meminfo ... */
	    if (sscanf(buffer, "MemTotal: %d", &total))
	    	lpmem->dwTotalPhys = total*1024;
	    if (sscanf(buffer, "MemFree: %d", &free))
	    	lpmem->dwAvailPhys = free*1024;
	    if (sscanf(buffer, "SwapTotal: %d", &total))
	        lpmem->dwTotalPageFile = total*1024;
	    if (sscanf(buffer, "SwapFree: %d", &free))
	        lpmem->dwAvailPageFile = free*1024;
        }
        fclose( f );

        if (lpmem->dwTotalPhys)
        {
            lpmem->dwTotalVirtual = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
            lpmem->dwAvailVirtual = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
            lpmem->dwMemoryLoad = (lpmem->dwTotalVirtual-lpmem->dwAvailVirtual)
                                      / (lpmem->dwTotalVirtual / 100);
            return;
        }
    }
#endif
    /* FIXME: should do something for other systems */
    lpmem->dwMemoryLoad    = 0;
    lpmem->dwTotalPhys     = 16*1024*1024;
    lpmem->dwAvailPhys     = 16*1024*1024;
    lpmem->dwTotalPageFile = 16*1024*1024;
    lpmem->dwAvailPageFile = 16*1024*1024;
    lpmem->dwTotalVirtual  = 32*1024*1024;
    lpmem->dwAvailVirtual  = 32*1024*1024;
}


/**********************************************************************
 *           WOWGlobalAllocLock (KERNEL32.62)
 *
 * Combined GlobalAlloc and GlobalLock.
 */
SEGPTR WINAPI WOWGlobalAllocLock16(DWORD flags,DWORD cb,HGLOBAL16 *hmem)
{
    HGLOBAL16 xhmem;
    xhmem = GlobalAlloc16(flags,cb);
    if (hmem) *hmem = xhmem;
    return WIN16_GlobalLock16(xhmem);
}


/**********************************************************************
 *           WOWGlobalUnlockFree (KERNEL32.64)
 *
 * Combined GlobalUnlock and GlobalFree.
 */
WORD WOWGlobalUnlockFree16(DWORD vpmem) {
    if (!GlobalUnlock16(HIWORD(vpmem)))
    	return 0;
    return GlobalFree16(HIWORD(vpmem));
}
