From: Timo Kreuzer Date: Wed, 25 Aug 2010 10:15:01 +0000 (+0000) Subject: [ROSTESTS] X-Git-Tag: ReactOS-0.3.12~129 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=14d5a266b3791731adfab16cb0f1d27fdac87322 [ROSTESTS] - Add wine style ntdll_apitest and move test for ZwContinue there svn path=/trunk/; revision=48621 --- diff --git a/rostests/apitests/directory.rbuild b/rostests/apitests/directory.rbuild index f5816b8aaf0..14446375bef 100644 --- a/rostests/apitests/directory.rbuild +++ b/rostests/apitests/directory.rbuild @@ -14,6 +14,10 @@ + + + + diff --git a/rostests/apitests/ntdll/ZwContinue.c b/rostests/apitests/ntdll/ZwContinue.c new file mode 100644 index 00000000000..0b181e31be1 --- /dev/null +++ b/rostests/apitests/ntdll/ZwContinue.c @@ -0,0 +1,173 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for ZwContinue + * PROGRAMMER: + */ + +#include +#include +#include +#include + +#ifdef _M_IX86 +#define ZWC_SEGMENT_BITS (0xFFFF) +#define ZWC_EFLAGS_BITS (0x3C0CD5) +#endif + +void continuePoint(void); +LONG NTAPI ZwContinue(IN CONTEXT *, IN BOOLEAN); + +static jmp_buf jmpbuf; +static CONTEXT continueContext; +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 = rand(); + + 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; +} + +void check(CONTEXT * pContext) +{ +#ifdef _M_IX86 + ok(pContext->ContextFlags == CONTEXT_FULL, + "ContextFlags=0x%lx\n", pContext->ContextFlags); + + /* Random data segments */ + ok((pContext->SegGs & ZWC_SEGMENT_BITS) == + (continueContext.SegGs & ZWC_SEGMENT_BITS), + "SegGs=0x%lx / 0x%lx\n", pContext->SegGs, continueContext.SegGs); + + ok((pContext->SegFs & ZWC_SEGMENT_BITS) == + (continueContext.SegFs & ZWC_SEGMENT_BITS), + "SegFs=0x%lx / 0x%lx\n", pContext->SegFs, continueContext.SegFs); + + ok((pContext->SegEs & ZWC_SEGMENT_BITS) == + (continueContext.SegEs & ZWC_SEGMENT_BITS), + "SegEs=0x%lx / 0x%lx\n", pContext->SegEs, continueContext.SegEs); + + ok((pContext->SegDs & ZWC_SEGMENT_BITS) == + (continueContext.SegDs & ZWC_SEGMENT_BITS), + "SegDs=0x%lx / 0x%lx\n", pContext->SegDs, continueContext.SegDs); + + /* Integer registers */ + ok(pContext->Edi == continueContext.Edi, + "Edi: 0x%lx != 0x%lx\n", pContext->Edi, continueContext.Edi); + ok(pContext->Esi == continueContext.Esi, + "Esi: 0x%lx != 0x%lx\n", pContext->Esi, continueContext.Esi); + ok(pContext->Ebx == continueContext.Ebx, + "Ebx: 0x%lx != 0x%lx\n", pContext->Ebx, continueContext.Ebx); + ok(pContext->Edx == continueContext.Edx, + "Edx: 0x%lx != 0x%lx\n", pContext->Edx, continueContext.Edx); + ok(pContext->Ecx == continueContext.Ecx, + "Ecx: 0x%lx != 0x%lx\n", pContext->Ecx, continueContext.Ecx); + ok(pContext->Eax == continueContext.Eax, + "Eax: 0x%lx != 0x%lx\n", pContext->Eax, continueContext.Eax); + + /* Control registers and segments */ + ok(pContext->Ebp == continueContext.Ebp, + "Ebp: 0x%lx != 0x%lx\n", pContext->Ebp, continueContext.Ebp); + ok(pContext->Eip == continueContext.Eip, + "Eip: 0x%lx != 0x%lx\n", pContext->Eip, continueContext.Eip); + ok(pContext->Esp == continueContext.Esp, + "Esp: 0x%lx != 0x%lx\n", pContext->Esp, continueContext.Esp); + + ok((pContext->SegCs & ZWC_SEGMENT_BITS) == + (continueContext.SegCs & ZWC_SEGMENT_BITS), + "SegCs: 0x%lx != 0x%lx\n", pContext->SegCs, continueContext.SegCs); + + ok((pContext->EFlags & ZWC_EFLAGS_BITS) == + (continueContext.EFlags & ZWC_EFLAGS_BITS), + "EFlags: 0x%lx != 0x%lx\n", pContext->EFlags, continueContext.EFlags); + + ok((pContext->SegSs & ZWC_SEGMENT_BITS) == + (continueContext.SegSs & ZWC_SEGMENT_BITS), + "SegSs: 0x%lx != 0x%lx\n", pContext->SegSs, continueContext.SegSs); +#endif + + /* Return where we came from */ + longjmp(jmpbuf, 1); +} + +void Test_ZwContinue() +{ + 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); + ok(0, "should never get here\n"); + } + + /* Second time */ + return; +} + +START_TEST(ZwContinue) +{ + Test_ZwContinue(); +} + diff --git a/rostests/apitests/ntdll/i386/ZwContinue.asm b/rostests/apitests/ntdll/i386/ZwContinue.asm new file mode 100644 index 00000000000..829fd24285b --- /dev/null +++ b/rostests/apitests/ntdll/i386/ZwContinue.asm @@ -0,0 +1,48 @@ +; cpu 486 +segment .text use32 + +extern _check + +global _continuePoint +_continuePoint: + push ss + push dword 0 + pushfd + push cs + push dword _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/rostests/apitests/ntdll/ntdll_apitest.rbuild b/rostests/apitests/ntdll/ntdll_apitest.rbuild new file mode 100644 index 00000000000..f9e2d64de17 --- /dev/null +++ b/rostests/apitests/ntdll/ntdll_apitest.rbuild @@ -0,0 +1,18 @@ + + + + + . + wine + ntdll + pseh + testlist.c + + ZwContinue.c + + + ZwContinue.asm + + + + diff --git a/rostests/apitests/ntdll/testlist.c b/rostests/apitests/ntdll/testlist.c new file mode 100644 index 00000000000..0bd842dbc88 --- /dev/null +++ b/rostests/apitests/ntdll/testlist.c @@ -0,0 +1,16 @@ +#define WIN32_LEAN_AND_MEAN +#define __ROS_LONG64__ +#include + +#define STANDALONE +#include "wine/test.h" + +extern void func_ZwContinue(void); + +const struct test winetest_testlist[] = +{ + { "ZwContinue", func_ZwContinue }, + + { 0, 0 } +}; +