branch update for HEAD-2003021201
[reactos.git] / lib / kernel32 / except / except.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/misc/except.c
6  * PURPOSE:         Exception functions
7  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
8  *                  modified from WINE [ Onno Hovers, (onno@stack.urc.tue.nl) ]
9  * UPDATE HISTORY:
10  *                  Created 01/11/98
11  */
12
13 #include <k32.h>
14
15
16 typedef LONG (STDCALL *LPTOP_LEVEL_EXCEPTION_FILTER)(
17         struct _EXCEPTION_POINTERS *ExceptionInfo
18         );
19
20 UINT GlobalErrMode;
21 LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter;
22
23 UINT GetErrorMode(void);
24
25
26
27 UINT GetErrorMode(void)
28 {
29         return GlobalErrMode;
30 }
31
32 UINT 
33 STDCALL
34 SetErrorMode(  UINT uMode  )
35 {
36         UINT OldErrMode = GetErrorMode();
37         GlobalErrMode = uMode;
38         return OldErrMode;
39 }
40
41 LPTOP_LEVEL_EXCEPTION_FILTER
42 STDCALL
43 SetUnhandledExceptionFilter(
44     LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
45     )
46 {
47     LPTOP_LEVEL_EXCEPTION_FILTER OldTopLevelExceptionFilter =
48                                          GlobalTopLevelExceptionFilter;
49     lpTopLevelExceptionFilter = GlobalTopLevelExceptionFilter;
50     return OldTopLevelExceptionFilter;
51 }
52
53
54 LONG
55 STDCALL
56 UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
57 {
58         DWORD   dbgRet;
59         HANDLE DebugPort;
60         NTSTATUS errCode;
61
62         if(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) {
63                 // might check read only resource
64                 // Is there a debugger running ?
65                 errCode = NtQueryInformationProcess(NtCurrentProcess(),ProcessDebugPort,&DebugPort,sizeof(HANDLE),NULL);
66                 if ( !NT_SUCCESS(errCode) ) {
67                         SetLastErrorByStatus(errCode);
68                         return EXCEPTION_EXECUTE_HANDLER;
69                 }
70                 if ( DebugPort ) {
71                         //return EXCEPTION_CONTINUE_SEARCH;
72                 }
73                 if(GlobalTopLevelExceptionFilter != NULL) {
74                 dbgRet = GlobalTopLevelExceptionFilter(ExceptionInfo);
75                 if(dbgRet == EXCEPTION_EXECUTE_HANDLER) 
76                         return EXCEPTION_EXECUTE_HANDLER;
77                 else if(dbgRet == EXCEPTION_CONTINUE_EXECUTION) 
78                         return EXCEPTION_CONTINUE_EXECUTION;
79                 }
80
81         }
82
83         //if ( GetErrorMode() & SEM_NOGPFAULTERRORBOX == SEM_NOGPFAULTERRORBOX ) {
84                 // produce a stack trace or pop a message
85                 //sprintf( message, "Unhandled exception 0x%08lx at address 0x%08lx.",
86                 //      ExceptionInfo->ExceptionRecord->ExceptionCode,
87                 //      (DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress );
88                 //MessageBoxA( 0, message, "Error", MB_OK | MB_ICONHAND );
89         
90         //}
91         // Returning EXCEPTION_EXECUTE_HANDLER means that the code in 
92         // the __execept block will be executed. Normally this will end up in a
93         // Terminate process.
94
95         return EXCEPTION_EXECUTE_HANDLER;
96         
97 }
98
99 VOID
100 STDCALL
101 RaiseException (
102         DWORD           dwExceptionCode,
103         DWORD           dwExceptionFlags,
104         DWORD           nNumberOfArguments,
105         CONST DWORD     * lpArguments           OPTIONAL
106         )
107 {
108         EXCEPTION_RECORD ExceptionRecord;
109
110         /* Do NOT normalize dwExceptionCode: it will be done in
111          * NTDLL.RtlRaiseException().
112          */
113         ExceptionRecord.ExceptionCode = dwExceptionCode;
114         ExceptionRecord.ExceptionRecord = NULL;
115         ExceptionRecord.ExceptionAddress = (PVOID) RaiseException;
116         /*
117          * Normalize dwExceptionFlags.
118          */
119         ExceptionRecord.ExceptionFlags = (dwExceptionFlags & EXCEPTION_NONCONTINUABLE);
120         /*
121          * Normalize nNumberOfArguments.
122          */
123         if (EXCEPTION_MAXIMUM_PARAMETERS < nNumberOfArguments)
124         {
125                 nNumberOfArguments = EXCEPTION_MAXIMUM_PARAMETERS;
126         }
127         /*
128          * If the exception has no argument,
129          * or it is a non-continuable exception,
130          * ignore nNumberOfArguments and lpArguments.
131          */
132         if ((NULL == lpArguments) || ExceptionRecord.ExceptionFlags)
133         {
134                 ExceptionRecord.NumberParameters = 0;
135         }
136         else
137         {
138                 ExceptionRecord.NumberParameters = nNumberOfArguments;
139                 for (   nNumberOfArguments = 0;
140                         (nNumberOfArguments < ExceptionRecord.NumberParameters); 
141                         nNumberOfArguments ++
142                         )
143                 {
144                         ExceptionRecord.ExceptionInformation [nNumberOfArguments]
145                                 = *lpArguments ++;
146                 }
147         }
148         RtlRaiseException (& ExceptionRecord);
149 }
150
151 /* EOF */