Release 950727
[wine] / memory / global.c
1 /*
2  * Global heap functions
3  *
4  * Copyright 1995 Alexandre Julliard
5  */
6
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include "windows.h"
11 #include "global.h"
12 #include "toolhelp.h"
13 #include "selectors.h"
14 #include "dde_mem.h"
15 #include "stackframe.h"
16 #include "stddebug.h"
17 #include "debug.h"
18
19   /* Global arena block */
20 typedef struct
21 {
22     DWORD    base;           /* Base address  */
23     DWORD    size;           /* Size in bytes (0 indicates a free block) */
24     HGLOBAL  handle;         /* Handle for this block */
25     HGLOBAL  hOwner;         /* Owner of this block */
26     BYTE     lockCount;      /* Count of GlobalFix() calls */
27     BYTE     pageLockCount;  /* Count of GlobalPageLock() calls */
28     BYTE     flags;          /* Allocation flags */
29     BYTE     selCount;       /* Number of selectors allocated for this block */
30     int      shmid;
31 } GLOBALARENA;
32
33   /* Flags definitions */
34 #define GA_MOVEABLE     0x02  /* same as GMEM_MOVEABLE */
35 #define GA_DGROUP       0x04
36 #define GA_DISCARDABLE  0x08
37 #define GA_IPCSHARE     0x10  /* same as GMEM_DDESHARE */
38
39   /* Arena array */
40 static GLOBALARENA *pGlobalArena = NULL;
41 static int globalArenaSize = 0;
42
43 #define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000  /* Largest allocation is 16M - 64K */
44
45 #define GET_ARENA_PTR(handle)  (pGlobalArena + ((handle) >> __AHSHIFT))
46
47 /***********************************************************************
48  *           GLOBAL_GetArena
49  *
50  * Return the arena for a given selector, growing the arena array if needed.
51  */
52 static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount )
53 {
54     if (((sel >> __AHSHIFT) + selcount) > globalArenaSize)
55     {
56         int newsize = ((sel >> __AHSHIFT) + selcount + 0xff) & ~0xff;
57         GLOBALARENA *pNewArena = realloc( pGlobalArena,
58                                           newsize * sizeof(GLOBALARENA) );
59         if (!pNewArena) return 0;
60         pGlobalArena = pNewArena;
61         memset( pGlobalArena + globalArenaSize, 0,
62                 (newsize - globalArenaSize) * sizeof(GLOBALARENA) );
63         globalArenaSize = newsize;
64     }
65     return pGlobalArena + (sel >> __AHSHIFT);
66 }
67
68
69 void debug_handles()
70 {
71     int printed=0;
72     int i;
73     for (i = globalArenaSize-1 ; i>=0 ; i--) {
74         if (pGlobalArena[i].size!=0 && (pGlobalArena[i].handle & 0x8000)){
75             printed=1;
76             printf("0x%08x, ",pGlobalArena[i].handle);
77         }
78     }
79     if (printed)
80         printf("\n");
81 }
82 /***********************************************************************
83  *           GLOBAL_FindArena
84  *
85  * Find the arena  for a given handle
86  * (when handle is not serial - e.g. DDE)
87  */
88 static GLOBALARENA *GLOBAL_FindArena( HGLOBAL handle)
89 {
90     int i;
91     for (i = globalArenaSize-1 ; i>=0 ; i--) {
92         if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == handle)
93             return ( &pGlobalArena[i] );
94     }
95     return NULL;
96 }
97
98
99 /***********************************************************************
100  *           GLOBAL_CreateBlock
101  *
102  * Create a global heap block for a fixed range of linear memory.
103  */
104 HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
105                             HGLOBAL hOwner, BOOL isCode,
106                             BOOL is32Bit, BOOL isReadOnly,
107                             SHMDATA *shmdata  )
108 {
109     WORD sel, selcount;
110     GLOBALARENA *pArena;
111
112       /* Allocate the selector(s) */
113
114     sel = SELECTOR_AllocBlock( ptr, size,
115                               isCode ? SEGMENT_CODE : SEGMENT_DATA,
116                               is32Bit, isReadOnly );
117     
118     if (!sel) return 0;
119     selcount = (size + 0xffff) / 0x10000;
120
121     if (!(pArena = GLOBAL_GetArena( sel, selcount )))
122     {
123         FreeSelector( sel );
124         return 0;
125     }
126
127       /* Fill the arena block */
128
129     pArena->base = (DWORD)ptr;
130     pArena->size = GET_SEL_LIMIT(sel) + 1;
131     if (flags & GMEM_DDESHARE)
132     {
133         pArena->handle = shmdata->handle;
134         pArena->shmid  = shmdata->shmid;
135         shmdata->sel   = sel;
136     }
137     else
138     {
139         pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
140         pArena->shmid  = 0;
141     }
142     pArena->hOwner = hOwner;
143     pArena->lockCount = 0;
144     pArena->pageLockCount = 0;
145     pArena->flags = flags & GA_MOVEABLE;
146     if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
147     if (flags & GMEM_DDESHARE) pArena->flags |= GA_IPCSHARE;
148     if (!isCode) pArena->flags |= GA_DGROUP;
149     pArena->selCount = selcount;
150     if (selcount > 1)  /* clear the next arena blocks */
151         memset( pArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );
152
153     return pArena->handle;
154 }
155
156
157 /***********************************************************************
158  *           GLOBAL_FreeBlock
159  *
160  * Free a block allocated by GLOBAL_CreateBlock, without touching
161  * the associated linear memory range.
162  */
163 BOOL GLOBAL_FreeBlock( HGLOBAL handle )
164 {
165     WORD sel;
166
167     if (!handle) return TRUE;
168     sel = GlobalHandleToSel( handle );
169     if (FreeSelector( sel )) return FALSE;  /* failed */
170     memset( GET_ARENA_PTR(sel), 0, sizeof(GLOBALARENA) );
171     return TRUE;
172 }
173
174
175 /***********************************************************************
176  *           GLOBAL_Alloc
177  *
178  * Implementation of GlobalAlloc()
179  */
180 HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner,
181                       BOOL isCode, BOOL is32Bit, BOOL isReadOnly )
182 {
183     void *ptr;
184     HGLOBAL handle;
185     SHMDATA shmdata;
186
187     dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags );
188
189       /* Fixup the size */
190
191     if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x1f) return 0;
192     if (size == 0) size = 0x20;
193     else size = (size + 0x1f) & ~0x1f;
194
195       /* Allocate the linear memory */
196
197     if (flags & GMEM_DDESHARE) 
198         ptr= DDE_malloc(flags, size, &shmdata);
199     else 
200         ptr = malloc( size );
201     if (!ptr) return 0;
202
203       /* Allocate the selector(s) */
204
205     handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner,
206                                 isCode, is32Bit, isReadOnly, &shmdata);
207     if (!handle)
208     {
209         free( ptr );
210         return 0;
211     }
212
213     if (flags & GMEM_ZEROINIT) memset( ptr, 0, size );
214     return handle;
215 }
216
217 /***********************************************************************
218  *           DDE_GlobalHandleToSel
219  */
220
221 WORD DDE_GlobalHandleToSel( HGLOBAL handle )
222 {
223     GLOBALARENA *pArena;
224     SEGPTR segptr;
225     
226     pArena= GLOBAL_FindArena(handle);
227     if (pArena) {
228         int ArenaIdx = pArena - pGlobalArena;
229
230         /* See if synchronized to the shared memory  */
231         return DDE_SyncHandle(handle, ( ArenaIdx << __AHSHIFT) | 7);
232     }
233
234     /* attach the block */
235     DDE_AttachHandle(handle, &segptr);
236
237     return SELECTOROF( segptr );
238 }
239
240
241 /***********************************************************************
242  *           GlobalAlloc   (KERNEL.15)
243  */
244 HGLOBAL GlobalAlloc( WORD flags, DWORD size )
245 {
246     HANDLE owner = GetCurrentPDB();
247
248     if (flags & GMEM_DDESHARE)
249         owner = GetExePtr(owner);  /* Make it a module handle */
250     return GLOBAL_Alloc( flags, size, owner, FALSE, FALSE, FALSE );
251 }
252
253
254 /***********************************************************************
255  *           GlobalReAlloc   (KERNEL.16)
256  */
257 HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
258 {
259     WORD selcount;
260     DWORD oldsize;
261     void *ptr;
262     GLOBALARENA *pArena, *pNewArena;
263     WORD sel = GlobalHandleToSel( handle );
264
265     dprintf_global( stddeb, "GlobalReAlloc: %04x %ld flags=%04x\n",
266                     handle, size, flags );
267     if (!handle) return 0;
268     
269     if (flags & GMEM_DDESHARE || is_dde_handle(handle)) {
270         fprintf(stdnimp,
271                 "GlobalReAlloc: shared memory reallocating unimplemented\n"); 
272         return 0;
273     }
274
275     pArena = GET_ARENA_PTR( handle );
276
277       /* Discard the block if requested */
278
279     if ((size == 0) && (flags & GMEM_MOVEABLE) && !(flags & GMEM_MODIFY))
280     {
281         if (!(pArena->flags & GA_MOVEABLE) ||
282             !(pArena->flags & GA_DISCARDABLE) ||
283             (pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
284         free( (void *)pArena->base );
285         pArena->base = 0;
286         /* Note: we rely on the fact that SELECTOR_ReallocBlock won't */
287         /* change the selector if we are shrinking the block */
288         SELECTOR_ReallocBlock( sel, 0, 1, SEGMENT_DATA, 0, 0 );
289         return handle;
290     }
291
292       /* Fixup the size */
293
294     if (size > GLOBAL_MAX_ALLOC_SIZE - 0x20) return 0;
295     if (size == 0) size = 0x20;
296     else size = (size + 0x1f) & ~0x1f;
297
298       /* Change the flags */
299
300     if (flags & GMEM_MODIFY)
301     {
302           /* Change the flags, leaving GA_DGROUP alone */
303         pArena->flags = (pArena->flags & GA_DGROUP) | (flags & GA_MOVEABLE);
304         if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
305         return handle;
306     }
307
308       /* Reallocate the linear memory */
309
310     ptr = (void *)pArena->base;
311     oldsize = pArena->size;
312     dprintf_global(stddeb,"oldsize %08lx\n",oldsize);
313     if (size == oldsize) return handle;  /* Nothing to do */
314
315     ptr = realloc( ptr, size );
316     if (!ptr)
317     {
318         FreeSelector( sel );
319         memset( pArena, 0, sizeof(GLOBALARENA) );
320         return 0;
321     }
322
323       /* Reallocate the selector(s) */
324
325     sel = SELECTOR_ReallocBlock( sel, ptr, size, SEGMENT_DATA, 0, 0 );
326     if (!sel)
327     {
328         free( ptr );
329         memset( pArena, 0, sizeof(GLOBALARENA) );
330         return 0;
331     }
332     selcount = (size + 0xffff) / 0x10000;
333
334     if (!(pNewArena = GLOBAL_GetArena( sel, selcount )))
335     {
336         free( ptr );
337         FreeSelector( sel );
338         return 0;
339     }
340
341       /* Fill the new arena block */
342
343     if (pNewArena != pArena) memcpy( pNewArena, pArena, sizeof(GLOBALARENA) );
344     pNewArena->base = (DWORD)ptr;
345     pNewArena->size = GET_SEL_LIMIT(sel) + 1;
346     pNewArena->selCount = selcount;
347     pNewArena->handle = (pNewArena->flags & GA_MOVEABLE) ? sel - 1 : sel;
348
349     if (selcount > 1)  /* clear the next arena blocks */
350         memset( pNewArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );
351
352     if ((oldsize < size) && (flags & GMEM_ZEROINIT))
353         memset( (char *)ptr + oldsize, 0, size - oldsize );
354     return pNewArena->handle;
355 }
356
357
358 /***********************************************************************
359  *           GlobalFree   (KERNEL.17)
360  */
361 HGLOBAL GlobalFree( HGLOBAL handle )
362 {
363     void *ptr = GlobalLock( handle );
364
365     dprintf_global( stddeb, "GlobalFree: %04x\n", handle );
366     if (!GLOBAL_FreeBlock( handle )) return handle;  /* failed */
367     if (is_dde_handle(handle)) return DDE_GlobalFree(handle);
368     if (ptr) free( ptr );
369     return 0;
370 }
371
372
373 /***********************************************************************
374  *           WIN16_GlobalLock   (KERNEL.18)
375  *
376  * This is the GlobalLock() function used by 16-bit code.
377  */
378 SEGPTR WIN16_GlobalLock( HGLOBAL handle )
379 {
380     dprintf_global( stddeb, "WIN16_GlobalLock(%04x) -> %08lx\n",
381                     handle, MAKELONG( 0, GlobalHandleToSel(handle)) );
382     if (!handle) return 0;
383     if ( !is_dde_handle(handle) && !GET_ARENA_PTR(handle)->base)
384         return (SEGPTR)0;
385
386     return (SEGPTR)MAKELONG( 0, GlobalHandleToSel(handle) );
387 }
388
389
390 /***********************************************************************
391  *           GlobalLock   (KERNEL.18)
392  *
393  * This is the GlobalLock() function used by 32-bit code.
394  */
395 LPSTR GlobalLock( HGLOBAL handle )
396 {
397     if (!handle) return 0;
398     if (is_dde_handle(handle)) {
399        return DDE_AttachHandle(handle, NULL);
400     }
401     return (LPSTR)GET_ARENA_PTR(handle)->base;
402 }
403
404
405 /***********************************************************************
406  *           GlobalUnlock   (KERNEL.19)
407  */
408 BOOL GlobalUnlock( HGLOBAL handle )
409 {
410     dprintf_global( stddeb, "GlobalUnlock: %04x\n", handle );
411     return 0;
412 }
413
414
415 /***********************************************************************
416  *           GlobalSize   (KERNEL.20)
417  */
418 DWORD GlobalSize( HGLOBAL handle )
419 {
420     dprintf_global( stddeb, "GlobalSize: %04x\n", handle );
421     if (!handle) return 0;
422     return GET_ARENA_PTR(handle)->size;
423 }
424
425
426 /***********************************************************************
427  *           GlobalHandle   (KERNEL.21)
428  */
429 DWORD GlobalHandle( WORD sel )
430 {
431     dprintf_global( stddeb, "GlobalHandle: %04x\n", sel );
432     return MAKELONG( GET_ARENA_PTR(sel)->handle, sel );
433 }
434
435
436 /***********************************************************************
437  *           GlobalFlags   (KERNEL.22)
438  */
439 WORD GlobalFlags( HGLOBAL handle )
440 {
441     GLOBALARENA *pArena;
442
443     dprintf_global( stddeb, "GlobalFlags: %04x\n", handle );
444     pArena = GET_ARENA_PTR(handle);
445     return pArena->lockCount |
446            ((pArena->flags & GA_DISCARDABLE) ? GMEM_DISCARDABLE : 0) |
447            ((pArena->base == 0) ? GMEM_DISCARDED : 0);
448 }
449
450
451 /***********************************************************************
452  *           LockSegment   (KERNEL.23)
453  */
454 HGLOBAL LockSegment( HGLOBAL handle )
455 {
456     dprintf_global( stddeb, "LockSegment: %04x\n", handle );
457     if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
458     GET_ARENA_PTR(handle)->lockCount++;
459     return handle;
460 }
461
462
463 /***********************************************************************
464  *           UnlockSegment   (KERNEL.24)
465  */
466 void UnlockSegment( HGLOBAL handle )
467 {
468     dprintf_global( stddeb, "UnlockSegment: %04x\n", handle );
469     if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
470     GET_ARENA_PTR(handle)->lockCount--;
471     /* FIXME: this ought to return the lock count in CX (go figure...) */
472 }
473
474
475 /***********************************************************************
476  *           GlobalCompact   (KERNEL.25)
477  */
478 DWORD GlobalCompact( DWORD desired )
479 {
480     return GLOBAL_MAX_ALLOC_SIZE;
481 }
482
483
484 /***********************************************************************
485  *           GlobalFreeAll   (KERNEL.26)
486  */
487 void GlobalFreeAll( HANDLE owner )
488 {
489     DWORD i;
490     GLOBALARENA *pArena;
491
492     pArena = pGlobalArena;
493     for (i = 0; i < globalArenaSize; i++, pArena++)
494     {
495         if ((pArena->size != 0) && (pArena->hOwner == owner))
496             GlobalFree( pArena->handle );
497     }
498 }
499
500
501 /***********************************************************************
502  *           GlobalWire   (KERNEL.111)
503  */
504 SEGPTR GlobalWire( HGLOBAL handle )
505 {
506     return WIN16_GlobalLock( handle );
507 }
508
509
510 /***********************************************************************
511  *           GlobalUnWire   (KERNEL.112)
512  */
513 BOOL GlobalUnWire( HGLOBAL handle )
514 {
515     return GlobalUnlock( handle );
516 }
517
518
519 /***********************************************************************
520  *           GlobalDOSAlloc   (KERNEL.184)
521  */
522 DWORD GlobalDOSAlloc( DWORD size )
523 {
524     WORD sel = GlobalAlloc( GMEM_FIXED, size );
525     if (!sel) return 0;
526     return MAKELONG( sel, sel /* this one ought to be a real-mode segment */ );
527 }
528
529
530 /***********************************************************************
531  *           GlobalDOSFree   (KERNEL.185)
532  */
533 WORD GlobalDOSFree( WORD sel )
534 {
535     return GlobalFree( GlobalHandle(sel) ) ? sel : 0;
536 }
537
538
539 /***********************************************************************
540  *           SetSwapAreaSize   (KERNEL.106)
541  */
542 LONG SetSwapAreaSize( WORD size )
543 {
544     dprintf_global(stdnimp, "STUB: SetSwapAreaSize(%d)\n", size );
545     return MAKELONG( size, 0xffff );
546 }
547
548
549 /***********************************************************************
550  *           GlobalLRUOldest   (KERNEL.163)
551  */
552 HGLOBAL GlobalLRUOldest( HGLOBAL handle )
553 {
554     dprintf_global( stddeb, "GlobalLRUOldest: %04x\n", handle );
555     if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
556     return handle;
557 }
558
559
560 /***********************************************************************
561  *           GlobalLRUNewest   (KERNEL.164)
562  */
563 HGLOBAL GlobalLRUNewest( HGLOBAL handle )
564 {
565     dprintf_global( stddeb, "GlobalLRUNewest: %04x\n", handle );
566     if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
567     return handle;
568 }
569
570
571 /***********************************************************************
572  *           GetFreeSpace   (KERNEL.169)
573  */
574 DWORD GetFreeSpace( UINT wFlags )
575 {
576     return GLOBAL_MAX_ALLOC_SIZE;
577 }
578
579
580 /***********************************************************************
581  *           GlobalPageLock   (KERNEL.191)
582  */
583 WORD GlobalPageLock( HGLOBAL handle )
584 {
585     dprintf_global( stddeb, "GlobalPageLock: %04x\n", handle );
586     return ++(GET_ARENA_PTR(handle)->pageLockCount);
587 }
588
589
590 /***********************************************************************
591  *           GlobalPageUnlock   (KERNEL.192)
592  */
593 WORD GlobalPageUnlock( HGLOBAL handle )
594 {
595     dprintf_global( stddeb, "GlobalPageUnlock: %04x\n", handle );
596     return --(GET_ARENA_PTR(handle)->pageLockCount);
597 }
598
599
600 /***********************************************************************
601  *           GlobalFix   (KERNEL.197)
602  */
603 void GlobalFix( HGLOBAL handle )
604 {
605     dprintf_global( stddeb, "GlobalFix: %04x\n", handle );
606     GET_ARENA_PTR(handle)->lockCount++;
607 }
608
609
610 /***********************************************************************
611  *           GlobalUnfix   (KERNEL.198)
612  */
613 void GlobalUnfix( HGLOBAL handle )
614 {
615     dprintf_global( stddeb, "GlobalUnfix: %04x\n", handle );
616     GET_ARENA_PTR(handle)->lockCount--;
617 }
618
619
620 /***********************************************************************
621  *           FarSetOwner   (KERNEL.403)
622  */
623 void FarSetOwner( HANDLE handle, WORD hOwner )
624 {
625     GET_ARENA_PTR(handle)->hOwner = hOwner;
626 }
627
628
629 /***********************************************************************
630  *           FarGetOwner   (KERNEL.404)
631  */
632 WORD FarGetOwner( HANDLE handle )
633 {
634     return GET_ARENA_PTR(handle)->hOwner;
635 }
636
637
638 /***********************************************************************
639  *           GlobalHandleToSel   (TOOLHELP.50)
640  */
641 WORD GlobalHandleToSel( HGLOBAL handle )
642 {
643     dprintf_toolhelp( stddeb, "GlobalHandleToSel: %04x\n", handle );
644     if (!handle) return 0;
645     if (is_dde_handle(handle)) 
646         return DDE_GlobalHandleToSel(handle);
647
648     if (!(handle & 7))
649     {
650         fprintf( stderr, "Program attempted invalid selector conversion\n" );
651         return handle - 1;
652     }
653     return handle | 7;
654 }
655
656
657 /***********************************************************************
658  *           GlobalFirst   (TOOLHELP.51)
659  */
660 BOOL GlobalFirst( GLOBALENTRY *pGlobal, WORD wFlags )
661 {
662     if (wFlags == GLOBAL_LRU) return FALSE;
663     pGlobal->dwNext = 0;
664     return GlobalNext( pGlobal, wFlags );
665 }
666
667
668 /***********************************************************************
669  *           GlobalNext   (TOOLHELP.52)
670  */
671 BOOL GlobalNext( GLOBALENTRY *pGlobal, WORD wFlags)
672 {
673     GLOBALARENA *pArena;
674
675     if (pGlobal->dwNext >= globalArenaSize) return FALSE;
676     pArena = pGlobalArena + pGlobal->dwNext;
677     if (wFlags == GLOBAL_FREE)  /* only free blocks */
678     {
679         int i;
680         for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++)
681             if (pArena->size == 0) break;  /* block is free */
682         if (i >= globalArenaSize) return FALSE;
683         pGlobal->dwNext = i;
684     }
685
686     pGlobal->dwAddress    = pArena->base;
687     pGlobal->dwBlockSize  = pArena->size;
688     pGlobal->hBlock       = pArena->handle;
689     pGlobal->wcLock       = pArena->lockCount;
690     pGlobal->wcPageLock   = pArena->pageLockCount;
691     pGlobal->wFlags       = (GetCurrentPDB() == pArena->hOwner);
692     pGlobal->wHeapPresent = FALSE;
693     pGlobal->hOwner       = pArena->hOwner;
694     pGlobal->wType        = GT_UNKNOWN;
695     pGlobal->wData        = 0;
696     pGlobal->dwNext++;
697     return TRUE;
698 }
699
700
701 /***********************************************************************
702  *           GlobalInfo   (TOOLHELP.53)
703  */
704 BOOL GlobalInfo( GLOBALINFO *pInfo )
705 {
706     int i;
707     GLOBALARENA *pArena;
708
709     pInfo->wcItems = globalArenaSize;
710     pInfo->wcItemsFree = 0;
711     pInfo->wcItemsLRU = 0;
712     for (i = 0, pArena = pGlobalArena; i < globalArenaSize; i++, pArena++)
713         if (pArena->size == 0) pInfo->wcItemsFree++;
714     return TRUE;
715 }
716
717
718 /***********************************************************************
719  *           GlobalEntryHandle   (TOOLHELP.54)
720  */
721 BOOL GlobalEntryHandle( GLOBALENTRY *pGlobal, HGLOBAL hItem )
722 {
723     return FALSE;
724 }
725
726
727 /***********************************************************************
728  *           GlobalEntryModule   (TOOLHELP.55)
729  */
730 BOOL GlobalEntryModule( GLOBALENTRY *pGlobal, HMODULE hModule, WORD wSeg )
731 {
732     return FALSE;
733 }
734
735
736 /***********************************************************************
737  *           MemManInfo   (TOOLHELP.72)
738  */
739 BOOL MemManInfo( MEMMANINFO *pInfo )
740 {
741     return TRUE;
742 }
743
744 /***********************************************************************
745  *               GlobalAlloc32
746  * implements    GlobalAlloc        (KERNEL32.316)
747  *               LocalAlloc         (KERNEL32.372)
748  */
749 void *GlobalAlloc32(int flags,int size)
750 {
751     dprintf_global(stddeb,"GlobalAlloc32(%x,%x)\n",flags,size);
752     return malloc(size);
753 }