update for HEAD-2003091401
[reactos.git] / lib / ntdll / rtl / exception.c
1 /* $Id$
2  *
3  * COPYRIGHT:         See COPYING in the top level directory
4  * PROJECT:           ReactOS kernel
5  * PURPOSE:           User-mode exception support
6  * FILE:              lib/ntdll/rtl/exception.c
7  * PROGRAMERS:        David Welch <welch@cwcom.net>
8  *                    Skywing <skywing@valhallalegends.com>
9  * UPDATES:           Skywing, 09/11/2003: Implemented RtlRaiseException and
10  *                    KiUserRaiseExceptionDispatcher.
11  */
12
13 /* INCLUDES *****************************************************************/
14
15 #include <ddk/ntddk.h>
16 #include <windows.h>
17 #include <string.h>
18 #include <napi/teb.h>
19
20 #define NDEBUG
21 #include <debug.h>
22
23 /* FUNCTIONS ***************************************************************/
24
25 VOID STDCALL
26 RtlBaseProcessStart(PTHREAD_START_ROUTINE StartAddress,
27   PVOID Parameter);
28
29 __declspec(dllexport)
30 PRTL_BASE_PROCESS_START_ROUTINE RtlBaseProcessStartRoutine = RtlBaseProcessStart;
31
32 ULONG
33 RtlpDispatchException(IN PEXCEPTION_RECORD  ExceptionRecord,
34         IN PCONTEXT  Context);
35
36 VOID STDCALL
37 KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,
38                           PCONTEXT Context)
39 {
40   EXCEPTION_RECORD NestedExceptionRecord;
41   NTSTATUS Status;
42
43   DPRINT("KiUserExceptionDispatcher()\n");
44
45   if (RtlpDispatchException(ExceptionRecord, Context) != ExceptionContinueExecution)
46     {
47       Status = NtContinue(Context, FALSE);
48     }
49   else
50     {
51       Status = NtRaiseException(ExceptionRecord, Context, FALSE);
52     }
53
54   NestedExceptionRecord.ExceptionCode = Status;
55   NestedExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
56   NestedExceptionRecord.ExceptionRecord = ExceptionRecord;
57   NestedExceptionRecord.NumberParameters = Status;
58
59   RtlRaiseException(&NestedExceptionRecord);
60 }
61
62 /* implemented in except.s */
63 VOID
64 RtlpCaptureContext(PCONTEXT Context);
65
66 /*
67  * @implemented
68  */
69 VOID STDCALL
70 RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
71 {
72   CONTEXT Context;
73   NTSTATUS Status;
74
75   RtlpCaptureContext(&Context);
76
77   ExceptionRecord->ExceptionAddress = (PVOID)(*(((PULONG)Context.Ebp)+1));
78   Context.ContextFlags = CONTEXT_FULL;
79
80   Status = ZwRaiseException(ExceptionRecord, &Context, TRUE);
81   RtlRaiseException(ExceptionRecord);
82   RtlRaiseStatus(Status); /* If we get to this point, something is seriously wrong... */
83 }
84
85 /*
86  * @implemented
87  */
88 VOID STDCALL
89 KiRaiseUserExceptionDispatcher(VOID)
90 {
91   EXCEPTION_RECORD ExceptionRecord;
92
93   ExceptionRecord.ExceptionCode = ((PTEB)NtCurrentTeb())->ExceptionCode;
94   ExceptionRecord.ExceptionFlags = 0;
95   ExceptionRecord.ExceptionRecord = NULL;
96   ExceptionRecord.NumberParameters = 0;
97
98   RtlRaiseException(&ExceptionRecord);
99 }
100
101 VOID STDCALL
102 RtlBaseProcessStart(PTHREAD_START_ROUTINE StartAddress,
103   PVOID Parameter)
104 {
105   NTSTATUS ExitStatus = STATUS_SUCCESS;
106
107   ExitStatus = (NTSTATUS) (StartAddress)(Parameter);
108
109   NtTerminateProcess(NtCurrentProcess(), ExitStatus);
110 }
111
112 /* EOF */