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 #ifdef KMT_USER_MODE 162 /* Overflow the stack - must cause a special exception */ 163 KmtStartSeh() 164 volatile CHAR *Pointer; 165 166 while (1) 167 { 168 Pointer = _alloca(1024); 169 *Pointer = 5; 170 } 171 KmtEndSeh(STATUS_STACK_OVERFLOW); 172 #endif 173 } 174