From 1a82f90f487df70e59560a136196ac3fef27c95c Mon Sep 17 00:00:00 2001 From: LeonidGoltsblat <138720759+LeonidGoltsblat@users.noreply.github.com> Date: Wed, 31 Jul 2024 04:12:04 +0300 Subject: [PATCH] Get thread locale in pj strerror (#4018) --- pjlib/include/pj/errno.h | 16 +++++++++++++++- pjlib/src/pj/os_error_win32.c | 13 +++++++++++-- pjlib/src/pjlib-test/errno.c | 10 ++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/pjlib/include/pj/errno.h b/pjlib/include/pj/errno.h index c2095482d..9eb8e9771 100644 --- a/pjlib/include/pj/errno.h +++ b/pjlib/include/pj/errno.h @@ -81,7 +81,9 @@ PJ_BEGIN_DECL /** * Guidelines on error message length. */ -#define PJ_ERR_MSG_SIZE 80 +#ifndef PJ_ERR_MSG_SIZE +# define PJ_ERR_MSG_SIZE 80 +#endif /** * Buffer for title string of #PJ_PERROR(). @@ -90,6 +92,18 @@ PJ_BEGIN_DECL # define PJ_PERROR_TITLE_BUF_SIZE 120 #endif +/** + * On Windows XP and later, force the use of GetThreadLocale() in pj_strerror() + * to obtain the required locale and corresponding language for the platform + * error message string. + * Default value is set to "no" for compatibility reason, which means use + * "User default language". + * + * Default: 0 (no) + */ +#ifndef PJ_STRERROR_USE_WIN_GET_THREAD_LOCALE +# define PJ_STRERROR_USE_WIN_GET_THREAD_LOCALE 0 +#endif /** * Get the last platform error/status, folded into pj_status_t. diff --git a/pjlib/src/pj/os_error_win32.c b/pjlib/src/pj/os_error_win32.c index 25719aad4..a07071d3b 100644 --- a/pjlib/src/pj/os_error_win32.c +++ b/pjlib/src/pj/os_error_win32.c @@ -173,12 +173,21 @@ int platform_strerror( pj_os_err_type os_errcode, if (!len) { + DWORD dwLanguageId; +#if defined(PJ_STRERROR_USE_WIN_GET_THREAD_LOCALE) && \ + (PJ_STRERROR_USE_WIN_GET_THREAD_LOCALE==1) && (WINVER >= 0x0500) + /* current thread language */ + dwLanguageId = LANGIDFROMLCID(GetThreadLocale()); +#else + /* LANG_USER_DEFAULT - User default language */ + dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); +#endif #if PJ_NATIVE_STRING_IS_UNICODE len = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, os_errcode, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + dwLanguageId, wbuf, PJ_ARRAY_SIZE(wbuf), NULL); @@ -190,7 +199,7 @@ int platform_strerror( pj_os_err_type os_errcode, | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, os_errcode, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + dwLanguageId, buf, (int)bufsize, NULL); diff --git a/pjlib/src/pjlib-test/errno.c b/pjlib/src/pjlib-test/errno.c index b5fbc4e53..9231f135e 100644 --- a/pjlib/src/pjlib-test/errno.c +++ b/pjlib/src/pjlib-test/errno.c @@ -86,7 +86,17 @@ int errno_test(void) pj_set_os_error(rc); /* Whole */ +#if defined(PJ_STRERROR_USE_WIN_GET_THREAD_LOCALE) && (PJ_STRERROR_USE_WIN_GET_THREAD_LOCALE==1) && (WINVER >= 0x0500) + LCID lcid = GetThreadLocale(); + /* set en_US thread locale to obtain "invalid" in errbuff */ + BOOL res = SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); + PJ_UNUSED_ARG(res); +#endif pj_strerror(rc, errbuf, sizeof(errbuf)); +#if defined(PJ_STRERROR_USE_WIN_GET_THREAD_LOCALE) && (PJ_STRERROR_USE_WIN_GET_THREAD_LOCALE==1) && (WINVER >= 0x0500) + /* restore thread locale now */ + SetThreadLocale(lcid); +#endif trim_newlines(errbuf); PJ_LOG(3,(THIS_FILE, "...msg for rc=ERROR_INVALID_DATA: '%s'", errbuf)); if (my_stristr(errbuf, "invalid") == NULL) {