update for HEAD-2003091401
[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
33 /*
34  * @implemented
35  */
36 UINT 
37 STDCALL
38 SetErrorMode(  UINT uMode  )
39 {
40         UINT OldErrMode = GetErrorMode();
41         GlobalErrMode = uMode;
42         return OldErrMode;
43 }
44
45
46 /*
47  * @implemented
48  */
49 LPTOP_LEVEL_EXCEPTION_FILTER
50 STDCALL
51 SetUnhandledExceptionFilter(
52     LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
53     )
54 {
55     LPTOP_LEVEL_EXCEPTION_FILTER OldTopLevelExceptionFilter =
56                                          GlobalTopLevelExceptionFilter;
57     GlobalTopLevelExceptionFilter = lpTopLevelExceptionFilter;
58     return OldTopLevelExceptionFilter;
59 }
60
61
62 /*
63  * @unimplemented
64  */
65 LONG
66 STDCALL
67 UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
68 {
69         DWORD   dbgRet;
70         HANDLE DebugPort;
71         NTSTATUS errCode;
72
73         if(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) {
74                 // might check read only resource
75                 // Is there a debugger running ?
76                 errCode = NtQueryInformationProcess(NtCurrentProcess(),ProcessDebugPort,&DebugPort,sizeof(HANDLE),NULL);
77                 if ( !NT_SUCCESS(errCode) ) {
78                         SetLastErrorByStatus(errCode);
79                         return EXCEPTION_EXECUTE_HANDLER;
80                 }
81                 if ( DebugPort ) {
82                         //return EXCEPTION_CONTINUE_SEARCH;
83                 }
84                 if(GlobalTopLevelExceptionFilter != NULL) {
85                 dbgRet = GlobalTopLevelExceptionFilter(ExceptionInfo);
86                 if(dbgRet == EXCEPTION_EXECUTE_HANDLER) 
87                         return EXCEPTION_EXECUTE_HANDLER;
88                 else if(dbgRet == EXCEPTION_CONTINUE_EXECUTION) 
89                         return EXCEPTION_CONTINUE_EXECUTION;
90                 }
91
92         }
93
94         //if ( GetErrorMode() & SEM_NOGPFAULTERRORBOX == SEM_NOGPFAULTERRORBOX ) {
95                 // produce a stack trace or pop a message
96                 //sprintf( message, "Unhandled exception 0x%08lx at address 0x%08lx.",
97                 //      ExceptionInfo->ExceptionRecord->ExceptionCode,
98                 //      (DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress );
99                 //MessageBoxA( 0, message, "Error", MB_OK | MB_ICONHAND );
100         
101         //}
102         // Returning EXCEPTION_EXECUTE_HANDLER means that the code in 
103         // the __execept block will be executed. Normally this will end up in a
104         // Terminate process.
105
106         return EXCEPTION_EXECUTE_HANDLER;
107         
108 }
109
110
111 /*
112  * @implemented
113  */
114 VOID
115 STDCALL
116 RaiseException (
117         DWORD           dwExceptionCode,
118         DWORD           dwExceptionFlags,
119         DWORD           nNumberOfArguments,
120         CONST DWORD     * lpArguments           OPTIONAL
121         )
122 {
123         EXCEPTION_RECORD ExceptionRecord;
124
125         /* Do NOT normalize dwExceptionCode: it will be done in
126          * NTDLL.RtlRaiseException().
127          */
128         ExceptionRecord.ExceptionCode = dwExceptionCode;
129         ExceptionRecord.ExceptionRecord = NULL;
130         ExceptionRecord.ExceptionAddress = (PVOID) RaiseException;
131         /*
132          * Normalize dwExceptionFlags.
133          */
134         ExceptionRecord.ExceptionFlags = (dwExceptionFlags & EXCEPTION_NONCONTINUABLE);
135         /*
136          * Normalize nNumberOfArguments.
137          */
138         if (EXCEPTION_MAXIMUM_PARAMETERS < nNumberOfArguments)
139         {
140                 nNumberOfArguments = EXCEPTION_MAXIMUM_PARAMETERS;
141         }
142         /*
143          * If the exception has no argument,
144          * or it is a non-continuable exception,
145          * ignore nNumberOfArguments and lpArguments.
146          */
147         if ((NULL == lpArguments) || ExceptionRecord.ExceptionFlags)
148         {
149                 ExceptionRecord.NumberParameters = 0;
150         }
151         else
152         {
153                 ExceptionRecord.NumberParameters = nNumberOfArguments;
154                 for (   nNumberOfArguments = 0;
155                         (nNumberOfArguments < ExceptionRecord.NumberParameters); 
156                         nNumberOfArguments ++
157                         )
158                 {
159                         ExceptionRecord.ExceptionInformation [nNumberOfArguments]
160                                 = *lpArguments ++;
161                 }
162         }
163         RtlRaiseException (& ExceptionRecord);
164 }
165
166 /* EOF */