Ignore:
Timestamp:
Jul 5, 2001, 8:10:08 PM (24 years ago)
Author:
sandervl
Message:

Global memory functions ported from Wine; Local memory functions now use Global*

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/heap.cpp

    r6092 r6176  
    1 /* $Id: heap.cpp,v 1.27 2001-06-24 15:45:36 sandervl Exp $ */
     1/* $Id: heap.cpp,v 1.28 2001-07-05 18:10:08 sandervl Exp $ */
    22
    33/*
    44 * Win32 heap API functions for OS/2
    55 *
    6  * Copyright 1999 Sander van Leeuwen
     6 * Copyright 1999-2001 Sander van Leeuwen
     7 *
     8 * Global memory functions ported from Wine
     9 * Copyright 1995 Alexandre Julliard
    710 *
    811 * Project Odin Software License can be found in LICENSE.TXT
     
    114117//******************************************************************************
    115118//******************************************************************************
    116 ODINFUNCTIONNODBG3(DWORD, HeapSize, HANDLE, hHeap, DWORD, arg2, PVOID, arg3)
     119ODINFUNCTIONNODBG3(DWORD, HeapSize, HANDLE, hHeap, DWORD, arg2, PVOID, lpMem)
    117120{
    118121 OS2Heap *curheap = OS2Heap::find(hHeap);
    119122
    120   dprintf2(("HeapSize %X %x", hHeap, arg2));
     123  dprintf2(("HeapSize %X %x %x", hHeap, arg2, lpMem));
    121124  if(curheap == NULL)
    122125        return(0);
    123   return curheap->Size(arg2, arg3);
     126  return curheap->Size(arg2, lpMem);
    124127}
    125128//******************************************************************************
     
    182185    return(processheap);
    183186}
    184 //******************************************************************************
    185 //******************************************************************************
    186 HLOCAL WIN32API LocalAlloc(UINT fuFlags, DWORD cbBytes)
    187 {
    188  HLOCAL lmem;
    189  DWORD  dwFlags = 0;
    190 
    191   if(processheap == NULL) {
    192       if(GetProcessHeap() == NULL)
    193          return(NULL);
    194   }
    195   if(fuFlags & LMEM_ZEROINIT)
    196     dwFlags = HEAP_ZERO_MEMORY;
    197 
    198   lmem = (HLOCAL)OS2ProcessHeap->Alloc(dwFlags, cbBytes, fuFlags);
    199 
    200   dprintf(("KERNEL32:  LocalAlloc flags %X, size %d returned %X\n", dwFlags, cbBytes, lmem));
    201 
    202   return(lmem);
    203 }
    204 //******************************************************************************
    205 //******************************************************************************
    206 HLOCAL WIN32API LocalDiscard(HLOCAL hMem)
    207 {
    208     dprintf(("KERNEL32:  LocalDiscard NOT IMPLEMENTED\n"));
    209 
    210 //    return O32_LocalDiscard(arg1);
    211     return(hMem);   //TODO: Possible memory leak
    212 }
    213 //******************************************************************************
    214 //******************************************************************************
    215 UINT WIN32API LocalFlags(HLOCAL hMem)
    216 {
    217     dprintf(("KERNEL32: LocalFlags %X\n", hMem));
    218 
    219     return OS2ProcessHeap->GetFlags((LPVOID)hMem);
    220 }
    221 //******************************************************************************
    222 //******************************************************************************
    223 HLOCAL WIN32API LocalFree(HLOCAL hMem)
    224 {
    225   dprintf(("KERNEL32: LocalFree %X\n", hMem));
    226 
    227   if(OS2ProcessHeap->GetLockCnt((LPVOID)hMem) != 0) {
    228         dprintf(("LocalFree, lock count != 0\n"));
    229         return(hMem);   //TODO: SetLastError
    230   }
    231   if(OS2ProcessHeap->Free(0, (LPVOID)hMem) == FALSE) {
    232         return(hMem);   //TODO: SetLastError
    233   }
    234   return NULL; //success
    235 }
    236 //******************************************************************************
    237 //******************************************************************************
    238 HLOCAL WIN32API LocalHandle(PCVOID lpMem)
    239 {
    240     dprintf(("KERNEL32:  LocalHandle\n"));
    241 
    242     return (HLOCAL)lpMem;
    243 }
    244 //******************************************************************************
    245 //******************************************************************************
    246 BOOL WIN32API LocalUnlock(HLOCAL hMem)
    247 {
    248     dprintf(("KERNEL32: LocalUnlock %X\n", hMem));
    249 
    250     return OS2ProcessHeap->Unlock((LPVOID)hMem);
    251 }
    252 //******************************************************************************
    253 //TODO: cbBytes==0 && fuFlags & LMEM_MOVEABLE not handled!!
    254 //******************************************************************************
    255 HLOCAL WIN32API LocalReAlloc(HLOCAL hMem, DWORD cbBytes, UINT fuFlags)
    256 {
    257   HLOCAL hLocalNew;
    258   LPVOID lpMem;
    259 
    260   dprintf(("KERNEL32: LocalReAlloc %X %d %X\n", hMem, cbBytes, fuFlags));
    261 
    262   //SvL: 8-8-'98: Notepad bugfix (assumes address is identical when new size < old size)
    263   if(OS2ProcessHeap->Size(0, (LPVOID)hMem) > cbBytes)
    264     return hMem;
    265 
    266   hLocalNew = LocalAlloc(fuFlags, cbBytes);
    267   if (hLocalNew != 0)
    268   {
    269     lpMem = LocalLock(hLocalNew);
    270 
    271     if (lpMem != NULL) /* copy memory if successful */
    272       memcpy(lpMem,
    273              (LPVOID)hMem,
    274              min(cbBytes, OS2ProcessHeap->Size(0, (LPVOID)hMem))
    275             );
    276 
    277     LocalUnlock(hLocalNew);
    278     OS2ProcessHeap->Free(0, (LPVOID)hMem);
    279   }
    280   return(hLocalNew);
    281 }
    282 //******************************************************************************
    283 //******************************************************************************
    284 UINT WIN32API LocalSize(HLOCAL hMem)
    285 {
    286     dprintf(("KERNEL32: LocalSize %X\n", hMem));
    287 
    288     return OS2ProcessHeap->Size(0, (PVOID)hMem);
    289 }
    290 //******************************************************************************
    291 //******************************************************************************
    292 PVOID WIN32API LocalLock(HLOCAL hMem)
    293 {
    294     dprintf(("KERNEL32:  LocalLock %X\n", hMem));
    295 
    296     if(OS2ProcessHeap->Lock((LPVOID)hMem) == FALSE) {
    297         return NULL;
     187#if 1
     188/*
     189 * Win32 Global heap functions (GlobalXXX).
     190 * These functions included in Win32 for compatibility with 16 bit Windows
     191 * Especially the moveable blocks and handles are oldish.
     192 * But the ability to directly allocate memory with GPTR and LPTR is widely
     193 * used.
     194 *
     195 * The handle stuff looks horrible, but it's implemented almost like Win95
     196 * does it.
     197 *
     198 */
     199
     200#define MAGIC_GLOBAL_USED 0x5342
     201#define GLOBAL_LOCK_MAX   0xFF
     202#define HANDLE_TO_INTERN(h)  ((PGLOBAL32_INTERN)(((char *)(h))-2))
     203#define INTERN_TO_HANDLE(i)  ((HGLOBAL) &((i)->Pointer))
     204#define POINTER_TO_HANDLE(p) (*(((HGLOBAL *)(p))-1))
     205#define ISHANDLE(h)          (((DWORD)(h)&2)!=0)
     206#define ISPOINTER(h)         (((DWORD)(h)&2)==0)
     207
     208#pragma pack(1)
     209
     210typedef struct __GLOBAL32_INTERN
     211{
     212   WORD         Magic;
     213   LPVOID       Pointer;
     214   BYTE         Flags;
     215   BYTE         LockCount;
     216} GLOBAL32_INTERN, *PGLOBAL32_INTERN;
     217
     218#pragma pack()
     219
     220/***********************************************************************
     221 *           GlobalAlloc   (KERNEL32.@)
     222 * RETURNS
     223 *      Handle: Success
     224 *      NULL: Failure
     225 */
     226HGLOBAL WINAPI GlobalAlloc(
     227                 UINT flags, /* [in] Object allocation attributes */
     228                 DWORD size    /* [in] Number of bytes to allocate */
     229) {
     230   PGLOBAL32_INTERN     pintern;
     231   DWORD                hpflags;
     232   LPVOID               palloc;
     233
     234   if(flags&GMEM_ZEROINIT)
     235      hpflags=HEAP_ZERO_MEMORY;
     236   else
     237      hpflags=0;
     238   
     239   if((flags & GMEM_MOVEABLE)==0) /* POINTER */
     240   {
     241      palloc=HeapAlloc(GetProcessHeap(), hpflags, size);
     242      dprintf(("KERNEL32: GlobalAlloc %x %d returned %x", flags, size, palloc));
     243      return (HGLOBAL) palloc;
     244   }
     245   else  /* HANDLE */
     246   {
     247      /* HeapLock(heap); */
     248
     249      pintern=(PGLOBAL32_INTERN)HeapAlloc(GetProcessHeap(), 0,  sizeof(GLOBAL32_INTERN));
     250      if (!pintern) return 0;
     251      if(size)
     252      {
     253         if (!(palloc=HeapAlloc(GetProcessHeap(), hpflags, size+sizeof(HGLOBAL)))) {
     254            HeapFree(GetProcessHeap(), 0, pintern);
     255            return 0;
     256         }
     257         *(HGLOBAL *)palloc=INTERN_TO_HANDLE(pintern);
     258         pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
     259      }
     260      else
     261         pintern->Pointer=NULL;
     262      pintern->Magic=MAGIC_GLOBAL_USED;
     263      pintern->Flags=flags>>8;
     264      pintern->LockCount=0;
     265     
     266      /* HeapUnlock(heap); */
     267       
     268      dprintf(("KERNEL32: GlobalAlloc %x %d returned %x", flags, size, INTERN_TO_HANDLE(pintern)));
     269      return INTERN_TO_HANDLE(pintern);
     270   }
     271}
     272/***********************************************************************
     273 *           GlobalLock   (KERNEL32.@)
     274 * RETURNS
     275 *      Pointer to first byte of block
     276 *      NULL: Failure
     277 */
     278LPVOID WINAPI GlobalLock(
     279              HGLOBAL hmem /* [in] Handle of global memory object */
     280) {
     281   PGLOBAL32_INTERN pintern;
     282   LPVOID           palloc;
     283
     284
     285   if(ISPOINTER(hmem)) {
     286      dprintf(("KERNEL32: GlobalLock %x returned %x", hmem, hmem));
     287      return (LPVOID) hmem;
     288   }
     289
     290   /* HeapLock(GetProcessHeap()); */
     291   
     292   pintern=HANDLE_TO_INTERN(hmem);
     293   if(pintern->Magic==MAGIC_GLOBAL_USED)
     294   {
     295      if(pintern->LockCount<GLOBAL_LOCK_MAX)
     296         pintern->LockCount++;
     297      palloc=pintern->Pointer;
     298   }
     299   else
     300   {
     301      dprintf(("ERROR: GlobalLock invalid handle %x", hmem));
     302      palloc=(LPVOID) NULL;
     303      SetLastError(ERROR_INVALID_HANDLE);
     304   }
     305   /* HeapUnlock(GetProcessHeap()); */;
     306
     307   dprintf(("KERNEL32: GlobalLock %x returned %x", hmem, palloc));
     308   return palloc;
     309}
     310
     311
     312/***********************************************************************
     313 *           GlobalUnlock   (KERNEL32.@)
     314 * RETURNS
     315 *      TRUE: Object is still locked
     316 *      FALSE: Object is unlocked
     317 */
     318BOOL WINAPI GlobalUnlock(
     319              HGLOBAL hmem /* [in] Handle of global memory object */
     320) {
     321   PGLOBAL32_INTERN       pintern;
     322   BOOL                 locked;
     323
     324   dprintf(("KERNEL32: GlobalUnlock %x", hmem));
     325
     326   if(ISPOINTER(hmem))
     327      return FALSE;
     328
     329   /* HeapLock(GetProcessHeap()); */
     330   pintern=HANDLE_TO_INTERN(hmem);
     331   
     332   if(pintern->Magic==MAGIC_GLOBAL_USED)
     333   {
     334      if((pintern->LockCount<GLOBAL_LOCK_MAX)&&(pintern->LockCount>0))
     335         pintern->LockCount--;
     336
     337      locked = (pintern->LockCount != 0);
     338      if (!locked) SetLastError(NO_ERROR);
     339   }
     340   else
     341   {
     342      dprintf(("ERROR: GlobalUnlock invalid handle %x", hmem));
     343      SetLastError(ERROR_INVALID_HANDLE);
     344      locked=FALSE;
     345   }
     346   /* HeapUnlock(GetProcessHeap()); */
     347   return locked;
     348}
     349
     350
     351/***********************************************************************
     352 *           GlobalHandle   (KERNEL32.@)
     353 * Returns the handle associated with the specified pointer.
     354 *
     355 * RETURNS
     356 *      Handle: Success
     357 *      NULL: Failure
     358 */
     359HGLOBAL WINAPI GlobalHandle(
     360                 LPCVOID pmem /* [in] Pointer to global memory block */
     361) {
     362    HGLOBAL handle;
     363    PGLOBAL32_INTERN  maybe_intern;
     364    LPCVOID test;
     365
     366    dprintf(("KERNEL32: GlobalHandle %x", pmem));
     367
     368    if (!pmem)
     369    {
     370        SetLastError( ERROR_INVALID_PARAMETER );
     371        return 0;
    298372    }
    299     return (PVOID)hMem;
    300 }
    301 //******************************************************************************
    302 
    303 //******************************************************************************
    304 //* this function is here for completeness, some stupid software requires it.
    305 UINT WIN32API LocalShrink(HLOCAL hMem,
    306                              UINT   cbNewSize)
    307 {
    308     dprintf(("KERNEL32:  LocalShrink %X, %08xh - stub (cbNewSize)\n",
    309              hMem,
    310              cbNewSize));
    311 
    312     return cbNewSize;
    313 }
    314 //******************************************************************************
    315 
    316 //******************************************************************************
    317 //* this function is here for completeness, mIRC/32 requires it.
    318 UINT WIN32API LocalCompact(UINT cbNewSize)
    319 {
    320     dprintf(("KERNEL32:  LocalCompact %08xh - stub (cbNewSize)\n",
    321              cbNewSize));
    322 
    323     return cbNewSize;
    324 }
     373
     374#ifdef __WIN32OS2__
     375        handle = 0;
     376
     377        /* note that if pmem is a pointer to a a block allocated by        */
     378        /* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate  */
     379        /* will fail.                                                      */
     380        if (ISPOINTER(pmem)) {
     381            if (HeapValidate( GetProcessHeap(), 0, pmem )) {
     382                handle = (HGLOBAL)pmem;  /* valid fixed block */
     383                return handle;
     384            }
     385            handle = POINTER_TO_HANDLE(pmem);
     386        } else
     387            handle = (HGLOBAL)pmem;
     388
     389        /* Now test handle either passed in or retrieved from pointer */
     390        maybe_intern = HANDLE_TO_INTERN( handle );
     391        if(IsBadReadPtr(maybe_intern, sizeof(GLOBAL32_INTERN))) {
     392            SetLastError( ERROR_INVALID_HANDLE );
     393            return 0;
     394        }
     395
     396        if (maybe_intern->Magic == MAGIC_GLOBAL_USED) {
     397            test = maybe_intern->Pointer;
     398            if (HeapValidate( GetProcessHeap(), 0, ((HGLOBAL *)test)-1 ) && /* obj(-handle) valid arena? */
     399                HeapValidate( GetProcessHeap(), 0, maybe_intern ))  /* intern valid arena? */
     400            {
     401                return handle;
     402            }
     403        }
     404        handle = 0;
     405        SetLastError( ERROR_INVALID_HANDLE );
     406#else
     407    __TRY
     408    {
     409        handle = 0;
     410
     411        /* note that if pmem is a pointer to a a block allocated by        */
     412        /* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate  */
     413        /* will fail.                                                      */
     414        if (ISPOINTER(pmem)) {
     415            if (HeapValidate( GetProcessHeap(), 0, pmem )) {
     416                handle = (HGLOBAL)pmem;  /* valid fixed block */
     417                break;
     418            }
     419            handle = POINTER_TO_HANDLE(pmem);
     420        } else
     421            handle = (HGLOBAL)pmem;
     422
     423        /* Now test handle either passed in or retrieved from pointer */
     424        maybe_intern = HANDLE_TO_INTERN( handle );
     425        if (maybe_intern->Magic == MAGIC_GLOBAL_USED) {
     426            test = maybe_intern->Pointer;
     427            if (HeapValidate( GetProcessHeap(), 0, ((HGLOBAL *)test)-1 ) && /* obj(-handle) valid arena? */
     428                HeapValidate( GetProcessHeap(), 0, maybe_intern ))  /* intern valid arena? */
     429                break;  /* valid moveable block */
     430        }
     431        handle = 0;
     432        SetLastError( ERROR_INVALID_HANDLE );
     433    }
     434    __EXCEPT(page_fault)
     435    {
     436        SetLastError( ERROR_INVALID_HANDLE );
     437        return 0;
     438    }
     439    __ENDTRY
     440#endif
     441    return handle;
     442}
     443
     444
     445/***********************************************************************
     446 *           GlobalReAlloc   (KERNEL32.@)
     447 * RETURNS
     448 *      Handle: Success
     449 *      NULL: Failure
     450 */
     451HGLOBAL WINAPI GlobalReAlloc(
     452                 HGLOBAL hmem, /* [in] Handle of global memory object */
     453                 DWORD size,     /* [in] New size of block */
     454                 UINT flags    /* [in] How to reallocate object */
     455) {
     456   LPVOID               palloc;
     457   HGLOBAL            hnew;
     458   PGLOBAL32_INTERN     pintern;
     459   DWORD heap_flags = (flags & GMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0;
     460
     461   hnew = 0;
     462   /* HeapLock(heap); */
     463   if(flags & GMEM_MODIFY) /* modify flags */
     464   {
     465      if( ISPOINTER(hmem) && (flags & GMEM_MOVEABLE))
     466      {
     467         /* make a fixed block moveable
     468          * actually only NT is able to do this. But it's soo simple
     469          */
     470         if (hmem == 0)
     471         {
     472             dprintf(("ERROR: GlobalReAlloc32 with null handle!\n"));
     473             SetLastError( ERROR_NOACCESS );
     474             return 0;
     475         }
     476         size=HeapSize(GetProcessHeap(), 0, (LPVOID) hmem);
     477         hnew=GlobalAlloc( flags, size);
     478         palloc=GlobalLock(hnew);
     479         memcpy(palloc, (LPVOID) hmem, size);
     480         GlobalUnlock(hnew);
     481         GlobalFree(hmem);
     482      }
     483      else if( ISPOINTER(hmem) &&(flags & GMEM_DISCARDABLE))
     484      {
     485         /* change the flags to make our block "discardable" */
     486         pintern=HANDLE_TO_INTERN(hmem);
     487         pintern->Flags = pintern->Flags | (GMEM_DISCARDABLE >> 8);
     488         hnew=hmem;
     489      }
     490      else
     491      {
     492         SetLastError(ERROR_INVALID_PARAMETER);
     493         hnew = 0;
     494      }
     495   }
     496   else
     497   {
     498      if(ISPOINTER(hmem))
     499      {
     500         /* reallocate fixed memory */
     501         hnew=(HGLOBAL)HeapReAlloc(GetProcessHeap(), heap_flags, (LPVOID) hmem, size);
     502      }
     503      else
     504      {
     505         /* reallocate a moveable block */
     506         pintern=HANDLE_TO_INTERN(hmem);
     507
     508#if 0
     509/* Apparently Windows doesn't care whether the handle is locked at this point */
     510/* See also the same comment in GlobalFree() */
     511         if(pintern->LockCount>1) {
     512            ERR("handle 0x%08lx is still locked, cannot realloc!\n",(DWORD)hmem);
     513            SetLastError(ERROR_INVALID_HANDLE);
     514         } else
     515#endif
     516         if(size!=0)
     517         {
     518            hnew=hmem;
     519            if(pintern->Pointer)
     520            {
     521               if((palloc = HeapReAlloc(GetProcessHeap(), heap_flags,
     522                                   (char *) pintern->Pointer-sizeof(HGLOBAL),
     523                                   size+sizeof(HGLOBAL))) == NULL)
     524                   return 0; /* Block still valid */
     525               pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
     526            }
     527            else
     528            {
     529                if((palloc=HeapAlloc(GetProcessHeap(), heap_flags, size+sizeof(HGLOBAL)))
     530                   == NULL)
     531                    return 0;
     532               *(HGLOBAL *)palloc=hmem;
     533               pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
     534            }
     535         }
     536         else
     537         {
     538            if(pintern->Pointer)
     539            {
     540               HeapFree(GetProcessHeap(), 0, (char *) pintern->Pointer-sizeof(HGLOBAL));
     541               pintern->Pointer=NULL;
     542            }
     543         }
     544      }
     545   }
     546   /* HeapUnlock(heap); */
     547   return hnew;
     548}
     549
     550
     551/***********************************************************************
     552 *           GlobalFree   (KERNEL32.@)
     553 * RETURNS
     554 *      NULL: Success
     555 *      Handle: Failure
     556 */
     557HGLOBAL WINAPI GlobalFree(
     558                 HGLOBAL hmem /* [in] Handle of global memory object */
     559) {
     560   PGLOBAL32_INTERN pintern;
     561   HGLOBAL        hreturned = 0;
     562
     563   dprintf(("KERNEL32: GlobalFree %x", hmem));
     564
     565   if(ISPOINTER(hmem)) /* POINTER */
     566   {
     567      if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) hmem = 0;
     568   }
     569   else  /* HANDLE */
     570   {
     571      /* HeapLock(heap); */
     572      pintern=HANDLE_TO_INTERN(hmem);
     573     
     574      if(pintern->Magic==MAGIC_GLOBAL_USED)
     575      { 
     576
     577/* WIN98 does not make this test. That is you can free a */
     578/* block you have not unlocked. Go figure!!              */
     579      /* if(pintern->LockCount!=0)  */
     580      /*    SetLastError(ERROR_INVALID_HANDLE);  */
     581
     582         if(pintern->Pointer)
     583            if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-sizeof(HGLOBAL)))
     584               hreturned=hmem;
     585         if(!HeapFree(GetProcessHeap(), 0, pintern))
     586            hreturned=hmem;
     587      }     
     588      /* HeapUnlock(heap); */
     589   }
     590   return hreturned;
     591}
     592
     593
     594/***********************************************************************
     595 *           GlobalSize   (KERNEL32.@)
     596 * RETURNS
     597 *      Size in bytes of the global memory object
     598 *      0: Failure
     599 */
     600DWORD WINAPI GlobalSize(
     601             HGLOBAL hmem /* [in] Handle of global memory object */
     602) {
     603   DWORD                retval;
     604   PGLOBAL32_INTERN     pintern;
     605
     606   dprintf(("KERNEL32: GlobalSize %x", hmem));
     607
     608   if(ISPOINTER(hmem))
     609   {
     610      retval=HeapSize(GetProcessHeap(), 0,  (LPVOID) hmem);
     611   }
     612   else
     613   {
     614      /* HeapLock(heap); */
     615      pintern=HANDLE_TO_INTERN(hmem);
     616     
     617      if(pintern->Magic==MAGIC_GLOBAL_USED)
     618      {
     619        if (!pintern->Pointer) /* handle case of GlobalAlloc( ??,0) */
     620            return 0;
     621         retval=HeapSize(GetProcessHeap(), 0,
     622                         (char *)(pintern->Pointer)-sizeof(HGLOBAL))-4;
     623         if (retval == 0xffffffff-4) retval = 0;
     624      }
     625      else
     626      {
     627         dprintf(("ERROR: GlobalSize invalid handle %x", hmem));
     628         retval=0;
     629      }
     630      /* HeapUnlock(heap); */
     631   }
     632   /* HeapSize returns 0xffffffff on failure */
     633   if (retval == 0xffffffff) retval = 0;
     634   return retval;
     635}
     636
     637
     638/***********************************************************************
     639 *           GlobalWire   (KERNEL32.@)
     640 */
     641LPVOID WINAPI GlobalWire(HGLOBAL hmem)
     642{
     643   return GlobalLock( hmem );
     644}
     645
     646
     647/***********************************************************************
     648 *           GlobalUnWire   (KERNEL32.@)
     649 */
     650BOOL WINAPI GlobalUnWire(HGLOBAL hmem)
     651{
     652   return GlobalUnlock( hmem);
     653}
     654
     655
     656/***********************************************************************
     657 *           GlobalFix   (KERNEL32.@)
     658 */
     659VOID WINAPI GlobalFix(HGLOBAL hmem)
     660{
     661    GlobalLock( hmem );
     662}
     663
     664
     665/***********************************************************************
     666 *           GlobalUnfix   (KERNEL32.@)
     667 */
     668VOID WINAPI GlobalUnfix(HGLOBAL hmem)
     669{
     670   GlobalUnlock( hmem);
     671}
     672
     673
     674/***********************************************************************
     675 *           GlobalFlags   (KERNEL32.@)
     676 * Returns information about the specified global memory object
     677 *
     678 * NOTES
     679 *      Should this return GMEM_INVALID_HANDLE on invalid handle?
     680 *
     681 * RETURNS
     682 *      Value specifying allocation flags and lock count
     683 *      GMEM_INVALID_HANDLE: Failure
     684 */
     685UINT WINAPI GlobalFlags(
     686              HGLOBAL hmem /* [in] Handle to global memory object */
     687) {
     688   DWORD                retval;
     689   PGLOBAL32_INTERN     pintern;
     690
     691   dprintf(("KERNEL32: GlobalFlags %x", hmem));
     692   
     693   if(ISPOINTER(hmem))
     694   {
     695      retval=0;
     696   }
     697   else
     698   {
     699      /* HeapLock(GetProcessHeap()); */
     700      pintern=HANDLE_TO_INTERN(hmem);
     701      if(pintern->Magic==MAGIC_GLOBAL_USED)
     702      {               
     703         retval=pintern->LockCount + (pintern->Flags<<8);
     704         if(pintern->Pointer==0)
     705            retval|= GMEM_DISCARDED;
     706      }
     707      else
     708      {
     709         dprintf(("ERROR: GlobalFlags invalid handle %x", hmem));
     710         retval=0;
     711      }
     712      /* HeapUnlock(GetProcessHeap()); */
     713   }
     714   return retval;
     715}
     716
     717
     718/***********************************************************************
     719 *           GlobalCompact   (KERNEL32.@)
     720 */
     721DWORD WINAPI GlobalCompact( DWORD minfree )
     722{
     723    dprintf(("KERNEL32:  GlobalCompact %d OBSOLETE", minfree));
     724
     725    return 0;  /* GlobalCompact does nothing in Win32 */
     726}
     727#else
    325728//******************************************************************************
    326729#ifdef DEBUG
     
    354757//******************************************************************************
    355758//******************************************************************************
    356 HGLOBAL WIN32API GlobalHandle( LPCVOID arg1)
    357 {
    358     dprintf(("KERNEL32:  OS2GlobalHandle\n"));
    359 
    360     return O32_GlobalHandle((LPVOID)arg1);
    361 }
    362 //******************************************************************************
    363 //******************************************************************************
    364 UINT WIN32API GlobalFlags(HGLOBAL arg1)
    365 {
    366     dprintf(("KERNEL32:  OS2GlobalFlags\n"));
    367 
    368     return O32_GlobalFlags(arg1);
     759HGLOBAL WIN32API GlobalHandle( LPCVOID lpMem)
     760{
     761    dprintf(("KERNEL32: GlobalHandle %x", lpMem));
     762
     763    return O32_GlobalHandle((LPVOID)lpMem);
     764}
     765//******************************************************************************
     766//******************************************************************************
     767UINT WIN32API GlobalFlags(HGLOBAL hMem)
     768{
     769    dprintf(("KERNEL32: GlobalFlags %x", hMem));
     770
     771    return O32_GlobalFlags(hMem);
    369772}
    370773//******************************************************************************
     
    378781//******************************************************************************
    379782//******************************************************************************
    380 PVOID WIN32API GlobalLock(HGLOBAL arg1)
     783PVOID WIN32API GlobalLock(HGLOBAL hMem)
    381784{
    382785 PVOID ret;
    383786
    384     ret = O32_GlobalLock(arg1);
    385     dprintf(("KERNEL32: GlobalLock %x returned %x", arg1, ret));
     787    ret = O32_GlobalLock(hMem);
     788    dprintf(("KERNEL32: GlobalLock %x returned %x", hMem, ret));
    386789    return ret;
    387790}
     
    422825   return GlobalLock( hmem );
    423826}
    424 
    425 
    426827/***********************************************************************
    427828 *           GlobalUnWire
     
    438839//******************************************************************************
    439840//******************************************************************************
     841HGLOBAL WIN32API GlobalDiscard(HGLOBAL hGlobal)
     842{
     843    dprintf(("KERNEL32: GlobalDiscard %x", hGlobal));
     844
     845    return O32_GlobalDiscard(hGlobal);
     846}
     847/***********************************************************************
     848 *           GlobalFix   (KERNEL32.@)
     849 */
     850VOID WINAPI GlobalFix(HGLOBAL hmem)
     851{
     852    GlobalLock( hmem );
     853}
     854/***********************************************************************
     855 *           GlobalUnfix   (KERNEL32.@)
     856 */
     857VOID WINAPI GlobalUnfix(HGLOBAL hmem)
     858{
     859   GlobalUnlock( hmem);
     860}
     861#endif
     862//******************************************************************************
     863//******************************************************************************
     864HLOCAL WIN32API LocalAlloc(UINT fuFlags, DWORD cbBytes)
     865{
     866    HLOCAL hLocal;
     867
     868    // Check flags
     869    if(fuFlags & (~(LMEM_MOVEABLE | LMEM_DISCARDABLE | LMEM_NOCOMPACT |
     870                    LMEM_NODISCARD | LMEM_ZEROINIT)))
     871    {
     872       dprintf(("LocalAlloc %x %x: INVALID flags!", fuFlags, cbBytes));
     873       SetLastError(ERROR_INVALID_PARAMETER);
     874       return 0;
     875    }
     876    // Note: local & global flags are the same (the ones used here), so no need for conversion
     877    hLocal = GlobalAlloc(fuFlags, cbBytes);
     878    dprintf(("KERNEL32: LocalAlloc flags %X, size %d returned %X", fuFlags, cbBytes, hLocal));
     879    return hLocal;
     880}
     881//******************************************************************************
     882//******************************************************************************
     883UINT WIN32API LocalFlags(HLOCAL hMem)
     884{
     885    UINT ret, retG;
     886    dprintf(("KERNEL32: LocalFlags %X\n", hMem));
     887
     888    retG = GlobalFlags(hMem);
     889
     890    if(retG == GMEM_INVALID_HANDLE)
     891    {
     892       return LMEM_INVALID_HANDLE;
     893    }
     894    // Low byte holds lock count.
     895    // Hi byte of low word contains some flags.
     896    ret = retG & 0xff; // Keep lock count.
     897    if (retG & GMEM_DISCARDABLE)  ret |= LMEM_DISCARDABLE;
     898    if (retG & GMEM_DISCARDED)    ret |= LMEM_DISCARDED;
     899
     900    return ret;
     901}
     902//******************************************************************************
     903//******************************************************************************
     904HLOCAL WIN32API LocalFree(HLOCAL hMem)
     905{
     906  dprintf(("KERNEL32: LocalFree %X", hMem));
     907
     908  return GlobalFree(hMem);
     909}
     910//******************************************************************************
     911//******************************************************************************
     912HLOCAL WIN32API LocalHandle(PCVOID lpMem)
     913{
     914    dprintf(("KERNEL32: LocalHandle %x", lpMem));
     915
     916    return GlobalHandle(lpMem);
     917}
     918//******************************************************************************
     919//******************************************************************************
     920BOOL WIN32API LocalUnlock(HLOCAL hMem)
     921{
     922    dprintf(("KERNEL32: LocalUnlock %X", hMem));
     923
     924    return GlobalUnlock(hMem);
     925}
     926//******************************************************************************
     927//TODO: cbBytes==0 && fuFlags & LMEM_MOVEABLE not handled!!
     928//******************************************************************************
     929HLOCAL WIN32API LocalReAlloc(HLOCAL hMem, DWORD cbBytes, UINT fuFlags)
     930{
     931  HLOCAL hLocalNew;
     932  LPVOID lpMem;
     933  DWORD  cbOldSize;
     934
     935  dprintf(("KERNEL32: LocalReAlloc %X %d %X\n", hMem, cbBytes, fuFlags));
     936
     937    // Check flags
     938    if(fuFlags & (~(LMEM_MOVEABLE | LMEM_DISCARDABLE | LMEM_NOCOMPACT |
     939                    LMEM_MODIFY | LMEM_ZEROINIT)))
     940    {
     941       dprintf(("LocalAlloc %x %x: INVALID flags!", fuFlags, cbBytes));
     942       SetLastError(ERROR_INVALID_PARAMETER);
     943       return 0;
     944    }
     945
     946    //SvL: 8-8-'98: Notepad bugfix (assumes address is identical when new size < old size)
     947    cbOldSize = LocalSize(hMem);
     948    if(cbOldSize > cbBytes)
     949        return hMem;
     950
     951    hLocalNew = LocalAlloc(fuFlags, cbBytes);
     952    if(hLocalNew != 0)
     953    {
     954        lpMem = LocalLock(hLocalNew);
     955
     956        if (lpMem != NULL) /* copy memory if successful */
     957            memcpy(lpMem, (LPVOID)hMem, min(cbBytes, cbOldSize));
     958
     959        LocalUnlock(hLocalNew);
     960        LocalFree(hMem);
     961    }
     962    return(hLocalNew);
     963}
     964//******************************************************************************
     965//******************************************************************************
     966UINT WIN32API LocalSize(HLOCAL hMem)
     967{
     968    dprintf(("KERNEL32: LocalSize %X", hMem));
     969
     970    return GlobalSize(hMem);
     971}
     972//******************************************************************************
     973//******************************************************************************
     974PVOID WIN32API LocalLock(HLOCAL hMem)
     975{
     976    dprintf(("KERNEL32:  LocalLock %X\n", hMem));
     977
     978    return GlobalLock(hMem);
     979}
     980//******************************************************************************
     981//* this function is here for completeness, some stupid software requires it.
     982//******************************************************************************
     983UINT WIN32API LocalShrink(HLOCAL hMem, UINT cbNewSize)
     984{
     985    dprintf(("KERNEL32:  LocalShrink %X, %08xh - OBSOLETE", hMem, cbNewSize));
     986
     987    return cbNewSize;
     988}
     989//******************************************************************************
     990//* this function is here for completeness, mIRC/32 requires it.
     991//******************************************************************************
     992UINT WIN32API LocalCompact(UINT cbNewSize)
     993{
     994    dprintf(("KERNEL32:  LocalCompact %08xh - OBSOLETE", cbNewSize));
     995
     996    return cbNewSize;
     997}
     998//******************************************************************************
     999//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.