Windows NT 4.0 source code leak
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.

398 lines
8.2 KiB

4 years ago
  1. // utxcpt2.c - user mode structured exception handling test 2
  2. //
  3. // Exception test from Markl.
  4. //
  5. #include <ntos.h>
  6. VOID
  7. ExceptionTest (
  8. )
  9. //
  10. // This routine tests the structured exception handling capabilities of the
  11. // MS C compiler and the NT exception handling facilities.
  12. //
  13. {
  14. EXCEPTION_RECORD ExceptionRecord;
  15. LONG Counter;
  16. ULONG rv;
  17. //
  18. // Announce start of exception test.
  19. //
  20. DbgPrint("Start of exception test\n");
  21. //
  22. // Initialize exception record.
  23. //
  24. ExceptionRecord.ExceptionCode = (NTSTATUS)49;
  25. ExceptionRecord.ExceptionRecord = (PEXCEPTION_RECORD)NULL;
  26. ExceptionRecord.NumberParameters = 1;
  27. ExceptionRecord.ExceptionInformation[0] = 9;
  28. //
  29. // Simply try statement with a finally clause that is entered sequentially.
  30. //
  31. DbgPrint("t1...");
  32. Counter = 0;
  33. try {
  34. Counter += 1;
  35. } finally {
  36. if (abnormal_termination() == 0) {
  37. Counter += 1;
  38. }
  39. }
  40. if (Counter != 2) {
  41. DbgPrint("BUG Finally clause executed as result of unwind\n");
  42. }
  43. DbgPrint("done\n");
  44. //
  45. // Simple try statement with an exception clause that is never executed
  46. // because there is no exception raised in the try clause.
  47. //
  48. // goto a;
  49. DbgPrint("t2...");
  50. Counter = 0;
  51. try {
  52. //a: Counter += 1;
  53. Counter += 1;
  54. } except (Counter) {
  55. Counter += 1;
  56. }
  57. if (Counter != 1) {
  58. DbgPrint("BUG Exception clause executed when it shouldn't be\n");
  59. }
  60. DbgPrint("done\n");
  61. //
  62. // Simple try statement with an exception handler that is never executed
  63. // because the exception expression continues execution.
  64. //
  65. DbgPrint("t3...");
  66. Counter = 0;
  67. ExceptionRecord.ExceptionFlags = 0;
  68. try {
  69. Counter -= 1;
  70. RtlRaiseException(&ExceptionRecord);
  71. } except (Counter) {
  72. Counter -= 1;
  73. }
  74. if (Counter != - 1) {
  75. DbgPrint("BUG Exception clause executed when it shouldn't be\n");
  76. }
  77. DbgPrint("done\n");
  78. //
  79. // Simple try statement with an exception clause that is always executed.
  80. //
  81. DbgPrint("t4...");
  82. Counter = 0;
  83. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  84. try {
  85. Counter += 1;
  86. RtlRaiseException(&ExceptionRecord);
  87. } except (Counter) {
  88. Counter += 1;
  89. }
  90. if (Counter != 2) {
  91. DbgPrint("BUG Exception clause not executed when it should be\n");
  92. }
  93. DbgPrint("done\n");
  94. //
  95. // Simply try statement with a finally clause that is entered as the
  96. // result of an exception.
  97. //
  98. DbgPrint("t5...");
  99. Counter = 0;
  100. ExceptionRecord.ExceptionFlags = 0;
  101. try {
  102. try {
  103. Counter += 1;
  104. RtlRaiseException(&ExceptionRecord);
  105. } finally {
  106. if (abnormal_termination() != 0) {
  107. Counter += 1;
  108. }
  109. }
  110. } except (Counter) {
  111. if (Counter == 2) {
  112. Counter += 1;
  113. }
  114. }
  115. if (Counter != 3) {
  116. DbgPrint("BUG Finally clause executed as result of sequential exit\n");
  117. }
  118. DbgPrint("done\n");
  119. //
  120. // Simple try that calls a function which raises an exception.
  121. //
  122. DbgPrint("t6...");
  123. Counter = 0;
  124. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  125. try {
  126. VOID foo(IN NTSTATUS Status);
  127. Counter += 1;
  128. foo(STATUS_ACCESS_VIOLATION);
  129. } except (exception_code() == STATUS_ACCESS_VIOLATION) {
  130. Counter += 1;
  131. }
  132. if (Counter != 2) {
  133. DbgPrint("BUG Exception clause not executed when it should be\n");
  134. }
  135. DbgPrint("done\n");
  136. //
  137. // Simple try that calls a function which calls a function that
  138. // raises an exception. The first function has a finally clause
  139. // that must be executed for this test to work.
  140. //
  141. DbgPrint("t7...");
  142. Counter = 0;
  143. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  144. try {
  145. VOID bar(IN NTSTATUS Status, IN PULONG Counter);
  146. bar(STATUS_ACCESS_VIOLATION, &Counter);
  147. } except (exception_code() == STATUS_ACCESS_VIOLATION) {
  148. if (Counter != 99) {
  149. DbgPrint("BUG finally in called procedure not executed\n");
  150. }
  151. }
  152. DbgPrint("done\n");
  153. //
  154. // A try within an except
  155. //
  156. DbgPrint("t8...");
  157. Counter = 0;
  158. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  159. try {
  160. foo(STATUS_ACCESS_VIOLATION);
  161. } except (exception_code() == STATUS_ACCESS_VIOLATION) {
  162. Counter++;
  163. try {
  164. foo(STATUS_SUCCESS);
  165. } except (exception_code() == STATUS_SUCCESS) {
  166. if ( Counter != 1 ) {
  167. DbgPrint("BUG Previous Handler not Entered\n");
  168. }
  169. Counter++;
  170. }
  171. }
  172. if (Counter != 2) {
  173. DbgPrint("BUG Both Handlers not entered\n");
  174. }
  175. DbgPrint("done\n");
  176. //
  177. // A goto from an exception clause that needs to pass
  178. // through a finally
  179. //
  180. DbgPrint("t9...");
  181. Counter = 0;
  182. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  183. try {
  184. try {
  185. foo(STATUS_ACCESS_VIOLATION);
  186. } except (exception_code() == STATUS_ACCESS_VIOLATION) {
  187. Counter++;
  188. goto t9;
  189. }
  190. } finally {
  191. Counter++;
  192. }
  193. t9:
  194. if (Counter != 2) {
  195. DbgPrint("BUG Finally and Exception Handlers not entered\n");
  196. }
  197. DbgPrint("done\n");
  198. //
  199. // A goto from an exception clause that needs to pass
  200. // through a finally
  201. //
  202. DbgPrint("t10...");
  203. Counter = 0;
  204. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  205. try {
  206. try {
  207. Counter++;
  208. } finally {
  209. Counter++;
  210. goto t10;
  211. }
  212. } finally {
  213. Counter++;
  214. }
  215. t10:
  216. if (Counter != 3) {
  217. DbgPrint("BUG Both Finally Handlers not entered\n");
  218. }
  219. DbgPrint("done\n");
  220. //
  221. // A return from an except clause
  222. //
  223. DbgPrint("t11...");
  224. Counter = 0;
  225. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  226. try {
  227. ULONG eret(IN NTSTATUS Status, IN PULONG Counter);
  228. Counter++;
  229. rv = eret(STATUS_ACCESS_VIOLATION, &Counter);
  230. } finally {
  231. Counter++;
  232. }
  233. if (Counter != 4) {
  234. DbgPrint("BUG Both Finally Handlers and Exception Handler not entered\n");
  235. }
  236. if (rv != 0xDEADBEEF) {
  237. DbgPrint("BUG rv is wrong\n");
  238. }
  239. DbgPrint("done\n");
  240. //
  241. // A return from a finally clause
  242. //
  243. DbgPrint("t12...");
  244. Counter = 0;
  245. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  246. try {
  247. VOID fret(IN PULONG Counter);
  248. Counter++;
  249. fret(&Counter);
  250. } finally {
  251. Counter++;
  252. }
  253. if (Counter != 5) {
  254. DbgPrint("BUG All three Finally Handlers not entered\n");
  255. }
  256. DbgPrint("done\n");
  257. //
  258. // Announce end of exception test.
  259. //
  260. DbgPrint("End of exception test\n");
  261. return;
  262. }
  263. main()
  264. {
  265. ExceptionTest ();
  266. }
  267. NTSTATUS
  268. ZwLastChance (
  269. IN PEXCEPTION_RECORD ExceptionRecord,
  270. IN PCONTEXT ContextRecord
  271. )
  272. {
  273. DbgPrint("ZwLastChance Entered\n");;
  274. }
  275. VOID
  276. fret(
  277. IN PULONG Counter
  278. )
  279. {
  280. try {
  281. try {
  282. *Counter += 1;
  283. } finally {
  284. *Counter += 1;
  285. return;
  286. }
  287. } finally {
  288. *Counter += 1;
  289. }
  290. }
  291. ULONG
  292. eret(
  293. IN NTSTATUS Status,
  294. IN PULONG Counter
  295. )
  296. {
  297. EXCEPTION_RECORD ExceptionRecord;
  298. try {
  299. try {
  300. foo(Status);
  301. } except (exception_code() == Status) {
  302. *Counter += 1;
  303. return 0xDEADBEEF;
  304. }
  305. } finally {
  306. *Counter += 1;
  307. }
  308. }
  309. VOID
  310. bar(
  311. IN NTSTATUS Status,
  312. IN PULONG Counter
  313. )
  314. {
  315. EXCEPTION_RECORD ExceptionRecord;
  316. try {
  317. foo(Status);
  318. }
  319. finally {
  320. if (abnormal_termination() != 0) {
  321. *Counter = 99;
  322. } else {
  323. *Counter = 100;
  324. }
  325. }
  326. }
  327. VOID
  328. foo(
  329. IN NTSTATUS Status
  330. )
  331. {
  332. EXCEPTION_RECORD ExceptionRecord;
  333. LONG Counter;
  334. //
  335. // Initialize exception record.
  336. //
  337. ExceptionRecord.ExceptionFlags = 0;
  338. ExceptionRecord.ExceptionCode = Status;
  339. ExceptionRecord.ExceptionRecord = (PEXCEPTION_RECORD)NULL;
  340. ExceptionRecord.NumberParameters = 0;
  341. RtlRaiseException(&ExceptionRecord);
  342. }