2 * Global heap functions
4 * Copyright 1995 Alexandre Julliard
16 #include "selectors.h"
18 #include "stackframe.h"
23 /* Global arena block */
26 DWORD base
; /* Base address (0 if discarded) */
27 DWORD size
; /* Size in bytes (0 indicates a free block) */
28 HGLOBAL16 handle
; /* Handle for this block */
29 HGLOBAL16 hOwner
; /* Owner of this block */
30 BYTE lockCount
; /* Count of GlobalFix() calls */
31 BYTE pageLockCount
; /* Count of GlobalPageLock() calls */
32 BYTE flags
; /* Allocation flags */
33 BYTE selCount
; /* Number of selectors allocated for this block */
39 /* Flags definitions */
40 #define GA_MOVEABLE 0x02 /* same as GMEM_MOVEABLE */
41 #define GA_DGROUP 0x04
42 #define GA_DISCARDABLE 0x08
43 #define GA_IPCSHARE 0x10 /* same as GMEM_DDESHARE */
46 static GLOBALARENA
*pGlobalArena
= NULL
;
47 static int globalArenaSize
= 0;
49 #define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000 /* Largest allocation is 16M - 64K */
51 #define GET_ARENA_PTR(handle) (pGlobalArena + ((handle) >> __AHSHIFT))
53 /***********************************************************************
56 * Return the arena for a given selector, growing the arena array if needed.
58 static GLOBALARENA
*GLOBAL_GetArena( WORD sel
, WORD selcount
)
60 if (((sel
>> __AHSHIFT
) + selcount
) > globalArenaSize
)
62 int newsize
= ((sel
>> __AHSHIFT
) + selcount
+ 0xff) & ~0xff;
63 GLOBALARENA
*pNewArena
= realloc( pGlobalArena
,
64 newsize
* sizeof(GLOBALARENA
) );
65 if (!pNewArena
) return 0;
66 pGlobalArena
= pNewArena
;
67 memset( pGlobalArena
+ globalArenaSize
, 0,
68 (newsize
- globalArenaSize
) * sizeof(GLOBALARENA
) );
69 globalArenaSize
= newsize
;
71 return pGlobalArena
+ (sel
>> __AHSHIFT
);
79 for (i
= globalArenaSize
-1 ; i
>=0 ; i
--) {
80 if (pGlobalArena
[i
].size
!=0 && (pGlobalArena
[i
].handle
& 0x8000)){
82 printf("0x%08x, ",pGlobalArena
[i
].handle
);
90 /***********************************************************************
93 * Create a global heap block for a fixed range of linear memory.
95 HGLOBAL16
GLOBAL_CreateBlock( WORD flags
, const void *ptr
, DWORD size
,
96 HGLOBAL16 hOwner
, BOOL16 isCode
,
97 BOOL16 is32Bit
, BOOL16 isReadOnly
,
103 /* Allocate the selector(s) */
105 sel
= SELECTOR_AllocBlock( ptr
, size
,
106 isCode
? SEGMENT_CODE
: SEGMENT_DATA
,
107 is32Bit
, isReadOnly
);
110 selcount
= (size
+ 0xffff) / 0x10000;
112 if (!(pArena
= GLOBAL_GetArena( sel
, selcount
)))
114 SELECTOR_FreeBlock( sel
, selcount
);
118 /* Fill the arena block */
120 pArena
->base
= (DWORD
)ptr
;
121 pArena
->size
= GET_SEL_LIMIT(sel
) + 1;
124 if ((flags
& GMEM_DDESHARE
) && Options
.ipc
)
126 pArena
->handle
= shmdata
->handle
;
127 pArena
->shmid
= shmdata
->shmid
;
132 pArena
->handle
= (flags
& GMEM_MOVEABLE
) ? sel
- 1 : sel
;
136 pArena
->handle
= (flags
& GMEM_MOVEABLE
) ? sel
- 1 : sel
;
138 pArena
->hOwner
= hOwner
;
139 pArena
->lockCount
= 0;
140 pArena
->pageLockCount
= 0;
141 pArena
->flags
= flags
& GA_MOVEABLE
;
142 if (flags
& GMEM_DISCARDABLE
) pArena
->flags
|= GA_DISCARDABLE
;
143 if (flags
& GMEM_DDESHARE
) pArena
->flags
|= GA_IPCSHARE
;
144 if (!isCode
) pArena
->flags
|= GA_DGROUP
;
145 pArena
->selCount
= selcount
;
146 if (selcount
> 1) /* clear the next arena blocks */
147 memset( pArena
+ 1, 0, (selcount
- 1) * sizeof(GLOBALARENA
) );
149 return pArena
->handle
;
153 /***********************************************************************
156 * Free a block allocated by GLOBAL_CreateBlock, without touching
157 * the associated linear memory range.
159 BOOL16
GLOBAL_FreeBlock( HGLOBAL16 handle
)
164 if (!handle
) return TRUE
;
165 sel
= GlobalHandleToSel( handle
);
166 pArena
= GET_ARENA_PTR(sel
);
167 SELECTOR_FreeBlock( sel
, (pArena
->size
+ 0xffff) / 0x10000 );
168 memset( pArena
, 0, sizeof(GLOBALARENA
) );
173 /***********************************************************************
176 * Implementation of GlobalAlloc16()
178 HGLOBAL16
GLOBAL_Alloc( UINT16 flags
, DWORD size
, HGLOBAL16 hOwner
,
179 BOOL16 isCode
, BOOL16 is32Bit
, BOOL16 isReadOnly
)
185 dprintf_global( stddeb
, "GlobalAlloc: %ld flags=%04x\n", size
, flags
);
187 /* If size is 0, create a discarded block */
189 if (size
== 0) return GLOBAL_CreateBlock( flags
, NULL
, 1, hOwner
, isCode
,
190 is32Bit
, isReadOnly
, NULL
);
194 if (size
>= GLOBAL_MAX_ALLOC_SIZE
- 0x1f) return 0;
195 size
= (size
+ 0x1f) & ~0x1f;
197 /* Allocate the linear memory */
200 if ((flags
& GMEM_DDESHARE
) && Options
.ipc
)
201 ptr
= DDE_malloc(flags
, size
, &shmdata
);
203 #endif /* CONFIG_IPC */
205 ptr
= HeapAlloc( SystemHeap
, 0, size
);
209 /* Allocate the selector(s) */
211 handle
= GLOBAL_CreateBlock( flags
, ptr
, size
, hOwner
,
212 isCode
, is32Bit
, isReadOnly
, &shmdata
);
215 HeapFree( SystemHeap
, 0, ptr
);
219 if (flags
& GMEM_ZEROINIT
) memset( ptr
, 0, size
);
225 /***********************************************************************
228 * Find the arena for a given handle
229 * (when handle is not serial - e.g. DDE)
231 static GLOBALARENA
*GLOBAL_FindArena( HGLOBAL16 handle
)
234 for (i
= globalArenaSize
-1 ; i
>=0 ; i
--) {
235 if (pGlobalArena
[i
].size
!=0 && pGlobalArena
[i
].handle
== handle
)
236 return ( &pGlobalArena
[i
] );
242 /***********************************************************************
243 * DDE_GlobalHandleToSel
246 WORD
DDE_GlobalHandleToSel( HGLOBAL16 handle
)
251 pArena
= GLOBAL_FindArena(handle
);
253 int ArenaIdx
= pArena
- pGlobalArena
;
255 /* See if synchronized to the shared memory */
256 return DDE_SyncHandle(handle
, ( ArenaIdx
<< __AHSHIFT
) | 7);
259 /* attach the block */
260 DDE_AttachHandle(handle
, &segptr
);
262 return SELECTOROF( segptr
);
264 #endif /* CONFIG_IPC */
267 /***********************************************************************
268 * GlobalAlloc16 (KERNEL.15)
270 HGLOBAL16
GlobalAlloc16( UINT16 flags
, DWORD size
)
272 HANDLE16 owner
= GetCurrentPDB();
274 if (flags
& GMEM_DDESHARE
)
275 owner
= GetExePtr(owner
); /* Make it a module handle */
276 return GLOBAL_Alloc( flags
, size
, owner
, FALSE
, FALSE
, FALSE
);
280 /***********************************************************************
281 * GlobalReAlloc16 (KERNEL.16)
283 HGLOBAL16
GlobalReAlloc16( HGLOBAL16 handle
, DWORD size
, UINT16 flags
)
288 GLOBALARENA
*pArena
, *pNewArena
;
289 WORD sel
= GlobalHandleToSel( handle
);
291 dprintf_global( stddeb
, "GlobalReAlloc16: %04x %ld flags=%04x\n",
292 handle
, size
, flags
);
293 if (!handle
) return 0;
296 if (Options
.ipc
&& (flags
& GMEM_DDESHARE
|| is_dde_handle(handle
))) {
298 "GlobalReAlloc16: shared memory reallocating unimplemented\n");
301 #endif /* CONFIG_IPC */
303 pArena
= GET_ARENA_PTR( handle
);
305 /* Discard the block if requested */
307 if ((size
== 0) && (flags
& GMEM_MOVEABLE
) && !(flags
& GMEM_MODIFY
))
309 if (!(pArena
->flags
& GA_MOVEABLE
) ||
310 !(pArena
->flags
& GA_DISCARDABLE
) ||
311 (pArena
->lockCount
> 0) || (pArena
->pageLockCount
> 0)) return 0;
312 HeapFree( SystemHeap
, 0, (void *)pArena
->base
);
314 /* Note: we rely on the fact that SELECTOR_ReallocBlock won't */
315 /* change the selector if we are shrinking the block */
316 SELECTOR_ReallocBlock( sel
, 0, 1, SEGMENT_DATA
, 0, 0 );
322 if (size
> GLOBAL_MAX_ALLOC_SIZE
- 0x20) return 0;
323 if (size
== 0) size
= 0x20;
324 else size
= (size
+ 0x1f) & ~0x1f;
326 /* Change the flags */
328 if (flags
& GMEM_MODIFY
)
330 /* Change the flags, leaving GA_DGROUP alone */
331 pArena
->flags
= (pArena
->flags
& GA_DGROUP
) | (flags
& GA_MOVEABLE
);
332 if (flags
& GMEM_DISCARDABLE
) pArena
->flags
|= GA_DISCARDABLE
;
336 /* Reallocate the linear memory */
338 ptr
= (void *)pArena
->base
;
339 oldsize
= pArena
->size
;
340 dprintf_global(stddeb
,"oldsize %08lx\n",oldsize
);
341 if (ptr
&& (size
== oldsize
)) return handle
; /* Nothing to do */
343 ptr
= HeapReAlloc( SystemHeap
, 0, ptr
, size
);
346 SELECTOR_FreeBlock( sel
, (oldsize
+ 0xffff) / 0x10000 );
347 memset( pArena
, 0, sizeof(GLOBALARENA
) );
351 /* Reallocate the selector(s) */
353 sel
= SELECTOR_ReallocBlock( sel
, ptr
, size
, SEGMENT_DATA
, 0, 0 );
356 HeapFree( SystemHeap
, 0, ptr
);
357 memset( pArena
, 0, sizeof(GLOBALARENA
) );
360 selcount
= (size
+ 0xffff) / 0x10000;
362 if (!(pNewArena
= GLOBAL_GetArena( sel
, selcount
)))
364 HeapFree( SystemHeap
, 0, ptr
);
365 SELECTOR_FreeBlock( sel
, selcount
);
369 /* Fill the new arena block */
371 if (pNewArena
!= pArena
) memcpy( pNewArena
, pArena
, sizeof(GLOBALARENA
) );
372 pNewArena
->base
= (DWORD
)ptr
;
373 pNewArena
->size
= GET_SEL_LIMIT(sel
) + 1;
374 pNewArena
->selCount
= selcount
;
375 pNewArena
->handle
= (pNewArena
->flags
& GA_MOVEABLE
) ? sel
- 1 : sel
;
377 if (selcount
> 1) /* clear the next arena blocks */
378 memset( pNewArena
+ 1, 0, (selcount
- 1) * sizeof(GLOBALARENA
) );
380 if ((oldsize
< size
) && (flags
& GMEM_ZEROINIT
))
381 memset( (char *)ptr
+ oldsize
, 0, size
- oldsize
);
382 return pNewArena
->handle
;
386 /***********************************************************************
387 * GlobalFree16 (KERNEL.17)
389 HGLOBAL16
GlobalFree16( HGLOBAL16 handle
)
391 void *ptr
= GlobalLock16( handle
);
393 dprintf_global( stddeb
, "GlobalFree16: %04x\n", handle
);
394 if (!GLOBAL_FreeBlock( handle
)) return handle
; /* failed */
396 if (is_dde_handle(handle
)) return DDE_GlobalFree(handle
);
397 #endif /* CONFIG_IPC */
398 if (ptr
) HeapFree( SystemHeap
, 0, ptr
);
403 /***********************************************************************
404 * WIN16_GlobalLock16 (KERNEL.18)
406 * This is the GlobalLock16() function used by 16-bit code.
408 SEGPTR
WIN16_GlobalLock16( HGLOBAL16 handle
)
410 dprintf_global( stddeb
, "WIN16_GlobalLock16(%04x) -> %08lx\n",
411 handle
, MAKELONG( 0, GlobalHandleToSel(handle
)) );
412 if (!handle
) return 0;
415 if (is_dde_handle(handle
))
416 return PTR_SEG_OFF_TO_SEGPTR( DDE_GlobalHandleToSel(handle
), 0 );
417 #endif /* CONFIG_IPC */
419 if (!GET_ARENA_PTR(handle
)->base
) return (SEGPTR
)0;
420 return PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(handle
), 0 );
424 /***********************************************************************
425 * GlobalLock16 (KERNEL.18)
427 * This is the GlobalLock16() function used by 32-bit code.
429 LPVOID
GlobalLock16( HGLOBAL16 handle
)
431 if (!handle
) return 0;
433 if (is_dde_handle(handle
)) return DDE_AttachHandle(handle
, NULL
);
435 return (LPVOID
)GET_ARENA_PTR(handle
)->base
;
439 /***********************************************************************
440 * GlobalUnlock16 (KERNEL.19)
442 BOOL16
GlobalUnlock16( HGLOBAL16 handle
)
444 dprintf_global( stddeb
, "GlobalUnlock16: %04x\n", handle
);
449 /***********************************************************************
450 * GlobalSize16 (KERNEL.20)
452 DWORD
GlobalSize16( HGLOBAL16 handle
)
454 dprintf_global( stddeb
, "GlobalSize16: %04x\n", handle
);
455 if (!handle
) return 0;
456 return GET_ARENA_PTR(handle
)->size
;
460 /***********************************************************************
461 * GlobalHandle16 (KERNEL.21)
463 DWORD
GlobalHandle16( WORD sel
)
465 dprintf_global( stddeb
, "GlobalHandle16: %04x\n", sel
);
466 return MAKELONG( GET_ARENA_PTR(sel
)->handle
, GlobalHandleToSel(sel
) );
470 /***********************************************************************
471 * GlobalFlags16 (KERNEL.22)
473 UINT16
GlobalFlags16( HGLOBAL16 handle
)
477 dprintf_global( stddeb
, "GlobalFlags16: %04x\n", handle
);
478 pArena
= GET_ARENA_PTR(handle
);
479 return pArena
->lockCount
|
480 ((pArena
->flags
& GA_DISCARDABLE
) ? GMEM_DISCARDABLE
: 0) |
481 ((pArena
->base
== 0) ? GMEM_DISCARDED
: 0);
485 /***********************************************************************
486 * LockSegment16 (KERNEL.23)
488 HGLOBAL16
LockSegment16( HGLOBAL16 handle
)
490 dprintf_global( stddeb
, "LockSegment: %04x\n", handle
);
491 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
492 GET_ARENA_PTR(handle
)->lockCount
++;
497 /***********************************************************************
498 * UnlockSegment16 (KERNEL.24)
500 void UnlockSegment16( HGLOBAL16 handle
)
502 dprintf_global( stddeb
, "UnlockSegment: %04x\n", handle
);
503 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
504 GET_ARENA_PTR(handle
)->lockCount
--;
505 /* FIXME: this ought to return the lock count in CX (go figure...) */
509 /***********************************************************************
510 * GlobalCompact16 (KERNEL.25)
512 DWORD
GlobalCompact16( DWORD desired
)
514 return GLOBAL_MAX_ALLOC_SIZE
;
518 /***********************************************************************
519 * GlobalFreeAll (KERNEL.26)
521 void GlobalFreeAll( HGLOBAL16 owner
)
526 pArena
= pGlobalArena
;
527 for (i
= 0; i
< globalArenaSize
; i
++, pArena
++)
529 if ((pArena
->size
!= 0) && (pArena
->hOwner
== owner
))
530 GlobalFree16( pArena
->handle
);
535 /***********************************************************************
536 * GlobalWire (KERNEL.111)
538 SEGPTR
GlobalWire( HGLOBAL16 handle
)
540 return WIN16_GlobalLock16( handle
);
544 /***********************************************************************
545 * GlobalUnWire (KERNEL.112)
547 BOOL16
GlobalUnWire( HGLOBAL16 handle
)
549 return GlobalUnlock16( handle
);
553 /***********************************************************************
554 * SetSwapAreaSize (KERNEL.106)
556 LONG
SetSwapAreaSize( WORD size
)
558 dprintf_global(stdnimp
, "STUB: SetSwapAreaSize(%d)\n", size
);
559 return MAKELONG( size
, 0xffff );
563 /***********************************************************************
564 * GlobalLRUOldest (KERNEL.163)
566 HGLOBAL16
GlobalLRUOldest( HGLOBAL16 handle
)
568 dprintf_global( stddeb
, "GlobalLRUOldest: %04x\n", handle
);
569 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
574 /***********************************************************************
575 * GlobalLRUNewest (KERNEL.164)
577 HGLOBAL16
GlobalLRUNewest( HGLOBAL16 handle
)
579 dprintf_global( stddeb
, "GlobalLRUNewest: %04x\n", handle
);
580 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
585 /***********************************************************************
586 * GetFreeSpace (KERNEL.169)
588 DWORD
GetFreeSpace( UINT16 wFlags
)
592 GlobalMemoryStatus( &ms
);
593 return ms
.dwAvailVirtual
;
597 /***********************************************************************
598 * GlobalPageLock (KERNEL.191)
600 WORD
GlobalPageLock( HGLOBAL16 handle
)
602 dprintf_global( stddeb
, "GlobalPageLock: %04x\n", handle
);
603 return ++(GET_ARENA_PTR(handle
)->pageLockCount
);
607 /***********************************************************************
608 * GlobalPageUnlock (KERNEL.192)
610 WORD
GlobalPageUnlock( HGLOBAL16 handle
)
612 dprintf_global( stddeb
, "GlobalPageUnlock: %04x\n", handle
);
613 return --(GET_ARENA_PTR(handle
)->pageLockCount
);
617 /***********************************************************************
618 * GlobalFix (KERNEL.197)
620 void GlobalFix( HGLOBAL16 handle
)
622 dprintf_global( stddeb
, "GlobalFix: %04x\n", handle
);
623 GET_ARENA_PTR(handle
)->lockCount
++;
627 /***********************************************************************
628 * GlobalUnfix (KERNEL.198)
630 void GlobalUnfix( HGLOBAL16 handle
)
632 dprintf_global( stddeb
, "GlobalUnfix: %04x\n", handle
);
633 GET_ARENA_PTR(handle
)->lockCount
--;
637 /***********************************************************************
638 * FarSetOwner (KERNEL.403)
640 void FarSetOwner( HGLOBAL16 handle
, HANDLE16 hOwner
)
642 GET_ARENA_PTR(handle
)->hOwner
= hOwner
;
646 /***********************************************************************
647 * FarGetOwner (KERNEL.404)
649 HANDLE16
FarGetOwner( HGLOBAL16 handle
)
651 return GET_ARENA_PTR(handle
)->hOwner
;
655 /***********************************************************************
656 * GlobalHandleToSel (TOOLHELP.50)
658 WORD
GlobalHandleToSel( HGLOBAL16 handle
)
660 dprintf_toolhelp( stddeb
, "GlobalHandleToSel: %04x\n", handle
);
661 if (!handle
) return 0;
663 if (is_dde_handle(handle
)) return DDE_GlobalHandleToSel(handle
);
667 fprintf( stderr
, "Program attempted invalid selector conversion\n" );
674 /***********************************************************************
675 * GlobalFirst (TOOLHELP.51)
677 BOOL16
GlobalFirst( GLOBALENTRY
*pGlobal
, WORD wFlags
)
679 if (wFlags
== GLOBAL_LRU
) return FALSE
;
681 return GlobalNext( pGlobal
, wFlags
);
685 /***********************************************************************
686 * GlobalNext (TOOLHELP.52)
688 BOOL16
GlobalNext( GLOBALENTRY
*pGlobal
, WORD wFlags
)
692 if (pGlobal
->dwNext
>= globalArenaSize
) return FALSE
;
693 pArena
= pGlobalArena
+ pGlobal
->dwNext
;
694 if (wFlags
== GLOBAL_FREE
) /* only free blocks */
697 for (i
= pGlobal
->dwNext
; i
< globalArenaSize
; i
++, pArena
++)
698 if (pArena
->size
== 0) break; /* block is free */
699 if (i
>= globalArenaSize
) return FALSE
;
703 pGlobal
->dwAddress
= pArena
->base
;
704 pGlobal
->dwBlockSize
= pArena
->size
;
705 pGlobal
->hBlock
= pArena
->handle
;
706 pGlobal
->wcLock
= pArena
->lockCount
;
707 pGlobal
->wcPageLock
= pArena
->pageLockCount
;
708 pGlobal
->wFlags
= (GetCurrentPDB() == pArena
->hOwner
);
709 pGlobal
->wHeapPresent
= FALSE
;
710 pGlobal
->hOwner
= pArena
->hOwner
;
711 pGlobal
->wType
= GT_UNKNOWN
;
718 /***********************************************************************
719 * GlobalInfo (TOOLHELP.53)
721 BOOL16
GlobalInfo( GLOBALINFO
*pInfo
)
726 pInfo
->wcItems
= globalArenaSize
;
727 pInfo
->wcItemsFree
= 0;
728 pInfo
->wcItemsLRU
= 0;
729 for (i
= 0, pArena
= pGlobalArena
; i
< globalArenaSize
; i
++, pArena
++)
730 if (pArena
->size
== 0) pInfo
->wcItemsFree
++;
735 /***********************************************************************
736 * GlobalEntryHandle (TOOLHELP.54)
738 BOOL16
GlobalEntryHandle( GLOBALENTRY
*pGlobal
, HGLOBAL16 hItem
)
744 /***********************************************************************
745 * GlobalEntryModule (TOOLHELP.55)
747 BOOL16
GlobalEntryModule( GLOBALENTRY
*pGlobal
, HMODULE16 hModule
, WORD wSeg
)
753 /***********************************************************************
754 * MemManInfo (TOOLHELP.72)
756 BOOL16
MemManInfo( MEMMANINFO
*info
)
760 if (info
->dwSize
< sizeof(MEMMANINFO
)) return FALSE
;
761 GlobalMemoryStatus( &status
);
762 info
->wPageSize
= getpagesize();
763 info
->dwLargestFreeBlock
= status
.dwAvailVirtual
;
764 info
->dwMaxPagesAvailable
= info
->dwLargestFreeBlock
/ info
->wPageSize
;
765 info
->dwMaxPagesLockable
= info
->dwMaxPagesAvailable
;
766 info
->dwTotalLinearSpace
= status
.dwTotalVirtual
/ info
->wPageSize
;
767 info
->dwTotalUnlockedPages
= info
->dwTotalLinearSpace
;
768 info
->dwFreePages
= info
->dwMaxPagesAvailable
;
769 info
->dwTotalPages
= info
->dwTotalLinearSpace
;
770 info
->dwFreeLinearSpace
= info
->dwMaxPagesAvailable
;
771 info
->dwSwapFilePages
= status
.dwTotalPageFile
/ info
->wPageSize
;
776 /***********************************************************************
777 * GlobalAlloc32 (KERNEL32.315)
779 HGLOBAL32
GlobalAlloc32( UINT32 flags
, DWORD size
)
783 if (flags
& GMEM_MOVEABLE
)
784 fprintf( stderr
, "GlobalAlloc32: unimplemented flag GMEM_MOVEABLE\n" );
786 if (flags
& GMEM_ZEROINIT
) heapFlags
|= HEAP_ZERO_MEMORY
;
787 return (HGLOBAL32
)HeapAlloc( GetProcessHeap(), heapFlags
, size
);
791 /***********************************************************************
792 * GlobalCompact32 (KERNEL32.316)
794 DWORD
GlobalCompact32( DWORD minfree
)
796 return 0; /* GlobalCompact does nothing in Win32 */
800 /***********************************************************************
801 * GlobalFlags32 (KERNEL32.321)
803 UINT32
GlobalFlags32( HGLOBAL32 handle
)
809 /***********************************************************************
810 * GlobalFree32 (KERNEL32.322)
812 HGLOBAL32
GlobalFree32( HGLOBAL32 handle
)
814 return HeapFree( GetProcessHeap(), 0, (LPVOID
)handle
) ? 0 : handle
;
818 /***********************************************************************
819 * GlobalHandle32 (KERNEL32.325)
821 HGLOBAL32
GlobalHandle32( LPCVOID ptr
)
823 return (HGLOBAL32
)ptr
;
827 /***********************************************************************
828 * GlobalLock32 (KERNEL32.326)
830 LPVOID
GlobalLock32( HGLOBAL32 handle
)
832 return (LPVOID
)handle
;
836 /***********************************************************************
837 * GlobalReAlloc32 (KERNEL32.328)
839 HGLOBAL32
GlobalReAlloc32( HGLOBAL32 handle
, DWORD size
, UINT32 flags
)
841 if (flags
& GMEM_MODIFY
)
843 fprintf( stderr
, "GlobalReAlloc32: GMEM_MODIFY not supported\n" );
847 return (HGLOBAL32
)HeapReAlloc( GetProcessHeap(), 0, (LPVOID
)handle
, size
);
851 /***********************************************************************
852 * GlobalSize32 (KERNEL32.329)
854 DWORD
GlobalSize32( HGLOBAL32 handle
)
856 return HeapSize( GetProcessHeap(), 0, (LPVOID
)handle
);
860 /***********************************************************************
861 * GlobalUnlock32 (KERNEL32.332)
863 BOOL32
GlobalUnlock32( HGLOBAL32 handle
)
869 /***********************************************************************
870 * GlobalMemoryStatus (KERNEL32.327)
872 VOID
GlobalMemoryStatus( LPMEMORYSTATUS lpmem
)
875 FILE *f
= fopen( "/proc/meminfo", "r" );
879 int total
, used
, free
;
881 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
882 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
883 while (fgets( buffer
, sizeof(buffer
), f
))
885 if (sscanf( buffer
, "Mem: %d %d %d", &total
, &used
, &free
))
887 lpmem
->dwTotalPhys
+= total
;
888 lpmem
->dwAvailPhys
+= free
;
890 else if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
892 lpmem
->dwTotalPageFile
+= total
;
893 lpmem
->dwAvailPageFile
+= free
;
898 if (lpmem
->dwTotalPhys
)
900 lpmem
->dwTotalVirtual
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
901 lpmem
->dwAvailVirtual
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
902 lpmem
->dwMemoryLoad
= (lpmem
->dwTotalVirtual
-lpmem
->dwAvailVirtual
)
903 * 100 / lpmem
->dwTotalVirtual
;
908 /* FIXME: should do something for other systems */
909 lpmem
->dwMemoryLoad
= 0;
910 lpmem
->dwTotalPhys
= 16*1024*1024;
911 lpmem
->dwAvailPhys
= 16*1024*1024;
912 lpmem
->dwTotalPageFile
= 16*1024*1024;
913 lpmem
->dwAvailPageFile
= 16*1024*1024;
914 lpmem
->dwTotalVirtual
= 32*1024*1024;
915 lpmem
->dwAvailVirtual
= 32*1024*1024;