From 9ca7155a562c9dcd23c691593e200d3441e4115b Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 15 May 2011 21:15:38 +0000 Subject: [PATCH] [ApiTest] - Add a test for stack corruption when in window procedure call out. svn path=/trunk/; revision=51773 --- rostests/apitests/user32/CMakeLists.txt | 1 + rostests/apitests/user32/WndProc.c | 100 ++++++++++++++++++ rostests/apitests/user32/testlist.c | 2 + .../apitests/user32/user32_apitest.rbuild | 1 + 4 files changed, 104 insertions(+) create mode 100644 rostests/apitests/user32/WndProc.c diff --git a/rostests/apitests/user32/CMakeLists.txt b/rostests/apitests/user32/CMakeLists.txt index ac394df6d3b..d57524afd53 100644 --- a/rostests/apitests/user32/CMakeLists.txt +++ b/rostests/apitests/user32/CMakeLists.txt @@ -14,6 +14,7 @@ list(APPEND SOURCE ScrollDC.c ScrollWindowEx.c SetCursorPos.c + WndProc.c testlist.c user32_apitest.rc) diff --git a/rostests/apitests/user32/WndProc.c b/rostests/apitests/user32/WndProc.c new file mode 100644 index 00000000000..bc5437088fc --- /dev/null +++ b/rostests/apitests/user32/WndProc.c @@ -0,0 +1,100 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for mismatch with function prototype in window procedure callback. + * PROGRAMMERS: + */ + +#include +#include +#include + +/* Used wine Redraw test for proof in principle. */ + +/* Global variables to trigger exit from loop */ +static int redrawComplete, WMPAINT_count; + +/* + Force stack corruption when calling from assumed window procedure callback. + Adding (6 and) more will force exception faults and terminate the test program. + The test is with five and this is safe for windows. + + But,,,, ReactOS compiled with GCC can handle this,,,,,, + */ +static LRESULT WINAPI redraw_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD ExtraData,DWORD ExtraData1,DWORD ExtraData2,DWORD ExtraData3) +{ + switch (msg) + { + case WM_PAINT: + trace("doing WM_PAINT %d\n", WMPAINT_count); + WMPAINT_count++; + if (WMPAINT_count > 10 && redrawComplete == 0) + { + PAINTSTRUCT ps; + BeginPaint(hwnd, &ps); + EndPaint(hwnd, &ps); + return 1; + } + /* + This will force one stack corruption "ret" fault with normal window + procedure callback. + */ +#ifdef __MINGW32__ + asm ("movl $0, %eax\n\t" + "leave\n\t" + "ret"); +#else +//#ifdef _MSC_VER + __asm + { + mov eax, 0 + leave + ret + } +#endif + } + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +static void test_wndproc(void) +{ + WNDCLASSA cls; + HWND hwndMain; + + cls.style = CS_DBLCLKS; + cls.lpfnWndProc = (WNDPROC)redraw_window_procA; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleA(0); + cls.hIcon = 0; + cls.hCursor = LoadCursorA(0, IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = "RedrawWindowClass"; + + if (!RegisterClassA(&cls)) + { + trace("Register failed %d\n", (int)GetLastError()); + return; + } + + hwndMain = CreateWindowA("RedrawWindowClass", "Main Window", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, 100, 100, NULL, NULL, 0, NULL); + + ok( WMPAINT_count == 0, "Multiple unexpected WM_PAINT calls %d\n", WMPAINT_count); + ShowWindow(hwndMain, SW_SHOW); + ok( WMPAINT_count == 0, "Multiple unexpected WM_PAINT calls %d\n", WMPAINT_count); + RedrawWindow(hwndMain, NULL,NULL,RDW_UPDATENOW | RDW_ALLCHILDREN); + ok( WMPAINT_count == 1 || broken(WMPAINT_count == 0), /* sometimes on win9x */ + "Multiple unexpected WM_PAINT calls %d\n", WMPAINT_count); + redrawComplete = TRUE; + ok( WMPAINT_count < 10, "RedrawWindow (RDW_UPDATENOW) never completed (%d)\n", WMPAINT_count); + + /* clean up */ + DestroyWindow( hwndMain); +} + +START_TEST(WndProc) +{ + test_wndproc(); +} diff --git a/rostests/apitests/user32/testlist.c b/rostests/apitests/user32/testlist.c index cb95521ee22..fe27138d10b 100644 --- a/rostests/apitests/user32/testlist.c +++ b/rostests/apitests/user32/testlist.c @@ -15,6 +15,7 @@ extern void func_GetPeekMessage(void); extern void func_DeferWindowPos(void); extern void func_GetKeyState(void); extern void func_SetCursorPos(void); +extern void func_WndProc(void); const struct test winetest_testlist[] = { @@ -28,6 +29,7 @@ const struct test winetest_testlist[] = { "DeferWindowPos", func_DeferWindowPos }, { "GetKeyState", func_GetKeyState }, { "SetCursorPos", func_SetCursorPos }, + { "WndProc", func_WndProc }, { 0, 0 } }; diff --git a/rostests/apitests/user32/user32_apitest.rbuild b/rostests/apitests/user32/user32_apitest.rbuild index e703e7905ca..fdd83b50d76 100644 --- a/rostests/apitests/user32/user32_apitest.rbuild +++ b/rostests/apitests/user32/user32_apitest.rbuild @@ -20,6 +20,7 @@ GetPeekMessage.c DeferWindowPos.c SetCursorPos.c + WndProc.c