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!!
17 #include <kernel32/kernel32.h>
20 #define MAGIC_GLOBAL_USED 0x5342BEEF
21 #define GLOBAL_LOCK_MAX 0xFF
23 typedef struct __GLOBAL_LOCAL_HANDLE
29 } GLOBAL_HANDLE, LOCAL_HANDLE, *PGLOBAL_HANDLE, *PLOCAL_HANDLE;
32 /* FUNCTIONS ***************************************************************/
38 GlobalAlloc(UINT uFlags,
42 PGLOBAL_HANDLE phandle;
46 DPRINT("GlobalAlloc( 0x%X, 0x%lX )\n", uFlags, dwBytes);
48 if ((uFlags & GMEM_MOVEABLE)==0) /* POINTER */
50 if ((uFlags & GMEM_ZEROINIT)==0)
51 return ((HGLOBAL)RtlAllocateHeap(hProcessHeap, 0, dwBytes));
53 return ((HGLOBAL)RtlAllocateHeap(hProcessHeap, HEAP_ZERO_MEMORY, dwBytes));
58 HeapLock(__ProcessHeap);
61 phandle=__HeapAllocFragment(__ProcessHeap, 0, sizeof(GLOBAL_HANDLE));
64 palloc=HeapAlloc(__ProcessHeap, 0, size+sizeof(HANDLE));
65 *(PHANDLE)palloc=(HANDLE) &(phandle->Pointer);
66 phandle->Pointer=palloc+sizeof(HANDLE);
69 phandle->Pointer=NULL;
70 phandle->Magic=MAGIC_GLOBAL_USED;
71 phandle->Flags=uFlags>>8;
73 HeapUnlock(__ProcessHeap);
75 return (HGLOBAL) &(phandle->Pointer);
86 GlobalCompact(DWORD dwMinFree)
88 return RtlCompactHeap(hProcessHeap, 0);
96 GlobalFix(HGLOBAL hMem)
98 if (hMem != INVALID_HANDLE_VALUE)
107 GlobalFlags(HGLOBAL hMem)
111 PGLOBAL_HANDLE phandle;
114 DPRINT("GlobalFlags( 0x%lX )\n", (ULONG)hMem);
117 if(((ULONG)hmem%8)==0)
123 HeapLock(__ProcessHeap);
124 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
125 if(phandle->Magic==MAGIC_GLOBAL_USED)
127 retval=phandle->LockCount + (phandle->Flags<<8);
128 if(phandle->Pointer==0)
129 retval|= LMEM_DISCARDED;
133 DPRINT("GlobalSize: invalid handle\n");
136 HeapUnlock(__ProcessHeap);
149 GlobalFree(HGLOBAL hMem)
152 PGLOBAL_HANDLE phandle;
155 DPRINT("GlobalFree( 0x%lX )\n", (ULONG)hMem);
157 if (((ULONG)hMem % 4) == 0) /* POINTER */
159 RtlFreeHeap(hProcessHeap, 0, (PVOID)hMem);
164 HeapLock(__ProcessHeap);
165 phandle=(PGLOBAL_HANDLE)(((LPVOID) hMem)-4);
166 if(phandle->Magic==MAGIC_GLOBAL_USED)
168 HeapLock(__ProcessHeap);
169 if(phandle->LockCount!=0)
170 SetLastError(ERROR_INVALID_HANDLE);
172 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap, 0, phandle->Pointer-sizeof(HANDLE));
173 __HeapFreeFragment(__ProcessHeap, 0, phandle);
175 HeapUnlock(__ProcessHeap);
187 GlobalHandle(LPCVOID pMem)
189 DPRINT("GlobalHandle( 0x%lX )\n", (ULONG)pMem);
192 if(((ULONG)pmem%8)==0) /* FIXED */
193 return (HGLOBAL) pmem;
195 return (HGLOBAL) *(LPVOID *)(pmem-sizeof(HANDLE));
198 return (HGLOBAL)pMem;
206 GlobalLock(HGLOBAL hMem)
209 PGLOBAL_HANDLE phandle;
213 DPRINT("GlobalLock( 0x%lX )\n", (ULONG)hMem);
216 if(((ULONG)hmem%8)==0)
217 return (LPVOID) hmem;
219 HeapLock(__ProcessHeap);
220 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
221 if(phandle->Magic==MAGIC_GLOBAL_USED)
223 if(phandle->LockCount<GLOBAL_LOCK_MAX)
224 phandle->LockCount++;
225 palloc=phandle->Pointer;
229 DPRINT("GlobalLock: invalid handle\n");
230 palloc=(LPVOID) hmem;
232 HeapUnlock(__ProcessHeap);
244 GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer)
247 SYSTEM_PERFORMANCE_INFORMATION Spi;
250 PIMAGE_NT_HEADERS ImageNtHeader;
252 RtlZeroMemory (lpBuffer, sizeof (MEMORYSTATUS));
253 lpBuffer->dwLength = sizeof (MEMORYSTATUS);
254 Status = NtQuerySystemInformation (
255 SystemPerformanceInformation,
260 /* FIXME: perform computations and fill lpBuffer fields */
261 Status = NtQueryInformationProcess (
268 /* FIXME: perform computations and fill lpBuffer fields */
269 Status = NtQueryInformationProcess (
276 /* FIXME: perform computations and fill lpBuffer fields */
277 ImageNtHeader = RtlImageNtHeader ((PVOID)NtCurrentPeb()->ImageBaseAddress);
278 /* FIXME: perform computations and fill lpBuffer fields */
283 GlobalReAlloc(HGLOBAL hMem,
290 PGLOBAL_HANDLE phandle;
293 DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG)hMem, dwBytes, uFlags);
297 HeapLock(__ProcessHeap);
298 if(flags & GMEM_MODIFY) /* modify flags */
300 if( (((ULONG)hmem%8)==0) && (flags & GMEM_MOVEABLE))
302 /* make a fixed block moveable
303 * actually only NT is able to do this. And it's soo simple
305 size=HeapSize(__ProcessHeap, 0, (LPVOID) hmem);
306 hnew=GlobalAlloc( flags, size);
307 palloc=GlobalLock(hnew);
308 memcpy(palloc, (LPVOID) hmem, size);
310 GlobalHeapFree(GetProcessHeap(),0,hmem);
312 else if((((ULONG)hmem%8) != 0)&&(flags & GMEM_DISCARDABLE))
314 /* change the flags to make our block "discardable" */
315 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
316 phandle->Flags = phandle->Flags | (GMEM_DISCARDABLE >> 8);
321 SetLastError(ERROR_INVALID_PARAMETER);
327 if(((ULONG)hmem%8)!=0)
329 /* reallocate fixed memory */
330 hnew=(HANDLE)HeapReAlloc(__ProcessHeap, 0, (LPVOID) hmem, size);
334 /* reallocate a moveable block */
335 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
336 if(phandle->LockCount!=0)
337 SetLastError(ERROR_INVALID_HANDLE);
343 palloc=HeapReAlloc(__ProcessHeap, 0,
344 phandle->Pointer-sizeof(HANDLE),
345 size+sizeof(HANDLE) );
346 phandle->Pointer=palloc+sizeof(HANDLE);
350 palloc=HeapAlloc(__ProcessHeap, 0, size+sizeof(HANDLE));
351 *(PHANDLE)palloc=hmem;
352 phandle->Pointer=palloc+sizeof(HANDLE);
359 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap, 0, phandle->Pointer-sizeof(HANDLE));
360 phandle->Pointer=NULL;
365 HeapUnlock(__ProcessHeap);
368 return ((HGLOBAL)RtlReAllocateHeap(hProcessHeap, uFlags, (LPVOID)hMem, dwBytes));
374 GlobalSize(HGLOBAL hMem)
378 PGLOBAL_HANDLE phandle;
381 DPRINT("GlobalSize( 0x%lX )\n", (ULONG)hMem);
383 if(((ULONG)hMem % 4) == 0)
385 retval = RtlSizeHeap(hProcessHeap, 0, hMem);
390 HeapLock(__ProcessHeap);
391 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
392 if(phandle->Magic==MAGIC_GLOBAL_USED)
394 retval=HeapSize(__ProcessHeap, 0, (phandle->Pointer)-sizeof(HANDLE))-4;
398 DPRINT("GlobalSize: invalid handle\n");
401 HeapUnlock(__ProcessHeap);
413 GlobalUnfix(HGLOBAL hMem)
415 if (hMem != INVALID_HANDLE_VALUE)
424 GlobalUnlock(HGLOBAL hMem)
427 PGLOBAL_HANDLE phandle;
431 DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG)hMem);
434 if(((ULONG)hmem%8)==0)
437 HeapLock(__ProcessHeap);
438 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
439 if(phandle->Magic==MAGIC_GLOBAL_USED)
441 if((phandle->LockCount<GLOBAL_LOCK_MAX)&&(phandle->LockCount>0))
442 phandle->LockCount--;
444 locked=(phandle->LockCount==0) ? TRUE : FALSE;
448 DPRINT("GlobalUnlock: invalid handle\n");
451 HeapUnlock(__ProcessHeap);
463 GlobalUnWire(HGLOBAL hMem)
465 return GlobalUnlock(hMem);
473 GlobalWire(HGLOBAL hMem)
475 return GlobalLock(hMem);