[ROSTESTS]
[reactos.git] / rostests / tests / zwcontinue / zwcontinue.c
1 #define WIN32_LEAN_AND_MEAN
2 #define STRICT
3 #include <windows.h>
4
5 #include <assert.h>
6 #include <setjmp.h>
7 #include <stddef.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <limits.h>
11 #include <time.h>
12
13 static unsigned int nRandBytes;
14
15 static int initrand(void)
16 {
17 unsigned int nRandMax;
18 unsigned int nRandMaxBits;
19 time_t tLoc;
20
21 nRandMax = RAND_MAX;
22
23 for(nRandMaxBits = 0; nRandMax != 0; nRandMax >>= 1, ++ nRandMaxBits);
24
25 nRandBytes = nRandMaxBits / CHAR_BIT;
26
27 assert(nRandBytes != 0);
28
29 srand((unsigned)(time(&tLoc) & UINT_MAX));
30
31 return 1;
32 }
33
34 static void randbytes(void * p, size_t n)
35 {
36 unsigned char * b;
37 size_t i;
38 int r = rand();
39
40 b = (unsigned char *)p;
41
42 for(i = 0; i < n; ++ i)
43 {
44 if(i % nRandBytes == 0)
45 r = rand();
46
47 b[i] = (unsigned char)(r & UCHAR_MAX);
48 r >>= CHAR_BIT;
49 }
50 }
51
52 static ULONG randULONG(void)
53 {
54 ULONG n;
55 randbytes(&n, sizeof(n));
56 return n;
57 }
58
59 #ifdef _M_IX86
60 #define ZWC_SEGMENT_BITS (0xFFFF)
61 #define ZWC_EFLAGS_BITS (0x3C0CD5)
62 #endif
63
64 static jmp_buf jmpbuf;
65 static CONTEXT continueContext;
66
67 extern void continuePoint(void);
68 extern void check(CONTEXT *);
69 extern LONG NTAPI ZwContinue(IN CONTEXT *, IN BOOLEAN);
70
71 void check(CONTEXT * actualContext)
72 {
73 #ifdef _M_IX86
74 assert(actualContext->ContextFlags == CONTEXT_FULL);
75
76 /* Random data segments */
77 assert
78 (
79 (actualContext->SegGs & ZWC_SEGMENT_BITS) ==
80 (continueContext.SegGs & ZWC_SEGMENT_BITS)
81 );
82
83 assert
84 (
85 (actualContext->SegFs & ZWC_SEGMENT_BITS) ==
86 (continueContext.SegFs & ZWC_SEGMENT_BITS)
87 );
88
89 assert
90 (
91 (actualContext->SegEs & ZWC_SEGMENT_BITS) ==
92 (continueContext.SegEs & ZWC_SEGMENT_BITS)
93 );
94
95 assert
96 (
97 (actualContext->SegDs & ZWC_SEGMENT_BITS) ==
98 (continueContext.SegDs & ZWC_SEGMENT_BITS)
99 );
100
101 /* Integer registers */
102 assert(actualContext->Edi == continueContext.Edi);
103 assert(actualContext->Esi == continueContext.Esi);
104 assert(actualContext->Ebx == continueContext.Ebx);
105 printf("%s %lX : %lX\n", "Edx", actualContext->Edx, continueContext.Edx);
106 //assert(actualContext->Edx == continueContext.Edx);
107 assert(actualContext->Ecx == continueContext.Ecx);
108 assert(actualContext->Eax == continueContext.Eax);
109
110 /* Control registers and segments */
111 assert(actualContext->Ebp == continueContext.Ebp);
112 assert(actualContext->Eip == continueContext.Eip);
113
114 assert
115 (
116 (actualContext->SegCs & ZWC_SEGMENT_BITS) ==
117 (continueContext.SegCs & ZWC_SEGMENT_BITS)
118 );
119
120 assert
121 (
122 (actualContext->EFlags & ZWC_EFLAGS_BITS) ==
123 (continueContext.EFlags & ZWC_EFLAGS_BITS)
124 );
125
126 assert(actualContext->Esp == continueContext.Esp);
127
128 assert
129 (
130 (actualContext->SegSs & ZWC_SEGMENT_BITS) ==
131 (continueContext.SegSs & ZWC_SEGMENT_BITS)
132 );
133 #endif
134
135 longjmp(jmpbuf, 1);
136 }
137
138 int main(void)
139 {
140 initrand();
141
142 /* First time */
143 if(setjmp(jmpbuf) == 0)
144 {
145 CONTEXT bogus;
146
147 continueContext.ContextFlags = CONTEXT_FULL;
148 GetThreadContext(GetCurrentThread(), &continueContext);
149
150 #ifdef _M_IX86
151 continueContext.ContextFlags = CONTEXT_FULL;
152
153 /* Fill the integer registers with random values */
154 continueContext.Edi = randULONG();
155 continueContext.Esi = randULONG();
156 continueContext.Ebx = randULONG();
157 continueContext.Edx = randULONG();
158 continueContext.Ecx = randULONG();
159 continueContext.Eax = randULONG();
160 continueContext.Ebp = randULONG();
161
162 /* Randomize all the allowed flags (determined experimentally with WinDbg) */
163 continueContext.EFlags = randULONG() & 0x3C0CD5;
164
165 /* Randomize the stack pointer as much as possible */
166 continueContext.Esp =
167 (ULONG)(((ULONG_PTR)&bogus) & 0xFFFFFFFF) +
168 sizeof(bogus) -
169 (randULONG() & 0xF) * 4;
170
171 /* continuePoint() is implemented in assembler */
172 continueContext.Eip = (ULONG)((ULONG_PTR)continuePoint & 0xFFFFFFF);
173
174 /* Can't do a lot about segments */
175 #endif
176
177 ZwContinue(&continueContext, FALSE);
178 }
179 /* Second time */
180 else
181 return 0;
182
183 assert(0);
184 return 1;
185 }