[KMTESTS:RTL]
[reactos.git] / rostests / kmtests / rtl / RtlException.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Exception test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #define KMT_EMULATE_KERNEL
9 #include <kmt_test.h>
10
11 static
12 VOID
13 PossiblyRaise(
14 _In_ BOOLEAN Raise)
15 {
16 if (Raise)
17 {
18 ExRaiseStatus(STATUS_ASSERTION_FAILURE);
19 }
20 }
21
22 static
23 VOID
24 InnerFunction(
25 _Inout_ PULONG State,
26 _In_ BOOLEAN Raise)
27 {
28 _SEH2_VOLATILE INT Var = 123;
29 static _SEH2_VOLATILE INT *AddressOfVar;
30
31 AddressOfVar = &Var;
32 ok_eq_ulong(*State, 1);
33 _SEH2_TRY
34 {
35 *State = 2;
36 PossiblyRaise(Raise);
37 ok_eq_ulong(*State, 2);
38 *State = 3;
39 }
40 _SEH2_FINALLY
41 {
42 ok_eq_int(Var, 123);
43 ok_eq_pointer(&Var, AddressOfVar);
44 if (Raise)
45 ok_eq_ulong(*State, 2);
46 else
47 ok_eq_ulong(*State, 3);
48 *State = 4;
49 }
50 _SEH2_END;
51
52 ok_eq_int(Var, 123);
53 ok_eq_pointer(&Var, AddressOfVar);
54 ok_eq_ulong(*State, 4);
55 *State = 5;
56 }
57
58 static
59 VOID
60 OuterFunction(
61 _Inout_ PULONG State,
62 _In_ BOOLEAN Raise)
63 {
64 _SEH2_VOLATILE INT Var = 456;
65 static _SEH2_VOLATILE INT *AddressOfVar;
66
67 AddressOfVar = &Var;
68 ok_eq_ulong(*State, 0);
69 _SEH2_TRY
70 {
71 *State = 1;
72 InnerFunction(State, Raise);
73 ok_eq_ulong(*State, 5);
74 *State = 6;
75 }
76 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
77 {
78 ok_eq_int(Var, 456);
79 ok_eq_pointer(&Var, AddressOfVar);
80 ok_eq_ulong(*State, 4);
81 *State = 7;
82 }
83 _SEH2_END;
84
85 ok_eq_int(Var, 456);
86 ok_eq_pointer(&Var, AddressOfVar);
87 if (Raise)
88 ok_eq_ulong(*State, 7);
89 else
90 ok_eq_ulong(*State, 6);
91 *State = 8;
92 }
93
94 static
95 VOID
96 TestNestedExceptionHandler(VOID)
97 {
98 ULONG State;
99
100 State = 0;
101 OuterFunction(&State, FALSE);
102 ok_eq_ulong(State, 8);
103
104 State = 0;
105 OuterFunction(&State, TRUE);
106 ok_eq_ulong(State, 8);
107 }
108
109 START_TEST(RtlException)
110 {
111 PCHAR Buffer[128];
112
113 /* Access a valid pointer - must not trigger SEH */
114 KmtStartSeh()
115 RtlFillMemory(Buffer, sizeof(Buffer), 0x12);
116 KmtEndSeh(STATUS_SUCCESS);
117
118 /* Read from a NULL pointer - must cause an access violation */
119 KmtStartSeh()
120 (void)*(volatile CHAR *)NULL;
121 KmtEndSeh(STATUS_ACCESS_VIOLATION);
122
123 /* Write to a NULL pointer - must cause an access violation */
124 KmtStartSeh()
125 *(volatile CHAR *)NULL = 5;
126 KmtEndSeh(STATUS_ACCESS_VIOLATION);
127
128 /* TODO: Find where MmBadPointer is defined - gives an unresolved external */
129 #if 0 //def KMT_KERNEL_MODE
130 /* Read from MmBadPointer - must cause an access violation */
131 KmtStartSeh()
132 (void)*(volatile CHAR *)MmBadPointer;
133 KmtEndSeh(STATUS_ACCESS_VIOLATION);
134
135 /* Write to MmBadPointer - must cause an access violation */
136 KmtStartSeh()
137 *(volatile CHAR *)MmBadPointer = 5;
138 KmtEndSeh(STATUS_ACCESS_VIOLATION);
139 #endif
140
141 KmtStartSeh()
142 ExRaiseStatus(STATUS_ACCESS_VIOLATION);
143 KmtEndSeh(STATUS_ACCESS_VIOLATION);
144
145 KmtStartSeh()
146 ExRaiseStatus(STATUS_TIMEOUT);
147 KmtEndSeh(STATUS_TIMEOUT);
148
149 KmtStartSeh()
150 ExRaiseStatus(STATUS_STACK_OVERFLOW);
151 KmtEndSeh(STATUS_STACK_OVERFLOW);
152
153 KmtStartSeh()
154 ExRaiseStatus(STATUS_GUARD_PAGE_VIOLATION);
155 KmtEndSeh(STATUS_GUARD_PAGE_VIOLATION);
156
157 TestNestedExceptionHandler();
158
159 /* We cannot test this in kernel mode easily - the stack is just "somewhere"
160 * in system space, and there's no guard page below it */
161 #if CORE_6640_IS_FIXED
162 #ifdef KMT_USER_MODE
163 /* Overflow the stack - must cause a special exception */
164 KmtStartSeh()
165 volatile CHAR *Pointer;
166
167 while (1)
168 {
169 Pointer = _alloca(1024);
170 *Pointer = 5;
171 }
172 KmtEndSeh(STATUS_STACK_OVERFLOW);
173 #endif
174 #endif /* CORE_6640_IS_FIXED */
175 }