~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ntdll/exception.c

Version: ~ [ wine-1.5.31 ] ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * NT exception handling routines
  3  *
  4  * Copyright 1999 Turchanov Sergey
  5  * Copyright 1999 Alexandre Julliard
  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  */
 21 
 22 #include "config.h"
 23 #include "wine/port.h"
 24 
 25 #include <assert.h>
 26 #include <errno.h>
 27 #include <signal.h>
 28 #include <stdarg.h>
 29 
 30 #include "ntstatus.h"
 31 #define WIN32_NO_STATUS
 32 #include "windef.h"
 33 #include "winternl.h"
 34 #include "wine/exception.h"
 35 #include "wine/server.h"
 36 #include "wine/list.h"
 37 #include "wine/debug.h"
 38 #include "excpt.h"
 39 #include "ntdll_misc.h"
 40 
 41 WINE_DEFAULT_DEBUG_CHANNEL(seh);
 42 
 43 typedef struct
 44 {
 45     struct list                 entry;
 46     PVECTORED_EXCEPTION_HANDLER func;
 47     ULONG                       count;
 48 } VECTORED_HANDLER;
 49 
 50 static struct list vectored_handlers = LIST_INIT(vectored_handlers);
 51 
 52 static RTL_CRITICAL_SECTION vectored_handlers_section;
 53 static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
 54 {
 55     0, 0, &vectored_handlers_section,
 56     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
 57       0, 0, { (DWORD_PTR)(__FILE__ ": vectored_handlers_section") }
 58 };
 59 static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0, 0, 0, 0 };
 60 
 61 /**********************************************************************
 62  *           wait_suspend
 63  *
 64  * Wait until the thread is no longer suspended.
 65  */
 66 void wait_suspend( CONTEXT *context )
 67 {
 68     LARGE_INTEGER timeout;
 69     int saved_errno = errno;
 70     context_t server_context;
 71 
 72     context_to_server( &server_context, context );
 73 
 74     /* store the context we got at suspend time */
 75     SERVER_START_REQ( set_suspend_context )
 76     {
 77         wine_server_add_data( req, &server_context, sizeof(server_context) );
 78         wine_server_call( req );
 79     }
 80     SERVER_END_REQ;
 81 
 82     /* wait with 0 timeout, will only return once the thread is no longer suspended */
 83     timeout.QuadPart = 0;
 84     NTDLL_wait_for_multiple_objects( 0, NULL, SELECT_INTERRUPTIBLE, &timeout, 0 );
 85 
 86     /* retrieve the new context */
 87     SERVER_START_REQ( get_suspend_context )
 88     {
 89         wine_server_set_reply( req, &server_context, sizeof(server_context) );
 90         wine_server_call( req );
 91     }
 92     SERVER_END_REQ;
 93 
 94     context_from_server( context, &server_context );
 95     errno = saved_errno;
 96 }
 97 
 98 
 99 /**********************************************************************
100  *           send_debug_event
101  *
102  * Send an EXCEPTION_DEBUG_EVENT event to the debugger.
103  */
104 NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context )
105 {
106     NTSTATUS ret;
107     DWORD i;
108     HANDLE handle = 0;
109     client_ptr_t params[EXCEPTION_MAXIMUM_PARAMETERS];
110     context_t server_context;
111 
112     if (!NtCurrentTeb()->Peb->BeingDebugged) return 0;  /* no debugger present */
113 
114     for (i = 0; i < min( rec->NumberParameters, EXCEPTION_MAXIMUM_PARAMETERS ); i++)
115         params[i] = rec->ExceptionInformation[i];
116 
117     context_to_server( &server_context, context );
118 
119     SERVER_START_REQ( queue_exception_event )
120     {
121         req->first   = first_chance;
122         req->code    = rec->ExceptionCode;
123         req->flags   = rec->ExceptionFlags;
124         req->record  = wine_server_client_ptr( rec->ExceptionRecord );
125         req->address = wine_server_client_ptr( rec->ExceptionAddress );
126         req->len     = i * sizeof(params[0]);
127         wine_server_add_data( req, params, req->len );
128         wine_server_add_data( req, &server_context, sizeof(server_context) );
129         if (!wine_server_call( req )) handle = wine_server_ptr_handle( reply->handle );
130     }
131     SERVER_END_REQ;
132     if (!handle) return 0;
133 
134     NTDLL_wait_for_multiple_objects( 1, &handle, SELECT_INTERRUPTIBLE, NULL, 0 );
135 
136     SERVER_START_REQ( get_exception_status )
137     {
138         req->handle = wine_server_obj_handle( handle );
139         wine_server_set_reply( req, &server_context, sizeof(server_context) );
140         ret = wine_server_call( req );
141     }
142     SERVER_END_REQ;
143     if (ret >= 0) context_from_server( context, &server_context );
144     return ret;
145 }
146 
147 
148 /**********************************************************************
149  *           call_vectored_handlers
150  *
151  * Call the vectored handlers chain.
152  */
153 LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
154 {
155     struct list *ptr;
156     LONG ret = EXCEPTION_CONTINUE_SEARCH;
157     EXCEPTION_POINTERS except_ptrs;
158     PVECTORED_EXCEPTION_HANDLER func;
159     VECTORED_HANDLER *handler, *to_free = NULL;
160 
161     except_ptrs.ExceptionRecord = rec;
162     except_ptrs.ContextRecord = context;
163 
164     RtlEnterCriticalSection( &vectored_handlers_section );
165     ptr = list_head( &vectored_handlers );
166     while (ptr)
167     {
168         handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
169         handler->count++;
170         func = RtlDecodePointer( handler->func );
171         RtlLeaveCriticalSection( &vectored_handlers_section );
172         RtlFreeHeap( GetProcessHeap(), 0, to_free );
173         to_free = NULL;
174 
175         TRACE( "calling handler at %p code=%x flags=%x\n",
176                func, rec->ExceptionCode, rec->ExceptionFlags );
177         ret = func( &except_ptrs );
178         TRACE( "handler at %p returned %x\n", func, ret );
179 
180         RtlEnterCriticalSection( &vectored_handlers_section );
181         ptr = list_next( &vectored_handlers, ptr );
182         if (!--handler->count)  /* removed during execution */
183         {
184             list_remove( &handler->entry );
185             to_free = handler;
186         }
187         if (ret == EXCEPTION_CONTINUE_EXECUTION) break;
188     }
189     RtlLeaveCriticalSection( &vectored_handlers_section );
190     RtlFreeHeap( GetProcessHeap(), 0, to_free );
191     return ret;
192 }
193 
194 
195 /*******************************************************************
196  *              raise_status
197  *
198  * Implementation of RtlRaiseStatus with a specific exception record.
199  */
200 void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec )
201 {
202     EXCEPTION_RECORD ExceptionRec;
203 
204     ExceptionRec.ExceptionCode    = status;
205     ExceptionRec.ExceptionFlags   = EH_NONCONTINUABLE;
206     ExceptionRec.ExceptionRecord  = rec;
207     ExceptionRec.NumberParameters = 0;
208     for (;;) RtlRaiseException( &ExceptionRec );  /* never returns */
209 }
210 
211 
212 /***********************************************************************
213  *            RtlRaiseStatus  (NTDLL.@)
214  *
215  * Raise an exception with ExceptionCode = status
216  */
217 void WINAPI RtlRaiseStatus( NTSTATUS status )
218 {
219     raise_status( status, NULL );
220 }
221 
222 
223 /*******************************************************************
224  *         RtlAddVectoredExceptionHandler   (NTDLL.@)
225  */
226 PVOID WINAPI RtlAddVectoredExceptionHandler( ULONG first, PVECTORED_EXCEPTION_HANDLER func )
227 {
228     VECTORED_HANDLER *handler = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*handler) );
229     if (handler)
230     {
231         handler->func = RtlEncodePointer( func );
232         handler->count = 1;
233         RtlEnterCriticalSection( &vectored_handlers_section );
234         if (first) list_add_head( &vectored_handlers, &handler->entry );
235         else list_add_tail( &vectored_handlers, &handler->entry );
236         RtlLeaveCriticalSection( &vectored_handlers_section );
237     }
238     return handler;
239 }
240 
241 
242 /*******************************************************************
243  *         RtlRemoveVectoredExceptionHandler   (NTDLL.@)
244  */
245 ULONG WINAPI RtlRemoveVectoredExceptionHandler( PVOID handler )
246 {
247     struct list *ptr;
248     ULONG ret = FALSE;
249 
250     RtlEnterCriticalSection( &vectored_handlers_section );
251     LIST_FOR_EACH( ptr, &vectored_handlers )
252     {
253         VECTORED_HANDLER *curr_handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
254         if (curr_handler == handler)
255         {
256             if (!--curr_handler->count) list_remove( ptr );
257             else handler = NULL;  /* don't free it yet */
258             ret = TRUE;
259             break;
260         }
261     }
262     RtlLeaveCriticalSection( &vectored_handlers_section );
263     if (ret) RtlFreeHeap( GetProcessHeap(), 0, handler );
264     return ret;
265 }
266 
267 
268 /*************************************************************
269  *            __wine_spec_unimplemented_stub
270  *
271  * ntdll-specific implementation to avoid depending on kernel functions.
272  * Can be removed once ntdll.spec no longer contains stubs.
273  */
274 void __wine_spec_unimplemented_stub( const char *module, const char *function )
275 {
276     EXCEPTION_RECORD record;
277 
278     record.ExceptionCode    = EXCEPTION_WINE_STUB;
279     record.ExceptionFlags   = EH_NONCONTINUABLE;
280     record.ExceptionRecord  = NULL;
281     record.ExceptionAddress = __wine_spec_unimplemented_stub;
282     record.NumberParameters = 2;
283     record.ExceptionInformation[0] = (ULONG_PTR)module;
284     record.ExceptionInformation[1] = (ULONG_PTR)function;
285     for (;;) RtlRaiseException( &record );
286 }
287 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.