blob: 8a4ef73a5341e87371b942855ec8d89468c77355 [file] [log] [blame]
Alexandre Julliard234bc241994-12-10 13:02:28 +00001/*
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002 * Global heap functions
3 *
4 * Copyright 1995 Alexandre Julliard
5 */
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00006/* 0xffff sometimes seems to mean: CURRENT_DS */
Alexandre Julliard121bd981993-07-08 17:37:25 +00007
Alexandre Julliard808cb041995-08-17 17:11:36 +00008#include <sys/types.h>
Alexandre Julliard121bd981993-07-08 17:37:25 +00009#include <stdlib.h>
Marcus Meissner6189c192000-03-04 19:19:15 +000010#include <time.h>
Alexandre Julliard383da682000-02-10 22:15:21 +000011#include <stdio.h>
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000012#include <unistd.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000013#include <string.h>
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000014
Marcus Meissner04c3e1d1999-02-19 10:37:02 +000015#include "wine/winbase16.h"
Lawson Whitney969515d2000-10-02 22:27:37 +000016#include "wine/exception.h"
Alexandre Julliard982a2232000-12-13 20:20:09 +000017#include "wine/port.h"
Alexandre Julliard2787be81995-05-22 18:23:01 +000018#include "global.h"
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +000019#include "toolhelp.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000020#include "selectors.h"
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +000021#include "miscemu.h"
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000022#include "stackframe.h"
Alexandre Julliard77b99181997-09-14 17:17:23 +000023#include "module.h"
Alexandre Julliard15657091999-05-23 10:25:25 +000024#include "debugtools.h"
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +000025#include "winerror.h"
Alexandre Julliardaca05781994-10-17 18:12:41 +000026
Alexandre Julliard383da682000-02-10 22:15:21 +000027DEFAULT_DEBUG_CHANNEL(global);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000028
Alexandre Julliardfa68b751995-04-03 16:55:37 +000029 /* Global arena block */
30typedef struct
31{
Alexandre Julliard1285c2f1996-05-06 16:06:24 +000032 DWORD base; /* Base address (0 if discarded) */
33 DWORD size; /* Size in bytes (0 indicates a free block) */
34 HGLOBAL16 handle; /* Handle for this block */
35 HGLOBAL16 hOwner; /* Owner of this block */
36 BYTE lockCount; /* Count of GlobalFix() calls */
37 BYTE pageLockCount; /* Count of GlobalPageLock() calls */
38 BYTE flags; /* Allocation flags */
39 BYTE selCount; /* Number of selectors allocated for this block */
Alexandre Julliardfa68b751995-04-03 16:55:37 +000040} GLOBALARENA;
41
42 /* Flags definitions */
Alexandre Julliard2787be81995-05-22 18:23:01 +000043#define GA_MOVEABLE 0x02 /* same as GMEM_MOVEABLE */
Alexandre Julliardfa68b751995-04-03 16:55:37 +000044#define GA_DGROUP 0x04
45#define GA_DISCARDABLE 0x08
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000046#define GA_IPCSHARE 0x10 /* same as GMEM_DDESHARE */
Andreas Mohrd23f5062000-10-02 22:16:21 +000047#define GA_DOSMEM 0x20
Alexandre Julliardfa68b751995-04-03 16:55:37 +000048
49 /* Arena array */
50static GLOBALARENA *pGlobalArena = NULL;
51static int globalArenaSize = 0;
52
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000053#define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000 /* Largest allocation is 16M - 64K */
Alexandre Julliard121bd981993-07-08 17:37:25 +000054
Alexandre Julliarda11d7b11998-03-01 20:05:02 +000055#define VALID_HANDLE(handle) (((handle)>>__AHSHIFT)<globalArenaSize)
Alexandre Julliardfa68b751995-04-03 16:55:37 +000056#define GET_ARENA_PTR(handle) (pGlobalArena + ((handle) >> __AHSHIFT))
Alexandre Julliard75a839a1993-07-15 11:13:45 +000057
Lawson Whitney969515d2000-10-02 22:27:37 +000058/* filter for page-fault exceptions */
59/* It is possible for a bogus global pointer to cause a */
60/* page zero reference, so I include EXCEPTION_PRIV_INSTRUCTION too. */
61
62static WINE_EXCEPTION_FILTER(page_fault)
63{
64 switch (GetExceptionCode()) {
65 case (EXCEPTION_ACCESS_VIOLATION):
66 case (EXCEPTION_PRIV_INSTRUCTION):
67 return EXCEPTION_EXECUTE_HANDLER;
68 default:
69 return EXCEPTION_CONTINUE_SEARCH;
70 }
71}
72
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000073/***********************************************************************
Alexandre Julliardfa68b751995-04-03 16:55:37 +000074 * GLOBAL_GetArena
75 *
76 * Return the arena for a given selector, growing the arena array if needed.
Alexandre Julliarddba420a1994-02-02 06:48:31 +000077 */
Alexandre Julliardfa68b751995-04-03 16:55:37 +000078static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount )
Alexandre Julliarddba420a1994-02-02 06:48:31 +000079{
Alexandre Julliard2787be81995-05-22 18:23:01 +000080 if (((sel >> __AHSHIFT) + selcount) > globalArenaSize)
Alexandre Julliardfa68b751995-04-03 16:55:37 +000081 {
Alexandre Julliard2787be81995-05-22 18:23:01 +000082 int newsize = ((sel >> __AHSHIFT) + selcount + 0xff) & ~0xff;
Alexandre Julliardfa68b751995-04-03 16:55:37 +000083 GLOBALARENA *pNewArena = realloc( pGlobalArena,
Alexandre Julliard2787be81995-05-22 18:23:01 +000084 newsize * sizeof(GLOBALARENA) );
Alexandre Julliardfa68b751995-04-03 16:55:37 +000085 if (!pNewArena) return 0;
86 pGlobalArena = pNewArena;
Alexandre Julliard2787be81995-05-22 18:23:01 +000087 memset( pGlobalArena + globalArenaSize, 0,
88 (newsize - globalArenaSize) * sizeof(GLOBALARENA) );
89 globalArenaSize = newsize;
Alexandre Julliardfa68b751995-04-03 16:55:37 +000090 }
91 return pGlobalArena + (sel >> __AHSHIFT);
92}
Alexandre Julliarddba420a1994-02-02 06:48:31 +000093
Juergen Schmiedebc2b771998-11-14 18:59:30 +000094void debug_handles(void)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000095{
96 int printed=0;
97 int i;
98 for (i = globalArenaSize-1 ; i>=0 ; i--) {
99 if (pGlobalArena[i].size!=0 && (pGlobalArena[i].handle & 0x8000)){
100 printed=1;
Alexandre Julliard15657091999-05-23 10:25:25 +0000101 DPRINTF("0x%08x, ",pGlobalArena[i].handle);
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000102 }
103 }
104 if (printed)
Alexandre Julliard15657091999-05-23 10:25:25 +0000105 DPRINTF("\n");
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000106}
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000107
108
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000109/***********************************************************************
Alexandre Julliard594997c1995-04-30 10:05:20 +0000110 * GLOBAL_CreateBlock
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000111 *
Alexandre Julliard594997c1995-04-30 10:05:20 +0000112 * Create a global heap block for a fixed range of linear memory.
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000113 */
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000114HGLOBAL16 GLOBAL_CreateBlock( WORD flags, const void *ptr, DWORD size,
Alexandre Julliard914406f2000-11-14 01:54:49 +0000115 HGLOBAL16 hOwner, unsigned char selflags )
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000116{
117 WORD sel, selcount;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000118 GLOBALARENA *pArena;
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000119
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000120 /* Allocate the selector(s) */
121
Alexandre Julliard914406f2000-11-14 01:54:49 +0000122 sel = SELECTOR_AllocBlock( ptr, size, selflags );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000123 if (!sel) return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000124 selcount = (size + 0xffff) / 0x10000;
125
126 if (!(pArena = GLOBAL_GetArena( sel, selcount )))
127 {
Alexandre Julliard914406f2000-11-14 01:54:49 +0000128 SELECTOR_FreeBlock( sel );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000129 return 0;
130 }
131
132 /* Fill the arena block */
133
134 pArena->base = (DWORD)ptr;
Alexandre Julliard8c540c62000-11-13 04:16:05 +0000135 pArena->size = GetSelectorLimit16(sel) + 1;
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000136 pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000137 pArena->hOwner = hOwner;
138 pArena->lockCount = 0;
139 pArena->pageLockCount = 0;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000140 pArena->flags = flags & GA_MOVEABLE;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000141 if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000142 if (flags & GMEM_DDESHARE) pArena->flags |= GA_IPCSHARE;
Alexandre Julliard914406f2000-11-14 01:54:49 +0000143 if (!(selflags & (WINE_LDT_FLAGS_CODE^WINE_LDT_FLAGS_DATA))) pArena->flags |= GA_DGROUP;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000144 pArena->selCount = selcount;
145 if (selcount > 1) /* clear the next arena blocks */
146 memset( pArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000147
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000148 return pArena->handle;
149}
Alexandre Julliard121bd981993-07-08 17:37:25 +0000150
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000151
152/***********************************************************************
Alexandre Julliard594997c1995-04-30 10:05:20 +0000153 * GLOBAL_FreeBlock
154 *
155 * Free a block allocated by GLOBAL_CreateBlock, without touching
156 * the associated linear memory range.
157 */
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000158BOOL16 GLOBAL_FreeBlock( HGLOBAL16 handle )
Alexandre Julliard594997c1995-04-30 10:05:20 +0000159{
160 WORD sel;
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000161 GLOBALARENA *pArena;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000162
163 if (!handle) return TRUE;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000164 sel = GlobalHandleToSel16( handle );
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000165 if (!VALID_HANDLE(sel))
166 return FALSE;
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000167 pArena = GET_ARENA_PTR(sel);
Alexandre Julliard914406f2000-11-14 01:54:49 +0000168 SELECTOR_FreeBlock( sel );
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000169 memset( pArena, 0, sizeof(GLOBALARENA) );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000170 return TRUE;
171}
172
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000173/***********************************************************************
174 * GLOBAL_MoveBlock
175 */
176BOOL16 GLOBAL_MoveBlock( HGLOBAL16 handle, const void *ptr, DWORD size )
177{
178 WORD sel;
179 GLOBALARENA *pArena;
180
181 if (!handle) return TRUE;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000182 sel = GlobalHandleToSel16( handle );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000183 if (!VALID_HANDLE(sel))
184 return FALSE;
185 pArena = GET_ARENA_PTR(sel);
186 if (pArena->selCount != 1)
187 return FALSE;
188
189 pArena->base = (DWORD)ptr;
190 pArena->size = size;
Alexandre Julliard914406f2000-11-14 01:54:49 +0000191 SELECTOR_ReallocBlock( sel, ptr, size );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000192 return TRUE;
193}
Alexandre Julliard594997c1995-04-30 10:05:20 +0000194
195/***********************************************************************
196 * GLOBAL_Alloc
197 *
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000198 * Implementation of GlobalAlloc16()
Alexandre Julliard594997c1995-04-30 10:05:20 +0000199 */
Alexandre Julliard914406f2000-11-14 01:54:49 +0000200HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner, unsigned char selflags )
Alexandre Julliard594997c1995-04-30 10:05:20 +0000201{
202 void *ptr;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000203 HGLOBAL16 handle;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000204
Alexandre Julliard15657091999-05-23 10:25:25 +0000205 TRACE("%ld flags=%04x\n", size, flags );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000206
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000207 /* If size is 0, create a discarded block */
208
Alexandre Julliard914406f2000-11-14 01:54:49 +0000209 if (size == 0) return GLOBAL_CreateBlock( flags, NULL, 1, hOwner, selflags );
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000210
211 /* Fixup the size */
Alexandre Julliard594997c1995-04-30 10:05:20 +0000212
Alexandre Julliarda2f2e011995-06-06 16:40:35 +0000213 if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x1f) return 0;
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000214 size = (size + 0x1f) & ~0x1f;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000215
Marcus Meissnere32a3171999-07-11 14:13:56 +0000216 /* Allocate the linear memory */
Alexandre Julliard079fd722000-01-25 01:41:35 +0000217 ptr = HeapAlloc( GetProcessHeap(), 0, size );
Alexandre Julliard77b99181997-09-14 17:17:23 +0000218 /* FIXME: free discardable blocks and try again? */
Alexandre Julliard594997c1995-04-30 10:05:20 +0000219 if (!ptr) return 0;
220
221 /* Allocate the selector(s) */
222
Alexandre Julliard914406f2000-11-14 01:54:49 +0000223 handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner, selflags );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000224 if (!handle)
225 {
Alexandre Julliard079fd722000-01-25 01:41:35 +0000226 HeapFree( GetProcessHeap(), 0, ptr );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000227 return 0;
228 }
229
230 if (flags & GMEM_ZEROINIT) memset( ptr, 0, size );
231 return handle;
232}
233
Alexandre Julliard594997c1995-04-30 10:05:20 +0000234/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000235 * GlobalAlloc (KERNEL.15)
236 * GlobalAlloc16 (KERNEL32.24)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000237 * RETURNS
238 * Handle: Success
239 * NULL: Failure
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000240 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000241HGLOBAL16 WINAPI GlobalAlloc16(
242 UINT16 flags, /* [in] Object allocation attributes */
243 DWORD size /* [in] Number of bytes to allocate */
244) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000245 HANDLE16 owner = GetCurrentPDB16();
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000246
Alexandre Julliard594997c1995-04-30 10:05:20 +0000247 if (flags & GMEM_DDESHARE)
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000248 owner = GetExePtr(owner); /* Make it a module handle */
Alexandre Julliard914406f2000-11-14 01:54:49 +0000249 return GLOBAL_Alloc( flags, size, owner, WINE_LDT_FLAGS_DATA );
Alexandre Julliard121bd981993-07-08 17:37:25 +0000250}
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000251
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000252
253/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000254 * GlobalReAlloc (KERNEL.16)
255 * GlobalReAlloc16 (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000256 * RETURNS
257 * Handle: Success
258 * NULL: Failure
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000259 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000260HGLOBAL16 WINAPI GlobalReAlloc16(
261 HGLOBAL16 handle, /* [in] Handle of global memory object */
262 DWORD size, /* [in] New size of block */
263 UINT16 flags /* [in] How to reallocate object */
264) {
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000265 WORD selcount;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000266 DWORD oldsize;
267 void *ptr;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000268 GLOBALARENA *pArena, *pNewArena;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000269 WORD sel = GlobalHandleToSel16( handle );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000270
Alexandre Julliard15657091999-05-23 10:25:25 +0000271 TRACE("%04x %ld flags=%04x\n",
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000272 handle, size, flags );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000273 if (!handle) return 0;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000274
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000275 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000276 WARN("Invalid handle 0x%04x!\n", handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000277 return 0;
278 }
Alexandre Julliard594997c1995-04-30 10:05:20 +0000279 pArena = GET_ARENA_PTR( handle );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000280
Alexandre Julliard2787be81995-05-22 18:23:01 +0000281 /* Discard the block if requested */
282
Alexandre Julliardded30381995-07-06 17:18:27 +0000283 if ((size == 0) && (flags & GMEM_MOVEABLE) && !(flags & GMEM_MODIFY))
Alexandre Julliard2787be81995-05-22 18:23:01 +0000284 {
285 if (!(pArena->flags & GA_MOVEABLE) ||
286 !(pArena->flags & GA_DISCARDABLE) ||
287 (pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
Alexandre Julliard079fd722000-01-25 01:41:35 +0000288 HeapFree( GetProcessHeap(), 0, (void *)pArena->base );
Alexandre Julliard2787be81995-05-22 18:23:01 +0000289 pArena->base = 0;
Alexandre Julliard77b99181997-09-14 17:17:23 +0000290
291 /* Note: we rely on the fact that SELECTOR_ReallocBlock won't
292 * change the selector if we are shrinking the block.
293 * FIXME: shouldn't we keep selectors until the block is deleted?
294 */
Alexandre Julliard284c9b91999-04-11 15:07:13 +0000295 SELECTOR_ReallocBlock( sel, 0, 1 );
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000296 return handle;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000297 }
298
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000299 /* Fixup the size */
300
Alexandre Julliard2787be81995-05-22 18:23:01 +0000301 if (size > GLOBAL_MAX_ALLOC_SIZE - 0x20) return 0;
302 if (size == 0) size = 0x20;
303 else size = (size + 0x1f) & ~0x1f;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000304
Alexandre Julliard594997c1995-04-30 10:05:20 +0000305 /* Change the flags */
306
307 if (flags & GMEM_MODIFY)
308 {
309 /* Change the flags, leaving GA_DGROUP alone */
Alexandre Julliard2787be81995-05-22 18:23:01 +0000310 pArena->flags = (pArena->flags & GA_DGROUP) | (flags & GA_MOVEABLE);
Alexandre Julliard594997c1995-04-30 10:05:20 +0000311 if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
312 return handle;
313 }
314
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000315 /* Reallocate the linear memory */
316
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000317 ptr = (void *)pArena->base;
318 oldsize = pArena->size;
Alexandre Julliard15657091999-05-23 10:25:25 +0000319 TRACE("oldsize %08lx\n",oldsize);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +0000320 if (ptr && (size == oldsize)) return handle; /* Nothing to do */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000321
Andreas Mohrd23f5062000-10-02 22:16:21 +0000322 if (pArena->flags & GA_DOSMEM)
Ove Kaaven7b499142000-07-28 22:23:59 +0000323 ptr = DOSMEM_ResizeBlock(ptr, size, NULL);
Bertho Stultiensc1d1cfe1999-04-18 12:14:06 +0000324 else
Alexandre Julliard079fd722000-01-25 01:41:35 +0000325 ptr = HeapReAlloc( GetProcessHeap(), 0, ptr, size );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000326 if (!ptr)
327 {
Alexandre Julliard914406f2000-11-14 01:54:49 +0000328 SELECTOR_FreeBlock( sel );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000329 memset( pArena, 0, sizeof(GLOBALARENA) );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000330 return 0;
331 }
332
333 /* Reallocate the selector(s) */
334
Alexandre Julliard284c9b91999-04-11 15:07:13 +0000335 sel = SELECTOR_ReallocBlock( sel, ptr, size );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000336 if (!sel)
337 {
Alexandre Julliard079fd722000-01-25 01:41:35 +0000338 HeapFree( GetProcessHeap(), 0, ptr );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000339 memset( pArena, 0, sizeof(GLOBALARENA) );
340 return 0;
341 }
342 selcount = (size + 0xffff) / 0x10000;
343
344 if (!(pNewArena = GLOBAL_GetArena( sel, selcount )))
345 {
Alexandre Julliard079fd722000-01-25 01:41:35 +0000346 HeapFree( GetProcessHeap(), 0, ptr );
Alexandre Julliard914406f2000-11-14 01:54:49 +0000347 SELECTOR_FreeBlock( sel );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000348 return 0;
349 }
350
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000351 /* Fill the new arena block */
352
353 if (pNewArena != pArena) memcpy( pNewArena, pArena, sizeof(GLOBALARENA) );
354 pNewArena->base = (DWORD)ptr;
Alexandre Julliard8c540c62000-11-13 04:16:05 +0000355 pNewArena->size = GetSelectorLimit16(sel) + 1;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000356 pNewArena->selCount = selcount;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000357 pNewArena->handle = (pNewArena->flags & GA_MOVEABLE) ? sel - 1 : sel;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000358
359 if (selcount > 1) /* clear the next arena blocks */
360 memset( pNewArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );
361
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000362 if ((oldsize < size) && (flags & GMEM_ZEROINIT))
363 memset( (char *)ptr + oldsize, 0, size - oldsize );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000364 return pNewArena->handle;
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000365}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000366
367
368/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000369 * GlobalFree (KERNEL.17)
370 * GlobalFree16 (KERNEL32.31)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000371 * RETURNS
372 * NULL: Success
373 * Handle: Failure
Alexandre Julliard121bd981993-07-08 17:37:25 +0000374 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000375HGLOBAL16 WINAPI GlobalFree16(
376 HGLOBAL16 handle /* [in] Handle of global memory object */
377) {
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000378 void *ptr;
Alexandre Julliard121bd981993-07-08 17:37:25 +0000379
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000380 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000381 WARN("Invalid handle 0x%04x passed to GlobalFree16!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000382 return 0;
383 }
384 ptr = (void *)GET_ARENA_PTR(handle)->base;
385
Alexandre Julliard15657091999-05-23 10:25:25 +0000386 TRACE("%04x\n", handle );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000387 if (!GLOBAL_FreeBlock( handle )) return handle; /* failed */
Alexandre Julliard079fd722000-01-25 01:41:35 +0000388 if (ptr) HeapFree( GetProcessHeap(), 0, ptr );
Alexandre Julliard121bd981993-07-08 17:37:25 +0000389 return 0;
390}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000391
392
393/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000394 * GlobalLock (KERNEL.18)
Alexandre Julliard121bd981993-07-08 17:37:25 +0000395 *
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000396 * This is the GlobalLock16() function used by 16-bit code.
Alexandre Julliard121bd981993-07-08 17:37:25 +0000397 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000398SEGPTR WINAPI WIN16_GlobalLock16( HGLOBAL16 handle )
Alexandre Julliard121bd981993-07-08 17:37:25 +0000399{
Ulrich Weigandb2682d41999-07-27 16:10:24 +0000400 WORD sel = GlobalHandleToSel16( handle );
401 TRACE("(%04x) -> %08lx\n", handle, MAKELONG( 0, sel ) );
402
Alexandre Julliard77b99181997-09-14 17:17:23 +0000403 if (handle)
404 {
405 if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000406
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000407 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000408 WARN("Invalid handle 0x%04x passed to WIN16_GlobalLock16!\n",handle);
Ulrich Weigandb2682d41999-07-27 16:10:24 +0000409 sel = 0;
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000410 }
Ulrich Weigand81a80571999-07-28 16:36:29 +0000411 else if (!GET_ARENA_PTR(handle)->base)
Ulrich Weigandb2682d41999-07-27 16:10:24 +0000412 sel = 0;
413 else
414 GET_ARENA_PTR(handle)->lockCount++;
Alexandre Julliard77b99181997-09-14 17:17:23 +0000415 }
Ulrich Weigandb2682d41999-07-27 16:10:24 +0000416
417 CURRENT_STACK16->ecx = sel; /* selector must be returned in CX as well */
Alexandre Julliard982a2232000-12-13 20:20:09 +0000418 return MAKESEGPTR( sel, 0 );
Alexandre Julliard121bd981993-07-08 17:37:25 +0000419}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000420
421
Alexandre Julliard58017232000-12-22 01:09:26 +0000422/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000423 * K32WOWGlobalLock16 (KERNEL32.60)
Alexandre Julliard58017232000-12-22 01:09:26 +0000424 */
425SEGPTR WINAPI K32WOWGlobalLock16( HGLOBAL16 hMem )
426{
427 return WIN16_GlobalLock16( hMem );
428}
429
430
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000431/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000432 * GlobalLock16 (KERNEL32.25)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000433 *
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000434 * This is the GlobalLock16() function used by 32-bit code.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000435 *
436 * RETURNS
437 * Pointer to first byte of memory block
438 * NULL: Failure
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000439 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000440LPVOID WINAPI GlobalLock16(
441 HGLOBAL16 handle /* [in] Handle of global memory object */
442) {
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000443 if (!handle) return 0;
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000444 if (!VALID_HANDLE(handle))
445 return (LPVOID)0;
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000446 GET_ARENA_PTR(handle)->lockCount++;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000447 return (LPVOID)GET_ARENA_PTR(handle)->base;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000448}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000449
450
451/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000452 * GlobalUnlock (KERNEL.19)
453 * GlobalUnlock16 (KERNEL32.26)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000454 * NOTES
455 * Should the return values be cast to booleans?
456 *
457 * RETURNS
458 * TRUE: Object is still locked
459 * FALSE: Object is unlocked
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000460 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000461BOOL16 WINAPI GlobalUnlock16(
462 HGLOBAL16 handle /* [in] Handle of global memory object */
463) {
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000464 GLOBALARENA *pArena = GET_ARENA_PTR(handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000465 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000466 WARN("Invalid handle 0x%04x passed to GlobalUnlock16!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000467 return 0;
468 }
Alexandre Julliard15657091999-05-23 10:25:25 +0000469 TRACE("%04x\n", handle );
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000470 if (pArena->lockCount) pArena->lockCount--;
471 return pArena->lockCount;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000472}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000473
Ulrich Weigand23e9b041998-12-01 15:19:54 +0000474/***********************************************************************
475 * GlobalChangeLockCount (KERNEL.365)
476 *
477 * This is declared as a register function as it has to preserve
478 * *all* registers, even AX/DX !
479 *
480 */
Ulrich Weigandb5151d01999-07-25 11:27:36 +0000481void WINAPI GlobalChangeLockCount16( HGLOBAL16 handle, INT16 delta,
482 CONTEXT86 *context )
Ulrich Weigand23e9b041998-12-01 15:19:54 +0000483{
Ulrich Weigand23e9b041998-12-01 15:19:54 +0000484 if ( delta == 1 )
485 GlobalLock16( handle );
486 else if ( delta == -1 )
487 GlobalUnlock16( handle );
488 else
Alexandre Julliard15657091999-05-23 10:25:25 +0000489 ERR("(%04X, %d): strange delta value\n", handle, delta );
Ulrich Weigand23e9b041998-12-01 15:19:54 +0000490}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000491
492/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000493 * GlobalSize (KERNEL.20)
494 * GlobalSize16 (KERNEL32.32)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000495 * RETURNS
496 * Size in bytes of object
497 * 0: Failure
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000498 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000499DWORD WINAPI GlobalSize16(
500 HGLOBAL16 handle /* [in] Handle of global memory object */
501) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000502 TRACE("%04x\n", handle );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000503 if (!handle) return 0;
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000504 if (!VALID_HANDLE(handle))
505 return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000506 return GET_ARENA_PTR(handle)->size;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000507}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000508
509
510/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000511 * GlobalHandle (KERNEL.21)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000512 * NOTES
513 * Why is GlobalHandleToSel used here with the sel as input?
514 *
515 * RETURNS
516 * Handle: Success
517 * NULL: Failure
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000518 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000519DWORD WINAPI GlobalHandle16(
520 WORD sel /* [in] Address of global memory block */
521) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000522 TRACE("%04x\n", sel );
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000523 if (!VALID_HANDLE(sel)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000524 WARN("Invalid handle 0x%04x passed to GlobalHandle16!\n",sel);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000525 return 0;
526 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000527 return MAKELONG( GET_ARENA_PTR(sel)->handle, GlobalHandleToSel16(sel) );
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000528}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000529
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000530/***********************************************************************
531 * GlobalHandleNoRIP (KERNEL.159)
532 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000533DWORD WINAPI GlobalHandleNoRIP16( WORD sel )
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000534{
535 int i;
536 for (i = globalArenaSize-1 ; i>=0 ; i--) {
537 if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == sel)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000538 return MAKELONG( GET_ARENA_PTR(sel)->handle, GlobalHandleToSel16(sel) );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000539 }
540 return 0;
541}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000542
Alexandre Julliard54c27111998-03-29 19:44:57 +0000543
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000544/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000545 * GlobalFlags (KERNEL.22)
546 * GlobalFlags16 (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000547 * NOTES
548 * Should this return GMEM_INVALID_HANDLE instead of 0 on invalid
549 * handle?
550 *
551 * RETURNS
552 * Value specifying flags and lock count
553 * GMEM_INVALID_HANDLE: Invalid handle
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000554 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000555UINT16 WINAPI GlobalFlags16(
556 HGLOBAL16 handle /* [in] Handle of global memory object */
557) {
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000558 GLOBALARENA *pArena;
559
Alexandre Julliard15657091999-05-23 10:25:25 +0000560 TRACE("%04x\n", handle );
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000561 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000562 WARN("Invalid handle 0x%04x passed to GlobalFlags16!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000563 return 0;
564 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000565 pArena = GET_ARENA_PTR(handle);
566 return pArena->lockCount |
Alexandre Julliard2787be81995-05-22 18:23:01 +0000567 ((pArena->flags & GA_DISCARDABLE) ? GMEM_DISCARDABLE : 0) |
568 ((pArena->base == 0) ? GMEM_DISCARDED : 0);
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000569}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000570
571
572/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000573 * LockSegment (KERNEL.23)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000574 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000575HGLOBAL16 WINAPI LockSegment16( HGLOBAL16 handle )
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000576{
Alexandre Julliard15657091999-05-23 10:25:25 +0000577 TRACE("%04x\n", handle );
Alexandre Julliard3051b641996-07-05 17:14:13 +0000578 if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000579 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000580 WARN("Invalid handle 0x%04x passed to LockSegment16!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000581 return 0;
582 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000583 GET_ARENA_PTR(handle)->lockCount++;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000584 return handle;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000585}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000586
587
588/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000589 * UnlockSegment (KERNEL.24)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000590 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000591void WINAPI UnlockSegment16( HGLOBAL16 handle )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000592{
Alexandre Julliard15657091999-05-23 10:25:25 +0000593 TRACE("%04x\n", handle );
Alexandre Julliard3051b641996-07-05 17:14:13 +0000594 if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000595 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000596 WARN("Invalid handle 0x%04x passed to UnlockSegment16!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000597 return;
598 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000599 GET_ARENA_PTR(handle)->lockCount--;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000600 /* FIXME: this ought to return the lock count in CX (go figure...) */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000601}
Alexandre Julliard401710d1993-09-04 10:09:32 +0000602
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000603
604/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000605 * GlobalCompact (KERNEL.25)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000606 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000607DWORD WINAPI GlobalCompact16( DWORD desired )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000608{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000609 return GLOBAL_MAX_ALLOC_SIZE;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000610}
611
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000612
613/***********************************************************************
Alexandre Julliard594997c1995-04-30 10:05:20 +0000614 * GlobalFreeAll (KERNEL.26)
615 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000616void WINAPI GlobalFreeAll16( HGLOBAL16 owner )
Alexandre Julliard594997c1995-04-30 10:05:20 +0000617{
618 DWORD i;
619 GLOBALARENA *pArena;
620
621 pArena = pGlobalArena;
622 for (i = 0; i < globalArenaSize; i++, pArena++)
623 {
624 if ((pArena->size != 0) && (pArena->hOwner == owner))
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000625 GlobalFree16( pArena->handle );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000626 }
627}
628
629
630/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000631 * GlobalWire (KERNEL.111)
632 * GlobalWire16 (KERNEL32.29)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000633 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000634SEGPTR WINAPI GlobalWire16( HGLOBAL16 handle )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000635{
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000636 return WIN16_GlobalLock16( handle );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000637}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000638
639
640/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000641 * GlobalUnWire (KERNEL.112)
642 * GlobalUnWire16 (KERNEL32.30)
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000643 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000644BOOL16 WINAPI GlobalUnWire16( HGLOBAL16 handle )
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000645{
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000646 return !GlobalUnlock16( handle );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000647}
Alexandre Julliardaca05781994-10-17 18:12:41 +0000648
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000649
650/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000651 * SetSwapAreaSize (KERNEL.106)
Alexandre Julliardaca05781994-10-17 18:12:41 +0000652 */
Alexandre Julliarde658d821997-11-30 17:45:40 +0000653LONG WINAPI SetSwapAreaSize16( WORD size )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000654{
Alexandre Julliard15657091999-05-23 10:25:25 +0000655 FIXME("(%d) - stub!\n", size );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000656 return MAKELONG( size, 0xffff );
657}
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000658
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000659
660/***********************************************************************
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000661 * GlobalLRUOldest (KERNEL.163)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000662 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000663HGLOBAL16 WINAPI GlobalLRUOldest16( HGLOBAL16 handle )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000664{
Alexandre Julliard15657091999-05-23 10:25:25 +0000665 TRACE("%04x\n", handle );
Alexandre Julliard3051b641996-07-05 17:14:13 +0000666 if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000667 return handle;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000668}
669
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000670
671/***********************************************************************
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000672 * GlobalLRUNewest (KERNEL.164)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000673 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000674HGLOBAL16 WINAPI GlobalLRUNewest16( HGLOBAL16 handle )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000675{
Alexandre Julliard15657091999-05-23 10:25:25 +0000676 TRACE("%04x\n", handle );
Alexandre Julliard3051b641996-07-05 17:14:13 +0000677 if (handle == (HGLOBAL16)-1) handle = CURRENT_DS;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000678 return handle;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000679}
680
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000681
682/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000683 * GetFreeSpace (KERNEL.169)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000684 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000685DWORD WINAPI GetFreeSpace16( UINT16 wFlags )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000686{
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000687 MEMORYSTATUS ms;
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000688 GlobalMemoryStatus( &ms );
689 return ms.dwAvailVirtual;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000690}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000691
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000692/***********************************************************************
693 * GlobalDOSAlloc (KERNEL.184)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000694 * RETURNS
695 * Address (HW=Paragraph segment; LW=Selector)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000696 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000697DWORD WINAPI GlobalDOSAlloc16(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000698 DWORD size /* [in] Number of bytes to be allocated */
699) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000700 UINT16 uParagraph;
Ove Kaaven7b499142000-07-28 22:23:59 +0000701 LPVOID lpBlock = DOSMEM_GetBlock( size, &uParagraph );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000702
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000703 if( lpBlock )
704 {
Alexandre Julliard21979011997-03-05 08:22:35 +0000705 HMODULE16 hModule = GetModuleHandle16("KERNEL");
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000706 WORD wSelector;
Andreas Mohrd23f5062000-10-02 22:16:21 +0000707 GLOBALARENA *pArena;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000708
Alexandre Julliard914406f2000-11-14 01:54:49 +0000709 wSelector = GLOBAL_CreateBlock(GMEM_FIXED, lpBlock, size, hModule, WINE_LDT_FLAGS_DATA );
Andreas Mohrd23f5062000-10-02 22:16:21 +0000710 pArena = GET_ARENA_PTR(wSelector);
711 pArena->flags |= GA_DOSMEM;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000712 return MAKELONG(wSelector,uParagraph);
713 }
714 return 0;
715}
716
Alexandre Julliard54c27111998-03-29 19:44:57 +0000717
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000718/***********************************************************************
719 * GlobalDOSFree (KERNEL.185)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000720 * RETURNS
721 * NULL: Success
722 * sel: Failure
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000723 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000724WORD WINAPI GlobalDOSFree16(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000725 WORD sel /* [in] Selector */
726) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000727 DWORD block = GetSelectorBase(sel);
728
729 if( block && block < 0x100000 )
730 {
731 LPVOID lpBlock = DOSMEM_MapDosToLinear( block );
Ove Kaaven7b499142000-07-28 22:23:59 +0000732 if( DOSMEM_FreeBlock( lpBlock ) )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000733 GLOBAL_FreeBlock( sel );
734 sel = 0;
735 }
736 return sel;
737}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000738
Alexandre Julliard54c27111998-03-29 19:44:57 +0000739
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000740/***********************************************************************
Patrik Stridvall3ca98232001-06-20 23:03:14 +0000741 * GlobalPageLock (KERNEL.191)
Patrik Stridvall044855c2001-07-11 18:56:41 +0000742 * GlobalSmartPageLock(KERNEL.230)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000743 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000744WORD WINAPI GlobalPageLock16( HGLOBAL16 handle )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000745{
Alexandre Julliard15657091999-05-23 10:25:25 +0000746 TRACE("%04x\n", handle );
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000747 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000748 WARN("Invalid handle 0x%04x passed to GlobalPageLock!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000749 return 0;
750 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000751 return ++(GET_ARENA_PTR(handle)->pageLockCount);
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000752}
753
754
755/***********************************************************************
Patrik Stridvall3ca98232001-06-20 23:03:14 +0000756 * GlobalPageUnlock (KERNEL.192)
Patrik Stridvall044855c2001-07-11 18:56:41 +0000757 * GlobalSmartPageUnlock(KERNEL.231)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000758 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000759WORD WINAPI GlobalPageUnlock16( HGLOBAL16 handle )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000760{
Alexandre Julliard15657091999-05-23 10:25:25 +0000761 TRACE("%04x\n", handle );
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000762 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000763 WARN("Invalid handle 0x%04x passed to GlobalPageUnlock!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000764 return 0;
765 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000766 return --(GET_ARENA_PTR(handle)->pageLockCount);
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000767}
768
769
770/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000771 * GlobalFix (KERNEL.197)
772 * GlobalFix16 (KERNEL32.27)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000773 */
Ulrich Weigand85a7ff41998-10-11 19:10:10 +0000774WORD WINAPI GlobalFix16( HGLOBAL16 handle )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000775{
Alexandre Julliard15657091999-05-23 10:25:25 +0000776 TRACE("%04x\n", handle );
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000777 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000778 WARN("Invalid handle 0x%04x passed to GlobalFix16!\n",handle);
Ulrich Weigand85a7ff41998-10-11 19:10:10 +0000779 return 0;
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000780 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000781 GET_ARENA_PTR(handle)->lockCount++;
Ulrich Weigand85a7ff41998-10-11 19:10:10 +0000782
Alexandre Julliarda3960291999-02-26 11:11:13 +0000783 return GlobalHandleToSel16(handle);
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000784}
785
786
787/***********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000788 * GlobalUnfix (KERNEL.198)
789 * GlobalUnfix16 (KERNEL32.28)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000790 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000791void WINAPI GlobalUnfix16( HGLOBAL16 handle )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000792{
Alexandre Julliard15657091999-05-23 10:25:25 +0000793 TRACE("%04x\n", handle );
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000794 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000795 WARN("Invalid handle 0x%04x passed to GlobalUnfix16!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000796 return;
797 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000798 GET_ARENA_PTR(handle)->lockCount--;
799}
800
801
802/***********************************************************************
803 * FarSetOwner (KERNEL.403)
804 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000805void WINAPI FarSetOwner16( HGLOBAL16 handle, HANDLE16 hOwner )
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000806{
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000807 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000808 WARN("Invalid handle 0x%04x passed to FarSetOwner!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000809 return;
810 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000811 GET_ARENA_PTR(handle)->hOwner = hOwner;
812}
813
814
815/***********************************************************************
816 * FarGetOwner (KERNEL.404)
817 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000818HANDLE16 WINAPI FarGetOwner16( HGLOBAL16 handle )
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000819{
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000820 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000821 WARN("Invalid handle 0x%04x passed to FarGetOwner!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000822 return 0;
823 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000824 return GET_ARENA_PTR(handle)->hOwner;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000825}
826
827
828/***********************************************************************
829 * GlobalHandleToSel (TOOLHELP.50)
830 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000831WORD WINAPI GlobalHandleToSel16( HGLOBAL16 handle )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000832{
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000833 if (!handle) return 0;
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000834 if (!VALID_HANDLE(handle)) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000835 WARN("Invalid handle 0x%04x passed to GlobalHandleToSel!\n",handle);
Alexandre Julliarda11d7b11998-03-01 20:05:02 +0000836 return 0;
837 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000838 if (!(handle & 7))
839 {
Alexandre Julliard15657091999-05-23 10:25:25 +0000840 WARN("Program attempted invalid selector conversion\n" );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000841 return handle - 1;
842 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000843 return handle | 7;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000844}
845
846
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000847/***********************************************************************
848 * GlobalFirst (TOOLHELP.51)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000849 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000850BOOL16 WINAPI GlobalFirst16( GLOBALENTRY *pGlobal, WORD wFlags )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000851{
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000852 if (wFlags == GLOBAL_LRU) return FALSE;
853 pGlobal->dwNext = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000854 return GlobalNext16( pGlobal, wFlags );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000855}
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000856
857
858/***********************************************************************
859 * GlobalNext (TOOLHELP.52)
860 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000861BOOL16 WINAPI GlobalNext16( GLOBALENTRY *pGlobal, WORD wFlags)
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000862{
863 GLOBALARENA *pArena;
864
Alexandre Julliard594997c1995-04-30 10:05:20 +0000865 if (pGlobal->dwNext >= globalArenaSize) return FALSE;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000866 pArena = pGlobalArena + pGlobal->dwNext;
867 if (wFlags == GLOBAL_FREE) /* only free blocks */
868 {
869 int i;
870 for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++)
871 if (pArena->size == 0) break; /* block is free */
872 if (i >= globalArenaSize) return FALSE;
873 pGlobal->dwNext = i;
874 }
875
876 pGlobal->dwAddress = pArena->base;
877 pGlobal->dwBlockSize = pArena->size;
878 pGlobal->hBlock = pArena->handle;
879 pGlobal->wcLock = pArena->lockCount;
880 pGlobal->wcPageLock = pArena->pageLockCount;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000881 pGlobal->wFlags = (GetCurrentPDB16() == pArena->hOwner);
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000882 pGlobal->wHeapPresent = FALSE;
883 pGlobal->hOwner = pArena->hOwner;
884 pGlobal->wType = GT_UNKNOWN;
885 pGlobal->wData = 0;
886 pGlobal->dwNext++;
887 return TRUE;
888}
889
890
891/***********************************************************************
892 * GlobalInfo (TOOLHELP.53)
893 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000894BOOL16 WINAPI GlobalInfo16( GLOBALINFO *pInfo )
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000895{
896 int i;
897 GLOBALARENA *pArena;
898
899 pInfo->wcItems = globalArenaSize;
900 pInfo->wcItemsFree = 0;
901 pInfo->wcItemsLRU = 0;
902 for (i = 0, pArena = pGlobalArena; i < globalArenaSize; i++, pArena++)
903 if (pArena->size == 0) pInfo->wcItemsFree++;
904 return TRUE;
905}
906
907
908/***********************************************************************
909 * GlobalEntryHandle (TOOLHELP.54)
910 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000911BOOL16 WINAPI GlobalEntryHandle16( GLOBALENTRY *pGlobal, HGLOBAL16 hItem )
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000912{
Alexandre Julliard03468f71998-02-15 19:40:49 +0000913 GLOBALARENA *pArena = GET_ARENA_PTR(hItem);
914
915 pGlobal->dwAddress = pArena->base;
916 pGlobal->dwBlockSize = pArena->size;
917 pGlobal->hBlock = pArena->handle;
918 pGlobal->wcLock = pArena->lockCount;
919 pGlobal->wcPageLock = pArena->pageLockCount;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000920 pGlobal->wFlags = (GetCurrentPDB16() == pArena->hOwner);
Alexandre Julliard03468f71998-02-15 19:40:49 +0000921 pGlobal->wHeapPresent = FALSE;
922 pGlobal->hOwner = pArena->hOwner;
923 pGlobal->wType = GT_UNKNOWN;
924 pGlobal->wData = 0;
925 pGlobal->dwNext++;
926 return TRUE;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000927}
928
929
930/***********************************************************************
931 * GlobalEntryModule (TOOLHELP.55)
932 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000933BOOL16 WINAPI GlobalEntryModule16( GLOBALENTRY *pGlobal, HMODULE16 hModule,
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000934 WORD wSeg )
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000935{
Andreas Mohrd23f5062000-10-02 22:16:21 +0000936 FIXME("(%p, 0x%04x, 0x%04x), stub.\n", pGlobal, hModule, wSeg);
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000937 return FALSE;
938}
939
940
941/***********************************************************************
942 * MemManInfo (TOOLHELP.72)
943 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000944BOOL16 WINAPI MemManInfo16( MEMMANINFO *info )
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000945{
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000946 MEMORYSTATUS status;
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000947
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000948 /*
949 * Not unsurprisingly although the documention says you
950 * _must_ provide the size in the dwSize field, this function
951 * (under Windows) always fills the structure and returns true.
952 */
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000953 GlobalMemoryStatus( &status );
Alexandre Julliard982a2232000-12-13 20:20:09 +0000954 info->wPageSize = getpagesize();
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000955 info->dwLargestFreeBlock = status.dwAvailVirtual;
956 info->dwMaxPagesAvailable = info->dwLargestFreeBlock / info->wPageSize;
957 info->dwMaxPagesLockable = info->dwMaxPagesAvailable;
958 info->dwTotalLinearSpace = status.dwTotalVirtual / info->wPageSize;
959 info->dwTotalUnlockedPages = info->dwTotalLinearSpace;
960 info->dwFreePages = info->dwMaxPagesAvailable;
961 info->dwTotalPages = info->dwTotalLinearSpace;
962 info->dwFreeLinearSpace = info->dwMaxPagesAvailable;
963 info->dwSwapFilePages = status.dwTotalPageFile / info->wPageSize;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000964 return TRUE;
965}
Alexandre Julliard2787be81995-05-22 18:23:01 +0000966
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000967/***********************************************************************
968 * GetFreeMemInfo (KERNEL.316)
969 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000970DWORD WINAPI GetFreeMemInfo16(void)
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000971{
972 MEMMANINFO info;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000973 MemManInfo16( &info );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000974 return MAKELONG( info.dwTotalLinearSpace, info.dwMaxPagesAvailable );
975}
976
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000977/*
978 * Win32 Global heap functions (GlobalXXX).
979 * These functions included in Win32 for compatibility with 16 bit Windows
980 * Especially the moveable blocks and handles are oldish.
981 * But the ability to directly allocate memory with GPTR and LPTR is widely
982 * used.
983 *
984 * The handle stuff looks horrible, but it's implemented almost like Win95
985 * does it.
986 *
987 */
988
989#define MAGIC_GLOBAL_USED 0x5342
990#define GLOBAL_LOCK_MAX 0xFF
Alexandre Julliard17216f51997-10-12 16:30:17 +0000991#define HANDLE_TO_INTERN(h) ((PGLOBAL32_INTERN)(((char *)(h))-2))
Alexandre Julliarda3960291999-02-26 11:11:13 +0000992#define INTERN_TO_HANDLE(i) ((HGLOBAL) &((i)->Pointer))
993#define POINTER_TO_HANDLE(p) (*(((HGLOBAL *)(p))-1))
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000994#define ISHANDLE(h) (((DWORD)(h)&2)!=0)
995#define ISPOINTER(h) (((DWORD)(h)&2)==0)
996
997typedef struct __GLOBAL32_INTERN
998{
999 WORD Magic;
1000 LPVOID Pointer WINE_PACKED;
1001 BYTE Flags;
1002 BYTE LockCount;
1003} GLOBAL32_INTERN, *PGLOBAL32_INTERN;
1004
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001005
1006/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001007 * GlobalAlloc (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001008 * RETURNS
1009 * Handle: Success
1010 * NULL: Failure
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001011 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001012HGLOBAL WINAPI GlobalAlloc(
1013 UINT flags, /* [in] Object allocation attributes */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001014 DWORD size /* [in] Number of bytes to allocate */
1015) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001016 PGLOBAL32_INTERN pintern;
1017 DWORD hpflags;
1018 LPVOID palloc;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001019
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001020 if(flags&GMEM_ZEROINIT)
1021 hpflags=HEAP_ZERO_MEMORY;
1022 else
1023 hpflags=0;
1024
Noel Borthwick83579c81999-07-24 12:18:04 +00001025 TRACE("() flags=%04x\n", flags );
1026
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001027 if((flags & GMEM_MOVEABLE)==0) /* POINTER */
1028 {
1029 palloc=HeapAlloc(GetProcessHeap(), hpflags, size);
Alexandre Julliarda3960291999-02-26 11:11:13 +00001030 return (HGLOBAL) palloc;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001031 }
1032 else /* HANDLE */
1033 {
Noel Borthwick83579c81999-07-24 12:18:04 +00001034 /* HeapLock(heap); */
1035
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001036 pintern=HeapAlloc(GetProcessHeap(), 0, sizeof(GLOBAL32_INTERN));
Alexandre Julliard982a2232000-12-13 20:20:09 +00001037 if (!pintern) return 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001038 if(size)
1039 {
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001040 if (!(palloc=HeapAlloc(GetProcessHeap(), hpflags, size+sizeof(HGLOBAL)))) {
1041 HeapFree(GetProcessHeap(), 0, pintern);
Alexandre Julliard982a2232000-12-13 20:20:09 +00001042 return 0;
Eric Pouech3bcfb902000-06-24 12:51:24 +00001043 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001044 *(HGLOBAL *)palloc=INTERN_TO_HANDLE(pintern);
Patrik Stridvalla9a671d1999-04-25 19:01:52 +00001045 pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001046 }
1047 else
1048 pintern->Pointer=NULL;
1049 pintern->Magic=MAGIC_GLOBAL_USED;
1050 pintern->Flags=flags>>8;
1051 pintern->LockCount=0;
1052
Noel Borthwick83579c81999-07-24 12:18:04 +00001053 /* HeapUnlock(heap); */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001054
1055 return INTERN_TO_HANDLE(pintern);
1056 }
1057}
1058
1059
1060/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001061 * GlobalLock (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001062 * RETURNS
1063 * Pointer to first byte of block
1064 * NULL: Failure
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001065 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001066LPVOID WINAPI GlobalLock(
1067 HGLOBAL hmem /* [in] Handle of global memory object */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001068) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001069 PGLOBAL32_INTERN pintern;
1070 LPVOID palloc;
1071
1072 if(ISPOINTER(hmem))
1073 return (LPVOID) hmem;
1074
1075 /* HeapLock(GetProcessHeap()); */
1076
1077 pintern=HANDLE_TO_INTERN(hmem);
1078 if(pintern->Magic==MAGIC_GLOBAL_USED)
1079 {
1080 if(pintern->LockCount<GLOBAL_LOCK_MAX)
1081 pintern->LockCount++;
1082 palloc=pintern->Pointer;
1083 }
1084 else
1085 {
Alexandre Julliard15657091999-05-23 10:25:25 +00001086 WARN("invalid handle\n");
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001087 palloc=(LPVOID) NULL;
Dmitry Timoshkovc34fe082000-11-27 01:33:25 +00001088 SetLastError(ERROR_INVALID_HANDLE);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001089 }
1090 /* HeapUnlock(GetProcessHeap()); */;
1091 return palloc;
1092}
1093
1094
1095/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001096 * GlobalUnlock (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001097 * RETURNS
1098 * TRUE: Object is still locked
1099 * FALSE: Object is unlocked
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001100 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001101BOOL WINAPI GlobalUnlock(
1102 HGLOBAL hmem /* [in] Handle of global memory object */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001103) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001104 PGLOBAL32_INTERN pintern;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001105 BOOL locked;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001106
1107 if(ISPOINTER(hmem))
1108 return FALSE;
1109
1110 /* HeapLock(GetProcessHeap()); */
1111 pintern=HANDLE_TO_INTERN(hmem);
1112
1113 if(pintern->Magic==MAGIC_GLOBAL_USED)
1114 {
1115 if((pintern->LockCount<GLOBAL_LOCK_MAX)&&(pintern->LockCount>0))
1116 pintern->LockCount--;
1117
Alexandre Julliardde25e6f2000-12-19 23:38:13 +00001118 locked = (pintern->LockCount != 0);
1119 if (!locked) SetLastError(NO_ERROR);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001120 }
1121 else
1122 {
Alexandre Julliard15657091999-05-23 10:25:25 +00001123 WARN("invalid handle\n");
Alexandre Julliardde25e6f2000-12-19 23:38:13 +00001124 SetLastError(ERROR_INVALID_HANDLE);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001125 locked=FALSE;
1126 }
1127 /* HeapUnlock(GetProcessHeap()); */
1128 return locked;
1129}
1130
1131
1132/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001133 * GlobalHandle (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001134 * Returns the handle associated with the specified pointer.
1135 *
Alexandre Julliard54c27111998-03-29 19:44:57 +00001136 * RETURNS
1137 * Handle: Success
1138 * NULL: Failure
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001139 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001140HGLOBAL WINAPI GlobalHandle(
Alexandre Julliard54c27111998-03-29 19:44:57 +00001141 LPCVOID pmem /* [in] Pointer to global memory block */
1142) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001143 HGLOBAL handle;
Guy Albertelli4ef64132000-01-23 02:25:11 +00001144 PGLOBAL32_INTERN maybe_intern;
1145 LPCVOID test;
Guy Albertelli98679972000-01-15 21:59:12 +00001146
1147 if (!pmem)
1148 {
Lawson Whitney969515d2000-10-02 22:27:37 +00001149 SetLastError( ERROR_INVALID_PARAMETER );
1150 return 0;
Guy Albertelli98679972000-01-15 21:59:12 +00001151 }
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001152
Lawson Whitney969515d2000-10-02 22:27:37 +00001153 __TRY
1154 {
1155 handle = 0;
Guy Albertelli4ef64132000-01-23 02:25:11 +00001156
Lawson Whitney969515d2000-10-02 22:27:37 +00001157 /* note that if pmem is a pointer to a a block allocated by */
1158 /* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate */
1159 /* will fail. */
1160 if (ISPOINTER(pmem)) {
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001161 if (HeapValidate( GetProcessHeap(), 0, pmem )) {
Lawson Whitney969515d2000-10-02 22:27:37 +00001162 handle = (HGLOBAL)pmem; /* valid fixed block */
1163 break;
1164 }
1165 handle = POINTER_TO_HANDLE(pmem);
1166 } else
1167 handle = (HGLOBAL)pmem;
1168
1169 /* Now test handle either passed in or retrieved from pointer */
Lawson Whitney969515d2000-10-02 22:27:37 +00001170 maybe_intern = HANDLE_TO_INTERN( handle );
1171 if (maybe_intern->Magic == MAGIC_GLOBAL_USED) {
1172 test = maybe_intern->Pointer;
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001173 if (HeapValidate( GetProcessHeap(), 0, ((HGLOBAL *)test)-1 ) && /* obj(-handle) valid arena? */
1174 HeapValidate( GetProcessHeap(), 0, maybe_intern )) /* intern valid arena? */
Lawson Whitney969515d2000-10-02 22:27:37 +00001175 break; /* valid moveable block */
1176 }
1177 handle = 0;
1178 SetLastError( ERROR_INVALID_HANDLE );
Alexandre Julliard17216f51997-10-12 16:30:17 +00001179 }
Lawson Whitney969515d2000-10-02 22:27:37 +00001180 __EXCEPT(page_fault)
1181 {
1182 SetLastError( ERROR_INVALID_HANDLE );
1183 return 0;
1184 }
1185 __ENDTRY
Alexandre Julliard17216f51997-10-12 16:30:17 +00001186
Lawson Whitney969515d2000-10-02 22:27:37 +00001187 return handle;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001188}
1189
1190
1191/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001192 * GlobalReAlloc (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001193 * RETURNS
1194 * Handle: Success
1195 * NULL: Failure
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001196 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001197HGLOBAL WINAPI GlobalReAlloc(
1198 HGLOBAL hmem, /* [in] Handle of global memory object */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001199 DWORD size, /* [in] New size of block */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001200 UINT flags /* [in] How to reallocate object */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001201) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001202 LPVOID palloc;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001203 HGLOBAL hnew;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001204 PGLOBAL32_INTERN pintern;
Alexandre Julliardd10ca9c1999-09-04 11:26:56 +00001205 DWORD heap_flags = (flags & GMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001206
Alexandre Julliard02e90081998-01-04 17:49:09 +00001207 hnew = 0;
Noel Borthwick83579c81999-07-24 12:18:04 +00001208 /* HeapLock(heap); */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001209 if(flags & GMEM_MODIFY) /* modify flags */
1210 {
1211 if( ISPOINTER(hmem) && (flags & GMEM_MOVEABLE))
1212 {
1213 /* make a fixed block moveable
1214 * actually only NT is able to do this. But it's soo simple
1215 */
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001216 if (hmem == 0)
1217 {
Alexandre Julliard15657091999-05-23 10:25:25 +00001218 ERR("GlobalReAlloc32 with null handle!\n");
Alexandre Julliard0ad42fa1999-01-31 15:04:42 +00001219 SetLastError( ERROR_NOACCESS );
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001220 return 0;
1221 }
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001222 size=HeapSize(GetProcessHeap(), 0, (LPVOID) hmem);
Alexandre Julliarda3960291999-02-26 11:11:13 +00001223 hnew=GlobalAlloc( flags, size);
1224 palloc=GlobalLock(hnew);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001225 memcpy(palloc, (LPVOID) hmem, size);
Alexandre Julliarda3960291999-02-26 11:11:13 +00001226 GlobalUnlock(hnew);
1227 GlobalFree(hmem);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001228 }
1229 else if( ISPOINTER(hmem) &&(flags & GMEM_DISCARDABLE))
1230 {
1231 /* change the flags to make our block "discardable" */
1232 pintern=HANDLE_TO_INTERN(hmem);
1233 pintern->Flags = pintern->Flags | (GMEM_DISCARDABLE >> 8);
1234 hnew=hmem;
1235 }
1236 else
1237 {
1238 SetLastError(ERROR_INVALID_PARAMETER);
Alexandre Julliard02e90081998-01-04 17:49:09 +00001239 hnew = 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001240 }
1241 }
1242 else
1243 {
1244 if(ISPOINTER(hmem))
1245 {
1246 /* reallocate fixed memory */
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001247 hnew=(HGLOBAL)HeapReAlloc(GetProcessHeap(), heap_flags, (LPVOID) hmem, size);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001248 }
1249 else
1250 {
1251 /* reallocate a moveable block */
1252 pintern=HANDLE_TO_INTERN(hmem);
Ulrich Weigand2e7008c2000-10-19 20:24:25 +00001253
1254#if 0
1255/* Apparently Windows doesn't care whether the handle is locked at this point */
1256/* See also the same comment in GlobalFree() */
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001257 if(pintern->LockCount>1) {
Alexandre Julliard15657091999-05-23 10:25:25 +00001258 ERR("handle 0x%08lx is still locked, cannot realloc!\n",(DWORD)hmem);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001259 SetLastError(ERROR_INVALID_HANDLE);
Ulrich Weigand2e7008c2000-10-19 20:24:25 +00001260 } else
1261#endif
1262 if(size!=0)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001263 {
1264 hnew=hmem;
1265 if(pintern->Pointer)
1266 {
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001267 if((palloc = HeapReAlloc(GetProcessHeap(), heap_flags,
Huw D M Daviesc43fdb72000-04-13 15:57:06 +00001268 (char *) pintern->Pointer-sizeof(HGLOBAL),
1269 size+sizeof(HGLOBAL))) == NULL)
1270 return 0; /* Block still valid */
Patrik Stridvalla9a671d1999-04-25 19:01:52 +00001271 pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001272 }
1273 else
1274 {
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001275 if((palloc=HeapAlloc(GetProcessHeap(), heap_flags, size+sizeof(HGLOBAL)))
Huw D M Daviesc43fdb72000-04-13 15:57:06 +00001276 == NULL)
1277 return 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001278 *(HGLOBAL *)palloc=hmem;
Patrik Stridvalla9a671d1999-04-25 19:01:52 +00001279 pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001280 }
1281 }
1282 else
1283 {
1284 if(pintern->Pointer)
1285 {
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001286 HeapFree(GetProcessHeap(), 0, (char *) pintern->Pointer-sizeof(HGLOBAL));
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001287 pintern->Pointer=NULL;
1288 }
1289 }
1290 }
1291 }
Noel Borthwick83579c81999-07-24 12:18:04 +00001292 /* HeapUnlock(heap); */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001293 return hnew;
1294}
1295
1296
1297/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001298 * GlobalFree (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001299 * RETURNS
1300 * NULL: Success
1301 * Handle: Failure
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001302 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001303HGLOBAL WINAPI GlobalFree(
1304 HGLOBAL hmem /* [in] Handle of global memory object */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001305) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001306 PGLOBAL32_INTERN pintern;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001307 HGLOBAL hreturned = 0;
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001308
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001309 if(ISPOINTER(hmem)) /* POINTER */
1310 {
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001311 if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) hmem = 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001312 }
1313 else /* HANDLE */
1314 {
Noel Borthwick83579c81999-07-24 12:18:04 +00001315 /* HeapLock(heap); */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001316 pintern=HANDLE_TO_INTERN(hmem);
1317
1318 if(pintern->Magic==MAGIC_GLOBAL_USED)
1319 {
Guy Albertelli4ef64132000-01-23 02:25:11 +00001320
1321/* WIN98 does not make this test. That is you can free a */
1322/* block you have not unlocked. Go figure!! */
1323 /* if(pintern->LockCount!=0) */
1324 /* SetLastError(ERROR_INVALID_HANDLE); */
1325
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001326 if(pintern->Pointer)
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001327 if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-sizeof(HGLOBAL)))
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001328 hreturned=hmem;
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001329 if(!HeapFree(GetProcessHeap(), 0, pintern))
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001330 hreturned=hmem;
1331 }
Noel Borthwick83579c81999-07-24 12:18:04 +00001332 /* HeapUnlock(heap); */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001333 }
1334 return hreturned;
1335}
1336
1337
1338/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001339 * GlobalSize (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001340 * RETURNS
1341 * Size in bytes of the global memory object
1342 * 0: Failure
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001343 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001344DWORD WINAPI GlobalSize(
1345 HGLOBAL hmem /* [in] Handle of global memory object */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001346) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001347 DWORD retval;
1348 PGLOBAL32_INTERN pintern;
1349
1350 if(ISPOINTER(hmem))
1351 {
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001352 retval=HeapSize(GetProcessHeap(), 0, (LPVOID) hmem);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001353 }
1354 else
1355 {
Noel Borthwick83579c81999-07-24 12:18:04 +00001356 /* HeapLock(heap); */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001357 pintern=HANDLE_TO_INTERN(hmem);
1358
1359 if(pintern->Magic==MAGIC_GLOBAL_USED)
1360 {
Guy Albertelli3db8e191999-02-14 17:38:24 +00001361 if (!pintern->Pointer) /* handle case of GlobalAlloc( ??,0) */
1362 return 0;
Alexandre Julliard61d32b42001-02-23 01:35:36 +00001363 retval=HeapSize(GetProcessHeap(), 0,
Alexandre Julliarda3960291999-02-26 11:11:13 +00001364 (char *)(pintern->Pointer)-sizeof(HGLOBAL))-4;
Rein Klazeseaec1ee1999-07-11 13:50:24 +00001365 if (retval == 0xffffffff-4) retval = 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001366 }
1367 else
1368 {
Alexandre Julliard15657091999-05-23 10:25:25 +00001369 WARN("invalid handle\n");
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001370 retval=0;
1371 }
Noel Borthwick83579c81999-07-24 12:18:04 +00001372 /* HeapUnlock(heap); */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001373 }
Guy Albertelli3db8e191999-02-14 17:38:24 +00001374 /* HeapSize returns 0xffffffff on failure */
1375 if (retval == 0xffffffff) retval = 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001376 return retval;
1377}
1378
1379
1380/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001381 * GlobalWire (KERNEL32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001382 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001383LPVOID WINAPI GlobalWire(HGLOBAL hmem)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001384{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001385 return GlobalLock( hmem );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001386}
1387
1388
1389/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001390 * GlobalUnWire (KERNEL32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001391 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001392BOOL WINAPI GlobalUnWire(HGLOBAL hmem)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001393{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001394 return GlobalUnlock( hmem);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001395}
1396
1397
1398/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001399 * GlobalFix (KERNEL32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001400 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001401VOID WINAPI GlobalFix(HGLOBAL hmem)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001402{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001403 GlobalLock( hmem );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001404}
1405
1406
1407/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001408 * GlobalUnfix (KERNEL32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001409 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001410VOID WINAPI GlobalUnfix(HGLOBAL hmem)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001411{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001412 GlobalUnlock( hmem);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001413}
1414
1415
1416/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001417 * GlobalFlags (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001418 * Returns information about the specified global memory object
1419 *
1420 * NOTES
1421 * Should this return GMEM_INVALID_HANDLE on invalid handle?
1422 *
1423 * RETURNS
1424 * Value specifying allocation flags and lock count
1425 * GMEM_INVALID_HANDLE: Failure
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001426 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001427UINT WINAPI GlobalFlags(
1428 HGLOBAL hmem /* [in] Handle to global memory object */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001429) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001430 DWORD retval;
1431 PGLOBAL32_INTERN pintern;
1432
1433 if(ISPOINTER(hmem))
1434 {
1435 retval=0;
1436 }
1437 else
1438 {
1439 /* HeapLock(GetProcessHeap()); */
1440 pintern=HANDLE_TO_INTERN(hmem);
1441 if(pintern->Magic==MAGIC_GLOBAL_USED)
1442 {
1443 retval=pintern->LockCount + (pintern->Flags<<8);
1444 if(pintern->Pointer==0)
1445 retval|= GMEM_DISCARDED;
1446 }
1447 else
1448 {
Francois Gougete76218d2001-05-09 17:31:31 +00001449 WARN("Invalid handle: %04x\n", hmem);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001450 retval=0;
1451 }
1452 /* HeapUnlock(GetProcessHeap()); */
1453 }
1454 return retval;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001455}
1456
1457
1458/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001459 * GlobalCompact (KERNEL32.@)
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001460 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001461DWORD WINAPI GlobalCompact( DWORD minfree )
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001462{
1463 return 0; /* GlobalCompact does nothing in Win32 */
1464}
1465
1466
1467/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +00001468 * GlobalMemoryStatus (KERNEL32.@)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001469 * RETURNS
1470 * None
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001471 */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001472VOID WINAPI GlobalMemoryStatus(
1473 LPMEMORYSTATUS lpmem
1474) {
Marcus Meissner6189c192000-03-04 19:19:15 +00001475 static MEMORYSTATUS cached_memstatus;
1476 static int cache_lastchecked = 0;
Francois Gougetea5924c2000-10-28 00:34:29 +00001477 SYSTEM_INFO si;
Patrik Stridvall7e9913f2000-03-08 18:25:22 +00001478#ifdef linux
Marcus Meissner6189c192000-03-04 19:19:15 +00001479 FILE *f;
Patrik Stridvall7e9913f2000-03-08 18:25:22 +00001480#endif
Marcus Meissner6189c192000-03-04 19:19:15 +00001481
1482 if (time(NULL)==cache_lastchecked) {
1483 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
1484 return;
1485 }
1486 cache_lastchecked = time(NULL);
1487
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001488#ifdef linux
Marcus Meissner6189c192000-03-04 19:19:15 +00001489 f = fopen( "/proc/meminfo", "r" );
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001490 if (f)
1491 {
1492 char buffer[256];
Stephen Crowley59c4a321998-11-24 20:41:02 +00001493 int total, used, free, shared, buffers, cached;
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001494
Stephen Crowley59c4a321998-11-24 20:41:02 +00001495 lpmem->dwLength = sizeof(MEMORYSTATUS);
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001496 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
1497 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
1498 while (fgets( buffer, sizeof(buffer), f ))
1499 {
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001500 /* old style /proc/meminfo ... */
Stephen Crowley59c4a321998-11-24 20:41:02 +00001501 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001502 {
1503 lpmem->dwTotalPhys += total;
Stephen Crowley59c4a321998-11-24 20:41:02 +00001504 lpmem->dwAvailPhys += free + buffers + cached;
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001505 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001506 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001507 {
1508 lpmem->dwTotalPageFile += total;
1509 lpmem->dwAvailPageFile += free;
1510 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001511
1512 /* new style /proc/meminfo ... */
1513 if (sscanf(buffer, "MemTotal: %d", &total))
1514 lpmem->dwTotalPhys = total*1024;
1515 if (sscanf(buffer, "MemFree: %d", &free))
1516 lpmem->dwAvailPhys = free*1024;
1517 if (sscanf(buffer, "SwapTotal: %d", &total))
1518 lpmem->dwTotalPageFile = total*1024;
1519 if (sscanf(buffer, "SwapFree: %d", &free))
1520 lpmem->dwAvailPageFile = free*1024;
Stephen Crowley59c4a321998-11-24 20:41:02 +00001521 if (sscanf(buffer, "Buffers: %d", &buffers))
1522 lpmem->dwAvailPhys += buffers*1024;
1523 if (sscanf(buffer, "Cached: %d", &cached))
1524 lpmem->dwAvailPhys += cached*1024;
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001525 }
1526 fclose( f );
1527
1528 if (lpmem->dwTotalPhys)
1529 {
Francois Gougetea5924c2000-10-28 00:34:29 +00001530 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
1531 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
1532 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
1533 / (TotalPhysical / 100);
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001534 }
Marcus Meissnerfddbcf32000-03-07 12:24:58 +00001535 } else
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001536#endif
Marcus Meissnerfddbcf32000-03-07 12:24:58 +00001537 {
1538 /* FIXME: should do something for other systems */
1539 lpmem->dwMemoryLoad = 0;
1540 lpmem->dwTotalPhys = 16*1024*1024;
1541 lpmem->dwAvailPhys = 16*1024*1024;
1542 lpmem->dwTotalPageFile = 16*1024*1024;
1543 lpmem->dwAvailPageFile = 16*1024*1024;
Marcus Meissnerfddbcf32000-03-07 12:24:58 +00001544 }
Francois Gougetea5924c2000-10-28 00:34:29 +00001545 GetSystemInfo(&si);
1546 lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress;
1547 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
1548 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
Marcus Meissnerfddbcf32000-03-07 12:24:58 +00001549 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
Mike McCormackc56a79a2001-01-04 19:52:51 +00001550
1551 /* it appears some memory display programs want to divide by these values */
1552 if(lpmem->dwTotalPageFile==0)
1553 lpmem->dwTotalPageFile++;
1554
1555 if(lpmem->dwAvailPageFile==0)
1556 lpmem->dwAvailPageFile++;
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001557}
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001558
Alexandre Julliard4220b291999-07-11 17:20:01 +00001559/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +00001560 * A20Proc (KERNEL.165)
Patrik Stridvall044855c2001-07-11 18:56:41 +00001561 * A20_Proc (SYSTEM.20)
Alexandre Julliard4220b291999-07-11 17:20:01 +00001562 */
1563void WINAPI A20Proc16( WORD unused )
1564{
1565 /* this is also a NOP in Windows */
1566}
1567
1568/***********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +00001569 * LimitEMSPages (KERNEL.156)
Alexandre Julliard4220b291999-07-11 17:20:01 +00001570 */
1571DWORD WINAPI LimitEMSPages16( DWORD unused )
1572{
1573 return 0;
1574}