2 * msvcrt.dll heap functions
4 * Copyright 2000 Jon Griffiths
6 * Note: Win32 heap operations are MT safe. We only lock the new
7 * handler and non atomic heap operations
13 #include "msvcrt/malloc.h"
16 #include "wine/debug.h"
18 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
21 #define LOCK_HEAP _mlock( _HEAP_LOCK )
22 #define UNLOCK_HEAP _munlock( _HEAP_LOCK )
25 typedef void (*MSVCRT_new_handler_func)(unsigned long size);
27 static MSVCRT_new_handler_func MSVCRT_new_handler;
28 static int MSVCRT_new_mode;
31 /*********************************************************************
32 * ??2@YAPAXI@Z (MSVCRT.@)
34 void* MSVCRT_operator_new(unsigned long size)
36 void *retval = HeapAlloc(GetProcessHeap(), 0, size);
37 TRACE("(%ld) returning %p\n", size, retval);
39 if(retval && MSVCRT_new_handler)
40 (*MSVCRT_new_handler)(size);
45 /*********************************************************************
46 * ??3@YAXPAX@Z (MSVCRT.@)
48 void MSVCRT_operator_delete(void *mem)
51 HeapFree(GetProcessHeap(), 0, mem);
55 /*********************************************************************
56 * ?_query_new_handler@@YAP6AHI@ZXZ (MSVCRT.@)
58 MSVCRT_new_handler_func MSVCRT__query_new_handler(void)
60 return MSVCRT_new_handler;
64 /*********************************************************************
65 * ?_query_new_mode@@YAHXZ (MSVCRT.@)
67 int MSVCRT__query_new_mode(void)
69 return MSVCRT_new_mode;
72 /*********************************************************************
73 * ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z (MSVCRT.@)
75 MSVCRT_new_handler_func MSVCRT__set_new_handler(MSVCRT_new_handler_func func)
77 MSVCRT_new_handler_func old_handler;
79 old_handler = MSVCRT_new_handler;
80 MSVCRT_new_handler = func;
85 /*********************************************************************
86 * ?set_new_handler@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
88 MSVCRT_new_handler_func MSVCRT_set_new_handler(void *func)
91 MSVCRT__set_new_handler(NULL);
95 /*********************************************************************
96 * ?_set_new_mode@@YAHH@Z (MSVCRT.@)
98 int MSVCRT__set_new_mode(int mode)
102 old_mode = MSVCRT_new_mode;
103 MSVCRT_new_mode = mode;
108 /*********************************************************************
109 * _callnewh (MSVCRT.@)
111 int _callnewh(unsigned long size)
113 if(MSVCRT_new_handler)
114 (*MSVCRT_new_handler)(size);
118 /*********************************************************************
121 void* _expand(void* mem, MSVCRT_size_t size)
123 return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, mem, size);
126 /*********************************************************************
127 * _heapchk (MSVCRT.@)
131 if (!HeapValidate( GetProcessHeap(), 0, NULL))
133 MSVCRT__set_errno(GetLastError());
139 /*********************************************************************
140 * _heapmin (MSVCRT.@)
144 if (!HeapCompact( GetProcessHeap(), 0 ))
146 if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
147 MSVCRT__set_errno(GetLastError());
153 /*********************************************************************
154 * _heapwalk (MSVCRT.@)
156 int _heapwalk(_HEAPINFO* next)
158 PROCESS_HEAP_ENTRY phe;
161 phe.lpData = next->_pentry;
162 phe.cbData = next->_size;
163 phe.wFlags = next->_useflag == _USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0;
165 if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY &&
166 !HeapValidate( GetProcessHeap(), 0, phe.lpData ))
169 MSVCRT__set_errno(GetLastError());
175 if (!HeapWalk( GetProcessHeap(), &phe ))
178 if (GetLastError() == ERROR_NO_MORE_ITEMS)
180 MSVCRT__set_errno(GetLastError());
182 return _HEAPBADBEGIN;
185 } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE));
188 next->_pentry = phe.lpData;
189 next->_size = phe.cbData;
190 next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? _USEDENTRY : _FREEENTRY;
194 /*********************************************************************
195 * _heapset (MSVCRT.@)
197 int _heapset(unsigned int value)
202 memset( &heap, 0, sizeof(_HEAPINFO) );
204 while ((retval = _heapwalk(&heap)) == _HEAPOK)
206 if (heap._useflag == _FREEENTRY)
207 memset(heap._pentry, value, heap._size);
210 return retval == _HEAPEND? _HEAPOK : retval;
213 /*********************************************************************
214 * _heapadd (MSVCRT.@)
216 int _heapadd(void* mem, MSVCRT_size_t size)
218 TRACE("(%p,%d) unsupported in Win32\n", mem,size);
219 SET_THREAD_VAR(errno,MSVCRT_ENOSYS);
223 /*********************************************************************
226 MSVCRT_size_t _msize(void* mem)
228 long size = HeapSize(GetProcessHeap(),0,mem);
231 WARN(":Probably called with non wine-allocated memory, ret = -1\n");
232 /* At least the Win32 crtdll/msvcrt also return -1 in this case */
237 /*********************************************************************
240 void* MSVCRT_calloc(MSVCRT_size_t size, MSVCRT_size_t count)
242 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
245 /*********************************************************************
248 void MSVCRT_free(void* ptr)
250 HeapFree(GetProcessHeap(),0,ptr);
253 /*********************************************************************
256 void* MSVCRT_malloc(MSVCRT_size_t size)
258 void *ret = HeapAlloc(GetProcessHeap(),0,size);
260 MSVCRT__set_errno(GetLastError());
264 /*********************************************************************
267 void* MSVCRT_realloc(void* ptr, MSVCRT_size_t size)
269 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);