From d42fce3c823d7ffb2a33ad546a64b141299956f0 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sun, 21 Jan 2018 22:39:53 +0100 Subject: [PATCH] [MSVCRT_WINETEST] Sync with Wine 3.0. CORE-14225 --- .../rostests/winetests/msvcrt/CMakeLists.txt | 2 +- modules/rostests/winetests/msvcrt/file.c | 148 +++++++++++++++++- modules/rostests/winetests/msvcrt/locale.c | 122 ++++----------- modules/rostests/winetests/msvcrt/printf.c | 22 +-- modules/rostests/winetests/msvcrt/scanf.c | 36 ++++- modules/rostests/winetests/msvcrt/string.c | 136 ++++++++++++++++ modules/rostests/winetests/msvcrt/time.c | 25 +-- 7 files changed, 376 insertions(+), 115 deletions(-) diff --git a/modules/rostests/winetests/msvcrt/CMakeLists.txt b/modules/rostests/winetests/msvcrt/CMakeLists.txt index f50ed55eae5..c456d9c0038 100644 --- a/modules/rostests/winetests/msvcrt/CMakeLists.txt +++ b/modules/rostests/winetests/msvcrt/CMakeLists.txt @@ -28,7 +28,7 @@ if(USE_CLANG_CL OR (NOT MSVC)) endif() set_module_type(msvcrt_winetest win32cui) -add_importlibs(msvcrt_winetest msvcrt kernel32) +add_importlibs(msvcrt_winetest advapi32 msvcrt kernel32) if(MSVC) target_link_libraries(msvcrt_winetest oldnames) diff --git a/modules/rostests/winetests/msvcrt/file.c b/modules/rostests/winetests/msvcrt/file.c index b2d32a7c1ff..d27e0d49f7c 100644 --- a/modules/rostests/winetests/msvcrt/file.c +++ b/modules/rostests/winetests/msvcrt/file.c @@ -21,6 +21,7 @@ #include "precomp.h" +#include #include #include #include @@ -212,7 +213,7 @@ static void test_readmode( BOOL ascii_mode ) static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9\r\n\r\nA,B,C,D,E\r\nX,Y,Z"; static const char padbuffer[] = "ghjghjghjghj"; static const char nlbuffer[] = "\r\n"; - char buffer[2*BUFSIZ+256]; + static char buffer[8192]; const char *optr; int fd; FILE *file; @@ -317,7 +318,7 @@ static void test_readmode( BOOL ascii_mode ) ok(feof(file)==0,"feof failure in %s\n", IOMODE); ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE); ok(feof(file)!=0,"feof failure in %s\n", IOMODE); - + /* test some additional functions */ rewind(file); ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE); @@ -340,6 +341,30 @@ static void test_readmode( BOOL ascii_mode ) fclose (file); unlink ("fdopen.tst"); + + /* test INTERNAL_BUFSIZ read containing 0x1a character (^Z) */ + fd = open("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE); + ok(fd != -1, "open failed\n"); + memset(buffer, 'a', sizeof(buffer)); + buffer[1] = 0x1a; + ok(write(fd, buffer, sizeof(buffer)) == sizeof(buffer), "write failed\n"); + ok(close(fd) != -1, "close failed\n"); + + fd = open("fdopen.tst", O_RDONLY); + ok(fd != -1, "open failed\n"); + file = fdopen(fd, ascii_mode ? "r" : "rb"); + ok(file != NULL, "fdopen failed\n"); + + memset(buffer, 0, sizeof(buffer)); + i = fread(buffer, 4096, 1, file); + ok(!i, "fread succeeded\n"); + ok(file->_bufsiz == 4096, "file->_bufsiz = %d\n", file->_bufsiz); + for(i=0; i<4096; i++) + if(buffer[i] != (i==1 ? 0x1a : 'a')) break; + ok(i==4096, "buffer[%d] = %d\n", i, buffer[i]); + + fclose(file); + unlink("fdopen.tst"); } static void test_asciimode(void) @@ -1513,6 +1538,113 @@ static void test_file_inherit( const char* selfname ) DeleteFileA("fdopen.tst"); } +static void test_invalid_stdin_child( void ) +{ + HANDLE handle; + ioinfo *info; + int ret; + char c; + + errno = 0xdeadbeef; + handle = (HANDLE)_get_osfhandle(STDIN_FILENO); + ok(handle == (HANDLE)-2, "handle = %p\n", handle); + ok(errno == 0xdeadbeef, "errno = %d\n", errno); + + info = &__pioinfo[STDIN_FILENO/MSVCRT_FD_BLOCK_SIZE][STDIN_FILENO%MSVCRT_FD_BLOCK_SIZE]; + ok(info->handle == (HANDLE)-2, "info->handle = %p\n", info->handle); + ok(info->wxflag == 0xc1, "info->wxflag = %x\n", info->wxflag); + + ok(stdin->_file == -2, "stdin->_file = %d\n", stdin->_file); + + errno = 0xdeadbeef; + ret = fread(&c, 1, 1, stdin); + ok(!ret, "fread(stdin) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = read(-2, &c, 1); + ok(ret == -1, "read(-2) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = read(STDIN_FILENO, &c, 1); + ok(ret == -1, "read(STDIN_FILENO) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = _flsbuf('a', stdin); + ok(ret == EOF, "_flsbuf(stdin) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = fwrite(&c, 1, 1, stdin); + ok(!ret, "fwrite(stdin) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = write(-2, &c, 1); + ok(ret == -1, "write(-2) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = write(STDIN_FILENO, &c, 1); + ok(ret == -1, "write(STDIN_FILENO) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = fclose(stdin); + ok(ret == -1, "fclose(stdin) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = close(-2); + ok(ret == -1, "close(-2) returned %d\n", ret); + ok(errno == EBADF, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ret = close(STDIN_FILENO); + ok(ret==-1 || !ret, "close(STDIN_FILENO) returned %d\n", ret); + ok((ret==-1 && errno==EBADF) || (!ret && errno==0xdeadbeef), "errno = %d\n", errno); +} + +static void test_invalid_stdin( const char* selfname ) +{ + char cmdline[MAX_PATH]; + PROCESS_INFORMATION proc; + SECURITY_ATTRIBUTES sa; + STARTUPINFOA startup; + HKEY key; + LONG ret; + + if(!p_fopen_s) { + /* Behaviour of the dll has changed in newer version */ + win_skip("skipping invalid stdin tests\n"); + return; + } + + ret = RegOpenCurrentUser(KEY_READ, &key); + ok(!ret, "RegOpenCurrentUser failed: %x\n", ret); + + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + startup.dwFlags = STARTF_USESTDHANDLES; + startup.hStdInput = key; + startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + startup.hStdError = GetStdHandle(STD_ERROR_HANDLE); + + sprintf(cmdline, "%s file stdin", selfname); + CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, + CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc); + winetest_wait_child_process(proc.hProcess); + + ret = RegCloseKey(key); + ok(!ret, "RegCloseKey failed: %x\n", ret); +} + static void test_tmpnam( void ) { char name[MAX_PATH] = "abc"; @@ -1601,10 +1733,13 @@ static void test_fopen_fclose_fcloseall( void ) ok(ret == 0, "The file '%s' was not closed\n", fname2); ret = fclose(stream3); ok(ret == 0, "The file '%s' was not closed\n", fname3); + errno = 0xdeadbeef; ret = fclose(stream2); ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret); + ok(errno == 0xdeadbeef, "errno = %d\n", errno); ret = fclose(stream3); ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret); + ok(errno == 0xdeadbeef, "errno = %d\n", errno); /* testing fcloseall() */ numclosed = _fcloseall(); @@ -2349,6 +2484,12 @@ static void test_close(void) ok(!GetHandleInformation(h, &flags), "GetHandleInformation succeeded\n"); ok(close(fd2), "close(fd2) succeeded\n"); + /* test close on already closed fd */ + errno = 0xdeadbeef; + ret1 = close(fd1); + ok(ret1 == -1, "close(fd1) succeeded\n"); + ok(errno == 9, "errno = %d\n", errno); + /* test close on stdout and stderr that use the same handle */ h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); @@ -2452,12 +2593,15 @@ START_TEST(file) test_file_inherit_child_no(arg_v[3]); else if (strcmp(arg_v[2], "pipes") == 0) test_pipes_child(arg_c, arg_v); + else if (strcmp(arg_v[2], "stdin") == 0) + test_invalid_stdin_child(); else ok(0, "invalid argument '%s'\n", arg_v[2]); return; } test_dup2(); test_file_inherit(arg_v[0]); + test_invalid_stdin(arg_v[0]); test_file_write_read(); test_chsize(); test_stat(); diff --git a/modules/rostests/winetests/msvcrt/locale.c b/modules/rostests/winetests/msvcrt/locale.c index 0554270f1d9..195b7738ae7 100644 --- a/modules/rostests/winetests/msvcrt/locale.c +++ b/modules/rostests/winetests/msvcrt/locale.c @@ -660,6 +660,24 @@ static void test_crtGetStringTypeW(void) static void test__Gettnames(void) { + static const DWORD time_data[] = { + LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, + LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, + LOCALE_SABBREVDAYNAME6, + LOCALE_SDAYNAME7, LOCALE_SDAYNAME1, LOCALE_SDAYNAME2, LOCALE_SDAYNAME3, + LOCALE_SDAYNAME4, LOCALE_SDAYNAME5, LOCALE_SDAYNAME6, + LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3, + LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, + LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9, + LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12, + LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3, LOCALE_SMONTHNAME4, + LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6, LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, + LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12, + LOCALE_S1159, LOCALE_S2359, + LOCALE_SSHORTDATE, LOCALE_SLONGDATE, + LOCALE_STIMEFORMAT + }; + struct { char *str[43]; LCID lcid; @@ -669,6 +687,7 @@ static void test__Gettnames(void) } *ret; int size; char buf[64]; + int i; if(!setlocale(LC_ALL, "english")) return; @@ -683,100 +702,27 @@ static void test__Gettnames(void) else ok(size==0x164 || broken(size==0xb8), "structure size: %x\n", size); - ok(!strcmp(ret->str[0], "Sun"), "ret->str[0] = %s\n", ret->str[0]); - ok(!strcmp(ret->str[1], "Mon"), "ret->str[1] = %s\n", ret->str[1]); - ok(!strcmp(ret->str[2], "Tue"), "ret->str[2] = %s\n", ret->str[2]); - ok(!strcmp(ret->str[3], "Wed"), "ret->str[3] = %s\n", ret->str[3]); - ok(!strcmp(ret->str[4], "Thu"), "ret->str[4] = %s\n", ret->str[4]); - ok(!strcmp(ret->str[5], "Fri"), "ret->str[5] = %s\n", ret->str[5]); - ok(!strcmp(ret->str[6], "Sat"), "ret->str[6] = %s\n", ret->str[6]); - ok(!strcmp(ret->str[7], "Sunday"), "ret->str[7] = %s\n", ret->str[7]); - ok(!strcmp(ret->str[8], "Monday"), "ret->str[8] = %s\n", ret->str[8]); - ok(!strcmp(ret->str[9], "Tuesday"), "ret->str[9] = %s\n", ret->str[9]); - ok(!strcmp(ret->str[10], "Wednesday"), "ret->str[10] = %s\n", ret->str[10]); - ok(!strcmp(ret->str[11], "Thursday"), "ret->str[11] = %s\n", ret->str[11]); - ok(!strcmp(ret->str[12], "Friday"), "ret->str[12] = %s\n", ret->str[12]); - ok(!strcmp(ret->str[13], "Saturday"), "ret->str[13] = %s\n", ret->str[13]); - ok(!strcmp(ret->str[14], "Jan"), "ret->str[14] = %s\n", ret->str[14]); - ok(!strcmp(ret->str[15], "Feb"), "ret->str[15] = %s\n", ret->str[15]); - ok(!strcmp(ret->str[16], "Mar"), "ret->str[16] = %s\n", ret->str[16]); - ok(!strcmp(ret->str[17], "Apr"), "ret->str[17] = %s\n", ret->str[17]); - ok(!strcmp(ret->str[18], "May"), "ret->str[18] = %s\n", ret->str[18]); - ok(!strcmp(ret->str[19], "Jun"), "ret->str[19] = %s\n", ret->str[19]); - ok(!strcmp(ret->str[20], "Jul"), "ret->str[20] = %s\n", ret->str[20]); - ok(!strcmp(ret->str[21], "Aug"), "ret->str[21] = %s\n", ret->str[21]); - ok(!strcmp(ret->str[22], "Sep"), "ret->str[22] = %s\n", ret->str[22]); - ok(!strcmp(ret->str[23], "Oct"), "ret->str[23] = %s\n", ret->str[23]); - ok(!strcmp(ret->str[24], "Nov"), "ret->str[24] = %s\n", ret->str[24]); - ok(!strcmp(ret->str[25], "Dec"), "ret->str[25] = %s\n", ret->str[25]); - ok(!strcmp(ret->str[26], "January"), "ret->str[26] = %s\n", ret->str[26]); - ok(!strcmp(ret->str[27], "February"), "ret->str[27] = %s\n", ret->str[27]); - ok(!strcmp(ret->str[28], "March"), "ret->str[28] = %s\n", ret->str[28]); - ok(!strcmp(ret->str[29], "April"), "ret->str[29] = %s\n", ret->str[29]); - ok(!strcmp(ret->str[30], "May"), "ret->str[30] = %s\n", ret->str[30]); - ok(!strcmp(ret->str[31], "June"), "ret->str[31] = %s\n", ret->str[31]); - ok(!strcmp(ret->str[32], "July"), "ret->str[32] = %s\n", ret->str[32]); - ok(!strcmp(ret->str[33], "August"), "ret->str[33] = %s\n", ret->str[33]); - ok(!strcmp(ret->str[34], "September"), "ret->str[34] = %s\n", ret->str[34]); - ok(!strcmp(ret->str[35], "October"), "ret->str[35] = %s\n", ret->str[35]); - ok(!strcmp(ret->str[36], "November"), "ret->str[36] = %s\n", ret->str[36]); - ok(!strcmp(ret->str[37], "December"), "ret->str[37] = %s\n", ret->str[37]); - ok(!strcmp(ret->str[38], "AM"), "ret->str[38] = %s\n", ret->str[38]); - ok(!strcmp(ret->str[39], "PM"), "ret->str[39] = %s\n", ret->str[39]); - ok(!strcmp(ret->str[40], "M/d/yyyy") || broken(!strcmp(ret->str[40], "M/d/yy"))/*NT*/, - "ret->str[40] = %s\n", ret->str[40]); - size = GetLocaleInfoA(MAKELCID(LANG_ENGLISH, SORT_DEFAULT), - LOCALE_SLONGDATE|LOCALE_NOUSEROVERRIDE, buf, sizeof(buf)); - ok(size, "GetLocaleInfo failed: %x\n", GetLastError()); - ok(!strcmp(ret->str[41], buf), "ret->str[41] = %s, expected %s\n", ret->str[41], buf); + for (i = 0; i < sizeof(time_data)/sizeof(time_data[0]); i++) + { + size = GetLocaleInfoA(MAKELCID(LANG_ENGLISH, SORT_DEFAULT), + time_data[i], buf, sizeof(buf)); + ok(size, "GetLocaleInfo failed: %x\n", GetLastError()); + ok(!strcmp(ret->str[i], buf), "ret->str[%i] = %s, expected %s\n", i, ret->str[i], buf); + } + free(ret); if(!setlocale(LC_TIME, "german")) return; ret = _Gettnames(); - ok(!strcmp(ret->str[0], "So"), "ret->str[0] = %s\n", ret->str[0]); - ok(!strcmp(ret->str[1], "Mo"), "ret->str[1] = %s\n", ret->str[1]); - ok(!strcmp(ret->str[2], "Di"), "ret->str[2] = %s\n", ret->str[2]); - ok(!strcmp(ret->str[3], "Mi"), "ret->str[3] = %s\n", ret->str[3]); - ok(!strcmp(ret->str[4], "Do"), "ret->str[4] = %s\n", ret->str[4]); - ok(!strcmp(ret->str[5], "Fr"), "ret->str[5] = %s\n", ret->str[5]); - ok(!strcmp(ret->str[6], "Sa"), "ret->str[6] = %s\n", ret->str[6]); - ok(!strcmp(ret->str[7], "Sonntag"), "ret->str[7] = %s\n", ret->str[7]); - ok(!strcmp(ret->str[8], "Montag"), "ret->str[8] = %s\n", ret->str[8]); - ok(!strcmp(ret->str[9], "Dienstag"), "ret->str[9] = %s\n", ret->str[9]); - ok(!strcmp(ret->str[10], "Mittwoch"), "ret->str[10] = %s\n", ret->str[10]); - ok(!strcmp(ret->str[11], "Donnerstag"), "ret->str[11] = %s\n", ret->str[11]); - ok(!strcmp(ret->str[12], "Freitag"), "ret->str[12] = %s\n", ret->str[12]); - ok(!strcmp(ret->str[13], "Samstag"), "ret->str[13] = %s\n", ret->str[13]); - ok(!strcmp(ret->str[14], "Jan"), "ret->str[14] = %s\n", ret->str[14]); - ok(!strcmp(ret->str[15], "Feb"), "ret->str[15] = %s\n", ret->str[15]); - ok(!strcmp(ret->str[16], "Mrz"), "ret->str[16] = %s\n", ret->str[16]); - ok(!strcmp(ret->str[17], "Apr"), "ret->str[17] = %s\n", ret->str[17]); - ok(!strcmp(ret->str[18], "Mai"), "ret->str[18] = %s\n", ret->str[18]); - ok(!strcmp(ret->str[19], "Jun"), "ret->str[19] = %s\n", ret->str[19]); - ok(!strcmp(ret->str[20], "Jul"), "ret->str[20] = %s\n", ret->str[20]); - ok(!strcmp(ret->str[21], "Aug"), "ret->str[21] = %s\n", ret->str[21]); - ok(!strcmp(ret->str[22], "Sep"), "ret->str[22] = %s\n", ret->str[22]); - ok(!strcmp(ret->str[23], "Okt"), "ret->str[23] = %s\n", ret->str[23]); - ok(!strcmp(ret->str[24], "Nov"), "ret->str[24] = %s\n", ret->str[24]); - ok(!strcmp(ret->str[25], "Dez"), "ret->str[25] = %s\n", ret->str[25]); - ok(!strcmp(ret->str[26], "Januar"), "ret->str[26] = %s\n", ret->str[26]); - ok(!strcmp(ret->str[27], "Februar"), "ret->str[27] = %s\n", ret->str[27]); - ok(!strcmp(ret->str[29], "April"), "ret->str[29] = %s\n", ret->str[29]); - ok(!strcmp(ret->str[30], "Mai"), "ret->str[30] = %s\n", ret->str[30]); - ok(!strcmp(ret->str[31], "Juni"), "ret->str[31] = %s\n", ret->str[31]); - ok(!strcmp(ret->str[32], "Juli"), "ret->str[32] = %s\n", ret->str[32]); - ok(!strcmp(ret->str[33], "August"), "ret->str[33] = %s\n", ret->str[33]); - ok(!strcmp(ret->str[34], "September"), "ret->str[34] = %s\n", ret->str[34]); - ok(!strcmp(ret->str[35], "Oktober"), "ret->str[35] = %s\n", ret->str[35]); - ok(!strcmp(ret->str[36], "November"), "ret->str[36] = %s\n", ret->str[36]); - ok(!strcmp(ret->str[37], "Dezember"), "ret->str[37] = %s\n", ret->str[37]); - ok(!strcmp(ret->str[38], ""), "ret->str[38] = %s\n", ret->str[38]); - ok(!strcmp(ret->str[39], ""), "ret->str[39] = %s\n", ret->str[39]); - ok(!strcmp(ret->str[40], "dd.MM.yyyy") || broken(!strcmp(ret->str[40], "dd.MM.yy"))/*NT*/, - "ret->str[40] = %s\n", ret->str[40]); - ok(!strcmp(ret->str[41], "dddd, d. MMMM yyyy"), "ret->str[41] = %s\n", ret->str[41]); + for (i = 0; i < sizeof(time_data)/sizeof(time_data[0]); i++) + { + size = GetLocaleInfoA(MAKELCID(LANG_GERMAN, SORT_DEFAULT), + time_data[i], buf, sizeof(buf)); + ok(size, "GetLocaleInfo failed: %x\n", GetLastError()); + ok(!strcmp(ret->str[i], buf), "ret->str[%i] = %s, expected %s\n", i, ret->str[i], buf); + } free(ret); setlocale(LC_ALL, "C"); diff --git a/modules/rostests/winetests/msvcrt/printf.c b/modules/rostests/winetests/msvcrt/printf.c index 372509088cb..43b2ec3dda1 100644 --- a/modules/rostests/winetests/msvcrt/printf.c +++ b/modules/rostests/winetests/msvcrt/printf.c @@ -1185,7 +1185,7 @@ static void test_xcvt(void) win_skip("_fcvt_s not available\n"); } -static int __cdecl _vsnwprintf_wrapper(wchar_t *str, size_t len, const wchar_t *format, ...) +static int WINAPIV _vsnwprintf_wrapper(wchar_t *str, size_t len, const wchar_t *format, ...) { int ret; __ms_va_list valist; @@ -1219,7 +1219,7 @@ static void test_vsnwprintf(void) ok( ret == 11 || broken(ret == -1 /* Win2k */), "got %d, expected 11\n", ret ); } -static int __cdecl vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) +static int WINAPIV vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) { int ret; __ms_va_list valist; @@ -1229,7 +1229,7 @@ static int __cdecl vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) return ret; } -static int __cdecl _vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) +static int WINAPIV _vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) { int ret; __ms_va_list valist; @@ -1239,7 +1239,7 @@ static int __cdecl _vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) return ret; } -static int __cdecl _vswprintf_l_wrapper(wchar_t *str, const wchar_t *format, void *locale, ...) +static int WINAPIV _vswprintf_l_wrapper(wchar_t *str, const wchar_t *format, void *locale, ...) { int ret; __ms_va_list valist; @@ -1249,7 +1249,7 @@ static int __cdecl _vswprintf_l_wrapper(wchar_t *str, const wchar_t *format, voi return ret; } -static int __cdecl _vswprintf_c_wrapper(wchar_t *str, size_t size, const wchar_t *format, ...) +static int WINAPIV _vswprintf_c_wrapper(wchar_t *str, size_t size, const wchar_t *format, ...) { int ret; __ms_va_list valist; @@ -1259,7 +1259,7 @@ static int __cdecl _vswprintf_c_wrapper(wchar_t *str, size_t size, const wchar_t return ret; } -static int __cdecl _vswprintf_c_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) +static int WINAPIV _vswprintf_c_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) { int ret; __ms_va_list valist; @@ -1269,7 +1269,7 @@ static int __cdecl _vswprintf_c_l_wrapper(wchar_t *str, size_t size, const wchar return ret; } -static int __cdecl _vswprintf_p_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) +static int WINAPIV _vswprintf_p_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) { int ret; __ms_va_list valist; @@ -1325,7 +1325,7 @@ static void test_vswprintf(void) ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); } -static int __cdecl _vscprintf_wrapper(const char *format, ...) +static int WINAPIV _vscprintf_wrapper(const char *format, ...) { int ret; __ms_va_list valist; @@ -1349,7 +1349,7 @@ static void test_vscprintf(void) ok( ret == 8, "got %d expected 8\n", ret ); } -static int __cdecl _vscwprintf_wrapper(const wchar_t *format, ...) +static int WINAPIV _vscwprintf_wrapper(const wchar_t *format, ...) { int ret; __ms_va_list valist; @@ -1376,7 +1376,7 @@ static void test_vscwprintf(void) ok( ret == 8, "got %d expected 8\n", ret ); } -static int __cdecl _vsnwprintf_s_wrapper(wchar_t *str, size_t sizeOfBuffer, +static int WINAPIV _vsnwprintf_s_wrapper(wchar_t *str, size_t sizeOfBuffer, size_t count, const wchar_t *format, ...) { int ret; @@ -1434,7 +1434,7 @@ static void test_vsnwprintf_s(void) ok( !wcscmp(out1, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); } -static int __cdecl _vsprintf_p_wrapper(char *str, size_t sizeOfBuffer, +static int WINAPIV _vsprintf_p_wrapper(char *str, size_t sizeOfBuffer, const char *format, ...) { int ret; diff --git a/modules/rostests/winetests/msvcrt/scanf.c b/modules/rostests/winetests/msvcrt/scanf.c index a5c4d9da713..d25bee6a003 100644 --- a/modules/rostests/winetests/msvcrt/scanf.c +++ b/modules/rostests/winetests/msvcrt/scanf.c @@ -257,7 +257,7 @@ static void test_sscanf( void ) static void test_sscanf_s(void) { - int (__cdecl *psscanf_s)(const char*,const char*,...); + int (WINAPIV *psscanf_s)(const char*,const char*,...); HMODULE hmod = GetModuleHandleA("msvcrt.dll"); int i, ret; char buf[100]; @@ -322,9 +322,43 @@ static void test_swscanf( void ) ok(c == 'b', "c = %x\n", c); } +static void test_swscanf_s(void) +{ + static const wchar_t fmt1[] = {'%','c',0}; + static const wchar_t fmt2[] = {'%','[','a','-','z',']',0}; + + int (WINAPIV *pswscanf_s)(const wchar_t*,const wchar_t*,...); + HMODULE hmod = GetModuleHandleA("msvcrt.dll"); + wchar_t buf[2], out[2]; + int ret; + + pswscanf_s = (void*)GetProcAddress(hmod, "swscanf_s"); + if(!pswscanf_s) { + win_skip("swscanf_s not available\n"); + return; + } + + buf[0] = 'a'; + buf[1] = '1'; + out[1] = 'b'; + ret = pswscanf_s(buf, fmt1, out, 1); + ok(ret == 1, "swscanf_s returned %d\n", ret); + ok(out[0] == 'a', "out[0] = %x\n", out[0]); + ok(out[1] == 'b', "out[1] = %x\n", out[1]); + + ret = pswscanf_s(buf, fmt2, out, 1); + ok(!ret, "swscanf_s returned %d\n", ret); + + ret = pswscanf_s(buf, fmt2, out, 2); + ok(ret == 1, "swscanf_s returned %d\n", ret); + ok(out[0] == 'a', "out[0] = %x\n", out[0]); + ok(!out[1], "out[1] = %x\n", out[1]); +} + START_TEST(scanf) { test_sscanf(); test_sscanf_s(); test_swscanf(); + test_swscanf_s(); } diff --git a/modules/rostests/winetests/msvcrt/string.c b/modules/rostests/winetests/msvcrt/string.c index 10974e5ad40..4fc34ebfc41 100644 --- a/modules/rostests/winetests/msvcrt/string.c +++ b/modules/rostests/winetests/msvcrt/string.c @@ -86,6 +86,10 @@ static double (__cdecl *p__atof_l)(const char*,_locale_t); static double (__cdecl *p__strtod_l)(const char *,char**,_locale_t); static int (__cdecl *p__strnset_s)(char*,size_t,int,size_t); static int (__cdecl *p__wcsset_s)(wchar_t*,size_t,wchar_t); +static size_t (__cdecl *p__mbsnlen)(const unsigned char*, size_t); +static int (__cdecl *p__mbccpy_s)(unsigned char*, size_t, int*, const unsigned char*); +static int (__cdecl *p__memicmp)(const char*, const char*, size_t); +static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t); #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y) #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y) @@ -306,6 +310,20 @@ static void test_mbcp(void) expect_eq(_mbslen(mbsonlylead), 0, int, "%d"); /* lead + NUL not counted as character */ expect_eq(_mbslen(mbstring), 4, int, "%d"); /* lead + invalid trail counted */ + if(!p__mbsnlen) { + win_skip("_mbsnlen tests\n"); + }else { + expect_eq(p__mbsnlen(mbstring, 8), 8, int, "%d"); + expect_eq(p__mbsnlen(mbstring, 9), 4, int, "%d"); + expect_eq(p__mbsnlen(mbstring, 10), 4, int, "%d"); + expect_eq(p__mbsnlen(mbsonlylead, 0), 0, int, "%d"); + expect_eq(p__mbsnlen(mbsonlylead, 1), 1, int, "%d"); + expect_eq(p__mbsnlen(mbsonlylead, 2), 0, int, "%d"); + expect_eq(p__mbsnlen(mbstring2, 7), 7, int, "%d"); + expect_eq(p__mbsnlen(mbstring2, 8), 4, int, "%d"); + expect_eq(p__mbsnlen(mbstring2, 9), 4, int, "%d"); + } + /* mbrlen */ if(!setlocale(LC_ALL, ".936") || !p_mbrlen) { win_skip("mbrlen tests\n"); @@ -348,6 +366,40 @@ static void test_mbcp(void) _mbccpy(buf, mbstring); expect_bin(buf, "\xb0\xb1\xff", 3); + if(!p__mbccpy_s) { + win_skip("_mbccpy_s tests\n"); + }else { + int err, copied; + + memset(buf, 0xff, sizeof(buf)); + copied = -1; + err = p__mbccpy_s(buf, 0, &copied, mbstring); + ok(err == EINVAL, "_mbccpy_s returned %d\n", err); + ok(!copied, "copied = %d\n", copied); + ok(buf[0] == 0xff, "buf[0] = %x\n", buf[0]); + + memset(buf, 0xff, sizeof(buf)); + copied = -1; + err = p__mbccpy_s(buf, 1, &copied, mbstring); + ok(err == ERANGE, "_mbccpy_s returned %d\n", err); + ok(!copied, "copied = %d\n", copied); + ok(!buf[0], "buf[0] = %x\n", buf[0]); + + memset(buf, 0xff, sizeof(buf)); + copied = -1; + err = p__mbccpy_s(buf, 2, &copied, mbstring); + ok(!err, "_mbccpy_s returned %d\n", err); + ok(copied == 2, "copied = %d\n", copied); + expect_bin(buf, "\xb0\xb1\xff", 3); + + memset(buf, 0xff, sizeof(buf)); + copied = -1; + err = p__mbccpy_s(buf, 2, &copied, (unsigned char *)"\xb0"); + ok(err == EILSEQ, "_mbccpy_s returned %d\n", err); + ok(copied == 1, "copied = %d\n", copied); + expect_bin(buf, "\x00\xff", 2); + } + memset(buf, 0xff, sizeof(buf)); _mbsncpy(buf, mbstring, 1); expect_bin(buf, "\xb0\xb1\xff", 3); @@ -3206,6 +3258,84 @@ static void test__ismbclx(void) _setmbcp(cp); } +static void test__memicmp(void) +{ + static const char *s1 = "abc"; + static const char *s2 = "aBd"; + int ret; + + ret = p__memicmp(NULL, NULL, 0); + ok(!ret, "got %d\n", ret); + + ret = p__memicmp(s1, s2, 2); + ok(!ret, "got %d\n", ret); + + ret = p__memicmp(s1, s2, 3); + ok(ret == -1, "got %d\n", ret); + + if (!p__memicmp_l) + return; + + /* Following calls crash on WinXP/W2k3. */ + errno = 0xdeadbeef; + ret = p__memicmp(NULL, NULL, 1); + ok(ret == _NLSCMPERROR, "got %d\n", ret); + ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); + + errno = 0xdeadbeef; + ret = p__memicmp(s1, NULL, 1); + ok(ret == _NLSCMPERROR, "got %d\n", ret); + ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); + + errno = 0xdeadbeef; + ret = p__memicmp(NULL, s2, 1); + ok(ret == _NLSCMPERROR, "got %d\n", ret); + ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); +} + +static void test__memicmp_l(void) +{ + static const char *s1 = "abc"; + static const char *s2 = "aBd"; + int ret; + + if (!p__memicmp_l) + { + win_skip("_memicmp_l not found.\n"); + return; + } + + errno = 0xdeadbeef; + ret = p__memicmp_l(NULL, NULL, 0, NULL); + ok(!ret, "got %d\n", ret); + ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); + + errno = 0xdeadbeef; + ret = p__memicmp_l(NULL, NULL, 1, NULL); + ok(ret == _NLSCMPERROR, "got %d\n", ret); + ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); + + errno = 0xdeadbeef; + ret = p__memicmp_l(s1, NULL, 1, NULL); + ok(ret == _NLSCMPERROR, "got %d\n", ret); + ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); + + errno = 0xdeadbeef; + ret = p__memicmp_l(NULL, s2, 1, NULL); + ok(ret == _NLSCMPERROR, "got %d\n", ret); + ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); + + errno = 0xdeadbeef; + ret = p__memicmp_l(s1, s2, 2, NULL); + ok(!ret, "got %d\n", ret); + ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); + + errno = 0xdeadbeef; + ret = p__memicmp_l(s1, s2, 3, NULL); + ok(ret == -1, "got %d\n", ret); + ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); +} + START_TEST(string) { char mem[100]; @@ -3260,6 +3390,10 @@ START_TEST(string) p__strtod_l = (void*)GetProcAddress(hMsvcrt, "_strtod_l"); p__strnset_s = (void*)GetProcAddress(hMsvcrt, "_strnset_s"); p__wcsset_s = (void*)GetProcAddress(hMsvcrt, "_wcsset_s"); + p__mbsnlen = (void*)GetProcAddress(hMsvcrt, "_mbsnlen"); + p__mbccpy_s = (void*)GetProcAddress(hMsvcrt, "_mbccpy_s"); + p__memicmp = (void*)GetProcAddress(hMsvcrt, "_memicmp"); + p__memicmp_l = (void*)GetProcAddress(hMsvcrt, "_memicmp_l"); /* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -3322,4 +3456,6 @@ START_TEST(string) test__wcsset_s(); test__mbscmp(); test__ismbclx(); + test__memicmp(); + test__memicmp_l(); } diff --git a/modules/rostests/winetests/msvcrt/time.c b/modules/rostests/winetests/msvcrt/time.c index 6173cf4bc68..176ead348e8 100644 --- a/modules/rostests/winetests/msvcrt/time.c +++ b/modules/rostests/winetests/msvcrt/time.c @@ -869,18 +869,19 @@ static void test__tzset(void) static void test_clock(void) { - static const int THRESH = 50; - clock_t s, e; - int i; - - for (i = 0; i < 10; i++) - { - s = clock(); - Sleep(1000); - e = clock(); - - ok(abs((e-s) - 1000) < THRESH, "clock off on loop %i: %i\n", i, e-s); - } + static const int THRESH = 100; + FILETIME start, cur; + int c, expect; + BOOL ret; + + ret = GetProcessTimes(GetCurrentProcess(), &start, &cur, &cur, &cur); + ok(ret, "GetProcessTimes failed with error: %d\n", GetLastError()); + GetSystemTimeAsFileTime(&cur); + expect = (((LONGLONG)cur.dwHighDateTime<<32)+cur.dwLowDateTime - + ((LONGLONG)start.dwHighDateTime<<32)-start.dwLowDateTime) / 10000; + + c = clock(); + ok(abs(c-expect) < THRESH, "clock() = %d, expected %d\n", c, expect); } START_TEST(time) -- 2.17.1