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 }

Generated on Sat May 15 19:42:17 2004 for test by doxygen 1.3.7