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