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

Last change on this file since 6438 was 6438, checked in by sandervl, 24 years ago

removed annoying DebugInt3

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