diff -cprN head/src/backend/utils/error/elog.c eventlog/src/backend/utils/error/elog.c
*** head/src/backend/utils/error/elog.c	2009-07-04 04:14:25.000000000 +0900
--- eventlog/src/backend/utils/error/elog.c	2009-09-15 12:31:24.555451172 +0900
*************** static int	syslog_facility = LOG_LOCAL0;
*** 111,118 ****
  static void write_syslog(int level, const char *line);
  #endif
  
  #ifdef WIN32
! static void write_eventlog(int level, const char *line);
  #endif
  
  /* We provide a small stack of ErrorData records for re-entrant cases */
--- 111,120 ----
  static void write_syslog(int level, const char *line);
  #endif
  
+ static void write_console(const char *line, int len);
+ 
  #ifdef WIN32
! static void write_eventlog(int level, const char *line, int len);
  #endif
  
  /* We provide a small stack of ErrorData records for re-entrant cases */
*************** write_syslog(int level, const char *line
*** 1567,1573 ****
   * Write a message line to the windows event log
   */
  static void
! write_eventlog(int level, const char *line)
  {
  	int			eventlevel = EVENTLOG_ERROR_TYPE;
  	static HANDLE evtHandle = INVALID_HANDLE_VALUE;
--- 1569,1575 ----
   * Write a message line to the windows event log
   */
  static void
! write_eventlog(int level, const char *line, int len)
  {
  	int			eventlevel = EVENTLOG_ERROR_TYPE;
  	static HANDLE evtHandle = INVALID_HANDLE_VALUE;
*************** write_eventlog(int level, const char *li
*** 1606,1613 ****
  			break;
  	}
  
! 
! 	ReportEvent(evtHandle,
  				eventlevel,
  				0,
  				0,				/* All events are Id 0 */
--- 1608,1616 ----
  			break;
  	}
  
! 	if (GetDatabaseEncoding() == GetPlatformEncoding())
! 	{
! 		ReportEventA(evtHandle,
  				eventlevel,
  				0,
  				0,				/* All events are Id 0 */
*************** write_eventlog(int level, const char *li
*** 1616,1624 ****
--- 1619,1685 ----
  				0,
  				&line,
  				NULL);
+ 	}
+ 	else
+ 	{
+ 		WCHAR  *utf16;
+ 		int		utf16len;
+ 
+ 		utf16 = pgwin32_toUTF16(line, len, &utf16len);
+ 		ReportEventW(evtHandle,
+ 				eventlevel,
+ 				0,
+ 				0,				/* All events are Id 0 */
+ 				NULL,
+ 				1,
+ 				0,
+ 				(LPCWSTR *) &utf16,
+ 				NULL);
+ 
+ 		pfree(utf16);
+ 	}
  }
+ 
  #endif   /* WIN32 */
  
+ static void
+ write_console(const char *line, int len)
+ {
+ 	if (GetDatabaseEncoding() != GetPlatformEncoding())
+ 	{
+ #ifdef WIN32
+ 		static bool	redirected = false;
+ 
+ 		if (!redirected)
+ 		{
+ 			WCHAR	   *utf16;
+ 			int			utf16len;
+ 			HANDLE		stderrHandle;
+ 			DWORD		written;
+ 
+ 			utf16 = pgwin32_toUTF16(line, len, &utf16len);
+ 			stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
+ 			if (WriteConsoleW(stderrHandle, utf16, utf16len, &written, NULL))
+ 			{
+ 				pfree(utf16);
+ 				return;
+ 			}
+ 
+ 			pfree(utf16);
+ 			redirected = true;	/* stderr might be redirected */
+ 		}
+ #else
+ 		/*
+ 		 * Conversion on non-win32 platform is not implemented yet.
+ 		 * It requires non-throw version of pg_do_encoding_conversion(),
+ 		 * that converts unconvertable characters to '?' without errors.
+ 		 */
+ #endif
+ 	}
+ 
+ 	write(fileno(stderr), line, len);
+ }
+ 
  /*
   * setup formatted_log_time, for consistent times between CSV and regular logs
   */
*************** send_message_to_server_log(ErrorData *ed
*** 2206,2212 ****
  	/* Write to eventlog, if enabled */
  	if (Log_destination & LOG_DESTINATION_EVENTLOG)
  	{
! 		write_eventlog(edata->elevel, buf.data);
  	}
  #endif   /* WIN32 */
  
--- 2267,2273 ----
  	/* Write to eventlog, if enabled */
  	if (Log_destination & LOG_DESTINATION_EVENTLOG)
  	{
! 		write_eventlog(edata->elevel, buf.data, buf.len);
  	}
  #endif   /* WIN32 */
  
*************** send_message_to_server_log(ErrorData *ed
*** 2230,2239 ****
  		 * because that's really a pipe to the syslogger process.
  		 */
  		else if (pgwin32_is_service())
! 			write_eventlog(edata->elevel, buf.data);
  #endif
  		else
! 			write(fileno(stderr), buf.data, buf.len);
  	}
  
  	/* If in the syslogger process, try to write messages direct to file */
--- 2291,2300 ----
  		 * because that's really a pipe to the syslogger process.
  		 */
  		else if (pgwin32_is_service())
! 			write_eventlog(edata->elevel, buf.data, buf.len);
  #endif
  		else
! 			write_console(buf.data, buf.len);
  	}
  
  	/* If in the syslogger process, try to write messages direct to file */
*************** send_message_to_server_log(ErrorData *ed
*** 2256,2267 ****
  		{
  			const char *msg = _("Not safe to send CSV data\n");
  
! 			write(fileno(stderr), msg, strlen(msg));
  			if (!(Log_destination & LOG_DESTINATION_STDERR) &&
  				whereToSendOutput != DestDebug)
  			{
  				/* write message to stderr unless we just sent it above */
! 				write(fileno(stderr), buf.data, buf.len);
  			}
  			pfree(buf.data);
  		}
--- 2317,2328 ----
  		{
  			const char *msg = _("Not safe to send CSV data\n");
  
! 			write_console(msg, strlen(msg));
  			if (!(Log_destination & LOG_DESTINATION_STDERR) &&
  				whereToSendOutput != DestDebug)
  			{
  				/* write message to stderr unless we just sent it above */
! 				write_console(buf.data, buf.len);
  			}
  			pfree(buf.data);
  		}
*************** void
*** 2642,2647 ****
--- 2703,2711 ----
  write_stderr(const char *fmt,...)
  {
  	va_list		ap;
+ #ifdef WIN32
+ 	char		errbuf[2048];		/* Arbitrary size? */
+ #endif
  
  	fmt = _(fmt);
  
*************** write_stderr(const char *fmt,...)
*** 2651,2656 ****
--- 2715,2721 ----
  	vfprintf(stderr, fmt, ap);
  	fflush(stderr);
  #else
+ 	vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
  
  	/*
  	 * On Win32, we print to stderr if running on a console, or write to
*************** write_stderr(const char *fmt,...)
*** 2658,2673 ****
  	 */
  	if (pgwin32_is_service())	/* Running as a service */
  	{
! 		char		errbuf[2048];		/* Arbitrary size? */
! 
! 		vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
! 
! 		write_eventlog(ERROR, errbuf);
  	}
  	else
  	{
  		/* Not running as service, write to stderr */
! 		vfprintf(stderr, fmt, ap);
  		fflush(stderr);
  	}
  #endif
--- 2723,2734 ----
  	 */
  	if (pgwin32_is_service())	/* Running as a service */
  	{
! 		write_eventlog(ERROR, errbuf, strlen(errbuf));
  	}
  	else
  	{
  		/* Not running as service, write to stderr */
! 		write_console(errbuf, strlen(errbuf));
  		fflush(stderr);
  	}
  #endif
diff -cprN head/src/backend/utils/mb/mbutils.c eventlog/src/backend/utils/mb/mbutils.c
*** head/src/backend/utils/mb/mbutils.c	2009-07-08 04:28:56.000000000 +0900
--- eventlog/src/backend/utils/mb/mbutils.c	2009-09-15 12:31:24.556451161 +0900
*************** static FmgrInfo *ToClientConvProc = NULL
*** 58,63 ****
--- 58,64 ----
   */
  static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
  static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
+ static pg_enc2name *PlatformEncoding = NULL;
  
  /*
   * During backend startup we can't set client encoding because we (a)
*************** pg_client_encoding(PG_FUNCTION_ARGS)
*** 978,980 ****
--- 979,1083 ----
  	Assert(ClientEncoding);
  	return DirectFunctionCall1(namein, CStringGetDatum(ClientEncoding->name));
  }
+ 
+ int
+ GetPlatformEncoding(void)
+ {
+ 	if (PlatformEncoding == NULL)
+ 		PlatformEncoding = &pg_enc2name_tbl[pg_get_encoding_from_locale("")];
+ 	return PlatformEncoding->encoding;
+ }
+ 
+ #ifdef WIN32
+ 
+ static const UINT encoding_to_codepage[] =
+ {
+ 	0,			/* PG_SQL_ASCII */
+ 	20932,		/* PG_EUC_JP */
+ 	20936,		/* PG_EUC_CN */
+ 	51949,		/* PG_EUC_KR */
+ 	0,			/* PG_EUC_TW */
+ 	20932,		/* PG_EUC_JIS_2004 */
+ 	CP_UTF8,	/* PG_UTF8 */
+ 	0,			/* PG_MULE_INTERNAL */
+ 	28591,		/* PG_LATIN1 */
+ 	28592,		/* PG_LATIN2 */
+ 	28593,		/* PG_LATIN3 */
+ 	28594,		/* PG_LATIN4 */
+ 	28599,		/* PG_LATIN5 */
+ 	0,			/* PG_LATIN6 */
+ 	0,			/* PG_LATIN7 */
+ 	0,			/* PG_LATIN8 */
+ 	28605,		/* PG_LATIN9 */
+ 	0,			/* PG_LATIN10 */
+ 	1256,		/* PG_WIN1256 */
+ 	1258,		/* PG_WIN1258 */
+ 	866,		/* PG_WIN866 */
+ 	874,		/* PG_WIN874 */
+ 	20866,		/* PG_KOI8R */
+ 	1251,		/* PG_WIN1251 */
+ 	1252,		/* PG_WIN1252 */
+ 	28595,		/* PG_ISO_8859_5 */
+ 	28596,		/* PG_ISO_8859_6 */
+ 	28597,		/* PG_ISO_8859_7 */
+ 	28598,		/* PG_ISO_8859_8 */
+ 	1250,		/* PG_WIN1250 */
+ 	1253,		/* PG_WIN1253 */
+ 	1254,		/* PG_WIN1254 */
+ 	1255,		/* PG_WIN1255 */
+ 	1257,		/* PG_WIN1257 */
+ 	21866,		/* PG_KOI8U */
+ 	932,		/* PG_SJIS */
+ 	950,		/* PG_BIG5 */
+ 	936,		/* PG_GBK */
+ 	0,			/* PG_UHC */
+ 	54936,		/* PG_GB18030 */
+ 	0,			/* PG_JOHAB */
+ 	932			/* PG_SHIFT_JIS_2004 */
+ };
+ 
+ /*
+  * Result is palloc'ed null-terminated utf16 string. The character length
+  * is also passed to utf16len if not null.
+  */
+ WCHAR *
+ pgwin32_toUTF16(const char *str, int len, int *utf16len)
+ {
+ 	WCHAR	   *utf16;
+ 	UINT		codepage;
+ 
+ 	codepage = encoding_to_codepage[GetDatabaseEncoding()];
+ 
+ 	/*
+ 	 * Use MultiByteToWideChar directly if there is a corresponding codepage,
+ 	 * or double conversion through UTF8.
+ 	 */
+ 	if (codepage != 0)
+ 	{
+ 		utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
+ 		len = MultiByteToWideChar(codepage, 0, str, len, utf16, len);
+ 		utf16[len] = L'\0';
+ 	}
+ 	else
+ 	{
+ 		char	   *utf8;
+ 
+ 		utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str,
+ 										len, GetDatabaseEncoding(), PG_UTF8);
+ 		if (utf8 != str)
+ 			len = strlen(utf8);
+ 
+ 		utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
+ 		len = MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, len);
+ 		utf16[len] = L'\0';
+ 
+ 		if (utf8 != str)
+ 			pfree(utf8);
+ 	}
+ 
+ 	if (utf16len)
+ 		*utf16len = len;
+ 	return utf16;
+ }
+ 
+ #endif
diff -cprN head/src/include/mb/pg_wchar.h eventlog/src/include/mb/pg_wchar.h
*** head/src/include/mb/pg_wchar.h	2009-06-11 23:49:11.000000000 +0900
--- eventlog/src/include/mb/pg_wchar.h	2009-09-15 12:31:24.556451161 +0900
*************** extern const char *pg_get_client_encodin
*** 402,407 ****
--- 402,408 ----
  extern void SetDatabaseEncoding(int encoding);
  extern int	GetDatabaseEncoding(void);
  extern const char *GetDatabaseEncodingName(void);
+ extern int	GetPlatformEncoding(void);
  extern void pg_bind_textdomain_codeset(const char *domainname);
  
  extern int	pg_valid_client_encoding(const char *name);
*************** extern void mic2latin_with_table(const u
*** 458,461 ****
--- 459,466 ----
  
  extern bool pg_utf8_islegal(const unsigned char *source, int length);
  
+ #ifdef WIN32
+ extern WCHAR *pgwin32_toUTF16(const char *str, int len, int *utf16len);
+ #endif
+ 
  #endif   /* PG_WCHAR_H */
diff -cprN head/src/port/open.c eventlog/src/port/open.c
*** head/src/port/open.c	2009-06-11 23:49:15.000000000 +0900
--- eventlog/src/port/open.c	2009-09-15 12:31:24.556451161 +0900
***************
*** 23,28 ****
--- 23,31 ----
  #include <fcntl.h>
  #include <assert.h>
  
+ #ifndef FRONTEND
+ #include "mb/pg_wchar.h"
+ #endif
  
  static int
  openFlagsToCreateFileFlags(int openFlags)
*************** pgwin32_open(const char *fileName, int f
*** 65,70 ****
--- 68,78 ----
  	HANDLE		h = INVALID_HANDLE_VALUE;
  	SECURITY_ATTRIBUTES sa;
  	int			loops = 0;
+ 	DWORD		dwDesiredAccess;
+ 	DWORD		dwShareMode;
+     DWORD		dwCreationDisposition;
+     DWORD		dwFlagsAndAttributes;
+ 	WCHAR	   *wFileName = NULL;
  
  	/* Check that we can handle the request */
  	assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND |
*************** pgwin32_open(const char *fileName, int f
*** 72,97 ****
  						 _O_SHORT_LIVED | O_DSYNC | O_DIRECT |
  		  (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);
  
- 	sa.nLength = sizeof(sa);
- 	sa.bInheritHandle = TRUE;
- 	sa.lpSecurityDescriptor = NULL;
- 
- 	while ((h = CreateFile(fileName,
  	/* cannot use O_RDONLY, as it == 0 */
! 					  (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
! 					 ((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ),
  	/* These flags allow concurrent rename/unlink */
! 					(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
! 						   &sa,
! 						   openFlagsToCreateFileFlags(fileFlags),
! 						   FILE_ATTRIBUTE_NORMAL |
  					 ((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) |
  			   ((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) |
  			  ((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) |
  				((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0) |
  					  ((fileFlags & O_DIRECT) ? FILE_FLAG_NO_BUFFERING : 0) |
! 					   ((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0),
! 						   NULL)) == INVALID_HANDLE_VALUE)
  	{
  		/*
  		 * Sharing violation or locking error can indicate antivirus, backup
--- 80,126 ----
  						 _O_SHORT_LIVED | O_DSYNC | O_DIRECT |
  		  (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);
  
  	/* cannot use O_RDONLY, as it == 0 */
! 	dwDesiredAccess = (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
! 						((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ);
  	/* These flags allow concurrent rename/unlink */
! 	dwShareMode = (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
!     dwCreationDisposition = openFlagsToCreateFileFlags(fileFlags);
!     dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL |
  					 ((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) |
  			   ((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) |
  			  ((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) |
  				((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0) |
  					  ((fileFlags & O_DIRECT) ? FILE_FLAG_NO_BUFFERING : 0) |
! 					   ((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0);
! 
! 	sa.nLength = sizeof(sa);
! 	sa.bInheritHandle = TRUE;
! 	sa.lpSecurityDescriptor = NULL;
! 
! #ifndef FRONTEND
! 	/*
! 	 * Use wide-character file name only if the database encoding doesn't match
! 	 * to the platform encoding and the path contains any multi-byte characters.
! 	 */
! 	if (GetDatabaseEncoding() != GetPlatformEncoding())
! 	{
! 		int		len;
! 		bool	hasMBChar = false;
! 
! 		for (len = 0; fileName[len]; len++)
! 			hasMBChar |= IS_HIGHBIT_SET(fileName[len]);
! 		if (hasMBChar)
! 			wFileName = pgwin32_toUTF16(fileName, len, NULL);
! 	}
! #endif
! 
! 	while ((h = (wFileName != NULL
! 				? CreateFileW(wFileName, dwDesiredAccess, dwShareMode, &sa,
! 						dwCreationDisposition, dwFlagsAndAttributes, NULL)
! 				: CreateFileA(fileName, dwDesiredAccess, dwShareMode, &sa,
! 						dwCreationDisposition, dwFlagsAndAttributes, NULL))
! 		   ) == INVALID_HANDLE_VALUE)
  	{
  		/*
  		 * Sharing violation or locking error can indicate antivirus, backup
*************** pgwin32_open(const char *fileName, int f
*** 119,128 ****
--- 148,166 ----
  				continue;
  		}
  
+ #ifndef FRONTEND
+ 		if (wFileName)
+ 			pfree(wFileName);
+ #endif
  		_dosmaperr(err);
  		return -1;
  	}
  
+ #ifndef FRONTEND
+ 	if (wFileName)
+ 		pfree(wFileName);
+ #endif
+ 
  	/* _open_osfhandle will, on error, set errno accordingly */
  	if ((fd = _open_osfhandle((long) h, fileFlags & O_APPEND)) < 0)
  		CloseHandle(h);			/* will not affect errno */
