merge in kjk_hyperion's ZwContinue test
authorRoyce Mitchell III <royce3@ev1.net>
Thu, 1 Jul 2004 23:58:44 +0000 (23:58 +0000)
committerRoyce Mitchell III <royce3@ev1.net>
Thu, 1 Jul 2004 23:58:44 +0000 (23:58 +0000)
svn path=/trunk/; revision=9963

reactos/apps/tests/zwcontinue/.cvsignore [new file with mode: 0644]
reactos/apps/tests/zwcontinue/Makefile [new file with mode: 0644]
reactos/apps/tests/zwcontinue/i386/.cvsignore [new file with mode: 0644]
reactos/apps/tests/zwcontinue/i386/zwcontinue.asm [new file with mode: 0644]
reactos/apps/tests/zwcontinue/zwcontinue.c [new file with mode: 0644]

diff --git a/reactos/apps/tests/zwcontinue/.cvsignore b/reactos/apps/tests/zwcontinue/.cvsignore
new file mode 100644 (file)
index 0000000..d63774a
--- /dev/null
@@ -0,0 +1,6 @@
+*.o
+*.d
+*.exe
+*.coff
+*.sym
+*.map
diff --git a/reactos/apps/tests/zwcontinue/Makefile b/reactos/apps/tests/zwcontinue/Makefile
new file mode 100644 (file)
index 0000000..a99bb3d
--- /dev/null
@@ -0,0 +1,23 @@
+# $Id: Makefile,v 1.2 2004/07/01 23:58:44 royce Exp $
+
+PATH_TO_TOP = ../../..
+
+TARGET_NORC = yes
+
+TARGET_TYPE = program
+
+TARGET_APPTYPE = console
+
+TARGET_NAME = zwcontinue
+
+TARGET_OBJECTS = $(TARGET_NAME).o i386/$(TARGET_NAME).o
+
+TARGET_CFLAGS = -Wall -Werror -D__USE_W32API
+
+TARGET_SDKLIBS = ntdll.a
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+# EOF
diff --git a/reactos/apps/tests/zwcontinue/i386/.cvsignore b/reactos/apps/tests/zwcontinue/i386/.cvsignore
new file mode 100644 (file)
index 0000000..6142305
--- /dev/null
@@ -0,0 +1,2 @@
+*.o
+*.d
diff --git a/reactos/apps/tests/zwcontinue/i386/zwcontinue.asm b/reactos/apps/tests/zwcontinue/i386/zwcontinue.asm
new file mode 100644 (file)
index 0000000..c811641
--- /dev/null
@@ -0,0 +1,48 @@
+cpu 486
+segment .text use32
+
+extern _check
+
+global _continuePoint
+_continuePoint:
+ push ss
+ push dword 0
+ pushfd
+ push cs
+ push _continuePoint
+ push ebp
+
+ push eax
+ push ecx
+ push edx
+ push ebx
+ push esi
+ push edi
+
+ push ds
+ push es
+ push fs
+ push gs
+
+ ; TODO: floating point state
+ sub esp, 70h
+
+ ; Debug registers
+ sub esp, 18h
+
+ push dword 00010007h
+
+ ; Fill the Esp field
+ lea eax, [esp+0CCh]
+ lea ecx, [esp+0C4h]
+ mov [ecx], eax
+
+ ; Call the function that will compare the current context with the expected one
+ cld
+ push esp
+ call _check
+
+ ; check() must not return
+ int 3
+
+; EOF
diff --git a/reactos/apps/tests/zwcontinue/zwcontinue.c b/reactos/apps/tests/zwcontinue/zwcontinue.c
new file mode 100644 (file)
index 0000000..637f022
--- /dev/null
@@ -0,0 +1,185 @@
+#define WIN32_LEAN_AND_MEAN
+#define STRICT
+#include <windows.h>
+
+#include <assert.h>
+#include <setjmp.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <time.h>
+
+static unsigned int nRandBytes;
+
+static int initrand(void)
+{
+ unsigned int nRandMax;
+ unsigned int nRandMaxBits;
+ time_t tLoc;
+
+ nRandMax = RAND_MAX;
+
+ for(nRandMaxBits = 0; nRandMax != 0; nRandMax >>= 1, ++ nRandMaxBits);
+
+ nRandBytes = nRandMaxBits / CHAR_BIT;
+
+ assert(nRandBytes != 0);
+
+ srand((unsigned)(time(&tLoc) & UINT_MAX));
+
+ return 1;
+}
+
+static void randbytes(void * p, size_t n)
+{
+ unsigned char * b;
+ size_t i;
+ int r;
+
+ b = (unsigned char *)p;
+
+ for(i = 0; i < n; ++ i)
+ {
+  if(i % nRandBytes == 0)
+   r = rand();
+
+  b[i] = (unsigned char)(r & UCHAR_MAX);
+  r >>= CHAR_BIT;
+ }
+}
+
+static ULONG randULONG(void)
+{
+ ULONG n;
+ randbytes(&n, sizeof(n));
+ return n;
+}
+
+#ifdef _M_IX86
+#define ZWC_SEGMENT_BITS (0xFFFF)
+#define ZWC_EFLAGS_BITS  (0x3C0CD5)
+#endif
+
+static jmp_buf jmpbuf;
+static CONTEXT continueContext;
+
+extern void continuePoint(void);
+extern void check(CONTEXT *);
+extern LONG NTAPI ZwContinue(IN CONTEXT *, IN BOOLEAN);
+
+void check(CONTEXT * actualContext)
+{
+#ifdef _M_IX86
+ assert(actualContext->ContextFlags == CONTEXT_FULL);
+
+ /* Random data segments */
+ assert
+ (
+  (actualContext->SegGs & ZWC_SEGMENT_BITS) ==
+  (continueContext.SegGs & ZWC_SEGMENT_BITS)
+ );
+
+ assert
+ (
+  (actualContext->SegFs & ZWC_SEGMENT_BITS) ==
+  (continueContext.SegFs & ZWC_SEGMENT_BITS)
+ );
+
+ assert
+ (
+  (actualContext->SegEs & ZWC_SEGMENT_BITS) ==
+  (continueContext.SegEs & ZWC_SEGMENT_BITS)
+ );
+
+ assert
+ (
+  (actualContext->SegDs & ZWC_SEGMENT_BITS) ==
+  (continueContext.SegDs & ZWC_SEGMENT_BITS)
+ );
+
+ /* Integer registers */
+ assert(actualContext->Edi == continueContext.Edi);
+ assert(actualContext->Esi == continueContext.Esi);
+ assert(actualContext->Ebx == continueContext.Ebx);
+ printf("%s %lX : %lX\n", "Edx", actualContext->Edx, continueContext.Edx);
+ //assert(actualContext->Edx == continueContext.Edx);
+ assert(actualContext->Ecx == continueContext.Ecx);
+ assert(actualContext->Eax == continueContext.Eax);
+
+ /* Control registers and segments */
+ assert(actualContext->Ebp == continueContext.Ebp);
+ assert(actualContext->Eip == continueContext.Eip);
+
+ assert
+ (
+  (actualContext->SegCs & ZWC_SEGMENT_BITS) ==
+  (continueContext.SegCs & ZWC_SEGMENT_BITS)
+ );
+
+ assert
+ (
+  (actualContext->EFlags & ZWC_EFLAGS_BITS) ==
+  (continueContext.EFlags & ZWC_EFLAGS_BITS)
+ );
+ assert(actualContext->Esp == continueContext.Esp);
+ assert
+ (
+  (actualContext->SegSs & ZWC_SEGMENT_BITS) ==
+  (continueContext.SegSs & ZWC_SEGMENT_BITS)
+ );
+#endif
+
+ longjmp(jmpbuf, 1);
+}
+
+int main(void)
+{
+ initrand();
+
+ /* First time */
+ if(setjmp(jmpbuf) == 0)
+ {
+  CONTEXT bogus;
+
+  continueContext.ContextFlags = CONTEXT_FULL;
+  GetThreadContext(GetCurrentThread(), &continueContext);
+
+#ifdef _M_IX86
+  continueContext.ContextFlags = CONTEXT_FULL;
+
+  /* Fill the integer registers with random values */
+  continueContext.Edi = randULONG();
+  continueContext.Esi = randULONG();
+  continueContext.Ebx = randULONG();
+  continueContext.Edx = randULONG();
+  continueContext.Ecx = randULONG();
+  continueContext.Eax = randULONG();
+  continueContext.Ebp = randULONG();
+
+  /* Randomize all the allowed flags (determined experimentally with WinDbg) */
+  continueContext.EFlags = randULONG() & 0x3C0CD5;
+
+  /* Randomize the stack pointer as much as possible */
+  continueContext.Esp =
+   (ULONG)(((ULONG_PTR)&bogus) & 0xFFFFFFFF) +
+   sizeof(bogus) -
+   (randULONG() & 0xF) * 4;
+
+  /* continuePoint() is implemented in assembler */
+  continueContext.Eip = (ULONG)((ULONG_PTR)continuePoint & 0xFFFFFFF);
+
+  /* Can't do a lot about segments */
+#endif
+
+  ZwContinue(&continueContext, FALSE);
+ }
+ /* Second time */
+ else
+  return 0;
+
+ assert(0);
+ return 1;
+}