2 * Global heap functions
4 * Copyright 1995 Alexandre Julliard
11 #include "selectors.h"
12 #include "stackframe.h"
16 #define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000 /* Largest allocation is 16M - 64K */
18 #define HGLOBAL_TO_SEL(handle) \
19 ((handle == (HGLOBAL)-1) ? CURRENT_DS : GlobalHandleToSel(handle))
21 /***********************************************************************
22 * GlobalAlloc (KERNEL.15)
24 HGLOBAL
GlobalAlloc( WORD flags
, DWORD size
)
29 dprintf_global( stddeb
, "GlobalAlloc: %ld flags=%04x\n", size
, flags
);
33 if (size
>= GLOBAL_MAX_ALLOC_SIZE
- 0x0f) return 0;
34 if (size
== 0) size
= 0x10;
35 else size
= (size
+ 0x0f) & ~0x0f;
37 /* Allocate the linear memory */
42 /* Allocate the selector(s) */
44 sel
= SELECTOR_AllocBlock( ptr
, size
, SEGMENT_DATA
, 0, 0 );
51 if (flags
& GMEM_ZEROINIT
) memset( ptr
, 0, size
);
53 /* Return the handle */
54 /* If allocating a GMEM_FIXED block, the handle is the selector. */
55 /* Otherwise, the handle is the selector-1 (don't ask me why :-) */
56 if (flags
& GMEM_MOVEABLE
) return sel
- 1;
61 /***********************************************************************
62 * GlobalReAlloc (KERNEL.16)
64 HGLOBAL
GlobalReAlloc( HGLOBAL handle
, DWORD size
, WORD flags
)
70 dprintf_global( stddeb
, "GlobalReAlloc: %04x %ld flags=%04x\n",
71 handle
, size
, flags
);
75 if (size
>= 0x00ff0000-0x0f) return 0; /* No allocation > 16Mb-64Kb */
76 if (size
== 0) size
= 0x10;
77 else size
= (size
+ 0x0f) & ~0x0f;
79 /* Reallocate the linear memory */
81 sel
= GlobalHandleToSel( handle
);
82 ptr
= (void *)GET_SEL_BASE( sel
);
83 oldsize
= GlobalSize( handle
);
84 if (size
== oldsize
) return handle
; /* Nothing to do */
86 ptr
= realloc( ptr
, size
);
93 /* Reallocate the selector(s) */
95 sel
= SELECTOR_ReallocBlock( sel
, ptr
, size
, SEGMENT_DATA
, 0, 0 );
102 if ((oldsize
< size
) && (flags
& GMEM_ZEROINIT
))
103 memset( (char *)ptr
+ oldsize
, 0, size
- oldsize
);
105 if (sel
== GlobalHandleToSel( handle
))
106 return handle
; /* Selector didn't change */
108 if (flags
& GMEM_MOVEABLE
) return sel
- 1;
113 /***********************************************************************
114 * GlobalFree (KERNEL.17)
116 HGLOBAL
GlobalFree( HGLOBAL handle
)
121 dprintf_global( stddeb
, "GlobalFree: %04x\n", handle
);
122 sel
= GlobalHandleToSel( handle
);
123 ptr
= (void *)GET_SEL_BASE(sel
);
124 if (FreeSelector( sel
)) return handle
; /* failed */
130 /***********************************************************************
131 * WIN16_GlobalLock (KERNEL.18)
133 * This is the GlobalLock() function used by 16-bit code.
135 SEGPTR
WIN16_GlobalLock( HGLOBAL handle
)
137 dprintf_global( stddeb
, "WIN16_GlobalLock: %04x\n", handle
);
138 if (!handle
) return 0;
139 return (SEGPTR
)MAKELONG( 0, HGLOBAL_TO_SEL(handle
) );
143 /***********************************************************************
144 * GlobalLock (KERNEL.18)
146 * This is the GlobalLock() function used by 32-bit code.
148 LPSTR
GlobalLock( HGLOBAL handle
)
150 dprintf_global( stddeb
, "GlobalLock: %04x\n", handle
);
151 if (!handle
) return 0;
152 return (LPSTR
)GET_SEL_BASE( HGLOBAL_TO_SEL(handle
) );
156 /***********************************************************************
157 * GlobalUnlock (KERNEL.19)
159 BOOL
GlobalUnlock( HGLOBAL handle
)
161 dprintf_global( stddeb
, "GlobalUnlock: %04x\n", handle
);
166 /***********************************************************************
167 * GlobalSize (KERNEL.20)
169 DWORD
GlobalSize( HGLOBAL handle
)
171 dprintf_global( stddeb
, "GlobalSize: %04x\n", handle
);
172 if (!handle
) return 0;
173 return GET_SEL_LIMIT( HGLOBAL_TO_SEL(handle
) ) + 1;
177 /***********************************************************************
178 * GlobalHandle (KERNEL.21)
180 DWORD
GlobalHandle( WORD sel
)
182 /* FIXME: what about GMEM_FIXED blocks? */
183 WORD handle
= sel
& ~1;
184 dprintf_global( stddeb
, "GlobalHandle(%04x): returning %08lx\n",
185 sel
, MAKELONG( handle
, sel
) );
186 return MAKELONG( handle
, sel
);
190 /***********************************************************************
191 * GlobalFlags (KERNEL.22)
193 WORD
GlobalFlags( HGLOBAL handle
)
195 dprintf_global( stddeb
, "GlobalFlags: %04x\n", handle
);
196 return 0; /* lock count is always 0 */
200 /***********************************************************************
201 * LockSegment (KERNEL.23)
203 HGLOBAL
LockSegment( HGLOBAL handle
)
205 dprintf_global( stddeb
, "LockSegment: %04x\n", handle
);
206 if (handle
== (HGLOBAL
)-1) handle
= CURRENT_DS
;
211 /***********************************************************************
212 * UnlockSegment (KERNEL.24)
214 void UnlockSegment( HGLOBAL handle
)
216 dprintf_global( stddeb
, "UnlockSegment: %04x\n", handle
);
217 /* FIXME: this ought to return the lock count in CX (go figure...) */
221 /***********************************************************************
222 * GlobalCompact (KERNEL.25)
224 DWORD
GlobalCompact( DWORD desired
)
226 return GLOBAL_MAX_ALLOC_SIZE
;
230 /***********************************************************************
231 * GlobalWire (KERNEL.111)
233 LPSTR
GlobalWire( HGLOBAL handle
)
235 return GlobalLock( handle
);
239 /***********************************************************************
240 * GlobalUnWire (KERNEL.112)
242 BOOL
GlobalUnWire( HGLOBAL handle
)
244 return GlobalUnlock( handle
);
248 /***********************************************************************
249 * GlobalDOSAlloc (KERNEL.184)
251 DWORD
GlobalDOSAlloc( DWORD size
)
253 WORD sel
= GlobalAlloc( GMEM_FIXED
, size
);
255 return MAKELONG( sel
, sel
/* this one ought to be a real-mode segment */ );
259 /***********************************************************************
260 * GlobalDOSFree (KERNEL.185)
262 WORD
GlobalDOSFree( WORD sel
)
264 return GlobalFree( GlobalHandle(sel
) ) ? sel
: 0;
268 /***********************************************************************
269 * SetSwapAreaSize (KERNEL.106)
271 LONG
SetSwapAreaSize( WORD size
)
273 dprintf_heap(stdnimp
, "STUB: SetSwapAreaSize(%d)\n", size
);
274 return MAKELONG( size
, 0xffff );
278 /***********************************************************************
279 * GlobalLRUOldest (KERNEL.163)
281 HGLOBAL
GlobalLRUOldest( HGLOBAL handle
)
283 dprintf_global( stddeb
, "GlobalLRUOldest: %04x\n", handle
);
284 if (handle
== (HGLOBAL
)-1) handle
= CURRENT_DS
;
289 /***********************************************************************
290 * GlobalLRUNewest (KERNEL.164)
292 HGLOBAL
GlobalLRUNewest( HGLOBAL handle
)
294 dprintf_global( stddeb
, "GlobalLRUNewest: %04x\n", handle
);
295 if (handle
== (HGLOBAL
)-1) handle
= CURRENT_DS
;
300 /***********************************************************************
301 * GetFreeSpace (KERNEL.169)
303 DWORD
GetFreeSpace( UINT wFlags
)
305 return GLOBAL_MAX_ALLOC_SIZE
;
309 /***********************************************************************
310 * GlobalPageLock (KERNEL.191)
312 WORD
GlobalPageLock( HGLOBAL handle
)
314 dprintf_global( stddeb
, "GlobalPageLock: %04x\n", handle
);
315 /* Nothing to do, as we can't page-lock a block (and we don't want to) */
316 return 1; /* lock count */
320 /***********************************************************************
321 * GlobalPageUnlock (KERNEL.192)
323 WORD
GlobalPageUnlock( HGLOBAL handle
)
325 dprintf_global( stddeb
, "GlobalPageUnlock: %04x\n", handle
);
326 return 0; /* lock count */
330 /***********************************************************************
331 * GlobalFix (KERNEL.197)
333 void GlobalFix( HGLOBAL handle
)
335 dprintf_global( stddeb
, "GlobalFix: %04x\n", handle
);
336 /* Nothing to do, as all the blocks are fixed in linear memory anyway */
340 /***********************************************************************
341 * GlobalUnfix (KERNEL.198)
343 void GlobalUnfix( HGLOBAL handle
)
345 dprintf_global( stddeb
, "GlobalUnfix: %04x\n", handle
);
346 /* This one is even more complicated that GlobalFix() :-) */
350 /***********************************************************************
351 * GlobalHandleToSel (TOOLHELP.50)
353 WORD
GlobalHandleToSel( HGLOBAL handle
)
355 dprintf_toolhelp( stddeb
, "GlobalHandleToSel: %04x\n", handle
);
358 fprintf( stderr
, "Program attempted invalid selector conversion\n" );
365 /**********************************************************************
366 * MemManInfo (toolhelp.72)
369 BOOL MemManInfo(LPMEMMANINFO lpmmi)