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