1 /* $Id: global.c,v 1.10 2002/10/28 15:08:32 robd 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 if ((uFlags
& GMEM_ZEROINIT
)==0)
50 return ((HGLOBAL
)RtlAllocateHeap(hProcessHeap
, 0, dwBytes
));
52 return ((HGLOBAL
)RtlAllocateHeap(hProcessHeap
, HEAP_ZERO_MEMORY
, dwBytes
));
57 HeapLock(__ProcessHeap
);
60 phandle
=__HeapAllocFragment(__ProcessHeap
, 0, sizeof(GLOBAL_HANDLE
));
63 palloc
=HeapAlloc(__ProcessHeap
, 0, size
+sizeof(HANDLE
));
64 *(PHANDLE
)palloc
=(HANDLE
) &(phandle
->Pointer
);
65 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
68 phandle
->Pointer
=NULL
;
69 phandle
->Magic
=MAGIC_GLOBAL_USED
;
70 phandle
->Flags
=uFlags
>>8;
72 HeapUnlock(__ProcessHeap
);
74 return (HGLOBAL
) &(phandle
->Pointer
);
82 GlobalCompact(DWORD dwMinFree
)
84 return RtlCompactHeap(hProcessHeap
, 0);
89 GlobalFix(HGLOBAL hMem
)
91 if (hMem
!= INVALID_HANDLE_VALUE
)
97 GlobalFlags(HGLOBAL hMem
)
101 PGLOBAL_HANDLE phandle
;
104 DPRINT("GlobalFlags( 0x%lX )\n", (ULONG
)hMem
);
107 if(((ULONG
)hmem
%8)==0)
113 HeapLock(__ProcessHeap
);
114 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
115 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
117 retval
=phandle
->LockCount
+ (phandle
->Flags
<<8);
118 if(phandle
->Pointer
==0)
119 retval
|= LMEM_DISCARDED
;
123 DPRINT("GlobalSize: invalid handle\n");
126 HeapUnlock(__ProcessHeap
);
136 GlobalFree(HGLOBAL hMem
)
139 PGLOBAL_HANDLE phandle
;
142 DPRINT("GlobalFree( 0x%lX )\n", (ULONG
)hMem
);
144 if (((ULONG
)hMem
% 4) == 0) /* POINTER */
146 RtlFreeHeap(hProcessHeap
, 0, (PVOID
)hMem
);
151 HeapLock(__ProcessHeap
);
152 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hMem
)-4);
153 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
155 HeapLock(__ProcessHeap
);
156 if(phandle
->LockCount
!=0)
157 SetLastError(ERROR_INVALID_HANDLE
);
159 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, phandle
->Pointer
-sizeof(HANDLE
));
160 __HeapFreeFragment(__ProcessHeap
, 0, phandle
);
162 HeapUnlock(__ProcessHeap
);
171 GlobalHandle(LPCVOID pMem
)
173 DPRINT("GlobalHandle( 0x%lX )\n", (ULONG
)pMem
);
176 if(((ULONG
)pmem
%8)==0) /* FIXED */
177 return (HGLOBAL
) pmem
;
179 return (HGLOBAL
) *(LPVOID
*)(pmem
-sizeof(HANDLE
));
182 return (HGLOBAL
)pMem
;
187 GlobalLock(HGLOBAL hMem
)
190 PGLOBAL_HANDLE phandle
;
194 DPRINT("GlobalLock( 0x%lX )\n", (ULONG
)hMem
);
197 if(((ULONG
)hmem
%8)==0)
198 return (LPVOID
) hmem
;
200 HeapLock(__ProcessHeap
);
201 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
202 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
204 if(phandle
->LockCount
<GLOBAL_LOCK_MAX
)
205 phandle
->LockCount
++;
206 palloc
=phandle
->Pointer
;
210 DPRINT("GlobalLock: invalid handle\n");
211 palloc
=(LPVOID
) hmem
;
213 HeapUnlock(__ProcessHeap
);
222 GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer
)
225 SYSTEM_PERFORMANCE_INFO Spi
;
228 PIMAGE_NT_HEADERS ImageNtHeader
;
230 RtlZeroMemory (lpBuffer
, sizeof (MEMORYSTATUS
));
231 lpBuffer
->dwLength
= sizeof (MEMORYSTATUS
);
232 Status
= NtQuerySystemInformation (
233 SystemPerformanceInformation
,
238 /* FIXME: perform computations and fill lpBuffer fields */
239 Status
= NtQueryInformationProcess (
246 /* FIXME: perform computations and fill lpBuffer fields */
247 Status
= NtQueryInformationProcess (
254 /* FIXME: perform computations and fill lpBuffer fields */
255 ImageNtHeader
= RtlImageNtHeader ((PVOID
)NtCurrentPeb()->ImageBaseAddress
);
256 /* FIXME: perform computations and fill lpBuffer fields */
261 GlobalReAlloc(HGLOBAL hMem
,
268 PGLOBAL_HANDLE phandle
;
271 DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG
)hMem
, dwBytes
, uFlags
);
275 HeapLock(__ProcessHeap
);
276 if(flags
& GMEM_MODIFY
) /* modify flags */
278 if( (((ULONG
)hmem
%8)==0) && (flags
& GMEM_MOVEABLE
))
280 /* make a fixed block moveable
281 * actually only NT is able to do this. And it's soo simple
283 size
=HeapSize(__ProcessHeap
, 0, (LPVOID
) hmem
);
284 hnew
=GlobalAlloc( flags
, size
);
285 palloc
=GlobalLock(hnew
);
286 memcpy(palloc
, (LPVOID
) hmem
, size
);
288 GlobalHeapFree(GetProcessHeap(),0,hmem
);
290 else if((((ULONG
)hmem
%8) != 0)&&(flags
& GMEM_DISCARDABLE
))
292 /* change the flags to make our block "discardable" */
293 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
294 phandle
->Flags
= phandle
->Flags
| (GMEM_DISCARDABLE
>> 8);
299 SetLastError(ERROR_INVALID_PARAMETER
);
305 if(((ULONG
)hmem
%8)!=0)
307 /* reallocate fixed memory */
308 hnew
=(HANDLE
)HeapReAlloc(__ProcessHeap
, 0, (LPVOID
) hmem
, size
);
312 /* reallocate a moveable block */
313 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
314 if(phandle
->LockCount
!=0)
315 SetLastError(ERROR_INVALID_HANDLE
);
321 palloc
=HeapReAlloc(__ProcessHeap
, 0,
322 phandle
->Pointer
-sizeof(HANDLE
),
323 size
+sizeof(HANDLE
) );
324 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
328 palloc
=HeapAlloc(__ProcessHeap
, 0, size
+sizeof(HANDLE
));
329 *(PHANDLE
)palloc
=hmem
;
330 phandle
->Pointer
=palloc
+sizeof(HANDLE
);
337 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap
, 0, phandle
->Pointer
-sizeof(HANDLE
));
338 phandle
->Pointer
=NULL
;
343 HeapUnlock(__ProcessHeap
);
346 return ((HGLOBAL
)RtlReAllocateHeap(hProcessHeap
, uFlags
, (LPVOID
)hMem
, dwBytes
));
352 GlobalSize(HGLOBAL hMem
)
356 PGLOBAL_HANDLE phandle
;
359 DPRINT("GlobalSize( 0x%lX )\n", (ULONG
)hMem
);
361 if(((ULONG
)hMem
% 4) == 0)
363 retval
= RtlSizeHeap(hProcessHeap
, 0, hMem
);
368 HeapLock(__ProcessHeap
);
369 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
370 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
372 retval
=HeapSize(__ProcessHeap
, 0, (phandle
->Pointer
)-sizeof(HANDLE
))-4;
376 DPRINT("GlobalSize: invalid handle\n");
379 HeapUnlock(__ProcessHeap
);
388 GlobalUnfix(HGLOBAL hMem
)
390 if (hMem
!= INVALID_HANDLE_VALUE
)
396 GlobalUnlock(HGLOBAL hMem
)
399 PGLOBAL_HANDLE phandle
;
403 DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG
)hMem
);
406 if(((ULONG
)hmem
%8)==0)
409 HeapLock(__ProcessHeap
);
410 phandle
=(PGLOBAL_HANDLE
)(((LPVOID
) hmem
)-4);
411 if(phandle
->Magic
==MAGIC_GLOBAL_USED
)
413 if((phandle
->LockCount
<GLOBAL_LOCK_MAX
)&&(phandle
->LockCount
>0))
414 phandle
->LockCount
--;
416 locked
=(phandle
->LockCount
==0) ? TRUE
: FALSE
;
420 DPRINT("GlobalUnlock: invalid handle\n");
423 HeapUnlock(__ProcessHeap
);
432 GlobalUnWire(HGLOBAL hMem
)
434 return GlobalUnlock(hMem
);
439 GlobalWire(HGLOBAL hMem
)
441 return GlobalLock(hMem
);