diff --git a/configure b/configure
index 38f24ffa2e22b24c266cae136183e8c8a6aa8e3a..0c25c09912bef83bb7ab9d12f387b7ba0a3ff866 100755
--- a/configure
+++ b/configure
@@ -17919,6 +17919,12 @@ case " $LIBOBJS " in
  ;;
 esac
 
+case " $LIBOBJS " in
+  *" win32env.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32env.$ac_objext"
+ ;;
+esac
+
 case " $LIBOBJS " in
   *" win32error.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32error.$ac_objext"
diff --git a/configure.in b/configure.in
index fadd4c53adfc3ef801d1a2414773551e9deefc71..3ece4326db6c4fcc2f6d282ca69c8ec02726b8c6 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-dnl $PostgreSQL: pgsql/configure.in,v 1.587 2009/01/14 18:10:21 momjian Exp $
+dnl $PostgreSQL: pgsql/configure.in,v 1.588 2009/01/21 10:30:02 mha Exp $
 dnl
 dnl Developers, please strive to achieve this order:
 dnl
@@ -1274,6 +1274,7 @@ AC_REPLACE_FUNCS(gettimeofday)
 AC_LIBOBJ(kill)
 AC_LIBOBJ(open)
 AC_LIBOBJ(rand)
+AC_LIBOBJ(win32env)
 AC_LIBOBJ(win32error)
 AC_DEFINE([HAVE_SYMLINK], 1,
           [Define to 1 if you have the `symlink' function.])
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 1d35a5066274ec794afef9e35a7d6ddb5b52010d..a29673fdbf1ae8e9e00b09c47ca77b7c4f83d50c 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -4,7 +4,7 @@
  *
  * Portions Copyright (c) 2002-2009, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.45 2009/01/09 14:07:00 mha Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.46 2009/01/21 10:30:02 mha Exp $
  *
  *-----------------------------------------------------------------------
  */
@@ -55,6 +55,9 @@
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
 
+#ifdef WIN32
+#include <shlwapi.h>
+#endif
 
 #define		MAX_L10N_DATA		80
 
@@ -89,6 +92,10 @@ static char lc_monetary_envbuf[LC_ENV_BUFSIZE];
 static char lc_numeric_envbuf[LC_ENV_BUFSIZE];
 static char lc_time_envbuf[LC_ENV_BUFSIZE];
 
+#ifdef WIN32
+static char *IsoLocaleName(const char *); /* MSVC specific */
+#endif
+
 
 /*
  * pg_perm_setlocale
@@ -148,8 +155,13 @@ pg_perm_setlocale(int category, const char *locale)
 		case LC_MESSAGES:
 			envvar = "LC_MESSAGES";
 			envbuf = lc_messages_envbuf;
+#ifdef WIN32
+			result = IsoLocaleName(locale);
+			if (result == NULL)
+				result = locale;
+#endif /* WIN32 */
 			break;
-#endif
+#endif /* LC_MESSAGES */
 		case LC_MONETARY:
 			envvar = "LC_MONETARY";
 			envbuf = lc_monetary_envbuf;
@@ -166,25 +178,13 @@ pg_perm_setlocale(int category, const char *locale)
 			elog(FATAL, "unrecognized LC category: %d", category);
 			envvar = NULL;		/* keep compiler quiet */
 			envbuf = NULL;
-			break;
+			return NULL;
 	}
 
 	snprintf(envbuf, LC_ENV_BUFSIZE - 1, "%s=%s", envvar, result);
 
-#ifndef WIN32
 	if (putenv(envbuf))
 		return NULL;
-#else
-
-	/*
-	 * On Windows, we need to modify both the process environment and the
-	 * cached version in msvcrt
-	 */
-	if (!SetEnvironmentVariable(envvar, result))
-		return NULL;
-	if (_putenv(envbuf))
-		return NULL;
-#endif
 
 	return result;
 }
@@ -599,3 +599,53 @@ cache_locale_time(void)
 
 	CurrentLCTimeValid = true;
 }
+
+
+#ifdef WIN32
+/*
+ *	Convert Windows locale name to the ISO formatted one
+ *	if possible.
+ *
+ *	This function returns NULL if conversion is impossible,
+ *	otherwise returns the pointer to a static area which
+ *	contains the iso formatted locale name.
+ */
+static
+char *IsoLocaleName(const char *winlocname)
+{
+#if (_MSC_VER >= 1400) /* VC8.0 or later */
+	static char	iso_lc_messages[32];
+	_locale_t	loct = NULL;
+
+	if (pg_strcasecmp("c", winlocname) == 0 ||
+		pg_strcasecmp("posix", winlocname) == 0)
+	{
+		strcpy(iso_lc_messages, "C");
+		return iso_lc_messages;
+	}
+
+	loct = _create_locale(LC_CTYPE, winlocname);
+	if (loct != NULL)
+	{
+		char	isolang[32], isocrty[32];
+		LCID	lcid;
+
+		lcid = loct->locinfo->lc_handle[LC_CTYPE];
+		if (lcid == 0)
+			lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
+		_free_locale(loct);
+
+		if (!GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, isolang, sizeof(isolang)))
+			return NULL;
+		if (!GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, isocrty, sizeof(isocrty)))'
+			return NULL;
+		snprintf(iso_lc_messages, sizeof(iso_lc_messages) - 1, "%s_%s", isolang, isocrty);
+		return iso_lc_messages;
+	}
+	return NULL;
+#else
+	return NULL; /* Not supported on this version of msvc/mingw */
+#endif /* _MSC_VER >= 1400 */
+}
+#endif /* WIN32 */
+
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 58baa59bffca24e1c7d13f3ba8339efcda276f77..16773c41bf4a2f54954c58f7e0caf2bf7cca101d 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.85 2009/01/07 03:39:33 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.86 2009/01/21 10:30:02 mha Exp $ */
 
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 #define WIN32_ONLY_COMPILER
@@ -291,6 +291,11 @@ extern int	pgwin32_is_service(void);
 /* in port/win32error.c */
 extern void _dosmaperr(unsigned long);
 
+/* in port/win32env.c */
+extern int pgwin32_putenv(const char *);
+extern void pgwin32_unsetenv(const char *);
+#define putenv(x) pgwin32_putenv(x)
+#define unsetenv(x) pgwin32_unsetenv(x)
 
 /* Things that exist in MingW headers, but need to be added to MSVC */
 #ifdef WIN32_ONLY_COMPILER
diff --git a/src/port/win32env.c b/src/port/win32env.c
new file mode 100644
index 0000000000000000000000000000000000000000..7533549608c58cc33d04b577ab706bde3d473ce4
--- /dev/null
+++ b/src/port/win32env.c
@@ -0,0 +1,93 @@
+/*-------------------------------------------------------------------------
+ *
+ * win32env.c
+ *    putenv() and unsetenv() for win32, that updates both process
+ *    environment and the cached versions in (potentially multiple)
+ *    MSVCRT.
+ *
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  $PostgreSQL: pgsql/src/port/win32env.c,v 1.1 2009/01/21 10:30:02 mha Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "c.h"
+
+int
+pgwin32_putenv(const char *envval)
+{
+	char   *envcpy;
+	char   *cp;
+
+	/*
+	 * Each version of MSVCRT has its own _putenv() call in the runtime
+	 * library.
+	 *
+	 * If we're in VC 7.0 or later (means != mingw), update in
+	 * the 6.0 MSVCRT.DLL environment as well, to work with third party
+	 * libraries linked against it (such as gnuwin32 libraries).
+	 */
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+	typedef int 		(_cdecl *PUTENVPROC)(const char *);
+	HMODULE				hmodule;
+	static PUTENVPROC	putenvFunc = NULL;
+	int					ret;
+
+	if (putenvFunc == NULL)
+	{
+		hmodule = GetModuleHandle("msvcrt");
+		if (hmodule == NULL)
+			return 1;
+		putenvFunc = (PUTENVPROC)GetProcAddress(hmodule, "_putenv");
+		if (putenvFunc == NULL)
+			return 1;
+	}
+	ret = putenvFunc(envval);
+	if (ret != 0)
+		return ret;
+#endif /* _MSC_VER >= 1300 */
+
+
+	/*
+	 * Update the process environment - to make modifications visible
+	 * to child processes.
+	 *
+	 * Need a copy of the string so we can modify it.
+	 */
+	envcpy = strdup(envval);
+	cp = strchr(envcpy, '=');
+	if (cp == NULL)
+		return -1;
+	*cp = '\0';
+	cp++;
+	if (strlen(cp) == 0)
+		cp = NULL;
+	if (!SetEnvironmentVariable(envcpy, cp))
+	{
+		free(envcpy);
+		return -1;
+	}
+	free(envcpy);
+
+	/* Finally, update our "own" cache */
+	return _putenv(envval);
+}
+
+void
+pgwin32_unsetenv(const char *name)
+{
+	char   *envbuf;
+
+	envbuf = (char *) malloc(strlen(name)+2);
+	if (!envbuf)
+		return;
+
+	sprintf(envbuf, "%s=", name);
+	pgwin32_putenv(envbuf);
+	free(envbuf);
+}
+
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index ae31b9fcc2b673fb3a9ed9b40748de7f9140bf74..4d70800853239552d826a309511b6b3a8b303552 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -3,7 +3,7 @@ package Mkvcbuild;
 #
 # Package that generates build files for msvc build
 #
-# $PostgreSQL: pgsql/src/tools/msvc/Mkvcbuild.pm,v 1.35 2008/12/20 22:04:02 mha Exp $
+# $PostgreSQL: pgsql/src/tools/msvc/Mkvcbuild.pm,v 1.36 2009/01/21 10:30:02 mha Exp $
 #
 use Carp;
 use Win32;
@@ -44,10 +44,10 @@ sub mkvcbuild
 
     our @pgportfiles = qw(
       chklocale.c crypt.c fseeko.c getrusage.c inet_aton.c random.c srandom.c
-      unsetenv.c getaddrinfo.c gettimeofday.c kill.c open.c rand.c
+      getaddrinfo.c gettimeofday.c kill.c open.c rand.c
       snprintf.c strlcat.c strlcpy.c copydir.c dirmod.c exec.c noblock.c path.c pipe.c
       pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c sprompt.c thread.c
-      getopt.c getopt_long.c dirent.c rint.c win32error.c);
+      getopt.c getopt_long.c dirent.c rint.c win32env.c win32error.c);
 
     $libpgport = $solution->AddProject('libpgport','lib','misc');
     $libpgport->AddDefine('FRONTEND');