Completed mutex and semaphore implementation
[reactos.git] / reactos / lib / kernel32 / mem / global.c
1 /* $Id: global.c,v 1.5 2001/01/20 12:18:54 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
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
33 /*********************************************************************
34 * GlobalAlloc -- KERNEL32 *
35 *********************************************************************/
36 HGLOBAL WINAPI GlobalAlloc(UINT flags, DWORD size)
37 {
38 PGLOBAL_HANDLE phandle;
39 PVOID palloc;
40
41 DPRINT("GlobalAlloc( 0x%X, 0x%lX )\n", flags, size );
42
43 if((flags & GMEM_MOVEABLE)==0) /* POINTER */
44 {
45 palloc=RtlAllocateHeap(hProcessHeap, 0, size);
46 return (HGLOBAL) palloc;
47 }
48 else /* HANDLE */
49 {
50 #if 0
51 HeapLock(__ProcessHeap);
52
53
54 phandle=__HeapAllocFragment(__ProcessHeap, 0, sizeof(GLOBAL_HANDLE));
55 if(size)
56 {
57 palloc=HeapAlloc(__ProcessHeap, 0, size+sizeof(HANDLE));
58 *(PHANDLE)palloc=(HANDLE) &(phandle->Pointer);
59 phandle->Pointer=palloc+sizeof(HANDLE);
60 }
61 else
62 phandle->Pointer=NULL;
63 phandle->Magic=MAGIC_GLOBAL_USED;
64 phandle->Flags=flags>>8;
65 phandle->LockCount=0;
66 HeapUnlock(__ProcessHeap);
67
68 return (HGLOBAL) &(phandle->Pointer);
69 #endif
70 return (HGLOBAL)NULL;
71 }
72 }
73
74 /*********************************************************************
75 * GlobalLock -- KERNEL32 *
76 *********************************************************************/
77 #if 0
78 LPVOID WINAPI GlobalLock(HGLOBAL hmem)
79 {
80 PGLOBAL_HANDLE phandle;
81 LPVOID palloc;
82
83 DPRINT("GlobalLock( 0x%lX )\n", (ULONG) hmem );
84
85 if(((ULONG)hmem%8)==0)
86 return (LPVOID) hmem;
87
88 HeapLock(__ProcessHeap);
89 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
90 if(phandle->Magic==MAGIC_GLOBAL_USED)
91 {
92 if(phandle->LockCount<GLOBAL_LOCK_MAX)
93 phandle->LockCount++;
94 palloc=phandle->Pointer;
95 }
96 else
97 {
98 DPRINT("GlobalLock: invalid handle\n");
99 palloc=(LPVOID) hmem;
100 }
101 HeapUnlock(__ProcessHeap);
102 return palloc;
103 }
104 #endif
105
106 /*********************************************************************
107 * GlobalUnlock -- KERNEL32 *
108 *********************************************************************/
109 #if 0
110 BOOL WINAPI GlobalUnlock(HGLOBAL hmem)
111 {
112 PGLOBAL_HANDLE phandle;
113 BOOL locked;
114
115 DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG) hmem );
116
117 if(((ULONG)hmem%8)==0)
118 return FALSE;
119
120 HeapLock(__ProcessHeap);
121 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
122 if(phandle->Magic==MAGIC_GLOBAL_USED)
123 {
124 if((phandle->LockCount<GLOBAL_LOCK_MAX)&&(phandle->LockCount>0))
125 phandle->LockCount--;
126
127 locked=(phandle->LockCount==0) ? TRUE : FALSE;
128 }
129 else
130 {
131 DPRINT("GlobalUnlock: invalid handle\n");
132 locked=FALSE;
133 }
134 HeapUnlock(__ProcessHeap);
135 return locked;
136 }
137 #endif
138
139 /*********************************************************************
140 * GlobalHandle -- KERNEL32 *
141 *********************************************************************/
142 #if 0
143 HGLOBAL WINAPI GlobalHandle(LPCVOID pmem)
144 {
145 DPRINT("GlobalHandle( 0x%lX )\n", (ULONG) pmem );
146
147 if(((ULONG)pmem%8)==0) /* FIXED */
148 return (HGLOBAL) pmem;
149 else /* MOVEABLE */
150 return (HGLOBAL) *(LPVOID *)(pmem-sizeof(HANDLE));
151 }
152 #endif
153
154 /*********************************************************************
155 * GlobalReAlloc -- KERNEL32 *
156 *********************************************************************/
157 #if 0
158 HGLOBAL WINAPI GlobalReAlloc(HGLOBAL hmem, DWORD size, UINT flags)
159 {
160 LPVOID palloc;
161 HGLOBAL hnew;
162 PGLOBAL_HANDLE phandle;
163
164 DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG) hmem, size, flags );
165
166 hnew=NULL;
167 HeapLock(__ProcessHeap);
168 if(flags & GMEM_MODIFY) /* modify flags */
169 {
170 if( (((ULONG)hmem%8)==0) && (flags & GMEM_MOVEABLE))
171 {
172 /* make a fixed block moveable
173 * actually only NT is able to do this. And it's soo simple
174 */
175 size=HeapSize(__ProcessHeap, 0, (LPVOID) hmem);
176 hnew=GlobalAlloc( flags, size);
177 palloc=GlobalLock(hnew);
178 memcpy(palloc, (LPVOID) hmem, size);
179 GlobalUnlock(hnew);
180 GlobalHeapFree(GetProcessHeap(),0,hmem);
181 }
182 else if((((ULONG)hmem%8) != 0)&&(flags & GMEM_DISCARDABLE))
183 {
184 /* change the flags to make our block "discardable" */
185 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
186 phandle->Flags = phandle->Flags | (GMEM_DISCARDABLE >> 8);
187 hnew=hmem;
188 }
189 else
190 {
191 SetLastError(ERROR_INVALID_PARAMETER);
192 hnew=NULL;
193 }
194 }
195 else
196 {
197 if(((ULONG)hmem%8)!=0)
198 {
199 /* reallocate fixed memory */
200 hnew=(HANDLE)HeapReAlloc(__ProcessHeap, 0, (LPVOID) hmem, size);
201 }
202 else
203 {
204 /* reallocate a moveable block */
205 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
206 if(phandle->LockCount!=0)
207 SetLastError(ERROR_INVALID_HANDLE);
208 else if(size!=0)
209 {
210 hnew=hmem;
211 if(phandle->Pointer)
212 {
213 palloc=HeapReAlloc(__ProcessHeap, 0,
214 phandle->Pointer-sizeof(HANDLE),
215 size+sizeof(HANDLE) );
216 phandle->Pointer=palloc+sizeof(HANDLE);
217 }
218 else
219 {
220 palloc=HeapAlloc(__ProcessHeap, 0, size+sizeof(HANDLE));
221 *(PHANDLE)palloc=hmem;
222 phandle->Pointer=palloc+sizeof(HANDLE);
223 }
224 }
225 else
226 {
227 if(phandle->Pointer)
228 {
229 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap, 0, phandle->Pointer-sizeof(HANDLE));
230 phandle->Pointer=NULL;
231 }
232 }
233 }
234 }
235 HeapUnlock(__ProcessHeap);
236 return hnew;
237 }
238 #endif
239
240 /*********************************************************************
241 * GlobalFree -- KERNEL32 *
242 *********************************************************************/
243 HGLOBAL WINAPI GlobalFree(HGLOBAL hmem)
244 {
245 #if 0
246 PGLOBAL_HANDLE phandle;
247 #endif
248
249 DPRINT("GlobalFree( 0x%lX )\n", (ULONG) hmem );
250
251 if (((ULONG)hmem % 4) == 0) /* POINTER */
252 {
253 RtlFreeHeap(hProcessHeap, 0, (LPVOID)hmem);
254 }
255 else /* HANDLE */
256 {
257 #if 0
258 HeapLock(__ProcessHeap);
259 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
260 if(phandle->Magic==MAGIC_GLOBAL_USED)
261 {
262 HeapLock(__ProcessHeap);
263 if(phandle->LockCount!=0)
264 SetLastError(ERROR_INVALID_HANDLE);
265 if(phandle->Pointer)
266 HeapHeapFree(GetProcessHeap(),0,__ProcessHeap, 0, phandle->Pointer-sizeof(HANDLE));
267 __HeapFreeFragment(__ProcessHeap, 0, phandle);
268 }
269 HeapUnlock(__ProcessHeap);
270 #endif
271 hmem = NULL;
272 }
273 return hmem;
274 }
275
276 /*********************************************************************
277 * GlobalSize -- KERNEL32 *
278 *********************************************************************/
279 DWORD WINAPI GlobalSize(HGLOBAL hmem)
280 {
281 DWORD retval;
282 PGLOBAL_HANDLE phandle;
283
284 DPRINT("GlobalSize( 0x%lX )\n", (ULONG) hmem );
285
286 if(((ULONG)hmem % 4) == 0)
287 {
288 retval = RtlSizeHeap(hProcessHeap, 0, hmem);
289 }
290 else
291 {
292 #if 0
293 HeapLock(__ProcessHeap);
294 phandle=(PGLOBAL_HANDLE)(((LPVOID) hmem)-4);
295 if(phandle->Magic==MAGIC_GLOBAL_USED)
296 {
297 retval=HeapSize(__ProcessHeap, 0, (phandle->Pointer)-sizeof(HANDLE))-4;
298 }
299 else
300 {
301 DPRINT("GlobalSize: invalid handle\n");
302 retval=0;
303 }
304 HeapUnlock(__ProcessHeap);
305 #endif
306 retval = 0;
307 }
308 return retval;
309 }
310
311 /*********************************************************************
312 * GlobalWire -- KERNEL32 *
313 *********************************************************************/
314 #if 0
315 LPVOID WINAPI GlobalWire(HGLOBAL hmem)
316 {
317 return GlobalLock( hmem );
318 }
319 #endif
320
321 /*********************************************************************
322 * GlobalUnWire -- KERNEL32 *
323 *********************************************************************/
324 #if 0
325 BOOL WINAPI GlobalUnWire(HGLOBAL hmem)
326 {
327 return GlobalUnlock( hmem);
328 }
329 #endif
330
331 /*********************************************************************
332 * GlobalFix -- KERNEL32 *
333 *********************************************************************/
334 #if 0
335 VOID WINAPI GlobalFix(HGLOBAL hmem)
336 {
337 GlobalLock( hmem );
338 }
339 #endif
340
341 /*********************************************************************
342 * GlobalUnfix -- KERNEL32 *
343 *********************************************************************/
344 #if 0
345 VOID WINAPI GlobalUnfix(HGLOBAL hmem)
346 {
347 GlobalUnlock( hmem);
348 }
349 #endif
350
351 /*********************************************************************
352 * GlobalFlags -- KERNEL32 *
353 *********************************************************************/
354 #if 0
355 UINT WINAPI GlobalFlags(HGLOBAL hmem)
356 {
357 return LocalFlags( (HLOCAL) hmem);
358 }
359 #endif
360
361 /* EOF */