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

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

MN: HeapReAlloc fix for shrinking allocation (return same pointer)

File size: 14.5 KB
Line 
1/* $Id: heap.cpp,v 1.23 2000-11-06 20:01:26 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 bytes", 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 OS2ProcessHeap->Lock((LPVOID)hMem);
297 return (PVOID)hMem;
298}
299//******************************************************************************
300
301//******************************************************************************
302//* this function is here for completeness, some stupid software requires it.
303UINT WIN32API LocalShrink(HLOCAL hMem,
304 UINT cbNewSize)
305{
306 dprintf(("KERNEL32: LocalShrink %X, %08xh - stub (cbNewSize)\n",
307 hMem,
308 cbNewSize));
309
310 return cbNewSize;
311}
312//******************************************************************************
313
314//******************************************************************************
315//* this function is here for completeness, mIRC/32 requires it.
316UINT WIN32API LocalCompact(UINT cbNewSize)
317{
318 dprintf(("KERNEL32: LocalCompact %08xh - stub (cbNewSize)\n",
319 cbNewSize));
320
321 return cbNewSize;
322}
323//******************************************************************************
324#ifdef DEBUG
325static ULONG totalGlobalAlloc = 0;
326#endif
327//******************************************************************************
328HGLOBAL WIN32API GlobalAlloc(UINT fuFlags, DWORD dwBytes)
329{
330 HGLOBAL ret;
331
332 ret = O32_GlobalAlloc(fuFlags, dwBytes);
333#ifdef DEBUG
334 totalGlobalAlloc += dwBytes;
335#endif
336 dprintf(("KERNEL32: GlobalAlloc %x %d returned %x (total %x)", fuFlags, dwBytes, ret, totalGlobalAlloc));
337 return ret;
338}
339//******************************************************************************
340//******************************************************************************
341HGLOBAL WIN32API GlobalFree( HGLOBAL arg1)
342{
343 HGLOBAL ret;
344
345#ifdef DEBUG
346 totalGlobalAlloc -= O32_GlobalSize(arg1);
347#endif
348 ret = O32_GlobalFree(arg1);
349 dprintf(("KERNEL32: GlobalFree %x returned %x (lasterr=%x) total %x", arg1, ret, GetLastError(), totalGlobalAlloc));
350 return ret;
351}
352//******************************************************************************
353//******************************************************************************
354HGLOBAL WIN32API GlobalHandle( LPCVOID arg1)
355{
356 dprintf(("KERNEL32: OS2GlobalHandle\n"));
357
358 return O32_GlobalHandle((LPVOID)arg1);
359}
360//******************************************************************************
361//******************************************************************************
362UINT WIN32API GlobalFlags(HGLOBAL arg1)
363{
364 dprintf(("KERNEL32: OS2GlobalFlags\n"));
365
366 return O32_GlobalFlags(arg1);
367}
368//******************************************************************************
369//******************************************************************************
370DWORD WIN32API GlobalCompact(DWORD dwMinFree)
371{
372 dprintf(("KERNEL32: GlobalCompact, OBSOLETE - stub\n"));
373
374 return(0);
375}
376//******************************************************************************
377//******************************************************************************
378PVOID WIN32API GlobalLock(HGLOBAL arg1)
379{
380 PVOID ret;
381
382 ret = O32_GlobalLock(arg1);
383 dprintf(("KERNEL32: GlobalLock %x returned %x", arg1, ret));
384 return ret;
385}
386//******************************************************************************
387//******************************************************************************
388HGLOBAL WIN32API GlobalReAlloc(HGLOBAL arg1, DWORD arg2, UINT arg3)
389{
390 dprintf(("KERNEL32: GlobalReAlloc\n"));
391
392 return O32_GlobalReAlloc(arg1, arg2, arg3);
393}
394//******************************************************************************
395//******************************************************************************
396DWORD WIN32API GlobalSize(HGLOBAL arg1)
397{
398 dprintf(("KERNEL32: GlobalSize\n"));
399
400 return O32_GlobalSize(arg1);
401}
402//******************************************************************************
403//******************************************************************************
404BOOL WIN32API GlobalUnlock(HGLOBAL arg1)
405{
406 dprintf(("KERNEL32: GlobalUnlock\n"));
407
408 return O32_GlobalUnlock(arg1);
409}
410/***********************************************************************
411 * GlobalWire
412 *
413 * The GlobalWire function is obsolete. It is provided only for compatibility
414 * with 16-bit versions of Windows. Applications that need to lock a global
415 * memory object should use the GlobalLock and GlobalUnlock functions.
416 *
417 */
418LPVOID WIN32API GlobalWire(HGLOBAL hmem)
419{
420 return GlobalLock( hmem );
421}
422
423
424/***********************************************************************
425 * GlobalUnWire
426 *
427 * The GlobalUnWire function is obsolete. It is provided only for compatibility
428 * with 16-bit versions of Windows. Applications that need to lock a global
429 * memory object should use the GlobalLock and GlobalUnlock functions.
430 *
431 */
432BOOL WIN32API GlobalUnWire(HGLOBAL hmem)
433{
434 return GlobalUnlock( hmem);
435}
436//******************************************************************************
437//******************************************************************************
Note: See TracBrowser for help on using the repository browser.