9253e76b5072f0d0d4183615b3e25802084fb30b
[reactos.git] / reactos / ntoskrnl / ke / i386 / usertrap.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * PROJECT: ReactOS kernel
21 * FILE: ntoskrnl/ke/i386/usertrap.c
22 * PURPOSE: Handling usermode exceptions.
23 * PROGRAMMER: David Welch (welch@cwcom.net)
24 * REVISION HISTORY:
25 * 18/11/01: Split from ntoskrnl/ke/i386/exp.c
26 */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31 #include <roscfg.h>
32 #include <internal/ntoskrnl.h>
33 #include <internal/ke.h>
34 #include <internal/i386/segment.h>
35 #include <internal/i386/mm.h>
36 #include <internal/module.h>
37 #include <internal/mm.h>
38 #include <internal/ps.h>
39 #include <internal/trap.h>
40 #include <ntdll/ldr.h>
41 #include <internal/safe.h>
42
43 #define NDEBUG
44 #include <internal/debug.h>
45
46 /* FUNCTIONS ****************************************************************/
47
48 BOOLEAN
49 print_user_address(PVOID address)
50 {
51 PLIST_ENTRY current_entry;
52 PLDR_MODULE current;
53 PEPROCESS CurrentProcess;
54 PPEB Peb = NULL;
55 ULONG_PTR RelativeAddress;
56 PPEB_LDR_DATA Ldr;
57 NTSTATUS Status;
58
59 CurrentProcess = PsGetCurrentProcess();
60 if (NULL != CurrentProcess)
61 {
62 Peb = CurrentProcess->Peb;
63 }
64
65 if (NULL == Peb)
66 {
67 DbgPrint("<%x>", address);
68 return(TRUE);
69 }
70
71 Status = MmSafeCopyFromUser(&Ldr, &Peb->Ldr, sizeof(PPEB_LDR_DATA));
72 if (!NT_SUCCESS(Status))
73 {
74 DbgPrint("<%x>", address);
75 return(TRUE);
76 }
77 current_entry = Ldr->InLoadOrderModuleList.Flink;
78
79 while (current_entry != &Ldr->InLoadOrderModuleList &&
80 current_entry != NULL)
81 {
82 current =
83 CONTAINING_RECORD(current_entry, LDR_MODULE, InLoadOrderModuleList);
84
85 if (address >= (PVOID)current->BaseAddress &&
86 address < (PVOID)(current->BaseAddress + current->SizeOfImage))
87 {
88 RelativeAddress =
89 (ULONG_PTR) address - (ULONG_PTR)current->BaseAddress;
90 DbgPrint("<%wZ: %x>", &current->BaseDllName, RelativeAddress);
91 return(TRUE);
92 }
93
94 current_entry = current_entry->Flink;
95 }
96 return(FALSE);
97 }
98
99 ULONG
100 KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
101 {
102 EXCEPTION_RECORD Er;
103
104 if (ExceptionNr == 0)
105 {
106 Er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
107 }
108 else if (ExceptionNr == 1)
109 {
110 Er.ExceptionCode = STATUS_SINGLE_STEP;
111 }
112 else if (ExceptionNr == 3)
113 {
114 Er.ExceptionCode = STATUS_BREAKPOINT;
115 }
116 else if (ExceptionNr == 4)
117 {
118 Er.ExceptionCode = STATUS_INTEGER_OVERFLOW;
119 }
120 else if (ExceptionNr == 5)
121 {
122 Er.ExceptionCode = STATUS_ARRAY_BOUNDS_EXCEEDED;
123 }
124 else if (ExceptionNr == 6)
125 {
126 Er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
127 }
128 else
129 {
130 Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
131 }
132 Er.ExceptionFlags = 0;
133 Er.ExceptionRecord = NULL;
134 Er.ExceptionAddress = (PVOID)Tf->Eip;
135 if (ExceptionNr == 14)
136 {
137 Er.NumberParameters = 2;
138 Er.ExceptionInformation[0] = Tf->ErrorCode & 0x1;
139 Er.ExceptionInformation[1] = (ULONG)Cr2;
140 }
141 else
142 {
143 Er.NumberParameters = 0;
144 }
145
146
147 Er.ExceptionFlags = ((NTSTATUS) STATUS_SINGLE_STEP == (NTSTATUS) Er.ExceptionCode ||
148 (NTSTATUS) STATUS_BREAKPOINT == (NTSTATUS) Er.ExceptionCode) ?
149 EXCEPTION_NONCONTINUABLE : 0;
150
151 KiDispatchException(&Er, 0, Tf, UserMode, TRUE);
152 return(0);
153 }