1 /* $Id: global.c,v 1.4 2000/07/01 17:07:00 ea Exp $
3 * Win32 Global/Local heap functions (GlobalXXX, LocalXXX).
4 * These functions included in Win32 for compatibility with 16 bit Windows
5 * Especially the moveable blocks and handles are oldish.
6 * But the ability to directly allocate memory with GPTR and LPTR is widely
13 #include <kernel32/kernel32.h>
15 #define MAGIC_GLOBAL_USED 0x5342BEEF
16 #define GLOBAL_LOCK_MAX 0xFF
18 typedef struct __GLOBAL_LOCAL_HANDLE
24 } GLOBAL_HANDLE
, LOCAL_HANDLE
, *PGLOBAL_HANDLE
, *PLOCAL_HANDLE
;
26 /*********************************************************************
27 * GlobalAlloc -- KERNEL32 *
28 *********************************************************************/
29 HGLOBAL WINAPI
GlobalAlloc(UINT flags
, DWORD size
)
31 PGLOBAL_HANDLE phandle
;
34 DPRINT("GlobalAlloc( 0x%X, 0x%lX )\n", flags
, size
);
36 if((flags
& GMEM_MOVEABLE
)==0) /* POINTER */
38 palloc
=HeapAlloc(__ProcessHeap
, 0, size
);
39 return (HGLOBAL
) palloc
;
43 HeapLock(__ProcessHeap
);
46 phandle
=__HeapAllocFragment(__ProcessHeap
, 0, sizeof(GLOBAL_HANDLE
));
49 palloc
=HeapAlloc(__ProcessHeap
, 0, size
+sizeof(HANDLE
));
50 *(PHANDLE
)palloc
=(HANDLE
) &(phandle
->Pointer
);
51 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
54 phandle
->Pointer
=NULL
;
55 phandle
->Magic
=MAGIC_GLOBAL_USED
;
56 phandle
->Flags
=flags
>>8;
58 HeapUnlock(__ProcessHeap
);
60 return (HGLOBAL
) &(phandle
->Pointer
);
64 /*********************************************************************
65 * GlobalLock -- KERNEL32 *
66 *********************************************************************/
67 LPVOID WINAPI
GlobalLock(HGLOBAL hmem
)
69 PGLOBAL_HANDLE phandle
;
72 DPRINT("GlobalLock( 0x%lX )\n", (ULONG
) hmem
);
74 if(((ULONG
)hmem
%8)==0)
77 HeapLock(__ProcessHeap
);
78 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
79 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
81 if(phandle
->LockCount
<GLOBAL_LOCK_MAX
)
83 palloc
=phandle
->Pointer
;
87 DPRINT("GlobalLock: invalid handle\n");
90 HeapUnlock(__ProcessHeap
);
94 /*********************************************************************
95 * GlobalUnlock -- KERNEL32 *
96 *********************************************************************/
97 BOOL WINAPI
GlobalUnlock(HGLOBAL hmem
)
99 PGLOBAL_HANDLE phandle
;
102 DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG
) hmem
);
104 if(((ULONG
)hmem
%8)==0)
107 HeapLock(__ProcessHeap
);
108 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
109 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
111 if((phandle
->LockCount
<GLOBAL_LOCK_MAX
)&&(phandle
->LockCount
>0))
112 phandle
->LockCount
--;
114 locked
=(phandle
->LockCount
==0) ? TRUE
: FALSE
;
118 DPRINT("GlobalUnlock: invalid handle\n");
121 HeapUnlock(__ProcessHeap
);
125 /*********************************************************************
126 * GlobalHandle -- KERNEL32 *
127 *********************************************************************/
128 HGLOBAL WINAPI
GlobalHandle(LPCVOID pmem
)
130 DPRINT("GlobalHandle( 0x%lX )\n", (ULONG
) pmem
);
132 if(((ULONG
)pmem
%8)==0) /* FIXED */
133 return (HGLOBAL
) pmem
;
135 return (HGLOBAL
) *(LPVOID
*)(pmem
-sizeof(HANDLE
));
138 /*********************************************************************
139 * GlobalReAlloc -- KERNEL32 *
140 *********************************************************************/
141 HGLOBAL WINAPI
GlobalReAlloc(HGLOBAL hmem
, DWORD size
, UINT flags
)
145 PGLOBAL_HANDLE phandle
;
147 DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG
) hmem
, size
, flags
);
150 HeapLock(__ProcessHeap
);
151 if(flags
& GMEM_MODIFY
) /* modify flags */
153 if( (((ULONG
)hmem
%8)==0) && (flags
& GMEM_MOVEABLE
))
155 /* make a fixed block moveable
156 * actually only NT is able to do this. And it's soo simple
158 size
=HeapSize(__ProcessHeap
, 0, (LPVOID
) hmem
);
159 hnew
=GlobalAlloc( flags
, size
);
160 palloc
=GlobalLock(hnew
);
161 memcpy(palloc
, (LPVOID
) hmem
, size
);
163 GlobalHeapFree(GetProcessHeap(),0,hmem
);
165 else if((((ULONG
)hmem
%8) != 0)&&(flags
& GMEM_DISCARDABLE
))
167 /* change the flags to make our block "discardable" */
168 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
169 phandle
->Flags
= phandle
->Flags
| (GMEM_DISCARDABLE
>> 8);
174 SetLastError(ERROR_INVALID_PARAMETER
);
180 if(((ULONG
)hmem
%8)!=0)
182 /* reallocate fixed memory */
183 hnew
=(HANDLE
)HeapReAlloc(__ProcessHeap
, 0, (LPVOID
) hmem
, size
);
187 /* reallocate a moveable block */
188 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
189 if(phandle
->LockCount
!=0)
190 SetLastError(ERROR_INVALID_HANDLE
);
196 palloc
=HeapReAlloc(__ProcessHeap
, 0,
197 phandle
->Pointer
-sizeof(HANDLE
),
198 size
+sizeof(HANDLE
) );
199 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
203 palloc
=HeapAlloc(__ProcessHeap
, 0, size
+sizeof(HANDLE
));
204 *(PHANDLE
)palloc
=hmem
;
205 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
212 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, phandle
->Pointer
-sizeof(HANDLE
));
213 phandle
->Pointer
=NULL
;
218 HeapUnlock(__ProcessHeap
);
222 /*********************************************************************
223 * GlobalFree -- KERNEL32 *
224 *********************************************************************/
225 HGLOBAL WINAPI
GlobalHeapFree(GetProcessHeap(),0,HGLOBAL hmem
)
227 PGLOBAL_HANDLE phandle
;
229 DPRINT("GlobalHeapFree(GetProcessHeap(),0, 0x%lX )\n", (ULONG
) hmem
);
231 if(((ULONG
)hmem
%4)==0) /* POINTER */
233 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, (LPVOID
) hmem
);
237 HeapLock(__ProcessHeap
);
238 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
239 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
241 HeapLock(__ProcessHeap
);
242 if(phandle
->LockCount
!=0)
243 SetLastError(ERROR_INVALID_HANDLE
);
245 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, phandle
->Pointer
-sizeof(HANDLE
));
246 __HeapFreeFragment(__ProcessHeap
, 0, phandle
);
248 HeapUnlock(__ProcessHeap
);
253 /*********************************************************************
254 * GlobalSize -- KERNEL32 *
255 *********************************************************************/
256 DWORD WINAPI
GlobalSize(HGLOBAL hmem
)
259 PGLOBAL_HANDLE phandle
;
261 DPRINT("GlobalSize( 0x%lX )\n", (ULONG
) hmem
);
263 if(((ULONG
)hmem
%8)==0)
265 retval
=HeapSize(__ProcessHeap
, 0, hmem
);
269 HeapLock(__ProcessHeap
);
270 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
271 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
273 retval
=HeapSize(__ProcessHeap
, 0, (phandle
->Pointer
)-sizeof(HANDLE
))-4;
277 DPRINT("GlobalSize: invalid handle\n");
280 HeapUnlock(__ProcessHeap
);
285 /*********************************************************************
286 * GlobalWire -- KERNEL32 *
287 *********************************************************************/
288 LPVOID WINAPI
GlobalWire(HGLOBAL hmem
)
290 return GlobalLock( hmem
);
293 /*********************************************************************
294 * GlobalUnWire -- KERNEL32 *
295 *********************************************************************/
296 BOOL WINAPI
GlobalUnWire(HGLOBAL hmem
)
298 return GlobalUnlock( hmem
);
301 /*********************************************************************
302 * GlobalFix -- KERNEL32 *
303 *********************************************************************/
304 VOID WINAPI
GlobalFix(HGLOBAL hmem
)
309 /*********************************************************************
310 * GlobalUnfix -- KERNEL32 *
311 *********************************************************************/
312 VOID WINAPI
GlobalUnfix(HGLOBAL hmem
)
317 /*********************************************************************
318 * GlobalFlags -- KERNEL32 *
319 *********************************************************************/
320 UINT WINAPI
GlobalFlags(HGLOBAL hmem
)
322 return LocalFlags( (HLOCAL
) hmem
);