From 0b9906c2fba3fa7d2aebc5e217da31cd129b2bfc Mon Sep 17 00:00:00 2001
From: Clinton Stimpson <clinton@elemtech.com>
Date: Wed, 4 Dec 2013 22:17:24 -0700
Subject: Windows: Use wide-character system APIs

Make CMake compile with -DUNICODE.  Make it possible for the 8 bit
encoding to eventually be UTF-8 instead ANSI.
---
 Source/CPack/WiX/cmCPackWIXGenerator.cxx  | 10 +++--
 Source/cmExportCommand.cxx                | 19 +++++---
 Source/cmFileTimeComparison.cxx           |  5 ++-
 Source/cmFindPackageCommand.cxx           | 29 +++++++------
 Source/cmGlobalVisualStudio7Generator.cxx |  9 ++--
 Source/cmGlobalVisualStudioGenerator.cxx  | 72 +++++++++++++++++--------------
 Source/cmLocalVisualStudio7Generator.cxx  |  2 +-
 Source/cmSystemTools.cxx                  | 32 +++++++++-----
 Source/cmcldeps.cxx                       |  7 +--
 9 files changed, 107 insertions(+), 78 deletions(-)

diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 91701c2..1b9b20a 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -23,6 +23,7 @@
 
 #include <cmsys/SystemTools.hxx>
 #include <cmsys/Directory.hxx>
+#include <cmsys/Encoding.hxx>
 
 #include <rpc.h> // for GUID generation
 
@@ -954,11 +955,12 @@ std::string cmCPackWIXGenerator::GenerateGUID()
   UUID guid;
   UuidCreate(&guid);
 
-  unsigned char *tmp = 0;
-  UuidToString(&guid, &tmp);
+  unsigned short *tmp = 0;
+  UuidToStringW(&guid, &tmp);
 
-  std::string result(reinterpret_cast<char*>(tmp));
-  RpcStringFree(&tmp);
+  std::string result =
+    cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(tmp));
+  RpcStringFreeW(&tmp);
 
   return cmSystemTools::UpperCase(result);
 }
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 3f6bc2e..0a67ccf 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -16,6 +16,7 @@
 #include "cmake.h"
 
 #include <cmsys/RegularExpression.hxx>
+#include <cmsys/Encoding.hxx>
 
 #include "cmExportBuildFileGenerator.h"
 
@@ -252,14 +253,14 @@ void cmExportCommand::ReportRegistryError(std::string const& msg,
   cmOStringStream e;
   e << msg << "\n"
     << "  HKEY_CURRENT_USER\\" << key << "\n";
-  char winmsg[1024];
-  if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+  wchar_t winmsg[1024];
+  if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS, 0, err,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    winmsg, 1024, 0) > 0)
     {
     e << "Windows reported:\n"
-      << "  " << winmsg;
+      << "  " << cmsys::Encoding::ToNarrow(winmsg);
     }
   this->Makefile->IssueMessage(cmake::WARNING, e.str());
 }
@@ -272,8 +273,9 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package,
   std::string key = "Software\\Kitware\\CMake\\Packages\\";
   key += package;
   HKEY hKey;
-  LONG err = RegCreateKeyEx(HKEY_CURRENT_USER,
-                            key.c_str(), 0, 0, REG_OPTION_NON_VOLATILE,
+  LONG err = RegCreateKeyExW(HKEY_CURRENT_USER,
+                            cmsys::Encoding::ToWide(key).c_str(),
+                            0, 0, REG_OPTION_NON_VOLATILE,
                             KEY_SET_VALUE, 0, &hKey, 0);
   if(err != ERROR_SUCCESS)
     {
@@ -281,8 +283,11 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package,
       "Cannot create/open registry key", key, err);
     return;
     }
-  err = RegSetValueEx(hKey, hash, 0, REG_SZ, (BYTE const*)content,
-                      static_cast<DWORD>(strlen(content)+1));
+
+  std::wstring wcontent = cmsys::Encoding::ToWide(content);
+  err = RegSetValueExW(hKey, cmsys::Encoding::ToWide(hash).c_str(),
+                       0, REG_SZ, (BYTE const*)wcontent.c_str(),
+                       static_cast<DWORD>(wcontent.size()+1)*sizeof(wchar_t));
   RegCloseKey(hKey);
   if(err != ERROR_SUCCESS)
     {
diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx
index 3167be4..02f10c0 100644
--- a/Source/cmFileTimeComparison.cxx
+++ b/Source/cmFileTimeComparison.cxx
@@ -16,6 +16,8 @@
 # include <cmsys/hash_map.hxx>
 #endif
 
+#include <cmsys/Encoding.hxx>
+
 // Use a platform-specific API to get file times efficiently.
 #if !defined(_WIN32) || defined(__CYGWIN__)
 #  define cmFileTimeComparison_Type struct stat
@@ -86,7 +88,8 @@ bool cmFileTimeComparisonInternal::Stat(const char* fname,
   // Windows version.  Get the modification time from extended file
   // attributes.
   WIN32_FILE_ATTRIBUTE_DATA fdata;
-  if(!GetFileAttributesEx(fname, GetFileExInfoStandard, &fdata))
+  if(!GetFileAttributesExW(cmsys::Encoding::ToWide(fname).c_str(),
+                           GetFileExInfoStandard, &fdata))
     {
     return false;
     }
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 12f04d6..55c20d6 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -13,6 +13,7 @@
 
 #include <cmsys/Directory.hxx>
 #include <cmsys/RegularExpression.hxx>
+#include <cmsys/Encoding.hxx>
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
 #include "cmVariableWatch.h"
@@ -1245,23 +1246,23 @@ void cmFindPackageCommand::LoadPackageRegistryWinSystem()
 void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
                                                   unsigned int view)
 {
-  std::string key = "Software\\Kitware\\CMake\\Packages\\";
-  key += this->Name;
-  std::set<cmStdString> bad;
+  std::wstring key = L"Software\\Kitware\\CMake\\Packages\\";
+  key += cmsys::Encoding::ToWide(this->Name);
+  std::set<std::wstring> bad;
   HKEY hKey;
-  if(RegOpenKeyEx(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(),
-                  0, KEY_QUERY_VALUE|view, &hKey) == ERROR_SUCCESS)
+  if(RegOpenKeyExW(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(),
+                   0, KEY_QUERY_VALUE|view, &hKey) == ERROR_SUCCESS)
     {
     DWORD valueType = REG_NONE;
-    char name[16384];
-    std::vector<char> data(512);
+    wchar_t name[16383]; // RegEnumValue docs limit name to 32767 _bytes_
+    std::vector<wchar_t> data(512);
     bool done = false;
     DWORD index = 0;
     while(!done)
       {
       DWORD nameSize = static_cast<DWORD>(sizeof(name));
-      DWORD dataSize = static_cast<DWORD>(data.size()-1);
-      switch(RegEnumValue(hKey, index, name, &nameSize,
+      DWORD dataSize = static_cast<DWORD>(data.size()*sizeof(data[0]));
+      switch(RegEnumValueW(hKey, index, name, &nameSize,
                           0, &valueType, (BYTE*)&data[0], &dataSize))
         {
         case ERROR_SUCCESS:
@@ -1269,7 +1270,7 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
           if(valueType == REG_SZ)
             {
             data[dataSize] = 0;
-            cmsys_ios::stringstream ss(&data[0]);
+            cmsys_ios::stringstream ss(cmsys::Encoding::ToNarrow(&data[0]));
             if(!this->CheckPackageRegistryEntry(ss))
               {
               // The entry is invalid.
@@ -1278,7 +1279,7 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
             }
           break;
         case ERROR_MORE_DATA:
-          data.resize(dataSize+1);
+          data.resize((dataSize+sizeof(data[0])-1)/sizeof(data[0]));
           break;
         case ERROR_NO_MORE_ITEMS: default: done = true; break;
         }
@@ -1288,13 +1289,13 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
 
   // Remove bad values if possible.
   if(user && !bad.empty() &&
-     RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
+     RegOpenKeyExW(HKEY_CURRENT_USER, key.c_str(),
                   0, KEY_SET_VALUE|view, &hKey) == ERROR_SUCCESS)
     {
-    for(std::set<cmStdString>::const_iterator vi = bad.begin();
+    for(std::set<std::wstring>::const_iterator vi = bad.begin();
         vi != bad.end(); ++vi)
       {
-      RegDeleteValue(hKey, vi->c_str());
+      RegDeleteValueW(hKey, vi->c_str());
       }
     RegCloseKey(hKey);
     }
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 25fe10b..a217d8c 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -16,6 +16,7 @@
 #include "cmLocalVisualStudio7Generator.h"
 #include "cmMakefile.h"
 #include "cmake.h"
+#include <cmsys/Encoding.hxx>
 
 cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
   const char* platformName)
@@ -897,11 +898,11 @@ void cmGlobalVisualStudio7Generator::CreateGUID(const char* name)
     }
   std::string ret;
   UUID uid;
-  unsigned char *uidstr;
+  unsigned short *uidstr;
   UuidCreate(&uid);
-  UuidToString(&uid,&uidstr);
-  ret = reinterpret_cast<char*>(uidstr);
-  RpcStringFree(&uidstr);
+  UuidToStringW(&uid,&uidstr);
+  ret = cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(uidstr));
+  RpcStringFreeW(&uidstr);
   ret = cmSystemTools::UpperCase(ret);
   this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
                                      ret.c_str(), "Stored GUID",
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 7afcfa7..6c782e4 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -17,6 +17,7 @@
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmTarget.h"
+#include <cmsys/Encoding.hxx>
 
 //----------------------------------------------------------------------------
 cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator()
@@ -559,52 +560,53 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
 
   keyname = regKeyBase + "\\OtherProjects7";
   hkey = NULL;
-  result = RegOpenKeyEx(HKEY_CURRENT_USER, keyname.c_str(),
-                        0, KEY_READ, &hkey);
+  result = RegOpenKeyExW(HKEY_CURRENT_USER,
+                         cmsys::Encoding::ToWide(keyname).c_str(),
+                         0, KEY_READ, &hkey);
   if (ERROR_SUCCESS == result)
     {
     // Iterate the subkeys and look for the values of interest in each subkey:
-    CHAR subkeyname[256];
-    DWORD cch_subkeyname = sizeof(subkeyname)/sizeof(subkeyname[0]);
-    CHAR keyclass[256];
-    DWORD cch_keyclass = sizeof(keyclass)/sizeof(keyclass[0]);
+    wchar_t subkeyname[256];
+    DWORD cch_subkeyname = sizeof(subkeyname)*sizeof(subkeyname[0]);
+    wchar_t keyclass[256];
+    DWORD cch_keyclass = sizeof(keyclass)*sizeof(keyclass[0]);
     FILETIME lastWriteTime;
     lastWriteTime.dwHighDateTime = 0;
     lastWriteTime.dwLowDateTime = 0;
 
-    while (ERROR_SUCCESS == RegEnumKeyEx(hkey, index, subkeyname,
+    while (ERROR_SUCCESS == RegEnumKeyExW(hkey, index, subkeyname,
                                          &cch_subkeyname,
       0, keyclass, &cch_keyclass, &lastWriteTime))
       {
       // Open the subkey and query the values of interest:
       HKEY hsubkey = NULL;
-      result = RegOpenKeyEx(hkey, subkeyname, 0, KEY_READ, &hsubkey);
+      result = RegOpenKeyExW(hkey, subkeyname, 0, KEY_READ, &hsubkey);
       if (ERROR_SUCCESS == result)
         {
         DWORD valueType = REG_SZ;
-        CHAR data1[256];
-        DWORD cch_data1 = sizeof(data1)/sizeof(data1[0]);
-        RegQueryValueEx(hsubkey, "Path", 0, &valueType,
+        wchar_t data1[256];
+        DWORD cch_data1 = sizeof(data1)*sizeof(data1[0]);
+        RegQueryValueExW(hsubkey, L"Path", 0, &valueType,
                         (LPBYTE) &data1[0], &cch_data1);
 
         DWORD data2 = 0;
         DWORD cch_data2 = sizeof(data2);
-        RegQueryValueEx(hsubkey, "Security", 0, &valueType,
+        RegQueryValueExW(hsubkey, L"Security", 0, &valueType,
                         (LPBYTE) &data2, &cch_data2);
 
         DWORD data3 = 0;
         DWORD cch_data3 = sizeof(data3);
-        RegQueryValueEx(hsubkey, "StorageFormat", 0, &valueType,
+        RegQueryValueExW(hsubkey, L"StorageFormat", 0, &valueType,
                         (LPBYTE) &data3, &cch_data3);
 
-        s2 = cmSystemTools::LowerCase(data1);
+        s2 = cmSystemTools::LowerCase(cmsys::Encoding::ToNarrow(data1));
         cmSystemTools::ConvertToUnixSlashes(s2);
         if (s2 == s1)
           {
           macrosRegistered = true;
           }
 
-        std::string fullname(data1);
+        std::string fullname = cmsys::Encoding::ToNarrow(data1);
         std::string filename;
         std::string filepath;
         std::string filepathname;
@@ -636,8 +638,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
         }
 
       ++index;
-      cch_subkeyname = sizeof(subkeyname)/sizeof(subkeyname[0]);
-      cch_keyclass = sizeof(keyclass)/sizeof(keyclass[0]);
+      cch_subkeyname = sizeof(subkeyname)*sizeof(subkeyname[0]);
+      cch_keyclass = sizeof(keyclass)*sizeof(keyclass[0]);
       lastWriteTime.dwHighDateTime = 0;
       lastWriteTime.dwLowDateTime = 0;
       }
@@ -662,27 +664,28 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
 
   keyname = regKeyBase + "\\RecordingProject7";
   hkey = NULL;
-  result = RegOpenKeyEx(HKEY_CURRENT_USER, keyname.c_str(),
-                        0, KEY_READ, &hkey);
+  result = RegOpenKeyExW(HKEY_CURRENT_USER,
+                         cmsys::Encoding::ToWide(keyname).c_str(),
+                         0, KEY_READ, &hkey);
   if (ERROR_SUCCESS == result)
     {
     DWORD valueType = REG_SZ;
-    CHAR data1[256];
-    DWORD cch_data1 = sizeof(data1)/sizeof(data1[0]);
-    RegQueryValueEx(hkey, "Path", 0, &valueType,
+    wchar_t data1[256];
+    DWORD cch_data1 = sizeof(data1)*sizeof(data1[0]);
+    RegQueryValueExW(hkey, L"Path", 0, &valueType,
                     (LPBYTE) &data1[0], &cch_data1);
 
     DWORD data2 = 0;
     DWORD cch_data2 = sizeof(data2);
-    RegQueryValueEx(hkey, "Security", 0, &valueType,
+    RegQueryValueExW(hkey, L"Security", 0, &valueType,
                     (LPBYTE) &data2, &cch_data2);
 
     DWORD data3 = 0;
     DWORD cch_data3 = sizeof(data3);
-    RegQueryValueEx(hkey, "StorageFormat", 0, &valueType,
+    RegQueryValueExW(hkey, L"StorageFormat", 0, &valueType,
                     (LPBYTE) &data3, &cch_data3);
 
-    s2 = cmSystemTools::LowerCase(data1);
+    s2 = cmSystemTools::LowerCase(cmsys::Encoding::ToNarrow(data1));
     cmSystemTools::ConvertToUnixSlashes(s2);
     if (s2 == s1)
       {
@@ -714,24 +717,27 @@ void WriteVSMacrosFileRegistryEntry(
 {
   std::string keyname = regKeyBase + "\\OtherProjects7";
   HKEY hkey = NULL;
-  LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, keyname.c_str(), 0,
+  LONG result = RegOpenKeyExW(HKEY_CURRENT_USER,
+    cmsys::Encoding::ToWide(keyname).c_str(), 0,
     KEY_READ|KEY_WRITE, &hkey);
   if (ERROR_SUCCESS == result)
     {
     // Create the subkey and set the values of interest:
     HKEY hsubkey = NULL;
-    char lpClass[] = "";
-    result = RegCreateKeyEx(hkey, nextAvailableSubKeyName.c_str(), 0,
-                            lpClass, 0, KEY_READ|KEY_WRITE, 0, &hsubkey, 0);
+    wchar_t lpClass[] = L"";
+    result = RegCreateKeyExW(hkey,
+      cmsys::Encoding::ToWide(nextAvailableSubKeyName).c_str(), 0,
+      lpClass, 0, KEY_READ|KEY_WRITE, 0, &hsubkey, 0);
     if (ERROR_SUCCESS == result)
       {
       DWORD dw = 0;
 
       std::string s(macrosFile);
       cmSystemTools::ReplaceString(s, "/", "\\");
+      std::wstring ws = cmsys::Encoding::ToWide(s);
 
-      result = RegSetValueEx(hsubkey, "Path", 0, REG_SZ, (LPBYTE) s.c_str(),
-        static_cast<DWORD>(strlen(s.c_str()) + 1));
+      result = RegSetValueExW(hsubkey, L"Path", 0, REG_SZ, (LPBYTE)ws.c_str(),
+        static_cast<DWORD>(ws.size() + 1)*sizeof(wchar_t));
       if (ERROR_SUCCESS != result)
         {
         std::cout << "error result 1: " << result << std::endl;
@@ -741,7 +747,7 @@ void WriteVSMacrosFileRegistryEntry(
       // Security value is always "1" for sample macros files (seems to be "2"
       // if you put the file somewhere outside the standard VSMacros folder)
       dw = 1;
-      result = RegSetValueEx(hsubkey, "Security",
+      result = RegSetValueExW(hsubkey, L"Security",
                              0, REG_DWORD, (LPBYTE) &dw, sizeof(DWORD));
       if (ERROR_SUCCESS != result)
         {
@@ -751,7 +757,7 @@ void WriteVSMacrosFileRegistryEntry(
 
       // StorageFormat value is always "0" for sample macros files
       dw = 0;
-      result = RegSetValueEx(hsubkey, "StorageFormat",
+      result = RegSetValueExW(hsubkey, L"StorageFormat",
                              0, REG_DWORD, (LPBYTE) &dw, sizeof(DWORD));
       if (ERROR_SUCCESS != result)
         {
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 2fd1016..14832e5 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -2224,7 +2224,7 @@ static bool cmLVS6G_IsFAT(const char* dir)
     char volRoot[4] = "_:/";
     volRoot[0] = dir[0];
     char fsName[16];
-    if(GetVolumeInformation(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
+    if(GetVolumeInformationA(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
        strstr(fsName, "FAT") != 0)
       {
       return true;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index b3dbd05..b8163c8 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -25,6 +25,7 @@
 #include <cmsys/RegularExpression.hxx>
 #include <cmsys/Directory.hxx>
 #include <cmsys/System.h>
+#include <cmsys/Encoding.hxx>
 #if defined(CMAKE_BUILD_WITH_CMAKE)
 # include "cmArchiveWrite.h"
 # include <cm_libarchive.h>
@@ -880,19 +881,23 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
      Try multiple times since we may be racing against another process
      creating/opening the destination file just before our MoveFileEx.  */
   int tries = 5;
-  while(!MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) && --tries)
+  while(!MoveFileExW(cmsys::Encoding::ToWide(oldname).c_str(),
+                     cmsys::Encoding::ToWide(newname).c_str(),
+                     MOVEFILE_REPLACE_EXISTING) && --tries)
     {
     // Try again only if failure was due to access permissions.
     if(GetLastError() != ERROR_ACCESS_DENIED)
       {
       return false;
       }
-    DWORD attrs = GetFileAttributes(newname);
+    DWORD attrs =
+      GetFileAttributesW(cmsys::Encoding::ToWide(newname).c_str());
     if((attrs != INVALID_FILE_ATTRIBUTES) &&
        (attrs & FILE_ATTRIBUTE_READONLY))
       {
       // Remove the read-only attribute from the destination file.
-      SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
+      SetFileAttributesW(cmsys::Encoding::ToWide(newname).c_str(),
+                         attrs & ~FILE_ATTRIBUTE_READONLY);
       }
     else
       {
@@ -1884,10 +1889,12 @@ bool cmSystemTools::CopyFileTime(const char* fromFile, const char* toFile)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   cmSystemToolsWindowsHandle hFrom =
-    CreateFile(fromFile, GENERIC_READ, FILE_SHARE_READ, 0,
-               OPEN_EXISTING, 0, 0);
+    CreateFileW(cmsys::Encoding::ToWide(fromFile).c_str(),
+                GENERIC_READ, FILE_SHARE_READ, 0,
+                OPEN_EXISTING, 0, 0);
   cmSystemToolsWindowsHandle hTo =
-    CreateFile(toFile, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+    CreateFileW(cmsys::Encoding::ToWide(toFile).c_str(),
+                GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
   if(!hFrom || !hTo)
     {
     return false;
@@ -1938,7 +1945,8 @@ bool cmSystemTools::FileTimeGet(const char* fname, cmSystemToolsFileTime* t)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   cmSystemToolsWindowsHandle h =
-    CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+    CreateFileW(cmsys::Encoding::ToWide(fname).c_str(),
+                GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
   if(!h)
     {
     return false;
@@ -1964,7 +1972,8 @@ bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   cmSystemToolsWindowsHandle h =
-    CreateFile(fname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+    CreateFileW(cmsys::Encoding::ToWide(fname).c_str(),
+                GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
   if(!h)
     {
     return false;
@@ -2059,9 +2068,10 @@ void cmSystemTools::FindCMakeResources(const char* argv0)
   std::string exe_dir;
 #if defined(_WIN32) && !defined(__CYGWIN__)
   (void)argv0; // ignore this on windows
-  char modulepath[_MAX_PATH];
-  ::GetModuleFileName(NULL, modulepath, sizeof(modulepath));
-  exe_dir = cmSystemTools::GetFilenamePath(modulepath);
+  wchar_t modulepath[_MAX_PATH];
+  ::GetModuleFileNameW(NULL, modulepath, sizeof(modulepath));
+  exe_dir =
+    cmSystemTools::GetFilenamePath(cmsys::Encoding::ToNarrow(modulepath));
 #elif defined(__APPLE__)
   (void)argv0; // ignore this on OS X
 # define CM_EXE_PATH_LOCAL_SIZE 16384
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index 8571557..0675470 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -23,6 +23,7 @@
 #include <windows.h>
 #include <sstream>
 #include <cmSystemTools.h>
+#include <cmsys/Encoding.hxx>
 
 // We don't want any wildcard expansion.
 // See http://msdn.microsoft.com/en-us/library/zay8tzh6(v=vs.85).aspx
@@ -100,7 +101,7 @@ static std::string getArg(std::string& cmdline) {
   return ret;
 }
 
-static void parseCommandLine(LPTSTR wincmdline,
+static void parseCommandLine(LPWSTR wincmdline,
                              std::string& lang,
                              std::string& srcfile,
                              std::string& dfile,
@@ -109,7 +110,7 @@ static void parseCommandLine(LPTSTR wincmdline,
                              std::string& clpath,
                              std::string& binpath,
                              std::string& rest) {
-  std::string cmdline(wincmdline);
+  std::string cmdline = cmsys::Encoding::ToNarrow(wincmdline);
   /* self */ getArg(cmdline);
   lang = getArg(cmdline);
   srcfile = getArg(cmdline);
@@ -247,7 +248,7 @@ int main() {
   // the same command line verbatim.
 
   std::string lang, srcfile, dfile, objfile, prefix, cl, binpath, rest;
-  parseCommandLine(GetCommandLine(), lang, srcfile, dfile, objfile,
+  parseCommandLine(GetCommandLineW(), lang, srcfile, dfile, objfile,
                                      prefix, cl, binpath, rest);
 
   // needed to suppress filename output of msvc tools
-- 
cgit v0.12