Moved wsprintf functions to dlls/user.
[wine] / dlls / crtdll / memory.c
1 /*
2  * CRTDLL memory functions
3  * 
4  * Copyright 1996,1998 Marcus Meissner
5  * Copyright 1996 Jukka Iivonen
6  * Copyright 1997,2000 Uwe Bonnes
7  * Copyright 2000 Jon Griffiths
8  *
9  * Implementation Notes:
10  * MT Safe.
11  * heapwalk from win does not work. This is most likely due to internal
12  * differences between wine and win (see memory/heap.c comments). This
13  * version works fine, however.
14  */
15
16 #include "crtdll.h"
17
18
19 DEFAULT_DEBUG_CHANNEL(crtdll);
20
21 static new_handler_type new_handler;
22
23
24 /*********************************************************************
25  *                  new           (CRTDLL.001)
26  *
27  * Allocate memory.
28  */
29 LPVOID __cdecl CRTDLL_new(DWORD size)
30 {
31     VOID* result;
32     if(!(result = HeapAlloc(GetProcessHeap(),0,size)) && new_handler)
33         (*new_handler)();
34     return result;
35 }
36
37
38 /*********************************************************************
39  *                  delete       (CRTDLL.002)
40  *
41  * Free memory created with new.
42  */
43 VOID __cdecl CRTDLL_delete(LPVOID ptr)
44 {
45     HeapFree(GetProcessHeap(),0,ptr);
46 }
47
48
49 /*********************************************************************
50  *                  set_new_handler(CRTDLL.003)
51  */
52 new_handler_type __cdecl CRTDLL_set_new_handler(new_handler_type func)
53 {
54     new_handler_type old_handler = new_handler;
55     new_handler = func;
56     return old_handler;
57 }
58
59
60 /*********************************************************************
61  *                  _expand        (CRTDLL.088)
62  *
63  * Increase the size of a block of memory allocated with malloc()
64  * or realloc().
65  */
66 LPVOID __cdecl CRTDLL__expand(LPVOID ptr, INT size)
67 {
68     return HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, ptr, size );
69 }
70
71
72 /*********************************************************************
73  *                  _heapchk        (CRTDLL.130)
74  *
75  * Check the consistency of the process heap.
76  */
77 INT __cdecl CRTDLL__heapchk(VOID)
78 {
79   if (!HeapValidate( GetProcessHeap(), 0, NULL))
80   {
81     __CRTDLL__set_errno(GetLastError());
82     return _HEAPBADNODE;
83   }
84   return _HEAPOK;
85 }
86
87
88 /*********************************************************************
89  *                  _heapmin        (CRTDLL.131)
90  *
91  * Minimise the size of the heap.
92  */
93 INT __cdecl CRTDLL__heapmin(VOID)
94 {
95   if (!HeapCompact( GetProcessHeap(), 0 ))
96   {
97     if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
98       __CRTDLL__set_errno(GetLastError());
99     return -1;
100   }
101   return 0;
102 }
103
104
105 /*********************************************************************
106  *                  _heapset        (CRTDLL.132)
107  *
108  * Fill free memory in the heap with a given value.
109  */
110 INT __cdecl CRTDLL__heapset(UINT value)
111 {
112   INT retVal;
113   struct _heapinfo heap;
114
115   memset( &heap, 0, sizeof(heap) );
116
117   while ((retVal = CRTDLL__heapwalk(&heap)) == _HEAPOK)
118   {
119     if (heap._useflag == _FREEENTRY)
120       memset(heap._pentry, value, heap._size);
121   }
122   return retVal == _HEAPEND? _HEAPOK : retVal;
123 }
124
125
126 /*********************************************************************
127  *                  _heapwalk        (CRTDLL.133)
128  *
129  * Walk the heap block by block.
130  */
131 INT __cdecl CRTDLL__heapwalk(struct _heapinfo *next)
132 {
133   PROCESS_HEAP_ENTRY phe;
134
135   phe.lpData = next->_pentry;
136   phe.cbData = next->_size;
137   phe.wFlags = next->_useflag == _USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0;
138
139   if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY && 
140       !HeapValidate( GetProcessHeap(), 0, phe.lpData ))
141   {
142     __CRTDLL__set_errno(GetLastError());
143     return _HEAPBADNODE;
144   }
145
146   do
147   {
148     if (!HeapWalk( GetProcessHeap(), &phe ))
149     {
150       if (GetLastError() == ERROR_NO_MORE_ITEMS)
151         return _HEAPEND;
152       __CRTDLL__set_errno(GetLastError());
153       if (!phe.lpData)
154         return _HEAPBADBEGIN;
155       return _HEAPBADNODE;
156     }
157   } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE));
158
159   next->_pentry = phe.lpData;
160   next->_size = phe.cbData;
161   next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? _USEDENTRY : _FREEENTRY;
162   return _HEAPOK;
163 }
164
165
166 /*********************************************************************
167  *                  _msize     (CRTDLL.234)
168  *
169  * Return the actual used size of an allocated block of memory.
170  *
171  */
172 LONG __cdecl CRTDLL__msize(LPVOID mem)
173 {
174   LONG size = HeapSize(GetProcessHeap(),0,mem);
175   if (size == -1)
176   {
177     WARN(":Probably called with non wine-allocated memory, ret = -1\n");
178     /* At least the win98/nt crtdlls also return -1 in this case */
179   }
180   return size;
181 }
182
183
184 /*********************************************************************
185  *                  calloc        (CRTDLL.350)
186  *
187  * Allocate memory from the heap and initialise it to zero.
188  */
189 LPVOID __cdecl CRTDLL_calloc(DWORD size, DWORD count)
190 {
191     return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
192 }
193
194
195 /*********************************************************************
196  *                  free          (CRTDLL.375)
197  *
198  * Free a block of memory allocated with malloc()
199  */
200 VOID __cdecl CRTDLL_free(LPVOID ptr)
201 {
202     HeapFree(GetProcessHeap(),0,ptr);
203 }
204
205
206 /*********************************************************************
207  *                  malloc        (CRTDLL.424)
208  * 
209  * Alocate memory from the heap.
210  */
211 LPVOID __cdecl CRTDLL_malloc(DWORD size)
212 {
213   LPVOID ret = HeapAlloc(GetProcessHeap(),0,size);
214   if (!ret)
215     __CRTDLL__set_errno(GetLastError());
216   return ret;
217 }
218
219
220 /*********************************************************************
221  *                  realloc        (CRTDLL.444)
222  *
223  * Resize a block of memory allocated with malloc() or realloc().
224  */
225 LPVOID __cdecl CRTDLL_realloc( VOID *ptr, DWORD size )
226 {
227     return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
228 }