Commits

Anonymous committed cdce65b

Make shellext Unicode compatible.

Comments (0)

Files changed (38)

win32/shellext/CShellExtCMenu.cpp

 #include "RegistryConfig.h"
 #include "TortoiseIconBitmap.h"
 #include "ThgVersion.h"
+//#include "UtfConverter.h"
 
 #include "Msi.h"
 
 
 struct MenuDescription
 {
-    std::string name;
+    std::wstring name;
     std::wstring menuText;
     std::wstring helpText;
-    std::string iconName;
+    std::wstring iconName;
     UINT idCmd;
 };
 
 
 MenuDescription menuDescList[] =
 {
-    {"commit",      L"Commit...",
+    {L"commit",      L"Commit...",
                     L"Commit changes in repository",
-                    "menucommit.ico", 0},
-    {"init",        L"Create Repository Here",
+                    L"menucommit.ico", 0},
+    {L"init",        L"Create Repository Here",
                     L"Create a new repository",
-                    "menucreaterepos.ico", 0},
-    {"clone",       L"Clone...",
+                    L"menucreaterepos.ico", 0},
+    {L"clone",       L"Clone...",
                     L"Create clone here from source",
-                    "menuclone.ico", 0},
-    {"status",      L"View File Status",
+                    L"menuclone.ico", 0},
+    {L"status",      L"View File Status",
                     L"Repository status & changes",
-                    "menushowchanged.ico", 0},
-    {"shelve",      L"Shelve Changes",
+                    L"menushowchanged.ico", 0},
+    {L"shelve",      L"Shelve Changes",
                     L"Shelve or unshelve file changes",
-                    "shelve.ico", 0},
-    {"add",         L"Add Files...",
+                    L"shelve.ico", 0},
+    {L"add",         L"Add Files...",
                     L"Add files to version control",
-                    "menuadd.ico", 0},
-    {"revert",      L"Revert Files...",
+                    L"menuadd.ico", 0},
+    {L"revert",      L"Revert Files...",
                     L"Revert file changes",
-                    "menurevert.ico", 0},
-    {"remove",      L"Remove Files...",
+                    L"menurevert.ico", 0},
+    {L"remove",      L"Remove Files...",
                     L"Remove files from version control",
-                    "menudelete.ico", 0},
-    {"rename",      L"Rename File...",
+                    L"menudelete.ico", 0},
+    {L"rename",      L"Rename File...",
                     L"Rename file or directory",
-                    "general.ico", 0},
-    {"log",         L"Repository Explorer",
+                    L"general.ico", 0},
+    {L"log",         L"Repository Explorer",
                     L"View change history in repository",
-                    "menulog.ico", 0},
-    {"synch",       L"Synchronize",
+                    L"menulog.ico", 0},
+    {L"synch",       L"Synchronize",
                     L"Synchronize with remote repository",
-                    "menusynch.ico", 0},
-    {"serve",       L"Web Server",
+                    L"menusynch.ico", 0},
+    {L"serve",       L"Web Server",
                     L"Start web server for this repository",
-                    "proxy.ico", 0},
-    {"update",      L"Update...",
+                    L"proxy.ico", 0},
+    {L"update",      L"Update...",
                     L"Update working directory",
-                    "menucheckout.ico", 0},
-    {"recover",     L"Recovery...",
+                    L"menucheckout.ico", 0},
+    {L"recover",     L"Recovery...",
                     L"Repair and recovery of repository",
-                    "general.ico", 0},
-    {"thgstatus",   L"Update Icons",
+                    L"general.ico", 0},
+    {L"thgstatus",   L"Update Icons",
                     L"Update icons for this repository",
-                    "refresh_overlays.ico", 0},
-    {"userconf",    L"Global Settings",
+                    L"refresh_overlays.ico", 0},
+    {L"userconf",    L"Global Settings",
                     L"Configure user wide settings",
-                    "settings_user.ico", 0},
-    {"repoconf",    L"Repository Settings",
+                    L"settings_user.ico", 0},
+    {L"repoconf",    L"Repository Settings",
                     L"Configure repository settings",
-                    "settings_repo.ico", 0},
-    {"about",       L"About TortoiseHg",
+                    L"settings_repo.ico", 0},
+    {L"about",       L"About TortoiseHg",
                     L"Show About Dialog",
-                    "menuabout.ico", 0},
-    {"datamine",    L"Annotate Files",
+                    L"menuabout.ico", 0},
+    {L"datamine",    L"Annotate Files",
                     L"Changeset information per file line",
-                    "menublame.ico", 0},
-    {"vdiff",       L"Visual Diff",
+                    L"menublame.ico", 0},
+    {L"vdiff",       L"Visual Diff",
                     L"View changes using GUI diff tool",
-                    "TortoiseMerge.ico", 0},
-    {"hgignore",    L"Edit Ignore Filter",
+                    L"TortoiseMerge.ico", 0},
+    {L"hgignore",    L"Edit Ignore Filter",
                     L"Edit repository ignore filter",
-                    "ignore.ico", 0},
-    {"guess",       L"Guess Renames",
+                    L"ignore.ico", 0},
+    {L"guess",       L"Guess Renames",
                     L"Detect renames and copies",
-                    "detect_rename.ico", 0},
-    {"grep",        L"Search History",
+                    L"detect_rename.ico", 0},
+    {L"grep",        L"Search History",
                     L"Search file revisions for patterns",
-                    "menurepobrowse.ico", 0},
-    {"forget",      L"Forget Files...",
+                    L"menurepobrowse.ico", 0},
+    {L"forget",      L"Forget Files...",
                     L"Remove files from version control",
-                    "menudelete.ico", 0},
-    {"shellconf",   L"Explorer Extension Settings",
+                    L"menudelete.ico", 0},
+    {L"shellconf",   L"Explorer Extension Settings",
                     L"Configure Explorer extension",
-                    "settings_repo.ico", 0},
+                    L"settings_repo.ico", 0},
 
     /* Add new items here */
 
     // template
-    //{"", L"", L"", ".ico", 0},
+    //{L"", L"", L"", ".ico", 0},
 };
 
-const char* const RepoNoFilesMenu =
-    "commit status shelve vdiff sep"
-    " add revert rename forget remove sep"
-    " log update grep sep"
-    " synch serve clone init thgstatus sep"
-    " hgignore guess recover sep"
-    " shellconf repoconf userconf sep"
-    " about"
+const wchar_t* const RepoNoFilesMenu =
+    L"commit status shelve vdiff sep"
+    L" add revert rename forget remove sep"
+    L" log update grep sep"
+    L" synch serve clone init thgstatus sep"
+    L" hgignore guess recover sep"
+    L" shellconf repoconf userconf sep"
+    L" about"
 ;
 
-const char* const RepoFilesMenu =
-    "commit status vdiff sep"
-    " add revert rename forget remove sep"
-    " log datamine sep"
-    " about"
+const wchar_t* const RepoFilesMenu =
+    L"commit status vdiff sep"
+    L" add revert rename forget remove sep"
+    L" log datamine sep"
+    L" about"
 ;
 
-const char* const NoRepoMenu =
-    "clone init shellconf userconf thgstatus sep"
-    " about"
+const wchar_t* const NoRepoMenu =
+    L"clone init shellconf userconf thgstatus sep"
+    L" about"
 ;
 
 
-typedef std::map<std::string, MenuDescription> MenuDescriptionMap;
+typedef std::map<std::wstring, MenuDescription> MenuDescriptionMap;
 typedef std::map<UINT, MenuDescription> MenuIdCmdMap;
 
 MenuDescriptionMap MenuDescMap;
 MenuIdCmdMap MenuIdMap;
 
 
-void AddMenuList(UINT idCmd, const std::string& name)
+void AddMenuList(UINT idCmd, const std::wstring& name)
 {
-    TDEBUG_TRACE("AddMenuList: idCmd = " << idCmd << " name = " << name);
+    TDEBUG_TRACEW(L"AddMenuList: idCmd = " << idCmd << L" name = " << name);
     MenuIdMap[idCmd] = MenuDescMap[name];
 }
 
 
 void GetCMenuTranslation(
-    const std::string& lang,
-    const std::string& name,
+    const std::wstring& lang,
+    const std::wstring& name,
     std::wstring& menuText,
     std::wstring& helpText
 )
 {
     std::wstring subkey = L"Software\\TortoiseHg\\CMenu\\";
-    subkey += _WCSTR(lang.c_str());
+    subkey += lang;
     subkey += L"\\";
-    subkey += _WCSTR(name.c_str());
+    subkey += name;
 
     TDEBUG_TRACEW(L"GetCMenuTranslation: " << subkey);
 
 {
     if (MenuDescMap.empty())
     {
-        std::string lang;
-        GetRegistryConfig("CMenuLang", lang);
+        std::wstring lang;
+        GetRegistryConfig(L"CMenuLang", lang);
 
         std::size_t sz = sizeof(menuDescList) / sizeof(MenuDescription);
         for (std::size_t i = 0; i < sz; i++)
 
             if (md.name.size() == 0)
             {
-                TDEBUG_TRACE("**** InitMenuMaps: ignoring entry with empty name");
+                TDEBUG_TRACEW(L"**** InitMenuMaps: ignoring entry with empty name");
                 break;
             }
 
-            TDEBUG_TRACE("InitMenuMaps: adding " << md.name);
+            TDEBUG_TRACEW(L"InitMenuMaps: adding " << md.name);
 
             // Look for translation of menu and help text
             if (lang.size())
 
 void InsertMenuItemWithIcon1(
     HMENU hMenu, UINT indexMenu, UINT idCmd,
-    const std::wstring& menuText, const std::string& iconName)
+    const std::wstring& menuText, const std::wstring& iconName)
 {
     MENUITEMINFOW mi;
     memset(&mi, 0, sizeof(mi));
         }
         else
         {
-            TDEBUG_TRACE("    ***** InsertMenuItemWithIcon1: can't find " + iconName);
+            TDEBUG_TRACEW(L"    ***** InsertMenuItemWithIcon1: can't find " + iconName);
             mi.fMask = MIIM_TYPE | MIIM_ID;
         }
     }
         }
         else
         {
-            TDEBUG_TRACE("    ***** InsertMenuItemWithIcon1: can't find " + iconName);
+            TDEBUG_TRACEW(L"    ***** InsertMenuItemWithIcon1: can't find " + iconName);
             mi.fMask = MIIM_TYPE | MIIM_ID;
         }
     }
 
 void InsertSubMenuItemWithIcon2(
     HMENU hMenu, HMENU hSubMenu, UINT indexMenu, UINT idCmd,
-    const std::wstring& menuText, const std::string& iconName)
+    const std::wstring& menuText, const std::wstring& iconName)
 {
     MENUITEMINFOW mi;
     memset(&mi, 0, sizeof(mi));
         }
         else
         {
-            TDEBUG_TRACE("    ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
+            TDEBUG_TRACEW(L"    ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
             mi.fMask = MIIM_TYPE | MIIM_ID;
         }
     }
         }
         else
         {
-            TDEBUG_TRACE("    ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
+            TDEBUG_TRACEW(L"    ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
             mi.fMask = MIIM_TYPE | MIIM_ID;
         }
     }
 
 
 void InsertMenuItemByName(
-    HMENU hMenu, const std::string& name, UINT indexMenu,
+    HMENU hMenu, const std::wstring& name, UINT indexMenu,
     UINT idCmd, UINT idCmdFirst, const std::wstring& prefix)
 {
     MenuDescriptionMap::iterator iter = MenuDescMap.find(name);
     if (iter == MenuDescMap.end())
     {
-        TDEBUG_TRACE("***** InsertMenuItemByName: can't find menu info for " << name);
+        TDEBUG_TRACEW(L"***** InsertMenuItemByName: can't find menu info for " << name);
         return;
     }
 
     const int count = ::GetMenuItemCount(hMenu);
     if (count == -1)
     {
-        TDEBUG_TRACE("***** HasTortoiseMenu: GetMenuItemCount returned -1");
+        TDEBUG_TRACEW(L"***** HasTortoiseMenu: GetMenuItemCount returned -1");
         return -1;
     }
 
         mii.fMask = MIIM_STRING;
         BOOL res = ::GetMenuItemInfoW(hMenu, i, true, &mii);
         if (res == 0) {
-            TDEBUG_TRACE("HasTortoiseMenu: "
+            TDEBUG_TRACEW(L"HasTortoiseMenu: "
                 << "first GetMenuItemInfo returned 0");
             continue;
         }
         ++mii.cch; // size of buffer is one more than length of string
         res = ::GetMenuItemInfoW(hMenu, i, true, &mii);
         if (res == 0) {
-            TDEBUG_TRACE("HasTortoiseMenu: "
+            TDEBUG_TRACEW(L"HasTortoiseMenu: "
                 << "second GetMenuItemInfo returned 0");
             continue;
         }
 
         if (menuitemtext == TortoiseHgMenuEntryString)
         {
-            TDEBUG_TRACE("HasTortoiseMenu: FOUND TortoiseHg menu entry");
+            TDEBUG_TRACEW(L"HasTortoiseMenu: FOUND TortoiseHg menu entry");
             hasmenu = true;
             return 0;
         }
     }
 
-    TDEBUG_TRACE("HasTortoiseMenu: TortoiseHg menu entry NOT found");
+    TDEBUG_TRACEW(L"HasTortoiseMenu: TortoiseHg menu entry NOT found");
     return 0;
 }
 
 CShellExtCMenu::QueryContextMenu(
     HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
 {
-    TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu");
+    TDEBUG_TRACEW(L"CShellExtCMenu::QueryContextMenu");
 
     UINT idCmd = idCmdFirst;
     BOOL bAppendItems = TRUE;
     bool hasthgmenu = false;
     if (HasTortoiseMenu(hMenu, hasthgmenu) == 0 && hasthgmenu)
     {
-        TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu: "
+        TDEBUG_TRACEW(L"CShellExtCMenu::QueryContextMenu: "
             << "TortoiseHg menu entry already in menu -> skipping");
         return S_OK;
     }
 
     InitMenuMaps();
 
-    typedef std::vector<std::string> entriesT;
+    typedef std::vector<std::wstring> entriesT;
     typedef entriesT::const_iterator entriesIter;
 
-    std::string promoted_string = "commit,log"; // default value if key not found
-    GetRegistryConfig("PromotedItems", promoted_string);
+    std::wstring promoted_string = L"commit,log"; // default value if key not found
+    GetRegistryConfig(L"PromotedItems", promoted_string);
 
     entriesT promoted;
-    Tokenize(promoted_string, promoted, ",");
+    Tokenize(promoted_string, promoted, L",");
 
     // Select menu to show
     bool fileMenu = myFiles.size() > 0;
     bool isHgrepo = false;
-    std::string cwd;
+    std::wstring cwd;
     if (!myFolder.empty())
     {
         cwd = myFolder;
     if (!cwd.empty())
     {
         // check if target directory is a Mercurial repository
-        std::string root = GetHgRepoRoot(cwd);
+        std::wstring root = GetHgRepoRoot(cwd);
         isHgrepo = !root.empty();
         if (myFiles.size() == 1 && root == myFiles[0])
         {
         }
     }
 
-    TDEBUG_TRACE(
-        "CShellExtCMenu::QueryContextMenu: isHgrepo = " 
-        << isHgrepo << ", fileMenu = " << fileMenu
+    TDEBUG_TRACEW(
+        L"CShellExtCMenu::QueryContextMenu: isHgrepo = " 
+        << isHgrepo << L", fileMenu = " << fileMenu
     );
 
     /* We have three menu types: files-selected, no-files-selected, no-repo */
-    const char* entries_string = 0;
+    const wchar_t* entries_string = 0;
     if (isHgrepo)
         if (fileMenu)
             entries_string = RepoFilesMenu;
     InsertMenu(hMenu, indexMenu++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
 
     entriesT entries;
-    Tokenize(entries_string, entries, " ");
+    Tokenize(entries_string, entries, L" ");
 
     for (entriesIter i = entries.begin(); i != entries.end(); i++)
     {
-        std::string name = *i;
+        std::wstring name = *i;
         if (contains(promoted, name))
         {
             InsertMenuItemByName(
         bool isSeparator = true;
         for (entriesIter i = entries.begin(); i != entries.end(); i++)
         {
-            std::string name = *i;
-            if (name == "sep")
+            std::wstring name = *i;
+            if (name == L"sep")
             {
                 if (!isSeparator)
                 {
         }
     }
 
-    TDEBUG_TRACE("  CShellExtCMenu::QueryContextMenu: adding main THG menu");
+    TDEBUG_TRACEW(L"  CShellExtCMenu::QueryContextMenu: adding main THG menu");
     InsertSubMenuItemWithIcon2(hMenu, hSubMenu, indexMenu++, idCmd++,
-            TortoiseHgMenuEntryString, "hg.ico");
+            TortoiseHgMenuEntryString, L"hg.ico");
 
     InsertMenu(hMenu, indexMenu++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
 
 STDMETHODIMP
 CShellExtCMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
 {
-    TDEBUG_TRACE("CShellExtCMenu::InvokeCommand");
+    TDEBUG_TRACEW(L"CShellExtCMenu::InvokeCommand");
 
     HRESULT hr = E_INVALIDARG;
     if (!HIWORD(lpcmi->lpVerb))
     {
         UINT idCmd = LOWORD(lpcmi->lpVerb);
-        TDEBUG_TRACE("CShellExtCMenu::InvokeCommand: idCmd = " << idCmd);
+        TDEBUG_TRACEW(L"CShellExtCMenu::InvokeCommand: idCmd = " << idCmd);
         MenuIdCmdMap::iterator iter = MenuIdMap.find(idCmd);
         if (iter != MenuIdMap.end())
         {
         }
         else
         {
-            TDEBUG_TRACE(
-                "***** CShellExtCMenu::InvokeCommand: action not found for idCmd "
+            TDEBUG_TRACEW(
+                L"***** CShellExtCMenu::InvokeCommand: action not found for idCmd "
                 << idCmd
             );
         }
     const char* psz = "";
     const wchar_t* pszw = 0;
 
-    std::string sflags = "?";
+    std::wstring sflags = L"?";
     switch (uFlags)
     {
     case GCS_HELPTEXTW:
-        sflags = "GCS_HELPTEXTW"; break;
+        sflags = L"GCS_HELPTEXTW"; break;
     case GCS_HELPTEXTA:
-        sflags = "GCS_HELPTEXTA"; break;
+        sflags = L"GCS_HELPTEXTA"; break;
     case GCS_VALIDATEW:
-        sflags = "GCS_VALIDATEW"; break;
+        sflags = L"GCS_VALIDATEW"; break;
     case GCS_VALIDATEA:
-        sflags = "GCS_VALIDATEA"; break;
+        sflags = L"GCS_VALIDATEA"; break;
     case GCS_VERBW:
-        sflags = "GCS_VERBW"; break;
+        sflags = L"GCS_VERBW"; break;
     case GCS_VERBA:
-        sflags = "GCS_VERBA"; break;
+        sflags = L"GCS_VERBA"; break;
     }
 
-    TDEBUG_TRACE(
-        "CShellExtCMenu::GetCommandString: idCmd = " << idCmd 
-        << ", uFlags = " << uFlags << " (" << sflags << ")"
-        << ", cchMax = " << cchMax
+    TDEBUG_TRACEW(
+        L"CShellExtCMenu::GetCommandString: idCmd = " << idCmd 
+        << L", uFlags = " << uFlags << L" (" << sflags << L")"
+        << L", cchMax = " << cchMax
     );
 
     MenuIdCmdMap::iterator iter = MenuIdMap.find(static_cast<UINT>(idCmd));
     if (iter == MenuIdMap.end())
     {
-        TDEBUG_TRACE("***** CShellExtCMenu::GetCommandString: idCmd not found");
+        TDEBUG_TRACEW(L"***** CShellExtCMenu::GetCommandString: idCmd not found");
     }
     else
     {
-        TDEBUG_TRACE(
-            "CShellExtCMenu::GetCommandString: name = \"" << iter->second.name << "\"");
+        TDEBUG_TRACEW(
+            L"CShellExtCMenu::GetCommandString: name = \"" << iter->second.name << L"\"");
 
         if (uFlags == GCS_HELPTEXTW)
         {
             size_t size = iter->second.helpText.size();
             if (size >= 40)
             {
-                TDEBUG_TRACE(
-                    "***** CShellExtCMenu::GetCommandString: warning:" 
-                    << " length of help text is " << size
-                    << ", which is not reasonably short (<40)");
+                TDEBUG_TRACEW(
+                    L"***** CShellExtCMenu::GetCommandString: warning:" 
+                    << L" length of help text is " << size
+                    << L", which is not reasonably short (<40)");
             }
         }
         else if (uFlags == GCS_HELPTEXTA)
 
     if (cchMax < 1)
     {
-        TDEBUG_TRACE("CShellExtCMenu::GetCommandString: cchMax = " 
+        TDEBUG_TRACEW(L"CShellExtCMenu::GetCommandString: cchMax = " 
             << cchMax << " (is <1)");
         return res;
     }
 
         size = strlen(psz);
 
-        TDEBUG_TRACE("CShellExtCMenu::GetCommandString: res = " << int(res)
+        TDEBUG_TRACEW(L"CShellExtCMenu::GetCommandString: res = " << int(res)
             << ", pszName = \"" << psz << "\"");
     }
 
     if (size > cchMax-1)
     {
-        TDEBUG_TRACE(
-            "***** CShellExtCMenu::GetCommandString: string was truncated: size = "
-                << size << ", cchMax = " << cchMax);
+        TDEBUG_TRACEW(
+            L"***** CShellExtCMenu::GetCommandString: string was truncated: size = "
+                << size << L", cchMax = " << cchMax);
     }
 
     return res;
 }
 
 
-void CShellExtCMenu::DoHgtk(const std::string &cmd)
+void CShellExtCMenu::DoHgtk(const std::wstring &cmd)
 {
-    std::string dir = GetTHgProgRoot();
+    std::wstring dir = GetTHgProgRoot();
     if (dir.empty())
     {
-        TDEBUG_TRACE("DoHgtk: THG root is empty");
+        TDEBUG_TRACEW(L"DoHgtk: THG root is empty");
         return;
     }
-    std::string hgcmd = dir + "\\hgtk.exe";
+    std::wstring hgcmd = dir + L"\\hgtk.exe";
 
-    WIN32_FIND_DATAA data;
-    HANDLE hfind = FindFirstFileA(hgcmd.c_str(), &data);
+    WIN32_FIND_DATA data;
+    HANDLE hfind = FindFirstFile(hgcmd.c_str(), &data);
     if (hfind == INVALID_HANDLE_VALUE)
-        hgcmd = dir + "\\hgtk.cmd";
+        hgcmd = dir + L"\\hgtk.cmd";
     else
         FindClose(hfind);
 
-    hgcmd = Quote(hgcmd) + " --nofork " + cmd;
+    hgcmd = Quote(hgcmd) + L" --nofork " + cmd;
 
-    std::string cwd;
+    std::wstring cwd;
     if (!myFolder.empty())
     {
         cwd = myFolder;
     }
     else
     {
-        TDEBUG_TRACE("***** DoHgtk: can't get cwd");
+        TDEBUG_TRACEW(L"***** DoHgtk: can't get cwd");
         return;
     }
 
 
     if (!myFiles.empty())
     {
-        const std::string tempfile = GetTemporaryFile();
+        const std::wstring tempfile = GetTemporaryFile();
         if (tempfile.empty())
         {
-            TDEBUG_TRACE("***** DoHgtk: error: GetTemporaryFile returned empty string");
+            TDEBUG_TRACEW(L"***** DoHgtk: error: GetTemporaryFile returned empty string");
             return;
         }
 
-        TDEBUG_TRACE("DoHgtk: temp file = " << tempfile);
-        HANDLE tempfileHandle = CreateFileA(
+        TDEBUG_TRACEW(L"DoHgtk: temp file = " << tempfile);
+        HANDLE tempfileHandle = CreateFile(
             tempfile.c_str(), GENERIC_WRITE,
             FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
         );
 
         if (tempfileHandle == INVALID_HANDLE_VALUE)
         {
-            TDEBUG_TRACE("***** DoHgtk: error: failed to create file " << tempfile);
+            TDEBUG_TRACEW(L"***** DoHgtk: error: failed to create file " << tempfile);
             return;
         }
 
-        typedef std::vector<std::string>::size_type ST;
+        typedef std::vector<std::wstring>::size_type ST;
         for (ST i = 0; i < myFiles.size(); i++)
         {
             DWORD dwWritten;
-            TDEBUG_TRACE("DoHgtk: temp file adding " << myFiles[i]);
-            WriteFile(
-                tempfileHandle, myFiles[i].c_str(),
-                static_cast<DWORD>(myFiles[i].size()), &dwWritten, 0
-            );
-            WriteFile(tempfileHandle, "\n", 1, &dwWritten, 0);
+			std::string utf8file = WideToMultibyte(myFiles[i], CP_UTF8);
+			TDEBUG_TRACEW(L"DoHgtk: temp file adding " << myFiles[i]);
+			WriteFile(
+				tempfileHandle, utf8file.c_str(),
+				static_cast<DWORD>(utf8file.size()), &dwWritten, 0
+				);
+			WriteFile(tempfileHandle, "\n", sizeof(char), &dwWritten, 0);
         }
         CloseHandle(tempfileHandle);
-        hgcmd += " --listfile " + Quote(tempfile);
+        hgcmd += L" --listfile " + Quote(tempfile);
+
+    {
+        HANDLE tempfileHandle = CreateFile(
+            L"d:\\hgk.txt", GENERIC_WRITE,
+            FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
+        );
+
+        if (tempfileHandle == INVALID_HANDLE_VALUE)
+        {
+            TDEBUG_TRACEW(L"***** DoHgtk: error: failed to create file " << tempfile);
+            return;
+        }
+
+        typedef std::vector<std::wstring>::size_type ST;
+        for (ST i = 0; i < myFiles.size(); i++)
+        {
+            DWORD dwWritten;
+			std::string utf8file = WideToMultibyte(myFiles[i], CP_UTF8);
+            TDEBUG_TRACEW(L"DoHgtk: temp file adding " << myFiles[i]);
+            WriteFile(
+                tempfileHandle, utf8file.c_str(),
+                static_cast<DWORD>(utf8file.size()), &dwWritten, 0
+            );
+            WriteFile(tempfileHandle, "\n", sizeof(char), &dwWritten, 0);
+        }
+        CloseHandle(tempfileHandle);
+    }
     }
 
-    if (cmd == "thgstatus")
+    if (cmd == L"thgstatus")
     {
         if (Thgstatus::remove(cwd) != 0)
         {
-            std::string p = dir + "\\TortoiseHgOverlayServer.exe";
+            std::wstring p = dir + L"\\TortoiseHgOverlayServer.exe";
             LaunchCommand(Quote(p), cwd);
         }
         InitStatus::check();
 {
     TCHAR name[MAX_PATH+1];
 
-    TDEBUG_TRACE("CShellExtCMenu::Initialize");
+    TDEBUG_TRACEW(L"CShellExtCMenu::Initialize");
 
     // get installed MSI product id (for debugging purposes for now)
 #ifdef _M_X64
-    const char* shellexid = "{59FD2A49-BA62-40CC-B155-D11DB11EE611}";
+    const wchar_t* shellexid = L"{59FD2A49-BA62-40CC-B155-D11DB11EE611}";
 #else
-    const char* shellexid = "{1126CF42-3994-428B-A746-464E1BC680F3}";
+    const wchar_t* shellexid = L"{1126CF42-3994-428B-A746-464E1BC680F3}";
 #endif
-    std::vector<char> product_id(50, 0);
-    UINT msires = ::MsiGetProductCodeA(shellexid, &product_id[0]);
-    TDEBUG_TRACE("MSI shellexid: " << shellexid);
-    TDEBUG_TRACE("MSI msires: " << msires);
-    TDEBUG_TRACE("MSI installed product id: " << &product_id[0]);
+    std::vector<wchar_t> product_id(50, 0);
+    UINT msires = ::MsiGetProductCode(shellexid, &product_id[0]);
+    TDEBUG_TRACEW(L"MSI shellexid: " << shellexid);
+    TDEBUG_TRACEW(L"MSI msires: " << msires);
+    TDEBUG_TRACEW(L"MSI installed product id: " << &product_id[0]);
 
     TDEBUG_TRACEW(
         L"---- TortoiseHg shell extension version " 
         << ThgVersion::get() << L"----"
     );
 
-    TDEBUG_TRACE("  pIDFolder: " << pIDFolder);
-    TDEBUG_TRACE("  pDataObj: " << pDataObj);
+    TDEBUG_TRACEW(L"  pIDFolder: " << pIDFolder);
+    TDEBUG_TRACEW(L"  pDataObj: " << pDataObj);
 
     myFolder.clear();
     myFiles.clear();
             if (hDrop)
             {
                 UINT uNumFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
-                TDEBUG_TRACE("  hDrop uNumFiles = " << uNumFiles);
+                TDEBUG_TRACEW(L"  hDrop uNumFiles = " << uNumFiles);
                 for (UINT i = 0; i < uNumFiles; ++i) {
                     if (DragQueryFile(hDrop, i, name, MAX_PATH) > 0)
                     {
-                        TDEBUG_TRACE("  DragQueryFile [" << i << "] = " << name);
+                        TDEBUG_TRACEW(L"  DragQueryFile [" << i << "] = " << name);
                         myFiles.push_back(name);
                     }   
                 }
             }
             else 
             {
-                TDEBUG_TRACE("  hDrop is NULL ");
+                TDEBUG_TRACEW(L"  hDrop is NULL ");
             }
 
             GlobalUnlock(stg.hGlobal);
         }
         else
         {
-            TDEBUG_TRACE("  pDataObj->GetData failed");
+            TDEBUG_TRACEW(L"  pDataObj->GetData failed");
         }
     }
 
     if (pIDFolder) 
     {
         SHGetPathFromIDList(pIDFolder, name);
-        TDEBUG_TRACE("  Folder " << name);
+        TDEBUG_TRACEW(L"  Folder " << name);
         myFolder = name;
     }
 

win32/shellext/CShellExtCMenu.h

 {
     ULONG m_cRef;
 
-    LPTSTR* m_ppszFileUserClickedOn; // [MAX_PATH]
-    std::vector<std::string> myFiles;
-    std::string myFolder;
+    LPWSTR* m_ppszFileUserClickedOn; // [MAX_PATH]
+    std::vector<std::wstring> myFiles;
+    std::wstring myFolder;
 
-    void DoHgtk(const std::string&);
+    void DoHgtk(const std::wstring&);
 
 public:
     explicit CShellExtCMenu(char dummy);

win32/shellext/CShellExtOverlay.cpp

 STDMETHODIMP CShellExtOverlay::GetOverlayInfo(
     LPWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags)
 {
-    TDEBUG_TRACE("CShellExtOverlay::GetOverlayInfo: myTortoiseClass = " << myTortoiseClass);
+    TDEBUG_TRACEW(L"CShellExtOverlay::GetOverlayInfo: myTortoiseClass = " << myTortoiseClass);
     // icons are determined by TortoiseOverlays shim
     *pIndex = 0;
     *pdwFlags = 0;
 {
     ThgCriticalSection cs(CShellExt::GetCriticalSection());
 
-    std::string cval;
-    if (GetRegistryConfig("EnableOverlays", cval) != 0 && cval == "0")
+    std::wstring cval;
+    if (GetRegistryConfig(L"EnableOverlays", cval) != 0 && cval == L"0")
         return S_FALSE;
 
     // This overlay handler processes all filenames in lowercase, so that a path
     std::wstring lowerpath(pwszPath);
     ::CharLowerW(const_cast<wchar_t*>(lowerpath.c_str()));
 
-    std::string path = WideToMultibyte(lowerpath.c_str());
+    std::wstring path = lowerpath; //WideToMultibyte(lowerpath.c_str());
 
-    if (GetRegistryConfig("LocalDisksOnly", cval) != 0 && cval != "0"
+    if (GetRegistryConfig(L"LocalDisksOnly", cval) != 0 && cval != L"0"
             && PathIsNetworkPath(path.c_str()))
         return S_FALSE;
 
-    char filterStatus = 0;
+    wchar_t filterStatus = 0;
     if (myTortoiseClass == 'A')
        filterStatus = 'A';
 

win32/shellext/Directory.cpp

 // You should have received a copy of the GNU General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+#include "stdafx.h"
+
 #include <time.h>
 
-#include "stdafx.h"
-
 #include "Directory.h"
 #include "Winstat.h"
 
 
 Directory::Directory(
-    Directory* p, const std::string& n, const std::string& basepath
+    Directory* p, const std::wstring& n, const std::wstring& basepath
 ):
     parent_(p), name_(n)
 {
     else if (basepath.empty())
         path_ = n;
     else
-        path_ = basepath + '/' + n;
+        path_ = basepath + L'/' + n;
 }
 
 
 }
 
 
-int splitbase(const std::string& n, std::string& base, std::string& rest)
+int splitbase(const std::wstring& n, std::wstring& base, std::wstring& rest)
 {
     if (n.empty())
         return 0;
 
     size_t x = n.find_first_of ('/');
-    if (x == std::string::npos)
+    if (x == std::wstring::npos)
     {
         base.clear();
         rest = n;
 }
 
 
-int Directory::add(const std::string& n_in, Direntry& e)
+int Directory::add(const std::wstring& n_in, Direntry& e)
 {
-    std::string base;
-    std::string rest;
+    std::wstring base;
+    std::wstring rest;
     
-    std::string n = n_in;
+    std::wstring n = n_in;
     Directory* cur = this;
     
     for (;;)
     {
 
         if (!splitbase(n, base, rest)) {
-            TDEBUG_TRACE("Directory(" << path() << ")::add(" << n_in 
+            TDEBUG_TRACEW(L"Directory(" << path() << ")::add(" << n_in 
                 << "): splitbase returned 0");
             return 0;
         }
 }
 
 
-const Direntry* Directory::get(const std::string& n_in) const
+const Direntry* Directory::get(const std::wstring& n_in) const
 {
-    std::string base;
-    std::string rest;
+    std::wstring base;
+    std::wstring rest;
 
-    std::string n = n_in;
+    std::wstring n = n_in;
     const Directory* cur = this;
 
     for (;;)
 
         if (!splitbase(n, base, rest))
         {
-            TDEBUG_TRACE("Directory(" << path() << ")::get(" 
+            TDEBUG_TRACEW(L"Directory(" << path() << ")::get(" 
                 << n_in << "): splitbase returned 0");
             return 0;
         }
 }
 
 
-Directory* Directory::getdir(const std::string& n_in)
+Directory* Directory::getdir(const std::wstring& n_in)
 {
-    std::string base;
-    std::string rest;
+    std::wstring base;
+    std::wstring rest;
 
-    std::string n = n_in;
+    std::wstring n = n_in;
     const Directory* cur = this;
 
     for (;;)
 
         if (!splitbase(n, base, rest))
         {
-            TDEBUG_TRACE("Directory(" << path() << ")::getdir("
+            TDEBUG_TRACEW(L"Directory(" << path() << ")::getdir("
                 << n_in << "): splitbase returned 0");
             return 0;
         }
 
         const bool leaf = base.empty();
-        const std::string& searchstr = (leaf ? n : base);
+        const std::wstring& searchstr = (leaf ? n : base);
 
         for (DirsT::const_iterator i = cur->subdirs_.begin();
                 i != cur->subdirs_.end(); ++i)
         const Directory* d = *i;
         if (!d)
         {
-            TDEBUG_TRACE("Directory(" << path() << ")::print: error: d is 0");
+            TDEBUG_TRACEW(L"Directory(" << path() << ")::print: error: d is 0");
             return;
         }
         d->print();
     }
 
-    std::string base = path();
+    std::wstring base = path();
 
     time_t t;
-    std::string s;
-    char* ctime_res = 0;
+    std::wstring s;
+    wchar_t* ctime_res = 0;
 
     for (FilesT::const_iterator i = files_.begin(); i != files_.end(); ++i)
     {
-        std::string p = (!base.empty() ? base + "/" + i->name : i->name);
+        std::wstring p = (!base.empty() ? base + L"/" + i->name : i->name);
         t = i->mtime;
-        ctime_res = ctime(&t);
+        ctime_res = _wctime(&t);
         if (ctime_res) {
             s = ctime_res;
             s.resize(s.size() - 1); // strip ending '\n'
         }
         else {
-            s = "unset";
+            s = L"unset";
         }
-        printf(
-            "%c %6o %10u %-24s %s\n", 
+        wprintf(
+            L"%c %6o %10u %-24s %s\n", 
             i->state, i->mode, i->size, s.c_str(), p.c_str()
         );
     }

win32/shellext/Directory.h

     typedef std::vector<Direntry> FilesT;
 
     Directory* const parent_;
-    const std::string name_;
-    std::string path_;
+    const std::wstring name_;
+    std::wstring path_;
 
     DirsT  subdirs_;
     FilesT files_;
 
 public:
-    Directory(Directory* p, const std::string& n, const std::string& basepath);
+    Directory(Directory* p, const std::wstring& n, const std::wstring& basepath);
     ~Directory();
 
-    const std::string& path() const { return path_; }
+    const std::wstring& path() const { return path_; }
 
-    int add(const std::string& relpath, Direntry& e);
+    int add(const std::wstring& relpath, Direntry& e);
 
-    const Direntry* get(const std::string& relpath) const;
-    Directory* getdir(const std::string& n);
+    const Direntry* get(const std::wstring& relpath) const;
+    Directory* getdir(const std::wstring& n);
 
     void print() const;
 };

win32/shellext/DirectoryStatus.cpp

 #include "TortoiseUtils.h"
 
 
-char DirectoryStatus::status(const std::string& relpath_) const
+wchar_t DirectoryStatus::status(const std::wstring& relpath_) const
 {
-    char res = 'C';
+    wchar_t res = L'C';
     bool added = false;
     bool modified = false;
 
-    const std::string relpath = relpath_ + '/';
+    const std::wstring relpath = relpath_ + L'/';
 
     for (V::const_iterator i = v_.begin(); i != v_.end(); ++i)
     {
 }
 
 
-int DirectoryStatus::read(const std::string& hgroot, const std::string& cwd)
+int DirectoryStatus::read(const std::wstring& hgroot, const std::wstring& cwd)
 {
     v_.clear();
     noicons_ = false;
 
-    std::string p = hgroot + "\\.hg\\thgstatus";
+    std::wstring p = hgroot + L"\\.hg\\thgstatus";
 
     FILE *f = fopenReadRenameAllowed(p.c_str());
     if (!f)
     {
-        TDEBUG_TRACE("DirectoryStatus::read: can't open '" << p << "'");
-        std::string p = (cwd.size() < hgroot.size() ? hgroot : cwd);
+        TDEBUG_TRACEW(L"DirectoryStatus::read: can't open '" << p << L"'");
+        std::wstring p = (cwd.size() < hgroot.size() ? hgroot : cwd);
         Thgstatus::update(p);
         return 0;
     }
     DirectoryStatus::E e;
 
     int res = 1;
-    const std::string noicons = "@@noicons";
+    const std::wstring noicons = L"@@noicons";
 
-    std::vector<char> vline(200);
+    std::vector<wchar_t> vline(200);
 
     for (;;)
     {
         vline.clear();
-        char t;
+        wchar_t t;
 
         for (;;)
         {
             if (fread(&t, sizeof(t), 1, f) != 1)
                 goto close;
-            if (t == '\n')
+            if (t == L'\n')
                 break;
             vline.push_back(t);
             if (vline.size() > 1000)
         }
         vline.push_back(0);
 
-        std::string line = &vline[0];
+        std::wstring line = &vline[0];
 
         if (line.substr(0, noicons.size()) == noicons)
         {
 
         e.status_ = line[0];
 
-        std::string path;
+        std::wstring path;
         if (line.size() > 1)
         {
             path = line.c_str() + 1;
-            ::CharLower(const_cast<char*>(path.c_str()));
+            ::CharLower(const_cast<wchar_t*>(path.c_str()));
         }
         path.push_back('/');
 
 close:
     fclose(f);
 
-    TDEBUG_TRACE("DirectoryStatus::read(" << hgroot << "): done. "
+    TDEBUG_TRACEW(L"DirectoryStatus::read(" << hgroot << "): done. "
         << v_.size() << " entries read. noicons_ = " << noicons_ );
 
     return res;
 
 struct CacheEntry
 {
-    std::string     hgroot_;
+    std::wstring     hgroot_;
     DirectoryStatus ds_;
     bool            readfailed_;
     unsigned        tickcount_;
 
 
 DirectoryStatus* DirectoryStatus::get(
-    const std::string& hgroot, const std::string& cwd)
+    const std::wstring& hgroot, const std::wstring& cwd)
 {
     static CacheEntry ce;
     

win32/shellext/DirectoryStatus.h

 {
     struct E
     {
-        std::string path_;
-        char status_;
+        std::wstring path_;
+        wchar_t status_;
 
         E(): status_(0) {}
     };
     DirectoryStatus(): noicons_(false) {}
 
     static DirectoryStatus* get(
-        const std::string& hgroot, const std::string& cwd);
-    char status(const std::string& relpath) const;
+        const std::wstring& hgroot, const std::wstring& cwd);
+    wchar_t status(const std::wstring& relpath) const;
     bool noicons() const { return noicons_; }
 
 private:
-    int read(const std::string& hgroot, const std::string& cwd);
+    int read(const std::wstring& hgroot, const std::wstring& cwd);
 };

win32/shellext/Direntry.cpp

     fread(&relpath[0], sizeof(char), length, f);
     relpath[length] = 0;
 
-    ::CharLowerBuff(&relpath[0], length);
+    ::CharLowerBuffA(&relpath[0], length);
 
     return 1;
 }

win32/shellext/Direntry.h

     unsigned size;
     unsigned mtime;
     
-    std::string name;
+    std::wstring name;
 
     int read(FILE* f, std::vector<char>& relpath);
     char status(const Winstat& stat) const;

win32/shellext/Dirstatecache.cpp

 
 
 Dirstate* Dirstatecache::get(
-    const std::string& hgroot, const std::string& cwd, bool& unset)
+    const std::wstring& hgroot, const std::wstring& cwd, bool& unset)
 {
     unset = false;
 
     }
 
     Winstat64 stat;
-    std::string path = hgroot + "\\.hg\\dirstate";
+    std::wstring path = hgroot + L"\\.hg\\dirstate";
 
     unsigned tc = GetTickCount();
     bool new_stat = false;
     {
         if (stat.lstat(path.c_str()) != 0)
         {
-            TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") failed");
+            TDEBUG_TRACEW(L"Dirstatecache::get: lstat(" << path <<") failed");
             return 0;
         }
-        TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") ok ");
+        TDEBUG_TRACEW(L"Dirstatecache::get: lstat(" << path <<") ok ");
         new_stat = true;
 
         if (cache().size() >= 10)
         {
-            TDEBUG_TRACE("Dirstatecache::get: dropping "
+            TDEBUG_TRACEW(L"Dirstatecache::get: dropping "
                                             << cache().back().hgroot);
             delete cache().back().dstate;
             cache().back().dstate = 0;
     {
         if (0 != stat.lstat(path.c_str()))
         {
-            TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") failed");
-            TDEBUG_TRACE("Dirstatecache::get: dropping " << iter->hgroot);
+            TDEBUG_TRACEW(L"Dirstatecache::get: lstat(" << path <<") failed");
+            TDEBUG_TRACEW(L"Dirstatecache::get: dropping " << iter->hgroot);
             delete iter->dstate;
             iter->dstate = 0;
             cache().erase(iter);
             return 0;
         }
         iter->tickcount = tc;
-        TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") ok ");
+        TDEBUG_TRACEW(L"Dirstatecache::get: lstat(" << path <<") ok ");
         new_stat = true;
     }
 
             return iter->dstate;
         }
 
-        TDEBUG_TRACE("Dirstatecache::get: refreshing " << hgroot);
+        TDEBUG_TRACEW(L"Dirstatecache::get: refreshing " << hgroot);
     } 
     else 
     {
-        TDEBUG_TRACE("Dirstatecache::get: reading " << hgroot);
+        TDEBUG_TRACEW(L"Dirstatecache::get: reading " << hgroot);
     }
 
     unset = false;
     {
         if (iter->unset)
         {
-            TDEBUG_TRACE(
-                "Dirstatecache::get: **** old and new have unset entries");
+            TDEBUG_TRACEW(
+                L"Dirstatecache::get: **** old and new have unset entries");
             request_thgstatus_update = false;
         }
         else
         {
-            TDEBUG_TRACE("Dirstatecache::get: new has unset entries");
+            TDEBUG_TRACEW(L"Dirstatecache::get: new has unset entries");
         }
     }
 
     iter->dstate = ds.release();
 
     unsigned delta = tc1 - tc0;
-    TDEBUG_TRACE("Dirstatecache::get: read done in " << delta << " ticks, "
+    TDEBUG_TRACEW(L"Dirstatecache::get: read done in " << delta << " ticks, "
         << cache().size() << " repos in cache");
 
     iter->dstate_mtime = stat.mtime;
 
     if (request_thgstatus_update)
     {
-        TDEBUG_TRACE("Dirstatecache::get: calling Thgstatus::update");
+        TDEBUG_TRACEW(L"Dirstatecache::get: calling Thgstatus::update");
         Thgstatus::update(cwd);
     }
     else
     {
-        TDEBUG_TRACE("Dirstatecache::get: omitting Thgstatus::update");
+        TDEBUG_TRACEW(L"Dirstatecache::get: omitting Thgstatus::update");
     }
 
     return iter->dstate;
 }
 
 
-void Dirstatecache::invalidate(const std::string& hgroot)
+void Dirstatecache::invalidate(const std::wstring& hgroot)
 {
     typedef std::list<E>::iterator Iter;
 
             delete i->dstate;
             i->dstate = 0;
             cache().erase(i);
-            TDEBUG_TRACE("Dirstatecache::invalidate(" << hgroot << ")");
+            TDEBUG_TRACEW(L"Dirstatecache::invalidate(" << hgroot << ")");
             break;
         }
     }

win32/shellext/Dirstatecache.h

         __int64         dstate_mtime;
         __int64         dstate_size;
 
-        std::string     hgroot;
+        std::wstring     hgroot;
         unsigned        tickcount;
         bool            unset;
 
 
 public:
     static Dirstate* get(
-        const std::string& hgroot, const std::string& cwd, bool& unset);
-    static void invalidate(const std::string& hgroot);
+        const std::wstring& hgroot, const std::wstring& cwd, bool& unset);
+    static void invalidate(const std::wstring& hgroot);
 };
 
 #endif

win32/shellext/IconBitmapUtils.cpp

 
     if (pfnBeginBufferedPaint == NULL || pfnEndBufferedPaint == NULL || pfnGetBufferedPaintBits == NULL)
     {
-        TDEBUG_TRACE("    IconBitmapUtils::IconToBitmapPARGB32: Theme functions not found, returns NULL");
+        TDEBUG_TRACEW(L"    IconBitmapUtils::IconToBitmapPARGB32: Theme functions not found, returns NULL");
         return NULL;
     }
 

win32/shellext/InitStatus.cpp

 }
 
 
-void InitStatus::add(std::string& s, const char* missing)
+void InitStatus::add(std::wstring& s, const wchar_t* missing)
 {
     if (!s.empty())
-        s += ", ";
+        s += L", ";
     s += missing;
 }
 
 
-std::string InitStatus::check()
+std::wstring InitStatus::check()
 {
     const InitStatus& self = inst();
-    std::string missing;
+    std::wstring missing;
 
     if (self.unchanged_ == 0)
-        add(missing, "unchanged");
+        add(missing, L"unchanged");
     if (self.added_ == 0)
-        add(missing, "added");
+        add(missing, L"added");
     if (self.modified_ == 0)
-        add(missing, "modified");
+        add(missing, L"modified");
     if (self.notinrepo_ == 0)
-        add(missing, "notinrepo");
+        add(missing, L"notinrepo");
     
     if (missing.empty())
-        return "";
+        return L"";
 
-    std::string reason = "uninitialized handlers: " + missing;
+    std::wstring reason = L"uninitialized handlers: " + missing;
     Thgstatus::error(reason);
-    std::string res = "InitStatus: error: " + reason;
-    TDEBUG_TRACE("***** " << res);
+    std::wstring res = L"InitStatus: error: " + reason;
+    TDEBUG_TRACEW(L"***** " << res);
     return res;
 }

win32/shellext/InitStatus.h

     int notinrepo_;
 
     static InitStatus& inst();
-    static std::string check();
+    static std::wstring check();
 
 private:
     InitStatus()
     : unchanged_(0), added_(0), modified_(0), notinrepo_(0) {}
 
-    static void add(std::string& s, const char* missing);
+    static void add(std::wstring& s, const wchar_t* missing);
 };

win32/shellext/Makefile.nmake

 
 # /MT = statically linked runtime libraries /MD = dynamically linked
 # THG_EXTRA_CPPFLAGS is taken from environment (may be undefined)
-CPPFLAGS         = /nologo /Ox /W2 /EHsc /MT /DAPPMAIN /DTHG_DEBUG $(THG_EXTRA_CPPFLAGS)
-BASE_LDFLAGS     = /nologo /INCREMENTAL:NO /MANIFEST $(LIBS)
+CPPFLAGS         = /D "_UNICODE" /D "UNICODE" /Zi /nologo /Ox /W2 /EHsc /MT /DAPPMAIN /DTHG_DEBUG $(THG_EXTRA_CPPFLAGS)
+BASE_LDFLAGS     = /nologo /INCREMENTAL:NO /MANIFEST $(LIBS) /PDB:ThgShellx86.pdb
 LDFLAGS_THGSHELL = $(BASE_LDFLAGS) /DLL /DEF:$(DEFFILE)
 LDFLAGS_DIRSTATE = $(BASE_LDFLAGS) /SUBSYSTEM:CONSOLE
 LDFLAGS_TERMINATE = $(BASE_LDFLAGS) /DLL /DEF:terminate.def
 THGSHELL_TARGET = THgShell$(THG_PLATFORM).dll
 TERMINATE_TARGET = terminate-$(THG_PLATFORM).dll
 
-all: $(THGSHELL_TARGET) $(TERMINATE_TARGET)
+all: $(THGSHELL_TARGET)
 
 clean:
     del *.obj *.dll *.exe *.lib *.exp *.manifest *.res parentid.h ThgCLSIDs.wxi

win32/shellext/QueryDirstate.cpp

 class QueryState
 {
 public:
-    std::string path;
+    std::wstring path;
     bool        isdir;
-    std::string basedir;
-    std::string hgroot;
+    std::wstring basedir;
+    std::wstring hgroot;
 
-    char        status;
+    wchar_t        status;
     unsigned    tickcount;
 
     QueryState(): isdir(false), status('0'), tickcount(0) {}
 };
 
 
-bool hasHgDir(char cls, const std::string& path, unsigned& ticks)
+bool hasHgDir(wchar_t cls, const std::wstring& path, unsigned& ticks)
 {
     ticks = 0;
 
     bool res = false;
 
-    if (path.empty() || path == "\\")
+    if (path.empty() || path == L"\\")
         return res;
 
-    const std::string p = path + "\\.hg";
+    const std::wstring p = path + L"\\.hg";
 
     if (::PathIsUNCServerShare(p.c_str()))
         return res;
     if (ticks > 5 /* ms */)
     {
         // trace slower PathIsDirectory calls (untypical on local discs)
-        TDEBUG_TRACE(
-            "[" << cls << "] hasHgDir: PathIsDirectory(\"" << p << "\")" << 
-            " -> " << res << ", in " << ticks << " ticks"
+        TDEBUG_TRACEW(
+            L"[" << cls << L"] hasHgDir: PathIsDirectory(\"" << p << L"\")" << 
+            L" -> " << res << L", in " << ticks << L" ticks"
         );
     }
 
 }
 
 
-int findHgRoot(char cls, QueryState& cur, QueryState& last, bool outdated)
+int findHgRoot(wchar_t cls, QueryState& cur, QueryState& last, bool outdated)
 {
-    std::string dp = "["; dp += cls; dp += "] findHgRoot"; 
+    std::wstring dp = L"["; dp += cls; dp += L"] findHgRoot"; 
 
     {
-        std::string p = cur.path;
-        p.push_back('\\');
-        if (p.find("\\.hg\\") != std::string::npos) 
+        std::wstring p = cur.path;
+        p.push_back(L'\\');
+        if (p.find(L"\\.hg\\") != std::wstring::npos) 
         {
             // ignore files and dirs named '.hg'
             last = cur;
 
     if (!outdated && !last.hgroot.empty() 
         && cur.path.size() >= last.hgroot.size()
-        && StartsWith(cur.path, last.hgroot + "\\"))
+        && StartsWith(cur.path, last.hgroot + L"\\"))
     {
         cur.hgroot = last.hgroot;
         return 1;
         if (has_hg)
         {
             cur.hgroot = cur.path;
-            TDEBUG_TRACE(dp << "(" << cur.path << "): hgroot = cur.path");
+            TDEBUG_TRACEW(dp << L"(" << cur.path << L"): hgroot = cur.path");
             return 1;
         }
     }
         return 1;
     }
 
-    for (std::string p = cur.basedir;;)
+    for (std::wstring p = cur.basedir;;)
     {
         bool has_hg = hasHgDir(cls, p, ticks);
         if (ticks > 5000 /* ms */)
         {
-            const std::string reason = "ignoring slow \"" + p + "\"";
+            const std::wstring reason = L"ignoring slow \"" + p + L"\"";
             Thgstatus::error(reason);
             file_access_is_unacceptably_slow = true;
             goto exit;
         if (has_hg) 
         {
             cur.hgroot = p;
-            TDEBUG_TRACE(
-                dp << "(" << cur.path << "): hgroot = '" << cur.hgroot
-                << "' (found repo)"
+            TDEBUG_TRACEW(
+                dp << L"(" << cur.path << L"): hgroot = '" << cur.hgroot
+                << L"' (found repo)"
             );
             return 1;
         }
-        std::string p2 = DirName(p);
+        std::wstring p2 = DirName(p);
         if (p2.size() == p.size())
             break;
         p.swap(p2);
 exit:
     if (file_access_is_unacceptably_slow)
     {
-        TDEBUG_TRACE(
-            "******" << dp << "(" << cur.path << "): ignored, " 
-            << "call took too long (" << ticks << " ticks)");
+        TDEBUG_TRACEW(
+            L"******" << dp << L"(" << cur.path << L"): ignored, " 
+            << L"call took too long (" << ticks << L" ticks)");
     }
     else
     {
-        TDEBUG_TRACE(dp << "(" << cur.path << "): NO repo found");
+        TDEBUG_TRACEW(dp << L"(" << cur.path << L"): NO repo found");
     }
     last = cur;
     return 0;
 
 
 int get_relpath(
-    const std::string& hgroot, 
-    const std::string& path,
-    std::string& res
+    const std::wstring& hgroot, 
+    const std::wstring& path,
+    std::wstring& res
 )
 {
     size_t offset = hgroot.size();
     if (path[offset] == '\\')
         offset++;
     
-    const char* relpathptr = path.c_str() + offset;
+    const wchar_t* relpathptr = path.c_str() + offset;
 
     res = relpathptr;
     return 1;
 
 int HgQueryDirstate(
     const char cls,
-    const std::string& path,
-    const char& filterStatus, 
+    const std::wstring& path,
+    const wchar_t& filterStatus, 
     char& outStatus
 )
 {
-    std::string dp = "["; dp += cls; dp += "] HgQueryDirstate: "; 
+    std::wstring dp = L"["; dp += cls; dp += L"] HgQueryDirstate: "; 
 
     static QueryState last;
 
         return 0;
     }
 
-    if (path[offset] == '\\')
+    if (path[offset] == L'\\')
         offset++;
-    const char* relpathptr = path.c_str() + offset;
+    const wchar_t* relpathptr = path.c_str() + offset;
 
-    std::string relpath = relpathptr;
+    std::wstring relpath = relpathptr;
 
     for (size_t i = 0; i < relpath.size(); ++i)
     {
-        if (relpath[i] == '\\')
-            relpath[i] = '/';
+        if (relpath[i] == L'\\')
+            relpath[i] = L'/';
     }
 
     DirectoryStatus* pdirsta = DirectoryStatus::get(cur.hgroot, cur.basedir);
     Dirstate* pds = Dirstatecache::get(cur.hgroot, cur.basedir, unset);
     if (!pds)
     {
-        TDEBUG_TRACE(
-            dp << "Dirstatecache::get(" << cur.hgroot 
-            << ") returns no Dirstate"
+        TDEBUG_TRACEW(
+            dp << L"Dirstatecache::get(" << cur.hgroot 
+            << L") returns no Dirstate"
         );
         last = cur;
         return 0;
     Winstat stat;
     if (0 != stat.lstat(path.c_str())) 
     {
-        TDEBUG_TRACE(dp << "lstat(" << path << ") failed");
+        TDEBUG_TRACEW(dp << L"lstat(" << path << L") failed");
         last = cur;
         return 0;
     }
 
     if (outStatus == 'M' && pdirsta)
     {
-        std::string relbase;
+        std::wstring relbase;
         if (get_relpath(cur.hgroot, cur.basedir, relbase))
         {
-            TDEBUG_TRACE(dp << "relbase = '" << relbase << "'");
+            TDEBUG_TRACEW(dp << L"relbase = '" << relbase << L"'");
 
-            char basedir_status = pdirsta->status(relbase);
-            TDEBUG_TRACE(dp << "basedir_status = " << basedir_status);
+            wchar_t basedir_status = pdirsta->status(relbase);
+            TDEBUG_TRACEW(dp << L"basedir_status = " << basedir_status);
 
-            if (basedir_status != 'M')
+            if (basedir_status != L'M')
             {
                 if (unset)
                 {
-                    TDEBUG_TRACE(dp << "omitting Thgstatus::update");
+                    TDEBUG_TRACEW(dp << L"omitting Thgstatus::update");
                 }
                 else
                 {
-                    TDEBUG_TRACE(dp << "calling Thgstatus::update");
+                    TDEBUG_TRACEW(dp << L"calling Thgstatus::update");
                     Thgstatus::update(cur.hgroot);
                 }
             }

win32/shellext/QueryDirstate.h

 
 int HgQueryDirstate(
     const char myClass,
-    const std::string& path,
-    const char& filterStatus, 
+    const std::wstring& path,
+    const wchar_t& filterStatus, 
     char& outStatus
 );
 

win32/shellext/RegistryConfig.cpp

 #include "stdafx.h"
 #include "RegistryConfig.h"
 
-int GetRegistryConfig(const std::string& name, std::string& res)
+int GetRegistryConfig(const std::wstring& name, std::wstring& res)
 {
-    const char* const subkey = "Software\\TortoiseHg";
+    const wchar_t* const subkey = L"Software\\TortoiseHg";
 
     HKEY hkey = 0;
-    LONG rv = RegOpenKeyExA(
+    LONG rv = RegOpenKeyEx(
         HKEY_CURRENT_USER, subkey, 0, KEY_READ, &hkey);
 
     if (rv != ERROR_SUCCESS || hkey == 0)
         return 0;
 
-    BYTE Data[MAX_PATH] = "";
+	BYTE Data[MAX_PATH * 2] = {0};
     DWORD cbData = MAX_PATH * sizeof(BYTE);
 
-    rv = RegQueryValueExA(
+    rv = RegQueryValueEx(
         hkey, name.c_str(), 0, 0, Data, &cbData);
 
     int ret = 0;
     if (rv == ERROR_SUCCESS)
     {
-        res = reinterpret_cast<const char*>(&Data);
+        res = reinterpret_cast<const wchar_t*>(&Data);
         ret = 1;
     }
 

win32/shellext/RegistryConfig.h

 
 #include <string>
 
-int GetRegistryConfig(const std::string& name, std::string& res);
+int GetRegistryConfig(const std::wstring& name, std::wstring& res);
 
 #endif

win32/shellext/ShellExt.cpp

 {
     if (dwReason == DLL_PROCESS_ATTACH)
     {
-        TDEBUG_TRACE("DllMain: DLL_PROCESS_ATTACH");
+        TDEBUG_TRACEW(L"DllMain: DLL_PROCESS_ATTACH");
         g_hmodThisDll = hInstance;
         ::InitializeCriticalSection(&g_critical_section);
         _LoadResources();
     }
     else if (dwReason == DLL_PROCESS_DETACH)
     {
-        TDEBUG_TRACE("DllMain: DLL_PROCESS_ATTACH");
+        TDEBUG_TRACEW(L"DllMain: DLL_PROCESS_ATTACH");
         ::DeleteCriticalSection(&g_critical_section);
         _UnloadResources();
     }
 
 STDAPI DllCanUnloadNow(void)
 {
-    TDEBUG_TRACE("DllCanUnloadNow");
+    TDEBUG_TRACEW(L"DllCanUnloadNow");
     return (g_cRefThisDll == 0 ? S_OK : S_FALSE);
 }
 
         ::CoTaskMemFree(ptr);
     }
 
-    TDEBUG_TRACEW("DllGetClassObject clsid = " << clsid);
+    TDEBUG_TRACEW(L"DllGetClassObject clsid = " << clsid);
 
     if (ppvOut == 0)
     {
-        TDEBUG_TRACE("**** DllGetClassObject: error: ppvOut is 0");
+        TDEBUG_TRACEW(L"**** DllGetClassObject: error: ppvOut is 0");
         return E_POINTER;
     }
 
     if (clsid == CLSID_TortoiseHgCmenu)
     {
         FactCmenu *pcf = new FactCmenu(0);
-        TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgCmenu");
+        TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgCmenu");
         return pcf->QueryInterface(riid, ppvOut);
     }
     else if (clsid == CLSID_TortoiseHgNormal)
     {
         FactOvl *pcf = new FactOvl('C');  // clean
-        TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgNormal");
+        TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgNormal");
         ++InitStatus::inst().unchanged_;
         return pcf->QueryInterface(riid, ppvOut);
     }
     else if (clsid == CLSID_TortoiseHgAdded)
     {
         FactOvl *pcf = new FactOvl('A');  // added
-        TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgAdded");
+        TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgAdded");
         ++InitStatus::inst().added_;
         return pcf->QueryInterface(riid, ppvOut);
     }
     else if (clsid == CLSID_TortoiseHgModified)
     {
         FactOvl *pcf = new FactOvl('M');   // modified
-        TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgModified");
+        TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgModified");
         ++InitStatus::inst().modified_;
         return pcf->QueryInterface(riid, ppvOut);
     }
     else if (clsid == CLSID_TortoiseHgUnversioned)
     {
         FactOvl *pcf = new FactOvl('?');   // not in repo
-        TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgUnversioned");
+        TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgUnversioned");
         ++InitStatus::inst().notinrepo_;
         return pcf->QueryInterface(riid, ppvOut);
     }

win32/shellext/StringUtils.cpp

 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+#include "stdafx.h"
 #include "StringUtils.h"
 
 #include <vector>
 
 
 // Quotes a string
-std::string Quote(const std::string& str)
+std::wstring Quote(const std::wstring& str)
 {
-   std::string sResult = "\"" + str + "\"";
+   std::wstring sResult = L"\"" + str + L"\"";
    return sResult;
 }
 
         NULL, 0, NULL, NULL
     );
     
-    std::vector<CHAR> narrow(ret + 1);
+    std::vector<char> narrow(ret + 1);
 
     ret = WideCharToMultiByte(
         CodePage, 0, wide.c_str(), static_cast<int>(wide.length()),

win32/shellext/StringUtils.h

 #include <windows.h>
 
 // Quotes a string
-std::string Quote(const std::string& str);
+std::wstring Quote(const std::wstring& str);
 
 // Convert Unicode string to multibyte string
 std::string WideToMultibyte(const std::wstring& wide, UINT CodePage = CP_ACP);

win32/shellext/ThgDebug.cpp

 // the Free Software Foundation, either version 2 of the License, or
 // (at your option) any later version.
 
+#include "stdafx.h"
 #include "ThgDebug.h"
 #include "RegistryConfig.h"
 
 bool ThgDebug::regDebugShellExt()
 {
-    std::string val;
-    return GetRegistryConfig("DebugShellExt", val) != 0 && val == "1";
+    std::wstring val;
+    return GetRegistryConfig(L"DebugShellExt", val) != 0 && val == L"1";
 }
 
 bool ThgDebug::enabled()

win32/shellext/ThgVersion.cpp

+#include "stdafx.h"
 #include "ThgVersion.h"
 #include "parentid.h"
 

win32/shellext/Thgstatus.cpp

 #include <vector>
 
 
-std::string GetPipeName()
+std::wstring GetPipeName()
 {
     DWORD size = 260;
-    std::vector<char> buf(size);
-    if (!::GetUserNameA(&buf[0], &size))
-        return "";
-    std::string res = "\\\\.\\pipe\\TortoiseHgRpcServer-bc0c27107423-";
+    std::vector<wchar_t> buf(size);
+    if (!::GetUserName(&buf[0], &size))
+        return L"";
+    std::wstring res = L"\\\\.\\pipe\\TortoiseHgRpcServer-bc0c27107423-";
     res += &buf[0];
     return res;
 }
 
 
-int Thgstatus::SendRequest(const std::string& request)
+int Thgstatus::SendRequest(const std::wstring& request)
 {
-    static const std::string pname = GetPipeName();
+    static const std::wstring pname = GetPipeName();
 
     if (pname.empty())
         return 0;
     BOOL fSuccess;
     DWORD cbRead;
 
-    TDEBUG_TRACE("Thgstatus::update: sending '" << request  << "' to " << pname);
+    TDEBUG_TRACEW(L"Thgstatus::update: sending '" << request  << "' to " << pname);
 
-    fSuccess = ::CallNamedPipeA(
-        pname.c_str(), (void*)request.c_str(), request.size(), 0, 0, &cbRead,
+    fSuccess = ::CallNamedPipe(
+        pname.c_str(), (void*)request.c_str(), sizeof(wchar_t) * request.size(), 0, 0, &cbRead,
         NMPWAIT_NOWAIT
     );
 
     }
     else if (err == ERROR_PIPE_BUSY)
     {
-        TDEBUG_TRACE("Thgstatus::update: CallNamedPipeA failed. " 
-            "ERROR_PIPE_BUSY");
+        TDEBUG_TRACEW(L"Thgstatus::update: CallNamedPipeA failed. " 
+            L"ERROR_PIPE_BUSY");
         return -1;
     }
     else