Release 20030408.
[wine/gsoc-2012-control.git] / dlls / msvcrt / exit.c
bloba719d1c1147bbc731ebe3dc2bff0ef8e2ebe523d
1 /*
2 * msvcrt.dll exit functions
4 * Copyright 2000 Jon Griffiths
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <stdio.h>
21 #include "msvcrt.h"
23 #include "msvcrt/conio.h"
24 #include "msvcrt/stdlib.h"
25 #include "mtdll.h"
26 #include "winuser.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
32 /* MT */
33 #define LOCK_EXIT _mlock(_EXIT_LOCK1)
34 #define UNLOCK_EXIT _munlock(_EXIT_LOCK1)
36 static _onexit_t *MSVCRT_atexit_table = NULL;
37 static int MSVCRT_atexit_table_size = 0;
38 static int MSVCRT_atexit_registered = 0; /* Points to free slot */
40 static LPCSTR szMsgBoxTitle = "Wine C++ Runtime Library";
42 extern int MSVCRT_app_type;
43 extern char *MSVCRT__pgmptr;
45 /* INTERNAL: call atexit functions */
46 void __MSVCRT__call_atexit(void)
48 /* Note: should only be called with the exit lock held */
49 TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
50 /* Last registered gets executed first */
51 while (MSVCRT_atexit_registered > 0)
53 MSVCRT_atexit_registered--;
54 TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
55 if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
56 (*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
57 TRACE("returned\n");
61 /*********************************************************************
62 * __dllonexit (MSVCRT.@)
64 _onexit_t __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
66 _onexit_t *tmp;
67 int len;
69 TRACE("(%p,%p,%p)\n", func, start, end);
71 if (!start || !*start || !end || !*end)
73 FIXME("bad table\n");
74 return NULL;
77 len = (*end - *start);
79 TRACE("table start %p-%p, %d entries\n", *start, *end, len);
81 if (++len <= 0)
82 return NULL;
84 tmp = (_onexit_t *)MSVCRT_realloc(*start, len * sizeof(tmp));
85 if (!tmp)
86 return NULL;
87 *start = tmp;
88 *end = tmp + len;
89 tmp[len - 1] = func;
90 TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
91 return func;
94 /*********************************************************************
95 * _exit (MSVCRT.@)
97 void MSVCRT__exit(int exitcode)
99 TRACE("(%d)\n", exitcode);
100 ExitProcess(exitcode);
103 /* Print out an error message with an option to debug */
104 static void DoMessageBox(LPCSTR lead, LPCSTR message)
106 MSGBOXPARAMSA msgbox;
107 char text[2048];
108 INT ret;
110 snprintf(text,sizeof(text),"%s\n\nProgram: %s\n%s\n\n"
111 "Press OK to exit the program, or Cancel to start the Wine debugger.\n ",
112 lead, MSVCRT__pgmptr, message);
114 msgbox.cbSize = sizeof(msgbox);
115 msgbox.hwndOwner = GetActiveWindow();
116 msgbox.hInstance = 0;
117 msgbox.lpszText = text;
118 msgbox.lpszCaption = szMsgBoxTitle;
119 msgbox.dwStyle = MB_OKCANCEL|MB_ICONERROR;
120 msgbox.lpszIcon = NULL;
121 msgbox.dwContextHelpId = 0;
122 msgbox.lpfnMsgBoxCallback = NULL;
123 msgbox.dwLanguageId = LANG_NEUTRAL;
125 ret = MessageBoxIndirectA(&msgbox);
126 if (ret == IDCANCEL)
127 DebugBreak();
130 /*********************************************************************
131 * _amsg_exit (MSVCRT.@)
133 void MSVCRT__amsg_exit(int errnum)
135 TRACE("(%d)\n", errnum);
136 /* FIXME: text for the error number. */
137 if (MSVCRT_app_type == 2)
139 char text[32];
140 sprintf(text, "Error: R60%d",errnum);
141 DoMessageBox("Runtime error!", text);
143 else
144 _cprintf("\nruntime error R60%d\n",errnum);
145 MSVCRT__exit(255);
148 /*********************************************************************
149 * abort (MSVCRT.@)
151 void MSVCRT_abort(void)
153 TRACE("()\n");
154 if (MSVCRT_app_type == 2)
156 DoMessageBox("Runtime error!", "abnormal program termination");
158 else
159 _cputs("\nabnormal program termination\n");
160 MSVCRT__exit(3);
163 /*********************************************************************
164 * _assert (MSVCRT.@)
166 void MSVCRT__assert(const char* str, const char* file, unsigned int line)
168 TRACE("(%s,%s,%d)\n",str,file,line);
169 if (MSVCRT_app_type == 2)
171 char text[2048];
172 snprintf(text, sizeof(text), "File: %s\nLine: %d\n\nEpression: \"%s\"", file, line, str);
173 DoMessageBox("Assertion failed!", text);
175 else
176 _cprintf("Assertion failed: %s, file %s, line %d\n\n",str, file, line);
177 MSVCRT__exit(3);
180 /*********************************************************************
181 * _c_exit (MSVCRT.@)
183 void MSVCRT__c_exit(void)
185 TRACE("(void)\n");
186 /* All cleanup is done on DLL detach; Return to caller */
189 /*********************************************************************
190 * _cexit (MSVCRT.@)
192 void MSVCRT__cexit(void)
194 TRACE("(void)\n");
195 /* All cleanup is done on DLL detach; Return to caller */
198 /*********************************************************************
199 * _onexit (MSVCRT.@)
201 _onexit_t _onexit(_onexit_t func)
203 TRACE("(%p)\n",func);
205 if (!func)
206 return NULL;
208 LOCK_EXIT;
209 if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
211 _onexit_t *newtable;
212 TRACE("expanding table\n");
213 newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
214 if (!newtable)
216 TRACE("failed!\n");
217 UNLOCK_EXIT;
218 return NULL;
220 memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size);
221 MSVCRT_atexit_table_size += 32;
222 if (MSVCRT_atexit_table)
223 MSVCRT_free (MSVCRT_atexit_table);
224 MSVCRT_atexit_table = newtable;
226 MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
227 MSVCRT_atexit_registered++;
228 UNLOCK_EXIT;
229 return func;
232 /*********************************************************************
233 * exit (MSVCRT.@)
235 void MSVCRT_exit(int exitcode)
237 TRACE("(%d)\n",exitcode);
238 LOCK_EXIT;
239 __MSVCRT__call_atexit();
240 UNLOCK_EXIT;
241 ExitProcess(exitcode);
244 /*********************************************************************
245 * atexit (MSVCRT.@)
247 int MSVCRT_atexit(void (*func)(void))
249 TRACE("(%p)\n", func);
250 return _onexit((_onexit_t)func) == (_onexit_t)func ? 0 : -1;
254 /*********************************************************************
255 * _purecall (MSVCRT.@)
257 void _purecall(void)
259 TRACE("(void)\n");
260 MSVCRT__amsg_exit( 25 );