Various cosmetic changes.
[wine] / dlls / msvcrt / heap.c
1 /*
2  * msvcrt.dll heap functions
3  *
4  * Copyright 2000 Jon Griffiths
5  *
6  * Note: Win32 heap operations are MT safe. We only lock the new
7  *       handler and non atomic heap operations
8  */
9
10 #include "msvcrt.h"
11 #include "ms_errno.h"
12
13 #include "msvcrt/malloc.h"
14 #include "mtdll.h"
15
16 #include "wine/debug.h"
17
18 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
19
20 /* MT */
21 #define LOCK_HEAP   _mlock( _HEAP_LOCK )
22 #define UNLOCK_HEAP _munlock( _HEAP_LOCK )
23
24
25 typedef void (*MSVCRT_new_handler_func)(unsigned long size);
26
27 static MSVCRT_new_handler_func MSVCRT_new_handler;
28 static int MSVCRT_new_mode;
29
30
31 /*********************************************************************
32  *              ??2@YAPAXI@Z (MSVCRT.@)
33  */
34 void* MSVCRT_operator_new(unsigned long size)
35 {
36   void *retval = HeapAlloc(GetProcessHeap(), 0, size);
37   TRACE("(%ld) returning %p\n", size, retval);
38   LOCK_HEAP;
39   if(retval && MSVCRT_new_handler)
40     (*MSVCRT_new_handler)(size);
41   UNLOCK_HEAP;
42   return retval;
43 }
44
45 /*********************************************************************
46  *              ??3@YAXPAX@Z (MSVCRT.@)
47  */
48 void MSVCRT_operator_delete(void *mem)
49 {
50   TRACE("(%p)\n", mem);
51   HeapFree(GetProcessHeap(), 0, mem);
52 }
53
54
55 /*********************************************************************
56  *              ?_query_new_handler@@YAP6AHI@ZXZ (MSVCRT.@)
57  */
58 MSVCRT_new_handler_func MSVCRT__query_new_handler(void)
59 {
60   return MSVCRT_new_handler;
61 }
62
63
64 /*********************************************************************
65  *              ?_query_new_mode@@YAHXZ (MSVCRT.@)
66  */
67 int MSVCRT__query_new_mode(void)
68 {
69   return MSVCRT_new_mode;
70 }
71
72 /*********************************************************************
73  *              ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z (MSVCRT.@)
74  */
75 MSVCRT_new_handler_func MSVCRT__set_new_handler(MSVCRT_new_handler_func func)
76 {
77   MSVCRT_new_handler_func old_handler;
78   LOCK_HEAP;
79   old_handler = MSVCRT_new_handler;
80   MSVCRT_new_handler = func;
81   UNLOCK_HEAP;
82   return old_handler;
83 }
84
85 /*********************************************************************
86  *              ?set_new_handler@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
87  */
88 MSVCRT_new_handler_func MSVCRT_set_new_handler(void *func)
89 {
90   TRACE("(%p)\n",func);
91   MSVCRT__set_new_handler(NULL);
92   return NULL;
93 }
94
95 /*********************************************************************
96  *              ?_set_new_mode@@YAHH@Z (MSVCRT.@)
97  */
98 int MSVCRT__set_new_mode(int mode)
99 {
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;
106 }
107
108 /*********************************************************************
109  *              _callnewh (MSVCRT.@)
110  */
111 int _callnewh(unsigned long size)
112 {
113   if(MSVCRT_new_handler)
114     (*MSVCRT_new_handler)(size);
115   return 0;
116 }
117
118 /*********************************************************************
119  *              _expand (MSVCRT.@)
120  */
121 void* _expand(void* mem, MSVCRT_size_t size)
122 {
123   return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, mem, size);
124 }
125
126 /*********************************************************************
127  *              _heapchk (MSVCRT.@)
128  */
129 int _heapchk(void)
130 {
131   if (!HeapValidate( GetProcessHeap(), 0, NULL))
132   {
133     MSVCRT__set_errno(GetLastError());
134     return _HEAPBADNODE;
135   }
136   return _HEAPOK;
137 }
138
139 /*********************************************************************
140  *              _heapmin (MSVCRT.@)
141  */
142 int _heapmin(void)
143 {
144   if (!HeapCompact( GetProcessHeap(), 0 ))
145   {
146     if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
147       MSVCRT__set_errno(GetLastError());
148     return -1;
149   }
150   return 0;
151 }
152
153 /*********************************************************************
154  *              _heapwalk (MSVCRT.@)
155  */
156 int _heapwalk(_HEAPINFO* next)
157 {
158   PROCESS_HEAP_ENTRY phe;
159
160   LOCK_HEAP;
161   phe.lpData = next->_pentry;
162   phe.cbData = next->_size;
163   phe.wFlags = next->_useflag == _USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0;
164
165   if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY &&
166       !HeapValidate( GetProcessHeap(), 0, phe.lpData ))
167   {
168     UNLOCK_HEAP;
169     MSVCRT__set_errno(GetLastError());
170     return _HEAPBADNODE;
171   }
172
173   do
174   {
175     if (!HeapWalk( GetProcessHeap(), &phe ))
176     {
177       UNLOCK_HEAP;
178       if (GetLastError() == ERROR_NO_MORE_ITEMS)
179          return _HEAPEND;
180       MSVCRT__set_errno(GetLastError());
181       if (!phe.lpData)
182         return _HEAPBADBEGIN;
183       return _HEAPBADNODE;
184     }
185   } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE));
186
187   UNLOCK_HEAP;
188   next->_pentry = phe.lpData;
189   next->_size = phe.cbData;
190   next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? _USEDENTRY : _FREEENTRY;
191   return _HEAPOK;
192 }
193
194 /*********************************************************************
195  *              _heapset (MSVCRT.@)
196  */
197 int _heapset(unsigned int value)
198 {
199   int retval;
200   _HEAPINFO heap;
201
202   memset( &heap, 0, sizeof(_HEAPINFO) );
203   LOCK_HEAP;
204   while ((retval = _heapwalk(&heap)) == _HEAPOK)
205   {
206     if (heap._useflag == _FREEENTRY)
207       memset(heap._pentry, value, heap._size);
208   }
209   UNLOCK_HEAP;
210   return retval == _HEAPEND? _HEAPOK : retval;
211 }
212
213 /*********************************************************************
214  *              _heapadd (MSVCRT.@)
215  */
216 int _heapadd(void* mem, MSVCRT_size_t size)
217 {
218   TRACE("(%p,%d) unsupported in Win32\n", mem,size);
219   SET_THREAD_VAR(errno,MSVCRT_ENOSYS);
220   return -1;
221 }
222
223 /*********************************************************************
224  *              _msize (MSVCRT.@)
225  */
226 MSVCRT_size_t _msize(void* mem)
227 {
228   long size = HeapSize(GetProcessHeap(),0,mem);
229   if (size == -1)
230   {
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 */
233   }
234   return size;
235 }
236
237 /*********************************************************************
238  *              calloc (MSVCRT.@)
239  */
240 void* MSVCRT_calloc(MSVCRT_size_t size, MSVCRT_size_t count)
241 {
242   return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
243 }
244
245 /*********************************************************************
246  *              free (MSVCRT.@)
247  */
248 void MSVCRT_free(void* ptr)
249 {
250   HeapFree(GetProcessHeap(),0,ptr);
251 }
252
253 /*********************************************************************
254  *                  malloc (MSVCRT.@)
255  */
256 void* MSVCRT_malloc(MSVCRT_size_t size)
257 {
258   void *ret = HeapAlloc(GetProcessHeap(),0,size);
259   if (!ret)
260     MSVCRT__set_errno(GetLastError());
261   return ret;
262 }
263
264 /*********************************************************************
265  *              realloc (MSVCRT.@)
266  */
267 void* MSVCRT_realloc(void* ptr, MSVCRT_size_t size)
268 {
269   return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
270 }