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;
404 WideCharToMultiByte(CP_UTF8, 0, wstr, (
int)iwlen, str, (
int)len,
nullptr,
nullptr);
405 if ((rc <= 0) || ((len > 0) && ((
size_t)rc > len)))
407 else if (!isNullTerminated)
409 if (str && ((
size_t)rc < len))
413 else if ((
size_t)rc == len)
415 if (str && (str[rc - 1] !=
'\0'))
421SSIZE_T ConvertMszWCharNToUtf8(
const WCHAR* wstr,
size_t wlen,
char* str,
size_t len)
428 if ((len > INT32_MAX) || (wlen > INT32_MAX))
430 SetLastError(ERROR_INVALID_PARAMETER);
434 const int iwlen = (int)len;
435 const int rc = WideCharToMultiByte(CP_UTF8, 0, wstr, (
int)wlen, str, iwlen,
nullptr,
nullptr);
436 if ((rc <= 0) || ((len > 0) && (rc > iwlen)))
442SSIZE_T ConvertUtf8ToWChar(
const char* str, WCHAR* wstr,
size_t wlen)
451 const size_t len = strlen(str);
452 return ConvertUtf8NToWChar(str, len + 1, wstr, wlen);
455SSIZE_T ConvertUtf8NToWChar(
const char* str,
size_t len, WCHAR* wstr,
size_t wlen)
457 size_t ilen = strnlen(str, len);
458 BOOL isNullTerminated = FALSE;
464 if ((len > INT32_MAX) || (wlen > INT32_MAX))
466 SetLastError(ERROR_INVALID_PARAMETER);
471 isNullTerminated = TRUE;
475 const int iwlen = (int)wlen;
476 const int rc = MultiByteToWideChar(CP_UTF8, 0, str, (
int)ilen, wstr, iwlen);
477 if ((rc <= 0) || ((wlen > 0) && (rc > iwlen)))
479 if (!isNullTerminated)
481 if (wstr && (rc < iwlen))
485 else if (rc == iwlen)
487 if (wstr && (wstr[rc - 1] !=
'\0'))
493SSIZE_T ConvertMszUtf8NToWChar(
const char* str,
size_t len, WCHAR* wstr,
size_t wlen)
500 if ((len > INT32_MAX) || (wlen > INT32_MAX))
502 SetLastError(ERROR_INVALID_PARAMETER);
506 const int iwlen = (int)wlen;
507 const int rc = MultiByteToWideChar(CP_UTF8, 0, str, (
int)len, wstr, iwlen);
508 if ((rc <= 0) || ((wlen > 0) && (rc > iwlen)))
514char* ConvertWCharToUtf8Alloc(
const WCHAR* wstr,
size_t* pUtfCharLength)
517 const SSIZE_T rc = ConvertWCharToUtf8(wstr,
nullptr, 0);
522 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
525 const SSIZE_T rc2 = ConvertWCharToUtf8(wstr, tmp, (
size_t)rc + 1ull);
531 WINPR_ASSERT(rc == rc2);
533 *pUtfCharLength = (size_t)rc2;
537char* ConvertWCharNToUtf8Alloc(
const WCHAR* wstr,
size_t wlen,
size_t* pUtfCharLength)
540 const SSIZE_T rc = ConvertWCharNToUtf8(wstr, wlen,
nullptr, 0);
546 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
549 const SSIZE_T rc2 = ConvertWCharNToUtf8(wstr, wlen, tmp, (
size_t)rc + 1ull);
555 WINPR_ASSERT(rc == rc2);
557 *pUtfCharLength = (size_t)rc2;
561char* ConvertMszWCharNToUtf8Alloc(
const WCHAR* wstr,
size_t wlen,
size_t* pUtfCharLength)
564 const SSIZE_T rc = ConvertMszWCharNToUtf8(wstr, wlen,
nullptr, 0);
570 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
573 const SSIZE_T rc2 = ConvertMszWCharNToUtf8(wstr, wlen, tmp, (
size_t)rc + 1ull);
579 WINPR_ASSERT(rc == rc2);
581 *pUtfCharLength = (size_t)rc2;
585WCHAR* ConvertUtf8ToWCharAlloc(
const char* str,
size_t* pSize)
587 WCHAR* tmp =
nullptr;
588 const SSIZE_T rc = ConvertUtf8ToWChar(str,
nullptr, 0);
593 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
596 const SSIZE_T rc2 = ConvertUtf8ToWChar(str, tmp, (
size_t)rc + 1ull);
602 WINPR_ASSERT(rc == rc2);
604 *pSize = (size_t)rc2;
608WCHAR* ConvertUtf8NToWCharAlloc(
const char* str,
size_t len,
size_t* pSize)
610 WCHAR* tmp =
nullptr;
611 const SSIZE_T rc = ConvertUtf8NToWChar(str, len,
nullptr, 0);
616 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
619 const SSIZE_T rc2 = ConvertUtf8NToWChar(str, len, tmp, (
size_t)rc + 1ull);
625 WINPR_ASSERT(rc == rc2);
627 *pSize = (size_t)rc2;
631WCHAR* ConvertMszUtf8NToWCharAlloc(
const char* str,
size_t len,
size_t* pSize)
633 WCHAR* tmp =
nullptr;
634 const SSIZE_T rc = ConvertMszUtf8NToWChar(str, len,
nullptr, 0);
639 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
642 const SSIZE_T rc2 = ConvertMszUtf8NToWChar(str, len, tmp, (
size_t)rc + 1ull);
648 WINPR_ASSERT(rc == rc2);
650 *pSize = (size_t)rc2;