22#include <winpr/config.h>
23#include <winpr/assert.h>
29#include <winpr/error.h>
30#include <winpr/print.h>
149#if !defined(WITH_WINPR_DEPRECATED)
153 MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
int cbMultiByte,
154 LPWSTR lpWideCharStr,
int cchWideChar)
156 return int_MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr,
200#if !defined(WITH_WINPR_DEPRECATED)
204 WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
int cchWideChar,
205 LPSTR lpMultiByteStr,
int cbMultiByte, LPCSTR lpDefaultChar,
206 LPBOOL lpUsedDefaultChar)
208 return int_WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr,
209 cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
226#if defined(WITH_WINPR_DEPRECATED)
227int ConvertToUnicode(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
int cbMultiByte,
228 LPWSTR* lpWideCharStr,
int cchWideChar)
231 BOOL allocate = FALSE;
239 if (cbMultiByte == -1)
241 size_t len = strnlen(lpMultiByteStr, INT_MAX);
244 cbMultiByte = (int)(len + 1);
247 if (cchWideChar == 0)
250 MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte,
nullptr, 0);
253 else if (!(*lpWideCharStr))
261 *lpWideCharStr = (LPWSTR)calloc((
size_t)cchWideChar + 1ull,
sizeof(WCHAR));
263 if (!(*lpWideCharStr))
270 status = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, *lpWideCharStr,
273 if (status != cchWideChar)
277 free(*lpWideCharStr);
278 *lpWideCharStr =
nullptr;
299#if defined(WITH_WINPR_DEPRECATED)
300int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
int cchWideChar,
301 LPSTR* lpMultiByteStr,
int cbMultiByte, LPCSTR lpDefaultChar,
302 LPBOOL lpUsedDefaultChar)
305 BOOL allocate = FALSE;
313 if (cchWideChar == -1)
314 cchWideChar = (int)(_wcslen(lpWideCharStr) + 1);
316 if (cbMultiByte == 0)
318 cbMultiByte = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar,
nullptr, 0,
322 else if (!(*lpMultiByteStr))
330 *lpMultiByteStr = (LPSTR)calloc(1, (
size_t)cbMultiByte + 1ull);
332 if (!(*lpMultiByteStr))
339 status = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, *lpMultiByteStr,
340 cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
342 if ((status != cbMultiByte) && allocate)
347 if ((status <= 0) && allocate)
349 free(*lpMultiByteStr);
350 *lpMultiByteStr =
nullptr;
361const WCHAR* ByteSwapUnicode(WCHAR* wstr,
size_t length)
363 WINPR_ASSERT(wstr || (length == 0));
365 for (
size_t x = 0; x < length; x++)
366 wstr[x] = _byteswap_ushort(wstr[x]);
370SSIZE_T ConvertWCharToUtf8(
const WCHAR* wstr,
char* str,
size_t len)
379 const size_t wlen = _wcslen(wstr);
380 return ConvertWCharNToUtf8(wstr, wlen + 1, str, len);
383SSIZE_T ConvertWCharNToUtf8(
const WCHAR* wstr,
size_t wlen,
char* str,
size_t len)
385 BOOL isNullTerminated = FALSE;
390 size_t iwlen = _wcsnlen(wstr, wlen);
392 if ((len > INT32_MAX) || (wlen > INT32_MAX))
394 SetLastError(ERROR_INVALID_PARAMETER);
400 isNullTerminated = TRUE;
403 WINPR_PRAGMA_DIAG_PUSH
404 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
406 WideCharToMultiByte(CP_UTF8, 0, wstr, (
int)iwlen, str, (
int)len,
nullptr,
nullptr);
407 WINPR_PRAGMA_DIAG_POP
408 if ((rc <= 0) || ((len > 0) && ((
size_t)rc > len)))
410 else if (!isNullTerminated)
412 if (str && ((
size_t)rc < len))
416 else if ((
size_t)rc == len)
418 if (str && (str[rc - 1] !=
'\0'))
424SSIZE_T ConvertMszWCharNToUtf8(
const WCHAR* wstr,
size_t wlen,
char* str,
size_t len)
431 if ((len > INT32_MAX) || (wlen > INT32_MAX))
433 SetLastError(ERROR_INVALID_PARAMETER);
437 const int iwlen = (int)len;
438 WINPR_PRAGMA_DIAG_PUSH
439 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
440 const int rc = WideCharToMultiByte(CP_UTF8, 0, wstr, (
int)wlen, str, iwlen,
nullptr,
nullptr);
441 WINPR_PRAGMA_DIAG_POP
442 if ((rc <= 0) || ((len > 0) && (rc > iwlen)))
448SSIZE_T ConvertUtf8ToWChar(
const char* str, WCHAR* wstr,
size_t wlen)
457 const size_t len = strlen(str);
458 return ConvertUtf8NToWChar(str, len + 1, wstr, wlen);
461SSIZE_T ConvertUtf8NToWChar(
const char* str,
size_t len, WCHAR* wstr,
size_t wlen)
463 size_t ilen = strnlen(str, len);
464 BOOL isNullTerminated = FALSE;
470 if ((len > INT32_MAX) || (wlen > INT32_MAX))
472 SetLastError(ERROR_INVALID_PARAMETER);
477 isNullTerminated = TRUE;
481 const int iwlen = (int)wlen;
482 WINPR_PRAGMA_DIAG_PUSH
483 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
484 const int rc = MultiByteToWideChar(CP_UTF8, 0, str, (
int)ilen, wstr, iwlen);
485 WINPR_PRAGMA_DIAG_POP
486 if ((rc <= 0) || ((wlen > 0) && (rc > iwlen)))
488 if (!isNullTerminated)
490 if (wstr && (rc < iwlen))
494 else if (rc == iwlen)
496 if (wstr && (wstr[rc - 1] !=
'\0'))
502SSIZE_T ConvertMszUtf8NToWChar(
const char* str,
size_t len, WCHAR* wstr,
size_t wlen)
509 if ((len > INT32_MAX) || (wlen > INT32_MAX))
511 SetLastError(ERROR_INVALID_PARAMETER);
515 const int iwlen = (int)wlen;
516 WINPR_PRAGMA_DIAG_PUSH
517 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
518 const int rc = MultiByteToWideChar(CP_UTF8, 0, str, (
int)len, wstr, iwlen);
519 WINPR_PRAGMA_DIAG_POP
520 if ((rc <= 0) || ((wlen > 0) && (rc > iwlen)))
526char* ConvertWCharToUtf8Alloc(
const WCHAR* wstr,
size_t* pUtfCharLength)
529 const SSIZE_T rc = ConvertWCharToUtf8(wstr,
nullptr, 0);
534 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
537 const SSIZE_T rc2 = ConvertWCharToUtf8(wstr, tmp, (
size_t)rc + 1ull);
543 WINPR_ASSERT(rc == rc2);
545 *pUtfCharLength = (size_t)rc2;
549char* ConvertWCharNToUtf8Alloc(
const WCHAR* wstr,
size_t wlen,
size_t* pUtfCharLength)
552 const SSIZE_T rc = ConvertWCharNToUtf8(wstr, wlen,
nullptr, 0);
558 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
561 const SSIZE_T rc2 = ConvertWCharNToUtf8(wstr, wlen, tmp, (
size_t)rc + 1ull);
567 WINPR_ASSERT(rc == rc2);
569 *pUtfCharLength = (size_t)rc2;
573char* ConvertMszWCharNToUtf8Alloc(
const WCHAR* wstr,
size_t wlen,
size_t* pUtfCharLength)
576 const SSIZE_T rc = ConvertMszWCharNToUtf8(wstr, wlen,
nullptr, 0);
582 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
585 const SSIZE_T rc2 = ConvertMszWCharNToUtf8(wstr, wlen, tmp, (
size_t)rc + 1ull);
591 WINPR_ASSERT(rc == rc2);
593 *pUtfCharLength = (size_t)rc2;
597WCHAR* ConvertUtf8ToWCharAlloc(
const char* str,
size_t* pSize)
599 WCHAR* tmp =
nullptr;
600 const SSIZE_T rc = ConvertUtf8ToWChar(str,
nullptr, 0);
605 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
608 const SSIZE_T rc2 = ConvertUtf8ToWChar(str, tmp, (
size_t)rc + 1ull);
614 WINPR_ASSERT(rc == rc2);
616 *pSize = (size_t)rc2;
620WCHAR* ConvertUtf8NToWCharAlloc(
const char* str,
size_t len,
size_t* pSize)
622 WCHAR* tmp =
nullptr;
623 const SSIZE_T rc = ConvertUtf8NToWChar(str, len,
nullptr, 0);
628 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
631 const SSIZE_T rc2 = ConvertUtf8NToWChar(str, len, tmp, (
size_t)rc + 1ull);
637 WINPR_ASSERT(rc == rc2);
639 *pSize = (size_t)rc2;
643WCHAR* ConvertMszUtf8NToWCharAlloc(
const char* str,
size_t len,
size_t* pSize)
645 WCHAR* tmp =
nullptr;
646 const SSIZE_T rc = ConvertMszUtf8NToWChar(str, len,
nullptr, 0);
651 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
654 const SSIZE_T rc2 = ConvertMszUtf8NToWChar(str, len, tmp, (
size_t)rc + 1ull);
660 WINPR_ASSERT(rc == rc2);
662 *pSize = (size_t)rc2;