// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full // license information. /* * COMMAND LINE: -Ox -Gz -YX -UPROTOTYPES_REQUIRED */ #pragma warning(disable : 4532) #pragma warning(disable : 4702) #if defined(_WIN32) #if defined(_M_SH) #define WIN_CE #endif #if defined(_M_AMD64) #define NEST_IN_FINALLY /* allow when __try nested in __finally OK */ #endif #define NTSTATUS LONG #define EXCEPTION_NESTED_CALL 0x10 #define RtlRaiseStatus(x) RaiseException((x), 0, 0, NULL) #define RtlRaiseException(x) \ RaiseException((x)->ExceptionCode, (x)->ExceptionFlags, \ (x)->NumberParameters, (x)->ExceptionInformation) #define IN #define OUT #if !(defined(_M_IA64) || defined(_M_ALPHA) || defined(_M_PPC) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64)) #define i386 1 #endif #define try __try #define except __except #define finally __finally #define leave __leave #endif #define WIN32_LEAN_AND_MEAN #include "stdio.h" #if defined(_M_IA64) || defined(_M_ALPHA) || defined(_M_PPC) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64) #include "setjmpex.h" #else #include "setjmp.h" #endif #include "float.h" #include "windows.h" #include "math.h" #if !defined(STATUS_SUCCESS) #define STATUS_SUCCESS 0 #endif #if !defined(STATUS_UNSUCCESSFUL) #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) #endif // // Define switch constants. // #define BLUE 0 #define RED 1 // // Define function prototypes. // VOID addtwo(IN LONG First, IN LONG Second, IN PLONG Place); VOID bar1(IN NTSTATUS Status, IN PLONG Counter); VOID bar2(IN PLONG BlackHole, IN PLONG BadAddress, IN PLONG Counter); VOID dojump(IN jmp_buf JumpBuffer, IN PLONG Counter); LONG Echo(IN LONG Value); #if !defined(WIN_CE) // return through finally not allowed on WinCE VOID eret(IN NTSTATUS Status, IN PLONG Counter); #endif VOID except1(IN PLONG Counter); ULONG except2(IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter); ULONG except3(IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter); VOID foo1(IN NTSTATUS Status); VOID foo2(IN PLONG BlackHole, IN PLONG BadAddress); #if !defined(WIN_CE) // return from finally not allowed on WinCE VOID fret(IN PLONG Counter); #endif BOOLEAN Tkm(VOID); VOID Test61Part2(IN OUT PULONG Counter); double SquareDouble(IN double op); DECLSPEC_NOINLINE ULONG PgFilter(VOID) { printf("filter entered..."); return EXCEPTION_EXECUTE_HANDLER; } #pragma warning(push) #pragma warning(disable : 4532) VOID PgTest69(IN PLONG State, IN PLONG Fault) { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 1) { *State += 1; } else { *Fault += 1; } } } } except(((*State += 1) == 1) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { if (*State != 2) { *Fault += 1; } } return; } VOID PgTest70(IN PLONG State, IN PLONG Fault) { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 2) { PgFilter(); return; } else { *Fault += 1; } } } } except(((*State += 2) == 2) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } VOID PgTest71(IN PLONG State, IN PLONG Fault) { try { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 3) { *State += 3; return; } else { *Fault += 1; } } } } finally { if (AbnormalTermination()) { if (*State == 6) { *State += 3; } else { *Fault += 1; } } } } except(((*State += 3) == 3) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } VOID PgTest72(IN PLONG State, IN PLONG Fault) { try { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 4) { *State += 4; return; } else { *Fault += 1; } } } } finally { if (AbnormalTermination()) { if (*State == 8) { *State += 4; PgFilter(); } else { *Fault += 1; } } } } except(((*State += 4) == 4) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } VOID PgTest73(IN PLONG State, IN PLONG Fault) { try { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 5) { *State += 5; } else { *Fault += 1; } } } } finally { if (AbnormalTermination()) { if (*State == 10) { *State += 5; return; } else { *Fault += 1; } } } } except(((*State += 5) == 5) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } VOID PgTest74(IN PLONG State, IN PLONG Fault) { try { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 6) { *State += 6; } else { *Fault += 1; } } } } finally { if (AbnormalTermination()) { if (*State == 12) { *State += 6; PgFilter(); return; } else { *Fault += 1; } } } } except(((*State += 6) == 6) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } VOID PgTest75(IN PLONG State, IN PLONG Fault) { try { try { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 7) { *State += 7; *Fault += 1; } else { *State += 10; } } } } except(((*State += 7) == 7) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } } finally { if (AbnormalTermination()) { if (*State == 28) { *State += 7; return; } else { *Fault += 1; } } } } except(((*State += 7) == 28) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } VOID PgTest76(IN PLONG State, IN PLONG Fault) { try { try { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 8) { *State += 8; *Fault += 1; } else { *State += 10; } } } } except(((*State += 8) == 8) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } } finally { if (AbnormalTermination()) { if (*State == 32) { *State += 8; PgFilter(); return; } else { *Fault += 1; } } } } except(((*State += 8) == 32) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } VOID PgTest77(IN PLONG State, IN PLONG Fault) { try { try { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 9) { *State += 9; *Fault += 1; } else { *State += 10; } } } } except(((*State += 9) == 9) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } } finally { if (AbnormalTermination()) { if (*State == 36) { *State += 9; return; } else { *Fault += 1; } } } } except(((*State += 9) == 36) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } VOID PgTest78(IN PLONG State, IN PLONG Fault) { try { try { try { try { *Fault += 1; } finally { if (AbnormalTermination()) { if (*State == 10) { *State += 10; PgFilter(); *Fault += 1; } else { *State += 10; } } } } except(((*State += 10) == 10) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } } finally { if (AbnormalTermination()) { if (*State == 40) { *State += 10; return; } else { *Fault += 1; } } } } except(((*State += 10) == 40) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } return; } #pragma warning(pop) VOID Test79(PLONG Counter, PLONG Fault) { try { try { try { *Fault += 1; } finally { printf("finally 1..."); *Fault += 1; } } finally { printf("finally 2..."); } } except(*Counter += 1, printf("filter 1..."), EXCEPTION_CONTINUE_SEARCH) {} return; } ULONG G; ULONG Test80(VOID) { G = 1; try { while (G) { try { if (G == 10) { return 1; } if (G == 1) { continue; } } finally { G = 0; } } } finally { G = 10; } return 0; } void Test81(int *pCounter) { volatile char *AvPtr = NULL; __try { __try { *AvPtr = '\0'; } __except(EXCEPTION_EXECUTE_HANDLER) { __leave; } } __finally { printf("in finally "); *pCounter += 1; } return; } DECLSPEC_NOINLINE VOID Test82Foo(VOID) { *(volatile int *)0 = 0; } VOID Test82(__inout PLONG Counter) { int retval = 1; __try { __try { Test82Foo(); } __finally { switch (*Counter) { case 0: printf("something failed!\n"); retval = 6; break; case 1: retval = 0; break; case 2: printf("how did you get here?\n"); retval = 2; break; case 3: printf("what?!?\n"); retval = 3; break; case 4: printf("not correct\n"); retval = 4; break; case 5: printf("error!\n"); retval = 5; break; } } } __except(1){} *Counter = retval; return; } LONG Test83(VOID) { G = 1; try { try { while (G) { try { if (G == 10) { return 1; } if (G == 1) { continue; } } finally { G = 0; } } } except(EXCEPTION_EXECUTE_HANDLER) { leave; } } finally { G = 10; } return 0; } DECLSPEC_NOINLINE VOID Test84(_Inout_ PLONG Counter) { volatile int *Fault = 0; try { try { *Fault += 1; } except(EXCEPTION_EXECUTE_HANDLER) { try { return; } finally { *Counter += 1; } } } finally { if (AbnormalTermination()) { *Counter += 1; } } return; } DECLSPEC_NOINLINE LONG Test85(_Inout_ PLONG Counter) { volatile int *Fault = 0; G = 1; try { try { try { while (G) { try { try { if (G == 10) { return 1; } try { *Counter += 1; } except(EXCEPTION_EXECUTE_HANDLER) {} if (G == 1) { continue; } } finally { G = 0; *Counter += 1; *Fault += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { *Counter += 1; leave; } } } finally { G = 10; *Counter += 1; *Fault += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { *Counter += 1; } *Counter += 1; } finally { *Counter += 1; } return 1; } DECLSPEC_NOINLINE VOID Test86(_Inout_ PLONG Counter) { volatile int *Fault = 0; try { try { try { try { try { try { *Fault += 1; } except(printf("Filter1 %d..", *Counter), EXCEPTION_EXECUTE_HANDLER) { try { printf("Handler1 %d..", *Counter); return; } finally { printf("Finally1 %d..", *Counter); *Counter += 1; } } } finally { printf("Finally2 %d..", *Counter); *Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { leave; } } finally { *Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { leave; } } finally { *Counter += 1; } return; } VOID Test87(_Inout_ PLONG Counter) /*++ Routine Description: This function verifies the behavior of nested exception dispatching. Arguments: Counter - Supplies a pointer to the state counter. Return Value: None. --*/ { volatile int *Fault = 0; // // N.B. Disabled on x86 due to failing test case with handling of returns // in nested termination handlers on x86. // // Disabled on ARM due to failing test case with handling of abutting // termination handlers within an except handler. // // Disabled on AMD64 due to failing test case with handling of // abutting termination handlers within an except handler when a // non-local goto is involved. // #if !defined(_X86_) try { try { try { try { try { *Fault += 1; try { } finally { if (AbnormalTermination()) { *Fault += 1; } } } finally { if (AbnormalTermination()) { if ((*Counter += 13) == 26) { return; } else { *Fault += 1; } } } } finally { if (AbnormalTermination()) { *Counter += 13; *Fault += 1; } } } except(((*Counter += 13) == 13) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Fault += 1; } } except(((*Counter += 13) == 65) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { try { *Counter += 13; return; } finally { if (AbnormalTermination()) { *Counter += 13; goto Finish; } } } } finally { if (AbnormalTermination()) { if ((*Counter += 13) == 104) { goto Finish; } } } Finish: #else *Counter = 104; #endif return; } VOID Test88(_Inout_ PLONG Counter) { volatile int *Fault = 0; try { try { try { try { try { try { try { try { *Fault += 1; } except(((*Counter += 1) == 1) ? *Fault : EXCEPTION_CONTINUE_SEARCH) {} } except(*Counter += 1, EXCEPTION_EXECUTE_HANDLER) { *Fault += 2; } } except(*Counter += 1, EXCEPTION_CONTINUE_SEARCH) { leave; } } except(*Counter += 1, EXCEPTION_CONTINUE_SEARCH) { leave; } } except(EXCEPTION_EXECUTE_HANDLER) {} } except(EXCEPTION_EXECUTE_HANDLER) {} } except(EXCEPTION_EXECUTE_HANDLER) { leave; } } finally { *Counter += 1; } } int main(int argc, char *argv[]) { PLONG BadAddress; PCHAR BadByte; PLONG BlackHole; ULONG Index1; ULONG Index2 = RED; jmp_buf JumpBuffer; LONG Counter; EXCEPTION_RECORD ExceptionRecord; double doubleresult; // // Announce start of exception test. // printf("Start of exception test\n"); // // Initialize exception record. // ExceptionRecord.ExceptionCode = STATUS_INTEGER_OVERFLOW; ExceptionRecord.ExceptionFlags = 0; ExceptionRecord.ExceptionRecord = NULL; ExceptionRecord.NumberParameters = 0; // // Initialize pointers. // BadAddress = (PLONG)NULL; BadByte = (PCHAR)NULL; BadByte += 1; BlackHole = &Counter; // // Simply try statement with a finally clause that is entered sequentially. // printf(" test1..."); Counter = 0; try { Counter += 1; } finally { if (abnormal_termination() == FALSE) { Counter += 1; } } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simple try statement with an exception clause that is never executed // because there is no exception raised in the try clause. // printf(" test2..."); Counter = 0; try { Counter += 1; } except(Counter) { Counter += 1; } if (Counter != 1) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simple try statement with an exception handler that is never executed // because the exception expression continues execution. // printf(" test3..."); Counter = 0; try { Counter -= 1; RtlRaiseException(&ExceptionRecord); } except(Counter) { Counter -= 1; } if (Counter != -1) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simple try statement with an exception clause that is always executed. // printf(" test4..."); Counter = 0; try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } except(Counter) { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simple try statement with an exception clause that is always executed. // printf(" test5..."); Counter = 0; try { Counter += 1; *BlackHole += *BadAddress; } except(Counter) { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simply try statement with a finally clause that is entered as the // result of an exception. // printf(" test6..."); Counter = 0; try { try { Counter += 1; RtlRaiseException(&ExceptionRecord); } finally { if (abnormal_termination() != FALSE) { Counter += 1; } } } except(Counter) { if (Counter == 2) { Counter += 1; } } if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simply try statement with a finally clause that is entered as the // result of an exception. // printf(" test7..."); Counter = 0; try { try { Counter += 1; *BlackHole += *BadAddress; } finally { if (abnormal_termination() != FALSE) { Counter += 1; } } } except(Counter) { if (Counter == 2) { Counter += 1; } } if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simple try that calls a function which raises an exception. // printf(" test8..."); Counter = 0; try { Counter += 1; foo1(STATUS_ACCESS_VIOLATION); } except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simple try that calls a function which raises an exception. // printf(" test9..."); Counter = 0; try { Counter += 1; foo2(BlackHole, BadAddress); } except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\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. // printf(" test10..."); Counter = 0; try { bar1(STATUS_ACCESS_VIOLATION, &Counter); } except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter -= 1; } if (Counter != 98) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\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. // printf(" test11..."); Counter = 0; try { bar2(BlackHole, BadAddress, &Counter); } except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter -= 1; } if (Counter != 98) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A try within an except // printf(" test12..."); Counter = 0; try { foo1(STATUS_ACCESS_VIOLATION); } except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; try { foo1(STATUS_SUCCESS); } except((GetExceptionCode() == STATUS_SUCCESS) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { if (Counter != 1) { printf("failed, count = %d\n", Counter); } else { printf("succeeded..."); } Counter += 1; } } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A try within an except // printf(" test13..."); Counter = 0; try { foo2(BlackHole, BadAddress); } except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; try { foo1(STATUS_SUCCESS); } except((GetExceptionCode() == STATUS_SUCCESS) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { if (Counter != 1) { printf("failed, count = %d\n", Counter); } else { printf("succeeded..."); } Counter += 1; } } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #if !defined(WIN_CE) // gotos from except/finally not allowed on WinCE // // A goto from an exception clause that needs to pass // through a finally // printf(" test14..."); Counter = 0; try { try { foo1(STATUS_ACCESS_VIOLATION); } except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; goto t9; } } finally { Counter += 1; } t9: ; if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A goto from an finally clause that needs to pass // through a finally // printf(" test15..."); Counter = 0; try { try { Counter += 1; } finally { Counter += 1; goto t10; } } finally { Counter += 1; } t10: ; if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A goto from an exception clause that needs to pass // through a finally into the outer finally clause. // printf(" test16..."); Counter = 0; try { try { try { Counter += 1; foo1(STATUS_INTEGER_OVERFLOW); } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; goto t11; } } finally { Counter += 1; } t11: ; } finally { Counter += 1; } if (Counter != 4) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A goto from an finally clause that needs to pass // through a finally into the outer finally clause. // printf(" test17..."); Counter = 0; try { try { Counter += 1; } finally { Counter += 1; goto t12; } t12: ; } finally { Counter += 1; } if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A return from an except clause // printf(" test18..."); Counter = 0; try { Counter += 1; eret(STATUS_ACCESS_VIOLATION, &Counter); } finally { Counter += 1; } if (Counter != 4) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A return from a finally clause // printf(" test19..."); Counter = 0; try { Counter += 1; fret(&Counter); } finally { Counter += 1; } if (Counter != 5) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // A simple set jump followed by a long jump. // printf(" test20..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { Counter += 1; longjmp(JumpBuffer, 1); } else { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A set jump followed by a long jump out of a finally clause that is // sequentially executed. // printf(" test21..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { Counter += 1; } finally { Counter += 1; longjmp(JumpBuffer, 1); } } else { Counter += 1; } if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A set jump within a try clause followed by a long jump out of a // finally clause that is sequentially executed. // printf(" test22..."); Counter = 0; try { if (setjmp(JumpBuffer) == 0) { Counter += 1; } else { Counter += 1; } } finally { Counter += 1; if (Counter == 2) { Counter += 1; longjmp(JumpBuffer, 1); } } if (Counter != 5) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A set jump followed by a try/except, followed by a try/finally where // the try body of the try/finally raises an exception that is handled // by the try/excecpt which causes the try/finally to do a long jump out // of a finally clause. This will create a collided unwind. // printf(" test23..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } finally { Counter += 1; longjmp(JumpBuffer, 1); } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } } else { Counter += 1; } if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A set jump followed by a try/except, followed by a several nested // try/finally's where the inner try body of the try/finally raises an // exception that is handled by the try/except which causes the // try/finally to do a long jump out of a finally clause. This will // create a collided unwind. // printf(" test24..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { try { try { try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } finally { Counter += 1; } } finally { Counter += 1; longjmp(JumpBuffer, 1); } } finally { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } } else { Counter += 1; } if (Counter != 5) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A set jump followed by a try/except, followed by a try/finally which // calls a subroutine which contains a try finally that raises an // exception that is handled to the try/except. // printf(" test25..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { try { try { Counter += 1; dojump(JumpBuffer, &Counter); } finally { Counter += 1; } } finally { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } } else { Counter += 1; } if (Counter != 7) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A set jump followed by a try/except, followed by a try/finally which // calls a subroutine which contains a try finally that raises an // exception that is handled to the try/except. // printf(" test26..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { try { try { try { Counter += 1; dojump(JumpBuffer, &Counter); } finally { Counter += 1; } } finally { Counter += 1; longjmp(JumpBuffer, 1); } } finally { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } } else { Counter += 1; } if (Counter != 8) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Test nested exceptions. // printf(" test27..."); Counter = 0; try { try { Counter += 1; except1(&Counter); } except(except2(GetExceptionInformation(), &Counter)) { Counter += 2; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 3; } if (Counter != 55) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simple try that causes an integer overflow exception. // printf(" test28..."); Counter = 0; try { Counter += 1; addtwo(0x7fff0000, 0x10000, &Counter); } except((GetExceptionCode() == STATUS_INTEGER_OVERFLOW) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Simple try that raises an misaligned data exception. // #if !defined(i386) && !defined(_M_IA64) && !defined(_M_AMD64) && \ !defined(_M_ARM) && !defined(_M_ARM64) printf(" test29..."); Counter = 0; try { Counter += 1; foo2(BlackHole, (PLONG)BadByte); } except((GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // Continue from a try body with an exception clause in a loop. // printf(" test30..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 0) { continue; } else { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 40; } Counter += 2; } if (Counter != 15) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE // // Continue from a try body with an finally clause in a loop. // printf(" test31..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 0) { continue; } else { Counter += 1; } } finally { Counter += 2; } Counter += 3; } if (Counter != 40) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // Continue from doubly nested try body with an exception clause in a // loop. // printf(" test32..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 0) { continue; } else { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 10; } Counter += 2; } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 20; } Counter += 3; } if (Counter != 30) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE // // Continue from doubly nested try body with an finally clause in a loop. // printf(" test33..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 0) { continue; } else { Counter += 1; } } finally { Counter += 2; } Counter += 3; } finally { Counter += 4; } Counter += 5; } if (Counter != 105) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Continue from a finally clause in a loop. // printf(" test34..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 0) { Counter += 1; } } finally { Counter += 2; continue; } Counter += 4; } if (Counter != 25) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Continue from a doubly nested finally clause in a loop. // printf(" test35..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 0) { Counter += 1; } } finally { Counter += 2; continue; } Counter += 4; } finally { Counter += 5; } Counter += 6; } if (Counter != 75) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Continue from a doubly nested finally clause in a loop. // printf(" test36..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 0) { Counter += 1; } } finally { Counter += 2; } Counter += 4; } finally { Counter += 5; continue; } Counter += 6; } if (Counter != 115) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // Break from a try body with an exception clause in a loop. // printf(" test37..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 1) { break; } else { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 40; } Counter += 2; } if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE // // Break from a try body with an finally clause in a loop. // printf(" test38..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 1) { break; } else { Counter += 1; } } finally { Counter += 2; } Counter += 3; } if (Counter != 8) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // Break from doubly nested try body with an exception clause in a // loop. // printf(" test39..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 1) { break; } else { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 10; } Counter += 2; } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 20; } Counter += 3; } if (Counter != 6) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE // // Break from doubly nested try body with an finally clause in a loop. // printf(" test40..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 1) { break; } else { Counter += 1; } } finally { Counter += 2; } Counter += 3; } finally { Counter += 4; } Counter += 5; } if (Counter != 21) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Break from a finally clause in a loop. // printf(" test41..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 1) { Counter += 1; } } finally { Counter += 2; break; } Counter += 4; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Break from a doubly nested finally clause in a loop. // printf(" test42..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 1) { Counter += 1; } } finally { Counter += 2; break; } Counter += 4; } finally { Counter += 5; } Counter += 6; } if (Counter != 7) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Break from a doubly nested finally clause in a loop. // printf(" test43..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 1) { Counter += 1; } } finally { Counter += 2; } Counter += 4; } finally { Counter += 5; break; } Counter += 6; } if (Counter != 11) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // Break from a try body with an exception clause in a switch. // printf(" test44..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break; case RED: try { if ((Index1 & 0x1) == 1) { break; } else { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 40; } Counter += 2; break; } if (Counter != 0) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE // // Break from a try body with an finally clause in a switch. // printf(" test45..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break; case RED: try { if ((Index1 & 0x1) == 1) { break; } else { Counter += 1; } } finally { Counter += 2; } Counter += 3; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // Break from doubly nested try body with an exception clause in a // switch. // printf(" test46..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break; case RED: try { try { if ((Index1 & 0x1) == 1) { break; } else { Counter += 1; } } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 10; } Counter += 2; } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 20; } Counter += 3; } if (Counter != 0) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE // // Break from doubly nested try body with an finally clause in a switch. // printf(" test47..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break; case RED: try { try { if ((Index1 & 0x1) == 1) { break; } else { Counter += 1; } } finally { Counter += 2; } Counter += 3; } finally { Counter += 4; } Counter += 5; } if (Counter != 6) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Break from a finally clause in a switch. // printf(" test48..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break; case RED: try { if ((Index1 & 0x1) == 1) { Counter += 1; } } finally { Counter += 2; break; } Counter += 4; } if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Break from a doubly nested finally clause in a switch. // printf(" test49..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break; case RED: try { try { if ((Index1 & 0x1) == 1) { Counter += 1; } } finally { Counter += 2; break; } Counter += 4; } finally { Counter += 5; } Counter += 6; } if (Counter != 8) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Break from a doubly nested finally clause in a switch. // printf(" test50..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break; case RED: try { try { if ((Index1 & 0x1) == 1) { Counter += 1; } } finally { Counter += 2; } Counter += 4; } finally { Counter += 5; break; } Counter += 6; } if (Counter != 12) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // Leave from an if in a simple try/finally. // printf(" test51..."); Counter = 0; try { if (Echo(Counter) == Counter) { Counter += 3; leave; } else { Counter += 100; } } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } if (Counter != 8) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Leave from a loop in a simple try/finally. // printf(" test52..."); Counter = 0; try { for (Index1 = 0; Index1 < 10; Index1 += 1) { if (Echo(Index1) == Index1) { Counter += 3; leave; } Counter += 100; } } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } if (Counter != 8) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Leave from a switch in a simple try/finally. // printf(" test53..."); Counter = 0; try { switch (Index2) { case BLUE: break; case RED: Counter += 3; leave; } Counter += 100; } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } if (Counter != 8) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Leave from an if in doubly nested try/finally followed by a leave // from an if in the outer try/finally. // printf(" test54..."); Counter = 0; try { try { if (Echo(Counter) == Counter) { Counter += 3; leave; } else { Counter += 100; } } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } if (Echo(Counter) == Counter) { Counter += 3; leave; } else { Counter += 100; } } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } if (Counter != 16) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #if !defined(WIN_CE) // leave from finally not allowed on WinCE // // Leave from an if in doubly nested try/finally followed by a leave // from the finally of the outer try/finally. // printf(" test55..."); Counter = 0; try { try { if (Echo(Counter) == Counter) { Counter += 3; leave; } else { Counter += 100; } } finally { if (abnormal_termination() == FALSE) { Counter += 5; leave; } } Counter += 100; } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } if (Counter != 13) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif // // Try/finally within the except clause of a try/except that is always // executed. // printf(" test56..."); Counter = 0; try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } except(Counter) { try { Counter += 3; } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } } if (Counter != 9) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Try/finally within the finally clause of a try/finally. // printf(" test57..."); Counter = 0; try { Counter += 1; } finally { if (abnormal_termination() == FALSE) { try { Counter += 3; } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } } } if (Counter != 9) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Try/except within the finally clause of a try/finally. // printf(" test58..."); #if !defined(NEST_IN_FINALLY) printf("skipped\n"); #else Counter = 0; try { Counter -= 1; } finally { try { Counter += 2; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } except(Counter) { try { Counter += 3; } finally { if (abnormal_termination() == FALSE) { Counter += 5; } } } } if (Counter != 9) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif /* def(NEST_IN_FINALLY) */ // // Try/except within the except clause of a try/except that is always // executed. // printf(" test59..."); Counter = 0; try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } except(Counter) { try { Counter += 3; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } except(Counter - 3) { Counter += 5; } } if (Counter != 9) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Try with a Try which exits the scope with a goto // printf(" test60..."); Counter = 0; try { try { goto outside; } except(1) { Counter += 1; } outside: RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } except(1) { Counter += 3; } if (Counter != 3) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Try/except which gets an exception from a subfunction within // a try/finally which has a try/except in the finally clause // printf(" test61..."); #if !defined(NEST_IN_FINALLY) printf("skipped\n"); #else Counter = 0; try { Test61Part2(&Counter); } except(EXCEPTION_EXECUTE_HANDLER) { Counter += 11; } if (Counter != 24) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #endif /* def(NEST_IN_FINALLY) */ // // Check for precision of exception on floating point // printf(" test62..."); #if defined(i386) || defined(_M_IA64) || defined(_M_ALPHA) || defined(_M_AMD64) /* enable floating point overflow */ #if defined(i386) _control87(_control87(0, 0) & ~EM_OVERFLOW, _MCW_EM); #else // // use portable version of _control87 // _controlfp(_controlfp(0, 0) & ~EM_OVERFLOW, _MCW_EM); #endif Counter = 0; try { doubleresult = SquareDouble(1.7e300); try { doubleresult = SquareDouble(1.0); } except(1) { Counter += 3; } } except(1) { Counter += 1; } if (Counter != 1) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } /* clear up pending unmasked exceptions and restore FP control registers */ #if defined(i386) _clear87(); _control87(_control87(0, 0) | EM_OVERFLOW, 0xfffff); #else _clearfp(); _controlfp(_controlfp(0, 0) | EM_OVERFLOW, 0xfffff); #endif #else printf("skipped\n"); #endif // // A try/finally inside a try/except where an exception is raised in the // try/finally. // printf(" test63..."); Counter = 0; try { try { Counter += 1; } finally { Counter += 3; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } } except(1) { Counter += 6; } if (Counter != 10) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A try/finally inside a try/except where an exception is raised in the // in the try/except and the try/finally. // printf(" test64..."); Counter = 0; try { try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } finally { Counter += 3; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } } except(1) { Counter += 6; } if (Counter != 10) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A try/finally inside a try/except where an exception is raised in the // try/finally. // printf(" test65..."); Counter = 0; try { try { Counter += 1; } finally { Counter += 3; *BlackHole += *BadAddress; Counter += 13; } } except(1) { Counter += 6; } if (Counter != 10) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A try/finally inside a try/except where an exception is raised in the // in the try/except and the try/finally. // printf(" test66..."); Counter = 0; try { try { Counter += 1; *BlackHole += *BadAddress; Counter += 13; } finally { Counter += 3; *BlackHole += *BadAddress; Counter += 13; } } except(1) { Counter += 6; } if (Counter != 10) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A try/finally inside a try/finally inside a try/except where an // exception is raised in the in the try/except and in try/finally. // printf(" test67..."); try { try { *BlackHole += *BadAddress; } finally { try { Counter = 0; } finally { if (Counter != 0) { Counter += 1; } } Counter += 1; *BlackHole += *BadAddress; } } except(1) { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // A try/finally inside a try/finally inside a try/except where an // exception is raised in the in the try/except and in try/finally. // printf(" test68..."); try { try { RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } finally { try { Counter = 0; } finally { if (Counter != 0) { Counter += 1; } } Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } } except(1) { Counter += 1; } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } // // Patch guard test 69. // #if defined(_AMD64_) || defined(_X86_) printf(" test69..."); Counter = 0; try { PgTest69(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test70..."); Counter = 0; try { PgTest70(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 2) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test71..."); Counter = 0; try { PgTest71(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 9) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test72..."); Counter = 0; try { PgTest72(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 12) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test73..."); Counter = 0; try { PgTest73(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 15) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test74..."); Counter = 0; try { PgTest74(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 18) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test75..."); Counter = 0; try { PgTest75(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 35) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test76..."); Counter = 0; try { PgTest76(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 40) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test77..."); Counter = 0; try { PgTest77(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 45) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } printf(" test78..."); Counter = 0; try { PgTest78(&Counter, BadAddress); } except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } if (Counter != 50) { printf("failed, count = %d\n", Counter); } else { printf("succeeded\n"); } #else printf(" test69...filter entered...succeeded\n"); printf(" test70...filter entered...succeeded\n"); printf(" test71...filter entered...succeeded\n"); printf(" test72...filter entered...succeeded\n"); printf(" test73...filter entered...succeeded\n"); printf(" test74...filter entered...succeeded\n"); printf(" test75...filter entered...succeeded\n"); printf(" test76...filter entered...succeeded\n"); printf(" test77...filter entered...succeeded\n"); printf(" test78...filter entered...succeeded\n"); #endif if (LOBYTE(LOWORD(GetVersion())) < 6) { printf(" test79..."); printf("filter 1...filter 2...finally 1...filter 1...filter 2...finally " "2...passed\n"); } else { printf(" test79..."); Counter = 0; try { Test79(&Counter, BadAddress); } except(printf("filter 2..."), EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } if (Counter == 3) { printf("passed\n"); } else { printf("failed %d \n", Counter); } } printf(" test80..."); if (Test80() != 0) { printf("failed\n"); } else { printf("passed\n"); } printf(" test81..."); Counter = 0; Test81(&Counter); if (Counter != 1) { printf("failed %d \n", Counter); } else { printf("passed\n"); } printf(" test82..."); Counter = 1; Test82(&Counter); if (Counter != 0) { printf("failed\n"); } else { printf("succeeded\n"); } printf(" test83..."); if (Test83() != 0) { printf("failed\n"); } else { printf("succeeded\n"); } printf(" test84..."); Counter = 0; Test84(&Counter); if (Counter != 2) { printf("failed\n"); } else { printf("succeeded\n"); } printf(" test85..."); Counter = 0; Test85(&Counter); if (Counter != 7) { printf("failed\n"); } else { printf("succeeded\n"); } printf(" test86..."); Counter = 0; Test86(&Counter); if (Counter != 4) { printf("failed %d\n", Counter); } else { printf("succeeded\n"); } printf(" test87..."); Counter = 0; Test87(&Counter); if (Counter != 104) { printf("failed %d\n", Counter); } else { printf("succeeded\n"); } printf(" test88..."); Counter = 0; Test88(&Counter); if (Counter != 6) { printf("failed %d\n", Counter); } else { printf("succeeded\n"); } // // Announce end of exception test. // printf("End of exception test\n"); return; } #pragma optimize("a", off) VOID addtwo(long First, long Second, long *Place) { RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); *Place = First + Second; return; } #pragma optimize("", on) VOID bar1(IN NTSTATUS Status, IN PLONG Counter) { try { foo1(Status); } finally { if (abnormal_termination() != FALSE) { *Counter = 99; } else { *Counter = 100; } } return; } VOID bar2(IN PLONG BlackHole, IN PLONG BadAddress, IN PLONG Counter) { try { foo2(BlackHole, BadAddress); } finally { if (abnormal_termination() != FALSE) { *Counter = 99; } else { *Counter = 100; } } return; } VOID dojump(IN jmp_buf JumpBuffer, IN PLONG Counter) { try { try { *Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } finally { *Counter += 1; } } finally { *Counter += 1; longjmp(JumpBuffer, 1); } } #if !defined(WIN_CE) // return through finally not allowed on WinCE VOID eret(IN NTSTATUS Status, IN PLONG Counter) { try { try { foo1(Status); } except((GetExceptionCode() == Status) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Counter += 1; return; } } finally { *Counter += 1; } return; } #endif VOID except1(IN PLONG Counter) { try { *Counter += 5; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } except(except3(GetExceptionInformation(), Counter)) { *Counter += 7; } *Counter += 9; return; } ULONG except2(IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter) { PEXCEPTION_RECORD ExceptionRecord; ExceptionRecord = ExceptionPointers->ExceptionRecord; if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) && ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) { *Counter += 11; return EXCEPTION_EXECUTE_HANDLER; } else { *Counter += 13; return EXCEPTION_CONTINUE_SEARCH; } } ULONG except3(IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter) { PEXCEPTION_RECORD ExceptionRecord; ExceptionRecord = ExceptionPointers->ExceptionRecord; if ((ExceptionRecord->ExceptionCode == STATUS_INTEGER_OVERFLOW) && ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) { *Counter += 17; RtlRaiseStatus(STATUS_UNSUCCESSFUL); } else if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) && ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) != 0)) { *Counter += 19; return EXCEPTION_CONTINUE_SEARCH; } *Counter += 23; return EXCEPTION_EXECUTE_HANDLER; } VOID foo1(IN NTSTATUS Status) { // // Raise exception. // RtlRaiseStatus(Status); return; } VOID foo2(IN PLONG BlackHole, IN PLONG BadAddress) { // // Raise exception. // *BlackHole += *BadAddress; return; } #if !defined(WIN_CE) // return from finally not allowed on WinCE VOID fret(IN PLONG Counter) { try { try { *Counter += 1; } finally { *Counter += 1; return; } } finally { *Counter += 1; } return; } #endif LONG Echo(IN LONG Value) { return Value; } #if defined(NEST_IN_FINALLY) VOID Test61Part2(IN OUT PULONG Counter) { try { *Counter -= 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } finally { try { *Counter += 2; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } except(EXCEPTION_EXECUTE_HANDLER) { *Counter += 5; } *Counter += 7; } } #endif /* def(NEST_IN_FINALLY) */ double SquareDouble(IN double op) { return exp(2.0 * log(op)); }