ntdll: Implement _snprintf_s and _vsnprintf_s.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Jacek Caban 2019-07-03 21:06:21 +02:00 committed by Alexandre Julliard
parent b350095b76
commit 4c2afc8ad9
3 changed files with 100 additions and 0 deletions

View File

@ -1406,6 +1406,7 @@
@ cdecl _memccpy(ptr ptr long long)
@ cdecl _memicmp(str str long)
@ varargs _snprintf(ptr long str) NTDLL__snprintf
@ varargs _snprintf_s(ptr long long str) _snprintf_s
@ varargs _snwprintf(ptr long wstr) NTDLL__snwprintf
@ cdecl _splitpath(str ptr ptr ptr ptr)
@ cdecl _strcmpi(str str) _stricmp
@ -1420,6 +1421,7 @@
@ cdecl _ultoa(long ptr long)
@ cdecl _ultow(long ptr long)
@ cdecl -norelay _vsnprintf(ptr long str ptr) NTDLL__vsnprintf
@ cdecl _vsnprintf_s(ptr long str ptr) _vsnprintf_s
@ cdecl _vsnwprintf(ptr long wstr ptr) NTDLL__vsnwprintf
@ cdecl _wcsicmp(wstr wstr) NTDLL__wcsicmp
@ cdecl _wcslwr(wstr) NTDLL__wcslwr

View File

@ -764,6 +764,51 @@ int WINAPIV NTDLL__snwprintf( WCHAR *str, SIZE_T len, const WCHAR *format, ... )
}
/*********************************************************************
* _vsnprintf_s (NTDLL.@)
*/
int CDECL _vsnprintf_s( char *str, SIZE_T size, SIZE_T len, const char *format, __ms_va_list args )
{
DWORD sz;
LPWSTR formatW = NULL;
pf_output out;
int r;
out.unicode = FALSE;
out.buf.A = str;
out.used = 0;
out.len = min( size, len );
if (format)
{
RtlMultiByteToUnicodeSize( &sz, format, strlen(format) + 1 );
if (!(formatW = RtlAllocateHeap( GetProcessHeap(), 0, sz ))) return -1;
RtlMultiByteToUnicodeN( formatW, sz, NULL, format, strlen(format) + 1 );
}
r = pf_vsnprintf( &out, formatW, args );
RtlFreeHeap( GetProcessHeap(), 0, formatW );
if (out.used < size) str[out.used] = 0;
else str[0] = 0;
if (r == size) r = -1;
return r;
}
/*********************************************************************
* _snprintf_s (NTDLL.@)
*/
int WINAPIV _snprintf_s( char *str, SIZE_T size, SIZE_T len, const char *format, ... )
{
int ret;
__ms_va_list valist;
__ms_va_start( valist, format );
ret = _vsnprintf_s( str, size, len, format, valist );
__ms_va_end( valist );
return ret;
}
/*********************************************************************
* vsprintf (NTDLL.@)
*/

View File

@ -61,6 +61,7 @@ static LPWSTR (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR);
static void (__cdecl *p_qsort)(void *,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
static void* (__cdecl *p_bsearch)(void *,void*,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
static int (WINAPIV *p__snprintf)(char *, size_t, const char *, ...);
static int (WINAPIV *p__snprintf_s)(char *, size_t, size_t, const char *, ...);
static int (__cdecl *p_tolower)(int);
static int (__cdecl *p_toupper)(int);
@ -103,6 +104,7 @@ static void InitFunctionPtrs(void)
p_bsearch= (void *)GetProcAddress(hntdll, "bsearch");
p__snprintf = (void *)GetProcAddress(hntdll, "_snprintf");
p__snprintf_s = (void *)GetProcAddress(hntdll, "_snprintf_s");
p_tolower = (void *)GetProcAddress(hntdll, "tolower");
p_toupper = (void *)GetProcAddress(hntdll, "toupper");
@ -1333,6 +1335,53 @@ static void test__snprintf(void)
res = p__snprintf(buffer, strlen(teststring) + 1, teststring);
ok(res == lstrlenA(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
ok(!strcmp(buffer, teststring), "_snprintf returned buffer '%s', expected '%s'.\n", buffer, teststring);
memset(buffer, 0x7c, sizeof(buffer));
res = p__snprintf(buffer, 4, "test");
ok(res == 4, "res = %d\n", res);
ok(!memcmp(buffer, "test", 4), "buf = %s\n", buffer);
ok(buffer[4] == 0x7c, "buffer[4] = %x\n", buffer[4]);
memset(buffer, 0x7c, sizeof(buffer));
res = p__snprintf(buffer, 3, "test");
ok(res == -1, "res = %d\n", res);
}
static void test__snprintf_s(void)
{
char buf[32];
int res;
memset(buf, 0xcc, sizeof(buf));
res = p__snprintf_s(buf, sizeof(buf), sizeof(buf), "test");
ok(res == 4, "res = %d\n", res);
ok(!strcmp(buf, "test"), "buf = %s\n", buf);
memset(buf, 0xcc, sizeof(buf));
res = p__snprintf_s(buf, 4, 4, "test");
ok(res == -1, "res = %d\n", res);
ok(!buf[0], "buf = %s\n", buf);
memset(buf, 0xcc, sizeof(buf));
res = p__snprintf_s(buf, 5, 4, "test");
ok(res == 4, "res = %d\n", res);
ok(!strcmp(buf, "test"), "buf = %s\n", buf);
memset(buf, 0xcc, sizeof(buf));
res = p__snprintf_s(buf, 5, 3, "test");
ok(res == -1, "res = %d\n", res);
ok(!strcmp(buf, "tes"), "buf = %s\n", buf);
memset(buf, 0xcc, sizeof(buf));
res = p__snprintf_s(buf, 4, 10, "test");
ok(res == -1, "res = %d\n", res);
ok(!buf[0], "buf = %s\n", buf);
memset(buf, 0xcc, sizeof(buf));
res = p__snprintf_s(buf, 6, 5, "test%c", 0);
ok(res == 5, "res = %d\n", res);
ok(!memcmp(buf, "test\0", 6), "buf = %s\n", buf);
}
static void test_tolower(void)
@ -1442,6 +1491,10 @@ START_TEST(string)
test_bsearch();
if (p__snprintf)
test__snprintf();
if (p__snprintf_s)
test__snprintf_s();
else
win_skip("_snprintf_s not available\n");
test_tolower();
test_toupper();
test__strnicmp();