forked from Mirrors/wine-wine
ntdll: Implement _snprintf_s and _vsnprintf_s.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>stable
parent
b350095b76
commit
4c2afc8ad9
|
@ -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
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue