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
);