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);