Don't crash on close from window manager.
[wine/multimedia.git] / dlls / msvcrt / heap.c
blob0e653a637e3869ffb68e0aae2c5e65b0d9396cb6
1 /*
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
8 */
10 #include "msvcrt.h"
12 DEFAULT_DEBUG_CHANNEL(msvcrt);
14 /* MT */
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
31 int * _pentry;
32 size_t _size;
33 int _useflag;
34 } 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);
48 LOCK_HEAP;
49 if(retval && MSVCRT_new_handler)
50 (*MSVCRT_new_handler)();
51 UNLOCK_HEAP;
52 return retval;
55 /*********************************************************************
56 * operator_delete (MSVCRT.@)
58 void __cdecl MSVCRT_operator_delete(void *mem)
60 TRACE("(%p)\n", 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;
88 LOCK_HEAP;
89 old_handler = MSVCRT_new_handler;
90 MSVCRT_new_handler = func;
91 UNLOCK_HEAP;
92 return old_handler;
95 /*********************************************************************
96 * ?_set_new_mode@@YAHH@Z (MSVCRT.@)
98 int __cdecl MSVCRT__set_new_mode(int mode)
100 int old_mode;
101 LOCK_HEAP;
102 old_mode = MSVCRT_new_mode;
103 MSVCRT_new_mode = mode;
104 UNLOCK_HEAP;
105 return old_mode;
108 /*********************************************************************
109 * _expand (MSVCRT.@)
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());
138 return -1;
140 return 0;
143 /*********************************************************************
144 * _heapwalk (MSVCRT.@)
146 int __cdecl MSVCRT__heapwalk(MSVCRT_HEAPINFO *next)
148 PROCESS_HEAP_ENTRY phe;
150 LOCK_HEAP;
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 ))
158 UNLOCK_HEAP;
159 MSVCRT__set_errno(GetLastError());
160 return MSVCRT_HEAPBADNODE;
165 if (!HeapWalk( GetProcessHeap(), &phe ))
167 UNLOCK_HEAP;
168 if (GetLastError() == ERROR_NO_MORE_ITEMS)
169 return MSVCRT_HEAPEND;
170 MSVCRT__set_errno(GetLastError());
171 if (!phe.lpData)
172 return MSVCRT_HEAPBADBEGIN;
173 return MSVCRT_HEAPBADNODE;
175 } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE));
177 UNLOCK_HEAP;
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)
189 int retval;
190 MSVCRT_HEAPINFO heap;
192 memset( &heap, 0, sizeof(MSVCRT_HEAPINFO) );
193 LOCK_HEAP;
194 while ((retval = MSVCRT__heapwalk(&heap)) == MSVCRT_HEAPOK)
196 if (heap._useflag == MSVCRT_FREEENTRY)
197 memset(heap._pentry, value, heap._size);
199 UNLOCK_HEAP;
200 return retval == MSVCRT_HEAPEND? MSVCRT_HEAPOK : retval;
203 /*********************************************************************
204 * _msize (MSVCRT.@)
206 long __cdecl MSVCRT__msize(void *mem)
208 long size = HeapSize(GetProcessHeap(),0,mem);
209 if (size == -1)
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 */
214 return size;
217 /*********************************************************************
218 * calloc (MSVCRT.@)
220 void *__cdecl MSVCRT_calloc(unsigned int size, unsigned int count)
222 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
225 /*********************************************************************
226 * free (MSVCRT.@)
228 void __cdecl MSVCRT_free(void *ptr)
230 HeapFree(GetProcessHeap(),0,ptr);
233 /*********************************************************************
234 * malloc (MSVCRT.@)
236 void * __cdecl MSVCRT_malloc(unsigned int size)
238 void *ret = HeapAlloc(GetProcessHeap(),0,size);
239 if (!ret)
240 MSVCRT__set_errno(GetLastError());
241 return ret;
244 /*********************************************************************
245 * realloc (MSVCRT.@)
247 void *__cdecl MSVCRT_realloc(void *ptr, unsigned int size)
249 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);