source: trunk/testapp/exceptions/seh/except.c@ 21999

Last change on this file since 21999 was 21999, checked in by dmik, 13 years ago

kernel32: Make SEH work in OS/2 context.

See #82 for details.

  • Property svn:executable set to *
File size: 3.6 KB
Line 
1#include <stdio.h>
2#include <windows.h>
3#include <excpt.h>
4
5#ifndef _MSC_VER
6
7#include <odinlx.h>
8
9int _main();
10int _argc;
11char **_argv;
12
13int WIN32API WinMain(HANDLE hInstance,
14 HANDLE hPrevInstance,
15 LPSTR lpCmdLine,
16 int nCmdShow)
17{
18 return _main(_argc, _argv);
19}
20
21int main(int argc, char **argv)
22{
23 _argc = argc;
24 _argv = argv;
25#ifdef ODIN_FORCE_WIN32_TIB
26 ForceWin32TIB();
27#endif
28 RegisterLxExe(WinMain, NULL);
29}
30
31#else
32#define _main main
33#endif
34
35int testCode = 0;
36
37int tries = 3;
38
39int exc_filter(DWORD code, DWORD filtercode, PEXCEPTION_POINTERS pPtrs)
40{
41 PEXCEPTION_RECORD pRec = pPtrs->ExceptionRecord;
42
43 printf("Filter: code %08lx, filtercode %08lx\n", code, filtercode);
44 printf("ExceptionCode %p\n", pRec->ExceptionCode);
45 printf("ExceptionAddress %p\n", pRec->ExceptionAddress);
46 printf("NumberParameters %d\n", pRec->NumberParameters);
47
48 if (code == filtercode)
49 {
50 if (testCode == 4 && tries)
51 {
52 --tries;
53 return EXCEPTION_CONTINUE_EXECUTION;
54 }
55
56 return EXCEPTION_EXECUTE_HANDLER;
57 }
58
59 return EXCEPTION_CONTINUE_SEARCH;
60}
61
62void throw_EXCEPTION_INT_DIVIDE_BY_ZERO()
63{
64 printf("Throwing EXCEPTION_INT_DIVIDE_BY_ZERO...\n");
65 int x = 0;
66 volatile int y = 4 / x;
67}
68
69void throw_EXCEPTION_ACCESS_VIOLATION()
70{
71 printf("Throwing EXCEPTION_ACCESS_VIOLATION...\n");
72 volatile int *x = 0;
73 *x = 0;
74}
75
76int _main(int argc, char **argv)
77{
78 testCode = argc > 1 ? atoi(argv[1]) : 0;
79
80 switch (testCode)
81 {
82 case 1:
83 printf("Target: Throw EXCEPTION_ACCESS_VIOLATION from inner __try\n"
84 "and catch it in inner __except.\n\n");
85 break;
86 case 2:
87 printf("Target: Throw EXCEPTION_INT_DIVIDE_BY_ZERO from inner __try\n"
88 "and catch it in outer __except.\n\n");
89 break;
90 case 3:
91 printf("Target: Throw EXCEPTION_INT_DIVIDE_BY_ZERO from outer __try\n"
92 "and catch it in outer __except.\n\n");
93 break;
94 case 4:
95 printf("Target: Throw EXCEPTION_INT_DIVIDE_BY_ZERO from outer __try,\n"
96 "fix it in the handler and continue execution.\n\n");
97 break;
98 default:
99 printf("Invalid test code %d\n", testCode);
100 return 1;
101 }
102
103 __try
104 {
105 if (testCode == 3 || testCode == 4)
106 {
107 throw_EXCEPTION_INT_DIVIDE_BY_ZERO();
108
109 printf("FAILED: No outer exception!\n");
110 return 1;
111 }
112
113 __try
114 {
115 if (testCode == 1)
116 throw_EXCEPTION_ACCESS_VIOLATION();
117 else if (testCode == 2)
118 throw_EXCEPTION_INT_DIVIDE_BY_ZERO();
119
120 printf("FAILED: No inner exception!\n");
121 return 1;
122 }
123 __except(exc_filter(GetExceptionCode(),
124 EXCEPTION_ACCESS_VIOLATION,
125 exception_info()))
126 {
127 // handle exception
128 printf("Inner exception handled.\n");
129 }
130 }
131 __except(exc_filter(GetExceptionCode(),
132 EXCEPTION_INT_DIVIDE_BY_ZERO,
133 exception_info()))
134 {
135 if (testCode == 4 && tries)
136 {
137 printf("FAILED: Outer exception (tries = %d)!\n", tries);
138 return 1;
139 }
140
141 // handle exception
142 printf("Outer exception handled.\n");
143 }
144
145 printf("Return.\n");
146
147 return 0;
148}
Note: See TracBrowser for help on using the repository browser.