ReactOS 0.4.15-dev-6042-g2eb6700
NtContinue.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for NtContinue
5 * PROGRAMMER:
6 */
7
8#include "precomp.h"
9
10#include <setjmp.h>
11#include <time.h>
12
13#ifdef _MSC_VER
14#pragma runtime_checks("s", off)
15#endif
16
17#define ok_eq_print(value, expected, spec) ok((value) == (expected), #value " = " spec ", expected " spec "\n", value, expected)
18#define ok_eq_hex(value, expected) ok_eq_print(value, expected, "%lx")
19#define ok_eq_hex64(value, expected) ok_eq_print(value, expected, "%I64x")
20#define ok_eq_xmm(value, expected) ok((value).Low == (expected).Low, #value " = %I64x'%08I64x, expected %I64x'%08I64x\n", (value).Low, (value).High, (expected).Low, (expected).High)
21
22#ifdef _M_IX86
23#define NTC_SEGMENT_BITS (0xFFFF)
24#define NTC_EFLAGS_BITS (0x3C0CD5)
25#endif
26
27void continuePoint(void);
28
31static unsigned int nRandBytes;
32
33static int initrand(void)
34{
35 unsigned int nRandMax;
36 unsigned int nRandMaxBits;
37 time_t tLoc;
38
39 nRandMax = RAND_MAX;
40 for(nRandMaxBits = 0; nRandMax != 0; nRandMax >>= 1, ++ nRandMaxBits);
41 nRandBytes = nRandMaxBits / CHAR_BIT;
42 //assert(nRandBytes != 0);
43 srand((unsigned)(time(&tLoc) & UINT_MAX));
44 return 1;
45}
46
47static void randbytes(void * p, size_t n)
48{
49 unsigned char * b;
50 size_t i;
51 int r = rand();
52
53 b = (unsigned char *)p;
54 for(i = 0; i < n; ++ i)
55 {
56 if(i % nRandBytes == 0)
57 r = rand();
58 b[i] = (unsigned char)(r & UCHAR_MAX);
59 r >>= CHAR_BIT;
60 }
61}
62
63static ULONG randULONG(void)
64{
65 ULONG n;
66 randbytes(&n, sizeof(n));
67 return n;
68}
69
70#ifdef _M_AMD64
71static ULONG64 randULONG64(void)
72{
73 return (ULONG64)randULONG() << 32 | randULONG();
74}
75#endif
76
77void check(CONTEXT * pContext)
78{
79#ifdef _M_IX86
80 ok(pContext->ContextFlags == CONTEXT_FULL,
81 "ContextFlags=0x%lx\n", pContext->ContextFlags);
82
83 /* Random data segments */
84 ok((pContext->SegGs & NTC_SEGMENT_BITS) ==
85 (continueContext.SegGs & NTC_SEGMENT_BITS),
86 "SegGs=0x%lx / 0x%lx\n", pContext->SegGs, continueContext.SegGs);
87
88 ok((pContext->SegFs & NTC_SEGMENT_BITS) ==
89 (continueContext.SegFs & NTC_SEGMENT_BITS),
90 "SegFs=0x%lx / 0x%lx\n", pContext->SegFs, continueContext.SegFs);
91
92 ok((pContext->SegEs & NTC_SEGMENT_BITS) ==
93 (continueContext.SegEs & NTC_SEGMENT_BITS),
94 "SegEs=0x%lx / 0x%lx\n", pContext->SegEs, continueContext.SegEs);
95
96 ok((pContext->SegDs & NTC_SEGMENT_BITS) ==
97 (continueContext.SegDs & NTC_SEGMENT_BITS),
98 "SegDs=0x%lx / 0x%lx\n", pContext->SegDs, continueContext.SegDs);
99
100 /* Integer registers */
101 ok(pContext->Edi == continueContext.Edi,
102 "Edi: 0x%lx != 0x%lx\n", pContext->Edi, continueContext.Edi);
103 ok(pContext->Esi == continueContext.Esi,
104 "Esi: 0x%lx != 0x%lx\n", pContext->Esi, continueContext.Esi);
105 ok(pContext->Ebx == continueContext.Ebx,
106 "Ebx: 0x%lx != 0x%lx\n", pContext->Ebx, continueContext.Ebx);
107 ok(pContext->Edx == continueContext.Edx,
108 "Edx: 0x%lx != 0x%lx\n", pContext->Edx, continueContext.Edx);
109 ok(pContext->Ecx == continueContext.Ecx,
110 "Ecx: 0x%lx != 0x%lx\n", pContext->Ecx, continueContext.Ecx);
111 ok(pContext->Eax == continueContext.Eax,
112 "Eax: 0x%lx != 0x%lx\n", pContext->Eax, continueContext.Eax);
113
114 /* Control registers and segments */
115 ok(pContext->Ebp == continueContext.Ebp,
116 "Ebp: 0x%lx != 0x%lx\n", pContext->Ebp, continueContext.Ebp);
117 ok(pContext->Eip == continueContext.Eip,
118 "Eip: 0x%lx != 0x%lx\n", pContext->Eip, continueContext.Eip);
119 ok(pContext->Esp == continueContext.Esp,
120 "Esp: 0x%lx != 0x%lx\n", pContext->Esp, continueContext.Esp);
121
122 ok((pContext->SegCs & NTC_SEGMENT_BITS) ==
123 (continueContext.SegCs & NTC_SEGMENT_BITS),
124 "SegCs: 0x%lx != 0x%lx\n", pContext->SegCs, continueContext.SegCs);
125
126 ok((pContext->EFlags & NTC_EFLAGS_BITS) ==
127 (continueContext.EFlags & NTC_EFLAGS_BITS),
128 "EFlags: 0x%lx != 0x%lx\n", pContext->EFlags, continueContext.EFlags);
129
130 ok((pContext->SegSs & NTC_SEGMENT_BITS) ==
131 (continueContext.SegSs & NTC_SEGMENT_BITS),
132 "SegSs: 0x%lx != 0x%lx\n", pContext->SegSs, continueContext.SegSs);
133#else
135 ok_eq_hex(pContext->MxCsr, continueContext.MxCsr);
137 ok_eq_hex(pContext->SegDs, 0x2B);
138 ok_eq_hex(pContext->SegEs, 0x2B);
139 ok_eq_hex(pContext->SegFs, 0x53);
140 ok_eq_hex(pContext->SegGs, 0x2B);
142 ok_eq_hex(pContext->EFlags, (continueContext.EFlags & ~0x1C0000) | 0x202);
143
144 ok_eq_hex64(pContext->Rax, continueContext.Rax);
145 ok_eq_hex64(pContext->Rdx, continueContext.Rdx);
146 ok_eq_hex64(pContext->Rbx, continueContext.Rbx);
147 ok_eq_hex64(pContext->Rsp, continueContext.Rsp);
148 ok_eq_hex64(pContext->Rbp, continueContext.Rbp);
149 ok_eq_hex64(pContext->Rsi, continueContext.Rsi);
150 ok_eq_hex64(pContext->Rdi, continueContext.Rdi);
151 ok_eq_hex64(pContext->R8, continueContext.R8);
152 ok_eq_hex64(pContext->R9, continueContext.R9);
156 ok_eq_hex64(pContext->R13, continueContext.R13);
157 ok_eq_hex64(pContext->R14, continueContext.R14);
158 ok_eq_hex64(pContext->R15, continueContext.R15);
159 ok_eq_xmm(pContext->Xmm0, continueContext.Xmm0);
160 ok_eq_xmm(pContext->Xmm1, continueContext.Xmm1);
161 ok_eq_xmm(pContext->Xmm2, continueContext.Xmm2);
162 ok_eq_xmm(pContext->Xmm3, continueContext.Xmm3);
163 ok_eq_xmm(pContext->Xmm4, continueContext.Xmm4);
164 ok_eq_xmm(pContext->Xmm5, continueContext.Xmm5);
165 ok_eq_xmm(pContext->Xmm6, continueContext.Xmm6);
166 ok_eq_xmm(pContext->Xmm7, continueContext.Xmm7);
167 ok_eq_xmm(pContext->Xmm8, continueContext.Xmm8);
168 ok_eq_xmm(pContext->Xmm9, continueContext.Xmm9);
169 ok_eq_xmm(pContext->Xmm10, continueContext.Xmm10);
170 ok_eq_xmm(pContext->Xmm11, continueContext.Xmm11);
171 ok_eq_xmm(pContext->Xmm12, continueContext.Xmm12);
172 ok_eq_xmm(pContext->Xmm13, continueContext.Xmm13);
173 ok_eq_xmm(pContext->Xmm14, continueContext.Xmm14);
174 ok_eq_xmm(pContext->Xmm15, continueContext.Xmm15);
175
176 // Clear the frame register to prevent unwinding, which is broken
177 ((_JUMP_BUFFER*)&jmpbuf)->Frame = 0;
178#endif
179
180 /* Return where we came from */
181 longjmp(jmpbuf, 1);
182}
183
185{
186 initrand();
187
188 RtlFillMemory(&continueContext, sizeof(continueContext), 0xBBBBBBBB);
189
190 /* First time */
191 if(setjmp(jmpbuf) == 0)
192 {
193 CONTEXT bogus[2];
194
195 RtlFillMemory(&bogus, sizeof(bogus), 0xCCCCCCCC);
196
199
200#ifdef _M_IX86
202
203 /* Fill the integer registers with random values */
211
212 /* Randomize all the allowed flags (determined experimentally with WinDbg) */
213 continueContext.EFlags = randULONG() & 0x3C0CD5;
214
215 /* Randomize the stack pointer as much as possible */
216 continueContext.Esp = (ULONG)(((ULONG_PTR)&bogus) & 0xFFFFFFFF) +
217 sizeof(bogus) - (randULONG() & 0xF) * 4;
218
219 /* continuePoint() is implemented in assembler */
221
222 /* Can't do a lot about segments */
223#elif defined(_M_AMD64)
225
226 /* Fill the integer registers with random values */
227 PULONG64 Registers = &continueContext.Rax;
228 for (ULONG i = 0; i < 16; i++)
229 {
230 Registers[i] = randULONG64();
231 }
232
233 /* Fill the XMM registers with random values */
234 Registers = (PULONG64)&continueContext.Xmm0;
235 for (ULONG i = 0; i < 32; i++)
236 {
237 Registers[i] = randULONG64();
238 }
239
240 continueContext.Dr0 = randULONG64() & 0xFFFF;
241 continueContext.Dr1 = randULONG64() & 0xFFFF;
242 continueContext.Dr2 = randULONG64() & 0xFFFF;
243 continueContext.Dr3 = randULONG64() & 0xFFFF;
244 continueContext.Dr6 = randULONG64() & 0xFFFF;
245 continueContext.Dr7 = randULONG64() & 0xFFFF;
246
247 /* Randomize all the allowed flags (determined experimentally with WinDbg) */
248 continueContext.EFlags = randULONG64() & 0x3C0CD5;
249
250 /* Randomize the stack pointer as much as possible */
251 continueContext.Rsp = (((ULONG_PTR)&bogus)) + (randULONG() & 0xF) * 16;
253
254 /* continuePoint() is implemented in assembler */
256#endif
257
259 ok(0, "should never get here\n");
260 }
261
262 /* Second time */
263 return;
264}
#define ALIGN_DOWN_BY(size, align)
void continuePoint(void)
static unsigned int nRandBytes
Definition: NtContinue.c:31
#define ok_eq_hex(value, expected)
Definition: NtContinue.c:18
#define ok_eq_hex64(value, expected)
Definition: NtContinue.c:19
static ULONG randULONG(void)
Definition: NtContinue.c:63
static void randbytes(void *p, size_t n)
Definition: NtContinue.c:47
static int initrand(void)
Definition: NtContinue.c:33
#define ok_eq_xmm(value, expected)
Definition: NtContinue.c:20
static jmp_buf jmpbuf
Definition: NtContinue.c:29
static CONTEXT continueContext
Definition: NtContinue.c:30
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define setjmp
Definition: setjmp.h:209
_JBTYPE jmp_buf[_JBLEN]
Definition: setjmp.h:186
#define FALSE
Definition: types.h:117
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:501
unsigned char
Definition: typeof.h:29
#define CHAR_BIT
Definition: urlcache.c:62
#define check(expected, result)
Definition: dplayx.c:32
__kernel_time_t time_t
Definition: linux.h:252
#define ULONG_PTR
Definition: config.h:101
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define UCHAR_MAX
Definition: limits.h:25
#define UINT_MAX
Definition: limits.h:41
void __cdecl srand(_In_ unsigned int _Seed)
#define RAND_MAX
Definition: stdlib.h:87
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define b
Definition: ke_i.h:79
__u16 time
Definition: mkdosfs.c:8
#define for
Definition: utility.h:88
unsigned __int64 * PULONG64
Definition: imports.h:198
unsigned __int64 ULONG64
Definition: imports.h:198
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1373
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
#define CONTEXT_FULL
Definition: nt_native.h:1375
NTSTATUS NTAPI NtContinue(IN PCONTEXT Context, IN BOOLEAN TestAlert)
Definition: except.c:220
ULONG Esp
Definition: nt_native.h:1479
ULONG SegFs
Definition: nt_native.h:1454
ULONG Dr3
Definition: nt_native.h:1437
ULONG Dr1
Definition: nt_native.h:1435
ULONG Edx
Definition: nt_native.h:1466
ULONG Esi
Definition: nt_native.h:1464
ULONG Ebp
Definition: nt_native.h:1475
ULONG ContextFlags
Definition: nt_native.h:1426
ULONG R8
Definition: ke.h:263
ULONG Dr6
Definition: nt_native.h:1438
ULONG SegSs
Definition: nt_native.h:1480
ULONG Ecx
Definition: nt_native.h:1467
ULONG Dr0
Definition: nt_native.h:1434
ULONG Eip
Definition: nt_native.h:1476
ULONG R12
Definition: ke.h:267
ULONG SegCs
Definition: nt_native.h:1477
ULONG SegDs
Definition: nt_native.h:1456
ULONG R9
Definition: ke.h:264
ULONG EFlags
Definition: nt_native.h:1478
ULONG SegGs
Definition: nt_native.h:1453
ULONG Dr2
Definition: nt_native.h:1436
ULONG R10
Definition: ke.h:265
ULONG Eax
Definition: nt_native.h:1468
ULONG SegEs
Definition: nt_native.h:1455
ULONG Ebx
Definition: nt_native.h:1465
ULONG Edi
Definition: nt_native.h:1463
ULONG R11
Definition: ke.h:266
ULONG Dr7
Definition: nt_native.h:1439
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148