Change __darwin__ to __APPLE__.
[wine] / memory / heap.c
1 /*
2  * Win32 heap functions
3  *
4  * Copyright 1996 Alexandre Julliard
5  * Copyright 1998 Ulrich Weigand
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "winnt.h"
32 #include "winternl.h"
33 #include "wine/unicode.h"
34 #include "thread.h"
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(heap);
38
39 /* address where we try to map the system heap */
40 #define SYSTEM_HEAP_BASE  ((void*)0x65430000)
41 #define SYSTEM_HEAP_SIZE  0x100000   /* Default heap size = 1Mb */
42
43 static HANDLE systemHeap;   /* globally shared heap */
44
45 /***********************************************************************
46  *           HEAP_CreateSystemHeap
47  *
48  * Create the system heap.
49  */
50 inline static HANDLE HEAP_CreateSystemHeap(void)
51 {
52     int created;
53     void *base;
54     HANDLE map, event;
55     UNICODE_STRING event_name;
56     OBJECT_ATTRIBUTES event_attr;
57
58     if (!(map = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE,
59                                     0, SYSTEM_HEAP_SIZE, "__SystemHeap" ))) return 0;
60     created = (GetLastError() != ERROR_ALREADY_EXISTS);
61
62     if (!(base = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, SYSTEM_HEAP_BASE )))
63     {
64         /* pre-defined address not available */
65         ERR( "system heap base address %p not available\n", SYSTEM_HEAP_BASE );
66         return 0;
67     }
68
69     /* create the system heap event */
70     RtlCreateUnicodeStringFromAsciiz( &event_name, "__SystemHeapEvent" );
71     event_attr.Length = sizeof(event_attr);
72     event_attr.RootDirectory = 0;
73     event_attr.ObjectName = &event_name;
74     event_attr.Attributes = 0;
75     event_attr.SecurityDescriptor = NULL;
76     event_attr.SecurityQualityOfService = NULL;
77     NtCreateEvent( &event, EVENT_ALL_ACCESS, &event_attr, TRUE, FALSE );
78
79     if (created)  /* newly created heap */
80     {
81         systemHeap = RtlCreateHeap( HEAP_SHARED, base, SYSTEM_HEAP_SIZE,
82                                     SYSTEM_HEAP_SIZE, NULL, NULL );
83         NtSetEvent( event, NULL );
84     }
85     else
86     {
87         /* wait for the heap to be initialized */
88         WaitForSingleObject( event, INFINITE );
89         systemHeap = (HANDLE)base;
90     }
91     CloseHandle( map );
92     return systemHeap;
93 }
94
95
96 /***********************************************************************
97  *           HeapCreate   (KERNEL32.@)
98  * RETURNS
99  *      Handle of heap: Success
100  *      NULL: Failure
101  */
102 HANDLE WINAPI HeapCreate(
103                 DWORD flags,       /* [in] Heap allocation flag */
104                 SIZE_T initialSize, /* [in] Initial heap size */
105                 SIZE_T maxSize      /* [in] Maximum heap size */
106 ) {
107     HANDLE ret;
108
109     if ( flags & HEAP_SHARED )
110     {
111         if (!systemHeap) HEAP_CreateSystemHeap();
112         else WARN( "Shared Heap requested, returning system heap.\n" );
113         ret = systemHeap;
114     }
115     else
116     {
117         ret = RtlCreateHeap( flags, NULL, maxSize, initialSize, NULL, NULL );
118         if (!ret) SetLastError( ERROR_NOT_ENOUGH_MEMORY );
119     }
120     return ret;
121 }
122
123 /***********************************************************************
124  *           HeapDestroy   (KERNEL32.@)
125  * RETURNS
126  *      TRUE: Success
127  *      FALSE: Failure
128  */
129 BOOL WINAPI HeapDestroy( HANDLE heap /* [in] Handle of heap */ )
130 {
131     if (heap == systemHeap)
132     {
133         WARN( "attempt to destroy system heap, returning TRUE!\n" );
134         return TRUE;
135     }
136     if (!RtlDestroyHeap( heap )) return TRUE;
137     SetLastError( ERROR_INVALID_HANDLE );
138     return FALSE;
139 }
140
141
142 /***********************************************************************
143  *           HeapCompact   (KERNEL32.@)
144  */
145 SIZE_T WINAPI HeapCompact( HANDLE heap, DWORD flags )
146 {
147     return RtlCompactHeap( heap, flags );
148 }
149
150
151 /***********************************************************************
152  *           HeapLock   (KERNEL32.@)
153  * Attempts to acquire the critical section object for a specified heap.
154  *
155  * RETURNS
156  *      TRUE: Success
157  *      FALSE: Failure
158  */
159 BOOL WINAPI HeapLock(
160               HANDLE heap /* [in] Handle of heap to lock for exclusive access */
161 ) {
162     return RtlLockHeap( heap );
163 }
164
165
166 /***********************************************************************
167  *           HeapUnlock   (KERNEL32.@)
168  * Releases ownership of the critical section object.
169  *
170  * RETURNS
171  *      TRUE: Success
172  *      FALSE: Failure
173  */
174 BOOL WINAPI HeapUnlock(
175               HANDLE heap /* [in] Handle to the heap to unlock */
176 ) {
177     return RtlUnlockHeap( heap );
178 }
179
180
181 /***********************************************************************
182  *           HeapValidate   (KERNEL32.@)
183  * Validates a specified heap.
184  *
185  * NOTES
186  *      Flags is ignored.
187  *
188  * RETURNS
189  *      TRUE: Success
190  *      FALSE: Failure
191  */
192 BOOL WINAPI HeapValidate(
193               HANDLE heap, /* [in] Handle to the heap */
194               DWORD flags,   /* [in] Bit flags that control access during operation */
195               LPCVOID block  /* [in] Optional pointer to memory block to validate */
196 ) {
197     return RtlValidateHeap( heap, flags, block );
198 }
199
200
201 /***********************************************************************
202  *           HeapWalk   (KERNEL32.@)
203  * Enumerates the memory blocks in a specified heap.
204  *
205  * TODO
206  *   - handling of PROCESS_HEAP_ENTRY_MOVEABLE and
207  *     PROCESS_HEAP_ENTRY_DDESHARE (needs heap.c support)
208  *
209  * RETURNS
210  *      TRUE: Success
211  *      FALSE: Failure
212  */
213 BOOL WINAPI HeapWalk(
214               HANDLE heap,               /* [in]  Handle to heap to enumerate */
215               LPPROCESS_HEAP_ENTRY entry /* [out] Pointer to structure of enumeration info */
216 ) {
217     NTSTATUS ret = RtlWalkHeap( heap, entry );
218     if (ret) SetLastError( RtlNtStatusToDosError(ret) );
219     return !ret;
220 }
221
222
223 /***********************************************************************
224  *           GetProcessHeap    (KERNEL32.@)
225  */
226 HANDLE WINAPI GetProcessHeap(void)
227 {
228     return NtCurrentTeb()->Peb->ProcessHeap;
229 }
230
231
232 /***********************************************************************
233  *           GetProcessHeaps    (KERNEL32.@)
234  */
235 DWORD WINAPI GetProcessHeaps( DWORD count, HANDLE *heaps )
236 {
237     return RtlGetProcessHeaps( count, heaps );
238 }
239
240
241
242 /* FIXME: these functions are needed for dlls that aren't properly separated yet */
243
244 LPVOID WINAPI HeapAlloc( HANDLE heap, DWORD flags, SIZE_T size )
245 {
246     return RtlAllocateHeap( heap, flags, size );
247 }
248
249 BOOL WINAPI HeapFree( HANDLE heap, DWORD flags, LPVOID ptr )
250 {
251     return RtlFreeHeap( heap, flags, ptr );
252 }
253
254 LPVOID WINAPI HeapReAlloc( HANDLE heap, DWORD flags, LPVOID ptr, SIZE_T size )
255 {
256     return RtlReAllocateHeap( heap, flags, ptr, size );
257 }
258
259 SIZE_T WINAPI HeapSize( HANDLE heap, DWORD flags, LPVOID ptr )
260 {
261     return RtlSizeHeap( heap, flags, ptr );
262 }