1 /* $Id: global.c,v 1.6 2001/04/05 01:54:16 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
;
34 /* FUNCTIONS ***************************************************************/
37 GlobalAlloc(UINT uFlags
,
41 PGLOBAL_HANDLE phandle
;
45 DPRINT("GlobalAlloc( 0x%X, 0x%lX )\n", uFlags
, dwBytes
);
47 if ((uFlags
& GMEM_MOVEABLE
)==0) /* POINTER */
49 return ((HGLOBAL
)RtlAllocateHeap(hProcessHeap
, 0, dwBytes
));
54 HeapLock(__ProcessHeap
);
57 phandle
=__HeapAllocFragment(__ProcessHeap
, 0, sizeof(GLOBAL_HANDLE
));
60 palloc
=HeapAlloc(__ProcessHeap
, 0, size
+sizeof(HANDLE
));
61 *(PHANDLE
)palloc
=(HANDLE
) &(phandle
->Pointer
);
62 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
65 phandle
->Pointer
=NULL
;
66 phandle
->Magic
=MAGIC_GLOBAL_USED
;
67 phandle
->Flags
=uFlags
>>8;
69 HeapUnlock(__ProcessHeap
);
71 return (HGLOBAL
) &(phandle
->Pointer
);
79 GlobalCompact(DWORD dwMinFree
)
81 return RtlCompactHeap(hProcessHeap
, 0);
86 GlobalFix(HGLOBAL hMem
)
88 if (hMem
!= INVALID_HANDLE_VALUE
)
94 GlobalFlags(HGLOBAL hMem
)
98 PGLOBAL_HANDLE phandle
;
101 DPRINT("GlobalFlags( 0x%lX )\n", (ULONG
)hMem
);
104 if(((ULONG
)hmem
%8)==0)
110 HeapLock(__ProcessHeap
);
111 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
112 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
114 retval
=phandle
->LockCount
+ (phandle
->Flags
<<8);
115 if(phandle
->Pointer
==0)
116 retval
|= LMEM_DISCARDED
;
120 DPRINT("GlobalSize: invalid handle\n");
123 HeapUnlock(__ProcessHeap
);
133 GlobalFree(HGLOBAL hMem
)
136 PGLOBAL_HANDLE phandle
;
139 DPRINT("GlobalFree( 0x%lX )\n", (ULONG
)hMem
);
141 if (((ULONG
)hMem
% 4) == 0) /* POINTER */
143 RtlFreeHeap(hProcessHeap
, 0, (PVOID
)hMem
);
148 HeapLock(__ProcessHeap
);
149 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hMem
)-4);
150 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
152 HeapLock(__ProcessHeap
);
153 if(phandle
->LockCount
!=0)
154 SetLastError(ERROR_INVALID_HANDLE
);
156 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, phandle
->Pointer
-sizeof(HANDLE
));
157 __HeapFreeFragment(__ProcessHeap
, 0, phandle
);
159 HeapUnlock(__ProcessHeap
);
168 GlobalHandle(LPCVOID pMem
)
170 DPRINT("GlobalHandle( 0x%lX )\n", (ULONG
)pMem
);
173 if(((ULONG
)pmem
%8)==0) /* FIXED */
174 return (HGLOBAL
) pmem
;
176 return (HGLOBAL
) *(LPVOID
*)(pmem
-sizeof(HANDLE
));
179 return (HGLOBAL
)pMem
;
184 GlobalLock(HGLOBAL hMem
)
187 PGLOBAL_HANDLE phandle
;
191 DPRINT("GlobalLock( 0x%lX )\n", (ULONG
)hMem
);
194 if(((ULONG
)hmem
%8)==0)
195 return (LPVOID
) hmem
;
197 HeapLock(__ProcessHeap
);
198 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
199 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
201 if(phandle
->LockCount
<GLOBAL_LOCK_MAX
)
202 phandle
->LockCount
++;
203 palloc
=phandle
->Pointer
;
207 DPRINT("GlobalLock: invalid handle\n");
208 palloc
=(LPVOID
) hmem
;
210 HeapUnlock(__ProcessHeap
);
219 GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer
)
221 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
226 GlobalReAlloc(HGLOBAL hMem
,
233 PGLOBAL_HANDLE phandle
;
236 DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG
)hMem
, dwBytes
, uFlags
);
240 HeapLock(__ProcessHeap
);
241 if(flags
& GMEM_MODIFY
) /* modify flags */
243 if( (((ULONG
)hmem
%8)==0) && (flags
& GMEM_MOVEABLE
))
245 /* make a fixed block moveable
246 * actually only NT is able to do this. And it's soo simple
248 size
=HeapSize(__ProcessHeap
, 0, (LPVOID
) hmem
);
249 hnew
=GlobalAlloc( flags
, size
);
250 palloc
=GlobalLock(hnew
);
251 memcpy(palloc
, (LPVOID
) hmem
, size
);
253 GlobalHeapFree(GetProcessHeap(),0,hmem
);
255 else if((((ULONG
)hmem
%8) != 0)&&(flags
& GMEM_DISCARDABLE
))
257 /* change the flags to make our block "discardable" */
258 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
259 phandle
->Flags
= phandle
->Flags
| (GMEM_DISCARDABLE
>> 8);
264 SetLastError(ERROR_INVALID_PARAMETER
);
270 if(((ULONG
)hmem
%8)!=0)
272 /* reallocate fixed memory */
273 hnew
=(HANDLE
)HeapReAlloc(__ProcessHeap
, 0, (LPVOID
) hmem
, size
);
277 /* reallocate a moveable block */
278 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
279 if(phandle
->LockCount
!=0)
280 SetLastError(ERROR_INVALID_HANDLE
);
286 palloc
=HeapReAlloc(__ProcessHeap
, 0,
287 phandle
->Pointer
-sizeof(HANDLE
),
288 size
+sizeof(HANDLE
) );
289 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
293 palloc
=HeapAlloc(__ProcessHeap
, 0, size
+sizeof(HANDLE
));
294 *(PHANDLE
)palloc
=hmem
;
295 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
302 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, phandle
->Pointer
-sizeof(HANDLE
));
303 phandle
->Pointer
=NULL
;
308 HeapUnlock(__ProcessHeap
);
311 return ((HGLOBAL
)RtlReAllocateHeap(hProcessHeap
, uFlags
, (LPVOID
)hMem
, dwBytes
));
317 GlobalSize(HGLOBAL hMem
)
321 PGLOBAL_HANDLE phandle
;
324 DPRINT("GlobalSize( 0x%lX )\n", (ULONG
)hMem
);
326 if(((ULONG
)hMem
% 4) == 0)
328 retval
= RtlSizeHeap(hProcessHeap
, 0, hMem
);
333 HeapLock(__ProcessHeap
);
334 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
335 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
337 retval
=HeapSize(__ProcessHeap
, 0, (phandle
->Pointer
)-sizeof(HANDLE
))-4;
341 DPRINT("GlobalSize: invalid handle\n");
344 HeapUnlock(__ProcessHeap
);
353 GlobalUnfix(HGLOBAL hMem
)
355 if (hMem
!= INVALID_HANDLE_VALUE
)
361 GlobalUnlock(HGLOBAL hMem
)
364 PGLOBAL_HANDLE phandle
;
368 DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG
)hMem
);
371 if(((ULONG
)hmem
%8)==0)
374 HeapLock(__ProcessHeap
);
375 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
376 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
378 if((phandle
->LockCount
<GLOBAL_LOCK_MAX
)&&(phandle
->LockCount
>0))
379 phandle
->LockCount
--;
381 locked
=(phandle
->LockCount
==0) ? TRUE
: FALSE
;
385 DPRINT("GlobalUnlock: invalid handle\n");
388 HeapUnlock(__ProcessHeap
);
397 GlobalUnWire(HGLOBAL hMem
)
399 return GlobalUnlock(hMem
);
404 GlobalWire(HGLOBAL hMem
)
406 return GlobalLock(hMem
);