1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS CRT 4 * PURPOSE: Implementation of mbstowcs_s 5 * FILE: lib/sdk/crt/string/mbstowcs_s.c 6 * PROGRAMMER: Timo Kreuzer 7 */ 8 9 #include <precomp.h> 10 #include <mbstring.h> 11 12 _Success_(return!=EINVAL) 13 _Check_return_opt_ 14 _CRTIMP 15 errno_t 16 __cdecl 17 mbstowcs_s( 18 _Out_opt_ size_t *pcchConverted, 19 _Out_writes_to_opt_(sizeInWords, *pcchConverted) wchar_t *pwcstr, 20 _In_ size_t sizeInWords, 21 _In_reads_or_z_(count) const char *pmbstr, 22 _In_ size_t count) 23 { 24 size_t cchMax, cwcWritten; 25 errno_t retval = 0; 26 27 /* Make sure, either we have a target buffer > 0 bytes, or no buffer */ 28 if (!MSVCRT_CHECK_PMT( ((sizeInWords != 0) && (pwcstr != 0)) || 29 ((sizeInWords == 0) && (pwcstr == 0)) )) 30 { 31 _set_errno(EINVAL); 32 return EINVAL; 33 } 34 35 /* Check if we have a return value pointer */ 36 if (pcchConverted) 37 { 38 /* Default to 0 bytes written */ 39 *pcchConverted = 0; 40 } 41 42 if (!MSVCRT_CHECK_PMT((count == 0) || (pmbstr != 0))) 43 { 44 _set_errno(EINVAL); 45 return EINVAL; 46 } 47 48 /* Check if there is anything to do */ 49 if ((pwcstr == 0) && (pmbstr == 0)) 50 { 51 _set_errno(EINVAL); 52 return EINVAL; 53 } 54 55 /* Check if we have a multibyte string */ 56 if (pmbstr) 57 { 58 /* Check if we also have a wchar buffer */ 59 if (pwcstr) 60 { 61 /* Calculate the maximum the we can write */ 62 cchMax = (count < sizeInWords) ? count + 1 : sizeInWords; 63 64 /* Now do the conversion */ 65 cwcWritten = mbstowcs(pwcstr, pmbstr, cchMax); 66 67 /* Check if the buffer was not zero terminated */ 68 if (cwcWritten == cchMax) 69 { 70 /* Check if we reached the max size of the dest buffer */ 71 if (cwcWritten == sizeInWords) 72 { 73 /* Does the caller allow this? */ 74 if (count != _TRUNCATE) 75 { 76 /* Not allowed, truncate to 0 length */ 77 pwcstr[0] = L'\0'; 78 79 /* Return error */ 80 _set_errno(ERANGE); 81 return ERANGE; 82 } 83 84 /* Inform the caller about truncation */ 85 retval = STRUNCATE; 86 } 87 88 /* zero teminate the buffer */ 89 pwcstr[cwcWritten - 1] = L'\0'; 90 } 91 else 92 { 93 /* The buffer is zero terminated, count the terminating char */ 94 cwcWritten++; 95 } 96 } 97 else 98 { 99 /* Get the length of the string, plus 0 terminator */ 100 cwcWritten = _mbsnlen((const unsigned char *)pmbstr, count) + 1; 101 } 102 } 103 else 104 { 105 cwcWritten = count + 1; 106 } 107 108 /* Check if we have a return value pointer */ 109 if (pcchConverted) 110 { 111 /* Default to 0 bytes written */ 112 *pcchConverted = cwcWritten; 113 } 114 115 return retval; 116 } 117