source: trunk/src/kernel32/heap.cpp@ 5116

Last change on this file since 5116 was 5116, checked in by sandervl, 25 years ago

LocalHeap now returns NULL for invalid handle

File size: 14.6 KB
Line 
1/* $Id: heap.cpp,v 1.25 2001-02-11 17:24:09 sandervl Exp $ */
2
3/*
4 * Win32 heap API functions for OS/2
5 *
6 * Copyright 1999 Sander van Leeuwen
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12#include <os2win.h>
13#include <stdlib.h>
14#include <string.h>
15#include <misc.h>
16#define _WIN32
17#include "os2heap.h"
18#include <heap.h>
19#include <odinwrap.h>
20
21#define DBG_LOCALLOG DBG_heap
22#include "dbglocal.h"
23
24static HANDLE processheap = NULL;
25OS2Heap *OS2ProcessHeap = NULL;
26
27//******************************************************************************
28//******************************************************************************
29ODINFUNCTIONNODBG3(LPVOID, HeapAlloc, HANDLE, hHeap, DWORD, dwFlags,
30 DWORD, dwBytes)
31{
32 OS2Heap *curheap = OS2Heap::find(hHeap);
33 LPVOID rc;
34
35 if(curheap == NULL)
36 return(NULL);
37
38 rc = curheap->Alloc(dwFlags, dwBytes);
39 dprintf2(("HeapAlloc %X bytes -> %x", dwBytes, rc));
40 return rc;
41}
42//******************************************************************************
43//******************************************************************************
44ODINFUNCTIONNODBG4(LPVOID, HeapReAlloc, HANDLE, hHeap, DWORD, dwFlags, LPVOID,
45 lpMem, DWORD, dwBytes)
46{
47 OS2Heap *curheap = OS2Heap::find(hHeap);
48
49 dprintf2(("HeapReAlloc %x %x %x %X bytes", hHeap, dwFlags, lpMem, dwBytes));
50 if(curheap == NULL)
51 return(NULL);
52
53 //Some apps (i.e. nt's cmd.exe) assume the returned pointer is the same as the old one!
54 if(curheap->Size(0, lpMem) > dwBytes)
55 return lpMem;
56
57 return(curheap->ReAlloc(dwFlags, lpMem, dwBytes));
58}
59//******************************************************************************
60//******************************************************************************
61ODINFUNCTIONNODBG3(BOOL, HeapFree, HANDLE, hHeap, DWORD, dwFlags, LPVOID, lpMem)
62{
63 OS2Heap *curheap = OS2Heap::find(hHeap);
64
65 dprintf2(("HeapFree %X", lpMem));
66 if(curheap == NULL)
67 return(FALSE);
68
69 return(curheap->Free(dwFlags, lpMem));
70}
71//******************************************************************************
72//******************************************************************************
73ODINFUNCTIONNODBG3(HANDLE, HeapCreate, DWORD, flOptions, DWORD, dwInitialSize,
74 DWORD, dwMaximumSize)
75{
76 OS2Heap *curheap;
77
78 //Create Open32 heap for it's handle
79 dprintf2(("HeapCreate dwInitialSize %X", dwInitialSize));
80 HANDLE hHeap = O32_HeapCreate(flOptions, 0, 4096);
81 if(hHeap == NULL)
82 return(NULL);
83
84 curheap = new OS2Heap(hHeap, flOptions, dwInitialSize, dwMaximumSize);
85
86 if(curheap == NULL)
87 {
88 O32_HeapDestroy(hHeap);
89 return(NULL);
90 }
91
92 if(curheap->getHeapHandle() == NULL)
93 {
94 O32_HeapDestroy(hHeap);
95 delete(curheap);
96 return(NULL);
97 }
98 return(curheap->getHeapHandle());
99}
100//******************************************************************************
101//******************************************************************************
102ODINFUNCTIONNODBG1(BOOL, HeapDestroy, HANDLE, hHeap)
103{
104 OS2Heap *curheap = OS2Heap::find(hHeap);
105
106 dprintf2(("HeapDestroy %X", hHeap));
107 if(curheap == NULL)
108 return(FALSE);
109
110 O32_HeapDestroy(curheap->getHeapHandle());
111 delete(curheap);
112 return(TRUE);
113}
114//******************************************************************************
115//******************************************************************************
116ODINFUNCTIONNODBG3(DWORD, HeapSize, HANDLE, hHeap, DWORD, arg2, PVOID, arg3)
117{
118 OS2Heap *curheap = OS2Heap::find(hHeap);
119
120 dprintf2(("HeapSize %X %x", hHeap, arg2));
121 if(curheap == NULL)
122 return(0);
123 return curheap->Size(arg2, arg3);
124}
125//******************************************************************************
126//TODO: Check this!!!
127//******************************************************************************
128ODINFUNCTIONNODBG2(DWORD, HeapCompact, HANDLE, hHeap, DWORD, dwFlags)
129{
130 dprintf(("KERNEL32: HeapCompact: Unknown API - stub\n"));
131 return(0);
132}
133//******************************************************************************
134//******************************************************************************
135ODINFUNCTIONNODBG3(BOOL, HeapValidate, HANDLE, hHeap, DWORD, dwFlags, LPCVOID, lpMem)
136{
137 dprintf(("KERNEL32: HeapValidate - stub\n"));
138 return(TRUE);
139}
140//******************************************************************************
141//******************************************************************************
142ODINFUNCTIONNODBG1(BOOL, HeapUnlock, HANDLE, hHeap)
143{
144 dprintf(("KERNEL32: HeapUnlock - stub (TRUE)\n"));
145 return(TRUE);
146}
147//******************************************************************************
148//******************************************************************************
149ODINFUNCTIONNODBG1(BOOL, HeapLock, HANDLE, hHeap)
150{
151 dprintf(("KERNEL32: HeapLock - stub (TRUE)\n"));
152 return(TRUE);
153}
154//******************************************************************************
155// LPPROCESS_HEAP_ENTRY lpEntry
156//******************************************************************************
157ODINFUNCTIONNODBG2(BOOL, HeapWalk, HANDLE, hHeap, LPVOID, lpEntry)
158{
159 dprintf(("KERNEL32: HeapWalk - stub (TRUE)\n"));
160 return(TRUE);
161}
162//******************************************************************************
163//******************************************************************************
164ODINFUNCTIONNODBG0(HANDLE, GetProcessHeap)
165{
166 HANDLE hHeap;
167
168// dprintf2(("KERNEL32: GetProcessHeap\n"));
169 //SvL: Only one process heap per process
170 if(processheap == NULL) {
171 //TODO: I haven't thought real hard about this. I added it just to make "hdr.exe" happy.
172 hHeap = O32_HeapCreate(HEAP_GENERATE_EXCEPTIONS, 1, 0x4000);
173
174 OS2ProcessHeap = new OS2Heap(hHeap, HEAP_GENERATE_EXCEPTIONS, 0x4000, 0);
175
176 if(OS2ProcessHeap == NULL) {
177 O32_HeapDestroy(hHeap);
178 return(NULL);
179 }
180 processheap = hHeap;
181 }
182 return(processheap);
183}
184//******************************************************************************
185//******************************************************************************
186HLOCAL WIN32API LocalAlloc(UINT fuFlags, DWORD cbBytes)
187{
188 HLOCAL lmem;
189 DWORD dwFlags = 0;
190
191 if(processheap == NULL) {
192 if(GetProcessHeap() == NULL)
193 return(NULL);
194 }
195 if(fuFlags & LMEM_ZEROINIT)
196 dwFlags = HEAP_ZERO_MEMORY;
197
198 lmem = (HLOCAL)OS2ProcessHeap->Alloc(dwFlags, cbBytes, fuFlags);
199
200 dprintf(("KERNEL32: LocalAlloc flags %X, size %d returned %X\n", dwFlags, cbBytes, lmem));
201
202 return(lmem);
203}
204//******************************************************************************
205//******************************************************************************
206HLOCAL WIN32API LocalDiscard(HLOCAL hMem)
207{
208 dprintf(("KERNEL32: LocalDiscard NOT IMPLEMENTED\n"));
209
210// return O32_LocalDiscard(arg1);
211 return(hMem); //TODO: Possible memory leak
212}
213//******************************************************************************
214//******************************************************************************
215UINT WIN32API LocalFlags(HLOCAL hMem)
216{
217 dprintf(("KERNEL32: LocalFlags %X\n", hMem));
218
219 return OS2ProcessHeap->GetFlags((LPVOID)hMem);
220}
221//******************************************************************************
222//******************************************************************************
223HLOCAL WIN32API LocalFree(HLOCAL hMem)
224{
225 dprintf(("KERNEL32: LocalFree %X\n", hMem));
226
227 if(OS2ProcessHeap->GetLockCnt((LPVOID)hMem) != 0) {
228 dprintf(("LocalFree, lock count != 0\n"));
229 return(hMem); //TODO: SetLastError
230 }
231 if(OS2ProcessHeap->Free(0, (LPVOID)hMem) == FALSE) {
232 return(hMem); //TODO: SetLastError
233 }
234 return NULL; //success
235}
236//******************************************************************************
237//******************************************************************************
238HLOCAL WIN32API LocalHandle(PCVOID lpMem)
239{
240 dprintf(("KERNEL32: LocalHandle\n"));
241
242 return (HLOCAL)lpMem;
243}
244//******************************************************************************
245//******************************************************************************
246BOOL WIN32API LocalUnlock(HLOCAL hMem)
247{
248 dprintf(("KERNEL32: LocalUnlock %X\n", hMem));
249
250 return OS2ProcessHeap->Unlock((LPVOID)hMem);
251}
252//******************************************************************************
253//TODO: cbBytes==0 && fuFlags & LMEM_MOVEABLE not handled!!
254//******************************************************************************
255HLOCAL WIN32API LocalReAlloc(HLOCAL hMem, DWORD cbBytes, UINT fuFlags)
256{
257 HLOCAL hLocalNew;
258 LPVOID lpMem;
259
260 dprintf(("KERNEL32: LocalReAlloc %X %d %X\n", hMem, cbBytes, fuFlags));
261
262 //SvL: 8-8-'98: Notepad bugfix (assumes address is identical when new size < old size)
263 if(OS2ProcessHeap->Size(0, (LPVOID)hMem) > cbBytes)
264 return hMem;
265
266 hLocalNew = LocalAlloc(fuFlags, cbBytes);
267 if (hLocalNew != 0)
268 {
269 lpMem = LocalLock(hLocalNew);
270
271 if (lpMem != NULL) /* copy memory if successful */
272 memcpy(lpMem,
273 (LPVOID)hMem,
274 min(cbBytes, OS2ProcessHeap->Size(0, (LPVOID)hMem))
275 );
276
277 LocalUnlock(hLocalNew);
278 OS2ProcessHeap->Free(0, (LPVOID)hMem);
279 }
280 return(hLocalNew);
281}
282//******************************************************************************
283//******************************************************************************
284UINT WIN32API LocalSize(HLOCAL hMem)
285{
286 dprintf(("KERNEL32: LocalSize %X\n", hMem));
287
288 return OS2ProcessHeap->Size(0, (PVOID)hMem);
289}
290//******************************************************************************
291//******************************************************************************
292PVOID WIN32API LocalLock(HLOCAL hMem)
293{
294 dprintf(("KERNEL32: LocalLock %X\n", hMem));
295
296 if(OS2ProcessHeap->Lock((LPVOID)hMem) == FALSE) {
297 return NULL;
298 }
299 return (PVOID)hMem;
300}
301//******************************************************************************
302
303//******************************************************************************
304//* this function is here for completeness, some stupid software requires it.
305UINT WIN32API LocalShrink(HLOCAL hMem,
306 UINT cbNewSize)
307{
308 dprintf(("KERNEL32: LocalShrink %X, %08xh - stub (cbNewSize)\n",
309 hMem,
310 cbNewSize));
311
312 return cbNewSize;
313}
314//******************************************************************************
315
316//******************************************************************************
317//* this function is here for completeness, mIRC/32 requires it.
318UINT WIN32API LocalCompact(UINT cbNewSize)
319{
320 dprintf(("KERNEL32: LocalCompact %08xh - stub (cbNewSize)\n",
321 cbNewSize));
322
323 return cbNewSize;
324}
325//******************************************************************************
326#ifdef DEBUG
327static ULONG totalGlobalAlloc = 0;
328#endif
329//******************************************************************************
330HGLOBAL WIN32API GlobalAlloc(UINT fuFlags, DWORD dwBytes)
331{
332 HGLOBAL ret;
333
334 ret = O32_GlobalAlloc(fuFlags, dwBytes);
335#ifdef DEBUG
336 totalGlobalAlloc += dwBytes;
337#endif
338 dprintf(("KERNEL32: GlobalAlloc %x %d returned %x (total %x)", fuFlags, dwBytes, ret, totalGlobalAlloc));
339 return ret;
340}
341//******************************************************************************
342//******************************************************************************
343HGLOBAL WIN32API GlobalFree( HGLOBAL arg1)
344{
345 HGLOBAL ret;
346
347#ifdef DEBUG
348 totalGlobalAlloc -= O32_GlobalSize(arg1);
349#endif
350 ret = O32_GlobalFree(arg1);
351 dprintf(("KERNEL32: GlobalFree %x returned %x (lasterr=%x) total %x", arg1, ret, GetLastError(), totalGlobalAlloc));
352 return ret;
353}
354//******************************************************************************
355//******************************************************************************
356HGLOBAL WIN32API GlobalHandle( LPCVOID arg1)
357{
358 dprintf(("KERNEL32: OS2GlobalHandle\n"));
359
360 return O32_GlobalHandle((LPVOID)arg1);
361}
362//******************************************************************************
363//******************************************************************************
364UINT WIN32API GlobalFlags(HGLOBAL arg1)
365{
366 dprintf(("KERNEL32: OS2GlobalFlags\n"));
367
368 return O32_GlobalFlags(arg1);
369}
370//******************************************************************************
371//******************************************************************************
372DWORD WIN32API GlobalCompact(DWORD dwMinFree)
373{
374 dprintf(("KERNEL32: GlobalCompact, OBSOLETE - stub\n"));
375
376 return(0);
377}
378//******************************************************************************
379//******************************************************************************
380PVOID WIN32API GlobalLock(HGLOBAL arg1)
381{
382 PVOID ret;
383
384 ret = O32_GlobalLock(arg1);
385 dprintf(("KERNEL32: GlobalLock %x returned %x", arg1, ret));
386 return ret;
387}
388//******************************************************************************
389//******************************************************************************
390HGLOBAL WIN32API GlobalReAlloc(HGLOBAL arg1, DWORD arg2, UINT arg3)
391{
392 dprintf(("KERNEL32: GlobalReAlloc %x %x %d", arg1, arg2, arg3));
393
394 return O32_GlobalReAlloc(arg1, arg2, arg3);
395}
396//******************************************************************************
397//******************************************************************************
398DWORD WIN32API GlobalSize(HGLOBAL arg1)
399{
400 dprintf(("KERNEL32: GlobalSize\n"));
401
402 return O32_GlobalSize(arg1);
403}
404//******************************************************************************
405//******************************************************************************
406BOOL WIN32API GlobalUnlock(HGLOBAL arg1)
407{
408 dprintf(("KERNEL32: GlobalUnlock\n"));
409
410 return O32_GlobalUnlock(arg1);
411}
412/***********************************************************************
413 * GlobalWire
414 *
415 * The GlobalWire function is obsolete. It is provided only for compatibility
416 * with 16-bit versions of Windows. Applications that need to lock a global
417 * memory object should use the GlobalLock and GlobalUnlock functions.
418 *
419 */
420LPVOID WIN32API GlobalWire(HGLOBAL hmem)
421{
422 return GlobalLock( hmem );
423}
424
425
426/***********************************************************************
427 * GlobalUnWire
428 *
429 * The GlobalUnWire function is obsolete. It is provided only for compatibility
430 * with 16-bit versions of Windows. Applications that need to lock a global
431 * memory object should use the GlobalLock and GlobalUnlock functions.
432 *
433 */
434BOOL WIN32API GlobalUnWire(HGLOBAL hmem)
435{
436 return GlobalUnlock( hmem);
437}
438//******************************************************************************
439//******************************************************************************
Note: See TracBrowser for help on using the repository browser.