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