:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[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 <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 */