Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2589 lines
49 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. xcpt4.c
  5. Abstract:
  6. This module implements user mode exception tests.
  7. Author:
  8. David N. Cutler (davec) 18-Sep-1990
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. --*/
  13. #include "ki.h"
  14. #pragma hdrstop
  15. #include "setjmpex.h"
  16. #include "float.h"
  17. #pragma warning(disable:4532)
  18. #pragma warning(disable:4702) // unreachable code
  19. #pragma optimize("",off)
  20. //
  21. // Define switch constants.
  22. //
  23. #define BLUE 0
  24. #define RED 1
  25. //
  26. // Define guaranteed fault.
  27. //
  28. #define FAULT *(volatile int *)0
  29. //
  30. // Define function prototypes.
  31. //
  32. VOID
  33. addtwo (
  34. IN LONG First,
  35. IN LONG Second,
  36. IN PLONG Place
  37. );
  38. VOID
  39. bar1 (
  40. IN NTSTATUS Status,
  41. IN PLONG Counter
  42. );
  43. VOID
  44. bar2 (
  45. IN PLONG BlackHole,
  46. IN PLONG BadAddress,
  47. IN PLONG Counter
  48. );
  49. ULONG64
  50. Catch (
  51. IN PEXCEPTION_RECORD ExceptionRecord
  52. );
  53. VOID
  54. dojump (
  55. IN jmp_buf JumpBuffer,
  56. IN PLONG Counter
  57. );
  58. LONG
  59. Echo(
  60. IN LONG Value
  61. );
  62. VOID
  63. eret (
  64. IN NTSTATUS Status,
  65. IN PLONG Counter
  66. );
  67. VOID
  68. except1 (
  69. IN PLONG Counter
  70. );
  71. ULONG
  72. except2 (
  73. IN PEXCEPTION_POINTERS ExceptionPointers,
  74. IN PLONG Counter
  75. );
  76. ULONG
  77. except3 (
  78. IN PEXCEPTION_POINTERS ExceptionPointers,
  79. IN PLONG Counter
  80. );
  81. VOID
  82. foo1 (
  83. IN NTSTATUS Status
  84. );
  85. VOID
  86. foo2 (
  87. IN PLONG BlackHole,
  88. IN PLONG BadAddress
  89. );
  90. VOID
  91. fret (
  92. IN PLONG Counter
  93. );
  94. BOOLEAN
  95. Tkm (
  96. VOID
  97. );
  98. VOID
  99. Test61Part2 (
  100. IN OUT PLONG Counter
  101. );
  102. VOID
  103. PerformFpTest(
  104. VOID
  105. );
  106. double
  107. SquareDouble (
  108. IN double op
  109. );
  110. VOID
  111. SquareDouble17E300 (
  112. OUT PVOID ans
  113. );
  114. LONG
  115. test66sub (
  116. IN PLONG Counter
  117. );
  118. LONG
  119. test67sub (
  120. IN PLONG Counter
  121. );
  122. VOID
  123. xcpt4 (
  124. VOID
  125. )
  126. {
  127. PLONG BadAddress;
  128. PCHAR BadByte;
  129. PLONG BlackHole;
  130. LONG Index1;
  131. ULONG Index2 = RED;
  132. jmp_buf JumpBuffer;
  133. LONG Counter;
  134. EXCEPTION_RECORD ExceptionRecord;
  135. double doubleresult;
  136. //
  137. // Announce start of exception test.
  138. //
  139. DbgPrint("Start of exception test\n");
  140. //
  141. // Initialize exception record.
  142. //
  143. ExceptionRecord.ExceptionCode = STATUS_INTEGER_OVERFLOW;
  144. ExceptionRecord.ExceptionFlags = 0;
  145. ExceptionRecord.ExceptionRecord = NULL;
  146. ExceptionRecord.NumberParameters = 0;
  147. //
  148. // Initialize pointers.
  149. //
  150. BadAddress = (PLONG)NULL;
  151. BadByte = (PCHAR)NULL;
  152. BadByte += 1;
  153. BlackHole = &Counter;
  154. //
  155. // Simply try statement with a finally clause that is entered sequentially.
  156. //
  157. DbgPrint(" test1...");
  158. Counter = 0;
  159. try {
  160. Counter += 1;
  161. } finally {
  162. if (abnormal_termination() == FALSE) {
  163. Counter += 1;
  164. }
  165. }
  166. if (Counter != 2) {
  167. DbgPrint("failed, count = %d\n", Counter);
  168. } else {
  169. DbgPrint("succeeded\n");
  170. }
  171. //
  172. // Simple try statement with an exception clause that is never executed
  173. // because there is no exception raised in the try clause.
  174. //
  175. DbgPrint(" test2...");
  176. Counter = 0;
  177. try {
  178. Counter += 1;
  179. } except (Counter) {
  180. Counter += 1;
  181. }
  182. if (Counter != 1) {
  183. DbgPrint("failed, count = %d\n", Counter);
  184. } else {
  185. DbgPrint("succeeded\n");
  186. }
  187. //
  188. // Simple try statement with an exception handler that is never executed
  189. // because the exception expression continues execution.
  190. //
  191. DbgPrint(" test3...");
  192. Counter = 0;
  193. try {
  194. Counter -= 1;
  195. RtlRaiseException(&ExceptionRecord);
  196. } except (Counter) {
  197. Counter -= 1;
  198. }
  199. if (Counter != - 1) {
  200. DbgPrint("failed, count = %d\n", Counter);
  201. } else {
  202. DbgPrint("succeeded\n");
  203. }
  204. //
  205. // Simple try statement with an exception clause that is always executed.
  206. //
  207. DbgPrint(" test4...");
  208. Counter = 0;
  209. try {
  210. Counter += 1;
  211. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  212. } except (Counter) {
  213. Counter += 1;
  214. }
  215. if (Counter != 2) {
  216. DbgPrint("failed, count = %d\n", Counter);
  217. } else {
  218. DbgPrint("succeeded\n");
  219. }
  220. //
  221. // Simple try statement with an exception clause that is always executed.
  222. //
  223. DbgPrint(" test5...");
  224. Counter = 0;
  225. try {
  226. Counter += 1;
  227. *BlackHole += *BadAddress;
  228. } except (Counter) {
  229. Counter += 1;
  230. }
  231. if (Counter != 2) {
  232. DbgPrint("failed, count = %d\n", Counter);
  233. } else {
  234. DbgPrint("succeeded\n");
  235. }
  236. //
  237. // Simply try statement with a finally clause that is entered as the
  238. // result of an exception.
  239. //
  240. DbgPrint(" test6...");
  241. Counter = 0;
  242. try {
  243. try {
  244. Counter += 1;
  245. RtlRaiseException(&ExceptionRecord);
  246. } finally {
  247. if (abnormal_termination() != FALSE) {
  248. Counter += 1;
  249. }
  250. }
  251. } except (Counter) {
  252. if (Counter == 2) {
  253. Counter += 1;
  254. }
  255. }
  256. if (Counter != 3) {
  257. DbgPrint("failed, count = %d\n", Counter);
  258. } else {
  259. DbgPrint("succeeded\n");
  260. }
  261. //
  262. // Simply try statement with a finally clause that is entered as the
  263. // result of an exception.
  264. //
  265. DbgPrint(" test7...");
  266. Counter = 0;
  267. try {
  268. try {
  269. Counter += 1;
  270. *BlackHole += *BadAddress;
  271. } finally {
  272. if (abnormal_termination() != FALSE) {
  273. Counter += 1;
  274. }
  275. }
  276. } except (Counter) {
  277. if (Counter == 2) {
  278. Counter += 1;
  279. }
  280. }
  281. if (Counter != 3) {
  282. DbgPrint("failed, count = %d\n", Counter);
  283. } else {
  284. DbgPrint("succeeded\n");
  285. }
  286. //
  287. // Simple try that calls a function which raises an exception.
  288. //
  289. DbgPrint(" test8...");
  290. Counter = 0;
  291. try {
  292. Counter += 1;
  293. foo1(STATUS_ACCESS_VIOLATION);
  294. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  295. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  296. Counter += 1;
  297. }
  298. if (Counter != 2) {
  299. DbgPrint("failed, count = %d\n", Counter);
  300. } else {
  301. DbgPrint("succeeded\n");
  302. }
  303. //
  304. // Simple try that calls a function which raises an exception.
  305. //
  306. DbgPrint(" test9...");
  307. Counter = 0;
  308. try {
  309. Counter += 1;
  310. foo2(BlackHole, BadAddress);
  311. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  312. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  313. Counter += 1;
  314. }
  315. if (Counter != 2) {
  316. DbgPrint("failed, count = %d\n", Counter);
  317. } else {
  318. DbgPrint("succeeded\n");
  319. }
  320. //
  321. // Simple try that calls a function which calls a function that
  322. // raises an exception. The first function has a finally clause
  323. // that must be executed for this test to work.
  324. //
  325. DbgPrint(" test10...");
  326. Counter = 0;
  327. try {
  328. bar1(STATUS_ACCESS_VIOLATION, &Counter);
  329. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  330. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  331. Counter -= 1;
  332. }
  333. if (Counter != 98) {
  334. DbgPrint("failed, count = %d\n", Counter);
  335. } else {
  336. DbgPrint("succeeded\n");
  337. }
  338. //
  339. // Simple try that calls a function which calls a function that
  340. // raises an exception. The first function has a finally clause
  341. // that must be executed for this test to work.
  342. //
  343. DbgPrint(" test11...");
  344. Counter = 0;
  345. try {
  346. bar2(BlackHole, BadAddress, &Counter);
  347. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  348. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  349. Counter -= 1;
  350. }
  351. if (Counter != 98) {
  352. DbgPrint("failed, count = %d\n", Counter);
  353. } else {
  354. DbgPrint("succeeded\n");
  355. }
  356. //
  357. // A try within an except
  358. //
  359. DbgPrint(" test12...");
  360. Counter = 0;
  361. try {
  362. foo1(STATUS_ACCESS_VIOLATION);
  363. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  364. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  365. Counter += 1;
  366. try {
  367. foo1(STATUS_SUCCESS);
  368. } except ((GetExceptionCode() == STATUS_SUCCESS) ?
  369. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  370. if (Counter != 1) {
  371. DbgPrint("failed, count = %d\n", Counter);
  372. } else {
  373. DbgPrint("succeeded...");
  374. }
  375. Counter += 1;
  376. }
  377. }
  378. if (Counter != 2) {
  379. DbgPrint("failed, count = %d\n", Counter);
  380. } else {
  381. DbgPrint("succeeded\n");
  382. }
  383. //
  384. // A try within an except
  385. //
  386. DbgPrint(" test13...");
  387. Counter = 0;
  388. try {
  389. foo2(BlackHole, BadAddress);
  390. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  391. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  392. Counter += 1;
  393. try {
  394. foo1(STATUS_SUCCESS);
  395. } except ((GetExceptionCode() == STATUS_SUCCESS) ?
  396. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  397. if (Counter != 1) {
  398. DbgPrint("failed, count = %d\n", Counter);
  399. } else {
  400. DbgPrint("succeeded...");
  401. }
  402. Counter += 1;
  403. }
  404. }
  405. if (Counter != 2) {
  406. DbgPrint("failed, count = %d\n", Counter);
  407. } else {
  408. DbgPrint("succeeded\n");
  409. }
  410. //
  411. // A goto from an exception clause that needs to pass
  412. // through a finally
  413. //
  414. DbgPrint(" test14...");
  415. Counter = 0;
  416. try {
  417. try {
  418. foo1(STATUS_ACCESS_VIOLATION);
  419. } except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ?
  420. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  421. Counter += 1;
  422. goto t9;
  423. }
  424. } finally {
  425. Counter += 1;
  426. }
  427. t9:;
  428. if (Counter != 2) {
  429. DbgPrint("failed, count = %d\n", Counter);
  430. } else {
  431. DbgPrint("succeeded\n");
  432. }
  433. //
  434. // A goto from an finally clause that needs to pass
  435. // through a finally
  436. //
  437. DbgPrint(" test15...");
  438. Counter = 0;
  439. try {
  440. try {
  441. Counter += 1;
  442. } finally {
  443. Counter += 1;
  444. goto t10;
  445. }
  446. } finally {
  447. Counter += 1;
  448. }
  449. t10:;
  450. if (Counter != 3) {
  451. DbgPrint("failed, count = %d\n", Counter);
  452. } else {
  453. DbgPrint("succeeded\n");
  454. }
  455. //
  456. // A goto from an exception clause that needs to pass
  457. // through a finally into the outer finally clause.
  458. //
  459. DbgPrint(" test16...");
  460. Counter = 0;
  461. try {
  462. try {
  463. try {
  464. Counter += 1;
  465. foo1(STATUS_INTEGER_OVERFLOW);
  466. } except (EXCEPTION_EXECUTE_HANDLER) {
  467. Counter += 1;
  468. goto t11;
  469. }
  470. } finally {
  471. Counter += 1;
  472. }
  473. t11:;
  474. } finally {
  475. Counter += 1;
  476. }
  477. if (Counter != 4) {
  478. DbgPrint("failed, count = %d\n", Counter);
  479. } else {
  480. DbgPrint("succeeded\n");
  481. }
  482. //
  483. // A goto from an finally clause that needs to pass
  484. // through a finally into the outer finally clause.
  485. //
  486. DbgPrint(" test17...");
  487. Counter = 0;
  488. try {
  489. try {
  490. Counter += 1;
  491. } finally {
  492. Counter += 1;
  493. goto t12;
  494. }
  495. t12:;
  496. } finally {
  497. Counter += 1;
  498. }
  499. if (Counter != 3) {
  500. DbgPrint("failed, count = %d\n", Counter);
  501. } else {
  502. DbgPrint("succeeded\n");
  503. }
  504. //
  505. // A return from an except clause
  506. //
  507. DbgPrint(" test18...");
  508. Counter = 0;
  509. try {
  510. Counter += 1;
  511. eret(STATUS_ACCESS_VIOLATION, &Counter);
  512. } finally {
  513. Counter += 1;
  514. }
  515. if (Counter != 4) {
  516. DbgPrint("failed, count = %d\n", Counter);
  517. } else {
  518. DbgPrint("succeeded\n");
  519. }
  520. //
  521. // A return from a finally clause
  522. //
  523. DbgPrint(" test19...");
  524. Counter = 0;
  525. try {
  526. Counter += 1;
  527. fret(&Counter);
  528. } finally {
  529. Counter += 1;
  530. }
  531. if (Counter != 5) {
  532. DbgPrint("failed, count = %d\n", Counter);
  533. } else {
  534. DbgPrint("succeeded\n");
  535. }
  536. //
  537. // A simple set jump followed by a long jump.
  538. //
  539. DbgPrint(" test20...");
  540. Counter = 0;
  541. if (setjmp(JumpBuffer) == 0) {
  542. Counter += 1;
  543. longjmp(JumpBuffer, 1);
  544. } else {
  545. Counter += 1;
  546. }
  547. if (Counter != 2) {
  548. DbgPrint("failed, count = %d\n", Counter);
  549. } else {
  550. DbgPrint("succeeded\n");
  551. }
  552. //
  553. // A set jump followed by a long jump out of a finally clause that is
  554. // sequentially executed.
  555. //
  556. DbgPrint(" test21...");
  557. Counter = 0;
  558. if (setjmp(JumpBuffer) == 0) {
  559. try {
  560. Counter += 1;
  561. } finally {
  562. Counter += 1;
  563. longjmp(JumpBuffer, 1);
  564. }
  565. } else {
  566. Counter += 1;
  567. }
  568. if (Counter != 3) {
  569. DbgPrint("failed, count = %d\n", Counter);
  570. } else {
  571. DbgPrint("succeeded\n");
  572. }
  573. //
  574. // A set jump within a try clause followed by a long jump out of a
  575. // finally clause that is sequentially executed.
  576. //
  577. DbgPrint(" test22...");
  578. Counter = 0;
  579. try {
  580. if (setjmp(JumpBuffer) == 0) {
  581. Counter += 1;
  582. } else {
  583. Counter += 1;
  584. }
  585. } finally {
  586. Counter += 1;
  587. if (Counter == 2) {
  588. Counter += 1;
  589. longjmp(JumpBuffer, 1);
  590. }
  591. }
  592. if (Counter != 5) {
  593. DbgPrint("failed, count = %d\n", Counter);
  594. } else {
  595. DbgPrint("succeeded\n");
  596. }
  597. //
  598. // A set jump followed by a try/except, followed by a try/finally where
  599. // the try body of the try/finally raises an exception that is handled
  600. // by the try/excecpt which causes the try/finally to do a long jump out
  601. // of a finally clause. This will create a collided unwind.
  602. //
  603. DbgPrint(" test23...");
  604. Counter = 0;
  605. if (setjmp(JumpBuffer) == 0) {
  606. try {
  607. try {
  608. Counter += 1;
  609. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  610. } finally {
  611. Counter += 1;
  612. longjmp(JumpBuffer, 1);
  613. }
  614. } except(EXCEPTION_EXECUTE_HANDLER) {
  615. Counter += 1;
  616. }
  617. } else {
  618. Counter += 1;
  619. }
  620. if (Counter != 3) {
  621. DbgPrint("failed, count = %d\n", Counter);
  622. } else {
  623. DbgPrint("succeeded\n");
  624. }
  625. //
  626. // A set jump followed by a try/except, followed by a several nested
  627. // try/finally's where the inner try body of the try/finally raises an
  628. // exception that is handled by the try/except which causes the
  629. // try/finally to do a long jump out of a finally clause. This will
  630. // create a collided unwind.
  631. //
  632. DbgPrint(" test24...");
  633. Counter = 0;
  634. if (setjmp(JumpBuffer) == 0) {
  635. try {
  636. try {
  637. try {
  638. try {
  639. Counter += 1;
  640. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  641. } finally {
  642. Counter += 1;
  643. }
  644. } finally {
  645. Counter += 1;
  646. longjmp(JumpBuffer, 1);
  647. }
  648. } finally {
  649. Counter += 1;
  650. }
  651. } except(EXCEPTION_EXECUTE_HANDLER) {
  652. Counter += 1;
  653. }
  654. } else {
  655. Counter += 1;
  656. }
  657. if (Counter != 5) {
  658. DbgPrint("failed, count = %d\n", Counter);
  659. } else {
  660. DbgPrint("succeeded\n");
  661. }
  662. //
  663. // A set jump followed by a try/except, followed by a try/finally which
  664. // calls a subroutine which contains a try finally that raises an
  665. // exception that is handled to the try/except.
  666. //
  667. DbgPrint(" test25...");
  668. Counter = 0;
  669. if (setjmp(JumpBuffer) == 0) {
  670. try {
  671. try {
  672. try {
  673. Counter += 1;
  674. dojump(JumpBuffer, &Counter);
  675. } finally {
  676. Counter += 1;
  677. }
  678. } finally {
  679. Counter += 1;
  680. }
  681. } except(EXCEPTION_EXECUTE_HANDLER) {
  682. Counter += 1;
  683. }
  684. } else {
  685. Counter += 1;
  686. }
  687. if (Counter != 7) {
  688. DbgPrint("failed, count = %d\n", Counter);
  689. } else {
  690. DbgPrint("succeeded\n");
  691. }
  692. //
  693. // A set jump followed by a try/except, followed by a try/finally which
  694. // calls a subroutine which contains a try finally that raises an
  695. // exception that is handled to the try/except.
  696. //
  697. DbgPrint(" test26...");
  698. Counter = 0;
  699. if (setjmp(JumpBuffer) == 0) {
  700. try {
  701. try {
  702. try {
  703. try {
  704. Counter += 1;
  705. dojump(JumpBuffer, &Counter);
  706. } finally {
  707. Counter += 1;
  708. }
  709. } finally {
  710. Counter += 1;
  711. longjmp(JumpBuffer, 1);
  712. }
  713. } finally {
  714. Counter += 1;
  715. }
  716. } except(EXCEPTION_EXECUTE_HANDLER) {
  717. Counter += 1;
  718. }
  719. } else {
  720. Counter += 1;
  721. }
  722. if (Counter != 8) {
  723. DbgPrint("failed, count = %d\n", Counter);
  724. } else {
  725. DbgPrint("succeeded\n");
  726. }
  727. //
  728. // Test nested exceptions.
  729. //
  730. DbgPrint(" test27...");
  731. Counter = 0;
  732. try {
  733. try {
  734. Counter += 1;
  735. except1(&Counter);
  736. } except(except2(GetExceptionInformation(), &Counter)) {
  737. Counter += 2;
  738. }
  739. } except(EXCEPTION_EXECUTE_HANDLER) {
  740. Counter += 3;
  741. }
  742. if (Counter != 55) {
  743. DbgPrint("failed, count = %d\n", Counter);
  744. } else {
  745. DbgPrint("succeeded\n");
  746. }
  747. //
  748. // Simple try that causes an integer overflow exception.
  749. //
  750. DbgPrint(" test28...");
  751. Counter = 0;
  752. try {
  753. Counter += 1;
  754. addtwo(0x7fff0000, 0x10000, &Counter);
  755. } except ((GetExceptionCode() == STATUS_INTEGER_OVERFLOW) ?
  756. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  757. Counter += 1;
  758. }
  759. if (Counter != 2) {
  760. DbgPrint("failed, count = %d\n", Counter);
  761. } else {
  762. DbgPrint("succeeded\n");
  763. }
  764. //
  765. // Simple try that raises an misaligned data exception.
  766. //
  767. #if 0
  768. DbgPrint(" test29...");
  769. Counter = 0;
  770. try {
  771. Counter += 1;
  772. foo2(BlackHole, (PLONG)BadByte);
  773. } except ((GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) ?
  774. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  775. Counter += 1;
  776. }
  777. if (Counter != 2) {
  778. DbgPrint("failed, count = %d\n", Counter);
  779. } else {
  780. DbgPrint("succeeded\n");
  781. }
  782. #endif
  783. //
  784. // Continue from a try body with an exception clause in a loop.
  785. //
  786. DbgPrint(" test30...");
  787. Counter = 0;
  788. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  789. try {
  790. if ((Index1 & 0x1) == 0) {
  791. continue;
  792. } else {
  793. Counter += 1;
  794. }
  795. } except (EXCEPTION_EXECUTE_HANDLER) {
  796. Counter += 40;
  797. }
  798. Counter += 2;
  799. }
  800. if (Counter != 15) {
  801. DbgPrint("failed, count = %d\n", Counter);
  802. } else {
  803. DbgPrint("succeeded\n");
  804. }
  805. //
  806. // Continue from a try body with an finally clause in a loop.
  807. //
  808. DbgPrint(" test31...");
  809. Counter = 0;
  810. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  811. try {
  812. if ((Index1 & 0x1) == 0) {
  813. continue;
  814. } else {
  815. Counter += 1;
  816. }
  817. } finally {
  818. Counter += 2;
  819. }
  820. Counter += 3;
  821. }
  822. if (Counter != 40) {
  823. DbgPrint("failed, count = %d\n", Counter);
  824. } else {
  825. DbgPrint("succeeded\n");
  826. }
  827. //
  828. // Continue from doubly nested try body with an exception clause in a
  829. // loop.
  830. //
  831. DbgPrint(" test32...");
  832. Counter = 0;
  833. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  834. try {
  835. try {
  836. if ((Index1 & 0x1) == 0) {
  837. continue;
  838. } else {
  839. Counter += 1;
  840. }
  841. } except (EXCEPTION_EXECUTE_HANDLER) {
  842. Counter += 10;
  843. }
  844. Counter += 2;
  845. } except (EXCEPTION_EXECUTE_HANDLER) {
  846. Counter += 20;
  847. }
  848. Counter += 3;
  849. }
  850. if (Counter != 30) {
  851. DbgPrint("failed, count = %d\n", Counter);
  852. } else {
  853. DbgPrint("succeeded\n");
  854. }
  855. //
  856. // Continue from doubly nested try body with an finally clause in a loop.
  857. //
  858. DbgPrint(" test33...");
  859. Counter = 0;
  860. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  861. try {
  862. try {
  863. if ((Index1 & 0x1) == 0) {
  864. continue;
  865. } else {
  866. Counter += 1;
  867. }
  868. } finally {
  869. Counter += 2;
  870. }
  871. Counter += 3;
  872. } finally {
  873. Counter += 4;
  874. }
  875. Counter += 5;
  876. }
  877. if (Counter != 105) {
  878. DbgPrint("failed, count = %d\n", Counter);
  879. } else {
  880. DbgPrint("succeeded\n");
  881. }
  882. //
  883. // Continue from a finally clause in a loop.
  884. //
  885. DbgPrint(" test34...");
  886. Counter = 0;
  887. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  888. try {
  889. if ((Index1 & 0x1) == 0) {
  890. Counter += 1;
  891. }
  892. } finally {
  893. Counter += 2;
  894. continue;
  895. }
  896. Counter += 4;
  897. }
  898. if (Counter != 25) {
  899. DbgPrint("failed, count = %d\n", Counter);
  900. } else {
  901. DbgPrint("succeeded\n");
  902. }
  903. //
  904. // Continue from a doubly nested finally clause in a loop.
  905. //
  906. DbgPrint(" test35...");
  907. Counter = 0;
  908. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  909. try {
  910. try {
  911. if ((Index1 & 0x1) == 0) {
  912. Counter += 1;
  913. }
  914. } finally {
  915. Counter += 2;
  916. continue;
  917. }
  918. Counter += 4;
  919. } finally {
  920. Counter += 5;
  921. }
  922. Counter += 6;
  923. }
  924. if (Counter != 75) {
  925. DbgPrint("failed, count = %d\n", Counter);
  926. } else {
  927. DbgPrint("succeeded\n");
  928. }
  929. //
  930. // Continue from a doubly nested finally clause in a loop.
  931. //
  932. DbgPrint(" test36...");
  933. Counter = 0;
  934. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  935. try {
  936. try {
  937. if ((Index1 & 0x1) == 0) {
  938. Counter += 1;
  939. }
  940. } finally {
  941. Counter += 2;
  942. }
  943. Counter += 4;
  944. } finally {
  945. Counter += 5;
  946. continue;
  947. }
  948. Counter += 6;
  949. }
  950. if (Counter != 115) {
  951. DbgPrint("failed, count = %d\n", Counter);
  952. } else {
  953. DbgPrint("succeeded\n");
  954. }
  955. //
  956. // Break from a try body with an exception clause in a loop.
  957. //
  958. DbgPrint(" test37...");
  959. Counter = 0;
  960. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  961. try {
  962. if ((Index1 & 0x1) == 1) {
  963. break;
  964. } else {
  965. Counter += 1;
  966. }
  967. } except (EXCEPTION_EXECUTE_HANDLER) {
  968. Counter += 40;
  969. }
  970. Counter += 2;
  971. }
  972. if (Counter != 3) {
  973. DbgPrint("failed, count = %d\n", Counter);
  974. } else {
  975. DbgPrint("succeeded\n");
  976. }
  977. //
  978. // Break from a try body with an finally clause in a loop.
  979. //
  980. DbgPrint(" test38...");
  981. Counter = 0;
  982. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  983. try {
  984. if ((Index1 & 0x1) == 1) {
  985. break;
  986. } else {
  987. Counter += 1;
  988. }
  989. } finally {
  990. Counter += 2;
  991. }
  992. Counter += 3;
  993. }
  994. if (Counter != 8) {
  995. DbgPrint("failed, count = %d\n", Counter);
  996. } else {
  997. DbgPrint("succeeded\n");
  998. }
  999. //
  1000. // Break from doubly nested try body with an exception clause in a
  1001. // loop.
  1002. //
  1003. DbgPrint(" test39...");
  1004. Counter = 0;
  1005. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1006. try {
  1007. try {
  1008. if ((Index1 & 0x1) == 1) {
  1009. break;
  1010. } else {
  1011. Counter += 1;
  1012. }
  1013. } except (EXCEPTION_EXECUTE_HANDLER) {
  1014. Counter += 10;
  1015. }
  1016. Counter += 2;
  1017. } except (EXCEPTION_EXECUTE_HANDLER) {
  1018. Counter += 20;
  1019. }
  1020. Counter += 3;
  1021. }
  1022. if (Counter != 6) {
  1023. DbgPrint("failed, count = %d\n", Counter);
  1024. } else {
  1025. DbgPrint("succeeded\n");
  1026. }
  1027. //
  1028. // Break from doubly nested try body with an finally clause in a loop.
  1029. //
  1030. DbgPrint(" test40...");
  1031. Counter = 0;
  1032. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1033. try {
  1034. try {
  1035. if ((Index1 & 0x1) == 1) {
  1036. break;
  1037. } else {
  1038. Counter += 1;
  1039. }
  1040. } finally {
  1041. Counter += 2;
  1042. }
  1043. Counter += 3;
  1044. } finally {
  1045. Counter += 4;
  1046. }
  1047. Counter += 5;
  1048. }
  1049. if (Counter != 21) {
  1050. DbgPrint("failed, count = %d\n", Counter);
  1051. } else {
  1052. DbgPrint("succeeded\n");
  1053. }
  1054. //
  1055. // Break from a finally clause in a loop.
  1056. //
  1057. DbgPrint(" test41...");
  1058. Counter = 0;
  1059. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1060. try {
  1061. if ((Index1 & 0x1) == 1) {
  1062. Counter += 1;
  1063. }
  1064. } finally {
  1065. Counter += 2;
  1066. break;
  1067. }
  1068. Counter += 4;
  1069. }
  1070. if (Counter != 2) {
  1071. DbgPrint("failed, count = %d\n", Counter);
  1072. } else {
  1073. DbgPrint("succeeded\n");
  1074. }
  1075. //
  1076. // Break from a doubly nested finally clause in a loop.
  1077. //
  1078. DbgPrint(" test42...");
  1079. Counter = 0;
  1080. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1081. try {
  1082. try {
  1083. if ((Index1 & 0x1) == 1) {
  1084. Counter += 1;
  1085. }
  1086. } finally {
  1087. Counter += 2;
  1088. break;
  1089. }
  1090. Counter += 4;
  1091. } finally {
  1092. Counter += 5;
  1093. }
  1094. Counter += 6;
  1095. }
  1096. if (Counter != 7) {
  1097. DbgPrint("failed, count = %d\n", Counter);
  1098. } else {
  1099. DbgPrint("succeeded\n");
  1100. }
  1101. //
  1102. // Break from a doubly nested finally clause in a loop.
  1103. //
  1104. DbgPrint(" test43...");
  1105. Counter = 0;
  1106. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1107. try {
  1108. try {
  1109. if ((Index1 & 0x1) == 1) {
  1110. Counter += 1;
  1111. }
  1112. } finally {
  1113. Counter += 2;
  1114. }
  1115. Counter += 4;
  1116. } finally {
  1117. Counter += 5;
  1118. break;
  1119. }
  1120. Counter += 6;
  1121. }
  1122. if (Counter != 11) {
  1123. DbgPrint("failed, count = %d\n", Counter);
  1124. } else {
  1125. DbgPrint("succeeded\n");
  1126. }
  1127. //
  1128. // Break from a try body with an exception clause in a switch.
  1129. //
  1130. DbgPrint(" test44...");
  1131. Counter = 0;
  1132. Index1 = 1;
  1133. switch (Index2) {
  1134. case BLUE:
  1135. Counter += 100;
  1136. break;
  1137. case RED:
  1138. try {
  1139. if ((Index1 & 0x1) == 1) {
  1140. break;
  1141. } else {
  1142. Counter += 1;
  1143. }
  1144. } except (EXCEPTION_EXECUTE_HANDLER) {
  1145. Counter += 40;
  1146. }
  1147. Counter += 2;
  1148. break;
  1149. }
  1150. if (Counter != 0) {
  1151. DbgPrint("failed, count = %d\n", Counter);
  1152. } else {
  1153. DbgPrint("succeeded\n");
  1154. }
  1155. //
  1156. // Break from a try body with an finally clause in a switch.
  1157. //
  1158. DbgPrint(" test45...");
  1159. Counter = 0;
  1160. Index1 = 1;
  1161. switch (Index2) {
  1162. case BLUE:
  1163. Counter += 100;
  1164. break;
  1165. case RED:
  1166. try {
  1167. if ((Index1 & 0x1) == 1) {
  1168. break;
  1169. } else {
  1170. Counter += 1;
  1171. }
  1172. } finally {
  1173. Counter += 2;
  1174. }
  1175. Counter += 3;
  1176. }
  1177. if (Counter != 2) {
  1178. DbgPrint("failed, count = %d\n", Counter);
  1179. } else {
  1180. DbgPrint("succeeded\n");
  1181. }
  1182. //
  1183. // Break from doubly nested try body with an exception clause in a
  1184. // switch.
  1185. //
  1186. DbgPrint(" test46...");
  1187. Counter = 0;
  1188. Index1 = 1;
  1189. switch (Index2) {
  1190. case BLUE:
  1191. Counter += 100;
  1192. break;
  1193. case RED:
  1194. try {
  1195. try {
  1196. if ((Index1 & 0x1) == 1) {
  1197. break;
  1198. } else {
  1199. Counter += 1;
  1200. }
  1201. } except (EXCEPTION_EXECUTE_HANDLER) {
  1202. Counter += 10;
  1203. }
  1204. Counter += 2;
  1205. } except (EXCEPTION_EXECUTE_HANDLER) {
  1206. Counter += 20;
  1207. }
  1208. Counter += 3;
  1209. }
  1210. if (Counter != 0) {
  1211. DbgPrint("failed, count = %d\n", Counter);
  1212. } else {
  1213. DbgPrint("succeeded\n");
  1214. }
  1215. //
  1216. // Break from doubly nested try body with an finally clause in a switch.
  1217. //
  1218. DbgPrint(" test47...");
  1219. Counter = 0;
  1220. Index1 = 1;
  1221. switch (Index2) {
  1222. case BLUE:
  1223. Counter += 100;
  1224. break;
  1225. case RED:
  1226. try {
  1227. try {
  1228. if ((Index1 & 0x1) == 1) {
  1229. break;
  1230. } else {
  1231. Counter += 1;
  1232. }
  1233. } finally {
  1234. Counter += 2;
  1235. }
  1236. Counter += 3;
  1237. } finally {
  1238. Counter += 4;
  1239. }
  1240. Counter += 5;
  1241. }
  1242. if (Counter != 6) {
  1243. DbgPrint("failed, count = %d\n", Counter);
  1244. } else {
  1245. DbgPrint("succeeded\n");
  1246. }
  1247. //
  1248. // Break from a finally clause in a switch.
  1249. //
  1250. DbgPrint(" test48...");
  1251. Counter = 0;
  1252. Index1 = 1;
  1253. switch (Index2) {
  1254. case BLUE:
  1255. Counter += 100;
  1256. break;
  1257. case RED:
  1258. try {
  1259. if ((Index1 & 0x1) == 1) {
  1260. Counter += 1;
  1261. }
  1262. } finally {
  1263. Counter += 2;
  1264. break;
  1265. }
  1266. Counter += 4;
  1267. }
  1268. if (Counter != 3) {
  1269. DbgPrint("failed, count = %d\n", Counter);
  1270. } else {
  1271. DbgPrint("succeeded\n");
  1272. }
  1273. //
  1274. // Break from a doubly nested finally clause in a switch.
  1275. //
  1276. DbgPrint(" test49...");
  1277. Counter = 0;
  1278. Index1 = 1;
  1279. switch (Index2) {
  1280. case BLUE:
  1281. Counter += 100;
  1282. break;
  1283. case RED:
  1284. try {
  1285. try {
  1286. if ((Index1 & 0x1) == 1) {
  1287. Counter += 1;
  1288. }
  1289. } finally {
  1290. Counter += 2;
  1291. break;
  1292. }
  1293. Counter += 4;
  1294. } finally {
  1295. Counter += 5;
  1296. }
  1297. Counter += 6;
  1298. }
  1299. if (Counter != 8) {
  1300. DbgPrint("failed, count = %d\n", Counter);
  1301. } else {
  1302. DbgPrint("succeeded\n");
  1303. }
  1304. //
  1305. // Break from a doubly nested finally clause in a switch.
  1306. //
  1307. DbgPrint(" test50...");
  1308. Counter = 0;
  1309. Index1 = 1;
  1310. switch (Index2) {
  1311. case BLUE:
  1312. Counter += 100;
  1313. break;
  1314. case RED:
  1315. try {
  1316. try {
  1317. if ((Index1 & 0x1) == 1) {
  1318. Counter += 1;
  1319. }
  1320. } finally {
  1321. Counter += 2;
  1322. }
  1323. Counter += 4;
  1324. } finally {
  1325. Counter += 5;
  1326. break;
  1327. }
  1328. Counter += 6;
  1329. }
  1330. if (Counter != 12) {
  1331. DbgPrint("failed, count = %d\n", Counter);
  1332. } else {
  1333. DbgPrint("succeeded\n");
  1334. }
  1335. //
  1336. // Leave from an if in a simple try/finally.
  1337. //
  1338. DbgPrint(" test51...");
  1339. Counter = 0;
  1340. try {
  1341. if (Echo(Counter) == Counter) {
  1342. Counter += 3;
  1343. leave;
  1344. } else {
  1345. Counter += 100;
  1346. }
  1347. } finally {
  1348. if (abnormal_termination() == FALSE) {
  1349. Counter += 5;
  1350. }
  1351. }
  1352. if (Counter != 8) {
  1353. DbgPrint("failed, count = %d\n", Counter);
  1354. } else {
  1355. DbgPrint("succeeded\n");
  1356. }
  1357. //
  1358. // Leave from a loop in a simple try/finally.
  1359. //
  1360. DbgPrint(" test52...");
  1361. Counter = 0;
  1362. try {
  1363. for (Index1 = 0; Index1 < 10; Index1 += 1) {
  1364. if (Echo(Index1) == Index1) {
  1365. Counter += 3;
  1366. leave;
  1367. }
  1368. Counter += 100;
  1369. }
  1370. } finally {
  1371. if (abnormal_termination() == FALSE) {
  1372. Counter += 5;
  1373. }
  1374. }
  1375. if (Counter != 8) {
  1376. DbgPrint("failed, count = %d\n", Counter);
  1377. } else {
  1378. DbgPrint("succeeded\n");
  1379. }
  1380. //
  1381. // Leave from a switch in a simple try/finally.
  1382. //
  1383. DbgPrint(" test53...");
  1384. Counter = 0;
  1385. try {
  1386. switch (Index2) {
  1387. case BLUE:
  1388. break;
  1389. case RED:
  1390. Counter += 3;
  1391. leave;
  1392. }
  1393. Counter += 100;
  1394. } finally {
  1395. if (abnormal_termination() == FALSE) {
  1396. Counter += 5;
  1397. }
  1398. }
  1399. if (Counter != 8) {
  1400. DbgPrint("failed, count = %d\n", Counter);
  1401. } else {
  1402. DbgPrint("succeeded\n");
  1403. }
  1404. //
  1405. // Leave from an if in doubly nested try/finally followed by a leave
  1406. // from an if in the outer try/finally.
  1407. //
  1408. DbgPrint(" test54...");
  1409. Counter = 0;
  1410. try {
  1411. try {
  1412. if (Echo(Counter) == Counter) {
  1413. Counter += 3;
  1414. leave;
  1415. } else {
  1416. Counter += 100;
  1417. }
  1418. } finally {
  1419. if (abnormal_termination() == FALSE) {
  1420. Counter += 5;
  1421. }
  1422. }
  1423. if (Echo(Counter) == Counter) {
  1424. Counter += 3;
  1425. leave;
  1426. } else {
  1427. Counter += 100;
  1428. }
  1429. } finally {
  1430. if (abnormal_termination() == FALSE) {
  1431. Counter += 5;
  1432. }
  1433. }
  1434. if (Counter != 16) {
  1435. DbgPrint("failed, count = %d\n", Counter);
  1436. } else {
  1437. DbgPrint("succeeded\n");
  1438. }
  1439. //
  1440. // Leave from an if in doubly nested try/finally followed by a leave
  1441. // from the finally of the outer try/finally.
  1442. //
  1443. DbgPrint(" test55...");
  1444. Counter = 0;
  1445. try {
  1446. try {
  1447. if (Echo(Counter) == Counter) {
  1448. Counter += 3;
  1449. leave;
  1450. } else {
  1451. Counter += 100;
  1452. }
  1453. } finally {
  1454. if (abnormal_termination() == FALSE) {
  1455. Counter += 5;
  1456. leave;
  1457. }
  1458. }
  1459. Counter += 100;
  1460. } finally {
  1461. if (abnormal_termination() == FALSE) {
  1462. Counter += 5;
  1463. }
  1464. }
  1465. if (Counter != 13) {
  1466. DbgPrint("failed, count = %d\n", Counter);
  1467. } else {
  1468. DbgPrint("succeeded\n");
  1469. }
  1470. //
  1471. // Try/finally within the except clause of a try/except that is always
  1472. // executed.
  1473. //
  1474. DbgPrint(" test56...");
  1475. Counter = 0;
  1476. try {
  1477. Counter += 1;
  1478. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1479. } except (Counter) {
  1480. try {
  1481. Counter += 3;
  1482. } finally {
  1483. if (abnormal_termination() == FALSE) {
  1484. Counter += 5;
  1485. }
  1486. }
  1487. }
  1488. if (Counter != 9) {
  1489. DbgPrint("failed, count = %d\n", Counter);
  1490. } else {
  1491. DbgPrint("succeeded\n");
  1492. }
  1493. //
  1494. // Try/finally within the finally clause of a try/finally.
  1495. //
  1496. DbgPrint(" test57...");
  1497. Counter = 0;
  1498. try {
  1499. Counter += 1;
  1500. } finally {
  1501. if (abnormal_termination() == FALSE) {
  1502. try {
  1503. Counter += 3;
  1504. } finally {
  1505. if (abnormal_termination() == FALSE) {
  1506. Counter += 5;
  1507. }
  1508. }
  1509. }
  1510. }
  1511. if (Counter != 9) {
  1512. DbgPrint("failed, count = %d\n", Counter);
  1513. } else {
  1514. DbgPrint("succeeded\n");
  1515. }
  1516. //
  1517. // Try/except within the finally clause of a try/finally.
  1518. //
  1519. DbgPrint(" test58...");
  1520. Counter = 0;
  1521. try {
  1522. Counter -= 1;
  1523. } finally {
  1524. try {
  1525. Counter += 2;
  1526. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1527. } except (Counter) {
  1528. try {
  1529. Counter += 3;
  1530. } finally {
  1531. if (abnormal_termination() == FALSE) {
  1532. Counter += 5;
  1533. }
  1534. }
  1535. }
  1536. }
  1537. if (Counter != 9) {
  1538. DbgPrint("failed, count = %d\n", Counter);
  1539. } else {
  1540. DbgPrint("succeeded\n");
  1541. }
  1542. //
  1543. // Try/except within the except clause of a try/except that is always
  1544. // executed.
  1545. //
  1546. DbgPrint(" test59...");
  1547. Counter = 0;
  1548. try {
  1549. Counter += 1;
  1550. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1551. } except (Counter) {
  1552. try {
  1553. Counter += 3;
  1554. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1555. } except(Counter - 3) {
  1556. Counter += 5;
  1557. }
  1558. }
  1559. if (Counter != 9) {
  1560. DbgPrint("failed, count = %d\n", Counter);
  1561. } else {
  1562. DbgPrint("succeeded\n");
  1563. }
  1564. //
  1565. // Try with a Try which exits the scope with a goto
  1566. //
  1567. DbgPrint(" test60...");
  1568. Counter = 0;
  1569. try {
  1570. try {
  1571. goto outside;
  1572. } except(1) {
  1573. Counter += 1;
  1574. }
  1575. outside:
  1576. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1577. } except(1) {
  1578. Counter += 3;
  1579. }
  1580. if (Counter != 3) {
  1581. DbgPrint("failed, count = %d\n", Counter);
  1582. } else {
  1583. DbgPrint("succeeded\n");
  1584. }
  1585. //
  1586. // Try/except which gets an exception from a subfunction within
  1587. // a try/finally which has a try/except in the finally clause
  1588. //
  1589. DbgPrint(" test61...");
  1590. Counter = 0;
  1591. try {
  1592. Test61Part2 (&Counter);
  1593. } except (EXCEPTION_EXECUTE_HANDLER) {
  1594. Counter += 11;
  1595. }
  1596. if (Counter != 24) {
  1597. DbgPrint("failed, count = %d\n", Counter);
  1598. } else {
  1599. DbgPrint("succeeded\n");
  1600. }
  1601. //
  1602. // Try/except within a try/except where the outer try/except gets
  1603. // a floating overflow exception.
  1604. //
  1605. DbgPrint(" test62...");
  1606. _controlfp(_controlfp(0,0) & ~EM_OVERFLOW, _MCW_EM);
  1607. Counter = 0;
  1608. try {
  1609. doubleresult = SquareDouble(1.7e300);
  1610. try {
  1611. doubleresult = SquareDouble (1.0);
  1612. } except (EXCEPTION_EXECUTE_HANDLER) {
  1613. Counter += 3;
  1614. }
  1615. } except ((GetExceptionCode() == STATUS_FLOAT_OVERFLOW) ?
  1616. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  1617. Counter += 1;
  1618. }
  1619. if (Counter != 1) {
  1620. DbgPrint("failed, count = %d\n", Counter);
  1621. } else {
  1622. DbgPrint("succeeded\n");
  1623. }
  1624. _clearfp ();
  1625. //
  1626. // Try/except within a try/except where the outer try/except gets
  1627. // a floating overflow exception in a subfunction.
  1628. //
  1629. DbgPrint(" test63...");
  1630. Counter = 0;
  1631. try {
  1632. SquareDouble17E300((PVOID)&doubleresult);
  1633. try {
  1634. SquareDouble17E300((PVOID)&doubleresult);
  1635. } except (EXCEPTION_EXECUTE_HANDLER) {
  1636. Counter += 3;
  1637. }
  1638. } except ((GetExceptionCode() == STATUS_FLOAT_OVERFLOW) ?
  1639. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  1640. Counter += 1;
  1641. }
  1642. if (Counter != 1) {
  1643. DbgPrint("failed, count = %d\n", Counter);
  1644. } else {
  1645. DbgPrint("succeeded\n");
  1646. }
  1647. _clearfp ();
  1648. //
  1649. // Try/finally within a try/except where the finally body causes an
  1650. // exception that leads to a collided unwind during the exception
  1651. // dispatch.
  1652. //
  1653. DbgPrint(" test64...");
  1654. Counter = 0;
  1655. try {
  1656. Counter += 1;
  1657. try {
  1658. Counter += 1;
  1659. FAULT;
  1660. Counter += 20;
  1661. } finally {
  1662. if (abnormal_termination() == FALSE) {
  1663. Counter += 20;
  1664. } else {
  1665. Counter += 1;
  1666. FAULT;
  1667. }
  1668. }
  1669. } except (EXCEPTION_EXECUTE_HANDLER) {
  1670. Counter += 10;
  1671. }
  1672. if (Counter != 13) {
  1673. DbgPrint("failed, count = %d\n", Counter);
  1674. } else {
  1675. DbgPrint("succeeded\n");
  1676. }
  1677. //
  1678. // Try/finally within a try/finally within a try/except that leads to a
  1679. // collided unwind during the exception dispatch.
  1680. //
  1681. DbgPrint(" test65...");
  1682. Counter = 0;
  1683. try {
  1684. Counter += 1;
  1685. try {
  1686. Counter += 1;
  1687. FAULT;
  1688. Counter += 20;
  1689. } finally {
  1690. if (abnormal_termination() == FALSE) {
  1691. Counter += 20;
  1692. } else {
  1693. try {
  1694. Counter += 1;
  1695. FAULT;
  1696. Counter += 20;
  1697. } finally {
  1698. if (abnormal_termination() == FALSE) {
  1699. Counter += 20;
  1700. } else {
  1701. Counter += 1;
  1702. }
  1703. }
  1704. }
  1705. FAULT;
  1706. }
  1707. } except (EXCEPTION_EXECUTE_HANDLER) {
  1708. Counter += 10;
  1709. }
  1710. if (Counter != 14) {
  1711. DbgPrint("failed, count = %d\n", Counter);
  1712. } else {
  1713. DbgPrint("succeeded\n");
  1714. }
  1715. //
  1716. // A call to a function with a try/finally that returns out of the try
  1717. // body.
  1718. //
  1719. DbgPrint(" test66...");
  1720. Counter = 0;
  1721. if ((test66sub(&Counter) + 1) != Counter) {
  1722. DbgPrint("failed, count = %d\n", Counter);
  1723. } else {
  1724. DbgPrint("succeeded\n");
  1725. }
  1726. //
  1727. // A call to a function with a try finally that returnss out of the
  1728. // termination hander.
  1729. //
  1730. DbgPrint(" test67...");
  1731. Counter = 0;
  1732. if (test67sub(&Counter) != Counter) {
  1733. DbgPrint("failed, count = %d\n", Counter);
  1734. } else {
  1735. DbgPrint("succeeded\n");
  1736. }
  1737. //
  1738. // Emulate C++ exception handing and frame consolidation.
  1739. //
  1740. DbgPrint(" test68...");
  1741. Counter = 0;
  1742. try {
  1743. Counter += 1;
  1744. ExceptionRecord.ExceptionCode = 0xbaadf00d;
  1745. ExceptionRecord.ExceptionInformation[4] = (ULONG_PTR)&Catch;
  1746. RtlRaiseException(&ExceptionRecord);
  1747. } except (Counter) {
  1748. Counter += 1;
  1749. }
  1750. if (Counter != 2) {
  1751. DbgPrint("failed, count = %d\n", Counter);
  1752. } else {
  1753. DbgPrint("succeeded\n");
  1754. }
  1755. //
  1756. // Announce end of exception test.
  1757. //
  1758. DbgBreakPoint();
  1759. DbgPrint("End of exception test\n");
  1760. return;
  1761. }
  1762. VOID
  1763. addtwo (
  1764. long First,
  1765. long Second,
  1766. long *Place
  1767. )
  1768. {
  1769. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1770. *Place = First + Second;
  1771. return;
  1772. }
  1773. VOID
  1774. bar1 (
  1775. IN NTSTATUS Status,
  1776. IN PLONG Counter
  1777. )
  1778. {
  1779. try {
  1780. foo1(Status);
  1781. } finally {
  1782. if (abnormal_termination() != FALSE) {
  1783. *Counter = 99;
  1784. } else {
  1785. *Counter = 100;
  1786. }
  1787. }
  1788. return;
  1789. }
  1790. VOID
  1791. bar2 (
  1792. IN PLONG BlackHole,
  1793. IN PLONG BadAddress,
  1794. IN PLONG Counter
  1795. )
  1796. {
  1797. try {
  1798. foo2(BlackHole, BadAddress);
  1799. } finally {
  1800. if (abnormal_termination() != FALSE) {
  1801. *Counter = 99;
  1802. } else {
  1803. *Counter = 100;
  1804. }
  1805. }
  1806. return;
  1807. }
  1808. ULONG64
  1809. Catch (
  1810. IN PEXCEPTION_RECORD ExceptionRecord
  1811. )
  1812. {
  1813. UNREFERENCED_PARAMETER(ExceptionRecord);
  1814. return 0;
  1815. }
  1816. VOID
  1817. dojump (
  1818. IN jmp_buf JumpBuffer,
  1819. IN PLONG Counter
  1820. )
  1821. {
  1822. try {
  1823. try {
  1824. *Counter += 1;
  1825. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1826. } finally {
  1827. *Counter += 1;
  1828. }
  1829. } finally {
  1830. *Counter += 1;
  1831. longjmp(JumpBuffer, 1);
  1832. }
  1833. }
  1834. VOID
  1835. eret(
  1836. IN NTSTATUS Status,
  1837. IN PLONG Counter
  1838. )
  1839. {
  1840. try {
  1841. try {
  1842. foo1(Status);
  1843. } except (((NTSTATUS)GetExceptionCode() == Status) ?
  1844. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
  1845. *Counter += 1;
  1846. return;
  1847. }
  1848. } finally {
  1849. *Counter += 1;
  1850. }
  1851. return;
  1852. }
  1853. VOID
  1854. except1 (
  1855. IN PLONG Counter
  1856. )
  1857. {
  1858. try {
  1859. *Counter += 5;
  1860. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1861. } except (except3(GetExceptionInformation(), Counter)) {
  1862. *Counter += 7;
  1863. }
  1864. *Counter += 9;
  1865. return;
  1866. }
  1867. ULONG
  1868. except2 (
  1869. IN PEXCEPTION_POINTERS ExceptionPointers,
  1870. IN PLONG Counter
  1871. )
  1872. {
  1873. PEXCEPTION_RECORD ExceptionRecord;
  1874. ExceptionRecord = ExceptionPointers->ExceptionRecord;
  1875. if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) &&
  1876. ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) {
  1877. *Counter += 11;
  1878. return EXCEPTION_EXECUTE_HANDLER;
  1879. } else {
  1880. *Counter += 13;
  1881. return EXCEPTION_CONTINUE_SEARCH;
  1882. }
  1883. }
  1884. ULONG
  1885. except3 (
  1886. IN PEXCEPTION_POINTERS ExceptionPointers,
  1887. IN PLONG Counter
  1888. )
  1889. {
  1890. PEXCEPTION_RECORD ExceptionRecord;
  1891. ExceptionRecord = ExceptionPointers->ExceptionRecord;
  1892. if ((ExceptionRecord->ExceptionCode == STATUS_INTEGER_OVERFLOW) &&
  1893. ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) {
  1894. *Counter += 17;
  1895. RtlRaiseStatus(STATUS_UNSUCCESSFUL);
  1896. } else if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) &&
  1897. ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) != 0)) {
  1898. *Counter += 19;
  1899. return EXCEPTION_CONTINUE_SEARCH;
  1900. }
  1901. *Counter += 23;
  1902. return EXCEPTION_EXECUTE_HANDLER;
  1903. }
  1904. VOID
  1905. foo1 (
  1906. IN NTSTATUS Status
  1907. )
  1908. {
  1909. //
  1910. // Raise exception.
  1911. //
  1912. RtlRaiseStatus(Status);
  1913. return;
  1914. }
  1915. VOID
  1916. foo2 (
  1917. IN PLONG BlackHole,
  1918. IN PLONG BadAddress
  1919. )
  1920. {
  1921. //
  1922. // Raise exception.
  1923. //
  1924. *BlackHole += *BadAddress;
  1925. return;
  1926. }
  1927. VOID
  1928. fret (
  1929. IN PLONG Counter
  1930. )
  1931. {
  1932. try {
  1933. try {
  1934. *Counter += 1;
  1935. } finally {
  1936. *Counter += 1;
  1937. return;
  1938. }
  1939. } finally {
  1940. *Counter += 1;
  1941. }
  1942. return;
  1943. }
  1944. LONG
  1945. Echo (
  1946. IN LONG Value
  1947. )
  1948. {
  1949. return Value;
  1950. }
  1951. VOID
  1952. Test61Part2 (
  1953. IN OUT PLONG Counter
  1954. )
  1955. {
  1956. try {
  1957. *Counter -= 1;
  1958. RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
  1959. } finally {
  1960. *Counter += 2;
  1961. *Counter += 5;
  1962. *Counter += 7;
  1963. }
  1964. }
  1965. double
  1966. SquareDouble (
  1967. IN double op
  1968. )
  1969. {
  1970. return op * op;
  1971. }
  1972. VOID
  1973. SquareDouble17E300 (
  1974. OUT PVOID output
  1975. )
  1976. {
  1977. double ans;
  1978. ans = SquareDouble (1.7e300);
  1979. *(double *) output = ans;
  1980. }
  1981. LONG
  1982. test66sub (
  1983. IN PLONG Counter
  1984. )
  1985. {
  1986. *Counter += 1;
  1987. try {
  1988. *Counter += 1;
  1989. return(*Counter);
  1990. } finally {
  1991. *Counter += 1;
  1992. }
  1993. }
  1994. LONG
  1995. test67sub (
  1996. IN PLONG Counter
  1997. )
  1998. {
  1999. *Counter += 1;
  2000. try {
  2001. *Counter += 1;
  2002. } finally {
  2003. *Counter += 1;
  2004. return(*Counter);
  2005. }
  2006. }