summaryrefslogtreecommitdiffstats
path: root/private/ntos/rtl/utxcpt2.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/rtl/utxcpt2.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/rtl/utxcpt2.c')
-rw-r--r--private/ntos/rtl/utxcpt2.c398
1 files changed, 398 insertions, 0 deletions
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 <ntos.h>
+
+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);
+}