test: utxcpt2.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# utxcpt2.c

Go to the documentation of this file.

    00001 //  utxcpt2.c - user mode structured exception handling test 2
    00002 //
    00003 //  Exception test from Markl.
    00004 //
    00005
    00006 #include <ntos.h>
    00007
    00008 VOID
    00009 ExceptionTest (
    00010     )
    00011
    00012 //
    00013 // This routine tests the structured exception handling capabilities of the
    00014 // MS C compiler and the NT exception handling facilities.
    00015 //
    00016
    00017 {
    00018
    00019     EXCEPTION_RECORD ExceptionRecord;
    00020     LONG Counter;
    00021     ULONG rv;
    00022
    00023     //
    00024     // Announce start of exception test.
    00025     //
    00026
    00027     DbgPrint("Start of exception test\n");
    00028
    00029     //
    00030     // Initialize exception record.
    00031     //
    00032
    00033     ExceptionRecord.ExceptionCode = (NTSTATUS)49;
    00034     ExceptionRecord.ExceptionRecord = (PEXCEPTION_RECORD)NULL;
    00035     ExceptionRecord.NumberParameters = 1;
    00036     ExceptionRecord.ExceptionInformation[0] = 9;
    00037
    00038     //
    00039     // Simply try statement with a finally clause that is entered sequentially.
    00040     //
    00041     DbgPrint("t1...");
    00042     Counter = 0;
    00043     try {
    00044         Counter += 1;
    00045     } finally {
    00046         if (abnormal_termination() == 0) {
    00047             Counter += 1;
    00048         }
    00049     }
    00050     if (Counter != 2) {
    00051         DbgPrint("BUG  Finally clause executed as result of unwind\n");
    00052     }
    00053     DbgPrint("done\n");
    00054
    00055     //
    00056     // Simple try statement with an exception clause that is never executed
    00057     // because there is no exception raised in the try clause.
    00058     //
    00059 //  goto a;
    00060     DbgPrint("t2...");
    00061     Counter = 0;
    00062     try {
    00063 //a:        Counter += 1;
    00064           Counter += 1;
    00065     } except (Counter) {
    00066         Counter += 1;
    00067     }
    00068     if (Counter != 1) {
    00069         DbgPrint("BUG  Exception clause executed when it shouldn't be\n");
    00070     }
    00071     DbgPrint("done\n");
    00072
    00073     //
    00074     // Simple try statement with an exception handler that is never executed
    00075     // because the exception expression continues execution.
    00076     //
    00077     DbgPrint("t3...");
    00078     Counter = 0;
    00079     ExceptionRecord.ExceptionFlags = 0;
    00080     try {
    00081         Counter -= 1;
    00082         RtlRaiseException(&ExceptionRecord);
    00083     } except (Counter) {
    00084         Counter -= 1;
    00085     }
    00086     if (Counter != - 1) {
    00087         DbgPrint("BUG  Exception clause executed when it shouldn't be\n");
    00088     }
    00089     DbgPrint("done\n");
    00090
    00091     //
    00092     // Simple try statement with an exception clause that is always executed.
    00093     //
    00094     DbgPrint("t4...");
    00095     Counter = 0;
    00096     ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    00097     try {
    00098         Counter += 1;
    00099         RtlRaiseException(&ExceptionRecord);
    00100     } except (Counter) {
    00101         Counter += 1;
    00102     }
    00103     if (Counter != 2) {
    00104         DbgPrint("BUG  Exception clause not executed when it should be\n");
    00105     }
    00106     DbgPrint("done\n");
    00107
    00108     //
    00109     // Simply try statement with a finally clause that is entered as the
    00110     // result of an exception.
    00111     //
    00112
    00113     DbgPrint("t5...");
    00114     Counter = 0;
    00115     ExceptionRecord.ExceptionFlags = 0;
    00116     try {
    00117         try {
    00118             Counter += 1;
    00119             RtlRaiseException(&ExceptionRecord);
    00120         } finally {
    00121             if (abnormal_termination() != 0) {
    00122                 Counter += 1;
    00123             }
    00124         }
    00125     } except (Counter) {
    00126         if (Counter == 2) {
    00127             Counter += 1;
    00128         }
    00129     }
    00130     if (Counter != 3) {
    00131         DbgPrint("BUG  Finally clause executed as result of sequential exit\n");
    00132     }
    00133     DbgPrint("done\n");
    00134
    00135     //
    00136     // Simple try that calls a function which raises an exception.
    00137     //
    00138     DbgPrint("t6...");
    00139     Counter = 0;
    00140     ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    00141     try {
    00142         VOID foo(IN NTSTATUS Status);
    00143
    00144         Counter += 1;
    00145         foo(STATUS_ACCESS_VIOLATION);
    00146     } except (exception_code() == STATUS_ACCESS_VIOLATION) {
    00147         Counter += 1;
    00148     }
    00149     if (Counter != 2) {
    00150         DbgPrint("BUG  Exception clause not executed when it should be\n");
    00151     }
    00152     DbgPrint("done\n");
    00153
    00154     //
    00155     // Simple try that calls a function which calls a function that
    00156     // raises an exception. The first function has a finally clause
    00157     // that must be executed for this test to work.
    00158     //
    00159     DbgPrint("t7...");
    00160     Counter = 0;
    00161     ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    00162     try {
    00163         VOID bar(IN NTSTATUS Status, IN PULONG Counter);
    00164
    00165         bar(STATUS_ACCESS_VIOLATION, &Counter);
    00166
    00167     } except (exception_code() == STATUS_ACCESS_VIOLATION) {
    00168         if (Counter != 99) {
    00169             DbgPrint("BUG  finally in called procedure not executed\n");
    00170         }
    00171     }
    00172     DbgPrint("done\n");
    00173
    00174     //
    00175     // A try within an except
    00176     //
    00177     DbgPrint("t8...");
    00178     Counter = 0;
    00179     ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    00180     try {
    00181
    00182         foo(STATUS_ACCESS_VIOLATION);
    00183
    00184     } except (exception_code() == STATUS_ACCESS_VIOLATION) {
    00185
    00186         Counter++;
    00187
    00188         try {
    00189
    00190             foo(STATUS_SUCCESS);
    00191
    00192         } except (exception_code() == STATUS_SUCCESS) {
    00193             if ( Counter != 1 ) {
    00194                 DbgPrint("BUG  Previous Handler not Entered\n");
    00195             }
    00196             Counter++;
    00197
    00198         }
    00199     }
    00200     if (Counter != 2) {
    00201         DbgPrint("BUG Both Handlers not entered\n");
    00202     }
    00203     DbgPrint("done\n");
    00204
    00205     //
    00206     // A goto from an exception clause that needs to pass
    00207     // through a finally
    00208     //
    00209     DbgPrint("t9...");
    00210     Counter = 0;
    00211     ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    00212     try {
    00213         try {
    00214             foo(STATUS_ACCESS_VIOLATION);
    00215         } except (exception_code() == STATUS_ACCESS_VIOLATION) {
    00216             Counter++;
    00217             goto t9;
    00218         }
    00219     } finally {
    00220         Counter++;
    00221     }
    00222 t9:
    00223     if (Counter != 2) {
    00224         DbgPrint("BUG Finally and Exception Handlers not entered\n");
    00225     }
    00226     DbgPrint("done\n");
    00227
    00228     //
    00229     // A goto from an exception clause that needs to pass
    00230     // through a finally
    00231     //
    00232     DbgPrint("t10...");
    00233     Counter = 0;
    00234     ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    00235     try {
    00236         try {
    00237             Counter++;
    00238         } finally {
    00239             Counter++;
    00240             goto t10;
    00241         }
    00242     } finally {
    00243         Counter++;
    00244     }
    00245 t10:
    00246     if (Counter != 3) {
    00247         DbgPrint("BUG Both Finally Handlers not entered\n");
    00248     }
    00249     DbgPrint("done\n");
    00250
    00251     //
    00252     // A return from an except clause
    00253     //
    00254     DbgPrint("t11...");
    00255     Counter = 0;
    00256     ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    00257
    00258     try {
    00259         ULONG eret(IN NTSTATUS Status, IN PULONG Counter);
    00260
    00261         Counter++;
    00262         rv = eret(STATUS_ACCESS_VIOLATION, &Counter);
    00263     } finally {
    00264         Counter++;
    00265     }
    00266
    00267     if (Counter != 4) {
    00268         DbgPrint("BUG Both Finally Handlers and Exception Handler not entered\n");
    00269     }
    00270     if (rv != 0xDEADBEEF) {
    00271         DbgPrint("BUG rv is wrong\n");
    00272     }
    00273     DbgPrint("done\n");
    00274
    00275     //
    00276     // A return from a finally clause
    00277     //
    00278     DbgPrint("t12...");
    00279     Counter = 0;
    00280     ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    00281
    00282     try {
    00283         VOID fret(IN PULONG Counter);
    00284
    00285         Counter++;
    00286         fret(&Counter);
    00287     } finally {
    00288         Counter++;
    00289     }
    00290
    00291     if (Counter != 5) {
    00292         DbgPrint("BUG All three Finally Handlers not entered\n");
    00293     }
    00294     DbgPrint("done\n");
    00295     //
    00296     // Announce end of exception test.
    00297     //
    00298
    00299     DbgPrint("End of exception test\n");
    00300
    00301     return;
    00302 }
    00303
    00304 main()
    00305 {
    00306     ExceptionTest ();
    00307 }
    00308
    00309
    00310 NTSTATUS
    00311 ZwLastChance (
    00312     IN PEXCEPTION_RECORD ExceptionRecord,
    00313     IN PCONTEXT ContextRecord
    00314     )
    00315 {
    00316     DbgPrint("ZwLastChance Entered\n");;
    00317 }
    00318
    00319
    00320 VOID
    00321 fret(
    00322     IN PULONG Counter
    00323     )
    00324 {
    00325
    00326     try {
    00327
    00328         try {
    00329             *Counter += 1;
    00330         } finally {
    00331             *Counter += 1;
    00332             return;
    00333         }
    00334     } finally {
    00335         *Counter += 1;
    00336     }
    00337 }
    00338 ULONG
    00339 eret(
    00340     IN NTSTATUS Status,
    00341     IN PULONG Counter
    00342     )
    00343 {
    00344
    00345     EXCEPTION_RECORD ExceptionRecord;
    00346
    00347     try {
    00348
    00349         try {
    00350             foo(Status);
    00351         } except (exception_code() == Status) {
    00352             *Counter += 1;
    00353             return 0xDEADBEEF;
    00354         }
    00355     } finally {
    00356         *Counter += 1;
    00357     }
    00358 }
    00359 VOID
    00360 bar(
    00361     IN NTSTATUS Status,
    00362     IN PULONG Counter
    00363     )
    00364 {
    00365
    00366     EXCEPTION_RECORD ExceptionRecord;
    00367
    00368     try {
    00369         foo(Status);
    00370     }
    00371
    00372     finally {
    00373         if (abnormal_termination() != 0) {
    00374             *Counter = 99;
    00375         } else {
    00376             *Counter = 100;
    00377         }
    00378     }
    00379 }
    00380
    00381 VOID
    00382 foo(
    00383     IN NTSTATUS Status
    00384     )
    00385 {
    00386     EXCEPTION_RECORD ExceptionRecord;
    00387     LONG Counter;
    00388
    00389     //
    00390     // Initialize exception record.
    00391     //
    00392
    00393     ExceptionRecord.ExceptionFlags = 0;
    00394     ExceptionRecord.ExceptionCode = Status;
    00395     ExceptionRecord.ExceptionRecord = (PEXCEPTION_RECORD)NULL;
    00396     ExceptionRecord.NumberParameters = 0;
    00397     RtlRaiseException(&ExceptionRecord);
    00398 }