2 * Global heap functions
4 * Copyright 1995 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* 0xffff sometimes seems to mean: CURRENT_DS */
22 #include <sys/types.h>
28 #include "wine/winbase16.h"
30 #include "kernel16_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(global
);
35 /* Global arena block */
38 void *base
; /* Base address (0 if discarded) */
39 DWORD size
; /* Size in bytes (0 indicates a free block) */
40 HGLOBAL16 handle
; /* Handle for this block */
41 HGLOBAL16 hOwner
; /* Owner of this block */
42 BYTE lockCount
; /* Count of GlobalFix() calls */
43 BYTE pageLockCount
; /* Count of GlobalPageLock() calls */
44 BYTE flags
; /* Allocation flags */
45 BYTE selCount
; /* Number of selectors allocated for this block */
48 /* Flags definitions */
49 #define GA_MOVEABLE 0x02 /* same as GMEM_MOVEABLE */
50 #define GA_DGROUP 0x04
51 #define GA_DISCARDABLE 0x08
52 #define GA_IPCSHARE 0x10 /* same as GMEM_DDESHARE */
53 #define GA_DOSMEM 0x20
55 /* Arena array (FIXME) */
56 static GLOBALARENA
*pGlobalArena
;
57 static int globalArenaSize
;
59 #define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000 /* Largest allocation is 16M - 64K */
60 #define GLOBAL_MAX_COUNT 8192 /* Max number of allocated blocks */
62 #define VALID_HANDLE(handle) (((handle)>>__AHSHIFT)<globalArenaSize)
63 #define GET_ARENA_PTR(handle) (pGlobalArena + ((handle) >> __AHSHIFT))
65 static HANDLE
get_win16_heap(void)
67 static HANDLE win16_heap
;
69 /* we create global memory block with execute permission. The access can be limited
70 * for 16-bit code on selector level */
71 if (!win16_heap
) win16_heap
= HeapCreate(HEAP_CREATE_ENABLE_EXECUTE
, 0, 0);
75 /***********************************************************************
78 * Return the arena for a given selector, growing the arena array if needed.
80 static GLOBALARENA
*GLOBAL_GetArena( WORD sel
, WORD selcount
)
82 if (((sel
>> __AHSHIFT
) + selcount
) > globalArenaSize
)
84 int newsize
= ((sel
>> __AHSHIFT
) + selcount
+ 0xff) & ~0xff;
88 pGlobalArena
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
89 GLOBAL_MAX_COUNT
* sizeof(GLOBALARENA
) );
90 if (!pGlobalArena
) return 0;
91 /* Hack: store a pointer to it in THHOOK instead of a handle */
92 *(GLOBALARENA
**)&pThhook
->hGlobalHeap
= pGlobalArena
;
94 if (newsize
> GLOBAL_MAX_COUNT
) return 0;
95 globalArenaSize
= newsize
;
97 return pGlobalArena
+ (sel
>> __AHSHIFT
);
101 /***********************************************************************
104 * Create a global heap block for a fixed range of linear memory.
106 HGLOBAL16
GLOBAL_CreateBlock( WORD flags
, void *ptr
, DWORD size
,
107 HGLOBAL16 hOwner
, unsigned char selflags
)
112 /* Allocate the selector(s) */
114 sel
= SELECTOR_AllocBlock( ptr
, size
, selflags
);
116 selcount
= (size
+ 0xffff) / 0x10000;
118 if (!(pArena
= GLOBAL_GetArena( sel
, selcount
)))
120 SELECTOR_FreeBlock( sel
);
124 /* Fill the arena block */
127 pArena
->size
= GetSelectorLimit16(sel
) + 1;
128 pArena
->handle
= (flags
& GMEM_MOVEABLE
) ? sel
- 1 : sel
;
129 pArena
->hOwner
= hOwner
;
130 pArena
->lockCount
= 0;
131 pArena
->pageLockCount
= 0;
132 pArena
->flags
= flags
& GA_MOVEABLE
;
133 if (flags
& GMEM_DISCARDABLE
) pArena
->flags
|= GA_DISCARDABLE
;
134 if (flags
& GMEM_DDESHARE
) pArena
->flags
|= GA_IPCSHARE
;
135 if (!(selflags
& (LDT_FLAGS_CODE
^ LDT_FLAGS_DATA
))) pArena
->flags
|= GA_DGROUP
;
136 pArena
->selCount
= selcount
;
137 if (selcount
> 1) /* clear the next arena blocks */
138 memset( pArena
+ 1, 0, (selcount
- 1) * sizeof(GLOBALARENA
) );
140 return pArena
->handle
;
144 /***********************************************************************
147 * Free a block allocated by GLOBAL_CreateBlock, without touching
148 * the associated linear memory range.
150 BOOL16
GLOBAL_FreeBlock( HGLOBAL16 handle
)
155 if (!handle
) return TRUE
;
156 sel
= GlobalHandleToSel16( handle
);
157 if (!VALID_HANDLE(sel
)) return FALSE
;
158 pArena
= GET_ARENA_PTR(sel
);
161 WARN( "already free %x\n", handle
);
164 SELECTOR_FreeBlock( sel
);
165 memset( pArena
, 0, sizeof(GLOBALARENA
) );
169 /***********************************************************************
172 BOOL16
GLOBAL_MoveBlock( HGLOBAL16 handle
, void *ptr
, DWORD size
)
177 if (!handle
) return TRUE
;
178 sel
= GlobalHandleToSel16( handle
);
179 if (!VALID_HANDLE(sel
)) return FALSE
;
180 pArena
= GET_ARENA_PTR(sel
);
181 if (pArena
->selCount
!= 1)
186 SELECTOR_ReallocBlock( sel
, ptr
, size
);
190 /***********************************************************************
193 * Implementation of GlobalAlloc16()
195 HGLOBAL16
GLOBAL_Alloc( UINT16 flags
, DWORD size
, HGLOBAL16 hOwner
, unsigned char selflags
)
201 TRACE("%ld flags=%04x\n", size
, flags
);
203 /* If size is 0, create a discarded block */
205 if (size
== 0) return GLOBAL_CreateBlock( flags
, NULL
, 1, hOwner
, selflags
);
209 if (size
> 0x100000) align
= 0xfff; /* selector limit will be in pages */
210 if (size
>= GLOBAL_MAX_ALLOC_SIZE
- align
) return 0;
211 size
= (size
+ align
) & ~align
;
213 /* Allocate the linear memory */
214 ptr
= HeapAlloc( get_win16_heap(), 0, size
);
215 /* FIXME: free discardable blocks and try again? */
218 /* Allocate the selector(s) */
220 handle
= GLOBAL_CreateBlock( flags
, ptr
, size
, hOwner
, selflags
);
223 HeapFree( get_win16_heap(), 0, ptr
);
227 if (flags
& GMEM_ZEROINIT
) memset( ptr
, 0, size
);
231 /***********************************************************************
232 * GlobalAlloc (KERNEL.15)
233 * GlobalAlloc16 (KERNEL32.24)
235 * Allocate a global memory object.
241 HGLOBAL16 WINAPI
GlobalAlloc16(
242 UINT16 flags
, /* [in] Object allocation attributes */
243 DWORD size
/* [in] Number of bytes to allocate */
245 HANDLE16 owner
= GetCurrentPDB16();
247 if (flags
& GMEM_DDESHARE
)
249 /* make it owned by the calling module */
250 STACK16FRAME
*frame
= CURRENT_STACK16
;
251 owner
= GetExePtr( frame
->cs
);
253 return GLOBAL_Alloc( flags
, size
, owner
, LDT_FLAGS_DATA
);
257 /***********************************************************************
258 * GlobalReAlloc (KERNEL.16)
260 * Change the size or attributes of a global memory object.
266 HGLOBAL16 WINAPI
GlobalReAlloc16(
267 HGLOBAL16 handle
, /* [in] Handle of global memory object */
268 DWORD size
, /* [in] New size of block */
269 UINT16 flags
/* [in] How to reallocate object */
274 GLOBALARENA
*pArena
, *pNewArena
;
275 WORD sel
= GlobalHandleToSel16( handle
);
276 HANDLE heap
= get_win16_heap();
278 TRACE("%04x %ld flags=%04x\n",
279 handle
, size
, flags
);
280 if (!handle
) return 0;
282 if (!VALID_HANDLE(handle
))
284 WARN("Invalid handle 0x%04x!\n", handle
);
287 pArena
= GET_ARENA_PTR( handle
);
289 /* Discard the block if requested */
291 if ((size
== 0) && (flags
& GMEM_MOVEABLE
) && !(flags
& GMEM_MODIFY
))
293 if (!(pArena
->flags
& GA_MOVEABLE
) ||
294 !(pArena
->flags
& GA_DISCARDABLE
) ||
295 (pArena
->lockCount
> 0) || (pArena
->pageLockCount
> 0)) return 0;
296 if (pArena
->flags
& GA_DOSMEM
)
297 DOSMEM_FreeBlock( pArena
->base
);
299 HeapFree( heap
, 0, pArena
->base
);
302 /* Note: we rely on the fact that SELECTOR_ReallocBlock won't
303 * change the selector if we are shrinking the block.
304 * FIXME: shouldn't we keep selectors until the block is deleted?
306 SELECTOR_ReallocBlock( sel
, 0, 1 );
312 if (size
> GLOBAL_MAX_ALLOC_SIZE
- 0x20) return 0;
313 if (size
== 0) size
= 0x20;
314 else size
= (size
+ 0x1f) & ~0x1f;
316 /* Change the flags */
318 if (flags
& GMEM_MODIFY
)
320 /* Change the flags, leaving GA_DGROUP alone */
321 pArena
->flags
= (pArena
->flags
& GA_DGROUP
) | (flags
& GA_MOVEABLE
);
322 if (flags
& GMEM_DISCARDABLE
) pArena
->flags
|= GA_DISCARDABLE
;
326 /* Reallocate the linear memory */
329 oldsize
= pArena
->size
;
330 TRACE("oldbase %p oldsize %08lx newsize %08lx\n", ptr
,oldsize
,size
);
331 if (ptr
&& (size
== oldsize
)) return handle
; /* Nothing to do */
333 if (pArena
->flags
& GA_DOSMEM
)
335 if (DOSMEM_ResizeBlock(ptr
, size
, TRUE
) == size
)
337 else if(pArena
->pageLockCount
> 0)
341 newptr
= DOSMEM_AllocBlock( size
, NULL
);
344 memcpy( newptr
, ptr
, oldsize
);
345 DOSMEM_FreeBlock( ptr
);
352 * if more than one reader (e.g. some pointer has been
353 * given out by GetVDMPointer32W16),
354 * only try to realloc in place
358 newptr
= HeapReAlloc( heap
,
359 (pArena
->pageLockCount
> 0) ? HEAP_REALLOC_IN_PLACE_ONLY
: 0,
362 newptr
= HeapAlloc( heap
, 0, size
);
368 FIXME("Realloc failed lock %d\n",pArena
->pageLockCount
);
369 if (pArena
->pageLockCount
<1)
371 if (pArena
->flags
& GA_DOSMEM
)
372 DOSMEM_FreeBlock( pArena
->base
);
374 HeapFree( heap
, 0, ptr
);
375 SELECTOR_FreeBlock( sel
);
376 memset( pArena
, 0, sizeof(GLOBALARENA
) );
382 /* Reallocate the selector(s) */
384 sel
= SELECTOR_ReallocBlock( sel
, ptr
, size
);
387 if (pArena
->flags
& GA_DOSMEM
)
388 DOSMEM_FreeBlock( pArena
->base
);
390 HeapFree( heap
, 0, ptr
);
391 memset( pArena
, 0, sizeof(GLOBALARENA
) );
394 selcount
= (size
+ 0xffff) / 0x10000;
396 if (!(pNewArena
= GLOBAL_GetArena( sel
, selcount
)))
398 if (pArena
->flags
& GA_DOSMEM
)
399 DOSMEM_FreeBlock( pArena
->base
);
401 HeapFree( heap
, 0, ptr
);
402 SELECTOR_FreeBlock( sel
);
406 /* Fill the new arena block
407 As we may have used HEAP_REALLOC_IN_PLACE_ONLY, areas may overlap*/
409 if (pNewArena
!= pArena
) memmove( pNewArena
, pArena
, sizeof(GLOBALARENA
) );
410 pNewArena
->base
= ptr
;
411 pNewArena
->size
= GetSelectorLimit16(sel
) + 1;
412 pNewArena
->selCount
= selcount
;
413 pNewArena
->handle
= (pNewArena
->flags
& GA_MOVEABLE
) ? sel
- 1 : sel
;
415 if (selcount
> 1) /* clear the next arena blocks */
416 memset( pNewArena
+ 1, 0, (selcount
- 1) * sizeof(GLOBALARENA
) );
418 if ((oldsize
< size
) && (flags
& GMEM_ZEROINIT
))
419 memset( (char *)ptr
+ oldsize
, 0, size
- oldsize
);
420 return pNewArena
->handle
;
424 /***********************************************************************
425 * GlobalFree (KERNEL.17)
426 * GlobalFree16 (KERNEL32.31)
431 HGLOBAL16 WINAPI
GlobalFree16(
432 HGLOBAL16 handle
/* [in] Handle of global memory object */
436 if (!VALID_HANDLE(handle
))
438 WARN("Invalid handle 0x%04x passed to GlobalFree16!\n",handle
);
441 ptr
= GET_ARENA_PTR(handle
)->base
;
443 TRACE("%04x\n", handle
);
444 if (!GLOBAL_FreeBlock( handle
)) return handle
; /* failed */
445 HeapFree( get_win16_heap(), 0, ptr
);
450 /**********************************************************************
451 * K32WOWGlobalLock16 (KERNEL32.60)
453 SEGPTR WINAPI
K32WOWGlobalLock16( HGLOBAL16 handle
)
455 WORD sel
= GlobalHandleToSel16( handle
);
456 TRACE("(%04x) -> %08lx\n", handle
, MAKELONG( 0, sel
) );
460 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
462 if (!VALID_HANDLE(handle
)) {
463 WARN("Invalid handle 0x%04x passed to WIN16_GlobalLock16!\n",handle
);
466 else if (!GET_ARENA_PTR(handle
)->base
)
469 GET_ARENA_PTR(handle
)->lockCount
++;
472 return MAKESEGPTR( sel
, 0 );
477 /***********************************************************************
478 * GlobalLock (KERNEL.18)
480 * This is the GlobalLock16() function used by 16-bit code.
482 SEGPTR WINAPI
WIN16_GlobalLock16( HGLOBAL16 handle
)
484 SEGPTR ret
= K32WOWGlobalLock16( handle
);
485 CURRENT_STACK16
->ecx
= SELECTOROF(ret
); /* selector must be returned in CX as well */
490 /***********************************************************************
491 * GlobalLock16 (KERNEL32.25)
493 * This is the GlobalLock16() function used by 32-bit code.
496 * Pointer to first byte of memory block
499 LPVOID WINAPI
GlobalLock16(
500 HGLOBAL16 handle
/* [in] Handle of global memory object */
502 if (!handle
) return 0;
503 if (!VALID_HANDLE(handle
))
505 GET_ARENA_PTR(handle
)->lockCount
++;
506 return GET_ARENA_PTR(handle
)->base
;
510 /***********************************************************************
511 * GlobalUnlock (KERNEL.19)
512 * GlobalUnlock16 (KERNEL32.26)
514 * Should the return values be cast to booleans?
517 * TRUE: Object is still locked
518 * FALSE: Object is unlocked
520 BOOL16 WINAPI
GlobalUnlock16(
521 HGLOBAL16 handle
/* [in] Handle of global memory object */
523 GLOBALARENA
*pArena
= GET_ARENA_PTR(handle
);
524 if (!VALID_HANDLE(handle
)) {
525 WARN("Invalid handle 0x%04x passed to GlobalUnlock16!\n",handle
);
528 TRACE("%04x\n", handle
);
529 if (pArena
->lockCount
) pArena
->lockCount
--;
530 return pArena
->lockCount
;
533 /***********************************************************************
534 * GlobalChangeLockCount (KERNEL.365)
536 * This is declared as a register function as it has to preserve
537 * *all* registers, even AX/DX !
540 void WINAPI
GlobalChangeLockCount16( HGLOBAL16 handle
, INT16 delta
, CONTEXT
*context
)
543 GlobalLock16( handle
);
544 else if ( delta
== -1 )
545 GlobalUnlock16( handle
);
547 ERR("(%04X, %d): strange delta value\n", handle
, delta
);
550 /***********************************************************************
551 * GlobalSize (KERNEL.20)
552 * GlobalSize16 (KERNEL32.32)
554 * Get the current size of a global memory object.
557 * Size in bytes of object
560 DWORD WINAPI
GlobalSize16(
561 HGLOBAL16 handle
/* [in] Handle of global memory object */
563 TRACE("%04x\n", handle
);
564 if (!handle
) return 0;
565 if (!VALID_HANDLE(handle
))
567 return GET_ARENA_PTR(handle
)->size
;
571 /***********************************************************************
572 * GlobalHandle (KERNEL.21)
574 * Get the handle associated with a pointer to the global memory block.
577 * Why is GlobalHandleToSel used here with the sel as input?
583 DWORD WINAPI
GlobalHandle16(
584 WORD sel
/* [in] Address of global memory block */
586 TRACE("%04x\n", sel
);
587 if (!VALID_HANDLE(sel
)) {
588 WARN("Invalid handle 0x%04x passed to GlobalHandle16!\n",sel
);
591 return MAKELONG( GET_ARENA_PTR(sel
)->handle
, GlobalHandleToSel16(sel
) );
594 /***********************************************************************
595 * GlobalHandleNoRIP (KERNEL.159)
597 DWORD WINAPI
GlobalHandleNoRIP16( WORD sel
)
600 for (i
= globalArenaSize
-1 ; i
>=0 ; i
--) {
601 if (pGlobalArena
[i
].size
!=0 && pGlobalArena
[i
].handle
== sel
)
602 return MAKELONG( GET_ARENA_PTR(sel
)->handle
, GlobalHandleToSel16(sel
) );
608 /***********************************************************************
609 * GlobalFlags (KERNEL.22)
611 * Get information about a global memory object.
614 * Should this return GMEM_INVALID_HANDLE instead of 0 on invalid
618 * Value specifying flags and lock count
619 * GMEM_INVALID_HANDLE: Invalid handle
621 UINT16 WINAPI
GlobalFlags16(
622 HGLOBAL16 handle
/* [in] Handle of global memory object */
626 TRACE("%04x\n", handle
);
627 if (!VALID_HANDLE(handle
)) {
628 WARN("Invalid handle 0x%04x passed to GlobalFlags16!\n",handle
);
631 pArena
= GET_ARENA_PTR(handle
);
632 return pArena
->lockCount
|
633 ((pArena
->flags
& GA_DISCARDABLE
) ? GMEM_DISCARDABLE
: 0) |
634 ((pArena
->base
== 0) ? GMEM_DISCARDED
: 0);
638 /***********************************************************************
639 * LockSegment (KERNEL.23)
641 HGLOBAL16 WINAPI
LockSegment16( HGLOBAL16 handle
)
643 TRACE("%04x\n", handle
);
644 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
645 if (!VALID_HANDLE(handle
)) {
646 WARN("Invalid handle 0x%04x passed to LockSegment16!\n",handle
);
649 GET_ARENA_PTR(handle
)->lockCount
++;
654 /***********************************************************************
655 * UnlockSegment (KERNEL.24)
657 void WINAPI
UnlockSegment16( HGLOBAL16 handle
)
659 TRACE("%04x\n", handle
);
660 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
661 if (!VALID_HANDLE(handle
)) {
662 WARN("Invalid handle 0x%04x passed to UnlockSegment16!\n",handle
);
665 GET_ARENA_PTR(handle
)->lockCount
--;
666 /* FIXME: this ought to return the lock count in CX (go figure...) */
670 /***********************************************************************
671 * GlobalCompact (KERNEL.25)
673 DWORD WINAPI
GlobalCompact16( DWORD desired
)
675 return GLOBAL_MAX_ALLOC_SIZE
;
679 /***********************************************************************
680 * GlobalFreeAll (KERNEL.26)
682 void WINAPI
GlobalFreeAll16( HGLOBAL16 owner
)
687 pArena
= pGlobalArena
;
688 for (i
= 0; i
< globalArenaSize
; i
++, pArena
++)
690 if ((pArena
->size
!= 0) && (pArena
->hOwner
== owner
))
691 GlobalFree16( pArena
->handle
);
696 /***********************************************************************
697 * GlobalWire (KERNEL.111)
698 * GlobalWire16 (KERNEL32.29)
700 SEGPTR WINAPI
GlobalWire16( HGLOBAL16 handle
)
702 return WIN16_GlobalLock16( handle
);
706 /***********************************************************************
707 * GlobalUnWire (KERNEL.112)
708 * GlobalUnWire16 (KERNEL32.30)
710 BOOL16 WINAPI
GlobalUnWire16( HGLOBAL16 handle
)
712 return !GlobalUnlock16( handle
);
716 /***********************************************************************
717 * SetSwapAreaSize (KERNEL.106)
719 LONG WINAPI
SetSwapAreaSize16( WORD size
)
721 FIXME("(%d) - stub!\n", size
);
722 return MAKELONG( size
, 0xffff );
726 /***********************************************************************
727 * GlobalLRUOldest (KERNEL.163)
729 HGLOBAL16 WINAPI
GlobalLRUOldest16( HGLOBAL16 handle
)
731 TRACE("%04x\n", handle
);
732 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
737 /***********************************************************************
738 * GlobalLRUNewest (KERNEL.164)
740 HGLOBAL16 WINAPI
GlobalLRUNewest16( HGLOBAL16 handle
)
742 TRACE("%04x\n", handle
);
743 if (handle
== (HGLOBAL16
)-1) handle
= CURRENT_DS
;
748 /***********************************************************************
749 * GetFreeSpace (KERNEL.169)
751 DWORD WINAPI
GetFreeSpace16( UINT16 wFlags
)
754 GlobalMemoryStatus( &ms
);
755 return min( ms
.dwAvailVirtual
, MAXLONG
);
758 /***********************************************************************
759 * GlobalDOSAlloc (KERNEL.184)
761 * Allocate memory in the first MB.
764 * Address (HW=Paragraph segment; LW=Selector)
766 DWORD WINAPI
GlobalDOSAlloc16(
767 DWORD size
/* [in] Number of bytes to be allocated */
770 LPVOID lpBlock
= DOSMEM_AllocBlock( size
, &uParagraph
);
774 HMODULE16 hModule
= GetModuleHandle16("KERNEL");
778 wSelector
= GLOBAL_CreateBlock(GMEM_FIXED
, lpBlock
, size
, hModule
, LDT_FLAGS_DATA
);
779 pArena
= GET_ARENA_PTR(wSelector
);
780 pArena
->flags
|= GA_DOSMEM
;
781 return MAKELONG(wSelector
,uParagraph
);
787 /***********************************************************************
788 * GlobalDOSFree (KERNEL.185)
790 * Free memory allocated with GlobalDOSAlloc
796 WORD WINAPI
GlobalDOSFree16(
797 WORD sel
/* [in] Selector */
799 DWORD block
= GetSelectorBase(sel
);
801 if( block
&& block
< 0x100000 )
803 LPVOID lpBlock
= DOSMEM_MapDosToLinear( block
);
804 if( DOSMEM_FreeBlock( lpBlock
) )
805 GLOBAL_FreeBlock( sel
);
812 /***********************************************************************
813 * GlobalPageLock (KERNEL.191)
814 * GlobalSmartPageLock(KERNEL.230)
816 WORD WINAPI
GlobalPageLock16( HGLOBAL16 handle
)
818 TRACE("%04x\n", handle
);
819 if (!VALID_HANDLE(handle
)) {
820 WARN("Invalid handle 0x%04x passed to GlobalPageLock!\n",handle
);
823 return ++(GET_ARENA_PTR(handle
)->pageLockCount
);
827 /***********************************************************************
828 * GlobalPageUnlock (KERNEL.192)
829 * GlobalSmartPageUnlock(KERNEL.231)
831 WORD WINAPI
GlobalPageUnlock16( HGLOBAL16 handle
)
833 TRACE("%04x\n", handle
);
834 if (!VALID_HANDLE(handle
)) {
835 WARN("Invalid handle 0x%04x passed to GlobalPageUnlock!\n",handle
);
838 return --(GET_ARENA_PTR(handle
)->pageLockCount
);
842 /***********************************************************************
843 * GlobalFix (KERNEL.197)
844 * GlobalFix16 (KERNEL32.27)
846 WORD WINAPI
GlobalFix16( HGLOBAL16 handle
)
848 TRACE("%04x\n", handle
);
849 if (!VALID_HANDLE(handle
)) {
850 WARN("Invalid handle 0x%04x passed to GlobalFix16!\n",handle
);
853 GET_ARENA_PTR(handle
)->lockCount
++;
855 return GlobalHandleToSel16(handle
);
859 /***********************************************************************
860 * GlobalUnfix (KERNEL.198)
861 * GlobalUnfix16 (KERNEL32.28)
863 void WINAPI
GlobalUnfix16( HGLOBAL16 handle
)
865 TRACE("%04x\n", handle
);
866 if (!VALID_HANDLE(handle
)) {
867 WARN("Invalid handle 0x%04x passed to GlobalUnfix16!\n",handle
);
870 GET_ARENA_PTR(handle
)->lockCount
--;
874 /***********************************************************************
875 * FarSetOwner (KERNEL.403)
877 void WINAPI
FarSetOwner16( HGLOBAL16 handle
, HANDLE16 hOwner
)
879 if (!VALID_HANDLE(handle
)) {
880 WARN("Invalid handle 0x%04x passed to FarSetOwner!\n",handle
);
883 GET_ARENA_PTR(handle
)->hOwner
= hOwner
;
887 /***********************************************************************
888 * FarGetOwner (KERNEL.404)
890 HANDLE16 WINAPI
FarGetOwner16( HGLOBAL16 handle
)
892 if (!VALID_HANDLE(handle
)) {
893 WARN("Invalid handle 0x%04x passed to FarGetOwner!\n",handle
);
896 return GET_ARENA_PTR(handle
)->hOwner
;
900 /************************************************************************
901 * GlobalMasterHandle (KERNEL.28)
904 * Should return selector and handle of the information structure for
905 * the global heap. selector and handle are stored in the THHOOK as
906 * pGlobalHeap and hGlobalHeap.
907 * As Wine doesn't have this structure, we return both values as zero
908 * Applications should interpret this as "No Global Heap"
910 DWORD WINAPI
GlobalMasterHandle16(void)
916 /***********************************************************************
917 * GlobalHandleToSel (TOOLHELP.50)
919 * FIXME: This is in TOOLHELP but we keep a copy here for now.
921 WORD WINAPI
GlobalHandleToSel16( HGLOBAL16 handle
)
923 if (!handle
) return 0;
924 if (!VALID_HANDLE(handle
)) {
925 WARN("Invalid handle 0x%04x passed to GlobalHandleToSel!\n",handle
);
930 WARN("Program attempted invalid selector conversion\n" );
937 /***********************************************************************
938 * GetFreeMemInfo (KERNEL.316)
940 DWORD WINAPI
GetFreeMemInfo16(void)
942 SYSTEM_BASIC_INFORMATION info
;
945 NtQuerySystemInformation( SystemBasicInformation
, &info
, sizeof(info
), NULL
);
946 GlobalMemoryStatus( &status
);
947 return MAKELONG( status
.dwTotalVirtual
/ info
.PageSize
, status
.dwAvailVirtual
/ info
.PageSize
);
950 /***********************************************************************
951 * A20Proc (KERNEL.165)
953 void WINAPI
A20Proc16( WORD unused
)
955 /* this is also a NOP in Windows */
958 /***********************************************************************
959 * LimitEMSPages (KERNEL.156)
961 DWORD WINAPI
LimitEMSPages16( DWORD unused
)