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
)))
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
)
163 if (!handle
) return TRUE
;
164 sel
= GlobalHandleToSel( handle
);
165 if (FreeSelector( sel
)) return FALSE
; /* failed */
166 memset( GET_ARENA_PTR(sel
), 0, sizeof(GLOBALARENA
) );
171 /***********************************************************************
174 * Implementation of GlobalAlloc16()
176 HGLOBAL16
GLOBAL_Alloc( UINT16 flags
, DWORD size
, HGLOBAL16 hOwner
,
177 BOOL16 isCode
, BOOL16 is32Bit
, BOOL16 isReadOnly
)
183 dprintf_global( stddeb
, "GlobalAlloc: %ld flags=%04x\n", size
, flags
);
185 /* If size is 0, create a discarded block */
187 if (size
== 0) return GLOBAL_CreateBlock( flags
, NULL
, 1, hOwner
, isCode
,
188 is32Bit
, isReadOnly
, NULL
);
192 if (size
>= GLOBAL_MAX_ALLOC_SIZE
- 0x1f) return 0;
193 size
= (size
+ 0x1f) & ~0x1f;
195 /* Allocate the linear memory */
198 if ((flags
& GMEM_DDESHARE
) && Options
.ipc
)
199 ptr
= DDE_malloc(flags
, size
, &shmdata
);
201 #endif /* CONFIG_IPC */
203 ptr
= HeapAlloc( SystemHeap
, 0, size
);
207 /* Allocate the selector(s) */
209 handle
= GLOBAL_CreateBlock( flags
, ptr
, size
, hOwner
,
210 isCode
, is32Bit
, isReadOnly
, &shmdata
);
213 HeapFree( SystemHeap
, 0, ptr
);
217 if (flags
& GMEM_ZEROINIT
) memset( ptr
, 0, size
);
223 /***********************************************************************
226 * Find the arena for a given handle
227 * (when handle is not serial - e.g. DDE)
229 static GLOBALARENA
*GLOBAL_FindArena( HGLOBAL handle
)
232 for (i
= globalArenaSize
-1 ; i
>=0 ; i
--) {
233 if (pGlobalArena
[i
].size
!=0 && pGlobalArena
[i
].handle
== handle
)
234 return ( &pGlobalArena
[i
] );
240 /***********************************************************************
241 * DDE_GlobalHandleToSel
244 WORD
DDE_GlobalHandleToSel( HGLOBAL handle
)
249 pArena
= GLOBAL_FindArena(handle
);
251 int ArenaIdx
= pArena
- pGlobalArena
;
253 /* See if synchronized to the shared memory */
254 return DDE_SyncHandle(handle
, ( ArenaIdx
<< __AHSHIFT
) | 7);
257 /* attach the block */
258 DDE_AttachHandle(handle
, &segptr
);
260 return SELECTOROF( segptr
);
262 #endif /* CONFIG_IPC */
265 /***********************************************************************
266 * GlobalAlloc16 (KERNEL.15)
268 HGLOBAL16
GlobalAlloc16( UINT16 flags
, DWORD size
)
270 HANDLE16 owner
= GetCurrentPDB();
272 if (flags
& GMEM_DDESHARE
)
273 owner
= GetExePtr(owner
); /* Make it a module handle */
274 return GLOBAL_Alloc( flags
, size
, owner
, FALSE
, FALSE
, FALSE
);
278 /***********************************************************************
279 * GlobalReAlloc16 (KERNEL.16)
281 HGLOBAL16
GlobalReAlloc16( HGLOBAL16 handle
, DWORD size
, UINT16 flags
)
286 GLOBALARENA
*pArena
, *pNewArena
;
287 WORD sel
= GlobalHandleToSel( handle
);
289 dprintf_global( stddeb
, "GlobalReAlloc16: %04x %ld flags=%04x\n",
290 handle
, size
, flags
);
291 if (!handle
) return 0;
294 if (Options
.ipc
&& (flags
& GMEM_DDESHARE
|| is_dde_handle(handle
))) {
296 "GlobalReAlloc16: shared memory reallocating unimplemented\n");
299 #endif /* CONFIG_IPC */
301 pArena
= GET_ARENA_PTR( handle
);
303 /* Discard the block if requested */
305 if ((size
== 0) && (flags
& GMEM_MOVEABLE
) && !(flags
& GMEM_MODIFY
))
307 if (!(pArena
->flags
& GA_MOVEABLE
) ||
308 !(pArena
->flags
& GA_DISCARDABLE
) ||
309 (pArena
->lockCount
> 0) || (pArena
->pageLockCount
> 0)) return 0;
310 HeapFree( SystemHeap
, 0, (void *)pArena
->base
);
312 /* Note: we rely on the fact that SELECTOR_ReallocBlock won't */
313 /* change the selector if we are shrinking the block */
314 SELECTOR_ReallocBlock( sel
, 0, 1, SEGMENT_DATA
, 0, 0 );
320 if (size
> GLOBAL_MAX_ALLOC_SIZE
- 0x20) return 0;
321 if (size
== 0) size
= 0x20;
322 else size
= (size
+ 0x1f) & ~0x1f;
324 /* Change the flags */
326 if (flags
& GMEM_MODIFY
)
328 /* Change the flags, leaving GA_DGROUP alone */
329 pArena
->flags
= (pArena
->flags
& GA_DGROUP
) | (flags
& GA_MOVEABLE
);
330 if (flags
& GMEM_DISCARDABLE
) pArena
->flags
|= GA_DISCARDABLE
;
334 /* Reallocate the linear memory */
336 ptr
= (void *)pArena
->base
;
337 oldsize
= pArena
->size
;
338 dprintf_global(stddeb
,"oldsize %08lx\n",oldsize
);
339 if (ptr
&& (size
== oldsize
)) return handle
; /* Nothing to do */
341 ptr
= HeapReAlloc( SystemHeap
, 0, ptr
, size
);
345 memset( pArena
, 0, sizeof(GLOBALARENA
) );
349 /* Reallocate the selector(s) */
351 sel
= SELECTOR_ReallocBlock( sel
, ptr
, size
, SEGMENT_DATA
, 0, 0 );
354 HeapFree( SystemHeap
, 0, ptr
);
355 memset( pArena
, 0, sizeof(GLOBALARENA
) );
358 selcount
= (size
+ 0xffff) / 0x10000;
360 if (!(pNewArena
= GLOBAL_GetArena( sel
, selcount
)))
362 HeapFree( SystemHeap
, 0, ptr
);
367 /* Fill the new arena block */
369 if (pNewArena
!= pArena
) memcpy( pNewArena
, pArena
, sizeof(GLOBALARENA
) );
370 pNewArena
->base
= (DWORD
)ptr
;
371 pNewArena
->size
= GET_SEL_LIMIT(sel
) + 1;
372 pNewArena
->selCount
= selcount
;
373 pNewArena
->handle
= (pNewArena
->flags
& GA_MOVEABLE
) ? sel
- 1 : sel
;
375 if (selcount
> 1) /* clear the next arena blocks */
376 memset( pNewArena
+ 1, 0, (selcount
- 1) * sizeof(GLOBALARENA
) );
378 if ((oldsize
< size
) && (flags
& GMEM_ZEROINIT
))
379 memset( (char *)ptr
+ oldsize
, 0, size
- oldsize
);
380 return pNewArena
->handle
;
384 /***********************************************************************
385 * GlobalFree16 (KERNEL.17)
387 HGLOBAL16
GlobalFree16( HGLOBAL16 handle
)
389 void *ptr
= GlobalLock16( handle
);
391 dprintf_global( stddeb
, "GlobalFree16: %04x\n", handle
);
392 if (!GLOBAL_FreeBlock( handle
)) return handle
; /* failed */
394 if (is_dde_handle(handle
)) return DDE_GlobalFree(handle
);
395 #endif /* CONFIG_IPC */
396 if (ptr
) HeapFree( SystemHeap
, 0, ptr
);
401 /***********************************************************************
402 * WIN16_GlobalLock16 (KERNEL.18)
404 * This is the GlobalLock16() function used by 16-bit code.
406 SEGPTR
WIN16_GlobalLock16( HGLOBAL16 handle
)
408 dprintf_global( stddeb
, "WIN16_GlobalLock16(%04x) -> %08lx\n",
409 handle
, MAKELONG( 0, GlobalHandleToSel(handle
)) );
410 if (!handle
) return 0;
413 if (is_dde_handle(handle
))
414 return PTR_SEG_OFF_TO_SEGPTR( DDE_GlobalHandleToSel(handle
), 0 );
415 #endif /* CONFIG_IPC */
417 if (!GET_ARENA_PTR(handle
)->base
) return (SEGPTR
)0;
418 return PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(handle
), 0 );
422 /***********************************************************************
423 * GlobalLock16 (KERNEL.18)
425 * This is the GlobalLock16() function used by 32-bit code.
427 LPVOID
GlobalLock16( HGLOBAL16 handle
)
429 if (!handle
) return 0;
431 if (is_dde_handle(handle
)) return DDE_AttachHandle(handle
, NULL
);
433 return (LPVOID
)GET_ARENA_PTR(handle
)->base
;
437 /***********************************************************************
438 * GlobalUnlock16 (KERNEL.19)
440 BOOL16
GlobalUnlock16( HGLOBAL16 handle
)
442 dprintf_global( stddeb
, "GlobalUnlock16: %04x\n", handle
);
447 /***********************************************************************
448 * GlobalSize16 (KERNEL.20)
450 DWORD
GlobalSize16( HGLOBAL16 handle
)
452 dprintf_global( stddeb
, "GlobalSize16: %04x\n", handle
);
453 if (!handle
) return 0;
454 return GET_ARENA_PTR(handle
)->size
;
458 /***********************************************************************
459 * GlobalHandle16 (KERNEL.21)
461 DWORD
GlobalHandle16( WORD sel
)
463 dprintf_global( stddeb
, "GlobalHandle16: %04x\n", sel
);
464 return MAKELONG( GET_ARENA_PTR(sel
)->handle
, GlobalHandleToSel(sel
) );
468 /***********************************************************************
469 * GlobalFlags16 (KERNEL.22)
471 UINT16
GlobalFlags16( HGLOBAL16 handle
)
475 dprintf_global( stddeb
, "GlobalFlags16: %04x\n", handle
);
476 pArena
= GET_ARENA_PTR(handle
);
477 return pArena
->lockCount
|
478 ((pArena
->flags
& GA_DISCARDABLE
) ? GMEM_DISCARDABLE
: 0) |
479 ((pArena
->base
== 0) ? GMEM_DISCARDED
: 0);
483 /***********************************************************************
484 * LockSegment16 (KERNEL.23)
486 HGLOBAL16
LockSegment16( HGLOBAL16 handle
)
488 dprintf_global( stddeb
, "LockSegment: %04x\n", handle
);
489 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
490 GET_ARENA_PTR(handle
)->lockCount
++;
495 /***********************************************************************
496 * UnlockSegment16 (KERNEL.24)
498 void UnlockSegment16( HGLOBAL16 handle
)
500 dprintf_global( stddeb
, "UnlockSegment: %04x\n", handle
);
501 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
502 GET_ARENA_PTR(handle
)->lockCount
--;
503 /* FIXME: this ought to return the lock count in CX (go figure...) */
507 /***********************************************************************
508 * GlobalCompact16 (KERNEL.25)
510 DWORD
GlobalCompact16( DWORD desired
)
512 return GLOBAL_MAX_ALLOC_SIZE
;
516 /***********************************************************************
517 * GlobalFreeAll (KERNEL.26)
519 void GlobalFreeAll( HGLOBAL16 owner
)
524 pArena
= pGlobalArena
;
525 for (i
= 0; i
< globalArenaSize
; i
++, pArena
++)
527 if ((pArena
->size
!= 0) && (pArena
->hOwner
== owner
))
528 GlobalFree16( pArena
->handle
);
533 /***********************************************************************
534 * GlobalWire (KERNEL.111)
536 SEGPTR
GlobalWire( HGLOBAL16 handle
)
538 return WIN16_GlobalLock16( handle
);
542 /***********************************************************************
543 * GlobalUnWire (KERNEL.112)
545 BOOL16
GlobalUnWire( HGLOBAL16 handle
)
547 return GlobalUnlock16( handle
);
551 /***********************************************************************
552 * GlobalDOSAlloc (KERNEL.184)
554 DWORD
GlobalDOSAlloc( DWORD size
)
556 WORD sel
= GlobalAlloc16( GMEM_FIXED
, size
);
558 return MAKELONG( sel
, sel
/* this one ought to be a real-mode segment */ );
562 /***********************************************************************
563 * GlobalDOSFree (KERNEL.185)
565 WORD
GlobalDOSFree( WORD sel
)
567 return GlobalFree16( GlobalHandle16(sel
) ) ? sel
: 0;
571 /***********************************************************************
572 * SetSwapAreaSize (KERNEL.106)
574 LONG
SetSwapAreaSize( WORD size
)
576 dprintf_global(stdnimp
, "STUB: SetSwapAreaSize(%d)\n", size
);
577 return MAKELONG( size
, 0xffff );
581 /***********************************************************************
582 * GlobalLRUOldest (KERNEL.163)
584 HGLOBAL16
GlobalLRUOldest( HGLOBAL16 handle
)
586 dprintf_global( stddeb
, "GlobalLRUOldest: %04x\n", handle
);
587 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
592 /***********************************************************************
593 * GlobalLRUNewest (KERNEL.164)
595 HGLOBAL16
GlobalLRUNewest( HGLOBAL16 handle
)
597 dprintf_global( stddeb
, "GlobalLRUNewest: %04x\n", handle
);
598 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
603 /***********************************************************************
604 * GetFreeSpace (KERNEL.169)
606 DWORD
GetFreeSpace( UINT16 wFlags
)
608 return GLOBAL_MAX_ALLOC_SIZE
;
612 /***********************************************************************
613 * GlobalPageLock (KERNEL.191)
615 WORD
GlobalPageLock( HGLOBAL16 handle
)
617 dprintf_global( stddeb
, "GlobalPageLock: %04x\n", handle
);
618 return ++(GET_ARENA_PTR(handle
)->pageLockCount
);
622 /***********************************************************************
623 * GlobalPageUnlock (KERNEL.192)
625 WORD
GlobalPageUnlock( HGLOBAL16 handle
)
627 dprintf_global( stddeb
, "GlobalPageUnlock: %04x\n", handle
);
628 return --(GET_ARENA_PTR(handle
)->pageLockCount
);
632 /***********************************************************************
633 * GlobalFix (KERNEL.197)
635 void GlobalFix( HGLOBAL16 handle
)
637 dprintf_global( stddeb
, "GlobalFix: %04x\n", handle
);
638 GET_ARENA_PTR(handle
)->lockCount
++;
642 /***********************************************************************
643 * GlobalUnfix (KERNEL.198)
645 void GlobalUnfix( HGLOBAL16 handle
)
647 dprintf_global( stddeb
, "GlobalUnfix: %04x\n", handle
);
648 GET_ARENA_PTR(handle
)->lockCount
--;
652 /***********************************************************************
653 * FarSetOwner (KERNEL.403)
655 void FarSetOwner( HANDLE16 handle
, HANDLE16 hOwner
)
657 GET_ARENA_PTR(handle
)->hOwner
= hOwner
;
661 /***********************************************************************
662 * FarGetOwner (KERNEL.404)
664 HANDLE16
FarGetOwner( HANDLE16 handle
)
666 return GET_ARENA_PTR(handle
)->hOwner
;
670 /***********************************************************************
671 * GlobalHandleToSel (TOOLHELP.50)
673 WORD
GlobalHandleToSel( HGLOBAL16 handle
)
675 dprintf_toolhelp( stddeb
, "GlobalHandleToSel: %04x\n", handle
);
676 if (!handle
) return 0;
678 if (is_dde_handle(handle
)) return DDE_GlobalHandleToSel(handle
);
682 fprintf( stderr
, "Program attempted invalid selector conversion\n" );
689 /***********************************************************************
690 * GlobalFirst (TOOLHELP.51)
692 BOOL16
GlobalFirst( GLOBALENTRY
*pGlobal
, WORD wFlags
)
694 if (wFlags
== GLOBAL_LRU
) return FALSE
;
696 return GlobalNext( pGlobal
, wFlags
);
700 /***********************************************************************
701 * GlobalNext (TOOLHELP.52)
703 BOOL16
GlobalNext( GLOBALENTRY
*pGlobal
, WORD wFlags
)
707 if (pGlobal
->dwNext
>= globalArenaSize
) return FALSE
;
708 pArena
= pGlobalArena
+ pGlobal
->dwNext
;
709 if (wFlags
== GLOBAL_FREE
) /* only free blocks */
712 for (i
= pGlobal
->dwNext
; i
< globalArenaSize
; i
++, pArena
++)
713 if (pArena
->size
== 0) break; /* block is free */
714 if (i
>= globalArenaSize
) return FALSE
;
718 pGlobal
->dwAddress
= pArena
->base
;
719 pGlobal
->dwBlockSize
= pArena
->size
;
720 pGlobal
->hBlock
= pArena
->handle
;
721 pGlobal
->wcLock
= pArena
->lockCount
;
722 pGlobal
->wcPageLock
= pArena
->pageLockCount
;
723 pGlobal
->wFlags
= (GetCurrentPDB() == pArena
->hOwner
);
724 pGlobal
->wHeapPresent
= FALSE
;
725 pGlobal
->hOwner
= pArena
->hOwner
;
726 pGlobal
->wType
= GT_UNKNOWN
;
733 /***********************************************************************
734 * GlobalInfo (TOOLHELP.53)
736 BOOL16
GlobalInfo( GLOBALINFO
*pInfo
)
741 pInfo
->wcItems
= globalArenaSize
;
742 pInfo
->wcItemsFree
= 0;
743 pInfo
->wcItemsLRU
= 0;
744 for (i
= 0, pArena
= pGlobalArena
; i
< globalArenaSize
; i
++, pArena
++)
745 if (pArena
->size
== 0) pInfo
->wcItemsFree
++;
750 /***********************************************************************
751 * GlobalEntryHandle (TOOLHELP.54)
753 BOOL16
GlobalEntryHandle( GLOBALENTRY
*pGlobal
, HGLOBAL16 hItem
)
759 /***********************************************************************
760 * GlobalEntryModule (TOOLHELP.55)
762 BOOL16
GlobalEntryModule( GLOBALENTRY
*pGlobal
, HMODULE16 hModule
, WORD wSeg
)
768 /***********************************************************************
769 * MemManInfo (TOOLHELP.72)
771 BOOL16
MemManInfo( MEMMANINFO
*pInfo
)
774 /* FIXME: does not take into account the dwSize member
775 * could be corrupting memory therefore
777 /* shamefully stolen from free */
785 if ((meminfo
= fopen("/proc/meminfo", "r")) < 0) {
786 perror("wine: open");
790 fgets(buf
, 80, meminfo
); /* read first line */
791 while ( fgets(buf
, 80, meminfo
) ) {
792 n
= sscanf( buf
, "%*s %d %d %d %d %d", &col
[0], &col
[1], &col
[2], &col
[3], &col
[4]);
793 if ( n
< 1 ) continue; /* escape the loop at the top */
795 availmem
+= col
[2] + col
[4];
798 fprintf(stderr
,"MemManInfo called with dwSize = %ld\n",pInfo
->dwSize
);
800 pInfo
->wPageSize
= getpagesize();
801 pInfo
->dwLargestFreeBlock
= availmem
;
802 pInfo
->dwTotalLinearSpace
= totalmem
/ pInfo
->wPageSize
;
803 pInfo
->dwMaxPagesAvailable
= pInfo
->dwLargestFreeBlock
/ pInfo
->wPageSize
;
804 pInfo
->dwMaxPagesLockable
= pInfo
->dwMaxPagesLockable
;
805 /* FIXME: the next three are not quite correct */
806 pInfo
->dwTotalUnlockedPages
= pInfo
->dwMaxPagesAvailable
;
807 pInfo
->dwFreePages
= pInfo
->dwMaxPagesAvailable
;
808 pInfo
->dwTotalPages
= pInfo
->dwMaxPagesAvailable
;
809 /* FIXME: the three above are not quite correct */
810 pInfo
->dwFreeLinearSpace
= pInfo
->dwMaxPagesAvailable
;
811 pInfo
->dwSwapFilePages
= 0L;
820 /***********************************************************************
821 * GlobalAlloc32 (KERNEL32.315)
823 HGLOBAL32
GlobalAlloc32( UINT32 flags
, DWORD size
)
827 if (flags
& GMEM_MOVEABLE
)
828 fprintf( stderr
, "GlobalAlloc32: unimplemented flag GMEM_MOVEABLE\n" );
830 if (flags
& GMEM_ZEROINIT
) heapFlags
|= HEAP_ZERO_MEMORY
;
831 return (HGLOBAL32
)HeapAlloc( GetProcessHeap(), heapFlags
, size
);
835 /***********************************************************************
836 * GlobalCompact32 (KERNEL32.316)
838 DWORD
GlobalCompact32( DWORD minfree
)
840 return 0; /* GlobalCompact does nothing in Win32 */
844 /***********************************************************************
845 * GlobalFlags32 (KERNEL32.321)
847 UINT32
GlobalFlags32( HGLOBAL32 handle
)
853 /***********************************************************************
854 * GlobalFree32 (KERNEL32.322)
856 HGLOBAL32
GlobalFree32( HGLOBAL32 handle
)
858 return HeapFree( GetProcessHeap(), 0, (LPVOID
)handle
) ? 0 : handle
;
862 /***********************************************************************
863 * GlobalHandle32 (KERNEL32.325)
865 HGLOBAL32
GlobalHandle32( LPCVOID ptr
)
867 return (HGLOBAL32
)ptr
;
871 /***********************************************************************
872 * GlobalLock32 (KERNEL32.326)
874 LPVOID
GlobalLock32( HGLOBAL32 handle
)
876 return (LPVOID
)handle
;
880 /***********************************************************************
881 * GlobalReAlloc32 (KERNEL32.328)
883 HGLOBAL32
GlobalReAlloc32( HGLOBAL32 handle
, DWORD size
, UINT32 flags
)
885 if (flags
& GMEM_MODIFY
)
887 fprintf( stderr
, "GlobalReAlloc32: GMEM_MODIFY not supported\n" );
891 return (HGLOBAL32
)HeapReAlloc( GetProcessHeap(), 0, (LPVOID
)handle
, size
);
895 /***********************************************************************
896 * GlobalSize32 (KERNEL32.329)
898 DWORD
GlobalSize32( HGLOBAL32 handle
)
900 return HeapSize( GetProcessHeap(), 0, (LPVOID
)handle
);
904 /***********************************************************************
905 * GlobalUnlock32 (KERNEL32.332)
907 BOOL32
GlobalUnlock32( HGLOBAL32 handle
)