blob: 704fe9d2edb0cae5cf88daa35fddce622f7b2230 [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 Julliard121bd981993-07-08 17:37:25 +00006
Alexandre Julliard808cb041995-08-17 17:11:36 +00007#include <sys/types.h>
Alexandre Julliard121bd981993-07-08 17:37:25 +00008#include <stdlib.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00009#include <string.h>
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000010
Alexandre Julliard234bc241994-12-10 13:02:28 +000011#include "windows.h"
Alexandre Julliard2787be81995-05-22 18:23:01 +000012#include "global.h"
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +000013#include "toolhelp.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000014#include "selectors.h"
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000015#include "dde_mem.h"
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000016#include "stackframe.h"
Alexandre Julliard808cb041995-08-17 17:11:36 +000017#include "options.h"
Alexandre Julliardaca05781994-10-17 18:12:41 +000018#include "stddebug.h"
Alexandre Julliardaca05781994-10-17 18:12:41 +000019#include "debug.h"
20
Alexandre Julliardfa68b751995-04-03 16:55:37 +000021 /* Global arena block */
22typedef struct
23{
24 DWORD base; /* Base address */
Alexandre Julliard2787be81995-05-22 18:23:01 +000025 DWORD size; /* Size in bytes (0 indicates a free block) */
Alexandre Julliardfa68b751995-04-03 16:55:37 +000026 HGLOBAL handle; /* Handle for this block */
27 HGLOBAL hOwner; /* Owner of this block */
28 BYTE lockCount; /* Count of GlobalFix() calls */
29 BYTE pageLockCount; /* Count of GlobalPageLock() calls */
30 BYTE flags; /* Allocation flags */
31 BYTE selCount; /* Number of selectors allocated for this block */
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000032 int shmid;
Alexandre Julliardfa68b751995-04-03 16:55:37 +000033} GLOBALARENA;
34
35 /* Flags definitions */
Alexandre Julliard2787be81995-05-22 18:23:01 +000036#define GA_MOVEABLE 0x02 /* same as GMEM_MOVEABLE */
Alexandre Julliardfa68b751995-04-03 16:55:37 +000037#define GA_DGROUP 0x04
38#define GA_DISCARDABLE 0x08
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000039#define GA_IPCSHARE 0x10 /* same as GMEM_DDESHARE */
Alexandre Julliardfa68b751995-04-03 16:55:37 +000040
41 /* Arena array */
42static GLOBALARENA *pGlobalArena = NULL;
43static int globalArenaSize = 0;
44
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000045#define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000 /* Largest allocation is 16M - 64K */
Alexandre Julliard121bd981993-07-08 17:37:25 +000046
Alexandre Julliardfa68b751995-04-03 16:55:37 +000047#define GET_ARENA_PTR(handle) (pGlobalArena + ((handle) >> __AHSHIFT))
Alexandre Julliard75a839a1993-07-15 11:13:45 +000048
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000049/***********************************************************************
Alexandre Julliardfa68b751995-04-03 16:55:37 +000050 * GLOBAL_GetArena
51 *
52 * Return the arena for a given selector, growing the arena array if needed.
Alexandre Julliarddba420a1994-02-02 06:48:31 +000053 */
Alexandre Julliardfa68b751995-04-03 16:55:37 +000054static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount )
Alexandre Julliarddba420a1994-02-02 06:48:31 +000055{
Alexandre Julliard2787be81995-05-22 18:23:01 +000056 if (((sel >> __AHSHIFT) + selcount) > globalArenaSize)
Alexandre Julliardfa68b751995-04-03 16:55:37 +000057 {
Alexandre Julliard2787be81995-05-22 18:23:01 +000058 int newsize = ((sel >> __AHSHIFT) + selcount + 0xff) & ~0xff;
Alexandre Julliardfa68b751995-04-03 16:55:37 +000059 GLOBALARENA *pNewArena = realloc( pGlobalArena,
Alexandre Julliard2787be81995-05-22 18:23:01 +000060 newsize * sizeof(GLOBALARENA) );
Alexandre Julliardfa68b751995-04-03 16:55:37 +000061 if (!pNewArena) return 0;
62 pGlobalArena = pNewArena;
Alexandre Julliard2787be81995-05-22 18:23:01 +000063 memset( pGlobalArena + globalArenaSize, 0,
64 (newsize - globalArenaSize) * sizeof(GLOBALARENA) );
65 globalArenaSize = newsize;
Alexandre Julliardfa68b751995-04-03 16:55:37 +000066 }
67 return pGlobalArena + (sel >> __AHSHIFT);
68}
Alexandre Julliarddba420a1994-02-02 06:48:31 +000069
Alexandre Julliardfa68b751995-04-03 16:55:37 +000070
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000071void debug_handles()
72{
73 int printed=0;
74 int i;
75 for (i = globalArenaSize-1 ; i>=0 ; i--) {
76 if (pGlobalArena[i].size!=0 && (pGlobalArena[i].handle & 0x8000)){
77 printed=1;
78 printf("0x%08x, ",pGlobalArena[i].handle);
79 }
80 }
81 if (printed)
82 printf("\n");
83}
84/***********************************************************************
85 * GLOBAL_FindArena
86 *
87 * Find the arena for a given handle
88 * (when handle is not serial - e.g. DDE)
89 */
90static GLOBALARENA *GLOBAL_FindArena( HGLOBAL handle)
91{
92 int i;
93 for (i = globalArenaSize-1 ; i>=0 ; i--) {
94 if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == handle)
95 return ( &pGlobalArena[i] );
96 }
97 return NULL;
98}
99
100
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000101/***********************************************************************
Alexandre Julliard594997c1995-04-30 10:05:20 +0000102 * GLOBAL_CreateBlock
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000103 *
Alexandre Julliard594997c1995-04-30 10:05:20 +0000104 * Create a global heap block for a fixed range of linear memory.
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000105 */
Alexandre Julliard594997c1995-04-30 10:05:20 +0000106HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
107 HGLOBAL hOwner, BOOL isCode,
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000108 BOOL is32Bit, BOOL isReadOnly,
109 SHMDATA *shmdata )
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000110{
111 WORD sel, selcount;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000112 GLOBALARENA *pArena;
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000113
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000114 /* Allocate the selector(s) */
115
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000116 sel = SELECTOR_AllocBlock( ptr, size,
117 isCode ? SEGMENT_CODE : SEGMENT_DATA,
118 is32Bit, isReadOnly );
119
Alexandre Julliard594997c1995-04-30 10:05:20 +0000120 if (!sel) return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000121 selcount = (size + 0xffff) / 0x10000;
122
123 if (!(pArena = GLOBAL_GetArena( sel, selcount )))
124 {
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000125 FreeSelector( sel );
126 return 0;
127 }
128
129 /* Fill the arena block */
130
131 pArena->base = (DWORD)ptr;
132 pArena->size = GET_SEL_LIMIT(sel) + 1;
Alexandre Julliard808cb041995-08-17 17:11:36 +0000133 if ((flags & GMEM_DDESHARE) && Options.ipc)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000134 {
135 pArena->handle = shmdata->handle;
136 pArena->shmid = shmdata->shmid;
137 shmdata->sel = sel;
138 }
139 else
140 {
141 pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
142 pArena->shmid = 0;
143 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000144 pArena->hOwner = hOwner;
145 pArena->lockCount = 0;
146 pArena->pageLockCount = 0;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000147 pArena->flags = flags & GA_MOVEABLE;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000148 if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000149 if (flags & GMEM_DDESHARE) pArena->flags |= GA_IPCSHARE;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000150 if (!isCode) pArena->flags |= GA_DGROUP;
151 pArena->selCount = selcount;
152 if (selcount > 1) /* clear the next arena blocks */
153 memset( pArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000154
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000155 return pArena->handle;
156}
Alexandre Julliard121bd981993-07-08 17:37:25 +0000157
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000158
159/***********************************************************************
Alexandre Julliard594997c1995-04-30 10:05:20 +0000160 * GLOBAL_FreeBlock
161 *
162 * Free a block allocated by GLOBAL_CreateBlock, without touching
163 * the associated linear memory range.
164 */
165BOOL GLOBAL_FreeBlock( HGLOBAL handle )
166{
167 WORD sel;
168
169 if (!handle) return TRUE;
170 sel = GlobalHandleToSel( handle );
171 if (FreeSelector( sel )) return FALSE; /* failed */
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000172 memset( GET_ARENA_PTR(sel), 0, sizeof(GLOBALARENA) );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000173 return TRUE;
174}
175
176
177/***********************************************************************
178 * GLOBAL_Alloc
179 *
180 * Implementation of GlobalAlloc()
181 */
182HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner,
183 BOOL isCode, BOOL is32Bit, BOOL isReadOnly )
184{
185 void *ptr;
186 HGLOBAL handle;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000187 SHMDATA shmdata;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000188
189 dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags );
190
191 /* Fixup the size */
192
Alexandre Julliarda2f2e011995-06-06 16:40:35 +0000193 if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x1f) return 0;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000194 if (size == 0) size = 0x20;
195 else size = (size + 0x1f) & ~0x1f;
196
197 /* Allocate the linear memory */
198
Alexandre Julliard808cb041995-08-17 17:11:36 +0000199 if ((flags & GMEM_DDESHARE) && Options.ipc)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000200 ptr= DDE_malloc(flags, size, &shmdata);
201 else
202 ptr = malloc( size );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000203 if (!ptr) return 0;
204
205 /* Allocate the selector(s) */
206
207 handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner,
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000208 isCode, is32Bit, isReadOnly, &shmdata);
Alexandre Julliard594997c1995-04-30 10:05:20 +0000209 if (!handle)
210 {
211 free( ptr );
212 return 0;
213 }
214
215 if (flags & GMEM_ZEROINIT) memset( ptr, 0, size );
216 return handle;
217}
218
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000219/***********************************************************************
220 * DDE_GlobalHandleToSel
221 */
222
223WORD DDE_GlobalHandleToSel( HGLOBAL handle )
224{
225 GLOBALARENA *pArena;
226 SEGPTR segptr;
227
228 pArena= GLOBAL_FindArena(handle);
229 if (pArena) {
230 int ArenaIdx = pArena - pGlobalArena;
231
232 /* See if synchronized to the shared memory */
233 return DDE_SyncHandle(handle, ( ArenaIdx << __AHSHIFT) | 7);
234 }
235
236 /* attach the block */
237 DDE_AttachHandle(handle, &segptr);
238
239 return SELECTOROF( segptr );
240}
241
Alexandre Julliard594997c1995-04-30 10:05:20 +0000242
243/***********************************************************************
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000244 * GlobalAlloc (KERNEL.15)
245 */
246HGLOBAL GlobalAlloc( WORD flags, DWORD size )
247{
Alexandre Julliard594997c1995-04-30 10:05:20 +0000248 HANDLE owner = GetCurrentPDB();
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000249
Alexandre Julliard594997c1995-04-30 10:05:20 +0000250 if (flags & GMEM_DDESHARE)
251 owner = GetExePtr(owner); /* Make it a module handle */
Alexandre Julliard594997c1995-04-30 10:05:20 +0000252 return GLOBAL_Alloc( flags, size, owner, FALSE, FALSE, FALSE );
Alexandre Julliard121bd981993-07-08 17:37:25 +0000253}
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000254
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000255
256/***********************************************************************
257 * GlobalReAlloc (KERNEL.16)
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000258 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000259HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000260{
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000261 WORD selcount;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000262 DWORD oldsize;
263 void *ptr;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000264 GLOBALARENA *pArena, *pNewArena;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000265 WORD sel = GlobalHandleToSel( handle );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000266
267 dprintf_global( stddeb, "GlobalReAlloc: %04x %ld flags=%04x\n",
268 handle, size, flags );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000269 if (!handle) return 0;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000270
Alexandre Julliard808cb041995-08-17 17:11:36 +0000271 if (Options.ipc && (flags & GMEM_DDESHARE || is_dde_handle(handle))) {
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000272 fprintf(stdnimp,
273 "GlobalReAlloc: shared memory reallocating unimplemented\n");
274 return 0;
275 }
276
Alexandre Julliard594997c1995-04-30 10:05:20 +0000277 pArena = GET_ARENA_PTR( handle );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000278
Alexandre Julliard2787be81995-05-22 18:23:01 +0000279 /* Discard the block if requested */
280
Alexandre Julliardded30381995-07-06 17:18:27 +0000281 if ((size == 0) && (flags & GMEM_MOVEABLE) && !(flags & GMEM_MODIFY))
Alexandre Julliard2787be81995-05-22 18:23:01 +0000282 {
283 if (!(pArena->flags & GA_MOVEABLE) ||
284 !(pArena->flags & GA_DISCARDABLE) ||
285 (pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
286 free( (void *)pArena->base );
287 pArena->base = 0;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000288 /* Note: we rely on the fact that SELECTOR_ReallocBlock won't */
289 /* change the selector if we are shrinking the block */
290 SELECTOR_ReallocBlock( sel, 0, 1, SEGMENT_DATA, 0, 0 );
291 return handle;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000292 }
293
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000294 /* Fixup the size */
295
Alexandre Julliard2787be81995-05-22 18:23:01 +0000296 if (size > GLOBAL_MAX_ALLOC_SIZE - 0x20) return 0;
297 if (size == 0) size = 0x20;
298 else size = (size + 0x1f) & ~0x1f;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000299
Alexandre Julliard594997c1995-04-30 10:05:20 +0000300 /* Change the flags */
301
302 if (flags & GMEM_MODIFY)
303 {
304 /* Change the flags, leaving GA_DGROUP alone */
Alexandre Julliard2787be81995-05-22 18:23:01 +0000305 pArena->flags = (pArena->flags & GA_DGROUP) | (flags & GA_MOVEABLE);
Alexandre Julliard594997c1995-04-30 10:05:20 +0000306 if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
307 return handle;
308 }
309
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000310 /* Reallocate the linear memory */
311
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000312 ptr = (void *)pArena->base;
313 oldsize = pArena->size;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000314 dprintf_global(stddeb,"oldsize %08lx\n",oldsize);
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000315 if (size == oldsize) return handle; /* Nothing to do */
316
317 ptr = realloc( ptr, size );
318 if (!ptr)
319 {
320 FreeSelector( sel );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000321 memset( pArena, 0, sizeof(GLOBALARENA) );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000322 return 0;
323 }
324
325 /* Reallocate the selector(s) */
326
327 sel = SELECTOR_ReallocBlock( sel, ptr, size, SEGMENT_DATA, 0, 0 );
328 if (!sel)
329 {
330 free( ptr );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000331 memset( pArena, 0, sizeof(GLOBALARENA) );
332 return 0;
333 }
334 selcount = (size + 0xffff) / 0x10000;
335
336 if (!(pNewArena = GLOBAL_GetArena( sel, selcount )))
337 {
338 free( ptr );
339 FreeSelector( sel );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000340 return 0;
341 }
342
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000343 /* Fill the new arena block */
344
345 if (pNewArena != pArena) memcpy( pNewArena, pArena, sizeof(GLOBALARENA) );
346 pNewArena->base = (DWORD)ptr;
347 pNewArena->size = GET_SEL_LIMIT(sel) + 1;
348 pNewArena->selCount = selcount;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000349 pNewArena->handle = (pNewArena->flags & GA_MOVEABLE) ? sel - 1 : sel;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000350
351 if (selcount > 1) /* clear the next arena blocks */
352 memset( pNewArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) );
353
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000354 if ((oldsize < size) && (flags & GMEM_ZEROINIT))
355 memset( (char *)ptr + oldsize, 0, size - oldsize );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000356 return pNewArena->handle;
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000357}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000358
359
360/***********************************************************************
361 * GlobalFree (KERNEL.17)
Alexandre Julliard121bd981993-07-08 17:37:25 +0000362 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000363HGLOBAL GlobalFree( HGLOBAL handle )
Alexandre Julliard121bd981993-07-08 17:37:25 +0000364{
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000365 void *ptr = GlobalLock( handle );
Alexandre Julliard121bd981993-07-08 17:37:25 +0000366
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000367 dprintf_global( stddeb, "GlobalFree: %04x\n", handle );
Alexandre Julliard594997c1995-04-30 10:05:20 +0000368 if (!GLOBAL_FreeBlock( handle )) return handle; /* failed */
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000369 if (is_dde_handle(handle)) return DDE_GlobalFree(handle);
370 if (ptr) free( ptr );
Alexandre Julliard121bd981993-07-08 17:37:25 +0000371 return 0;
372}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000373
374
375/***********************************************************************
376 * WIN16_GlobalLock (KERNEL.18)
Alexandre Julliard121bd981993-07-08 17:37:25 +0000377 *
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000378 * This is the GlobalLock() function used by 16-bit code.
Alexandre Julliard121bd981993-07-08 17:37:25 +0000379 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000380SEGPTR WIN16_GlobalLock( HGLOBAL handle )
Alexandre Julliard121bd981993-07-08 17:37:25 +0000381{
Alexandre Julliard594997c1995-04-30 10:05:20 +0000382 dprintf_global( stddeb, "WIN16_GlobalLock(%04x) -> %08lx\n",
383 handle, MAKELONG( 0, GlobalHandleToSel(handle)) );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000384 if (!handle) return 0;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000385 if ( !is_dde_handle(handle) && !GET_ARENA_PTR(handle)->base)
386 return (SEGPTR)0;
387
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000388 return (SEGPTR)MAKELONG( 0, GlobalHandleToSel(handle) );
Alexandre Julliard121bd981993-07-08 17:37:25 +0000389}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000390
391
392/***********************************************************************
393 * GlobalLock (KERNEL.18)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000394 *
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000395 * This is the GlobalLock() function used by 32-bit code.
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000396 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000397LPSTR GlobalLock( HGLOBAL handle )
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000398{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000399 if (!handle) return 0;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000400 if (is_dde_handle(handle)) {
401 return DDE_AttachHandle(handle, NULL);
402 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000403 return (LPSTR)GET_ARENA_PTR(handle)->base;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000404}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000405
406
407/***********************************************************************
408 * GlobalUnlock (KERNEL.19)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000409 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000410BOOL GlobalUnlock( HGLOBAL handle )
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000411{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000412 dprintf_global( stddeb, "GlobalUnlock: %04x\n", handle );
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000413 return 0;
414}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000415
416
417/***********************************************************************
418 * GlobalSize (KERNEL.20)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000419 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000420DWORD GlobalSize( HGLOBAL handle )
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000421{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000422 dprintf_global( stddeb, "GlobalSize: %04x\n", handle );
423 if (!handle) return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000424 return GET_ARENA_PTR(handle)->size;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000425}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000426
427
428/***********************************************************************
429 * GlobalHandle (KERNEL.21)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000430 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000431DWORD GlobalHandle( WORD sel )
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000432{
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000433 dprintf_global( stddeb, "GlobalHandle: %04x\n", sel );
434 return MAKELONG( GET_ARENA_PTR(sel)->handle, sel );
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000435}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000436
437
438/***********************************************************************
439 * GlobalFlags (KERNEL.22)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000440 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000441WORD GlobalFlags( HGLOBAL handle )
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000442{
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000443 GLOBALARENA *pArena;
444
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000445 dprintf_global( stddeb, "GlobalFlags: %04x\n", handle );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000446 pArena = GET_ARENA_PTR(handle);
447 return pArena->lockCount |
Alexandre Julliard2787be81995-05-22 18:23:01 +0000448 ((pArena->flags & GA_DISCARDABLE) ? GMEM_DISCARDABLE : 0) |
449 ((pArena->base == 0) ? GMEM_DISCARDED : 0);
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000450}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000451
452
453/***********************************************************************
454 * LockSegment (KERNEL.23)
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000455 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000456HGLOBAL LockSegment( HGLOBAL handle )
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000457{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000458 dprintf_global( stddeb, "LockSegment: %04x\n", handle );
459 if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000460 GET_ARENA_PTR(handle)->lockCount++;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000461 return handle;
Alexandre Julliard75a839a1993-07-15 11:13:45 +0000462}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000463
464
465/***********************************************************************
466 * UnlockSegment (KERNEL.24)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000467 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000468void UnlockSegment( HGLOBAL handle )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000469{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000470 dprintf_global( stddeb, "UnlockSegment: %04x\n", handle );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000471 if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
472 GET_ARENA_PTR(handle)->lockCount--;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000473 /* FIXME: this ought to return the lock count in CX (go figure...) */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000474}
Alexandre Julliard401710d1993-09-04 10:09:32 +0000475
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000476
477/***********************************************************************
478 * GlobalCompact (KERNEL.25)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000479 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000480DWORD GlobalCompact( DWORD desired )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000481{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000482 return GLOBAL_MAX_ALLOC_SIZE;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000483}
484
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000485
486/***********************************************************************
Alexandre Julliard594997c1995-04-30 10:05:20 +0000487 * GlobalFreeAll (KERNEL.26)
488 */
489void GlobalFreeAll( HANDLE owner )
490{
491 DWORD i;
492 GLOBALARENA *pArena;
493
494 pArena = pGlobalArena;
495 for (i = 0; i < globalArenaSize; i++, pArena++)
496 {
497 if ((pArena->size != 0) && (pArena->hOwner == owner))
498 GlobalFree( pArena->handle );
499 }
500}
501
502
503/***********************************************************************
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000504 * GlobalWire (KERNEL.111)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000505 */
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000506SEGPTR GlobalWire( HGLOBAL handle )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000507{
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000508 return WIN16_GlobalLock( handle );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000509}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000510
511
512/***********************************************************************
513 * GlobalUnWire (KERNEL.112)
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000514 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000515BOOL GlobalUnWire( HGLOBAL handle )
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000516{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000517 return GlobalUnlock( handle );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000518}
Alexandre Julliardaca05781994-10-17 18:12:41 +0000519
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000520
521/***********************************************************************
522 * GlobalDOSAlloc (KERNEL.184)
523 */
524DWORD GlobalDOSAlloc( DWORD size )
525{
526 WORD sel = GlobalAlloc( GMEM_FIXED, size );
527 if (!sel) return 0;
528 return MAKELONG( sel, sel /* this one ought to be a real-mode segment */ );
529}
530
531
532/***********************************************************************
533 * GlobalDOSFree (KERNEL.185)
534 */
535WORD GlobalDOSFree( WORD sel )
536{
537 return GlobalFree( GlobalHandle(sel) ) ? sel : 0;
538}
539
540
Alexandre Julliardaca05781994-10-17 18:12:41 +0000541/***********************************************************************
542 * SetSwapAreaSize (KERNEL.106)
543 */
544LONG SetSwapAreaSize( WORD size )
545{
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000546 dprintf_global(stdnimp, "STUB: SetSwapAreaSize(%d)\n", size );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000547 return MAKELONG( size, 0xffff );
548}
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000549
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000550
551/***********************************************************************
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000552 * GlobalLRUOldest (KERNEL.163)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000553 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000554HGLOBAL GlobalLRUOldest( HGLOBAL handle )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000555{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000556 dprintf_global( stddeb, "GlobalLRUOldest: %04x\n", handle );
557 if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
558 return handle;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000559}
560
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000561
562/***********************************************************************
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000563 * GlobalLRUNewest (KERNEL.164)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000564 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000565HGLOBAL GlobalLRUNewest( HGLOBAL handle )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000566{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000567 dprintf_global( stddeb, "GlobalLRUNewest: %04x\n", handle );
568 if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
569 return handle;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000570}
571
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000572
573/***********************************************************************
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000574 * GetFreeSpace (KERNEL.169)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000575 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000576DWORD GetFreeSpace( UINT wFlags )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000577{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000578 return GLOBAL_MAX_ALLOC_SIZE;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000579}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000580
581
582/***********************************************************************
583 * GlobalPageLock (KERNEL.191)
584 */
585WORD GlobalPageLock( HGLOBAL handle )
586{
587 dprintf_global( stddeb, "GlobalPageLock: %04x\n", handle );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000588 return ++(GET_ARENA_PTR(handle)->pageLockCount);
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000589}
590
591
592/***********************************************************************
593 * GlobalPageUnlock (KERNEL.192)
594 */
595WORD GlobalPageUnlock( HGLOBAL handle )
596{
597 dprintf_global( stddeb, "GlobalPageUnlock: %04x\n", handle );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000598 return --(GET_ARENA_PTR(handle)->pageLockCount);
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000599}
600
601
602/***********************************************************************
603 * GlobalFix (KERNEL.197)
604 */
605void GlobalFix( HGLOBAL handle )
606{
607 dprintf_global( stddeb, "GlobalFix: %04x\n", handle );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000608 GET_ARENA_PTR(handle)->lockCount++;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000609}
610
611
612/***********************************************************************
613 * GlobalUnfix (KERNEL.198)
614 */
615void GlobalUnfix( HGLOBAL handle )
616{
617 dprintf_global( stddeb, "GlobalUnfix: %04x\n", handle );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000618 GET_ARENA_PTR(handle)->lockCount--;
619}
620
621
622/***********************************************************************
623 * FarSetOwner (KERNEL.403)
624 */
625void FarSetOwner( HANDLE handle, WORD hOwner )
626{
627 GET_ARENA_PTR(handle)->hOwner = hOwner;
628}
629
630
631/***********************************************************************
632 * FarGetOwner (KERNEL.404)
633 */
634WORD FarGetOwner( HANDLE handle )
635{
636 return GET_ARENA_PTR(handle)->hOwner;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000637}
638
639
640/***********************************************************************
641 * GlobalHandleToSel (TOOLHELP.50)
642 */
643WORD GlobalHandleToSel( HGLOBAL handle )
644{
645 dprintf_toolhelp( stddeb, "GlobalHandleToSel: %04x\n", handle );
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000646 if (!handle) return 0;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000647 if (is_dde_handle(handle))
648 return DDE_GlobalHandleToSel(handle);
649
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000650 if (!(handle & 7))
651 {
652 fprintf( stderr, "Program attempted invalid selector conversion\n" );
653 return handle - 1;
654 }
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000655 return handle | 7;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000656}
657
658
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000659/***********************************************************************
660 * GlobalFirst (TOOLHELP.51)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000661 */
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000662BOOL GlobalFirst( GLOBALENTRY *pGlobal, WORD wFlags )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000663{
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000664 if (wFlags == GLOBAL_LRU) return FALSE;
665 pGlobal->dwNext = 0;
666 return GlobalNext( pGlobal, wFlags );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000667}
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000668
669
670/***********************************************************************
671 * GlobalNext (TOOLHELP.52)
672 */
673BOOL GlobalNext( GLOBALENTRY *pGlobal, WORD wFlags)
674{
675 GLOBALARENA *pArena;
676
Alexandre Julliard594997c1995-04-30 10:05:20 +0000677 if (pGlobal->dwNext >= globalArenaSize) return FALSE;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000678 pArena = pGlobalArena + pGlobal->dwNext;
679 if (wFlags == GLOBAL_FREE) /* only free blocks */
680 {
681 int i;
682 for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++)
683 if (pArena->size == 0) break; /* block is free */
684 if (i >= globalArenaSize) return FALSE;
685 pGlobal->dwNext = i;
686 }
687
688 pGlobal->dwAddress = pArena->base;
689 pGlobal->dwBlockSize = pArena->size;
690 pGlobal->hBlock = pArena->handle;
691 pGlobal->wcLock = pArena->lockCount;
692 pGlobal->wcPageLock = pArena->pageLockCount;
693 pGlobal->wFlags = (GetCurrentPDB() == pArena->hOwner);
694 pGlobal->wHeapPresent = FALSE;
695 pGlobal->hOwner = pArena->hOwner;
696 pGlobal->wType = GT_UNKNOWN;
697 pGlobal->wData = 0;
698 pGlobal->dwNext++;
699 return TRUE;
700}
701
702
703/***********************************************************************
704 * GlobalInfo (TOOLHELP.53)
705 */
706BOOL GlobalInfo( GLOBALINFO *pInfo )
707{
708 int i;
709 GLOBALARENA *pArena;
710
711 pInfo->wcItems = globalArenaSize;
712 pInfo->wcItemsFree = 0;
713 pInfo->wcItemsLRU = 0;
714 for (i = 0, pArena = pGlobalArena; i < globalArenaSize; i++, pArena++)
715 if (pArena->size == 0) pInfo->wcItemsFree++;
716 return TRUE;
717}
718
719
720/***********************************************************************
721 * GlobalEntryHandle (TOOLHELP.54)
722 */
723BOOL GlobalEntryHandle( GLOBALENTRY *pGlobal, HGLOBAL hItem )
724{
725 return FALSE;
726}
727
728
729/***********************************************************************
730 * GlobalEntryModule (TOOLHELP.55)
731 */
732BOOL GlobalEntryModule( GLOBALENTRY *pGlobal, HMODULE hModule, WORD wSeg )
733{
734 return FALSE;
735}
736
737
738/***********************************************************************
739 * MemManInfo (TOOLHELP.72)
740 */
741BOOL MemManInfo( MEMMANINFO *pInfo )
742{
743 return TRUE;
744}
Alexandre Julliard2787be81995-05-22 18:23:01 +0000745
746/***********************************************************************
747 * GlobalAlloc32
748 * implements GlobalAlloc (KERNEL32.316)
749 * LocalAlloc (KERNEL32.372)
750 */
751void *GlobalAlloc32(int flags,int size)
752{
753 dprintf_global(stddeb,"GlobalAlloc32(%x,%x)\n",flags,size);
754 return malloc(size);
755}