Check for GMEM_ZEROINIT flag and pass HEAP_ZERO_MEMORY flag to RtlAllocateHeap if...
[reactos.git] / reactos / lib / kernel32 / mem / global.c
1 /* $Id: global.c,v 1.10 2002/10/28 15:08:32 robd Exp $
2 *
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
7 * used.
8 */
9
10 /*
11 * NOTE: Only fixed memory is implemented!!
12 */
13
14 #include <ddk/ntddk.h>
15 #include <ntdll/rtl.h>
16 #include <windows.h>
17
18 #define NDEBUG
19 #include <kernel32/kernel32.h>
20
21 #if 0
22 #define MAGIC_GLOBAL_USED 0x5342BEEF
23 #define GLOBAL_LOCK_MAX 0xFF
24
25 typedef struct __GLOBAL_LOCAL_HANDLE
26 {
27 ULONG Magic;
28 LPVOID Pointer;
29 BYTE Flags;
30 BYTE LockCount;
31 } GLOBAL_HANDLE, LOCAL_HANDLE, *PGLOBAL_HANDLE, *PLOCAL_HANDLE;
32 #endif
33
34 /* FUNCTIONS ***************************************************************/
35
36 HGLOBAL STDCALL
37 GlobalAlloc(UINT uFlags,
38 DWORD dwBytes)
39 {
40 #if 0
41 PGLOBAL_HANDLE phandle;
42 PVOID palloc;
43 #endif
44
45 DPRINT("GlobalAlloc( 0x%X, 0x%lX )\n", uFlags, dwBytes);
46
47 if ((uFlags & GMEM_MOVEABLE)==0) /* POINTER */
48 {
49 if ((uFlags & GMEM_ZEROINIT)==0)
50 return ((HGLOBAL)RtlAllocateHeap(hProcessHeap, 0, dwBytes));
51 else
52 return ((HGLOBAL)RtlAllocateHeap(hProcessHeap, HEAP_ZERO_MEMORY, dwBytes));
53 }
54 else /* HANDLE */
55 {
56 #if 0
57 HeapLock(__ProcessHeap);
58
59
60 phandle=__HeapAllocFragment(__ProcessHeap, 0, sizeof(GLOBAL_HANDLE));
61 if(dwBytes)
62 {
63 palloc=HeapAlloc(__ProcessHeap, 0, size+sizeof(HANDLE));
64 *(PHANDLE)palloc=(HANDLE) &(phandle->Pointer);
65 phandle->Pointer=palloc+sizeof(HANDLE);
66 }
67 else
68 phandle->Pointer=NULL;
69 phandle->Magic=MAGIC_GLOBAL_USED;
70 phandle->Flags=uFlags>>8;
71 phandle->LockCount=0;
72 HeapUnlock(__ProcessHeap);
73
74 return (HGLOBAL) &(phandle->Pointer);
75 #endif
76 return (HGLOBAL)NULL;
77 }
78 }
79
80
81 UINT STDCALL
82 GlobalCompact(DWORD dwMinFree)
83 {
84 return RtlCompactHeap(hProcessHeap, 0);
85 }
86
87
88 VOID STDCALL
89 GlobalFix(HGLOBAL hMem)
90 {
91 if (hMem != INVALID_HANDLE_VALUE)
92 GlobalLock(hMem);
93 }
94
95
96 UINT STDCALL
97 GlobalFlags(HGLOBAL hMem)
98 {
99 #if 0
100 DWORD retval;
101 PGLOBAL_HANDLE phandle;
102 #endif
103
104 DPRINT("GlobalFlags( 0x%lX )\n", (ULONG)hMem);
105
106 #if 0
107 if(((ULONG)hmem%8)==0)
108 {
109 retval=0;
110 }
111 else
112 {
113 HeapLock(__ProcessHeap);
114 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
115 if(phandle->Magic==MAGIC_GLOBAL_USED)
116 {
117 retval=phandle->LockCount + (phandle->Flags<<8);
118 if(phandle->Pointer==0)
119 retval|= LMEM_DISCARDED;
120 }
121 else
122 {
123 DPRINT("GlobalSize: invalid handle\n");
124 retval=0;
125 }
126 HeapUnlock(__ProcessHeap);
127 }
128 return retval;
129 #endif
130
131 return 0;
132 }
133
134
135 HGLOBAL STDCALL
136 GlobalFree(HGLOBAL hMem)
137 {
138 #if 0
139 PGLOBAL_HANDLE phandle;
140 #endif
141
142 DPRINT("GlobalFree( 0x%lX )\n", (ULONG)hMem);
143
144 if (((ULONG)hMem % 4) == 0) /* POINTER */
145 {
146 RtlFreeHeap(hProcessHeap, 0, (PVOID)hMem);
147 }
148 else /* HANDLE */
149 {
150 #if 0
151 HeapLock(__ProcessHeap);
152 phandle=(PGLOBAL_HANDLE)(((LPVOID) hMem)-4);
153 if(phandle->Magic==MAGIC_GLOBAL_USED)
154 {
155 HeapLock(__ProcessHeap);
156 if(phandle->LockCount!=0)
157 SetLastError(ERROR_INVALID_HANDLE);
158 if(phandle->Pointer)
159 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap, 0, phandle->Pointer-sizeof(HANDLE));
160 __HeapFreeFragment(__ProcessHeap, 0, phandle);
161 }
162 HeapUnlock(__ProcessHeap);
163 #endif
164 hMem = NULL;
165 }
166 return hMem;
167 }
168
169
170 HGLOBAL STDCALL
171 GlobalHandle(LPCVOID pMem)
172 {
173 DPRINT("GlobalHandle( 0x%lX )\n", (ULONG)pMem);
174
175 #if 0
176 if(((ULONG)pmem%8)==0) /* FIXED */
177 return (HGLOBAL) pmem;
178 else /* MOVEABLE */
179 return (HGLOBAL) *(LPVOID *)(pmem-sizeof(HANDLE));
180 #endif
181
182 return (HGLOBAL)pMem;
183 }
184
185
186 LPVOID STDCALL
187 GlobalLock(HGLOBAL hMem)
188 {
189 #if 0
190 PGLOBAL_HANDLE phandle;
191 LPVOID palloc;
192 #endif
193
194 DPRINT("GlobalLock( 0x%lX )\n", (ULONG)hMem);
195
196 #if 0
197 if(((ULONG)hmem%8)==0)
198 return (LPVOID) hmem;
199
200 HeapLock(__ProcessHeap);
201 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
202 if(phandle->Magic==MAGIC_GLOBAL_USED)
203 {
204 if(phandle->LockCount<GLOBAL_LOCK_MAX)
205 phandle->LockCount++;
206 palloc=phandle->Pointer;
207 }
208 else
209 {
210 DPRINT("GlobalLock: invalid handle\n");
211 palloc=(LPVOID) hmem;
212 }
213 HeapUnlock(__ProcessHeap);
214 return palloc;
215 #else
216 return (LPVOID)hMem;
217 #endif
218 }
219
220
221 VOID STDCALL
222 GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer)
223 {
224 NTSTATUS Status;
225 SYSTEM_PERFORMANCE_INFO Spi;
226 QUOTA_LIMITS Ql;
227 VM_COUNTERS Vmc;
228 PIMAGE_NT_HEADERS ImageNtHeader;
229
230 RtlZeroMemory (lpBuffer, sizeof (MEMORYSTATUS));
231 lpBuffer->dwLength = sizeof (MEMORYSTATUS);
232 Status = NtQuerySystemInformation (
233 SystemPerformanceInformation,
234 & Spi,
235 sizeof Spi,
236 NULL
237 );
238 /* FIXME: perform computations and fill lpBuffer fields */
239 Status = NtQueryInformationProcess (
240 GetCurrentProcess(),
241 ProcessQuotaLimits,
242 & Ql,
243 sizeof Ql,
244 NULL
245 );
246 /* FIXME: perform computations and fill lpBuffer fields */
247 Status = NtQueryInformationProcess (
248 GetCurrentProcess(),
249 ProcessVmCounters,
250 & Vmc,
251 sizeof Vmc,
252 NULL
253 );
254 /* FIXME: perform computations and fill lpBuffer fields */
255 ImageNtHeader = RtlImageNtHeader ((PVOID)NtCurrentPeb()->ImageBaseAddress);
256 /* FIXME: perform computations and fill lpBuffer fields */
257 }
258
259
260 HGLOBAL STDCALL
261 GlobalReAlloc(HGLOBAL hMem,
262 DWORD dwBytes,
263 UINT uFlags)
264 {
265 #if 0
266 LPVOID palloc;
267 HGLOBAL hnew;
268 PGLOBAL_HANDLE phandle;
269 #endif
270
271 DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG)hMem, dwBytes, uFlags);
272
273 #if 0
274 hnew=NULL;
275 HeapLock(__ProcessHeap);
276 if(flags & GMEM_MODIFY) /* modify flags */
277 {
278 if( (((ULONG)hmem%8)==0) && (flags & GMEM_MOVEABLE))
279 {
280 /* make a fixed block moveable
281 * actually only NT is able to do this. And it's soo simple
282 */
283 size=HeapSize(__ProcessHeap, 0, (LPVOID) hmem);
284 hnew=GlobalAlloc( flags, size);
285 palloc=GlobalLock(hnew);
286 memcpy(palloc, (LPVOID) hmem, size);
287 GlobalUnlock(hnew);
288 GlobalHeapFree(GetProcessHeap(),0,hmem);
289 }
290 else if((((ULONG)hmem%8) != 0)&&(flags & GMEM_DISCARDABLE))
291 {
292 /* change the flags to make our block "discardable" */
293 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
294 phandle->Flags = phandle->Flags | (GMEM_DISCARDABLE >> 8);
295 hnew=hmem;
296 }
297 else
298 {
299 SetLastError(ERROR_INVALID_PARAMETER);
300 hnew=NULL;
301 }
302 }
303 else
304 {
305 if(((ULONG)hmem%8)!=0)
306 {
307 /* reallocate fixed memory */
308 hnew=(HANDLE)HeapReAlloc(__ProcessHeap, 0, (LPVOID) hmem, size);
309 }
310 else
311 {
312 /* reallocate a moveable block */
313 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
314 if(phandle->LockCount!=0)
315 SetLastError(ERROR_INVALID_HANDLE);
316 else if(size!=0)
317 {
318 hnew=hmem;
319 if(phandle->Pointer)
320 {
321 palloc=HeapReAlloc(__ProcessHeap, 0,
322 phandle->Pointer-sizeof(HANDLE),
323 size+sizeof(HANDLE) );
324 phandle->Pointer=palloc+sizeof(HANDLE);
325 }
326 else
327 {
328 palloc=HeapAlloc(__ProcessHeap, 0, size+sizeof(HANDLE));
329 *(PHANDLE)palloc=hmem;
330 phandle->Pointer=palloc+sizeof(HANDLE);
331 }
332 }
333 else
334 {
335 if(phandle->Pointer)
336 {
337 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap, 0, phandle->Pointer-sizeof(HANDLE));
338 phandle->Pointer=NULL;
339 }
340 }
341 }
342 }
343 HeapUnlock(__ProcessHeap);
344 return hnew;
345 #else
346 return ((HGLOBAL)RtlReAllocateHeap(hProcessHeap, uFlags, (LPVOID)hMem, dwBytes));
347 #endif
348 }
349
350
351 DWORD STDCALL
352 GlobalSize(HGLOBAL hMem)
353 {
354 DWORD retval;
355 #if 0
356 PGLOBAL_HANDLE phandle;
357 #endif
358
359 DPRINT("GlobalSize( 0x%lX )\n", (ULONG)hMem);
360
361 if(((ULONG)hMem % 4) == 0)
362 {
363 retval = RtlSizeHeap(hProcessHeap, 0, hMem);
364 }
365 else
366 {
367 #if 0
368 HeapLock(__ProcessHeap);
369 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
370 if(phandle->Magic==MAGIC_GLOBAL_USED)
371 {
372 retval=HeapSize(__ProcessHeap, 0, (phandle->Pointer)-sizeof(HANDLE))-4;
373 }
374 else
375 {
376 DPRINT("GlobalSize: invalid handle\n");
377 retval=0;
378 }
379 HeapUnlock(__ProcessHeap);
380 #endif
381 retval = 0;
382 }
383 return retval;
384 }
385
386
387 VOID STDCALL
388 GlobalUnfix(HGLOBAL hMem)
389 {
390 if (hMem != INVALID_HANDLE_VALUE)
391 GlobalUnlock(hMem);
392 }
393
394
395 BOOL STDCALL
396 GlobalUnlock(HGLOBAL hMem)
397 {
398 #if 0
399 PGLOBAL_HANDLE phandle;
400 BOOL locked;
401 #endif
402
403 DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG)hMem);
404
405 #if 0
406 if(((ULONG)hmem%8)==0)
407 return FALSE;
408
409 HeapLock(__ProcessHeap);
410 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
411 if(phandle->Magic==MAGIC_GLOBAL_USED)
412 {
413 if((phandle->LockCount<GLOBAL_LOCK_MAX)&&(phandle->LockCount>0))
414 phandle->LockCount--;
415
416 locked=(phandle->LockCount==0) ? TRUE : FALSE;
417 }
418 else
419 {
420 DPRINT("GlobalUnlock: invalid handle\n");
421 locked=FALSE;
422 }
423 HeapUnlock(__ProcessHeap);
424 return locked;
425 #endif
426
427 return TRUE;
428 }
429
430
431 BOOL STDCALL
432 GlobalUnWire(HGLOBAL hMem)
433 {
434 return GlobalUnlock(hMem);
435 }
436
437
438 LPVOID STDCALL
439 GlobalWire(HGLOBAL hMem)
440 {
441 return GlobalLock(hMem);
442 }
443
444 /* EOF */