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