update for HEAD-2003050101
[reactos.git] / 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 = (STATUS_SINGLE_STEP == (NTSTATUS) Er.ExceptionCode || STATUS_BREAKPOINT == (NTSTATUS) Er.ExceptionCode ?
148                        0 : EXCEPTION_NONCONTINUABLE);
149
150   KiDispatchException(&Er, 0, Tf, UserMode, TRUE);
151   return(0);
152 }