diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 2562eb5416..253f18488f 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -988,25 +988,60 @@ static char *
IsoLocaleName(const char *winlocname)
{
#ifdef _MSC_VER
- static char iso_lc_messages[32];
- _locale_t loct = NULL;
+ static char iso_lc_messages[LOCALE_NAME_MAX_LENGTH];
+ _locale_t loct;
if (pg_strcasecmp("c", winlocname) == 0 ||
pg_strcasecmp("posix", winlocname) == 0)
{
- strcpy(iso_lc_messages, "C");
- return iso_lc_messages;
+ return "C";
}
-
loct = _create_locale(LC_CTYPE, winlocname);
if (loct != NULL)
{
size_t rc;
- char *hyphen;
+ char* hyphen;
+
+#if _WIN32_WINNT >= 0x0600
+ WCHAR wc_locale_name[LOCALE_NAME_MAX_LENGTH];
+ WCHAR buffer[LOCALE_NAME_MAX_LENGTH];
+ char loc_name[LOCALE_NAME_MAX_LENGTH];
+ char* tmp;
+
+ /*
+ * We know input locale is valid and has following syntax
+ * [_[.]]
+ * GetLocaleInfoEx can only take locale name without code-page
+ * so we are trimming the unwanted part from the locale name.
+ */
+ tmp = strchr(winlocname, '.');
+ if (tmp != NULL) {
+ size_t cp_index;
+ cp_index = (size_t)(tmp - winlocname);
+ strncpy(loc_name, winlocname, cp_index);
+ loc_name[cp_index] = '\0';
+ }
+ else {
+ // assuming only locale name is given as input string.
+ strcpy(loc_name, winlocname);
+ }
+ memset(wc_locale_name, 0, sizeof(wc_locale_name));
+ memset(buffer, 0, sizeof(buffer));
+ MultiByteToWideChar(CP_ACP, 0, loc_name, -1, wc_locale_name,
+ LOCALE_NAME_MAX_LENGTH);
+ if ((GetLocaleInfoEx(wc_locale_name, LOCALE_SNAME,
+ (LPWSTR)&buffer, LOCALE_NAME_MAX_LENGTH)) > 0) {
+ rc = wchar2char(iso_lc_messages, buffer, sizeof(iso_lc_messages),
+ NULL);
+ }
+ else
+ return NULL;
+#else /* _WIN32_WINNT < 0x0600 */
/* Locale names use only ASCII, any conversion locale suffices. */
rc = wchar2char(iso_lc_messages, loct->locinfo->locale_name[LC_CTYPE],
sizeof(iso_lc_messages), NULL);
+#endif /* _WIN32_WINNT >= 0x0600 */
_free_locale(loct);
if (rc == -1 || rc == sizeof(iso_lc_messages))
return NULL;