diff --git a/rostests/apitests/crt/crtdll_crt_apitest.cmake b/rostests/apitests/crt/crtdll_crt_apitest.cmake index 669f6d580d2..f739fb50ed9 100644 --- a/rostests/apitests/crt/crtdll_crt_apitest.cmake +++ b/rostests/apitests/crt/crtdll_crt_apitest.cmake @@ -454,7 +454,7 @@ list(APPEND SOURCE_CRTDLL # signal.c # sin.c # sinh.c -# sprintf.c + sprintf.c # sqrt.c # srand.c # sscanf.c diff --git a/rostests/apitests/crt/msvcrt_crt_apitest.cmake b/rostests/apitests/crt/msvcrt_crt_apitest.cmake index 7e2f9aaeace..5c75c235a09 100644 --- a/rostests/apitests/crt/msvcrt_crt_apitest.cmake +++ b/rostests/apitests/crt/msvcrt_crt_apitest.cmake @@ -1156,7 +1156,7 @@ list(APPEND SOURCE_MSVCRT # signal.c # sin.c # sinh.c -# sprintf.c + sprintf.c # sprintf_s.c # sqrt.c # srand.c diff --git a/rostests/apitests/crt/ntdll_crt_apitest.cmake b/rostests/apitests/crt/ntdll_crt_apitest.cmake index c6fae82feb4..3b3560ec3b9 100644 --- a/rostests/apitests/crt/ntdll_crt_apitest.cmake +++ b/rostests/apitests/crt/ntdll_crt_apitest.cmake @@ -80,7 +80,7 @@ list(APPEND SOURCE_NTDLL # pow.c # qsort.c # sin.c -# sprintf.c + sprintf.c # sqrt.c # sscanf.c # strcat.c diff --git a/rostests/apitests/crt/sprintf.c b/rostests/apitests/crt/sprintf.c new file mode 100644 index 00000000000..790f9b4df75 --- /dev/null +++ b/rostests/apitests/crt/sprintf.c @@ -0,0 +1,271 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for sprintf + * PROGRAMMER: Thomas Faber + */ + +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#pragma GCC diagnostic ignored "-Wnonnull" +#endif + +#define StartSeh() ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY { +#define EndSeh(ExpectedStatus) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus) + +static +PVOID +AllocateGuarded( + SIZE_T SizeRequested) +{ + NTSTATUS Status; + SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE); + PVOID VirtualMemory = NULL; + PCHAR StartOfBuffer; + + Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS); + + if (!NT_SUCCESS(Status)) + return NULL; + + Size -= PAGE_SIZE; + if (Size) + { + Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + Size = 0; + Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); + ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); + return NULL; + } + } + + StartOfBuffer = VirtualMemory; + StartOfBuffer += Size - SizeRequested; + + return StartOfBuffer; +} + +static +VOID +FreeGuarded( + PVOID Pointer) +{ + NTSTATUS Status; + PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer); + SIZE_T Size = 0; + + Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); + ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); +} + +/* NOTE: This test is not only used for all the CRT apitests, but also for + * user32's wsprintf. Make sure to test them all */ +START_TEST(sprintf) +{ + NTSTATUS ExceptionStatus; + int Length; + CHAR Buffer[128]; + PCHAR String; + + /* basic parameter tests */ + StartSeh() + Length = sprintf(NULL, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + Length = sprintf(NULL, ""); + ok_int(Length, 0); +#if defined(TEST_CRTDLL) || defined(TEST_USER32) + EndSeh(STATUS_ACCESS_VIOLATION); +#else + EndSeh(STATUS_SUCCESS); +#endif + + StartSeh() + Length = sprintf(NULL, "Hello"); + ok_int(Length, 5); +#if defined(TEST_CRTDLL) || defined(TEST_USER32) + EndSeh(STATUS_ACCESS_VIOLATION); +#else + EndSeh(STATUS_SUCCESS); +#endif + + /* some basic formats */ + Length = sprintf(Buffer, "abcde"); + ok_str(Buffer, "abcde"); + ok_int(Length, 5); + + Length = sprintf(Buffer, "%%"); + ok_str(Buffer, "%"); + ok_int(Length, 1); + + Length = sprintf(Buffer, "%"); + ok_str(Buffer, ""); + ok_int(Length, 0); + + Length = sprintf(Buffer, "%%%"); + ok_str(Buffer, "%"); + ok_int(Length, 1); + + Length = sprintf(Buffer, "%d", 8); + ok_str(Buffer, "8"); + ok_int(Length, 1); + + Length = sprintf(Buffer, "%s", "hello"); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + + /* field width for %s */ + Length = sprintf(Buffer, "%8s", "hello"); + ok_str(Buffer, " hello"); + ok_int(Length, 8); + + Length = sprintf(Buffer, "%4s", "hello"); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + + Length = sprintf(Buffer, "%-8s", "hello"); + ok_str(Buffer, "hello "); + ok_int(Length, 8); + + Length = sprintf(Buffer, "%-5s", "hello"); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + + Length = sprintf(Buffer, "%0s", "hello"); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + + Length = sprintf(Buffer, "%-0s", "hello"); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + + /* TODO: wsprintf can't do * */ +#ifndef TEST_USER32 + Length = sprintf(Buffer, "%*s", -8, "hello"); + ok_str(Buffer, "hello "); + ok_int(Length, 8); +#endif + + /* precision for %s */ + Length = sprintf(Buffer, "%.s", "hello"); + ok_str(Buffer, ""); + ok_int(Length, 0); + + Length = sprintf(Buffer, "%.0s", "hello"); + ok_str(Buffer, ""); + ok_int(Length, 0); + + Length = sprintf(Buffer, "%.10s", "hello"); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + + Length = sprintf(Buffer, "%.5s", "hello"); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + + Length = sprintf(Buffer, "%.4s", "hello"); + ok_str(Buffer, "hell"); + ok_int(Length, 4); + +#ifndef TEST_USER32 + StartSeh() + Length = sprintf(Buffer, "%.*s", -1, "hello"); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + EndSeh(STATUS_SUCCESS); +#endif + + String = AllocateGuarded(6); + if (!String) + { + skip("Guarded allocation failure\n"); + return; + } + + strcpy(String, "hello"); + StartSeh() + Length = sprintf(Buffer, "%.8s", String); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + EndSeh(STATUS_SUCCESS); + + StartSeh() + Length = sprintf(Buffer, "%.6s", String); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + EndSeh(STATUS_SUCCESS); + + StartSeh() + Length = sprintf(Buffer, "%.5s", String); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + EndSeh(STATUS_SUCCESS); + + StartSeh() + Length = sprintf(Buffer, "%.4s", String); + ok_str(Buffer, "hell"); + ok_int(Length, 4); + EndSeh(STATUS_SUCCESS); + + /* TODO: wsprintf can't do *, and also seems to use strlen despite a + * precision being given */ +#ifndef TEST_USER32 + String[5] = '!'; + StartSeh() + Length = sprintf(Buffer, "%.5s", String); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + EndSeh(STATUS_SUCCESS); + + StartSeh() + Length = sprintf(Buffer, "%.6s", String); + ok_str(Buffer, "hello!"); + ok_int(Length, 6); + EndSeh(STATUS_SUCCESS); + + StartSeh() + Length = sprintf(Buffer, "%.*s", 5, String); + ok_str(Buffer, "hello"); + ok_int(Length, 5); + EndSeh(STATUS_SUCCESS); + + StartSeh() + Length = sprintf(Buffer, "%.*s", 6, String); + ok_str(Buffer, "hello!"); + ok_int(Length, 6); + EndSeh(STATUS_SUCCESS); + + /* both field width and precision */ + StartSeh() + Length = sprintf(Buffer, "%8.5s", String); + ok_str(Buffer, " hello"); + ok_int(Length, 8); + EndSeh(STATUS_SUCCESS); + + StartSeh() + Length = sprintf(Buffer, "%-*.6s", -8, String); + ok_str(Buffer, "hello! "); + ok_int(Length, 8); + EndSeh(STATUS_SUCCESS); + + StartSeh() + Length = sprintf(Buffer, "%*.*s", -8, 6, String); + ok_str(Buffer, "hello! "); + ok_int(Length, 8); + EndSeh(STATUS_SUCCESS); +#endif + + FreeGuarded(String); +} diff --git a/rostests/apitests/crt/testlist.c b/rostests/apitests/crt/testlist.c index c3e317af66b..4c2546cf60a 100644 --- a/rostests/apitests/crt/testlist.c +++ b/rostests/apitests/crt/testlist.c @@ -5,10 +5,12 @@ #define STANDALONE #include "wine/test.h" +extern void func_sprintf(void); extern void func_strcpy(void); const struct test winetest_testlist[] = { + { "sprintf", func_sprintf }, { "strcpy", func_strcpy }, #if defined(TEST_CRTDLL) || defined(TEST_MSVCRT) || defined(TEST_STATIC_CRT) // ... diff --git a/rostests/apitests/user32/CMakeLists.txt b/rostests/apitests/user32/CMakeLists.txt index aa4ada96edb..a83c34bc59b 100644 --- a/rostests/apitests/user32/CMakeLists.txt +++ b/rostests/apitests/user32/CMakeLists.txt @@ -1,8 +1,4 @@ -add_definitions(-D_DLL -D__USE_CRTIMP) - -set_rc_compiler() - list(APPEND SOURCE helper.c DeferWindowPos.c @@ -15,16 +11,17 @@ list(APPEND SOURCE RealGetWindowClass.c ScrollDC.c ScrollWindowEx.c - SetCursorPos.c SetActiveWindow.c + SetCursorPos.c SystemParametersInfo.c TrackMouseEvent.c WndProc.c + wsprintf.c testlist.c user32_apitest.rc) add_executable(user32_apitest ${SOURCE}) -target_link_libraries(user32_apitest wine) +target_link_libraries(user32_apitest wine ${PSEH_LIB}) set_module_type(user32_apitest win32cui) add_importlibs(user32_apitest gdi32 user32 msvcrt kernel32 ntdll) add_cd_file(TARGET user32_apitest DESTINATION reactos/bin FOR all) diff --git a/rostests/apitests/user32/testlist.c b/rostests/apitests/user32/testlist.c index fef794dc007..f1d248fedd2 100644 --- a/rostests/apitests/user32/testlist.c +++ b/rostests/apitests/user32/testlist.c @@ -5,39 +5,41 @@ #define STANDALONE #include "wine/test.h" +extern void func_DeferWindowPos(void); extern void func_desktop(void); +extern void func_GetIconInfo(void); +extern void func_GetKeyState(void); +extern void func_GetPeekMessage(void); +extern void func_GetSystemMetrics(void); extern void func_InitializeLpkHooks(void); extern void func_RealGetWindowClass(void); extern void func_ScrollDC(void); extern void func_ScrollWindowEx(void); -extern void func_GetSystemMetrics(void); -extern void func_GetIconInfo(void); -extern void func_GetPeekMessage(void); -extern void func_DeferWindowPos(void); -extern void func_GetKeyState(void); -extern void func_SetCursorPos(void); extern void func_SetActiveWindow(void); +extern void func_SetCursorPos(void); extern void func_SystemParametersInfo(void); extern void func_TrackMouseEvent(void); extern void func_WndProc(void); +extern void func_wsprintf(void); const struct test winetest_testlist[] = { + { "desktop", func_desktop }, + { "DeferWindowPos", func_DeferWindowPos }, + { "GetIconInfo", func_GetIconInfo }, + { "GetKeyState", func_GetKeyState }, + { "GetPeekMessage", func_GetPeekMessage }, + { "GetSystemMetrics", func_GetSystemMetrics }, { "InitializeLpkHooks", func_InitializeLpkHooks }, { "RealGetWindowClass", func_RealGetWindowClass }, { "ScrollDC", func_ScrollDC }, { "ScrollWindowEx", func_ScrollWindowEx }, - { "GetSystemMetrics", func_GetSystemMetrics }, - { "GetIconInfo", func_GetIconInfo }, - { "GetPeekMessage", func_GetPeekMessage }, - { "DeferWindowPos", func_DeferWindowPos }, - { "desktop", func_desktop } , - { "GetKeyState", func_GetKeyState }, - { "SetCursorPos", func_SetCursorPos }, { "SetActiveWindow", func_SetActiveWindow }, + { "SetCursorPos", func_SetCursorPos }, { "SystemParametersInfo", func_SystemParametersInfo }, { "TrackMouseEvent", func_TrackMouseEvent }, { "WndProc", func_WndProc }, + { "wsprintf", func_wsprintf }, { 0, 0 } }; diff --git a/rostests/apitests/user32/wsprintf.c b/rostests/apitests/user32/wsprintf.c new file mode 100644 index 00000000000..2c0258063dc --- /dev/null +++ b/rostests/apitests/user32/wsprintf.c @@ -0,0 +1,4 @@ +#define sprintf wsprintfA +#define func_sprintf func_wsprintf +#define TEST_USER32 1 +#include "../crt/sprintf.c"