Release 960712
[wine/testsucceed.git] / memory / global.c
blobc21f5ceae671bd8875b29b0784187956fc8ed9ba
1 /*
2 * Global heap functions
4 * Copyright 1995 Alexandre Julliard
5 */
7 #include <sys/types.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <string.h>
12 #include "windows.h"
13 #include "global.h"
14 #include "heap.h"
15 #include "toolhelp.h"
16 #include "selectors.h"
17 #include "dde_mem.h"
18 #include "stackframe.h"
19 #include "options.h"
20 #include "stddebug.h"
21 #include "debug.h"
23 /* Global arena block */
24 typedef struct
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 */
34 #ifdef CONFIG_IPC
35 int shmid;
36 #endif
37 } GLOBALARENA;
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 */
45 /* Arena array */
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 /***********************************************************************
54 * GLOBAL_GetArena
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);
75 void debug_handles()
77 int printed=0;
78 int i;
79 for (i = globalArenaSize-1 ; i>=0 ; i--) {
80 if (pGlobalArena[i].size!=0 && (pGlobalArena[i].handle & 0x8000)){
81 printed=1;
82 printf("0x%08x, ",pGlobalArena[i].handle);
85 if (printed)
86 printf("\n");
90 /***********************************************************************
91 * GLOBAL_CreateBlock
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,
98 SHMDATA *shmdata )
100 WORD sel, selcount;
101 GLOBALARENA *pArena;
103 /* Allocate the selector(s) */
105 sel = SELECTOR_AllocBlock( ptr, size,
106 isCode ? SEGMENT_CODE : SEGMENT_DATA,
107 is32Bit, isReadOnly );
109 if (!sel) return 0;
110 selcount = (size + 0xffff) / 0x10000;
112 if (!(pArena = GLOBAL_GetArena( sel, selcount )))
114 FreeSelector( sel );
115 return 0;
118 /* Fill the arena block */
120 pArena->base = (DWORD)ptr;
121 pArena->size = GET_SEL_LIMIT(sel) + 1;
123 #ifdef CONFIG_IPC
124 if ((flags & GMEM_DDESHARE) && Options.ipc)
126 pArena->handle = shmdata->handle;
127 pArena->shmid = shmdata->shmid;
128 shmdata->sel = sel;
130 else
132 pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
133 pArena->shmid = 0;
135 #else
136 pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
137 #endif
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 /***********************************************************************
154 * GLOBAL_FreeBlock
156 * Free a block allocated by GLOBAL_CreateBlock, without touching
157 * the associated linear memory range.
159 BOOL16 GLOBAL_FreeBlock( HGLOBAL16 handle )
161 WORD sel;
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) );
167 return TRUE;
171 /***********************************************************************
172 * GLOBAL_Alloc
174 * Implementation of GlobalAlloc16()
176 HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
177 BOOL16 isCode, BOOL16 is32Bit, BOOL16 isReadOnly )
179 void *ptr;
180 HGLOBAL16 handle;
181 SHMDATA shmdata;
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 );
190 /* Fixup the size */
192 if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x1f) return 0;
193 size = (size + 0x1f) & ~0x1f;
195 /* Allocate the linear memory */
197 #ifdef CONFIG_IPC
198 if ((flags & GMEM_DDESHARE) && Options.ipc)
199 ptr = DDE_malloc(flags, size, &shmdata);
200 else
201 #endif /* CONFIG_IPC */
203 ptr = HeapAlloc( SystemHeap, 0, size );
205 if (!ptr) return 0;
207 /* Allocate the selector(s) */
209 handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner,
210 isCode, is32Bit, isReadOnly, &shmdata);
211 if (!handle)
213 HeapFree( SystemHeap, 0, ptr );
214 return 0;
217 if (flags & GMEM_ZEROINIT) memset( ptr, 0, size );
218 return handle;
222 #ifdef CONFIG_IPC
223 /***********************************************************************
224 * GLOBAL_FindArena
226 * Find the arena for a given handle
227 * (when handle is not serial - e.g. DDE)
229 static GLOBALARENA *GLOBAL_FindArena( HGLOBAL handle)
231 int i;
232 for (i = globalArenaSize-1 ; i>=0 ; i--) {
233 if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == handle)
234 return ( &pGlobalArena[i] );
236 return NULL;
240 /***********************************************************************
241 * DDE_GlobalHandleToSel
244 WORD DDE_GlobalHandleToSel( HGLOBAL handle )
246 GLOBALARENA *pArena;
247 SEGPTR segptr;
249 pArena= GLOBAL_FindArena(handle);
250 if (pArena) {
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 )
283 WORD selcount;
284 DWORD oldsize;
285 void *ptr;
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;
293 #ifdef CONFIG_IPC
294 if (Options.ipc && (flags & GMEM_DDESHARE || is_dde_handle(handle))) {
295 fprintf(stdnimp,
296 "GlobalReAlloc16: shared memory reallocating unimplemented\n");
297 return 0;
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 );
311 pArena->base = 0;
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 );
315 return handle;
318 /* Fixup the size */
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;
331 return handle;
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 );
342 if (!ptr)
344 FreeSelector( sel );
345 memset( pArena, 0, sizeof(GLOBALARENA) );
346 return 0;
349 /* Reallocate the selector(s) */
351 sel = SELECTOR_ReallocBlock( sel, ptr, size, SEGMENT_DATA, 0, 0 );
352 if (!sel)
354 HeapFree( SystemHeap, 0, ptr );
355 memset( pArena, 0, sizeof(GLOBALARENA) );
356 return 0;
358 selcount = (size + 0xffff) / 0x10000;
360 if (!(pNewArena = GLOBAL_GetArena( sel, selcount )))
362 HeapFree( SystemHeap, 0, ptr );
363 FreeSelector( sel );
364 return 0;
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 */
393 #ifdef CONFIG_IPC
394 if (is_dde_handle(handle)) return DDE_GlobalFree(handle);
395 #endif /* CONFIG_IPC */
396 if (ptr) HeapFree( SystemHeap, 0, ptr );
397 return 0;
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;
412 #ifdef CONFIG_IPC
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;
430 #ifdef CONFIG_IPC
431 if (is_dde_handle(handle)) return DDE_AttachHandle(handle, NULL);
432 #endif
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 );
443 return 0;
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 )
473 GLOBALARENA *pArena;
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++;
491 return handle;
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 )
521 DWORD i;
522 GLOBALARENA *pArena;
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 );
557 if (!sel) return 0;
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;
588 return handle;
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;
599 return handle;
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;
677 #ifdef CONFIG_IPC
678 if (is_dde_handle(handle)) return DDE_GlobalHandleToSel(handle);
679 #endif
680 if (!(handle & 7))
682 fprintf( stderr, "Program attempted invalid selector conversion\n" );
683 return handle - 1;
685 return handle | 7;
689 /***********************************************************************
690 * GlobalFirst (TOOLHELP.51)
692 BOOL16 GlobalFirst( GLOBALENTRY *pGlobal, WORD wFlags )
694 if (wFlags == GLOBAL_LRU) return FALSE;
695 pGlobal->dwNext = 0;
696 return GlobalNext( pGlobal, wFlags );
700 /***********************************************************************
701 * GlobalNext (TOOLHELP.52)
703 BOOL16 GlobalNext( GLOBALENTRY *pGlobal, WORD wFlags)
705 GLOBALARENA *pArena;
707 if (pGlobal->dwNext >= globalArenaSize) return FALSE;
708 pArena = pGlobalArena + pGlobal->dwNext;
709 if (wFlags == GLOBAL_FREE) /* only free blocks */
711 int i;
712 for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++)
713 if (pArena->size == 0) break; /* block is free */
714 if (i >= globalArenaSize) return FALSE;
715 pGlobal->dwNext = i;
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;
727 pGlobal->wData = 0;
728 pGlobal->dwNext++;
729 return TRUE;
733 /***********************************************************************
734 * GlobalInfo (TOOLHELP.53)
736 BOOL16 GlobalInfo( GLOBALINFO *pInfo )
738 int i;
739 GLOBALARENA *pArena;
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++;
746 return TRUE;
750 /***********************************************************************
751 * GlobalEntryHandle (TOOLHELP.54)
753 BOOL16 GlobalEntryHandle( GLOBALENTRY *pGlobal, HGLOBAL16 hItem )
755 return FALSE;
759 /***********************************************************************
760 * GlobalEntryModule (TOOLHELP.55)
762 BOOL16 GlobalEntryModule( GLOBALENTRY *pGlobal, HMODULE16 hModule, WORD wSeg )
764 return FALSE;
768 /***********************************************************************
769 * MemManInfo (TOOLHELP.72)
771 BOOL16 MemManInfo( MEMMANINFO *pInfo )
773 #ifdef linux
774 /* FIXME: does not take into account the dwSize member
775 * could be corrupting memory therefore
777 /* shamefully stolen from free */
778 DWORD availmem = 0;
779 DWORD totalmem = 0;
780 FILE *meminfo;
781 char buf[80];
782 int col[5];
783 int n;
785 if ((meminfo = fopen("/proc/meminfo", "r")) < 0) {
786 perror("wine: open");
787 return FALSE;
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 */
794 totalmem += col[0];
795 availmem += col[2] + col[4];
798 fprintf(stderr,"MemManInfo called with dwSize = %ld\n",pInfo->dwSize);
799 if (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;
813 return TRUE;
814 #else
815 return TRUE;
816 #endif
820 /***********************************************************************
821 * GlobalAlloc32 (KERNEL32.315)
823 HGLOBAL32 GlobalAlloc32( UINT32 flags, DWORD size )
825 DWORD heapFlags = 0;
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 )
849 return 0;
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" );
888 return 0;
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 )
909 return TRUE;