ReactOS  0.4.15-dev-5492-g47f3a4e
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 
27 void continuePoint(void);
28 
29 static jmp_buf jmpbuf;
31 static unsigned int nRandBytes;
32 
33 static 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 
47 static 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 
63 static ULONG randULONG(void)
64 {
65  ULONG n;
66  randbytes(&n, sizeof(n));
67  return n;
68 }
69 
70 #ifdef _M_AMD64
71 static ULONG64 randULONG64(void)
72 {
73  return (ULONG64)randULONG() << 32 | randULONG();
74 }
75 #endif
76 
77 void 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);
136  ok_eq_hex(pContext->SegCs, continueContext.SegCs);
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);
141  ok_eq_hex(pContext->SegSs, continueContext.SegSs);
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);
153  ok_eq_hex64(pContext->R10, continueContext.R10);
154  ok_eq_hex64(pContext->R11, continueContext.R11);
155  ok_eq_hex64(pContext->R12, continueContext.R12);
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 */
220  continueContext.Eip = (ULONG)((ULONG_PTR)continuePoint & 0xFFFFFFF);
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 }
ULONG Esp
Definition: nt_native.h:1479
static unsigned int nRandBytes
Definition: NtContinue.c:31
ULONG Eip
Definition: nt_native.h:1476
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
ULONG Ecx
Definition: nt_native.h:1467
START_TEST(NtContinue)
Definition: NtContinue.c:184
void __cdecl srand(_In_ unsigned int _Seed)
GLdouble n
Definition: glext.h:7729
#define CHAR_BIT
Definition: urlcache.c:62
ULONG SegGs
Definition: nt_native.h:1453
int __MINGW_NOTHROW __cdecl setjmp(jmp_buf _Buf)
ULONG SegFs
Definition: nt_native.h:1454
__u16 time
Definition: mkdosfs.c:366
ULONG SegDs
Definition: nt_native.h:1456
#define ok_eq_hex64(value, expected)
Definition: NtContinue.c:19
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
ULONG Dr7
Definition: nt_native.h:1439
ULONG Dr3
Definition: nt_native.h:1437
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:501
ULONG R8
Definition: ke.h:263
#define FALSE
Definition: types.h:117
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1148
NTSTATUS NTAPI NtContinue(IN PCONTEXT Context, IN BOOLEAN TestAlert)
Definition: except.c:220
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
ULONG SegEs
Definition: nt_native.h:1455
ULONG Esi
Definition: nt_native.h:1464
ULONG Dr1
Definition: nt_native.h:1435
ULONG SegCs
Definition: nt_native.h:1477
#define ok_eq_xmm(value, expected)
Definition: NtContinue.c:20
ULONG Edx
Definition: nt_native.h:1466
unsigned char
Definition: typeof.h:29
ULONG R9
Definition: ke.h:264
ULONG EFlags
Definition: nt_native.h:1478
ULONG Dr2
Definition: nt_native.h:1436
ULONG Ebx
Definition: nt_native.h:1465
#define b
Definition: ke_i.h:79
ULONG ContextFlags
Definition: nt_native.h:1426
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define CONTEXT_FULL
Definition: nt_native.h:1375
static CONTEXT continueContext
Definition: NtContinue.c:30
static ULONG randULONG(void)
Definition: NtContinue.c:63
ULONG R11
Definition: ke.h:266
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
void continuePoint(void)
#define for
Definition: utility.h:88
void check(CONTEXT *pContext)
Definition: NtContinue.c:77
unsigned __int64 ULONG64
Definition: imports.h:198
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1373
ULONG Eax
Definition: nt_native.h:1468
_JBTYPE jmp_buf[_JBLEN]
Definition: setjmp.h:186
#define RAND_MAX
Definition: stdlib.h:87
#define ALIGN_DOWN_BY(size, align)
#define UINT_MAX
Definition: limits.h:41
static int initrand(void)
Definition: NtContinue.c:33
ULONG SegSs
Definition: nt_native.h:1480
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
__kernel_time_t time_t
Definition: linux.h:252
#define UCHAR_MAX
Definition: limits.h:25
#define ok(value,...)
Definition: atltest.h:57
ULONG Dr6
Definition: nt_native.h:1438
ULONG R12
Definition: ke.h:267
ULONG Dr0
Definition: nt_native.h:1434
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
ULONG R10
Definition: ke.h:265
static void randbytes(void *p, size_t n)
Definition: NtContinue.c:47
unsigned __int64 * PULONG64
Definition: imports.h:198
GLfloat GLfloat p
Definition: glext.h:8902
static jmp_buf jmpbuf
Definition: NtContinue.c:29
#define ok_eq_hex(value, expected)
Definition: NtContinue.c:18
ULONG Ebp
Definition: nt_native.h:1475
ULONG Edi
Definition: nt_native.h:1463