Release 960528
[wine/gsoc-2012-control.git] / memory / global.c
blobc8e4d5d1f5073c3fa8908a78bf5241bd7379a421
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, BOOL isCode,
97 BOOL is32Bit, BOOL 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 BOOL 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 BOOL isCode, BOOL is32Bit, BOOL 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 #ifndef WINELIB
409 dprintf_global( stddeb, "WIN16_GlobalLock16(%04x) -> %08lx\n",
410 handle, MAKELONG( 0, GlobalHandleToSel(handle)) );
411 if (!handle) return 0;
413 #ifdef CONFIG_IPC
414 if (is_dde_handle(handle))
415 return PTR_SEG_OFF_TO_SEGPTR( DDE_GlobalHandleToSel(handle), 0 );
416 #endif /* CONFIG_IPC */
418 if (!GET_ARENA_PTR(handle)->base) return (SEGPTR)0;
419 return PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(handle), 0 );
420 #else /* WINELIB */
421 return GlobalLock16( handle );
422 #endif /* WINELIB */
426 /***********************************************************************
427 * GlobalLock16 (KERNEL.18)
429 * This is the GlobalLock16() function used by 32-bit code.
431 LPVOID GlobalLock16( HGLOBAL16 handle )
433 if (!handle) return 0;
434 #ifdef CONFIG_IPC
435 if (is_dde_handle(handle)) return DDE_AttachHandle(handle, NULL);
436 #endif
437 return (LPVOID)GET_ARENA_PTR(handle)->base;
441 /***********************************************************************
442 * GlobalUnlock16 (KERNEL.19)
444 BOOL16 GlobalUnlock16( HGLOBAL16 handle )
446 dprintf_global( stddeb, "GlobalUnlock16: %04x\n", handle );
447 return 0;
451 /***********************************************************************
452 * GlobalSize16 (KERNEL.20)
454 DWORD GlobalSize16( HGLOBAL16 handle )
456 dprintf_global( stddeb, "GlobalSize16: %04x\n", handle );
457 if (!handle) return 0;
458 return GET_ARENA_PTR(handle)->size;
462 /***********************************************************************
463 * GlobalHandle16 (KERNEL.21)
465 DWORD GlobalHandle16( WORD sel )
467 dprintf_global( stddeb, "GlobalHandle16: %04x\n", sel );
468 return MAKELONG( GET_ARENA_PTR(sel)->handle, GlobalHandleToSel(sel) );
472 /***********************************************************************
473 * GlobalFlags16 (KERNEL.22)
475 UINT16 GlobalFlags16( HGLOBAL16 handle )
477 GLOBALARENA *pArena;
479 dprintf_global( stddeb, "GlobalFlags16: %04x\n", handle );
480 pArena = GET_ARENA_PTR(handle);
481 return pArena->lockCount |
482 ((pArena->flags & GA_DISCARDABLE) ? GMEM_DISCARDABLE : 0) |
483 ((pArena->base == 0) ? GMEM_DISCARDED : 0);
487 /***********************************************************************
488 * LockSegment (KERNEL.23)
490 HGLOBAL LockSegment( HGLOBAL handle )
492 dprintf_global( stddeb, "LockSegment: %04x\n", handle );
493 if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
494 GET_ARENA_PTR(handle)->lockCount++;
495 return handle;
499 /***********************************************************************
500 * UnlockSegment (KERNEL.24)
502 void UnlockSegment( HGLOBAL handle )
504 dprintf_global( stddeb, "UnlockSegment: %04x\n", handle );
505 if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
506 GET_ARENA_PTR(handle)->lockCount--;
507 /* FIXME: this ought to return the lock count in CX (go figure...) */
511 /***********************************************************************
512 * GlobalCompact16 (KERNEL.25)
514 DWORD GlobalCompact16( DWORD desired )
516 return GLOBAL_MAX_ALLOC_SIZE;
520 /***********************************************************************
521 * GlobalFreeAll (KERNEL.26)
523 void GlobalFreeAll( HGLOBAL16 owner )
525 DWORD i;
526 GLOBALARENA *pArena;
528 pArena = pGlobalArena;
529 for (i = 0; i < globalArenaSize; i++, pArena++)
531 if ((pArena->size != 0) && (pArena->hOwner == owner))
532 GlobalFree16( pArena->handle );
537 /***********************************************************************
538 * GlobalWire (KERNEL.111)
540 SEGPTR GlobalWire( HGLOBAL16 handle )
542 return WIN16_GlobalLock16( handle );
546 /***********************************************************************
547 * GlobalUnWire (KERNEL.112)
549 BOOL GlobalUnWire( HGLOBAL16 handle )
551 return GlobalUnlock16( handle );
555 /***********************************************************************
556 * GlobalDOSAlloc (KERNEL.184)
558 DWORD GlobalDOSAlloc( DWORD size )
560 WORD sel = GlobalAlloc16( GMEM_FIXED, size );
561 if (!sel) return 0;
562 return MAKELONG( sel, sel /* this one ought to be a real-mode segment */ );
566 /***********************************************************************
567 * GlobalDOSFree (KERNEL.185)
569 WORD GlobalDOSFree( WORD sel )
571 return GlobalFree16( GlobalHandle16(sel) ) ? sel : 0;
575 /***********************************************************************
576 * SetSwapAreaSize (KERNEL.106)
578 LONG SetSwapAreaSize( WORD size )
580 dprintf_global(stdnimp, "STUB: SetSwapAreaSize(%d)\n", size );
581 return MAKELONG( size, 0xffff );
585 /***********************************************************************
586 * GlobalLRUOldest (KERNEL.163)
588 HGLOBAL16 GlobalLRUOldest( HGLOBAL16 handle )
590 dprintf_global( stddeb, "GlobalLRUOldest: %04x\n", handle );
591 if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
592 return handle;
596 /***********************************************************************
597 * GlobalLRUNewest (KERNEL.164)
599 HGLOBAL16 GlobalLRUNewest( HGLOBAL16 handle )
601 dprintf_global( stddeb, "GlobalLRUNewest: %04x\n", handle );
602 if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
603 return handle;
607 /***********************************************************************
608 * GetFreeSpace (KERNEL.169)
610 DWORD GetFreeSpace( UINT16 wFlags )
612 return GLOBAL_MAX_ALLOC_SIZE;
616 /***********************************************************************
617 * GlobalPageLock (KERNEL.191)
619 WORD GlobalPageLock( HGLOBAL16 handle )
621 dprintf_global( stddeb, "GlobalPageLock: %04x\n", handle );
622 return ++(GET_ARENA_PTR(handle)->pageLockCount);
626 /***********************************************************************
627 * GlobalPageUnlock (KERNEL.192)
629 WORD GlobalPageUnlock( HGLOBAL16 handle )
631 dprintf_global( stddeb, "GlobalPageUnlock: %04x\n", handle );
632 return --(GET_ARENA_PTR(handle)->pageLockCount);
636 /***********************************************************************
637 * GlobalFix (KERNEL.197)
639 void GlobalFix( HGLOBAL16 handle )
641 dprintf_global( stddeb, "GlobalFix: %04x\n", handle );
642 GET_ARENA_PTR(handle)->lockCount++;
646 /***********************************************************************
647 * GlobalUnfix (KERNEL.198)
649 void GlobalUnfix( HGLOBAL16 handle )
651 dprintf_global( stddeb, "GlobalUnfix: %04x\n", handle );
652 GET_ARENA_PTR(handle)->lockCount--;
656 /***********************************************************************
657 * FarSetOwner (KERNEL.403)
659 void FarSetOwner( HANDLE handle, HANDLE hOwner )
661 GET_ARENA_PTR(handle)->hOwner = hOwner;
665 /***********************************************************************
666 * FarGetOwner (KERNEL.404)
668 WORD FarGetOwner( HANDLE handle )
670 return GET_ARENA_PTR(handle)->hOwner;
674 /***********************************************************************
675 * GlobalHandleToSel (TOOLHELP.50)
677 WORD GlobalHandleToSel( HGLOBAL16 handle )
679 dprintf_toolhelp( stddeb, "GlobalHandleToSel: %04x\n", handle );
680 if (!handle) return 0;
681 #ifdef CONFIG_IPC
682 if (is_dde_handle(handle)) return DDE_GlobalHandleToSel(handle);
683 #endif
684 if (!(handle & 7))
686 fprintf( stderr, "Program attempted invalid selector conversion\n" );
687 return handle - 1;
689 return handle | 7;
693 /***********************************************************************
694 * GlobalFirst (TOOLHELP.51)
696 BOOL GlobalFirst( GLOBALENTRY *pGlobal, WORD wFlags )
698 if (wFlags == GLOBAL_LRU) return FALSE;
699 pGlobal->dwNext = 0;
700 return GlobalNext( pGlobal, wFlags );
704 /***********************************************************************
705 * GlobalNext (TOOLHELP.52)
707 BOOL GlobalNext( GLOBALENTRY *pGlobal, WORD wFlags)
709 GLOBALARENA *pArena;
711 if (pGlobal->dwNext >= globalArenaSize) return FALSE;
712 pArena = pGlobalArena + pGlobal->dwNext;
713 if (wFlags == GLOBAL_FREE) /* only free blocks */
715 int i;
716 for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++)
717 if (pArena->size == 0) break; /* block is free */
718 if (i >= globalArenaSize) return FALSE;
719 pGlobal->dwNext = i;
722 pGlobal->dwAddress = pArena->base;
723 pGlobal->dwBlockSize = pArena->size;
724 pGlobal->hBlock = pArena->handle;
725 pGlobal->wcLock = pArena->lockCount;
726 pGlobal->wcPageLock = pArena->pageLockCount;
727 pGlobal->wFlags = (GetCurrentPDB() == pArena->hOwner);
728 pGlobal->wHeapPresent = FALSE;
729 pGlobal->hOwner = pArena->hOwner;
730 pGlobal->wType = GT_UNKNOWN;
731 pGlobal->wData = 0;
732 pGlobal->dwNext++;
733 return TRUE;
737 /***********************************************************************
738 * GlobalInfo (TOOLHELP.53)
740 BOOL GlobalInfo( GLOBALINFO *pInfo )
742 int i;
743 GLOBALARENA *pArena;
745 pInfo->wcItems = globalArenaSize;
746 pInfo->wcItemsFree = 0;
747 pInfo->wcItemsLRU = 0;
748 for (i = 0, pArena = pGlobalArena; i < globalArenaSize; i++, pArena++)
749 if (pArena->size == 0) pInfo->wcItemsFree++;
750 return TRUE;
754 /***********************************************************************
755 * GlobalEntryHandle (TOOLHELP.54)
757 BOOL GlobalEntryHandle( GLOBALENTRY *pGlobal, HGLOBAL16 hItem )
759 return FALSE;
763 /***********************************************************************
764 * GlobalEntryModule (TOOLHELP.55)
766 BOOL GlobalEntryModule( GLOBALENTRY *pGlobal, HMODULE16 hModule, WORD wSeg )
768 return FALSE;
772 /***********************************************************************
773 * MemManInfo (TOOLHELP.72)
775 BOOL MemManInfo( MEMMANINFO *pInfo )
777 #ifdef linux
778 /* FIXME: does not take into account the dwSize member
779 * could be corrupting memory therefore
781 /* shamefully stolen from free */
782 DWORD availmem = 0;
783 DWORD totalmem = 0;
784 FILE *meminfo;
785 char buf[80];
786 int col[5];
787 int n;
789 if ((meminfo = fopen("/proc/meminfo", "r")) < 0) {
790 perror("wine: open");
791 return FALSE;
794 fgets(buf, 80, meminfo); /* read first line */
795 while ( fgets(buf, 80, meminfo) ) {
796 n = sscanf( buf, "%*s %d %d %d %d %d", &col[0], &col[1], &col[2], &col[3], &col[4]);
797 if ( n < 1 ) continue; /* escape the loop at the top */
798 totalmem += col[0];
799 availmem += col[2] + col[4];
802 fprintf(stderr,"MemManInfo called with dwSize = %ld\n",pInfo->dwSize);
803 if (pInfo->dwSize) {
804 pInfo->wPageSize = getpagesize();
805 pInfo->dwLargestFreeBlock = availmem;
806 pInfo->dwTotalLinearSpace = totalmem / pInfo->wPageSize;
807 pInfo->dwMaxPagesAvailable = pInfo->dwLargestFreeBlock / pInfo->wPageSize;
808 pInfo->dwMaxPagesLockable = pInfo->dwMaxPagesLockable;
809 /* FIXME: the next three are not quite correct */
810 pInfo->dwTotalUnlockedPages = pInfo->dwMaxPagesAvailable;
811 pInfo->dwFreePages = pInfo->dwMaxPagesAvailable;
812 pInfo->dwTotalPages = pInfo->dwMaxPagesAvailable;
813 /* FIXME: the three above are not quite correct */
814 pInfo->dwFreeLinearSpace = pInfo->dwMaxPagesAvailable;
815 pInfo->dwSwapFilePages = 0L;
817 return TRUE;
818 #else
819 return TRUE;
820 #endif
824 /***********************************************************************
825 * GlobalAlloc32 (KERNEL32.315)
827 HGLOBAL32 GlobalAlloc32( UINT32 flags, DWORD size )
829 DWORD heapFlags = 0;
831 if (flags & GMEM_MOVEABLE)
832 fprintf( stderr, "GlobalAlloc32: unimplemented flag GMEM_MOVEABLE\n" );
834 if (flags & GMEM_ZEROINIT) heapFlags |= HEAP_ZERO_MEMORY;
835 return (HGLOBAL32)HeapAlloc( GetProcessHeap(), heapFlags, size );
839 /***********************************************************************
840 * GlobalCompact32 (KERNEL32.316)
842 DWORD GlobalCompact32( DWORD minfree )
844 return 0; /* GlobalCompact does nothing in Win32 */
848 /***********************************************************************
849 * GlobalFlags32 (KERNEL32.321)
851 UINT32 GlobalFlags32( HGLOBAL32 handle )
853 return 0;
857 /***********************************************************************
858 * GlobalFree32 (KERNEL32.322)
860 HGLOBAL32 GlobalFree32( HGLOBAL32 handle )
862 return HeapFree( GetProcessHeap(), 0, (LPVOID)handle ) ? 0 : handle;
866 /***********************************************************************
867 * GlobalHandle32 (KERNEL32.325)
869 HGLOBAL32 GlobalHandle32( LPCVOID ptr )
871 return (HGLOBAL32)ptr;
875 /***********************************************************************
876 * GlobalLock32 (KERNEL32.326)
878 LPVOID GlobalLock32( HGLOBAL32 handle )
880 return (LPVOID)handle;
884 /***********************************************************************
885 * GlobalReAlloc32 (KERNEL32.328)
887 HGLOBAL32 GlobalReAlloc32( HGLOBAL32 handle, DWORD size, UINT32 flags )
889 if (flags & GMEM_MODIFY)
891 fprintf( stderr, "GlobalReAlloc32: GMEM_MODIFY not supported\n" );
892 return 0;
895 return (HGLOBAL32)HeapReAlloc( GetProcessHeap(), 0, (LPVOID)handle, size );
899 /***********************************************************************
900 * GlobalSize32 (KERNEL32.329)
902 DWORD GlobalSize32( HGLOBAL32 handle )
904 return HeapSize( GetProcessHeap(), 0, (LPVOID)handle );
908 /***********************************************************************
909 * GlobalUnlock32 (KERNEL32.332)
911 BOOL32 GlobalUnlock32( HGLOBAL32 handle )
913 return TRUE;