1 /* $Id: global.c,v 1.5 2001/01/20 12:18:54 ekohl 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
11 * NOTE: Only fixed memory is implemented!!
14 #include <ddk/ntddk.h>
15 #include <ntdll/rtl.h>
19 #include <kernel32/kernel32.h>
22 #define MAGIC_GLOBAL_USED 0x5342BEEF
23 #define GLOBAL_LOCK_MAX 0xFF
25 typedef struct __GLOBAL_LOCAL_HANDLE
31 } GLOBAL_HANDLE
, LOCAL_HANDLE
, *PGLOBAL_HANDLE
, *PLOCAL_HANDLE
;
33 /*********************************************************************
34 * GlobalAlloc -- KERNEL32 *
35 *********************************************************************/
36 HGLOBAL WINAPI
GlobalAlloc(UINT flags
, DWORD size
)
38 PGLOBAL_HANDLE phandle
;
41 DPRINT("GlobalAlloc( 0x%X, 0x%lX )\n", flags
, size
);
43 if((flags
& GMEM_MOVEABLE
)==0) /* POINTER */
45 palloc
=RtlAllocateHeap(hProcessHeap
, 0, size
);
46 return (HGLOBAL
) palloc
;
51 HeapLock(__ProcessHeap
);
54 phandle
=__HeapAllocFragment(__ProcessHeap
, 0, sizeof(GLOBAL_HANDLE
));
57 palloc
=HeapAlloc(__ProcessHeap
, 0, size
+sizeof(HANDLE
));
58 *(PHANDLE
)palloc
=(HANDLE
) &(phandle
->Pointer
);
59 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
62 phandle
->Pointer
=NULL
;
63 phandle
->Magic
=MAGIC_GLOBAL_USED
;
64 phandle
->Flags
=flags
>>8;
66 HeapUnlock(__ProcessHeap
);
68 return (HGLOBAL
) &(phandle
->Pointer
);
74 /*********************************************************************
75 * GlobalLock -- KERNEL32 *
76 *********************************************************************/
78 LPVOID WINAPI
GlobalLock(HGLOBAL hmem
)
80 PGLOBAL_HANDLE phandle
;
83 DPRINT("GlobalLock( 0x%lX )\n", (ULONG
) hmem
);
85 if(((ULONG
)hmem
%8)==0)
88 HeapLock(__ProcessHeap
);
89 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
90 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
92 if(phandle
->LockCount
<GLOBAL_LOCK_MAX
)
94 palloc
=phandle
->Pointer
;
98 DPRINT("GlobalLock: invalid handle\n");
101 HeapUnlock(__ProcessHeap
);
106 /*********************************************************************
107 * GlobalUnlock -- KERNEL32 *
108 *********************************************************************/
110 BOOL WINAPI
GlobalUnlock(HGLOBAL hmem
)
112 PGLOBAL_HANDLE phandle
;
115 DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG
) hmem
);
117 if(((ULONG
)hmem
%8)==0)
120 HeapLock(__ProcessHeap
);
121 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
122 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
124 if((phandle
->LockCount
<GLOBAL_LOCK_MAX
)&&(phandle
->LockCount
>0))
125 phandle
->LockCount
--;
127 locked
=(phandle
->LockCount
==0) ? TRUE
: FALSE
;
131 DPRINT("GlobalUnlock: invalid handle\n");
134 HeapUnlock(__ProcessHeap
);
139 /*********************************************************************
140 * GlobalHandle -- KERNEL32 *
141 *********************************************************************/
143 HGLOBAL WINAPI
GlobalHandle(LPCVOID pmem
)
145 DPRINT("GlobalHandle( 0x%lX )\n", (ULONG
) pmem
);
147 if(((ULONG
)pmem
%8)==0) /* FIXED */
148 return (HGLOBAL
) pmem
;
150 return (HGLOBAL
) *(LPVOID
*)(pmem
-sizeof(HANDLE
));
154 /*********************************************************************
155 * GlobalReAlloc -- KERNEL32 *
156 *********************************************************************/
158 HGLOBAL WINAPI
GlobalReAlloc(HGLOBAL hmem
, DWORD size
, UINT flags
)
162 PGLOBAL_HANDLE phandle
;
164 DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG
) hmem
, size
, flags
);
167 HeapLock(__ProcessHeap
);
168 if(flags
& GMEM_MODIFY
) /* modify flags */
170 if( (((ULONG
)hmem
%8)==0) && (flags
& GMEM_MOVEABLE
))
172 /* make a fixed block moveable
173 * actually only NT is able to do this. And it's soo simple
175 size
=HeapSize(__ProcessHeap
, 0, (LPVOID
) hmem
);
176 hnew
=GlobalAlloc( flags
, size
);
177 palloc
=GlobalLock(hnew
);
178 memcpy(palloc
, (LPVOID
) hmem
, size
);
180 GlobalHeapFree(GetProcessHeap(),0,hmem
);
182 else if((((ULONG
)hmem
%8) != 0)&&(flags
& GMEM_DISCARDABLE
))
184 /* change the flags to make our block "discardable" */
185 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
186 phandle
->Flags
= phandle
->Flags
| (GMEM_DISCARDABLE
>> 8);
191 SetLastError(ERROR_INVALID_PARAMETER
);
197 if(((ULONG
)hmem
%8)!=0)
199 /* reallocate fixed memory */
200 hnew
=(HANDLE
)HeapReAlloc(__ProcessHeap
, 0, (LPVOID
) hmem
, size
);
204 /* reallocate a moveable block */
205 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
206 if(phandle
->LockCount
!=0)
207 SetLastError(ERROR_INVALID_HANDLE
);
213 palloc
=HeapReAlloc(__ProcessHeap
, 0,
214 phandle
->Pointer
-sizeof(HANDLE
),
215 size
+sizeof(HANDLE
) );
216 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
220 palloc
=HeapAlloc(__ProcessHeap
, 0, size
+sizeof(HANDLE
));
221 *(PHANDLE
)palloc
=hmem
;
222 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
229 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, phandle
->Pointer
-sizeof(HANDLE
));
230 phandle
->Pointer
=NULL
;
235 HeapUnlock(__ProcessHeap
);
240 /*********************************************************************
241 * GlobalFree -- KERNEL32 *
242 *********************************************************************/
243 HGLOBAL WINAPI
GlobalFree(HGLOBAL hmem
)
246 PGLOBAL_HANDLE phandle
;
249 DPRINT("GlobalFree( 0x%lX )\n", (ULONG
) hmem
);
251 if (((ULONG
)hmem
% 4) == 0) /* POINTER */
253 RtlFreeHeap(hProcessHeap
, 0, (LPVOID
)hmem
);
258 HeapLock(__ProcessHeap
);
259 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
260 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
262 HeapLock(__ProcessHeap
);
263 if(phandle
->LockCount
!=0)
264 SetLastError(ERROR_INVALID_HANDLE
);
266 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, phandle
->Pointer
-sizeof(HANDLE
));
267 __HeapFreeFragment(__ProcessHeap
, 0, phandle
);
269 HeapUnlock(__ProcessHeap
);
276 /*********************************************************************
277 * GlobalSize -- KERNEL32 *
278 *********************************************************************/
279 DWORD WINAPI
GlobalSize(HGLOBAL hmem
)
282 PGLOBAL_HANDLE phandle
;
284 DPRINT("GlobalSize( 0x%lX )\n", (ULONG
) hmem
);
286 if(((ULONG
)hmem
% 4) == 0)
288 retval
= RtlSizeHeap(hProcessHeap
, 0, hmem
);
293 HeapLock(__ProcessHeap
);
294 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
295 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
297 retval
=HeapSize(__ProcessHeap
, 0, (phandle
->Pointer
)-sizeof(HANDLE
))-4;
301 DPRINT("GlobalSize: invalid handle\n");
304 HeapUnlock(__ProcessHeap
);
311 /*********************************************************************
312 * GlobalWire -- KERNEL32 *
313 *********************************************************************/
315 LPVOID WINAPI
GlobalWire(HGLOBAL hmem
)
317 return GlobalLock( hmem
);
321 /*********************************************************************
322 * GlobalUnWire -- KERNEL32 *
323 *********************************************************************/
325 BOOL WINAPI
GlobalUnWire(HGLOBAL hmem
)
327 return GlobalUnlock( hmem
);
331 /*********************************************************************
332 * GlobalFix -- KERNEL32 *
333 *********************************************************************/
335 VOID WINAPI
GlobalFix(HGLOBAL hmem
)
341 /*********************************************************************
342 * GlobalUnfix -- KERNEL32 *
343 *********************************************************************/
345 VOID WINAPI
GlobalUnfix(HGLOBAL hmem
)
351 /*********************************************************************
352 * GlobalFlags -- KERNEL32 *
353 *********************************************************************/
355 UINT WINAPI
GlobalFlags(HGLOBAL hmem
)
357 return LocalFlags( (HLOCAL
) hmem
);