Index: src/file.c
==================================================================
--- src/file.c
+++ src/file.c
@@ -27,10 +27,14 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
 #include "file.h"
+#if defined(_WIN32)
+#include <direct.h>
+#endif
+
 
 /*
 ** On Windows, include the Platform SDK header file.
 */
 #ifdef _WIN32
@@ -68,12 +72,12 @@
   }else{
     return stat(zFilename, buf);
   }
 #else
   int rc = 0;
-  char *zMbcs = fossil_utf8_to_mbcs(zFilename);
-  rc = stat(zMbcs, buf);
+  wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
+  rc = _wstati64(zMbcs, buf);
   fossil_mbcs_free(zMbcs);
   return rc;
 #endif
 }
 
@@ -298,13 +302,17 @@
 
 /*
 ** Wrapper around the access() system call.
 */
 int file_access(const char *zFilename, int flags){
-  char *zMbcs = fossil_utf8_to_mbcs(zFilename);
-  int rc = access(zMbcs, flags);
+#ifdef _WIN32
+  wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
+  int rc = _waccess(zMbcs, flags);
   fossil_mbcs_free(zMbcs);
+#else
+  int rc = access(zFilename, flags);
+#endif
   return rc;
 }
 
 /*
 ** Find an unused filename similar to zBase with zSuffix appended.
@@ -389,13 +397,17 @@
 
 /*
 ** Delete a file.
 */
 void file_delete(const char *zFilename){
-  char *z = fossil_utf8_to_mbcs(zFilename);
-  unlink(z);
+#ifdef _WIN32
+  wchar_t *z = fossil_utf8_to_unicode(zFilename);
+  _wunlink(z);
   fossil_mbcs_free(z);
+#else
+  unlink(zFilename);
+#endif
 }
 
 /*
 ** Create the directory named in the argument, if it does not already
 ** exist.  If forceFlag is 1, delete any prior non-directory object 
@@ -410,12 +422,12 @@
     file_delete(zName);
   }
   if( rc!=1 ){
 #if defined(_WIN32)
     int rc;
-    char *zMbcs = fossil_utf8_to_mbcs(zName);
-    rc = mkdir(zMbcs);
+    wchar_t *zMbcs = fossil_utf8_to_unicode(zName);
+    rc = _wmkdir(zMbcs);
     fossil_mbcs_free(zMbcs);
     return rc;
 #else
     return mkdir(zName, 0755);
 #endif
@@ -561,24 +573,24 @@
 }
 
 /*
 ** Get the current working directory.
 **
-** On windows, the name is converted from MBCS to UTF8 and all '\\'
+** On windows, the name is converted from unicode to UTF8 and all '\\'
 ** characters are converted to '/'.  No conversions are needed on
 ** unix.
 */
 void file_getcwd(char *zBuf, int nBuf){
 #ifdef _WIN32
   char *zPwdUtf8;
   int nPwd;
   int i;
-  char zPwd[2000];
-  if( getcwd(zPwd, sizeof(zPwd)-1)==0 ){
+  wchar_t zPwd[2000];
+  if( _wgetcwd(zPwd, sizeof(zPwd)-1)==0 ){
     fossil_fatal("cannot find the current working directory.");
   }
-  zPwdUtf8 = fossil_mbcs_to_utf8(zPwd);
+  zPwdUtf8 = fossil_unicode_to_utf8(zPwd);
   nPwd = strlen(zPwdUtf8);
   if( nPwd > nBuf-1 ){
     fossil_fatal("pwd too big: max %d\n", nBuf-1);
   }
   for(i=0; zPwdUtf8[i]; i++) if( zPwdUtf8[i]=='\\' ) zPwdUtf8[i] = '/';
@@ -928,14 +940,14 @@
   unsigned int i, j;
   const char *zDir = ".";
   int cnt = 0;
 
 #if defined(_WIN32)
-  char zTmpPath[MAX_PATH];
+  wchar_t zTmpPath[MAX_PATH];
 
-  if( GetTempPath(sizeof(zTmpPath), zTmpPath) ){
-    azDirs[0] = zTmpPath;
+  if( GetTempPathW(MAX_PATH, zTmpPath) ){
+    azDirs[0] = fossil_unicode_to_utf8(zTmpPath);
   }
 
   azDirs[1] = fossil_getenv("TEMP");
   azDirs[2] = fossil_getenv("TMP");
 #endif
@@ -1014,10 +1026,29 @@
   return sqlite3_win32_mbcs_to_utf8(zMbcs);
 #else
   return (char*)zMbcs;  /* No-op on unix */
 #endif  
 }
+
+/*
+** Translate Unicode to UTF8.  Return a pointer to the translated text.
+** Call fossil_mbcs_free() to deallocate any memory used to store the
+** returned pointer when done.
+*/
+char *fossil_unicode_to_utf8(const void *zUnicode){
+#ifdef _WIN32
+  int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
+  char *zUtf = sqlite3_malloc( nByte );
+  if( zUtf==0 ){
+    return 0;
+  }
+  WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, zUtf, nByte, 0, 0);
+  return zUtf;
+#else
+  return (char *)zUnicode;  /* No-op on unix */
+#endif
+}
 
 /*
 ** Translate UTF8 to MBCS for use in system calls.  Return a pointer to the
 ** translated text..  Call fossil_mbcs_free() to deallocate any memory
 ** used to store the returned pointer when done.
@@ -1028,18 +1059,41 @@
   return sqlite3_win32_utf8_to_mbcs(zUtf8);
 #else
   return (char*)zUtf8;  /* No-op on unix */
 #endif  
 }
+
+/*
+** Translate UTF8 to unicode for use in system calls.  Return a pointer to the
+** translated text..  Call fossil_mbcs_free() to deallocate any memory
+** used to store the returned pointer when done.
+*/
+void *fossil_utf8_to_unicode(const char *zUtf8){
+#ifdef _WIN32
+  int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
+  wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
+  if( zUnicode==0 ){
+    return 0;
+  }
+  MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
+  return zUnicode;
+#else
+  return (void *)zUtf8;  /* No-op on unix */
+#endif
+}
 
 /*
 ** Return the value of an environment variable as UTF8.
 */
 char *fossil_getenv(const char *zName){
-  char *zValue = getenv(zName);
 #ifdef _WIN32
-  if( zValue ) zValue = fossil_mbcs_to_utf8(zValue);
+  wchar_t *uName = fossil_utf8_to_unicode(zName);
+  void *zValue = _wgetenv(uName);
+  fossil_mbcs_free(uName);
+  if( zValue ) zValue = fossil_unicode_to_utf8(zValue);
+#else
+  char *zValue = getenv(zName);
 #endif
   return zValue;
 }
 
 /*
@@ -1085,11 +1139,11 @@
 
 /*
 ** Translate MBCS to UTF8.  Return a pointer.  Call fossil_mbcs_free()
 ** to deallocate any memory used to store the returned pointer when done.
 */
-void fossil_mbcs_free(char *zOld){
+void fossil_mbcs_free(void *zOld){
 #ifdef _WIN32
   extern void sqlite3_free(void*);
   sqlite3_free(zOld);
 #else
   /* No-op on unix */
@@ -1098,10 +1152,16 @@
 
 /*
 ** Like fopen() but always takes a UTF8 argument.
 */
 FILE *fossil_fopen(const char *zName, const char *zMode){
-  char *zMbcs = fossil_utf8_to_mbcs(zName);
-  FILE *f = fopen(zMbcs, zMode);
-  fossil_mbcs_free(zMbcs);
+#ifdef _WIN32
+  wchar_t *uMode = fossil_utf8_to_unicode(zMode);
+  wchar_t *uName = fossil_utf8_to_unicode(zName);
+  FILE *f = _wfopen(uName, uMode);
+  fossil_mbcs_free(uName);
+  fossil_mbcs_free(uMode);
+#else
+  FILE *f = fopen(zName, zMode);
+#endif
   return f;
 }

Index: src/rebuild.c
==================================================================
--- src/rebuild.c
+++ src/rebuild.c
@@ -21,10 +21,19 @@
 #include "rebuild.h"
 #include <assert.h>
 #include <dirent.h>
 #include <errno.h>
 
+#ifndef _WIN32
+#define _WDIR DIR
+#define _wdirent dirent
+#define _wopendir opendir
+#define _wreaddir readdir
+#define _wclosedir closedir
+#define wchar_t char
+#endif
+
 /*
 ** Make changes to the stable part of the schema (the part that is not
 ** simply deleted and reconstructed on a rebuild) to bring the schema
 ** up to the latest.
 */
@@ -818,28 +827,28 @@
 /*
 ** Recursively read all files from the directory zPath and install
 ** every file read as a new artifact in the repository.
 */
 void recon_read_dir(char *zPath){
-  DIR *d;
-  struct dirent *pEntry;
+  _WDIR *d;
+  struct _wdirent *pEntry;
   Blob aContent; /* content of the just read artifact */
   static int nFileRead = 0;
-  char *zMbcsPath;
+  wchar_t *zMbcsPath;
   char *zUtf8Name;
 
-  zMbcsPath = fossil_utf8_to_mbcs(zPath);
-  d = opendir(zMbcsPath);
+  zMbcsPath = fossil_utf8_to_unicode(zPath);
+  d = _wopendir(zMbcsPath);
   if( d ){
-    while( (pEntry=readdir(d))!=0 ){
+    while( (pEntry=_wreaddir(d))!=0 ){
       Blob path;
       char *zSubpath;
 
       if( pEntry->d_name[0]=='.' ){
         continue;
       }
-      zUtf8Name = fossil_mbcs_to_utf8(pEntry->d_name);
+      zUtf8Name = fossil_unicode_to_utf8(pEntry->d_name);
       zSubpath = mprintf("%s/%s", zPath, zUtf8Name);
       fossil_mbcs_free(zUtf8Name);
       if( file_isdir(zSubpath)==1 ){
         recon_read_dir(zSubpath);
       }
@@ -854,11 +863,11 @@
       blob_reset(&aContent);
       free(zSubpath);
       fossil_print("\r%d", ++nFileRead);
       fflush(stdout);
     }
-    closedir(d);
+    _wclosedir(d);
   }else {
     fossil_panic("encountered error %d while trying to open \"%s\".",
                   errno, g.argv[3]);
   }
   fossil_mbcs_free(zMbcsPath);

Index: src/vfile.c
==================================================================
--- src/vfile.c
+++ src/vfile.c
@@ -25,10 +25,19 @@
 #include "dirent.h"
 #else
 #include <dirent.h>
 #endif
 
+#ifndef _WIN32
+#define _WDIR DIR
+#define _wdirent dirent
+#define _wopendir opendir
+#define _wreaddir readdir
+#define _wclosedir closedir
+#define wchar_t char
+#endif
+
 /*
 ** The input is guaranteed to be a 40-character well-formed UUID.
 ** Find its rid.
 */
 int fast_uuid_to_rid(const char *zUuid){
@@ -381,18 +390,18 @@
 ** Any files or directories that match the glob pattern pIgnore are 
 ** excluded from the scan.  Name matching occurs after the first
 ** nPrefix characters are elided from the filename.
 */
 void vfile_scan(Blob *pPath, int nPrefix, int allFlag, Glob *pIgnore){
-  DIR *d;
+  _WDIR *d;
   int origSize;
   const char *zDir;
-  struct dirent *pEntry;
+  struct _wdirent *pEntry;
   int skipAll = 0;
   static Stmt ins;
   static int depth = 0;
-  char *zMbcs;
+  wchar_t *zMbcs;
 
   origSize = blob_size(pPath);
   if( pIgnore ){
     blob_appendf(pPath, "/");
     if( glob_match(pIgnore, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1;
@@ -407,22 +416,22 @@
     );
   }
   depth++;
 
   zDir = blob_str(pPath);
-  zMbcs = fossil_utf8_to_mbcs(zDir);
-  d = opendir(zMbcs);
+  zMbcs = fossil_utf8_to_unicode(zDir);
+  d = _wopendir(zMbcs);
   if( d ){
-    while( (pEntry=readdir(d))!=0 ){
+    while( (pEntry=_wreaddir(d))!=0 ){
       char *zPath;
       char *zUtf8;
       if( pEntry->d_name[0]=='.' ){
         if( !allFlag ) continue;
         if( pEntry->d_name[1]==0 ) continue;
         if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
       }
-      zUtf8 = fossil_mbcs_to_utf8(pEntry->d_name);
+      zUtf8 = fossil_unicode_to_utf8(pEntry->d_name);
       blob_appendf(pPath, "/%s", zUtf8);
       fossil_mbcs_free(zUtf8);
       zPath = blob_str(pPath);
       if( glob_match(pIgnore, &zPath[nPrefix+1]) ){
         /* do nothing */
@@ -435,11 +444,11 @@
         db_step(&ins);
         db_reset(&ins);
       }
       blob_resize(pPath, origSize);
     }
-    closedir(d);
+    _wclosedir(d);
   }
   fossil_mbcs_free(zMbcs);
 
   depth--;
   if( depth==0 ){