Fixed global and local memory functions
[reactos.git] / reactos / lib / kernel32 / mem / global.c
1 /* $Id: global.c,v 1.6 2001/04/05 01:54:16 ekohl 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 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
222 }
223
224
225 HGLOBAL STDCALL
226 GlobalReAlloc(HGLOBAL hMem,
227 DWORD dwBytes,
228 UINT uFlags)
229 {
230 #if 0
231 LPVOID palloc;
232 HGLOBAL hnew;
233 PGLOBAL_HANDLE phandle;
234 #endif
235
236 DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG)hMem, dwBytes, uFlags);
237
238 #if 0
239 hnew=NULL;
240 HeapLock(__ProcessHeap);
241 if(flags & GMEM_MODIFY) /* modify flags */
242 {
243 if( (((ULONG)hmem%8)==0) && (flags & GMEM_MOVEABLE))
244 {
245 /* make a fixed block moveable
246 * actually only NT is able to do this. And it's soo simple
247 */
248 size=HeapSize(__ProcessHeap, 0, (LPVOID) hmem);
249 hnew=GlobalAlloc( flags, size);
250 palloc=GlobalLock(hnew);
251 memcpy(palloc, (LPVOID) hmem, size);
252 GlobalUnlock(hnew);
253 GlobalHeapFree(GetProcessHeap(),0,hmem);
254 }
255 else if((((ULONG)hmem%8) != 0)&&(flags & GMEM_DISCARDABLE))
256 {
257 /* change the flags to make our block "discardable" */
258 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
259 phandle->Flags = phandle->Flags | (GMEM_DISCARDABLE >> 8);
260 hnew=hmem;
261 }
262 else
263 {
264 SetLastError(ERROR_INVALID_PARAMETER);
265 hnew=NULL;
266 }
267 }
268 else
269 {
270 if(((ULONG)hmem%8)!=0)
271 {
272 /* reallocate fixed memory */
273 hnew=(HANDLE)HeapReAlloc(__ProcessHeap, 0, (LPVOID) hmem, size);
274 }
275 else
276 {
277 /* reallocate a moveable block */
278 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
279 if(phandle->LockCount!=0)
280 SetLastError(ERROR_INVALID_HANDLE);
281 else if(size!=0)
282 {
283 hnew=hmem;
284 if(phandle->Pointer)
285 {
286 palloc=HeapReAlloc(__ProcessHeap, 0,
287 phandle->Pointer-sizeof(HANDLE),
288 size+sizeof(HANDLE) );
289 phandle->Pointer=palloc+sizeof(HANDLE);
290 }
291 else
292 {
293 palloc=HeapAlloc(__ProcessHeap, 0, size+sizeof(HANDLE));
294 *(PHANDLE)palloc=hmem;
295 phandle->Pointer=palloc+sizeof(HANDLE);
296 }
297 }
298 else
299 {
300 if(phandle->Pointer)
301 {
302 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap, 0, phandle->Pointer-sizeof(HANDLE));
303 phandle->Pointer=NULL;
304 }
305 }
306 }
307 }
308 HeapUnlock(__ProcessHeap);
309 return hnew;
310 #else
311 return ((HGLOBAL)RtlReAllocateHeap(hProcessHeap, uFlags, (LPVOID)hMem, dwBytes));
312 #endif
313 }
314
315
316 DWORD STDCALL
317 GlobalSize(HGLOBAL hMem)
318 {
319 DWORD retval;
320 #if 0
321 PGLOBAL_HANDLE phandle;
322 #endif
323
324 DPRINT("GlobalSize( 0x%lX )\n", (ULONG)hMem);
325
326 if(((ULONG)hMem % 4) == 0)
327 {
328 retval = RtlSizeHeap(hProcessHeap, 0, hMem);
329 }
330 else
331 {
332 #if 0
333 HeapLock(__ProcessHeap);
334 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
335 if(phandle->Magic==MAGIC_GLOBAL_USED)
336 {
337 retval=HeapSize(__ProcessHeap, 0, (phandle->Pointer)-sizeof(HANDLE))-4;
338 }
339 else
340 {
341 DPRINT("GlobalSize: invalid handle\n");
342 retval=0;
343 }
344 HeapUnlock(__ProcessHeap);
345 #endif
346 retval = 0;
347 }
348 return retval;
349 }
350
351
352 VOID STDCALL
353 GlobalUnfix(HGLOBAL hMem)
354 {
355 if (hMem != INVALID_HANDLE_VALUE)
356 GlobalUnlock(hMem);
357 }
358
359
360 BOOL STDCALL
361 GlobalUnlock(HGLOBAL hMem)
362 {
363 #if 0
364 PGLOBAL_HANDLE phandle;
365 BOOL locked;
366 #endif
367
368 DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG)hMem);
369
370 #if 0
371 if(((ULONG)hmem%8)==0)
372 return FALSE;
373
374 HeapLock(__ProcessHeap);
375 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
376 if(phandle->Magic==MAGIC_GLOBAL_USED)
377 {
378 if((phandle->LockCount<GLOBAL_LOCK_MAX)&&(phandle->LockCount>0))
379 phandle->LockCount--;
380
381 locked=(phandle->LockCount==0) ? TRUE : FALSE;
382 }
383 else
384 {
385 DPRINT("GlobalUnlock: invalid handle\n");
386 locked=FALSE;
387 }
388 HeapUnlock(__ProcessHeap);
389 return locked;
390 #endif
391
392 return TRUE;
393 }
394
395
396 BOOL STDCALL
397 GlobalUnWire(HGLOBAL hMem)
398 {
399 return GlobalUnlock(hMem);
400 }
401
402
403 LPVOID STDCALL
404 GlobalWire(HGLOBAL hMem)
405 {
406 return GlobalLock(hMem);
407 }
408
409 /* EOF */