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