From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/rtl/utxcpt2.c | 398 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 private/ntos/rtl/utxcpt2.c (limited to 'private/ntos/rtl/utxcpt2.c') diff --git a/private/ntos/rtl/utxcpt2.c b/private/ntos/rtl/utxcpt2.c new file mode 100644 index 000000000..3b8037320 --- /dev/null +++ b/private/ntos/rtl/utxcpt2.c @@ -0,0 +1,398 @@ +// utxcpt2.c - user mode structured exception handling test 2 +// +// Exception test from Markl. +// + +#include + +VOID +ExceptionTest ( + ) + +// +// This routine tests the structured exception handling capabilities of the +// MS C compiler and the NT exception handling facilities. +// + +{ + + EXCEPTION_RECORD ExceptionRecord; + LONG Counter; + ULONG rv; + + // + // Announce start of exception test. + // + + DbgPrint("Start of exception test\n"); + + // + // Initialize exception record. + // + + ExceptionRecord.ExceptionCode = (NTSTATUS)49; + ExceptionRecord.ExceptionRecord = (PEXCEPTION_RECORD)NULL; + ExceptionRecord.NumberParameters = 1; + ExceptionRecord.ExceptionInformation[0] = 9; + + // + // Simply try statement with a finally clause that is entered sequentially. + // + DbgPrint("t1..."); + Counter = 0; + try { + Counter += 1; + } finally { + if (abnormal_termination() == 0) { + Counter += 1; + } + } + if (Counter != 2) { + DbgPrint("BUG Finally clause executed as result of unwind\n"); + } + DbgPrint("done\n"); + + // + // Simple try statement with an exception clause that is never executed + // because there is no exception raised in the try clause. + // +// goto a; + DbgPrint("t2..."); + Counter = 0; + try { +//a: Counter += 1; + Counter += 1; + } except (Counter) { + Counter += 1; + } + if (Counter != 1) { + DbgPrint("BUG Exception clause executed when it shouldn't be\n"); + } + DbgPrint("done\n"); + + // + // Simple try statement with an exception handler that is never executed + // because the exception expression continues execution. + // + DbgPrint("t3..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = 0; + try { + Counter -= 1; + RtlRaiseException(&ExceptionRecord); + } except (Counter) { + Counter -= 1; + } + if (Counter != - 1) { + DbgPrint("BUG Exception clause executed when it shouldn't be\n"); + } + DbgPrint("done\n"); + + // + // Simple try statement with an exception clause that is always executed. + // + DbgPrint("t4..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + try { + Counter += 1; + RtlRaiseException(&ExceptionRecord); + } except (Counter) { + Counter += 1; + } + if (Counter != 2) { + DbgPrint("BUG Exception clause not executed when it should be\n"); + } + DbgPrint("done\n"); + + // + // Simply try statement with a finally clause that is entered as the + // result of an exception. + // + + DbgPrint("t5..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = 0; + try { + try { + Counter += 1; + RtlRaiseException(&ExceptionRecord); + } finally { + if (abnormal_termination() != 0) { + Counter += 1; + } + } + } except (Counter) { + if (Counter == 2) { + Counter += 1; + } + } + if (Counter != 3) { + DbgPrint("BUG Finally clause executed as result of sequential exit\n"); + } + DbgPrint("done\n"); + + // + // Simple try that calls a function which raises an exception. + // + DbgPrint("t6..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + try { + VOID foo(IN NTSTATUS Status); + + Counter += 1; + foo(STATUS_ACCESS_VIOLATION); + } except (exception_code() == STATUS_ACCESS_VIOLATION) { + Counter += 1; + } + if (Counter != 2) { + DbgPrint("BUG Exception clause not executed when it should be\n"); + } + DbgPrint("done\n"); + + // + // Simple try that calls a function which calls a function that + // raises an exception. The first function has a finally clause + // that must be executed for this test to work. + // + DbgPrint("t7..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + try { + VOID bar(IN NTSTATUS Status, IN PULONG Counter); + + bar(STATUS_ACCESS_VIOLATION, &Counter); + + } except (exception_code() == STATUS_ACCESS_VIOLATION) { + if (Counter != 99) { + DbgPrint("BUG finally in called procedure not executed\n"); + } + } + DbgPrint("done\n"); + + // + // A try within an except + // + DbgPrint("t8..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + try { + + foo(STATUS_ACCESS_VIOLATION); + + } except (exception_code() == STATUS_ACCESS_VIOLATION) { + + Counter++; + + try { + + foo(STATUS_SUCCESS); + + } except (exception_code() == STATUS_SUCCESS) { + if ( Counter != 1 ) { + DbgPrint("BUG Previous Handler not Entered\n"); + } + Counter++; + + } + } + if (Counter != 2) { + DbgPrint("BUG Both Handlers not entered\n"); + } + DbgPrint("done\n"); + + // + // A goto from an exception clause that needs to pass + // through a finally + // + DbgPrint("t9..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + try { + try { + foo(STATUS_ACCESS_VIOLATION); + } except (exception_code() == STATUS_ACCESS_VIOLATION) { + Counter++; + goto t9; + } + } finally { + Counter++; + } +t9: + if (Counter != 2) { + DbgPrint("BUG Finally and Exception Handlers not entered\n"); + } + DbgPrint("done\n"); + + // + // A goto from an exception clause that needs to pass + // through a finally + // + DbgPrint("t10..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + try { + try { + Counter++; + } finally { + Counter++; + goto t10; + } + } finally { + Counter++; + } +t10: + if (Counter != 3) { + DbgPrint("BUG Both Finally Handlers not entered\n"); + } + DbgPrint("done\n"); + + // + // A return from an except clause + // + DbgPrint("t11..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + + try { + ULONG eret(IN NTSTATUS Status, IN PULONG Counter); + + Counter++; + rv = eret(STATUS_ACCESS_VIOLATION, &Counter); + } finally { + Counter++; + } + + if (Counter != 4) { + DbgPrint("BUG Both Finally Handlers and Exception Handler not entered\n"); + } + if (rv != 0xDEADBEEF) { + DbgPrint("BUG rv is wrong\n"); + } + DbgPrint("done\n"); + + // + // A return from a finally clause + // + DbgPrint("t12..."); + Counter = 0; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + + try { + VOID fret(IN PULONG Counter); + + Counter++; + fret(&Counter); + } finally { + Counter++; + } + + if (Counter != 5) { + DbgPrint("BUG All three Finally Handlers not entered\n"); + } + DbgPrint("done\n"); + // + // Announce end of exception test. + // + + DbgPrint("End of exception test\n"); + + return; +} + +main() +{ + ExceptionTest (); +} + + +NTSTATUS +ZwLastChance ( + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT ContextRecord + ) +{ + DbgPrint("ZwLastChance Entered\n");; +} + + +VOID +fret( + IN PULONG Counter + ) +{ + + try { + + try { + *Counter += 1; + } finally { + *Counter += 1; + return; + } + } finally { + *Counter += 1; + } +} +ULONG +eret( + IN NTSTATUS Status, + IN PULONG Counter + ) +{ + + EXCEPTION_RECORD ExceptionRecord; + + try { + + try { + foo(Status); + } except (exception_code() == Status) { + *Counter += 1; + return 0xDEADBEEF; + } + } finally { + *Counter += 1; + } +} +VOID +bar( + IN NTSTATUS Status, + IN PULONG Counter + ) +{ + + EXCEPTION_RECORD ExceptionRecord; + + try { + foo(Status); + } + + finally { + if (abnormal_termination() != 0) { + *Counter = 99; + } else { + *Counter = 100; + } + } +} + +VOID +foo( + IN NTSTATUS Status + ) +{ + EXCEPTION_RECORD ExceptionRecord; + LONG Counter; + + // + // Initialize exception record. + // + + ExceptionRecord.ExceptionFlags = 0; + ExceptionRecord.ExceptionCode = Status; + ExceptionRecord.ExceptionRecord = (PEXCEPTION_RECORD)NULL; + ExceptionRecord.NumberParameters = 0; + RtlRaiseException(&ExceptionRecord); +} -- cgit v1.2.3