Release 960717
[wine/multimedia.git] / memory / global.c
blobc3d66a75f1524d6182407db38df90003a5e51bc2
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 static DWORD globalDOSfree = 655350;
51 #define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000 /* Largest allocation is 16M - 64K */
53 #define GET_ARENA_PTR(handle) (pGlobalArena + ((handle) >> __AHSHIFT))
55 /***********************************************************************
56 * GLOBAL_GetArena
58 * Return the arena for a given selector, growing the arena array if needed.
60 static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount )
62 if (((sel >> __AHSHIFT) + selcount) > globalArenaSize)
64 int newsize = ((sel >> __AHSHIFT) + selcount + 0xff) & ~0xff;
65 GLOBALARENA *pNewArena = realloc( pGlobalArena,
66 newsize * sizeof(GLOBALARENA) );
67 if (!pNewArena) return 0;
68 pGlobalArena = pNewArena;
69 memset( pGlobalArena + globalArenaSize, 0,
70 (newsize - globalArenaSize) * sizeof(GLOBALARENA) );
71 globalArenaSize = newsize;
73 return pGlobalArena + (sel >> __AHSHIFT);
77 void debug_handles()
79 int printed=0;
80 int i;
81 for (i = globalArenaSize-1 ; i>=0 ; i--) {
82 if (pGlobalArena[i].size!=0 && (pGlobalArena[i].handle & 0x8000)){
83 printed=1;
84 printf("0x%08x, ",pGlobalArena[i].handle);
87 if (printed)
88 printf("\n");
92 /***********************************************************************
93 * GLOBAL_CreateBlock
95 * Create a global heap block for a fixed range of linear memory.
97 HGLOBAL16 GLOBAL_CreateBlock( WORD flags, const void *ptr, DWORD size,
98 HGLOBAL16 hOwner, BOOL16 isCode,
99 BOOL16 is32Bit, BOOL16 isReadOnly,
100 SHMDATA *shmdata )
102 WORD sel, selcount;
103 GLOBALARENA *pArena;
105 /* Allocate the selector(s) */
107 sel = SELECTOR_AllocBlock( ptr, size,
108 isCode ? SEGMENT_CODE : SEGMENT_DATA,
109 is32Bit, isReadOnly );
111 if (!sel) return 0;
112 selcount = (size + 0xffff) / 0x10000;
114 if (!(pArena = GLOBAL_GetArena( sel, selcount )))
116 FreeSelector( sel );
117 return 0;
120 /* Fill the arena block */
122 pArena->base = (DWORD)ptr;
123 pArena->size = GET_SEL_LIMIT(sel) + 1;
125 #ifdef CONFIG_IPC
126 if ((flags & GMEM_DDESHARE) && Options.ipc)
128 pArena->handle = shmdata->handle;
129 pArena->shmid = shmdata->shmid;
130 shmdata->sel = sel;
132 else
134 pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
135 pArena->shmid = 0;
137 #else
138 pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
139 #endif
140 pArena->hOwner = hOwner;
141 pArena->lockCount = 0;
142 pArena->pageLockCount = 0;
143 pArena->flags = flags & GA_MOVEABLE;
144 if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
145 if (flags & GMEM_DDESHARE) pArena->flags |= GA_IPCSHARE;
146 if (!isCode) pArena->flags |= GA_DGROUP;
147 pArena->selCount = selcount;
148 if (selcount > 1) /* clear the next arena blocks */
149 memset( pArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );
151 return pArena->handle;
155 /***********************************************************************
156 * GLOBAL_FreeBlock
158 * Free a block allocated by GLOBAL_CreateBlock, without touching
159 * the associated linear memory range.
161 BOOL16 GLOBAL_FreeBlock( HGLOBAL16 handle )
163 WORD sel;
165 if (!handle) return TRUE;
166 sel = GlobalHandleToSel( handle );
167 if (FreeSelector( sel )) return FALSE; /* failed */
168 memset( GET_ARENA_PTR(sel), 0, sizeof(GLOBALARENA) );
169 return TRUE;
173 /***********************************************************************
174 * GLOBAL_Alloc
176 * Implementation of GlobalAlloc16()
178 HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
179 BOOL16 isCode, BOOL16 is32Bit, BOOL16 isReadOnly )
181 void *ptr;
182 HGLOBAL16 handle;
183 SHMDATA shmdata;
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 );
192 /* Fixup the size */
194 if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x1f) return 0;
195 size = (size + 0x1f) & ~0x1f;
197 /* Allocate the linear memory */
199 #ifdef CONFIG_IPC
200 if ((flags & GMEM_DDESHARE) && Options.ipc)
201 ptr = DDE_malloc(flags, size, &shmdata);
202 else
203 #endif /* CONFIG_IPC */
205 ptr = HeapAlloc( SystemHeap, 0, size );
207 if (!ptr) return 0;
209 /* Allocate the selector(s) */
211 handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner,
212 isCode, is32Bit, isReadOnly, &shmdata);
213 if (!handle)
215 HeapFree( SystemHeap, 0, ptr );
216 return 0;
219 if (flags & GMEM_ZEROINIT) memset( ptr, 0, size );
220 return handle;
224 #ifdef CONFIG_IPC
225 /***********************************************************************
226 * GLOBAL_FindArena
228 * Find the arena for a given handle
229 * (when handle is not serial - e.g. DDE)
231 static GLOBALARENA *GLOBAL_FindArena( HGLOBAL handle)
233 int i;
234 for (i = globalArenaSize-1 ; i>=0 ; i--) {
235 if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == handle)
236 return ( &pGlobalArena[i] );
238 return NULL;
242 /***********************************************************************
243 * DDE_GlobalHandleToSel
246 WORD DDE_GlobalHandleToSel( HGLOBAL handle )
248 GLOBALARENA *pArena;
249 SEGPTR segptr;
251 pArena= GLOBAL_FindArena(handle);
252 if (pArena) {
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 )
285 WORD selcount;
286 DWORD oldsize;
287 void *ptr;
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;
295 #ifdef CONFIG_IPC
296 if (Options.ipc && (flags & GMEM_DDESHARE || is_dde_handle(handle))) {
297 fprintf(stdnimp,
298 "GlobalReAlloc16: shared memory reallocating unimplemented\n");
299 return 0;
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 );
313 pArena->base = 0;
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 );
317 return handle;
320 /* Fixup the size */
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;
333 return handle;
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 );
344 if (!ptr)
346 FreeSelector( sel );
347 memset( pArena, 0, sizeof(GLOBALARENA) );
348 return 0;
351 /* Reallocate the selector(s) */
353 sel = SELECTOR_ReallocBlock( sel, ptr, size, SEGMENT_DATA, 0, 0 );
354 if (!sel)
356 HeapFree( SystemHeap, 0, ptr );
357 memset( pArena, 0, sizeof(GLOBALARENA) );
358 return 0;
360 selcount = (size + 0xffff) / 0x10000;
362 if (!(pNewArena = GLOBAL_GetArena( sel, selcount )))
364 HeapFree( SystemHeap, 0, ptr );
365 FreeSelector( sel );
366 return 0;
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 */
395 #ifdef CONFIG_IPC
396 if (is_dde_handle(handle)) return DDE_GlobalFree(handle);
397 #endif /* CONFIG_IPC */
398 if (ptr) HeapFree( SystemHeap, 0, ptr );
399 return 0;
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;
414 #ifdef CONFIG_IPC
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;
432 #ifdef CONFIG_IPC
433 if (is_dde_handle(handle)) return DDE_AttachHandle(handle, NULL);
434 #endif
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 );
445 return 0;
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 )
475 GLOBALARENA *pArena;
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++;
493 return handle;
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 )
523 DWORD i;
524 GLOBALARENA *pArena;
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 * GlobalDOSAlloc (KERNEL.184)
556 * Some programs rely on failure to allocate > 640K total with this function
558 DWORD GlobalDOSAlloc( DWORD size )
560 WORD sel;
562 if (size > globalDOSfree) return 0;
563 sel = GlobalAlloc16( GMEM_FIXED, size );
565 dprintf_global( stddeb, "GlobalDOSAlloc: %08lx -> returning %04x\n",
566 size, sel );
567 if (!sel) return 0;
569 globalDOSfree -= size;
570 return MAKELONG( sel, sel /* this one ought to be a real-mode segment */ );
574 /***********************************************************************
575 * GlobalDOSFree (KERNEL.185)
577 WORD GlobalDOSFree( WORD sel )
579 GLOBALARENA *pArena = GET_ARENA_PTR(sel);
581 if (!pArena) return sel;
582 globalDOSfree += pArena->size;
583 GlobalFree16( pArena->handle );
584 return 0;
588 /***********************************************************************
589 * SetSwapAreaSize (KERNEL.106)
591 LONG SetSwapAreaSize( WORD size )
593 dprintf_global(stdnimp, "STUB: SetSwapAreaSize(%d)\n", size );
594 return MAKELONG( size, 0xffff );
598 /***********************************************************************
599 * GlobalLRUOldest (KERNEL.163)
601 HGLOBAL16 GlobalLRUOldest( HGLOBAL16 handle )
603 dprintf_global( stddeb, "GlobalLRUOldest: %04x\n", handle );
604 if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
605 return handle;
609 /***********************************************************************
610 * GlobalLRUNewest (KERNEL.164)
612 HGLOBAL16 GlobalLRUNewest( HGLOBAL16 handle )
614 dprintf_global( stddeb, "GlobalLRUNewest: %04x\n", handle );
615 if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
616 return handle;
620 /***********************************************************************
621 * GetFreeSpace (KERNEL.169)
623 DWORD GetFreeSpace( UINT16 wFlags )
625 return GLOBAL_MAX_ALLOC_SIZE;
629 /***********************************************************************
630 * GlobalPageLock (KERNEL.191)
632 WORD GlobalPageLock( HGLOBAL16 handle )
634 dprintf_global( stddeb, "GlobalPageLock: %04x\n", handle );
635 return ++(GET_ARENA_PTR(handle)->pageLockCount);
639 /***********************************************************************
640 * GlobalPageUnlock (KERNEL.192)
642 WORD GlobalPageUnlock( HGLOBAL16 handle )
644 dprintf_global( stddeb, "GlobalPageUnlock: %04x\n", handle );
645 return --(GET_ARENA_PTR(handle)->pageLockCount);
649 /***********************************************************************
650 * GlobalFix (KERNEL.197)
652 void GlobalFix( HGLOBAL16 handle )
654 dprintf_global( stddeb, "GlobalFix: %04x\n", handle );
655 GET_ARENA_PTR(handle)->lockCount++;
659 /***********************************************************************
660 * GlobalUnfix (KERNEL.198)
662 void GlobalUnfix( HGLOBAL16 handle )
664 dprintf_global( stddeb, "GlobalUnfix: %04x\n", handle );
665 GET_ARENA_PTR(handle)->lockCount--;
669 /***********************************************************************
670 * FarSetOwner (KERNEL.403)
672 void FarSetOwner( HGLOBAL16 handle, HANDLE16 hOwner )
674 GET_ARENA_PTR(handle)->hOwner = hOwner;
678 /***********************************************************************
679 * FarGetOwner (KERNEL.404)
681 HANDLE16 FarGetOwner( HGLOBAL16 handle )
683 return GET_ARENA_PTR(handle)->hOwner;
687 /***********************************************************************
688 * GlobalHandleToSel (TOOLHELP.50)
690 WORD GlobalHandleToSel( HGLOBAL16 handle )
692 dprintf_toolhelp( stddeb, "GlobalHandleToSel: %04x\n", handle );
693 if (!handle) return 0;
694 #ifdef CONFIG_IPC
695 if (is_dde_handle(handle)) return DDE_GlobalHandleToSel(handle);
696 #endif
697 if (!(handle & 7))
699 fprintf( stderr, "Program attempted invalid selector conversion\n" );
700 return handle - 1;
702 return handle | 7;
706 /***********************************************************************
707 * GlobalFirst (TOOLHELP.51)
709 BOOL16 GlobalFirst( GLOBALENTRY *pGlobal, WORD wFlags )
711 if (wFlags == GLOBAL_LRU) return FALSE;
712 pGlobal->dwNext = 0;
713 return GlobalNext( pGlobal, wFlags );
717 /***********************************************************************
718 * GlobalNext (TOOLHELP.52)
720 BOOL16 GlobalNext( GLOBALENTRY *pGlobal, WORD wFlags)
722 GLOBALARENA *pArena;
724 if (pGlobal->dwNext >= globalArenaSize) return FALSE;
725 pArena = pGlobalArena + pGlobal->dwNext;
726 if (wFlags == GLOBAL_FREE) /* only free blocks */
728 int i;
729 for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++)
730 if (pArena->size == 0) break; /* block is free */
731 if (i >= globalArenaSize) return FALSE;
732 pGlobal->dwNext = i;
735 pGlobal->dwAddress = pArena->base;
736 pGlobal->dwBlockSize = pArena->size;
737 pGlobal->hBlock = pArena->handle;
738 pGlobal->wcLock = pArena->lockCount;
739 pGlobal->wcPageLock = pArena->pageLockCount;
740 pGlobal->wFlags = (GetCurrentPDB() == pArena->hOwner);
741 pGlobal->wHeapPresent = FALSE;
742 pGlobal->hOwner = pArena->hOwner;
743 pGlobal->wType = GT_UNKNOWN;
744 pGlobal->wData = 0;
745 pGlobal->dwNext++;
746 return TRUE;
750 /***********************************************************************
751 * GlobalInfo (TOOLHELP.53)
753 BOOL16 GlobalInfo( GLOBALINFO *pInfo )
755 int i;
756 GLOBALARENA *pArena;
758 pInfo->wcItems = globalArenaSize;
759 pInfo->wcItemsFree = 0;
760 pInfo->wcItemsLRU = 0;
761 for (i = 0, pArena = pGlobalArena; i < globalArenaSize; i++, pArena++)
762 if (pArena->size == 0) pInfo->wcItemsFree++;
763 return TRUE;
767 /***********************************************************************
768 * GlobalEntryHandle (TOOLHELP.54)
770 BOOL16 GlobalEntryHandle( GLOBALENTRY *pGlobal, HGLOBAL16 hItem )
772 return FALSE;
776 /***********************************************************************
777 * GlobalEntryModule (TOOLHELP.55)
779 BOOL16 GlobalEntryModule( GLOBALENTRY *pGlobal, HMODULE16 hModule, WORD wSeg )
781 return FALSE;
785 /***********************************************************************
786 * MemManInfo (TOOLHELP.72)
788 BOOL16 MemManInfo( MEMMANINFO *pInfo )
790 #ifdef linux
791 /* FIXME: does not take into account the dwSize member
792 * could be corrupting memory therefore
794 /* shamefully stolen from free */
795 DWORD availmem = 0;
796 DWORD totalmem = 0;
797 FILE *meminfo;
798 char buf[80];
799 int col[5];
800 int n;
802 if ((meminfo = fopen("/proc/meminfo", "r")) < 0) {
803 perror("wine: open");
804 return FALSE;
807 fgets(buf, 80, meminfo); /* read first line */
808 while ( fgets(buf, 80, meminfo) ) {
809 n = sscanf( buf, "%*s %d %d %d %d %d", &col[0], &col[1], &col[2], &col[3], &col[4]);
810 if ( n < 1 ) continue; /* escape the loop at the top */
811 totalmem += col[0];
812 availmem += col[2] + col[4];
815 fprintf(stderr,"MemManInfo called with dwSize = %ld\n",pInfo->dwSize);
816 if (pInfo->dwSize) {
817 pInfo->wPageSize = getpagesize();
818 pInfo->dwLargestFreeBlock = availmem;
819 pInfo->dwTotalLinearSpace = totalmem / pInfo->wPageSize;
820 pInfo->dwMaxPagesAvailable = pInfo->dwLargestFreeBlock / pInfo->wPageSize;
821 pInfo->dwMaxPagesLockable = pInfo->dwMaxPagesLockable;
822 /* FIXME: the next three are not quite correct */
823 pInfo->dwTotalUnlockedPages = pInfo->dwMaxPagesAvailable;
824 pInfo->dwFreePages = pInfo->dwMaxPagesAvailable;
825 pInfo->dwTotalPages = pInfo->dwMaxPagesAvailable;
826 /* FIXME: the three above are not quite correct */
827 pInfo->dwFreeLinearSpace = pInfo->dwMaxPagesAvailable;
828 pInfo->dwSwapFilePages = 0L;
830 return TRUE;
831 #else
832 return TRUE;
833 #endif
837 /***********************************************************************
838 * GlobalAlloc32 (KERNEL32.315)
840 HGLOBAL32 GlobalAlloc32( UINT32 flags, DWORD size )
842 DWORD heapFlags = 0;
844 if (flags & GMEM_MOVEABLE)
845 fprintf( stderr, "GlobalAlloc32: unimplemented flag GMEM_MOVEABLE\n" );
847 if (flags & GMEM_ZEROINIT) heapFlags |= HEAP_ZERO_MEMORY;
848 return (HGLOBAL32)HeapAlloc( GetProcessHeap(), heapFlags, size );
852 /***********************************************************************
853 * GlobalCompact32 (KERNEL32.316)
855 DWORD GlobalCompact32( DWORD minfree )
857 return 0; /* GlobalCompact does nothing in Win32 */
861 /***********************************************************************
862 * GlobalFlags32 (KERNEL32.321)
864 UINT32 GlobalFlags32( HGLOBAL32 handle )
866 return 0;
870 /***********************************************************************
871 * GlobalFree32 (KERNEL32.322)
873 HGLOBAL32 GlobalFree32( HGLOBAL32 handle )
875 return HeapFree( GetProcessHeap(), 0, (LPVOID)handle ) ? 0 : handle;
879 /***********************************************************************
880 * GlobalHandle32 (KERNEL32.325)
882 HGLOBAL32 GlobalHandle32( LPCVOID ptr )
884 return (HGLOBAL32)ptr;
888 /***********************************************************************
889 * GlobalLock32 (KERNEL32.326)
891 LPVOID GlobalLock32( HGLOBAL32 handle )
893 return (LPVOID)handle;
897 /***********************************************************************
898 * GlobalReAlloc32 (KERNEL32.328)
900 HGLOBAL32 GlobalReAlloc32( HGLOBAL32 handle, DWORD size, UINT32 flags )
902 if (flags & GMEM_MODIFY)
904 fprintf( stderr, "GlobalReAlloc32: GMEM_MODIFY not supported\n" );
905 return 0;
908 return (HGLOBAL32)HeapReAlloc( GetProcessHeap(), 0, (LPVOID)handle, size );
912 /***********************************************************************
913 * GlobalSize32 (KERNEL32.329)
915 DWORD GlobalSize32( HGLOBAL32 handle )
917 return HeapSize( GetProcessHeap(), 0, (LPVOID)handle );
921 /***********************************************************************
922 * GlobalUnlock32 (KERNEL32.332)
924 BOOL32 GlobalUnlock32( HGLOBAL32 handle )
926 return TRUE;