diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 6ead0a77f42..3866dc65ccb 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1110,7 +1110,7 @@ @ cdecl _wcstoi64_l(wstr ptr long ptr) msvcrt._wcstoi64_l @ stub _wcstol_l @ stub _wcstombs_l -@ stub _wcstombs_s_l +@ cdecl _wcstombs_s_l(ptr ptr long wstr long ptr) msvcrt._wcstombs_s_l @ cdecl _wcstoui64(wstr ptr long) msvcrt._wcstoui64 @ cdecl _wcstoui64_l(wstr ptr long ptr) msvcrt._wcstoui64_l @ stub _wcstoul_l @@ -1456,7 +1456,7 @@ @ stub wcstok_s @ cdecl wcstol(wstr ptr long) msvcrt.wcstol @ cdecl wcstombs(ptr ptr long) msvcrt.wcstombs -@ stub wcstombs_s +@ cdecl wcstombs_s(ptr ptr long wstr long) msvcrt.wcstombs_s @ cdecl wcstoul(wstr ptr long) msvcrt.wcstoul @ stub wcsxfrm @ stub wctob diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 72dff798245..ea3e534eb8d 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1097,7 +1097,7 @@ @ cdecl _wcstoi64_l(wstr ptr long ptr) msvcrt._wcstoi64_l @ stub _wcstol_l @ stub _wcstombs_l -@ stub _wcstombs_s_l +@ cdecl _wcstombs_s_l(ptr ptr long wstr long ptr) msvcrt._wcstombs_s_l @ cdecl _wcstoui64(wstr ptr long) msvcrt._wcstoui64 @ cdecl _wcstoui64_l(wstr ptr long ptr) msvcrt._wcstoui64_l @ stub _wcstoul_l @@ -1440,7 +1440,7 @@ @ stub wcstok_s @ cdecl wcstol(wstr ptr long) msvcrt.wcstol @ cdecl wcstombs(ptr ptr long) msvcrt.wcstombs -@ stub wcstombs_s +@ cdecl wcstombs_s(ptr ptr long wstr long) msvcrt.wcstombs_s @ cdecl wcstoul(wstr ptr long) msvcrt.wcstoul @ stub wcsxfrm @ stub wctob diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 5f82cf1b9e2..1e7b9e20643 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1039,7 +1039,7 @@ @ cdecl _wcstoi64_l(wstr ptr long ptr) MSVCRT__wcstoi64_l # stub _wcstol_l # stub _wcstombs_l -# stub _wcstombs_s_l +@ cdecl _wcstombs_s_l(ptr ptr long wstr long ptr) MSVCRT__wcstombs_s_l @ cdecl _wcstoui64(wstr ptr long) MSVCRT__wcstoui64 @ cdecl _wcstoui64_l(wstr ptr long ptr) MSVCRT__wcstoui64_l # stub _wcstoul_l @@ -1396,7 +1396,7 @@ # stub wcstok_s @ cdecl wcstol(wstr ptr long) ntdll.wcstol @ cdecl wcstombs(ptr ptr long) ntdll.wcstombs -# stub wcstombs_s +@ cdecl wcstombs_s(ptr ptr long wstr long) MSVCRT_wcstombs_s @ cdecl wcstoul(wstr ptr long) ntdll.wcstoul @ stub wcsxfrm #(ptr wstr long) MSVCRT_wcsxfrm # stub wctob diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 04d90dea4b6..ddeb9997205 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -226,6 +226,82 @@ double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end, return ret; } +/********************************************************************* + * _wcstombs_s_l (MSVCRT.@) + */ +int CDECL MSVCRT__wcstombs_s_l(MSVCRT_size_t *ret, char *mbstr, + MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr, + MSVCRT_size_t count, MSVCRT__locale_t locale) +{ + char default_char = '\0', *p; + int hlp, len; + + if(!size) + return 0; + + if(!mbstr || !wcstr) { + MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0); + if(mbstr) + *mbstr = '\0'; + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } + + if(!locale) + locale = get_locale(); + + if(size<=count) + len = size; + else if(count==_TRUNCATE) + len = size-1; + else + len = count; + + p = mbstr; + *ret = 0; + while(1) { + if(!len) + break; + + if(*wcstr == '\0') { + *p = '\0'; + break; + } + + hlp = WideCharToMultiByte(locale->locinfo->lc_codepage, + WC_NO_BEST_FIT_CHARS, wcstr, 1, p, len, &default_char, NULL); + if(!hlp || *p=='\0') + break; + + p += hlp; + len -= hlp; + + wcstr++; + *ret += 1; + } + + if(!len && size<=count) { + MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0); + *mbstr = '\0'; + *MSVCRT__errno() = MSVCRT_ERANGE; + return MSVCRT_ERANGE; + } + + if(*wcstr == '\0') + *ret += 1; + *p = '\0'; + return 0; +} + +/********************************************************************* + * wcstombs_s (MSVCRT.@) + */ +int CDECL MSVCRT_wcstombs_s(MSVCRT_size_t *ret, char *mbstr, + MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr, MSVCRT_size_t count) +{ + return MSVCRT__wcstombs_s_l(ret, mbstr, size, wcstr, count, NULL); +} + /********************************************************************* * wcstod (MSVCRT.@) */