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
12 DEFAULT_DEBUG_CHANNEL(msvcrt);
15 extern CRITICAL_SECTION MSVCRT_heap_cs;
16 #define LOCK_HEAP EnterCriticalSection(&MSVCRT_heap_cs)
17 #define UNLOCK_HEAP LeaveCriticalSection(&MSVCRT_heap_cs)
19 /* heap function constants */
20 #define MSVCRT_HEAPEMPTY -1
21 #define MSVCRT_HEAPOK -2
22 #define MSVCRT_HEAPBADBEGIN -3
23 #define MSVCRT_HEAPBADNODE -4
24 #define MSVCRT_HEAPEND -5
25 #define MSVCRT_HEAPBADPTR -6
26 #define MSVCRT_FREEENTRY 0
27 #define MSVCRT_USEDENTRY 1
29 typedef struct MSVCRT_heapinfo
36 typedef void (*MSVCRT_new_handler_func)(void);
38 static MSVCRT_new_handler_func MSVCRT_new_handler;
39 static int MSVCRT_new_mode;
41 /*********************************************************************
42 * operator_new (MSVCRT.@)
44 void *__cdecl MSVCRT_operator_new(unsigned long size)
46 void *retval = HeapAlloc(GetProcessHeap(), 0, size);
47 TRACE("(%ld) returning %p\n", size, retval);
49 if(retval && MSVCRT_new_handler)
50 (*MSVCRT_new_handler)();
55 /*********************************************************************
56 * operator_delete (MSVCRT.@)
58 void __cdecl MSVCRT_operator_delete(void *mem)
61 HeapFree(GetProcessHeap(), 0, mem);
65 /*********************************************************************
66 * ?_query_new_handler@@YAP6AHI@ZXZ (MSVCRT.@)
68 MSVCRT_new_handler_func __cdecl MSVCRT__query_new_handler(void)
70 return MSVCRT_new_handler;
74 /*********************************************************************
75 * ?_query_new_mode@@YAHXZ (MSVCRT.@)
77 int __cdecl MSVCRT__query_new_mode(void)
79 return MSVCRT_new_mode;
82 /*********************************************************************
83 * ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z (MSVCRT.@)
85 MSVCRT_new_handler_func __cdecl MSVCRT__set_new_handler(MSVCRT_new_handler_func func)
87 MSVCRT_new_handler_func old_handler;
89 old_handler = MSVCRT_new_handler;
90 MSVCRT_new_handler = func;
95 /*********************************************************************
96 * ?_set_new_mode@@YAHH@Z (MSVCRT.@)
98 int __cdecl MSVCRT__set_new_mode(int mode)
102 old_mode = MSVCRT_new_mode;
103 MSVCRT_new_mode = mode;
108 /*********************************************************************
111 void *__cdecl MSVCRT__expand(void *mem, unsigned int size)
113 return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, mem, size);
116 /*********************************************************************
117 * _heapchk (MSVCRT.@)
119 int __cdecl MSVCRT__heapchk(void)
121 if (!HeapValidate( GetProcessHeap(), 0, NULL))
123 MSVCRT__set_errno(GetLastError());
124 return MSVCRT_HEAPBADNODE;
126 return MSVCRT_HEAPOK;
129 /*********************************************************************
130 * _heapmin (MSVCRT.@)
132 int __cdecl MSVCRT__heapmin(void)
134 if (!HeapCompact( GetProcessHeap(), 0 ))
136 if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
137 MSVCRT__set_errno(GetLastError());
143 /*********************************************************************
144 * _heapwalk (MSVCRT.@)
146 int __cdecl MSVCRT__heapwalk(MSVCRT_HEAPINFO *next)
148 PROCESS_HEAP_ENTRY phe;
151 phe.lpData = next->_pentry;
152 phe.cbData = next->_size;
153 phe.wFlags = next->_useflag == MSVCRT_USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0;
155 if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY &&
156 !HeapValidate( GetProcessHeap(), 0, phe.lpData ))
159 MSVCRT__set_errno(GetLastError());
160 return MSVCRT_HEAPBADNODE;
165 if (!HeapWalk( GetProcessHeap(), &phe ))
168 if (GetLastError() == ERROR_NO_MORE_ITEMS)
169 return MSVCRT_HEAPEND;
170 MSVCRT__set_errno(GetLastError());
172 return MSVCRT_HEAPBADBEGIN;
173 return MSVCRT_HEAPBADNODE;
175 } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE));
178 next->_pentry = phe.lpData;
179 next->_size = phe.cbData;
180 next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? MSVCRT_USEDENTRY : MSVCRT_FREEENTRY;
181 return MSVCRT_HEAPOK;
184 /*********************************************************************
185 * _heapset (MSVCRT.@)
187 int __cdecl MSVCRT__heapset(unsigned int value)
190 MSVCRT_HEAPINFO heap;
192 memset( &heap, 0, sizeof(MSVCRT_HEAPINFO) );
194 while ((retval = MSVCRT__heapwalk(&heap)) == MSVCRT_HEAPOK)
196 if (heap._useflag == MSVCRT_FREEENTRY)
197 memset(heap._pentry, value, heap._size);
200 return retval == MSVCRT_HEAPEND? MSVCRT_HEAPOK : retval;
203 /*********************************************************************
206 long __cdecl MSVCRT__msize(void *mem)
208 long size = HeapSize(GetProcessHeap(),0,mem);
211 WARN(":Probably called with non wine-allocated memory, ret = -1\n");
212 /* At least the Win32 crtdll/msvcrt also return -1 in this case */
217 /*********************************************************************
220 void *__cdecl MSVCRT_calloc(unsigned int size, unsigned int count)
222 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
225 /*********************************************************************
228 void __cdecl MSVCRT_free(void *ptr)
230 HeapFree(GetProcessHeap(),0,ptr);
233 /*********************************************************************
236 void * __cdecl MSVCRT_malloc(unsigned int size)
238 void *ret = HeapAlloc(GetProcessHeap(),0,size);
240 MSVCRT__set_errno(GetLastError());
244 /*********************************************************************
247 void *__cdecl MSVCRT_realloc(void *ptr, unsigned int size)
249 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);