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