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 #include "msvcrt/stdlib.h"
15 DEFAULT_DEBUG_CHANNEL(msvcrt
);
18 extern CRITICAL_SECTION MSVCRT_heap_cs
;
19 #define LOCK_HEAP EnterCriticalSection(&MSVCRT_heap_cs)
20 #define UNLOCK_HEAP LeaveCriticalSection(&MSVCRT_heap_cs)
22 /* heap function constants */
23 #define MSVCRT_HEAPEMPTY -1
24 #define MSVCRT_HEAPOK -2
25 #define MSVCRT_HEAPBADBEGIN -3
26 #define MSVCRT_HEAPBADNODE -4
27 #define MSVCRT_HEAPEND -5
28 #define MSVCRT_HEAPBADPTR -6
29 #define MSVCRT_FREEENTRY 0
30 #define MSVCRT_USEDENTRY 1
32 typedef struct MSVCRT_heapinfo
39 typedef void (*MSVCRT_new_handler_func
)(void);
41 static MSVCRT_new_handler_func MSVCRT_new_handler
;
42 static int MSVCRT_new_mode
;
44 /*********************************************************************
45 * operator_new (MSVCRT.@)
47 void* MSVCRT_operator_new(unsigned long size
)
49 void *retval
= HeapAlloc(GetProcessHeap(), 0, size
);
50 TRACE("(%ld) returning %p\n", size
, retval
);
52 if(retval
&& MSVCRT_new_handler
)
53 (*MSVCRT_new_handler
)();
58 /*********************************************************************
59 * operator_delete (MSVCRT.@)
61 void MSVCRT_operator_delete(void *mem
)
64 HeapFree(GetProcessHeap(), 0, mem
);
68 /*********************************************************************
69 * ?_query_new_handler@@YAP6AHI@ZXZ (MSVCRT.@)
71 MSVCRT_new_handler_func
MSVCRT__query_new_handler(void)
73 return MSVCRT_new_handler
;
77 /*********************************************************************
78 * ?_query_new_mode@@YAHXZ (MSVCRT.@)
80 int MSVCRT__query_new_mode(void)
82 return MSVCRT_new_mode
;
85 /*********************************************************************
86 * ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z (MSVCRT.@)
88 MSVCRT_new_handler_func
MSVCRT__set_new_handler(MSVCRT_new_handler_func func
)
90 MSVCRT_new_handler_func old_handler
;
92 old_handler
= MSVCRT_new_handler
;
93 MSVCRT_new_handler
= func
;
98 /*********************************************************************
99 * ?_set_new_mode@@YAHH@Z (MSVCRT.@)
101 int MSVCRT__set_new_mode(int mode
)
105 old_mode
= MSVCRT_new_mode
;
106 MSVCRT_new_mode
= mode
;
111 /*********************************************************************
114 void* _expand(void* mem
, unsigned int size
)
116 return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY
, mem
, size
);
119 /*********************************************************************
120 * _heapchk (MSVCRT.@)
124 if (!HeapValidate( GetProcessHeap(), 0, NULL
))
126 MSVCRT__set_errno(GetLastError());
127 return MSVCRT_HEAPBADNODE
;
129 return MSVCRT_HEAPOK
;
132 /*********************************************************************
133 * _heapmin (MSVCRT.@)
137 if (!HeapCompact( GetProcessHeap(), 0 ))
139 if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED
)
140 MSVCRT__set_errno(GetLastError());
146 /*********************************************************************
147 * _heapwalk (MSVCRT.@)
149 int _heapwalk(MSVCRT_HEAPINFO
* next
)
151 PROCESS_HEAP_ENTRY phe
;
154 phe
.lpData
= next
->_pentry
;
155 phe
.cbData
= next
->_size
;
156 phe
.wFlags
= next
->_useflag
== MSVCRT_USEDENTRY
? PROCESS_HEAP_ENTRY_BUSY
: 0;
158 if (phe
.lpData
&& phe
.wFlags
& PROCESS_HEAP_ENTRY_BUSY
&&
159 !HeapValidate( GetProcessHeap(), 0, phe
.lpData
))
162 MSVCRT__set_errno(GetLastError());
163 return MSVCRT_HEAPBADNODE
;
168 if (!HeapWalk( GetProcessHeap(), &phe
))
171 if (GetLastError() == ERROR_NO_MORE_ITEMS
)
172 return MSVCRT_HEAPEND
;
173 MSVCRT__set_errno(GetLastError());
175 return MSVCRT_HEAPBADBEGIN
;
176 return MSVCRT_HEAPBADNODE
;
178 } while (phe
.wFlags
& (PROCESS_HEAP_REGION
|PROCESS_HEAP_UNCOMMITTED_RANGE
));
181 next
->_pentry
= phe
.lpData
;
182 next
->_size
= phe
.cbData
;
183 next
->_useflag
= phe
.wFlags
& PROCESS_HEAP_ENTRY_BUSY
? MSVCRT_USEDENTRY
: MSVCRT_FREEENTRY
;
184 return MSVCRT_HEAPOK
;
187 /*********************************************************************
188 * _heapset (MSVCRT.@)
190 int _heapset(unsigned int value
)
193 MSVCRT_HEAPINFO heap
;
195 memset( &heap
, 0, sizeof(MSVCRT_HEAPINFO
) );
197 while ((retval
= _heapwalk(&heap
)) == MSVCRT_HEAPOK
)
199 if (heap
._useflag
== MSVCRT_FREEENTRY
)
200 memset(heap
._pentry
, value
, heap
._size
);
203 return retval
== MSVCRT_HEAPEND
? MSVCRT_HEAPOK
: retval
;
206 /*********************************************************************
209 long _msize(void* mem
)
211 long size
= HeapSize(GetProcessHeap(),0,mem
);
214 WARN(":Probably called with non wine-allocated memory, ret = -1\n");
215 /* At least the Win32 crtdll/msvcrt also return -1 in this case */
220 /*********************************************************************
223 void* MSVCRT_calloc(unsigned int size
, unsigned int count
)
225 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, size
* count
);
228 /*********************************************************************
231 void MSVCRT_free(void* ptr
)
233 HeapFree(GetProcessHeap(),0,ptr
);
236 /*********************************************************************
239 void* MSVCRT_malloc(unsigned int size
)
241 void *ret
= HeapAlloc(GetProcessHeap(),0,size
);
243 MSVCRT__set_errno(GetLastError());
247 /*********************************************************************
250 void* MSVCRT_realloc(void* ptr
, unsigned int size
)
252 return HeapReAlloc(GetProcessHeap(), 0, ptr
, size
);