source: trunk/src/kernel32/heap.cpp@ 7007

Last change on this file since 7007 was 7005, checked in by phaller, 24 years ago

profile compatibility

File size: 30.3 KB
Line 
1/* $Id: heap.cpp,v 1.35 2001-10-10 22:25:34 phaller Exp $ */
2
3/*
4 * Win32 heap API functions for OS/2
5 *
6 * Copyright 1999-2001 Sander van Leeuwen
7 *
8 * Global memory functions ported from Wine
9 * Copyright 1995 Alexandre Julliard
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14
15#include <os2win.h>
16#include <stdlib.h>
17#include <string.h>
18#include <misc.h>
19#define _WIN32
20#include "os2heap.h"
21#include <heap.h>
22#include <odinwrap.h>
23#include "initterm.h"
24
25#define DBG_LOCALLOG DBG_heap
26#include "dbglocal.h"
27
28ODINDEBUGCHANNEL(KERNEL32-HEAP)
29
30
31static HANDLE processheap = NULL;
32OS2Heap *OS2ProcessHeap = NULL;
33
34//******************************************************************************
35//******************************************************************************
36ODINFUNCTIONNODBG3(LPVOID, HeapAlloc, HANDLE, hHeap, DWORD, dwFlags,
37 DWORD, dwBytes)
38{
39 OS2Heap *curheap = OS2Heap::find(hHeap);
40 LPVOID rc;
41
42 if(curheap == NULL)
43 return(NULL);
44
45 rc = curheap->Alloc(dwFlags, dwBytes);
46 dprintf2(("HeapAlloc %d bytes -> %x", dwBytes, rc));
47 return rc;
48}
49//******************************************************************************
50//******************************************************************************
51ODINFUNCTIONNODBG4(LPVOID, HeapReAlloc, HANDLE, hHeap, DWORD, dwFlags, LPVOID,
52 lpMem, DWORD, dwBytes)
53{
54 OS2Heap *curheap = OS2Heap::find(hHeap);
55
56 dprintf2(("HeapReAlloc %x %x %x %X bytes", hHeap, dwFlags, lpMem, dwBytes));
57 if(curheap == NULL)
58 return(NULL);
59
60 //Some apps (i.e. nt's cmd.exe) assume the returned pointer is the same as the old one!
61 if(lpMem && curheap->Size(0, lpMem) > dwBytes)
62 return lpMem;
63
64 return(curheap->ReAlloc(dwFlags, lpMem, dwBytes));
65}
66//******************************************************************************
67//******************************************************************************
68ODINFUNCTIONNODBG3(BOOL, HeapFree, HANDLE, hHeap, DWORD, dwFlags, LPVOID, lpMem)
69{
70 OS2Heap *curheap = OS2Heap::find(hHeap);
71
72 dprintf2(("HeapFree %X", lpMem));
73 if(curheap == NULL)
74 return(FALSE);
75
76 return(curheap->Free(dwFlags, lpMem));
77}
78//******************************************************************************
79//******************************************************************************
80ODINFUNCTIONNODBG3(HANDLE, HeapCreate, DWORD, flOptions, DWORD, dwInitialSize,
81 DWORD, dwMaximumSize)
82{
83 OS2Heap *curheap;
84
85 //Create Open32 heap for it's handle
86 dprintf2(("HeapCreate dwInitialSize %X", dwInitialSize));
87
88 curheap = new OS2Heap(flOptions, dwInitialSize, dwMaximumSize);
89
90 if(curheap == NULL)
91 {
92 return(NULL);
93 }
94
95 if(curheap->getHeapHandle() == NULL)
96 {
97 delete(curheap);
98 return(NULL);
99 }
100 return(curheap->getHeapHandle());
101}
102//******************************************************************************
103//******************************************************************************
104ODINFUNCTIONNODBG1(BOOL, HeapDestroy, HANDLE, hHeap)
105{
106 OS2Heap *curheap = OS2Heap::find(hHeap);
107
108 dprintf2(("HeapDestroy %X", hHeap));
109 if(curheap == NULL)
110 return(FALSE);
111
112 delete(curheap);
113 return(TRUE);
114}
115//******************************************************************************
116//******************************************************************************
117ODINFUNCTIONNODBG3(DWORD, HeapSize, HANDLE, hHeap, DWORD, arg2, PVOID, lpMem)
118{
119 OS2Heap *curheap = OS2Heap::find(hHeap);
120
121 dprintf2(("HeapSize %X %x %x", hHeap, arg2, lpMem));
122 if(curheap == NULL)
123 return(0);
124 return curheap->Size(arg2, lpMem);
125}
126//******************************************************************************
127//TODO: Check this!!!
128//******************************************************************************
129ODINFUNCTIONNODBG2(DWORD, HeapCompact, HANDLE, hHeap, DWORD, dwFlags)
130{
131 dprintf(("KERNEL32: HeapCompact: Unknown API - stub\n"));
132 return(0);
133}
134//******************************************************************************
135//******************************************************************************
136ODINFUNCTIONNODBG3(BOOL, HeapValidate, HANDLE, hHeap, DWORD, dwFlags, LPCVOID, lpMem)
137{
138 OS2Heap *curheap = OS2Heap::find(hHeap);
139
140 dprintf2(("KERNEL32: HeapValidate %x %x %x", hHeap, dwFlags, lpMem));
141 if(curheap == NULL)
142 return FALSE;
143
144 return curheap->Validate(dwFlags, lpMem);
145}
146//******************************************************************************
147//******************************************************************************
148ODINFUNCTIONNODBG1(BOOL, HeapUnlock, HANDLE, hHeap)
149{
150 dprintf(("KERNEL32: HeapUnlock - stub (TRUE)\n"));
151 return(TRUE);
152}
153//******************************************************************************
154//******************************************************************************
155ODINFUNCTIONNODBG1(BOOL, HeapLock, HANDLE, hHeap)
156{
157 dprintf(("KERNEL32: HeapLock - stub (TRUE)\n"));
158 return(TRUE);
159}
160//******************************************************************************
161// LPPROCESS_HEAP_ENTRY lpEntry
162//******************************************************************************
163ODINFUNCTIONNODBG2(BOOL, HeapWalk, HANDLE, hHeap, LPVOID, lpEntry)
164{
165 dprintf(("KERNEL32: HeapWalk - stub (TRUE)\n"));
166 return(TRUE);
167}
168//******************************************************************************
169//******************************************************************************
170ODINFUNCTIONNODBG0(HANDLE, GetProcessHeap)
171{
172 HANDLE hHeap;
173
174// dprintf2(("KERNEL32: GetProcessHeap\n"));
175 //SvL: Only one process heap per process
176 if(processheap == NULL) {
177 OS2ProcessHeap = new OS2Heap(HEAP_GENERATE_EXCEPTIONS, 0x4000, 0);
178
179 if(OS2ProcessHeap == NULL) {
180 return(NULL);
181 }
182 processheap = OS2ProcessHeap->getHeapHandle();
183 }
184 return(processheap);
185}
186#if 1
187/*
188 * Win32 Global heap functions (GlobalXXX).
189 * These functions included in Win32 for compatibility with 16 bit Windows
190 * Especially the moveable blocks and handles are oldish.
191 * But the ability to directly allocate memory with GPTR and LPTR is widely
192 * used.
193 *
194 * The handle stuff looks horrible, but it's implemented almost like Win95
195 * does it.
196 *
197 */
198
199#define MAGIC_GLOBAL_USED 0x5342
200#define GLOBAL_LOCK_MAX 0xFF
201#define HANDLE_TO_INTERN(h) ((PGLOBAL32_INTERN)(((char *)(h))-2))
202#define INTERN_TO_HANDLE(i) ((HGLOBAL) &((i)->Pointer))
203#define ISHANDLE(h) (((DWORD)(h)&2)!=0)
204#define ISPOINTER(h) (((DWORD)(h)&2)==0)
205
206//SvL: -2 for 8 byte alignment
207#define POINTER_TO_HANDLE(p) (*(((HGLOBAL *)(p))-2))
208#define HGLOBAL_SIZE 2*sizeof(HGLOBAL)
209
210#pragma pack(1)
211
212typedef struct __GLOBAL32_INTERN
213{
214 WORD Magic;
215 LPVOID Pointer;
216 BYTE Flags;
217 BYTE LockCount;
218} GLOBAL32_INTERN, *PGLOBAL32_INTERN;
219
220#pragma pack()
221
222/***********************************************************************
223 * GlobalAlloc (KERNEL32.@)
224 * RETURNS
225 * Handle: Success
226 * NULL: Failure
227 */
228HGLOBAL WINAPI GlobalAlloc(
229 UINT flags, /* [in] Object allocation attributes */
230 DWORD size /* [in] Number of bytes to allocate */
231) {
232 PGLOBAL32_INTERN pintern;
233 DWORD hpflags;
234 LPVOID palloc;
235
236 if(flags&GMEM_ZEROINIT)
237 hpflags=HEAP_ZERO_MEMORY;
238 else
239 hpflags=0;
240
241 if((flags & GMEM_MOVEABLE)==0) /* POINTER */
242 {
243 palloc=HeapAlloc(GetProcessHeap(), hpflags, size);
244 dprintf(("KERNEL32: GlobalAlloc %x %d returned %x", flags, size, palloc));
245 return (HGLOBAL) palloc;
246 }
247 else /* HANDLE */
248 {
249 /* HeapLock(heap); */
250
251 pintern=(PGLOBAL32_INTERN)HeapAlloc(GetProcessHeap(), 0, sizeof(GLOBAL32_INTERN));
252 if (!pintern) return 0;
253 if(size)
254 {
255 //SvL: 2*sizeof for 8 byte alignment
256 if (!(palloc=HeapAlloc(GetProcessHeap(), hpflags, size+HGLOBAL_SIZE))) {
257 HeapFree(GetProcessHeap(), 0, pintern);
258 return 0;
259 }
260 *(HGLOBAL *)palloc=INTERN_TO_HANDLE(pintern);
261 //SvL: 2*sizeof for 8 byte alignment
262 pintern->Pointer=(char *) palloc+HGLOBAL_SIZE;
263 }
264 else
265 pintern->Pointer=NULL;
266 pintern->Magic=MAGIC_GLOBAL_USED;
267 pintern->Flags=flags>>8;
268 pintern->LockCount=0;
269
270 /* HeapUnlock(heap); */
271
272 dprintf(("KERNEL32: GlobalAlloc %x %d returned %x", flags, size, INTERN_TO_HANDLE(pintern)));
273 return INTERN_TO_HANDLE(pintern);
274 }
275}
276/***********************************************************************
277 * GlobalLock (KERNEL32.@)
278 * RETURNS
279 * Pointer to first byte of block
280 * NULL: Failure
281 */
282LPVOID WINAPI GlobalLock(
283 HGLOBAL hmem /* [in] Handle of global memory object */
284) {
285 PGLOBAL32_INTERN pintern;
286 LPVOID palloc;
287
288
289 if(hmem == NULL || ISPOINTER(hmem)) {
290 dprintf(("KERNEL32: GlobalLock %x returned %x", hmem, hmem));
291 return (LPVOID) hmem;
292 }
293
294 /* verify lpMem address */
295 if (hmem >= (HGLOBAL)ulMaxAddr || hmem < (HGLOBAL)0x10000)
296 {
297 dprintf(("GlobalLock ERROR BAD HEAP POINTER:%X\n", hmem));
298 DebugInt3();
299 return 0;
300 }
301
302 /* HeapLock(GetProcessHeap()); */
303
304 pintern=HANDLE_TO_INTERN(hmem);
305 if(pintern->Magic==MAGIC_GLOBAL_USED)
306 {
307 if(pintern->LockCount<GLOBAL_LOCK_MAX)
308 pintern->LockCount++;
309 palloc=pintern->Pointer;
310 }
311 else
312 {
313 dprintf(("ERROR: GlobalLock invalid handle %x", hmem));
314 palloc=(LPVOID) NULL;
315 SetLastError(ERROR_INVALID_HANDLE);
316 }
317 /* HeapUnlock(GetProcessHeap()); */;
318
319 dprintf(("KERNEL32: GlobalLock %x returned %x", hmem, palloc));
320 return palloc;
321}
322
323
324/***********************************************************************
325 * GlobalUnlock (KERNEL32.@)
326 * RETURNS
327 * TRUE: Object is still locked
328 * FALSE: Object is unlocked
329 */
330BOOL WINAPI GlobalUnlock(
331 HGLOBAL hmem /* [in] Handle of global memory object */
332) {
333 PGLOBAL32_INTERN pintern;
334 BOOL locked;
335
336 dprintf(("KERNEL32: GlobalUnlock %x", hmem));
337
338 if(hmem == NULL || ISPOINTER(hmem))
339 return FALSE;
340
341 /* verify lpMem address */
342 if (hmem >= (HGLOBAL)ulMaxAddr || hmem < (HGLOBAL)0x10000)
343 {
344 dprintf(("GlobalUnlock ERROR BAD HEAP POINTER:%X\n", hmem));
345 DebugInt3();
346 return 0;
347 }
348
349 /* HeapLock(GetProcessHeap()); */
350 pintern=HANDLE_TO_INTERN(hmem);
351
352 if(pintern->Magic==MAGIC_GLOBAL_USED)
353 {
354 if((pintern->LockCount<GLOBAL_LOCK_MAX)&&(pintern->LockCount>0))
355 pintern->LockCount--;
356
357 locked = (pintern->LockCount != 0);
358 if (!locked) SetLastError(NO_ERROR);
359 }
360 else
361 {
362 dprintf(("ERROR: GlobalUnlock invalid handle %x", hmem));
363 SetLastError(ERROR_INVALID_HANDLE);
364 locked=FALSE;
365 }
366 /* HeapUnlock(GetProcessHeap()); */
367 return locked;
368}
369
370
371/***********************************************************************
372 * GlobalHandle (KERNEL32.@)
373 * Returns the handle associated with the specified pointer.
374 *
375 * RETURNS
376 * Handle: Success
377 * NULL: Failure
378 */
379HGLOBAL WINAPI GlobalHandle(
380 LPCVOID pmem /* [in] Pointer to global memory block */
381) {
382 HGLOBAL handle;
383 PGLOBAL32_INTERN maybe_intern;
384 LPCVOID test;
385
386 dprintf(("KERNEL32: GlobalHandle %x", pmem));
387
388 if (!pmem)
389 {
390 SetLastError( ERROR_INVALID_PARAMETER );
391 return 0;
392 }
393
394#ifdef __WIN32OS2__
395 handle = 0;
396
397 /* note that if pmem is a pointer to a a block allocated by */
398 /* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate */
399 /* will fail. */
400 if (ISPOINTER(pmem)) {
401 if (HeapValidate( GetProcessHeap(), 0, pmem )) {
402 handle = (HGLOBAL)pmem; /* valid fixed block */
403 return handle;
404 }
405 handle = POINTER_TO_HANDLE(pmem);
406 } else
407 handle = (HGLOBAL)pmem;
408
409 /* Now test handle either passed in or retrieved from pointer */
410 maybe_intern = HANDLE_TO_INTERN( handle );
411 if(IsBadReadPtr(maybe_intern, sizeof(GLOBAL32_INTERN))) {
412 SetLastError( ERROR_INVALID_HANDLE );
413 return 0;
414 }
415
416 if (maybe_intern->Magic == MAGIC_GLOBAL_USED) {
417 test = maybe_intern->Pointer;
418 //SvL: -2 for 8 byte alignment
419 if (HeapValidate( GetProcessHeap(), 0, ((HGLOBAL *)test)-2 ) && /* obj(-handle) valid arena? */
420 HeapValidate( GetProcessHeap(), 0, maybe_intern )) /* intern valid arena? */
421 {
422 return handle;
423 }
424 }
425 handle = 0;
426 SetLastError( ERROR_INVALID_HANDLE );
427#else
428 __TRY
429 {
430 handle = 0;
431
432 /* note that if pmem is a pointer to a a block allocated by */
433 /* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate */
434 /* will fail. */
435 if (ISPOINTER(pmem)) {
436 if (HeapValidate( GetProcessHeap(), 0, pmem )) {
437 handle = (HGLOBAL)pmem; /* valid fixed block */
438 break;
439 }
440 handle = POINTER_TO_HANDLE(pmem);
441 } else
442 handle = (HGLOBAL)pmem;
443
444 /* Now test handle either passed in or retrieved from pointer */
445 maybe_intern = HANDLE_TO_INTERN( handle );
446 if (maybe_intern->Magic == MAGIC_GLOBAL_USED) {
447 test = maybe_intern->Pointer;
448 if (HeapValidate( GetProcessHeap(), 0, ((HGLOBAL *)test)-1 ) && /* obj(-handle) valid arena? */
449 HeapValidate( GetProcessHeap(), 0, maybe_intern )) /* intern valid arena? */
450 break; /* valid moveable block */
451 }
452 handle = 0;
453 SetLastError( ERROR_INVALID_HANDLE );
454 }
455 __EXCEPT(page_fault)
456 {
457 SetLastError( ERROR_INVALID_HANDLE );
458 return 0;
459 }
460 __ENDTRY
461#endif
462 return handle;
463}
464
465
466/***********************************************************************
467 * GlobalReAlloc (KERNEL32.@)
468 * RETURNS
469 * Handle: Success
470 * NULL: Failure
471 */
472HGLOBAL WINAPI GlobalReAlloc(
473 HGLOBAL hmem, /* [in] Handle of global memory object */
474 DWORD size, /* [in] New size of block */
475 UINT flags /* [in] How to reallocate object */
476) {
477 LPVOID palloc;
478 HGLOBAL hnew;
479 PGLOBAL32_INTERN pintern;
480 DWORD heap_flags = (flags & GMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0;
481
482#ifdef __WIN32OS2__
483 hmem = GlobalHandle((LPCVOID)hmem);
484#endif
485
486 hnew = 0;
487 /* HeapLock(heap); */
488 if(flags & GMEM_MODIFY) /* modify flags */
489 {
490 if( ISPOINTER(hmem) && (flags & GMEM_MOVEABLE))
491 {
492 /* make a fixed block moveable
493 * actually only NT is able to do this. But it's soo simple
494 */
495 if (hmem == 0)
496 {
497 dprintf(("ERROR: GlobalReAlloc32 with null handle!\n"));
498 SetLastError( ERROR_NOACCESS );
499 return 0;
500 }
501 size=HeapSize(GetProcessHeap(), 0, (LPVOID) hmem);
502 hnew=GlobalAlloc( flags, size);
503 palloc=GlobalLock(hnew);
504 memcpy(palloc, (LPVOID) hmem, size);
505 GlobalUnlock(hnew);
506 GlobalFree(hmem);
507 }
508 else if( ISPOINTER(hmem) &&(flags & GMEM_DISCARDABLE))
509 {
510 /* change the flags to make our block "discardable" */
511 pintern=HANDLE_TO_INTERN(hmem);
512 pintern->Flags = pintern->Flags | (GMEM_DISCARDABLE >> 8);
513 hnew=hmem;
514 }
515 else
516 {
517 SetLastError(ERROR_INVALID_PARAMETER);
518 hnew = 0;
519 }
520 }
521 else
522 {
523 if(ISPOINTER(hmem))
524 {
525 /* reallocate fixed memory */
526 hnew=(HGLOBAL)HeapReAlloc(GetProcessHeap(), heap_flags, (LPVOID) hmem, size);
527 }
528 else
529 {
530 /* reallocate a moveable block */
531 pintern=HANDLE_TO_INTERN(hmem);
532
533#if 0
534/* Apparently Windows doesn't care whether the handle is locked at this point */
535/* See also the same comment in GlobalFree() */
536 if(pintern->LockCount>1) {
537 ERR("handle 0x%08lx is still locked, cannot realloc!\n",(DWORD)hmem);
538 SetLastError(ERROR_INVALID_HANDLE);
539 } else
540#endif
541 if(size!=0)
542 {
543 hnew=hmem;
544 if(pintern->Pointer)
545 {
546 if((palloc = HeapReAlloc(GetProcessHeap(), heap_flags,
547 (char *) pintern->Pointer-HGLOBAL_SIZE,
548 size+HGLOBAL_SIZE)) == NULL)
549 return 0; /* Block still valid */
550 pintern->Pointer=(char *) palloc+HGLOBAL_SIZE;
551 }
552 else
553 {
554 if((palloc=HeapAlloc(GetProcessHeap(), heap_flags, size+HGLOBAL_SIZE))
555 == NULL)
556 return 0;
557 *(HGLOBAL *)palloc=hmem;
558 pintern->Pointer=(char *) palloc+HGLOBAL_SIZE;
559 }
560 }
561 else
562 {
563 if(pintern->Pointer)
564 {
565 HeapFree(GetProcessHeap(), 0, (char *) pintern->Pointer-HGLOBAL_SIZE);
566 pintern->Pointer=NULL;
567 }
568 }
569 }
570 }
571 /* HeapUnlock(heap); */
572 return hnew;
573}
574
575
576/***********************************************************************
577 * GlobalFree (KERNEL32.@)
578 * RETURNS
579 * NULL: Success
580 * Handle: Failure
581 */
582HGLOBAL WINAPI GlobalFree(
583 HGLOBAL hmem /* [in] Handle of global memory object */
584) {
585 PGLOBAL32_INTERN pintern;
586 HGLOBAL hreturned = 0;
587
588 dprintf(("KERNEL32: GlobalFree %x", hmem));
589
590 /* verify lpMem address */
591 if (hmem >= (HGLOBAL)ulMaxAddr || hmem < (HGLOBAL)0x10000)
592 {
593 dprintf(("GlobalFree ERROR BAD HEAP POINTER:%X\n", hmem));
594// DebugInt3();
595 return 0;
596 }
597
598 if(ISPOINTER(hmem)) /* POINTER */
599 {
600 if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) hmem = 0;
601 }
602 else /* HANDLE */
603 {
604 /* HeapLock(heap); */
605 pintern=HANDLE_TO_INTERN(hmem);
606
607 if(pintern->Magic==MAGIC_GLOBAL_USED)
608 {
609
610/* WIN98 does not make this test. That is you can free a */
611/* block you have not unlocked. Go figure!! */
612 /* if(pintern->LockCount!=0) */
613 /* SetLastError(ERROR_INVALID_HANDLE); */
614
615 if(pintern->Pointer)
616 if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-HGLOBAL_SIZE))
617 hreturned=hmem;
618 if(!HeapFree(GetProcessHeap(), 0, pintern))
619 hreturned=hmem;
620 }
621 /* HeapUnlock(heap); */
622 }
623 return hreturned;
624}
625
626
627/***********************************************************************
628 * GlobalSize (KERNEL32.@)
629 * RETURNS
630 * Size in bytes of the global memory object
631 * 0: Failure
632 */
633DWORD WINAPI GlobalSize(
634 HGLOBAL hmem /* [in] Handle of global memory object */
635) {
636 DWORD retval;
637 PGLOBAL32_INTERN pintern;
638
639 dprintf(("KERNEL32: GlobalSize %x", hmem));
640
641 if(ISPOINTER(hmem))
642 {
643 retval=HeapSize(GetProcessHeap(), 0, (LPVOID) hmem);
644 }
645 else
646 {
647 /* HeapLock(heap); */
648 pintern=HANDLE_TO_INTERN(hmem);
649
650 if(pintern->Magic==MAGIC_GLOBAL_USED)
651 {
652 if (!pintern->Pointer) /* handle case of GlobalAlloc( ??,0) */
653 return 0;
654 retval=HeapSize(GetProcessHeap(), 0,
655 (char *)(pintern->Pointer)-HGLOBAL_SIZE)-HGLOBAL_SIZE;
656 //SvL: ???
657 if (retval == 0xffffffff-HGLOBAL_SIZE) retval = 0;
658 }
659 else
660 {
661 dprintf(("ERROR: GlobalSize invalid handle %x", hmem));
662 retval=0;
663 }
664 /* HeapUnlock(heap); */
665 }
666 /* HeapSize returns 0xffffffff on failure */
667 if (retval == 0xffffffff) retval = 0;
668 dprintf(("KERNEL32: GlobalSize %x = %d", hmem, retval));
669 return retval;
670}
671
672
673/***********************************************************************
674 * GlobalWire (KERNEL32.@)
675 */
676LPVOID WINAPI GlobalWire(HGLOBAL hmem)
677{
678 return GlobalLock( hmem );
679}
680
681
682/***********************************************************************
683 * GlobalUnWire (KERNEL32.@)
684 */
685BOOL WINAPI GlobalUnWire(HGLOBAL hmem)
686{
687 return GlobalUnlock( hmem);
688}
689
690
691/***********************************************************************
692 * GlobalFix (KERNEL32.@)
693 */
694VOID WINAPI GlobalFix(HGLOBAL hmem)
695{
696 GlobalLock( hmem );
697}
698
699
700/***********************************************************************
701 * GlobalUnfix (KERNEL32.@)
702 */
703VOID WINAPI GlobalUnfix(HGLOBAL hmem)
704{
705 GlobalUnlock( hmem);
706}
707
708
709/***********************************************************************
710 * GlobalFlags (KERNEL32.@)
711 * Returns information about the specified global memory object
712 *
713 * NOTES
714 * Should this return GMEM_INVALID_HANDLE on invalid handle?
715 *
716 * RETURNS
717 * Value specifying allocation flags and lock count
718 * GMEM_INVALID_HANDLE: Failure
719 */
720UINT WINAPI GlobalFlags(
721 HGLOBAL hmem /* [in] Handle to global memory object */
722) {
723 DWORD retval;
724 PGLOBAL32_INTERN pintern;
725
726 dprintf(("KERNEL32: GlobalFlags %x", hmem));
727
728 if(ISPOINTER(hmem))
729 {
730 retval=0;
731 }
732 else
733 {
734 /* HeapLock(GetProcessHeap()); */
735 pintern=HANDLE_TO_INTERN(hmem);
736 if(pintern->Magic==MAGIC_GLOBAL_USED)
737 {
738 retval=pintern->LockCount + (pintern->Flags<<8);
739 if(pintern->Pointer==0)
740 retval|= GMEM_DISCARDED;
741 }
742 else
743 {
744 dprintf(("ERROR: GlobalFlags invalid handle %x", hmem));
745 retval=0;
746 }
747 /* HeapUnlock(GetProcessHeap()); */
748 }
749 return retval;
750}
751
752
753/***********************************************************************
754 * GlobalCompact (KERNEL32.@)
755 */
756DWORD WINAPI GlobalCompact( DWORD minfree )
757{
758 dprintf(("KERNEL32: GlobalCompact %d OBSOLETE", minfree));
759
760 return 0; /* GlobalCompact does nothing in Win32 */
761}
762#else
763//******************************************************************************
764#ifdef DEBUG
765static ULONG totalGlobalAlloc = 0;
766#endif
767//******************************************************************************
768HGLOBAL WIN32API GlobalAlloc(UINT fuFlags, DWORD dwBytes)
769{
770 HGLOBAL ret;
771
772 ret = O32_GlobalAlloc(fuFlags, dwBytes);
773#ifdef DEBUG
774 totalGlobalAlloc += dwBytes;
775#endif
776 dprintf(("KERNEL32: GlobalAlloc %x %d returned %x (total %x)", fuFlags, dwBytes, ret, totalGlobalAlloc));
777 return ret;
778}
779//******************************************************************************
780//******************************************************************************
781HGLOBAL WIN32API GlobalFree( HGLOBAL arg1)
782{
783 HGLOBAL ret;
784
785#ifdef DEBUG
786 totalGlobalAlloc -= O32_GlobalSize(arg1);
787#endif
788 ret = O32_GlobalFree(arg1);
789 dprintf(("KERNEL32: GlobalFree %x returned %x (lasterr=%x) total %x", arg1, ret, GetLastError(), totalGlobalAlloc));
790 return ret;
791}
792//******************************************************************************
793//******************************************************************************
794HGLOBAL WIN32API GlobalHandle( LPCVOID lpMem)
795{
796 dprintf(("KERNEL32: GlobalHandle %x", lpMem));
797
798 return O32_GlobalHandle((LPVOID)lpMem);
799}
800//******************************************************************************
801//******************************************************************************
802UINT WIN32API GlobalFlags(HGLOBAL hMem)
803{
804 dprintf(("KERNEL32: GlobalFlags %x", hMem));
805
806 return O32_GlobalFlags(hMem);
807}
808//******************************************************************************
809//******************************************************************************
810DWORD WIN32API GlobalCompact(DWORD dwMinFree)
811{
812 dprintf(("KERNEL32: GlobalCompact, OBSOLETE - stub\n"));
813
814 return(0);
815}
816//******************************************************************************
817//******************************************************************************
818PVOID WIN32API GlobalLock(HGLOBAL hMem)
819{
820 PVOID ret;
821
822 ret = O32_GlobalLock(hMem);
823 dprintf(("KERNEL32: GlobalLock %x returned %x", hMem, ret));
824 return ret;
825}
826//******************************************************************************
827//******************************************************************************
828HGLOBAL WIN32API GlobalReAlloc(HGLOBAL arg1, DWORD arg2, UINT arg3)
829{
830 dprintf(("KERNEL32: GlobalReAlloc %x %x %d", arg1, arg2, arg3));
831
832 return O32_GlobalReAlloc(arg1, arg2, arg3);
833}
834//******************************************************************************
835//******************************************************************************
836DWORD WIN32API GlobalSize(HGLOBAL arg1)
837{
838 dprintf(("KERNEL32: GlobalSize\n"));
839
840 return O32_GlobalSize(arg1);
841}
842//******************************************************************************
843//******************************************************************************
844BOOL WIN32API GlobalUnlock(HGLOBAL arg1)
845{
846 dprintf(("KERNEL32: GlobalUnlock\n"));
847
848 return O32_GlobalUnlock(arg1);
849}
850/***********************************************************************
851 * GlobalWire
852 *
853 * The GlobalWire function is obsolete. It is provided only for compatibility
854 * with 16-bit versions of Windows. Applications that need to lock a global
855 * memory object should use the GlobalLock and GlobalUnlock functions.
856 *
857 */
858LPVOID WIN32API GlobalWire(HGLOBAL hmem)
859{
860 return GlobalLock( hmem );
861}
862/***********************************************************************
863 * GlobalUnWire
864 *
865 * The GlobalUnWire function is obsolete. It is provided only for compatibility
866 * with 16-bit versions of Windows. Applications that need to lock a global
867 * memory object should use the GlobalLock and GlobalUnlock functions.
868 *
869 */
870BOOL WIN32API GlobalUnWire(HGLOBAL hmem)
871{
872 return GlobalUnlock( hmem);
873}
874//******************************************************************************
875//******************************************************************************
876HGLOBAL WIN32API GlobalDiscard(HGLOBAL hGlobal)
877{
878 dprintf(("KERNEL32: GlobalDiscard %x", hGlobal));
879
880 return O32_GlobalDiscard(hGlobal);
881}
882/***********************************************************************
883 * GlobalFix (KERNEL32.@)
884 */
885VOID WINAPI GlobalFix(HGLOBAL hmem)
886{
887 GlobalLock( hmem );
888}
889/***********************************************************************
890 * GlobalUnfix (KERNEL32.@)
891 */
892VOID WINAPI GlobalUnfix(HGLOBAL hmem)
893{
894 GlobalUnlock( hmem);
895}
896#endif
897//******************************************************************************
898//******************************************************************************
899HLOCAL WIN32API LocalAlloc(UINT fuFlags, DWORD cbBytes)
900{
901 HLOCAL hLocal;
902
903 // Check flags
904 if(fuFlags & (~(LMEM_MOVEABLE | LMEM_DISCARDABLE | LMEM_NOCOMPACT |
905 LMEM_NODISCARD | LMEM_ZEROINIT)))
906 {
907 dprintf(("LocalAlloc %x %x: INVALID flags!", fuFlags, cbBytes));
908 SetLastError(ERROR_INVALID_PARAMETER);
909 return 0;
910 }
911 // Note: local & global flags are the same (the ones used here), so no need for conversion
912 hLocal = GlobalAlloc(fuFlags, cbBytes);
913 dprintf(("KERNEL32: LocalAlloc flags %X, size %d returned %X", fuFlags, cbBytes, hLocal));
914 return hLocal;
915}
916//******************************************************************************
917//******************************************************************************
918UINT WIN32API LocalFlags(HLOCAL hMem)
919{
920 UINT ret, retG;
921 dprintf(("KERNEL32: LocalFlags %X\n", hMem));
922
923 retG = GlobalFlags(hMem);
924
925 if(retG == GMEM_INVALID_HANDLE)
926 {
927 return LMEM_INVALID_HANDLE;
928 }
929 // Low byte holds lock count.
930 // Hi byte of low word contains some flags.
931 ret = retG & 0xff; // Keep lock count.
932 if (retG & GMEM_DISCARDABLE) ret |= LMEM_DISCARDABLE;
933 if (retG & GMEM_DISCARDED) ret |= LMEM_DISCARDED;
934
935 return ret;
936}
937//******************************************************************************
938//******************************************************************************
939HLOCAL WIN32API LocalFree(HLOCAL hMem)
940{
941 dprintf(("KERNEL32: LocalFree %X", hMem));
942
943 return GlobalFree(hMem);
944}
945//******************************************************************************
946//******************************************************************************
947HLOCAL WIN32API LocalHandle(PCVOID lpMem)
948{
949 dprintf(("KERNEL32: LocalHandle %x", lpMem));
950
951 return GlobalHandle(lpMem);
952}
953//******************************************************************************
954//******************************************************************************
955BOOL WIN32API LocalUnlock(HLOCAL hMem)
956{
957 dprintf(("KERNEL32: LocalUnlock %X", hMem));
958
959 return GlobalUnlock(hMem);
960}
961//******************************************************************************
962//TODO: cbBytes==0 && fuFlags & LMEM_MOVEABLE not handled!!
963//******************************************************************************
964HLOCAL WIN32API LocalReAlloc(HLOCAL hMem, DWORD cbBytes, UINT fuFlags)
965{
966 HLOCAL hLocalNew, hLocalOld;
967 LPVOID lpMem, lpMemOld;
968 DWORD cbOldSize;
969
970 dprintf(("KERNEL32: LocalReAlloc %X %d %X\n", hMem, cbBytes, fuFlags));
971
972 // Check flags
973 if(fuFlags & (~(LMEM_MOVEABLE | LMEM_DISCARDABLE | LMEM_NOCOMPACT |
974 LMEM_MODIFY | LMEM_ZEROINIT)))
975 {
976 dprintf(("LocalAlloc %x %x: INVALID flags!", fuFlags, cbBytes));
977 SetLastError(ERROR_INVALID_PARAMETER);
978 return 0;
979 }
980
981 //SvL: 8-8-'98: Notepad bugfix (assumes address is identical when new size < old size)
982 cbOldSize = LocalSize(hMem);
983 if(cbOldSize > cbBytes)
984 return hMem;
985
986 return GlobalReAlloc(hMem, cbBytes, fuFlags);
987}
988//******************************************************************************
989//******************************************************************************
990UINT WIN32API LocalSize(HLOCAL hMem)
991{
992 dprintf(("KERNEL32: LocalSize %X", hMem));
993
994 return GlobalSize(hMem);
995}
996//******************************************************************************
997//******************************************************************************
998PVOID WIN32API LocalLock(HLOCAL hMem)
999{
1000 dprintf(("KERNEL32: LocalLock %X\n", hMem));
1001
1002 return GlobalLock(hMem);
1003}
1004//******************************************************************************
1005//* this function is here for completeness, some stupid software requires it.
1006//******************************************************************************
1007UINT WIN32API LocalShrink(HLOCAL hMem, UINT cbNewSize)
1008{
1009 dprintf(("KERNEL32: LocalShrink %X, %08xh - OBSOLETE", hMem, cbNewSize));
1010
1011 return cbNewSize;
1012}
1013//******************************************************************************
1014//* this function is here for completeness, mIRC/32 requires it.
1015//******************************************************************************
1016UINT WIN32API LocalCompact(UINT cbNewSize)
1017{
1018 dprintf(("KERNEL32: LocalCompact %08xh - OBSOLETE", cbNewSize));
1019
1020 return cbNewSize;
1021}
1022//******************************************************************************
1023//******************************************************************************
Note: See TracBrowser for help on using the repository browser.